(install): Don't try to copy ../lib-src/fns-*.el, as it isn't used anymore.
[emacs.git] / src / xdisp.c
blobfb66bf0beb08b3c0ec819c504df30fd4a8accfc6
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"
202 Cursor No_Cursor;
203 #endif
205 #ifndef FRAME_X_OUTPUT
206 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
207 #endif
209 #define INFINITY 10000000
211 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
212 || defined (USE_GTK)
213 extern void set_frame_menubar P_ ((struct frame *f, int, int));
214 extern int pending_menu_activation;
215 #endif
217 extern int interrupt_input;
218 extern int command_loop_level;
220 extern int minibuffer_auto_raise;
221 extern Lisp_Object Vminibuffer_list;
223 extern Lisp_Object Qface;
224 extern Lisp_Object Qmode_line, Qmode_line_inactive, Qheader_line;
226 extern Lisp_Object Voverriding_local_map;
227 extern Lisp_Object Voverriding_local_map_menu_flag;
228 extern Lisp_Object Qmenu_item;
229 extern Lisp_Object Qwhen;
230 extern Lisp_Object Qhelp_echo;
232 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
233 Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
234 Lisp_Object Qredisplay_end_trigger_functions;
235 Lisp_Object Qinhibit_point_motion_hooks;
236 Lisp_Object QCeval, QCfile, QCdata, QCpropertize;
237 Lisp_Object Qfontified;
238 Lisp_Object Qgrow_only;
239 Lisp_Object Qinhibit_eval_during_redisplay;
240 Lisp_Object Qbuffer_position, Qposition, Qobject;
242 /* Cursor shapes */
243 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
245 /* 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 /* Margin around tool bar buttons in pixels. */
269 Lisp_Object Vtool_bar_button_margin;
271 /* Thickness of shadow to draw around tool bar buttons. */
273 EMACS_INT tool_bar_button_relief;
275 /* Non-zero means automatically resize tool-bars so that all tool-bar
276 items are visible, and no blank lines remain. */
278 int auto_resize_tool_bars_p;
280 /* Non-zero means draw block and hollow cursor as wide as the glyph
281 under it. For example, if a block cursor is over a tab, it will be
282 drawn as wide as that tab on the display. */
284 int x_stretch_cursor_p;
286 /* Non-nil means don't actually do any redisplay. */
288 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
290 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
292 int inhibit_eval_during_redisplay;
294 /* Names of text properties relevant for redisplay. */
296 Lisp_Object Qdisplay;
297 extern Lisp_Object Qface, Qinvisible, Qwidth;
299 /* Symbols used in text property values. */
301 Lisp_Object Vdisplay_pixels_per_inch;
302 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
303 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
304 Lisp_Object Qmargin, Qpointer;
305 extern Lisp_Object Qheight;
306 extern Lisp_Object QCwidth, QCheight, QCascent;
307 extern Lisp_Object Qscroll_bar;
309 /* Non-nil means highlight trailing whitespace. */
311 Lisp_Object Vshow_trailing_whitespace;
313 #ifdef HAVE_WINDOW_SYSTEM
314 extern Lisp_Object Voverflow_newline_into_fringe;
316 /* Test if overflow newline into fringe. Called with iterator IT
317 at or past right window margin, and with IT->current_x set. */
319 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) \
320 (!NILP (Voverflow_newline_into_fringe) \
321 && FRAME_WINDOW_P (it->f) \
322 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
323 && it->current_x == it->last_visible_x)
325 #endif /* HAVE_WINDOW_SYSTEM */
327 /* Non-nil means show the text cursor in void text areas
328 i.e. in blank areas after eol and eob. This used to be
329 the default in 21.3. */
331 Lisp_Object Vvoid_text_area_pointer;
333 /* Name of the face used to highlight trailing whitespace. */
335 Lisp_Object Qtrailing_whitespace;
337 /* The symbol `image' which is the car of the lists used to represent
338 images in Lisp. */
340 Lisp_Object Qimage;
342 /* The image map types. */
343 Lisp_Object QCmap, QCpointer;
344 Lisp_Object Qrect, Qcircle, Qpoly;
346 /* Non-zero means print newline to stdout before next mini-buffer
347 message. */
349 int noninteractive_need_newline;
351 /* Non-zero means print newline to message log before next message. */
353 static int message_log_need_newline;
355 /* Three markers that message_dolog uses.
356 It could allocate them itself, but that causes trouble
357 in handling memory-full errors. */
358 static Lisp_Object message_dolog_marker1;
359 static Lisp_Object message_dolog_marker2;
360 static Lisp_Object message_dolog_marker3;
362 /* The buffer position of the first character appearing entirely or
363 partially on the line of the selected window which contains the
364 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
365 redisplay optimization in redisplay_internal. */
367 static struct text_pos this_line_start_pos;
369 /* Number of characters past the end of the line above, including the
370 terminating newline. */
372 static struct text_pos this_line_end_pos;
374 /* The vertical positions and the height of this line. */
376 static int this_line_vpos;
377 static int this_line_y;
378 static int this_line_pixel_height;
380 /* X position at which this display line starts. Usually zero;
381 negative if first character is partially visible. */
383 static int this_line_start_x;
385 /* Buffer that this_line_.* variables are referring to. */
387 static struct buffer *this_line_buffer;
389 /* Nonzero means truncate lines in all windows less wide than the
390 frame. */
392 int truncate_partial_width_windows;
394 /* A flag to control how to display unibyte 8-bit character. */
396 int unibyte_display_via_language_environment;
398 /* Nonzero means we have more than one non-mini-buffer-only frame.
399 Not guaranteed to be accurate except while parsing
400 frame-title-format. */
402 int multiple_frames;
404 Lisp_Object Vglobal_mode_string;
407 /* List of variables (symbols) which hold markers for overlay arrows.
408 The symbols on this list are examined during redisplay to determine
409 where to display overlay arrows. */
411 Lisp_Object Voverlay_arrow_variable_list;
413 /* Marker for where to display an arrow on top of the buffer text. */
415 Lisp_Object Voverlay_arrow_position;
417 /* String to display for the arrow. Only used on terminal frames. */
419 Lisp_Object Voverlay_arrow_string;
421 /* Values of those variables at last redisplay are stored as
422 properties on `overlay-arrow-position' symbol. However, if
423 Voverlay_arrow_position is a marker, last-arrow-position is its
424 numerical position. */
426 Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
428 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
429 properties on a symbol in overlay-arrow-variable-list. */
431 Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
433 /* Like mode-line-format, but for the title bar on a visible frame. */
435 Lisp_Object Vframe_title_format;
437 /* Like mode-line-format, but for the title bar on an iconified frame. */
439 Lisp_Object Vicon_title_format;
441 /* List of functions to call when a window's size changes. These
442 functions get one arg, a frame on which one or more windows' sizes
443 have changed. */
445 static Lisp_Object Vwindow_size_change_functions;
447 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
449 /* Nonzero if overlay arrow has been displayed once in this window. */
451 static int overlay_arrow_seen;
453 /* Nonzero means highlight the region even in nonselected windows. */
455 int highlight_nonselected_windows;
457 /* If cursor motion alone moves point off frame, try scrolling this
458 many lines up or down if that will bring it back. */
460 static EMACS_INT scroll_step;
462 /* Nonzero means scroll just far enough to bring point back on the
463 screen, when appropriate. */
465 static EMACS_INT scroll_conservatively;
467 /* Recenter the window whenever point gets within this many lines of
468 the top or bottom of the window. This value is translated into a
469 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
470 that there is really a fixed pixel height scroll margin. */
472 EMACS_INT scroll_margin;
474 /* Number of windows showing the buffer of the selected window (or
475 another buffer with the same base buffer). keyboard.c refers to
476 this. */
478 int buffer_shared;
480 /* Vector containing glyphs for an ellipsis `...'. */
482 static Lisp_Object default_invis_vector[3];
484 /* Zero means display the mode-line/header-line/menu-bar in the default face
485 (this slightly odd definition is for compatibility with previous versions
486 of emacs), non-zero means display them using their respective faces.
488 This variable is deprecated. */
490 int mode_line_inverse_video;
492 /* Prompt to display in front of the mini-buffer contents. */
494 Lisp_Object minibuf_prompt;
496 /* Width of current mini-buffer prompt. Only set after display_line
497 of the line that contains the prompt. */
499 int minibuf_prompt_width;
501 /* This is the window where the echo area message was displayed. It
502 is always a mini-buffer window, but it may not be the same window
503 currently active as a mini-buffer. */
505 Lisp_Object echo_area_window;
507 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
508 pushes the current message and the value of
509 message_enable_multibyte on the stack, the function restore_message
510 pops the stack and displays MESSAGE again. */
512 Lisp_Object Vmessage_stack;
514 /* Nonzero means multibyte characters were enabled when the echo area
515 message was specified. */
517 int message_enable_multibyte;
519 /* Nonzero if we should redraw the mode lines on the next redisplay. */
521 int update_mode_lines;
523 /* Nonzero if window sizes or contents have changed since last
524 redisplay that finished. */
526 int windows_or_buffers_changed;
528 /* Nonzero means a frame's cursor type has been changed. */
530 int cursor_type_changed;
532 /* Nonzero after display_mode_line if %l was used and it displayed a
533 line number. */
535 int line_number_displayed;
537 /* Maximum buffer size for which to display line numbers. */
539 Lisp_Object Vline_number_display_limit;
541 /* Line width to consider when repositioning for line number display. */
543 static EMACS_INT line_number_display_limit_width;
545 /* Number of lines to keep in the message log buffer. t means
546 infinite. nil means don't log at all. */
548 Lisp_Object Vmessage_log_max;
550 /* The name of the *Messages* buffer, a string. */
552 static Lisp_Object Vmessages_buffer_name;
554 /* Current, index 0, and last displayed echo area message. Either
555 buffers from echo_buffers, or nil to indicate no message. */
557 Lisp_Object echo_area_buffer[2];
559 /* The buffers referenced from echo_area_buffer. */
561 static Lisp_Object echo_buffer[2];
563 /* A vector saved used in with_area_buffer to reduce consing. */
565 static Lisp_Object Vwith_echo_area_save_vector;
567 /* Non-zero means display_echo_area should display the last echo area
568 message again. Set by redisplay_preserve_echo_area. */
570 static int display_last_displayed_message_p;
572 /* Nonzero if echo area is being used by print; zero if being used by
573 message. */
575 int message_buf_print;
577 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
579 Lisp_Object Qinhibit_menubar_update;
580 int inhibit_menubar_update;
582 /* Maximum height for resizing mini-windows. Either a float
583 specifying a fraction of the available height, or an integer
584 specifying a number of lines. */
586 Lisp_Object Vmax_mini_window_height;
588 /* Non-zero means messages should be displayed with truncated
589 lines instead of being continued. */
591 int message_truncate_lines;
592 Lisp_Object Qmessage_truncate_lines;
594 /* Set to 1 in clear_message to make redisplay_internal aware
595 of an emptied echo area. */
597 static int message_cleared_p;
599 /* Non-zero means we want a hollow cursor in windows that are not
600 selected. Zero means there's no cursor in such windows. */
602 Lisp_Object Vcursor_in_non_selected_windows;
603 Lisp_Object Qcursor_in_non_selected_windows;
605 /* How to blink the default frame cursor off. */
606 Lisp_Object Vblink_cursor_alist;
608 /* A scratch glyph row with contents used for generating truncation
609 glyphs. Also used in direct_output_for_insert. */
611 #define MAX_SCRATCH_GLYPHS 100
612 struct glyph_row scratch_glyph_row;
613 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
615 /* Ascent and height of the last line processed by move_it_to. */
617 static int last_max_ascent, last_height;
619 /* Non-zero if there's a help-echo in the echo area. */
621 int help_echo_showing_p;
623 /* If >= 0, computed, exact values of mode-line and header-line height
624 to use in the macros CURRENT_MODE_LINE_HEIGHT and
625 CURRENT_HEADER_LINE_HEIGHT. */
627 int current_mode_line_height, current_header_line_height;
629 /* The maximum distance to look ahead for text properties. Values
630 that are too small let us call compute_char_face and similar
631 functions too often which is expensive. Values that are too large
632 let us call compute_char_face and alike too often because we
633 might not be interested in text properties that far away. */
635 #define TEXT_PROP_DISTANCE_LIMIT 100
637 #if GLYPH_DEBUG
639 /* Variables to turn off display optimizations from Lisp. */
641 int inhibit_try_window_id, inhibit_try_window_reusing;
642 int inhibit_try_cursor_movement;
644 /* Non-zero means print traces of redisplay if compiled with
645 GLYPH_DEBUG != 0. */
647 int trace_redisplay_p;
649 #endif /* GLYPH_DEBUG */
651 #ifdef DEBUG_TRACE_MOVE
652 /* Non-zero means trace with TRACE_MOVE to stderr. */
653 int trace_move;
655 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
656 #else
657 #define TRACE_MOVE(x) (void) 0
658 #endif
660 /* Non-zero means automatically scroll windows horizontally to make
661 point visible. */
663 int automatic_hscrolling_p;
665 /* How close to the margin can point get before the window is scrolled
666 horizontally. */
667 EMACS_INT hscroll_margin;
669 /* How much to scroll horizontally when point is inside the above margin. */
670 Lisp_Object Vhscroll_step;
672 /* A list of symbols, one for each supported image type. */
674 Lisp_Object Vimage_types;
676 /* The variable `resize-mini-windows'. If nil, don't resize
677 mini-windows. If t, always resize them to fit the text they
678 display. If `grow-only', let mini-windows grow only until they
679 become empty. */
681 Lisp_Object Vresize_mini_windows;
683 /* Buffer being redisplayed -- for redisplay_window_error. */
685 struct buffer *displayed_buffer;
687 /* Value returned from text property handlers (see below). */
689 enum prop_handled
691 HANDLED_NORMALLY,
692 HANDLED_RECOMPUTE_PROPS,
693 HANDLED_OVERLAY_STRING_CONSUMED,
694 HANDLED_RETURN
697 /* A description of text properties that redisplay is interested
698 in. */
700 struct props
702 /* The name of the property. */
703 Lisp_Object *name;
705 /* A unique index for the property. */
706 enum prop_idx idx;
708 /* A handler function called to set up iterator IT from the property
709 at IT's current position. Value is used to steer handle_stop. */
710 enum prop_handled (*handler) P_ ((struct it *it));
713 static enum prop_handled handle_face_prop P_ ((struct it *));
714 static enum prop_handled handle_invisible_prop P_ ((struct it *));
715 static enum prop_handled handle_display_prop P_ ((struct it *));
716 static enum prop_handled handle_composition_prop P_ ((struct it *));
717 static enum prop_handled handle_overlay_change P_ ((struct it *));
718 static enum prop_handled handle_fontified_prop P_ ((struct it *));
720 /* Properties handled by iterators. */
722 static struct props it_props[] =
724 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
725 /* Handle `face' before `display' because some sub-properties of
726 `display' need to know the face. */
727 {&Qface, FACE_PROP_IDX, handle_face_prop},
728 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
729 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
730 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
731 {NULL, 0, NULL}
734 /* Value is the position described by X. If X is a marker, value is
735 the marker_position of X. Otherwise, value is X. */
737 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
739 /* Enumeration returned by some move_it_.* functions internally. */
741 enum move_it_result
743 /* Not used. Undefined value. */
744 MOVE_UNDEFINED,
746 /* Move ended at the requested buffer position or ZV. */
747 MOVE_POS_MATCH_OR_ZV,
749 /* Move ended at the requested X pixel position. */
750 MOVE_X_REACHED,
752 /* Move within a line ended at the end of a line that must be
753 continued. */
754 MOVE_LINE_CONTINUED,
756 /* Move within a line ended at the end of a line that would
757 be displayed truncated. */
758 MOVE_LINE_TRUNCATED,
760 /* Move within a line ended at a line end. */
761 MOVE_NEWLINE_OR_CR
764 /* This counter is used to clear the face cache every once in a while
765 in redisplay_internal. It is incremented for each redisplay.
766 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
767 cleared. */
769 #define CLEAR_FACE_CACHE_COUNT 500
770 static int clear_face_cache_count;
772 /* Record the previous terminal frame we displayed. */
774 static struct frame *previous_terminal_frame;
776 /* Non-zero while redisplay_internal is in progress. */
778 int redisplaying_p;
780 /* Non-zero means don't free realized faces. Bound while freeing
781 realized faces is dangerous because glyph matrices might still
782 reference them. */
784 int inhibit_free_realized_faces;
785 Lisp_Object Qinhibit_free_realized_faces;
787 /* If a string, XTread_socket generates an event to display that string.
788 (The display is done in read_char.) */
790 Lisp_Object help_echo_string;
791 Lisp_Object help_echo_window;
792 Lisp_Object help_echo_object;
793 int help_echo_pos;
795 /* Temporary variable for XTread_socket. */
797 Lisp_Object previous_help_echo_string;
801 /* Function prototypes. */
803 static void setup_for_ellipsis P_ ((struct it *));
804 static void mark_window_display_accurate_1 P_ ((struct window *, int));
805 static int single_display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
806 static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
807 static int cursor_row_p P_ ((struct window *, struct glyph_row *));
808 static int redisplay_mode_lines P_ ((Lisp_Object, int));
809 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
811 #if 0
812 static int invisible_text_between_p P_ ((struct it *, int, int));
813 #endif
815 static int next_element_from_ellipsis P_ ((struct it *));
816 static void pint2str P_ ((char *, int, int));
817 static void pint2hrstr P_ ((char *, int, int));
818 static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
819 struct text_pos));
820 static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
821 static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
822 static void store_frame_title_char P_ ((char));
823 static int store_frame_title P_ ((const unsigned char *, int, int));
824 static void x_consider_frame_title P_ ((Lisp_Object));
825 static void handle_stop P_ ((struct it *));
826 static int tool_bar_lines_needed P_ ((struct frame *));
827 static int single_display_prop_intangible_p P_ ((Lisp_Object));
828 static void ensure_echo_area_buffers P_ ((void));
829 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
830 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
831 static int with_echo_area_buffer P_ ((struct window *, int,
832 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
833 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
834 static void clear_garbaged_frames P_ ((void));
835 static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
836 static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
837 static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
838 static int display_echo_area P_ ((struct window *));
839 static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
840 static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
841 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
842 static int string_char_and_length P_ ((const unsigned char *, int, int *));
843 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
844 struct text_pos));
845 static int compute_window_start_on_continuation_line P_ ((struct window *));
846 static Lisp_Object safe_eval_handler P_ ((Lisp_Object));
847 static void insert_left_trunc_glyphs P_ ((struct it *));
848 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *,
849 Lisp_Object));
850 static void extend_face_to_end_of_line P_ ((struct it *));
851 static int append_space P_ ((struct it *, int));
852 static int make_cursor_line_fully_visible P_ ((struct window *));
853 static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
854 static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
855 static int trailing_whitespace_p P_ ((int));
856 static int message_log_check_duplicate P_ ((int, int, int, int));
857 static void push_it P_ ((struct it *));
858 static void pop_it P_ ((struct it *));
859 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
860 static void select_frame_for_redisplay P_ ((Lisp_Object));
861 static void redisplay_internal P_ ((int));
862 static int echo_area_display P_ ((int));
863 static void redisplay_windows P_ ((Lisp_Object));
864 static void redisplay_window P_ ((Lisp_Object, int));
865 static Lisp_Object redisplay_window_error ();
866 static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
867 static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
868 static void update_menu_bar P_ ((struct frame *, int));
869 static int try_window_reusing_current_matrix P_ ((struct window *));
870 static int try_window_id P_ ((struct window *));
871 static int display_line P_ ((struct it *));
872 static int display_mode_lines P_ ((struct window *));
873 static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
874 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
875 static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
876 static char *decode_mode_spec P_ ((struct window *, int, int, int, int *));
877 static void display_menu_bar P_ ((struct window *));
878 static int display_count_lines P_ ((int, int, int, int, int *));
879 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
880 int, int, struct it *, int, int, int, int));
881 static void compute_line_metrics P_ ((struct it *));
882 static void run_redisplay_end_trigger_hook P_ ((struct it *));
883 static int get_overlay_strings P_ ((struct it *, int));
884 static void next_overlay_string P_ ((struct it *));
885 static void reseat P_ ((struct it *, struct text_pos, int));
886 static void reseat_1 P_ ((struct it *, struct text_pos, int));
887 static void back_to_previous_visible_line_start P_ ((struct it *));
888 static void reseat_at_previous_visible_line_start P_ ((struct it *));
889 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
890 static int next_element_from_display_vector P_ ((struct it *));
891 static int next_element_from_string P_ ((struct it *));
892 static int next_element_from_c_string P_ ((struct it *));
893 static int next_element_from_buffer P_ ((struct it *));
894 static int next_element_from_composition P_ ((struct it *));
895 static int next_element_from_image P_ ((struct it *));
896 static int next_element_from_stretch P_ ((struct it *));
897 static void load_overlay_strings P_ ((struct it *, int));
898 static int init_from_display_pos P_ ((struct it *, struct window *,
899 struct display_pos *));
900 static void reseat_to_string P_ ((struct it *, unsigned char *,
901 Lisp_Object, int, int, int, int));
902 static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
903 int, int, int));
904 void move_it_vertically_backward P_ ((struct it *, int));
905 static void init_to_row_start P_ ((struct it *, struct window *,
906 struct glyph_row *));
907 static int init_to_row_end P_ ((struct it *, struct window *,
908 struct glyph_row *));
909 static void back_to_previous_line_start P_ ((struct it *));
910 static int forward_to_next_line_start P_ ((struct it *, int *));
911 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
912 Lisp_Object, int));
913 static struct text_pos string_pos P_ ((int, Lisp_Object));
914 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
915 static int number_of_chars P_ ((unsigned char *, int));
916 static void compute_stop_pos P_ ((struct it *));
917 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
918 Lisp_Object));
919 static int face_before_or_after_it_pos P_ ((struct it *, int));
920 static int next_overlay_change P_ ((int));
921 static int handle_single_display_prop P_ ((struct it *, Lisp_Object,
922 Lisp_Object, struct text_pos *,
923 int));
924 static int underlying_face_id P_ ((struct it *));
925 static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
926 struct window *));
928 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
929 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
931 #ifdef HAVE_WINDOW_SYSTEM
933 static void update_tool_bar P_ ((struct frame *, int));
934 static void build_desired_tool_bar_string P_ ((struct frame *f));
935 static int redisplay_tool_bar P_ ((struct frame *));
936 static void display_tool_bar_line P_ ((struct it *));
937 static void notice_overwritten_cursor P_ ((struct window *,
938 enum glyph_row_area,
939 int, int, int, int));
943 #endif /* HAVE_WINDOW_SYSTEM */
946 /***********************************************************************
947 Window display dimensions
948 ***********************************************************************/
950 /* Return the bottom boundary y-position for text lines in window W.
951 This is the first y position at which a line cannot start.
952 It is relative to the top of the window.
954 This is the height of W minus the height of a mode line, if any. */
956 INLINE int
957 window_text_bottom_y (w)
958 struct window *w;
960 int height = WINDOW_TOTAL_HEIGHT (w);
962 if (WINDOW_WANTS_MODELINE_P (w))
963 height -= CURRENT_MODE_LINE_HEIGHT (w);
964 return height;
967 /* Return the pixel width of display area AREA of window W. AREA < 0
968 means return the total width of W, not including fringes to
969 the left and right of the window. */
971 INLINE int
972 window_box_width (w, area)
973 struct window *w;
974 int area;
976 int cols = XFASTINT (w->total_cols);
977 int pixels = 0;
979 if (!w->pseudo_window_p)
981 cols -= WINDOW_SCROLL_BAR_COLS (w);
983 if (area == TEXT_AREA)
985 if (INTEGERP (w->left_margin_cols))
986 cols -= XFASTINT (w->left_margin_cols);
987 if (INTEGERP (w->right_margin_cols))
988 cols -= XFASTINT (w->right_margin_cols);
989 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
991 else if (area == LEFT_MARGIN_AREA)
993 cols = (INTEGERP (w->left_margin_cols)
994 ? XFASTINT (w->left_margin_cols) : 0);
995 pixels = 0;
997 else if (area == RIGHT_MARGIN_AREA)
999 cols = (INTEGERP (w->right_margin_cols)
1000 ? XFASTINT (w->right_margin_cols) : 0);
1001 pixels = 0;
1005 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1009 /* Return the pixel height of the display area of window W, not
1010 including mode lines of W, if any. */
1012 INLINE int
1013 window_box_height (w)
1014 struct window *w;
1016 struct frame *f = XFRAME (w->frame);
1017 int height = WINDOW_TOTAL_HEIGHT (w);
1019 xassert (height >= 0);
1021 /* Note: the code below that determines the mode-line/header-line
1022 height is essentially the same as that contained in the macro
1023 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1024 the appropriate glyph row has its `mode_line_p' flag set,
1025 and if it doesn't, uses estimate_mode_line_height instead. */
1027 if (WINDOW_WANTS_MODELINE_P (w))
1029 struct glyph_row *ml_row
1030 = (w->current_matrix && w->current_matrix->rows
1031 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1032 : 0);
1033 if (ml_row && ml_row->mode_line_p)
1034 height -= ml_row->height;
1035 else
1036 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1039 if (WINDOW_WANTS_HEADER_LINE_P (w))
1041 struct glyph_row *hl_row
1042 = (w->current_matrix && w->current_matrix->rows
1043 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1044 : 0);
1045 if (hl_row && hl_row->mode_line_p)
1046 height -= hl_row->height;
1047 else
1048 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1051 /* With a very small font and a mode-line that's taller than
1052 default, we might end up with a negative height. */
1053 return max (0, height);
1056 /* Return the window-relative coordinate of the left edge of display
1057 area AREA of window W. AREA < 0 means return the left edge of the
1058 whole window, to the right of the left fringe of W. */
1060 INLINE int
1061 window_box_left_offset (w, area)
1062 struct window *w;
1063 int area;
1065 int x;
1067 if (w->pseudo_window_p)
1068 return 0;
1070 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1072 if (area == TEXT_AREA)
1073 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1074 + window_box_width (w, LEFT_MARGIN_AREA));
1075 else if (area == RIGHT_MARGIN_AREA)
1076 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1077 + window_box_width (w, LEFT_MARGIN_AREA)
1078 + window_box_width (w, TEXT_AREA)
1079 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1081 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1082 else if (area == LEFT_MARGIN_AREA
1083 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1084 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1086 return x;
1090 /* Return the window-relative coordinate of the right edge of display
1091 area AREA of window W. AREA < 0 means return the left edge of the
1092 whole window, to the left of the right fringe of W. */
1094 INLINE int
1095 window_box_right_offset (w, area)
1096 struct window *w;
1097 int area;
1099 return window_box_left_offset (w, area) + window_box_width (w, area);
1102 /* Return the frame-relative coordinate of the left edge of display
1103 area AREA of window W. AREA < 0 means return the left edge of the
1104 whole window, to the right of the left fringe of W. */
1106 INLINE int
1107 window_box_left (w, area)
1108 struct window *w;
1109 int area;
1111 struct frame *f = XFRAME (w->frame);
1112 int x;
1114 if (w->pseudo_window_p)
1115 return FRAME_INTERNAL_BORDER_WIDTH (f);
1117 x = (WINDOW_LEFT_EDGE_X (w)
1118 + window_box_left_offset (w, area));
1120 return x;
1124 /* Return the frame-relative coordinate of the right edge of display
1125 area AREA of window W. AREA < 0 means return the left edge of the
1126 whole window, to the left of the right fringe of W. */
1128 INLINE int
1129 window_box_right (w, area)
1130 struct window *w;
1131 int area;
1133 return window_box_left (w, area) + window_box_width (w, area);
1136 /* Get the bounding box of the display area AREA of window W, without
1137 mode lines, in frame-relative coordinates. AREA < 0 means the
1138 whole window, not including the left and right fringes of
1139 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1140 coordinates of the upper-left corner of the box. Return in
1141 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1143 INLINE void
1144 window_box (w, area, box_x, box_y, box_width, box_height)
1145 struct window *w;
1146 int area;
1147 int *box_x, *box_y, *box_width, *box_height;
1149 if (box_width)
1150 *box_width = window_box_width (w, area);
1151 if (box_height)
1152 *box_height = window_box_height (w);
1153 if (box_x)
1154 *box_x = window_box_left (w, area);
1155 if (box_y)
1157 *box_y = WINDOW_TOP_EDGE_Y (w);
1158 if (WINDOW_WANTS_HEADER_LINE_P (w))
1159 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1164 /* Get the bounding box of the display area AREA of window W, without
1165 mode lines. AREA < 0 means the whole window, not including the
1166 left and right fringe of the window. Return in *TOP_LEFT_X
1167 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1168 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1169 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1170 box. */
1172 INLINE void
1173 window_box_edges (w, area, top_left_x, top_left_y,
1174 bottom_right_x, bottom_right_y)
1175 struct window *w;
1176 int area;
1177 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
1179 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1180 bottom_right_y);
1181 *bottom_right_x += *top_left_x;
1182 *bottom_right_y += *top_left_y;
1187 /***********************************************************************
1188 Utilities
1189 ***********************************************************************/
1191 /* Return the bottom y-position of the line the iterator IT is in.
1192 This can modify IT's settings. */
1195 line_bottom_y (it)
1196 struct it *it;
1198 int line_height = it->max_ascent + it->max_descent;
1199 int line_top_y = it->current_y;
1201 if (line_height == 0)
1203 if (last_height)
1204 line_height = last_height;
1205 else if (IT_CHARPOS (*it) < ZV)
1207 move_it_by_lines (it, 1, 1);
1208 line_height = (it->max_ascent || it->max_descent
1209 ? it->max_ascent + it->max_descent
1210 : last_height);
1212 else
1214 struct glyph_row *row = it->glyph_row;
1216 /* Use the default character height. */
1217 it->glyph_row = NULL;
1218 it->what = IT_CHARACTER;
1219 it->c = ' ';
1220 it->len = 1;
1221 PRODUCE_GLYPHS (it);
1222 line_height = it->ascent + it->descent;
1223 it->glyph_row = row;
1227 return line_top_y + line_height;
1231 /* Return 1 if position CHARPOS is visible in window W. Set *FULLY to
1232 1 if POS is visible and the line containing POS is fully visible.
1233 EXACT_MODE_LINE_HEIGHTS_P non-zero means compute exact mode-line
1234 and header-lines heights. */
1237 pos_visible_p (w, charpos, fully, exact_mode_line_heights_p)
1238 struct window *w;
1239 int charpos, *fully, exact_mode_line_heights_p;
1241 struct it it;
1242 struct text_pos top;
1243 int visible_p;
1244 struct buffer *old_buffer = NULL;
1246 if (XBUFFER (w->buffer) != current_buffer)
1248 old_buffer = current_buffer;
1249 set_buffer_internal_1 (XBUFFER (w->buffer));
1252 *fully = visible_p = 0;
1253 SET_TEXT_POS_FROM_MARKER (top, w->start);
1255 /* Compute exact mode line heights, if requested. */
1256 if (exact_mode_line_heights_p)
1258 if (WINDOW_WANTS_MODELINE_P (w))
1259 current_mode_line_height
1260 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1261 current_buffer->mode_line_format);
1263 if (WINDOW_WANTS_HEADER_LINE_P (w))
1264 current_header_line_height
1265 = display_mode_line (w, HEADER_LINE_FACE_ID,
1266 current_buffer->header_line_format);
1269 start_display (&it, w, top);
1270 move_it_to (&it, charpos, 0, it.last_visible_y, -1,
1271 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
1273 /* Note that we may overshoot because of invisible text. */
1274 if (IT_CHARPOS (it) >= charpos)
1276 int top_y = it.current_y;
1277 int bottom_y = line_bottom_y (&it);
1278 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1280 if (top_y < window_top_y)
1281 visible_p = bottom_y > window_top_y;
1282 else if (top_y < it.last_visible_y)
1284 visible_p = 1;
1285 *fully = bottom_y <= it.last_visible_y;
1288 else if (it.current_y + it.max_ascent + it.max_descent > it.last_visible_y)
1290 move_it_by_lines (&it, 1, 0);
1291 if (charpos < IT_CHARPOS (it))
1293 visible_p = 1;
1294 *fully = 0;
1298 if (old_buffer)
1299 set_buffer_internal_1 (old_buffer);
1301 current_header_line_height = current_mode_line_height = -1;
1302 return visible_p;
1306 /* Return the next character from STR which is MAXLEN bytes long.
1307 Return in *LEN the length of the character. This is like
1308 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1309 we find one, we return a `?', but with the length of the invalid
1310 character. */
1312 static INLINE int
1313 string_char_and_length (str, maxlen, len)
1314 const unsigned char *str;
1315 int maxlen, *len;
1317 int c;
1319 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
1320 if (!CHAR_VALID_P (c, 1))
1321 /* We may not change the length here because other places in Emacs
1322 don't use this function, i.e. they silently accept invalid
1323 characters. */
1324 c = '?';
1326 return c;
1331 /* Given a position POS containing a valid character and byte position
1332 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1334 static struct text_pos
1335 string_pos_nchars_ahead (pos, string, nchars)
1336 struct text_pos pos;
1337 Lisp_Object string;
1338 int nchars;
1340 xassert (STRINGP (string) && nchars >= 0);
1342 if (STRING_MULTIBYTE (string))
1344 int rest = SBYTES (string) - BYTEPOS (pos);
1345 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1346 int len;
1348 while (nchars--)
1350 string_char_and_length (p, rest, &len);
1351 p += len, rest -= len;
1352 xassert (rest >= 0);
1353 CHARPOS (pos) += 1;
1354 BYTEPOS (pos) += len;
1357 else
1358 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1360 return pos;
1364 /* Value is the text position, i.e. character and byte position,
1365 for character position CHARPOS in STRING. */
1367 static INLINE struct text_pos
1368 string_pos (charpos, string)
1369 int charpos;
1370 Lisp_Object string;
1372 struct text_pos pos;
1373 xassert (STRINGP (string));
1374 xassert (charpos >= 0);
1375 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1376 return pos;
1380 /* Value is a text position, i.e. character and byte position, for
1381 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1382 means recognize multibyte characters. */
1384 static struct text_pos
1385 c_string_pos (charpos, s, multibyte_p)
1386 int charpos;
1387 unsigned char *s;
1388 int multibyte_p;
1390 struct text_pos pos;
1392 xassert (s != NULL);
1393 xassert (charpos >= 0);
1395 if (multibyte_p)
1397 int rest = strlen (s), len;
1399 SET_TEXT_POS (pos, 0, 0);
1400 while (charpos--)
1402 string_char_and_length (s, rest, &len);
1403 s += len, rest -= len;
1404 xassert (rest >= 0);
1405 CHARPOS (pos) += 1;
1406 BYTEPOS (pos) += len;
1409 else
1410 SET_TEXT_POS (pos, charpos, charpos);
1412 return pos;
1416 /* Value is the number of characters in C string S. MULTIBYTE_P
1417 non-zero means recognize multibyte characters. */
1419 static int
1420 number_of_chars (s, multibyte_p)
1421 unsigned char *s;
1422 int multibyte_p;
1424 int nchars;
1426 if (multibyte_p)
1428 int rest = strlen (s), len;
1429 unsigned char *p = (unsigned char *) s;
1431 for (nchars = 0; rest > 0; ++nchars)
1433 string_char_and_length (p, rest, &len);
1434 rest -= len, p += len;
1437 else
1438 nchars = strlen (s);
1440 return nchars;
1444 /* Compute byte position NEWPOS->bytepos corresponding to
1445 NEWPOS->charpos. POS is a known position in string STRING.
1446 NEWPOS->charpos must be >= POS.charpos. */
1448 static void
1449 compute_string_pos (newpos, pos, string)
1450 struct text_pos *newpos, pos;
1451 Lisp_Object string;
1453 xassert (STRINGP (string));
1454 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1456 if (STRING_MULTIBYTE (string))
1457 *newpos = string_pos_nchars_ahead (pos, string,
1458 CHARPOS (*newpos) - CHARPOS (pos));
1459 else
1460 BYTEPOS (*newpos) = CHARPOS (*newpos);
1463 /* EXPORT:
1464 Return an estimation of the pixel height of mode or top lines on
1465 frame F. FACE_ID specifies what line's height to estimate. */
1468 estimate_mode_line_height (f, face_id)
1469 struct frame *f;
1470 enum face_id face_id;
1472 #ifdef HAVE_WINDOW_SYSTEM
1473 if (FRAME_WINDOW_P (f))
1475 int height = FONT_HEIGHT (FRAME_FONT (f));
1477 /* This function is called so early when Emacs starts that the face
1478 cache and mode line face are not yet initialized. */
1479 if (FRAME_FACE_CACHE (f))
1481 struct face *face = FACE_FROM_ID (f, face_id);
1482 if (face)
1484 if (face->font)
1485 height = FONT_HEIGHT (face->font);
1486 if (face->box_line_width > 0)
1487 height += 2 * face->box_line_width;
1491 return height;
1493 #endif
1495 return 1;
1498 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1499 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1500 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1501 not force the value into range. */
1503 void
1504 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
1505 FRAME_PTR f;
1506 register int pix_x, pix_y;
1507 int *x, *y;
1508 NativeRectangle *bounds;
1509 int noclip;
1512 #ifdef HAVE_WINDOW_SYSTEM
1513 if (FRAME_WINDOW_P (f))
1515 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1516 even for negative values. */
1517 if (pix_x < 0)
1518 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1519 if (pix_y < 0)
1520 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1522 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1523 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1525 if (bounds)
1526 STORE_NATIVE_RECT (*bounds,
1527 FRAME_COL_TO_PIXEL_X (f, pix_x),
1528 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1529 FRAME_COLUMN_WIDTH (f) - 1,
1530 FRAME_LINE_HEIGHT (f) - 1);
1532 if (!noclip)
1534 if (pix_x < 0)
1535 pix_x = 0;
1536 else if (pix_x > FRAME_TOTAL_COLS (f))
1537 pix_x = FRAME_TOTAL_COLS (f);
1539 if (pix_y < 0)
1540 pix_y = 0;
1541 else if (pix_y > FRAME_LINES (f))
1542 pix_y = FRAME_LINES (f);
1545 #endif
1547 *x = pix_x;
1548 *y = pix_y;
1552 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1553 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1554 can't tell the positions because W's display is not up to date,
1555 return 0. */
1558 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
1559 struct window *w;
1560 int hpos, vpos;
1561 int *frame_x, *frame_y;
1563 #ifdef HAVE_WINDOW_SYSTEM
1564 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1566 int success_p;
1568 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1569 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1571 if (display_completed)
1573 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1574 struct glyph *glyph = row->glyphs[TEXT_AREA];
1575 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1577 hpos = row->x;
1578 vpos = row->y;
1579 while (glyph < end)
1581 hpos += glyph->pixel_width;
1582 ++glyph;
1585 /* If first glyph is partially visible, its first visible position is still 0. */
1586 if (hpos < 0)
1587 hpos = 0;
1589 success_p = 1;
1591 else
1593 hpos = vpos = 0;
1594 success_p = 0;
1597 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1598 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1599 return success_p;
1601 #endif
1603 *frame_x = hpos;
1604 *frame_y = vpos;
1605 return 1;
1609 #ifdef HAVE_WINDOW_SYSTEM
1611 /* Find the glyph under window-relative coordinates X/Y in window W.
1612 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1613 strings. Return in *HPOS and *VPOS the row and column number of
1614 the glyph found. Return in *AREA the glyph area containing X.
1615 Value is a pointer to the glyph found or null if X/Y is not on
1616 text, or we can't tell because W's current matrix is not up to
1617 date. */
1619 static struct glyph *
1620 x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
1621 struct window *w;
1622 int x, y;
1623 int *hpos, *vpos, *dx, *dy, *area;
1625 struct glyph *glyph, *end;
1626 struct glyph_row *row = NULL;
1627 int x0, i;
1629 /* Find row containing Y. Give up if some row is not enabled. */
1630 for (i = 0; i < w->current_matrix->nrows; ++i)
1632 row = MATRIX_ROW (w->current_matrix, i);
1633 if (!row->enabled_p)
1634 return NULL;
1635 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1636 break;
1639 *vpos = i;
1640 *hpos = 0;
1642 /* Give up if Y is not in the window. */
1643 if (i == w->current_matrix->nrows)
1644 return NULL;
1646 /* Get the glyph area containing X. */
1647 if (w->pseudo_window_p)
1649 *area = TEXT_AREA;
1650 x0 = 0;
1652 else
1654 if (x < window_box_left_offset (w, TEXT_AREA))
1656 *area = LEFT_MARGIN_AREA;
1657 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1659 else if (x < window_box_right_offset (w, TEXT_AREA))
1661 *area = TEXT_AREA;
1662 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1664 else
1666 *area = RIGHT_MARGIN_AREA;
1667 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1671 /* Find glyph containing X. */
1672 glyph = row->glyphs[*area];
1673 end = glyph + row->used[*area];
1674 x -= x0;
1675 while (glyph < end && x >= glyph->pixel_width)
1677 x -= glyph->pixel_width;
1678 ++glyph;
1681 if (glyph == end)
1682 return NULL;
1684 if (dx)
1686 *dx = x;
1687 *dy = y - (row->y + row->ascent - glyph->ascent);
1690 *hpos = glyph - row->glyphs[*area];
1691 return glyph;
1695 /* EXPORT:
1696 Convert frame-relative x/y to coordinates relative to window W.
1697 Takes pseudo-windows into account. */
1699 void
1700 frame_to_window_pixel_xy (w, x, y)
1701 struct window *w;
1702 int *x, *y;
1704 if (w->pseudo_window_p)
1706 /* A pseudo-window is always full-width, and starts at the
1707 left edge of the frame, plus a frame border. */
1708 struct frame *f = XFRAME (w->frame);
1709 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1710 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1712 else
1714 *x -= WINDOW_LEFT_EDGE_X (w);
1715 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1719 /* EXPORT:
1720 Return in *R the clipping rectangle for glyph string S. */
1722 void
1723 get_glyph_string_clip_rect (s, nr)
1724 struct glyph_string *s;
1725 NativeRectangle *nr;
1727 XRectangle r;
1729 if (s->row->full_width_p)
1731 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1732 r.x = WINDOW_LEFT_EDGE_X (s->w);
1733 r.width = WINDOW_TOTAL_WIDTH (s->w);
1735 /* Unless displaying a mode or menu bar line, which are always
1736 fully visible, clip to the visible part of the row. */
1737 if (s->w->pseudo_window_p)
1738 r.height = s->row->visible_height;
1739 else
1740 r.height = s->height;
1742 else
1744 /* This is a text line that may be partially visible. */
1745 r.x = window_box_left (s->w, s->area);
1746 r.width = window_box_width (s->w, s->area);
1747 r.height = s->row->visible_height;
1750 /* If S draws overlapping rows, it's sufficient to use the top and
1751 bottom of the window for clipping because this glyph string
1752 intentionally draws over other lines. */
1753 if (s->for_overlaps_p)
1755 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1756 r.height = window_text_bottom_y (s->w) - r.y;
1758 else
1760 /* Don't use S->y for clipping because it doesn't take partially
1761 visible lines into account. For example, it can be negative for
1762 partially visible lines at the top of a window. */
1763 if (!s->row->full_width_p
1764 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1765 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1766 else
1767 r.y = max (0, s->row->y);
1769 /* If drawing a tool-bar window, draw it over the internal border
1770 at the top of the window. */
1771 if (s->w == XWINDOW (s->f->tool_bar_window))
1772 r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
1775 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1777 /* If drawing the cursor, don't let glyph draw outside its
1778 advertised boundaries. Cleartype does this under some circumstances. */
1779 if (s->hl == DRAW_CURSOR)
1781 struct glyph *glyph = s->first_glyph;
1782 int height;
1784 if (s->x > r.x)
1786 r.width -= s->x - r.x;
1787 r.x = s->x;
1789 r.width = min (r.width, glyph->pixel_width);
1791 /* Don't draw cursor glyph taller than our actual glyph. */
1792 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
1793 if (height < r.height)
1795 r.y = s->ybase + glyph->descent - height;
1796 r.height = height;
1800 #ifdef CONVERT_FROM_XRECT
1801 CONVERT_FROM_XRECT (r, *nr);
1802 #else
1803 *nr = r;
1804 #endif
1807 #endif /* HAVE_WINDOW_SYSTEM */
1810 /***********************************************************************
1811 Lisp form evaluation
1812 ***********************************************************************/
1814 /* Error handler for safe_eval and safe_call. */
1816 static Lisp_Object
1817 safe_eval_handler (arg)
1818 Lisp_Object arg;
1820 add_to_log ("Error during redisplay: %s", arg, Qnil);
1821 return Qnil;
1825 /* Evaluate SEXPR and return the result, or nil if something went
1826 wrong. Prevent redisplay during the evaluation. */
1828 Lisp_Object
1829 safe_eval (sexpr)
1830 Lisp_Object sexpr;
1832 Lisp_Object val;
1834 if (inhibit_eval_during_redisplay)
1835 val = Qnil;
1836 else
1838 int count = SPECPDL_INDEX ();
1839 struct gcpro gcpro1;
1841 GCPRO1 (sexpr);
1842 specbind (Qinhibit_redisplay, Qt);
1843 /* Use Qt to ensure debugger does not run,
1844 so there is no possibility of wanting to redisplay. */
1845 val = internal_condition_case_1 (Feval, sexpr, Qt,
1846 safe_eval_handler);
1847 UNGCPRO;
1848 val = unbind_to (count, val);
1851 return val;
1855 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
1856 Return the result, or nil if something went wrong. Prevent
1857 redisplay during the evaluation. */
1859 Lisp_Object
1860 safe_call (nargs, args)
1861 int nargs;
1862 Lisp_Object *args;
1864 Lisp_Object val;
1866 if (inhibit_eval_during_redisplay)
1867 val = Qnil;
1868 else
1870 int count = SPECPDL_INDEX ();
1871 struct gcpro gcpro1;
1873 GCPRO1 (args[0]);
1874 gcpro1.nvars = nargs;
1875 specbind (Qinhibit_redisplay, Qt);
1876 /* Use Qt to ensure debugger does not run,
1877 so there is no possibility of wanting to redisplay. */
1878 val = internal_condition_case_2 (Ffuncall, nargs, args, Qt,
1879 safe_eval_handler);
1880 UNGCPRO;
1881 val = unbind_to (count, val);
1884 return val;
1888 /* Call function FN with one argument ARG.
1889 Return the result, or nil if something went wrong. */
1891 Lisp_Object
1892 safe_call1 (fn, arg)
1893 Lisp_Object fn, arg;
1895 Lisp_Object args[2];
1896 args[0] = fn;
1897 args[1] = arg;
1898 return safe_call (2, args);
1903 /***********************************************************************
1904 Debugging
1905 ***********************************************************************/
1907 #if 0
1909 /* Define CHECK_IT to perform sanity checks on iterators.
1910 This is for debugging. It is too slow to do unconditionally. */
1912 static void
1913 check_it (it)
1914 struct it *it;
1916 if (it->method == next_element_from_string)
1918 xassert (STRINGP (it->string));
1919 xassert (IT_STRING_CHARPOS (*it) >= 0);
1921 else
1923 xassert (IT_STRING_CHARPOS (*it) < 0);
1924 if (it->method == next_element_from_buffer)
1926 /* Check that character and byte positions agree. */
1927 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
1931 if (it->dpvec)
1932 xassert (it->current.dpvec_index >= 0);
1933 else
1934 xassert (it->current.dpvec_index < 0);
1937 #define CHECK_IT(IT) check_it ((IT))
1939 #else /* not 0 */
1941 #define CHECK_IT(IT) (void) 0
1943 #endif /* not 0 */
1946 #if GLYPH_DEBUG
1948 /* Check that the window end of window W is what we expect it
1949 to be---the last row in the current matrix displaying text. */
1951 static void
1952 check_window_end (w)
1953 struct window *w;
1955 if (!MINI_WINDOW_P (w)
1956 && !NILP (w->window_end_valid))
1958 struct glyph_row *row;
1959 xassert ((row = MATRIX_ROW (w->current_matrix,
1960 XFASTINT (w->window_end_vpos)),
1961 !row->enabled_p
1962 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
1963 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
1967 #define CHECK_WINDOW_END(W) check_window_end ((W))
1969 #else /* not GLYPH_DEBUG */
1971 #define CHECK_WINDOW_END(W) (void) 0
1973 #endif /* not GLYPH_DEBUG */
1977 /***********************************************************************
1978 Iterator initialization
1979 ***********************************************************************/
1981 /* Initialize IT for displaying current_buffer in window W, starting
1982 at character position CHARPOS. CHARPOS < 0 means that no buffer
1983 position is specified which is useful when the iterator is assigned
1984 a position later. BYTEPOS is the byte position corresponding to
1985 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
1987 If ROW is not null, calls to produce_glyphs with IT as parameter
1988 will produce glyphs in that row.
1990 BASE_FACE_ID is the id of a base face to use. It must be one of
1991 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
1992 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
1993 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
1995 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
1996 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
1997 will be initialized to use the corresponding mode line glyph row of
1998 the desired matrix of W. */
2000 void
2001 init_iterator (it, w, charpos, bytepos, row, base_face_id)
2002 struct it *it;
2003 struct window *w;
2004 int charpos, bytepos;
2005 struct glyph_row *row;
2006 enum face_id base_face_id;
2008 int highlight_region_p;
2010 /* Some precondition checks. */
2011 xassert (w != NULL && it != NULL);
2012 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2013 && charpos <= ZV));
2015 /* If face attributes have been changed since the last redisplay,
2016 free realized faces now because they depend on face definitions
2017 that might have changed. Don't free faces while there might be
2018 desired matrices pending which reference these faces. */
2019 if (face_change_count && !inhibit_free_realized_faces)
2021 face_change_count = 0;
2022 free_all_realized_faces (Qnil);
2025 /* Use one of the mode line rows of W's desired matrix if
2026 appropriate. */
2027 if (row == NULL)
2029 if (base_face_id == MODE_LINE_FACE_ID
2030 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2031 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2032 else if (base_face_id == HEADER_LINE_FACE_ID)
2033 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2036 /* Clear IT. */
2037 bzero (it, sizeof *it);
2038 it->current.overlay_string_index = -1;
2039 it->current.dpvec_index = -1;
2040 it->base_face_id = base_face_id;
2041 it->string = Qnil;
2042 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2044 /* The window in which we iterate over current_buffer: */
2045 XSETWINDOW (it->window, w);
2046 it->w = w;
2047 it->f = XFRAME (w->frame);
2049 /* Extra space between lines (on window systems only). */
2050 if (base_face_id == DEFAULT_FACE_ID
2051 && FRAME_WINDOW_P (it->f))
2053 if (NATNUMP (current_buffer->extra_line_spacing))
2054 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
2055 else if (it->f->extra_line_spacing > 0)
2056 it->extra_line_spacing = it->f->extra_line_spacing;
2059 /* If realized faces have been removed, e.g. because of face
2060 attribute changes of named faces, recompute them. When running
2061 in batch mode, the face cache of Vterminal_frame is null. If
2062 we happen to get called, make a dummy face cache. */
2063 if (noninteractive && FRAME_FACE_CACHE (it->f) == NULL)
2064 init_frame_faces (it->f);
2065 if (FRAME_FACE_CACHE (it->f)->used == 0)
2066 recompute_basic_faces (it->f);
2068 /* Current value of the `space-width', and 'height' properties. */
2069 it->space_width = Qnil;
2070 it->font_height = Qnil;
2072 /* Are control characters displayed as `^C'? */
2073 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
2075 /* -1 means everything between a CR and the following line end
2076 is invisible. >0 means lines indented more than this value are
2077 invisible. */
2078 it->selective = (INTEGERP (current_buffer->selective_display)
2079 ? XFASTINT (current_buffer->selective_display)
2080 : (!NILP (current_buffer->selective_display)
2081 ? -1 : 0));
2082 it->selective_display_ellipsis_p
2083 = !NILP (current_buffer->selective_display_ellipses);
2085 /* Display table to use. */
2086 it->dp = window_display_table (w);
2088 /* Are multibyte characters enabled in current_buffer? */
2089 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2091 /* Non-zero if we should highlight the region. */
2092 highlight_region_p
2093 = (!NILP (Vtransient_mark_mode)
2094 && !NILP (current_buffer->mark_active)
2095 && XMARKER (current_buffer->mark)->buffer != 0);
2097 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2098 start and end of a visible region in window IT->w. Set both to
2099 -1 to indicate no region. */
2100 if (highlight_region_p
2101 /* Maybe highlight only in selected window. */
2102 && (/* Either show region everywhere. */
2103 highlight_nonselected_windows
2104 /* Or show region in the selected window. */
2105 || w == XWINDOW (selected_window)
2106 /* Or show the region if we are in the mini-buffer and W is
2107 the window the mini-buffer refers to. */
2108 || (MINI_WINDOW_P (XWINDOW (selected_window))
2109 && WINDOWP (minibuf_selected_window)
2110 && w == XWINDOW (minibuf_selected_window))))
2112 int charpos = marker_position (current_buffer->mark);
2113 it->region_beg_charpos = min (PT, charpos);
2114 it->region_end_charpos = max (PT, charpos);
2116 else
2117 it->region_beg_charpos = it->region_end_charpos = -1;
2119 /* Get the position at which the redisplay_end_trigger hook should
2120 be run, if it is to be run at all. */
2121 if (MARKERP (w->redisplay_end_trigger)
2122 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2123 it->redisplay_end_trigger_charpos
2124 = marker_position (w->redisplay_end_trigger);
2125 else if (INTEGERP (w->redisplay_end_trigger))
2126 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2128 /* Correct bogus values of tab_width. */
2129 it->tab_width = XINT (current_buffer->tab_width);
2130 if (it->tab_width <= 0 || it->tab_width > 1000)
2131 it->tab_width = 8;
2133 /* Are lines in the display truncated? */
2134 it->truncate_lines_p
2135 = (base_face_id != DEFAULT_FACE_ID
2136 || XINT (it->w->hscroll)
2137 || (truncate_partial_width_windows
2138 && !WINDOW_FULL_WIDTH_P (it->w))
2139 || !NILP (current_buffer->truncate_lines));
2141 /* Get dimensions of truncation and continuation glyphs. These are
2142 displayed as fringe bitmaps under X, so we don't need them for such
2143 frames. */
2144 if (!FRAME_WINDOW_P (it->f))
2146 if (it->truncate_lines_p)
2148 /* We will need the truncation glyph. */
2149 xassert (it->glyph_row == NULL);
2150 produce_special_glyphs (it, IT_TRUNCATION);
2151 it->truncation_pixel_width = it->pixel_width;
2153 else
2155 /* We will need the continuation glyph. */
2156 xassert (it->glyph_row == NULL);
2157 produce_special_glyphs (it, IT_CONTINUATION);
2158 it->continuation_pixel_width = it->pixel_width;
2161 /* Reset these values to zero because the produce_special_glyphs
2162 above has changed them. */
2163 it->pixel_width = it->ascent = it->descent = 0;
2164 it->phys_ascent = it->phys_descent = 0;
2167 /* Set this after getting the dimensions of truncation and
2168 continuation glyphs, so that we don't produce glyphs when calling
2169 produce_special_glyphs, above. */
2170 it->glyph_row = row;
2171 it->area = TEXT_AREA;
2173 /* Get the dimensions of the display area. The display area
2174 consists of the visible window area plus a horizontally scrolled
2175 part to the left of the window. All x-values are relative to the
2176 start of this total display area. */
2177 if (base_face_id != DEFAULT_FACE_ID)
2179 /* Mode lines, menu bar in terminal frames. */
2180 it->first_visible_x = 0;
2181 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2183 else
2185 it->first_visible_x
2186 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2187 it->last_visible_x = (it->first_visible_x
2188 + window_box_width (w, TEXT_AREA));
2190 /* If we truncate lines, leave room for the truncator glyph(s) at
2191 the right margin. Otherwise, leave room for the continuation
2192 glyph(s). Truncation and continuation glyphs are not inserted
2193 for window-based redisplay. */
2194 if (!FRAME_WINDOW_P (it->f))
2196 if (it->truncate_lines_p)
2197 it->last_visible_x -= it->truncation_pixel_width;
2198 else
2199 it->last_visible_x -= it->continuation_pixel_width;
2202 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2203 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2206 /* Leave room for a border glyph. */
2207 if (!FRAME_WINDOW_P (it->f)
2208 && !WINDOW_RIGHTMOST_P (it->w))
2209 it->last_visible_x -= 1;
2211 it->last_visible_y = window_text_bottom_y (w);
2213 /* For mode lines and alike, arrange for the first glyph having a
2214 left box line if the face specifies a box. */
2215 if (base_face_id != DEFAULT_FACE_ID)
2217 struct face *face;
2219 it->face_id = base_face_id;
2221 /* If we have a boxed mode line, make the first character appear
2222 with a left box line. */
2223 face = FACE_FROM_ID (it->f, base_face_id);
2224 if (face->box != FACE_NO_BOX)
2225 it->start_of_box_run_p = 1;
2228 /* If a buffer position was specified, set the iterator there,
2229 getting overlays and face properties from that position. */
2230 if (charpos >= BUF_BEG (current_buffer))
2232 it->end_charpos = ZV;
2233 it->face_id = -1;
2234 IT_CHARPOS (*it) = charpos;
2236 /* Compute byte position if not specified. */
2237 if (bytepos < charpos)
2238 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2239 else
2240 IT_BYTEPOS (*it) = bytepos;
2242 it->start = it->current;
2244 /* Compute faces etc. */
2245 reseat (it, it->current.pos, 1);
2248 CHECK_IT (it);
2252 /* Initialize IT for the display of window W with window start POS. */
2254 void
2255 start_display (it, w, pos)
2256 struct it *it;
2257 struct window *w;
2258 struct text_pos pos;
2260 struct glyph_row *row;
2261 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2263 row = w->desired_matrix->rows + first_vpos;
2264 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2265 it->first_vpos = first_vpos;
2267 if (!it->truncate_lines_p)
2269 int start_at_line_beg_p;
2270 int first_y = it->current_y;
2272 /* If window start is not at a line start, skip forward to POS to
2273 get the correct continuation lines width. */
2274 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2275 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2276 if (!start_at_line_beg_p)
2278 int new_x;
2280 reseat_at_previous_visible_line_start (it);
2281 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2283 new_x = it->current_x + it->pixel_width;
2285 /* If lines are continued, this line may end in the middle
2286 of a multi-glyph character (e.g. a control character
2287 displayed as \003, or in the middle of an overlay
2288 string). In this case move_it_to above will not have
2289 taken us to the start of the continuation line but to the
2290 end of the continued line. */
2291 if (it->current_x > 0
2292 && !it->truncate_lines_p /* Lines are continued. */
2293 && (/* And glyph doesn't fit on the line. */
2294 new_x > it->last_visible_x
2295 /* Or it fits exactly and we're on a window
2296 system frame. */
2297 || (new_x == it->last_visible_x
2298 && FRAME_WINDOW_P (it->f))))
2300 if (it->current.dpvec_index >= 0
2301 || it->current.overlay_string_index >= 0)
2303 set_iterator_to_next (it, 1);
2304 move_it_in_display_line_to (it, -1, -1, 0);
2307 it->continuation_lines_width += it->current_x;
2310 /* We're starting a new display line, not affected by the
2311 height of the continued line, so clear the appropriate
2312 fields in the iterator structure. */
2313 it->max_ascent = it->max_descent = 0;
2314 it->max_phys_ascent = it->max_phys_descent = 0;
2316 it->current_y = first_y;
2317 it->vpos = 0;
2318 it->current_x = it->hpos = 0;
2322 #if 0 /* Don't assert the following because start_display is sometimes
2323 called intentionally with a window start that is not at a
2324 line start. Please leave this code in as a comment. */
2326 /* Window start should be on a line start, now. */
2327 xassert (it->continuation_lines_width
2328 || IT_CHARPOS (it) == BEGV
2329 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
2330 #endif /* 0 */
2334 /* Return 1 if POS is a position in ellipses displayed for invisible
2335 text. W is the window we display, for text property lookup. */
2337 static int
2338 in_ellipses_for_invisible_text_p (pos, w)
2339 struct display_pos *pos;
2340 struct window *w;
2342 Lisp_Object prop, window;
2343 int ellipses_p = 0;
2344 int charpos = CHARPOS (pos->pos);
2346 /* If POS specifies a position in a display vector, this might
2347 be for an ellipsis displayed for invisible text. We won't
2348 get the iterator set up for delivering that ellipsis unless
2349 we make sure that it gets aware of the invisible text. */
2350 if (pos->dpvec_index >= 0
2351 && pos->overlay_string_index < 0
2352 && CHARPOS (pos->string_pos) < 0
2353 && charpos > BEGV
2354 && (XSETWINDOW (window, w),
2355 prop = Fget_char_property (make_number (charpos),
2356 Qinvisible, window),
2357 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2359 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2360 window);
2361 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2364 return ellipses_p;
2368 /* Initialize IT for stepping through current_buffer in window W,
2369 starting at position POS that includes overlay string and display
2370 vector/ control character translation position information. Value
2371 is zero if there are overlay strings with newlines at POS. */
2373 static int
2374 init_from_display_pos (it, w, pos)
2375 struct it *it;
2376 struct window *w;
2377 struct display_pos *pos;
2379 int charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2380 int i, overlay_strings_with_newlines = 0;
2382 /* If POS specifies a position in a display vector, this might
2383 be for an ellipsis displayed for invisible text. We won't
2384 get the iterator set up for delivering that ellipsis unless
2385 we make sure that it gets aware of the invisible text. */
2386 if (in_ellipses_for_invisible_text_p (pos, w))
2388 --charpos;
2389 bytepos = 0;
2392 /* Keep in mind: the call to reseat in init_iterator skips invisible
2393 text, so we might end up at a position different from POS. This
2394 is only a problem when POS is a row start after a newline and an
2395 overlay starts there with an after-string, and the overlay has an
2396 invisible property. Since we don't skip invisible text in
2397 display_line and elsewhere immediately after consuming the
2398 newline before the row start, such a POS will not be in a string,
2399 but the call to init_iterator below will move us to the
2400 after-string. */
2401 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2403 for (i = 0; i < it->n_overlay_strings; ++i)
2405 const char *s = SDATA (it->overlay_strings[i]);
2406 const char *e = s + SBYTES (it->overlay_strings[i]);
2408 while (s < e && *s != '\n')
2409 ++s;
2411 if (s < e)
2413 overlay_strings_with_newlines = 1;
2414 break;
2418 /* If position is within an overlay string, set up IT to the right
2419 overlay string. */
2420 if (pos->overlay_string_index >= 0)
2422 int relative_index;
2424 /* If the first overlay string happens to have a `display'
2425 property for an image, the iterator will be set up for that
2426 image, and we have to undo that setup first before we can
2427 correct the overlay string index. */
2428 if (it->method == next_element_from_image)
2429 pop_it (it);
2431 /* We already have the first chunk of overlay strings in
2432 IT->overlay_strings. Load more until the one for
2433 pos->overlay_string_index is in IT->overlay_strings. */
2434 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
2436 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
2437 it->current.overlay_string_index = 0;
2438 while (n--)
2440 load_overlay_strings (it, 0);
2441 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
2445 it->current.overlay_string_index = pos->overlay_string_index;
2446 relative_index = (it->current.overlay_string_index
2447 % OVERLAY_STRING_CHUNK_SIZE);
2448 it->string = it->overlay_strings[relative_index];
2449 xassert (STRINGP (it->string));
2450 it->current.string_pos = pos->string_pos;
2451 it->method = next_element_from_string;
2454 #if 0 /* This is bogus because POS not having an overlay string
2455 position does not mean it's after the string. Example: A
2456 line starting with a before-string and initialization of IT
2457 to the previous row's end position. */
2458 else if (it->current.overlay_string_index >= 0)
2460 /* If POS says we're already after an overlay string ending at
2461 POS, make sure to pop the iterator because it will be in
2462 front of that overlay string. When POS is ZV, we've thereby
2463 also ``processed'' overlay strings at ZV. */
2464 while (it->sp)
2465 pop_it (it);
2466 it->current.overlay_string_index = -1;
2467 it->method = next_element_from_buffer;
2468 if (CHARPOS (pos->pos) == ZV)
2469 it->overlay_strings_at_end_processed_p = 1;
2471 #endif /* 0 */
2473 if (CHARPOS (pos->string_pos) >= 0)
2475 /* Recorded position is not in an overlay string, but in another
2476 string. This can only be a string from a `display' property.
2477 IT should already be filled with that string. */
2478 it->current.string_pos = pos->string_pos;
2479 xassert (STRINGP (it->string));
2482 /* Restore position in display vector translations, control
2483 character translations or ellipses. */
2484 if (pos->dpvec_index >= 0)
2486 if (it->dpvec == NULL)
2487 get_next_display_element (it);
2488 xassert (it->dpvec && it->current.dpvec_index == 0);
2489 it->current.dpvec_index = pos->dpvec_index;
2492 CHECK_IT (it);
2493 return !overlay_strings_with_newlines;
2497 /* Initialize IT for stepping through current_buffer in window W
2498 starting at ROW->start. */
2500 static void
2501 init_to_row_start (it, w, row)
2502 struct it *it;
2503 struct window *w;
2504 struct glyph_row *row;
2506 init_from_display_pos (it, w, &row->start);
2507 it->start = row->start;
2508 it->continuation_lines_width = row->continuation_lines_width;
2509 CHECK_IT (it);
2513 /* Initialize IT for stepping through current_buffer in window W
2514 starting in the line following ROW, i.e. starting at ROW->end.
2515 Value is zero if there are overlay strings with newlines at ROW's
2516 end position. */
2518 static int
2519 init_to_row_end (it, w, row)
2520 struct it *it;
2521 struct window *w;
2522 struct glyph_row *row;
2524 int success = 0;
2526 if (init_from_display_pos (it, w, &row->end))
2528 if (row->continued_p)
2529 it->continuation_lines_width
2530 = row->continuation_lines_width + row->pixel_width;
2531 CHECK_IT (it);
2532 success = 1;
2535 return success;
2541 /***********************************************************************
2542 Text properties
2543 ***********************************************************************/
2545 /* Called when IT reaches IT->stop_charpos. Handle text property and
2546 overlay changes. Set IT->stop_charpos to the next position where
2547 to stop. */
2549 static void
2550 handle_stop (it)
2551 struct it *it;
2553 enum prop_handled handled;
2554 int handle_overlay_change_p = 1;
2555 struct props *p;
2557 it->dpvec = NULL;
2558 it->current.dpvec_index = -1;
2562 handled = HANDLED_NORMALLY;
2564 /* Call text property handlers. */
2565 for (p = it_props; p->handler; ++p)
2567 handled = p->handler (it);
2569 if (handled == HANDLED_RECOMPUTE_PROPS)
2570 break;
2571 else if (handled == HANDLED_RETURN)
2572 return;
2573 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
2574 handle_overlay_change_p = 0;
2577 if (handled != HANDLED_RECOMPUTE_PROPS)
2579 /* Don't check for overlay strings below when set to deliver
2580 characters from a display vector. */
2581 if (it->method == next_element_from_display_vector)
2582 handle_overlay_change_p = 0;
2584 /* Handle overlay changes. */
2585 if (handle_overlay_change_p)
2586 handled = handle_overlay_change (it);
2588 /* Determine where to stop next. */
2589 if (handled == HANDLED_NORMALLY)
2590 compute_stop_pos (it);
2593 while (handled == HANDLED_RECOMPUTE_PROPS);
2597 /* Compute IT->stop_charpos from text property and overlay change
2598 information for IT's current position. */
2600 static void
2601 compute_stop_pos (it)
2602 struct it *it;
2604 register INTERVAL iv, next_iv;
2605 Lisp_Object object, limit, position;
2607 /* If nowhere else, stop at the end. */
2608 it->stop_charpos = it->end_charpos;
2610 if (STRINGP (it->string))
2612 /* Strings are usually short, so don't limit the search for
2613 properties. */
2614 object = it->string;
2615 limit = Qnil;
2616 position = make_number (IT_STRING_CHARPOS (*it));
2618 else
2620 int charpos;
2622 /* If next overlay change is in front of the current stop pos
2623 (which is IT->end_charpos), stop there. Note: value of
2624 next_overlay_change is point-max if no overlay change
2625 follows. */
2626 charpos = next_overlay_change (IT_CHARPOS (*it));
2627 if (charpos < it->stop_charpos)
2628 it->stop_charpos = charpos;
2630 /* If showing the region, we have to stop at the region
2631 start or end because the face might change there. */
2632 if (it->region_beg_charpos > 0)
2634 if (IT_CHARPOS (*it) < it->region_beg_charpos)
2635 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
2636 else if (IT_CHARPOS (*it) < it->region_end_charpos)
2637 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
2640 /* Set up variables for computing the stop position from text
2641 property changes. */
2642 XSETBUFFER (object, current_buffer);
2643 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
2644 position = make_number (IT_CHARPOS (*it));
2648 /* Get the interval containing IT's position. Value is a null
2649 interval if there isn't such an interval. */
2650 iv = validate_interval_range (object, &position, &position, 0);
2651 if (!NULL_INTERVAL_P (iv))
2653 Lisp_Object values_here[LAST_PROP_IDX];
2654 struct props *p;
2656 /* Get properties here. */
2657 for (p = it_props; p->handler; ++p)
2658 values_here[p->idx] = textget (iv->plist, *p->name);
2660 /* Look for an interval following iv that has different
2661 properties. */
2662 for (next_iv = next_interval (iv);
2663 (!NULL_INTERVAL_P (next_iv)
2664 && (NILP (limit)
2665 || XFASTINT (limit) > next_iv->position));
2666 next_iv = next_interval (next_iv))
2668 for (p = it_props; p->handler; ++p)
2670 Lisp_Object new_value;
2672 new_value = textget (next_iv->plist, *p->name);
2673 if (!EQ (values_here[p->idx], new_value))
2674 break;
2677 if (p->handler)
2678 break;
2681 if (!NULL_INTERVAL_P (next_iv))
2683 if (INTEGERP (limit)
2684 && next_iv->position >= XFASTINT (limit))
2685 /* No text property change up to limit. */
2686 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
2687 else
2688 /* Text properties change in next_iv. */
2689 it->stop_charpos = min (it->stop_charpos, next_iv->position);
2693 xassert (STRINGP (it->string)
2694 || (it->stop_charpos >= BEGV
2695 && it->stop_charpos >= IT_CHARPOS (*it)));
2699 /* Return the position of the next overlay change after POS in
2700 current_buffer. Value is point-max if no overlay change
2701 follows. This is like `next-overlay-change' but doesn't use
2702 xmalloc. */
2704 static int
2705 next_overlay_change (pos)
2706 int pos;
2708 int noverlays;
2709 int endpos;
2710 Lisp_Object *overlays;
2711 int len;
2712 int i;
2714 /* Get all overlays at the given position. */
2715 len = 10;
2716 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
2717 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL, 1);
2718 if (noverlays > len)
2720 len = noverlays;
2721 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
2722 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL, 1);
2725 /* If any of these overlays ends before endpos,
2726 use its ending point instead. */
2727 for (i = 0; i < noverlays; ++i)
2729 Lisp_Object oend;
2730 int oendpos;
2732 oend = OVERLAY_END (overlays[i]);
2733 oendpos = OVERLAY_POSITION (oend);
2734 endpos = min (endpos, oendpos);
2737 return endpos;
2742 /***********************************************************************
2743 Fontification
2744 ***********************************************************************/
2746 /* Handle changes in the `fontified' property of the current buffer by
2747 calling hook functions from Qfontification_functions to fontify
2748 regions of text. */
2750 static enum prop_handled
2751 handle_fontified_prop (it)
2752 struct it *it;
2754 Lisp_Object prop, pos;
2755 enum prop_handled handled = HANDLED_NORMALLY;
2757 /* Get the value of the `fontified' property at IT's current buffer
2758 position. (The `fontified' property doesn't have a special
2759 meaning in strings.) If the value is nil, call functions from
2760 Qfontification_functions. */
2761 if (!STRINGP (it->string)
2762 && it->s == NULL
2763 && !NILP (Vfontification_functions)
2764 && !NILP (Vrun_hooks)
2765 && (pos = make_number (IT_CHARPOS (*it)),
2766 prop = Fget_char_property (pos, Qfontified, Qnil),
2767 NILP (prop)))
2769 int count = SPECPDL_INDEX ();
2770 Lisp_Object val;
2772 val = Vfontification_functions;
2773 specbind (Qfontification_functions, Qnil);
2775 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
2776 safe_call1 (val, pos);
2777 else
2779 Lisp_Object globals, fn;
2780 struct gcpro gcpro1, gcpro2;
2782 globals = Qnil;
2783 GCPRO2 (val, globals);
2785 for (; CONSP (val); val = XCDR (val))
2787 fn = XCAR (val);
2789 if (EQ (fn, Qt))
2791 /* A value of t indicates this hook has a local
2792 binding; it means to run the global binding too.
2793 In a global value, t should not occur. If it
2794 does, we must ignore it to avoid an endless
2795 loop. */
2796 for (globals = Fdefault_value (Qfontification_functions);
2797 CONSP (globals);
2798 globals = XCDR (globals))
2800 fn = XCAR (globals);
2801 if (!EQ (fn, Qt))
2802 safe_call1 (fn, pos);
2805 else
2806 safe_call1 (fn, pos);
2809 UNGCPRO;
2812 unbind_to (count, Qnil);
2814 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
2815 something. This avoids an endless loop if they failed to
2816 fontify the text for which reason ever. */
2817 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
2818 handled = HANDLED_RECOMPUTE_PROPS;
2821 return handled;
2826 /***********************************************************************
2827 Faces
2828 ***********************************************************************/
2830 /* Set up iterator IT from face properties at its current position.
2831 Called from handle_stop. */
2833 static enum prop_handled
2834 handle_face_prop (it)
2835 struct it *it;
2837 int new_face_id, next_stop;
2839 if (!STRINGP (it->string))
2841 new_face_id
2842 = face_at_buffer_position (it->w,
2843 IT_CHARPOS (*it),
2844 it->region_beg_charpos,
2845 it->region_end_charpos,
2846 &next_stop,
2847 (IT_CHARPOS (*it)
2848 + TEXT_PROP_DISTANCE_LIMIT),
2851 /* Is this a start of a run of characters with box face?
2852 Caveat: this can be called for a freshly initialized
2853 iterator; face_id is -1 in this case. We know that the new
2854 face will not change until limit, i.e. if the new face has a
2855 box, all characters up to limit will have one. But, as
2856 usual, we don't know whether limit is really the end. */
2857 if (new_face_id != it->face_id)
2859 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2861 /* If new face has a box but old face has not, this is
2862 the start of a run of characters with box, i.e. it has
2863 a shadow on the left side. The value of face_id of the
2864 iterator will be -1 if this is the initial call that gets
2865 the face. In this case, we have to look in front of IT's
2866 position and see whether there is a face != new_face_id. */
2867 it->start_of_box_run_p
2868 = (new_face->box != FACE_NO_BOX
2869 && (it->face_id >= 0
2870 || IT_CHARPOS (*it) == BEG
2871 || new_face_id != face_before_it_pos (it)));
2872 it->face_box_p = new_face->box != FACE_NO_BOX;
2875 else
2877 int base_face_id, bufpos;
2879 if (it->current.overlay_string_index >= 0)
2880 bufpos = IT_CHARPOS (*it);
2881 else
2882 bufpos = 0;
2884 /* For strings from a buffer, i.e. overlay strings or strings
2885 from a `display' property, use the face at IT's current
2886 buffer position as the base face to merge with, so that
2887 overlay strings appear in the same face as surrounding
2888 text, unless they specify their own faces. */
2889 base_face_id = underlying_face_id (it);
2891 new_face_id = face_at_string_position (it->w,
2892 it->string,
2893 IT_STRING_CHARPOS (*it),
2894 bufpos,
2895 it->region_beg_charpos,
2896 it->region_end_charpos,
2897 &next_stop,
2898 base_face_id, 0);
2900 #if 0 /* This shouldn't be neccessary. Let's check it. */
2901 /* If IT is used to display a mode line we would really like to
2902 use the mode line face instead of the frame's default face. */
2903 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
2904 && new_face_id == DEFAULT_FACE_ID)
2905 new_face_id = CURRENT_MODE_LINE_FACE_ID (it->w);
2906 #endif
2908 /* Is this a start of a run of characters with box? Caveat:
2909 this can be called for a freshly allocated iterator; face_id
2910 is -1 is this case. We know that the new face will not
2911 change until the next check pos, i.e. if the new face has a
2912 box, all characters up to that position will have a
2913 box. But, as usual, we don't know whether that position
2914 is really the end. */
2915 if (new_face_id != it->face_id)
2917 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2918 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
2920 /* If new face has a box but old face hasn't, this is the
2921 start of a run of characters with box, i.e. it has a
2922 shadow on the left side. */
2923 it->start_of_box_run_p
2924 = new_face->box && (old_face == NULL || !old_face->box);
2925 it->face_box_p = new_face->box != FACE_NO_BOX;
2929 it->face_id = new_face_id;
2930 return HANDLED_NORMALLY;
2934 /* Return the ID of the face ``underlying'' IT's current position,
2935 which is in a string. If the iterator is associated with a
2936 buffer, return the face at IT's current buffer position.
2937 Otherwise, use the iterator's base_face_id. */
2939 static int
2940 underlying_face_id (it)
2941 struct it *it;
2943 int face_id = it->base_face_id, i;
2945 xassert (STRINGP (it->string));
2947 for (i = it->sp - 1; i >= 0; --i)
2948 if (NILP (it->stack[i].string))
2949 face_id = it->stack[i].face_id;
2951 return face_id;
2955 /* Compute the face one character before or after the current position
2956 of IT. BEFORE_P non-zero means get the face in front of IT's
2957 position. Value is the id of the face. */
2959 static int
2960 face_before_or_after_it_pos (it, before_p)
2961 struct it *it;
2962 int before_p;
2964 int face_id, limit;
2965 int next_check_charpos;
2966 struct text_pos pos;
2968 xassert (it->s == NULL);
2970 if (STRINGP (it->string))
2972 int bufpos, base_face_id;
2974 /* No face change past the end of the string (for the case
2975 we are padding with spaces). No face change before the
2976 string start. */
2977 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
2978 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
2979 return it->face_id;
2981 /* Set pos to the position before or after IT's current position. */
2982 if (before_p)
2983 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
2984 else
2985 /* For composition, we must check the character after the
2986 composition. */
2987 pos = (it->what == IT_COMPOSITION
2988 ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string)
2989 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
2991 if (it->current.overlay_string_index >= 0)
2992 bufpos = IT_CHARPOS (*it);
2993 else
2994 bufpos = 0;
2996 base_face_id = underlying_face_id (it);
2998 /* Get the face for ASCII, or unibyte. */
2999 face_id = face_at_string_position (it->w,
3000 it->string,
3001 CHARPOS (pos),
3002 bufpos,
3003 it->region_beg_charpos,
3004 it->region_end_charpos,
3005 &next_check_charpos,
3006 base_face_id, 0);
3008 /* Correct the face for charsets different from ASCII. Do it
3009 for the multibyte case only. The face returned above is
3010 suitable for unibyte text if IT->string is unibyte. */
3011 if (STRING_MULTIBYTE (it->string))
3013 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
3014 int rest = SBYTES (it->string) - BYTEPOS (pos);
3015 int c, len;
3016 struct face *face = FACE_FROM_ID (it->f, face_id);
3018 c = string_char_and_length (p, rest, &len);
3019 face_id = FACE_FOR_CHAR (it->f, face, c);
3022 else
3024 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3025 || (IT_CHARPOS (*it) <= BEGV && before_p))
3026 return it->face_id;
3028 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3029 pos = it->current.pos;
3031 if (before_p)
3032 DEC_TEXT_POS (pos, it->multibyte_p);
3033 else
3035 if (it->what == IT_COMPOSITION)
3036 /* For composition, we must check the position after the
3037 composition. */
3038 pos.charpos += it->cmp_len, pos.bytepos += it->len;
3039 else
3040 INC_TEXT_POS (pos, it->multibyte_p);
3043 /* Determine face for CHARSET_ASCII, or unibyte. */
3044 face_id = face_at_buffer_position (it->w,
3045 CHARPOS (pos),
3046 it->region_beg_charpos,
3047 it->region_end_charpos,
3048 &next_check_charpos,
3049 limit, 0);
3051 /* Correct the face for charsets different from ASCII. Do it
3052 for the multibyte case only. The face returned above is
3053 suitable for unibyte text if current_buffer is unibyte. */
3054 if (it->multibyte_p)
3056 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3057 struct face *face = FACE_FROM_ID (it->f, face_id);
3058 face_id = FACE_FOR_CHAR (it->f, face, c);
3062 return face_id;
3067 /***********************************************************************
3068 Invisible text
3069 ***********************************************************************/
3071 /* Set up iterator IT from invisible properties at its current
3072 position. Called from handle_stop. */
3074 static enum prop_handled
3075 handle_invisible_prop (it)
3076 struct it *it;
3078 enum prop_handled handled = HANDLED_NORMALLY;
3080 if (STRINGP (it->string))
3082 extern Lisp_Object Qinvisible;
3083 Lisp_Object prop, end_charpos, limit, charpos;
3085 /* Get the value of the invisible text property at the
3086 current position. Value will be nil if there is no such
3087 property. */
3088 charpos = make_number (IT_STRING_CHARPOS (*it));
3089 prop = Fget_text_property (charpos, Qinvisible, it->string);
3091 if (!NILP (prop)
3092 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3094 handled = HANDLED_RECOMPUTE_PROPS;
3096 /* Get the position at which the next change of the
3097 invisible text property can be found in IT->string.
3098 Value will be nil if the property value is the same for
3099 all the rest of IT->string. */
3100 XSETINT (limit, SCHARS (it->string));
3101 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3102 it->string, limit);
3104 /* Text at current position is invisible. The next
3105 change in the property is at position end_charpos.
3106 Move IT's current position to that position. */
3107 if (INTEGERP (end_charpos)
3108 && XFASTINT (end_charpos) < XFASTINT (limit))
3110 struct text_pos old;
3111 old = it->current.string_pos;
3112 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3113 compute_string_pos (&it->current.string_pos, old, it->string);
3115 else
3117 /* The rest of the string is invisible. If this is an
3118 overlay string, proceed with the next overlay string
3119 or whatever comes and return a character from there. */
3120 if (it->current.overlay_string_index >= 0)
3122 next_overlay_string (it);
3123 /* Don't check for overlay strings when we just
3124 finished processing them. */
3125 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3127 else
3129 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3130 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3135 else
3137 int invis_p, newpos, next_stop, start_charpos;
3138 Lisp_Object pos, prop, overlay;
3140 /* First of all, is there invisible text at this position? */
3141 start_charpos = IT_CHARPOS (*it);
3142 pos = make_number (IT_CHARPOS (*it));
3143 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3144 &overlay);
3145 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3147 /* If we are on invisible text, skip over it. */
3148 if (invis_p && IT_CHARPOS (*it) < it->end_charpos)
3150 /* Record whether we have to display an ellipsis for the
3151 invisible text. */
3152 int display_ellipsis_p = invis_p == 2;
3154 handled = HANDLED_RECOMPUTE_PROPS;
3156 /* Loop skipping over invisible text. The loop is left at
3157 ZV or with IT on the first char being visible again. */
3160 /* Try to skip some invisible text. Return value is the
3161 position reached which can be equal to IT's position
3162 if there is nothing invisible here. This skips both
3163 over invisible text properties and overlays with
3164 invisible property. */
3165 newpos = skip_invisible (IT_CHARPOS (*it),
3166 &next_stop, ZV, it->window);
3168 /* If we skipped nothing at all we weren't at invisible
3169 text in the first place. If everything to the end of
3170 the buffer was skipped, end the loop. */
3171 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
3172 invis_p = 0;
3173 else
3175 /* We skipped some characters but not necessarily
3176 all there are. Check if we ended up on visible
3177 text. Fget_char_property returns the property of
3178 the char before the given position, i.e. if we
3179 get invis_p = 0, this means that the char at
3180 newpos is visible. */
3181 pos = make_number (newpos);
3182 prop = Fget_char_property (pos, Qinvisible, it->window);
3183 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3186 /* If we ended up on invisible text, proceed to
3187 skip starting with next_stop. */
3188 if (invis_p)
3189 IT_CHARPOS (*it) = next_stop;
3191 while (invis_p);
3193 /* The position newpos is now either ZV or on visible text. */
3194 IT_CHARPOS (*it) = newpos;
3195 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3197 /* If there are before-strings at the start of invisible
3198 text, and the text is invisible because of a text
3199 property, arrange to show before-strings because 20.x did
3200 it that way. (If the text is invisible because of an
3201 overlay property instead of a text property, this is
3202 already handled in the overlay code.) */
3203 if (NILP (overlay)
3204 && get_overlay_strings (it, start_charpos))
3206 handled = HANDLED_RECOMPUTE_PROPS;
3207 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3209 else if (display_ellipsis_p)
3210 setup_for_ellipsis (it);
3214 return handled;
3218 /* Make iterator IT return `...' next. */
3220 static void
3221 setup_for_ellipsis (it)
3222 struct it *it;
3224 if (it->dp
3225 && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3227 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3228 it->dpvec = v->contents;
3229 it->dpend = v->contents + v->size;
3231 else
3233 /* Default `...'. */
3234 it->dpvec = default_invis_vector;
3235 it->dpend = default_invis_vector + 3;
3238 /* The ellipsis display does not replace the display of the
3239 character at the new position. Indicate this by setting
3240 IT->dpvec_char_len to zero. */
3241 it->dpvec_char_len = 0;
3243 it->current.dpvec_index = 0;
3244 it->method = next_element_from_display_vector;
3249 /***********************************************************************
3250 'display' property
3251 ***********************************************************************/
3253 /* Set up iterator IT from `display' property at its current position.
3254 Called from handle_stop. */
3256 static enum prop_handled
3257 handle_display_prop (it)
3258 struct it *it;
3260 Lisp_Object prop, object;
3261 struct text_pos *position;
3262 int display_replaced_p = 0;
3264 if (STRINGP (it->string))
3266 object = it->string;
3267 position = &it->current.string_pos;
3269 else
3271 object = it->w->buffer;
3272 position = &it->current.pos;
3275 /* Reset those iterator values set from display property values. */
3276 it->font_height = Qnil;
3277 it->space_width = Qnil;
3278 it->voffset = 0;
3280 /* We don't support recursive `display' properties, i.e. string
3281 values that have a string `display' property, that have a string
3282 `display' property etc. */
3283 if (!it->string_from_display_prop_p)
3284 it->area = TEXT_AREA;
3286 prop = Fget_char_property (make_number (position->charpos),
3287 Qdisplay, object);
3288 if (NILP (prop))
3289 return HANDLED_NORMALLY;
3291 if (CONSP (prop)
3292 /* Simple properties. */
3293 && !EQ (XCAR (prop), Qimage)
3294 && !EQ (XCAR (prop), Qspace)
3295 && !EQ (XCAR (prop), Qwhen)
3296 && !EQ (XCAR (prop), Qspace_width)
3297 && !EQ (XCAR (prop), Qheight)
3298 && !EQ (XCAR (prop), Qraise)
3299 /* Marginal area specifications. */
3300 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
3301 && !EQ (XCAR (prop), Qleft_fringe)
3302 && !EQ (XCAR (prop), Qright_fringe)
3303 && !NILP (XCAR (prop)))
3305 for (; CONSP (prop); prop = XCDR (prop))
3307 if (handle_single_display_prop (it, XCAR (prop), object,
3308 position, display_replaced_p))
3309 display_replaced_p = 1;
3312 else if (VECTORP (prop))
3314 int i;
3315 for (i = 0; i < ASIZE (prop); ++i)
3316 if (handle_single_display_prop (it, AREF (prop, i), object,
3317 position, display_replaced_p))
3318 display_replaced_p = 1;
3320 else
3322 if (handle_single_display_prop (it, prop, object, position, 0))
3323 display_replaced_p = 1;
3326 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
3330 /* Value is the position of the end of the `display' property starting
3331 at START_POS in OBJECT. */
3333 static struct text_pos
3334 display_prop_end (it, object, start_pos)
3335 struct it *it;
3336 Lisp_Object object;
3337 struct text_pos start_pos;
3339 Lisp_Object end;
3340 struct text_pos end_pos;
3342 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
3343 Qdisplay, object, Qnil);
3344 CHARPOS (end_pos) = XFASTINT (end);
3345 if (STRINGP (object))
3346 compute_string_pos (&end_pos, start_pos, it->string);
3347 else
3348 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
3350 return end_pos;
3354 /* Set up IT from a single `display' sub-property value PROP. OBJECT
3355 is the object in which the `display' property was found. *POSITION
3356 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3357 means that we previously saw a display sub-property which already
3358 replaced text display with something else, for example an image;
3359 ignore such properties after the first one has been processed.
3361 If PROP is a `space' or `image' sub-property, set *POSITION to the
3362 end position of the `display' property.
3364 Value is non-zero if something was found which replaces the display
3365 of buffer or string text. */
3367 static int
3368 handle_single_display_prop (it, prop, object, position,
3369 display_replaced_before_p)
3370 struct it *it;
3371 Lisp_Object prop;
3372 Lisp_Object object;
3373 struct text_pos *position;
3374 int display_replaced_before_p;
3376 Lisp_Object value;
3377 int replaces_text_display_p = 0;
3378 Lisp_Object form;
3380 /* If PROP is a list of the form `(when FORM . VALUE)', FORM is
3381 evaluated. If the result is nil, VALUE is ignored. */
3382 form = Qt;
3383 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3385 prop = XCDR (prop);
3386 if (!CONSP (prop))
3387 return 0;
3388 form = XCAR (prop);
3389 prop = XCDR (prop);
3392 if (!NILP (form) && !EQ (form, Qt))
3394 int count = SPECPDL_INDEX ();
3395 struct gcpro gcpro1;
3397 /* Bind `object' to the object having the `display' property, a
3398 buffer or string. Bind `position' to the position in the
3399 object where the property was found, and `buffer-position'
3400 to the current position in the buffer. */
3401 specbind (Qobject, object);
3402 specbind (Qposition, make_number (CHARPOS (*position)));
3403 specbind (Qbuffer_position,
3404 make_number (STRINGP (object)
3405 ? IT_CHARPOS (*it) : CHARPOS (*position)));
3406 GCPRO1 (form);
3407 form = safe_eval (form);
3408 UNGCPRO;
3409 unbind_to (count, Qnil);
3412 if (NILP (form))
3413 return 0;
3415 if (CONSP (prop)
3416 && EQ (XCAR (prop), Qheight)
3417 && CONSP (XCDR (prop)))
3419 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3420 return 0;
3422 /* `(height HEIGHT)'. */
3423 it->font_height = XCAR (XCDR (prop));
3424 if (!NILP (it->font_height))
3426 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3427 int new_height = -1;
3429 if (CONSP (it->font_height)
3430 && (EQ (XCAR (it->font_height), Qplus)
3431 || EQ (XCAR (it->font_height), Qminus))
3432 && CONSP (XCDR (it->font_height))
3433 && INTEGERP (XCAR (XCDR (it->font_height))))
3435 /* `(+ N)' or `(- N)' where N is an integer. */
3436 int steps = XINT (XCAR (XCDR (it->font_height)));
3437 if (EQ (XCAR (it->font_height), Qplus))
3438 steps = - steps;
3439 it->face_id = smaller_face (it->f, it->face_id, steps);
3441 else if (FUNCTIONP (it->font_height))
3443 /* Call function with current height as argument.
3444 Value is the new height. */
3445 Lisp_Object height;
3446 height = safe_call1 (it->font_height,
3447 face->lface[LFACE_HEIGHT_INDEX]);
3448 if (NUMBERP (height))
3449 new_height = XFLOATINT (height);
3451 else if (NUMBERP (it->font_height))
3453 /* Value is a multiple of the canonical char height. */
3454 struct face *face;
3456 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
3457 new_height = (XFLOATINT (it->font_height)
3458 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
3460 else
3462 /* Evaluate IT->font_height with `height' bound to the
3463 current specified height to get the new height. */
3464 Lisp_Object value;
3465 int count = SPECPDL_INDEX ();
3467 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
3468 value = safe_eval (it->font_height);
3469 unbind_to (count, Qnil);
3471 if (NUMBERP (value))
3472 new_height = XFLOATINT (value);
3475 if (new_height > 0)
3476 it->face_id = face_with_height (it->f, it->face_id, new_height);
3479 else if (CONSP (prop)
3480 && EQ (XCAR (prop), Qspace_width)
3481 && CONSP (XCDR (prop)))
3483 /* `(space_width WIDTH)'. */
3484 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3485 return 0;
3487 value = XCAR (XCDR (prop));
3488 if (NUMBERP (value) && XFLOATINT (value) > 0)
3489 it->space_width = value;
3491 else if (CONSP (prop)
3492 && EQ (XCAR (prop), Qraise)
3493 && CONSP (XCDR (prop)))
3495 /* `(raise FACTOR)'. */
3496 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3497 return 0;
3499 #ifdef HAVE_WINDOW_SYSTEM
3500 value = XCAR (XCDR (prop));
3501 if (NUMBERP (value))
3503 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3504 it->voffset = - (XFLOATINT (value)
3505 * (FONT_HEIGHT (face->font)));
3507 #endif /* HAVE_WINDOW_SYSTEM */
3509 else if (!it->string_from_display_prop_p)
3511 /* `((margin left-margin) VALUE)' or `((margin right-margin)
3512 VALUE) or `((margin nil) VALUE)' or VALUE. */
3513 Lisp_Object location, value;
3514 struct text_pos start_pos;
3515 int valid_p;
3517 /* Characters having this form of property are not displayed, so
3518 we have to find the end of the property. */
3519 start_pos = *position;
3520 *position = display_prop_end (it, object, start_pos);
3521 value = Qnil;
3523 /* Let's stop at the new position and assume that all
3524 text properties change there. */
3525 it->stop_charpos = position->charpos;
3527 if (CONSP (prop)
3528 && (EQ (XCAR (prop), Qleft_fringe)
3529 || EQ (XCAR (prop), Qright_fringe))
3530 && CONSP (XCDR (prop)))
3532 unsigned face_id = DEFAULT_FACE_ID;
3534 /* Save current settings of IT so that we can restore them
3535 when we are finished with the glyph property value. */
3537 /* `(left-fringe BITMAP FACE)'. */
3538 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3539 return 0;
3541 #ifdef HAVE_WINDOW_SYSTEM
3542 value = XCAR (XCDR (prop));
3543 if (!NUMBERP (value)
3544 || !valid_fringe_bitmap_id_p (XINT (value)))
3545 return 0;
3547 if (CONSP (XCDR (XCDR (prop))))
3549 Lisp_Object face_name = XCAR (XCDR (XCDR (prop)));
3551 face_id = lookup_named_face (it->f, face_name, 'A');
3552 if (face_id < 0)
3553 return 0;
3556 push_it (it);
3558 it->area = TEXT_AREA;
3559 it->what = IT_IMAGE;
3560 it->image_id = -1; /* no image */
3561 it->position = start_pos;
3562 it->object = NILP (object) ? it->w->buffer : object;
3563 it->method = next_element_from_image;
3564 it->face_id = face_id;
3566 /* Say that we haven't consumed the characters with
3567 `display' property yet. The call to pop_it in
3568 set_iterator_to_next will clean this up. */
3569 *position = start_pos;
3571 if (EQ (XCAR (prop), Qleft_fringe))
3573 it->left_user_fringe_bitmap = XINT (value);
3574 it->left_user_fringe_face_id = face_id;
3576 else
3578 it->right_user_fringe_bitmap = XINT (value);
3579 it->right_user_fringe_face_id = face_id;
3581 #endif /* HAVE_WINDOW_SYSTEM */
3582 return 1;
3585 location = Qunbound;
3586 if (CONSP (prop) && CONSP (XCAR (prop)))
3588 Lisp_Object tem;
3590 value = XCDR (prop);
3591 if (CONSP (value))
3592 value = XCAR (value);
3594 tem = XCAR (prop);
3595 if (EQ (XCAR (tem), Qmargin)
3596 && (tem = XCDR (tem),
3597 tem = CONSP (tem) ? XCAR (tem) : Qnil,
3598 (NILP (tem)
3599 || EQ (tem, Qleft_margin)
3600 || EQ (tem, Qright_margin))))
3601 location = tem;
3604 if (EQ (location, Qunbound))
3606 location = Qnil;
3607 value = prop;
3610 #ifdef HAVE_WINDOW_SYSTEM
3611 if (FRAME_TERMCAP_P (it->f))
3612 valid_p = STRINGP (value);
3613 else
3614 valid_p = (STRINGP (value)
3615 || (CONSP (value) && EQ (XCAR (value), Qspace))
3616 || valid_image_p (value));
3617 #else /* not HAVE_WINDOW_SYSTEM */
3618 valid_p = STRINGP (value);
3619 #endif /* not HAVE_WINDOW_SYSTEM */
3621 if ((EQ (location, Qleft_margin)
3622 || EQ (location, Qright_margin)
3623 || NILP (location))
3624 && valid_p
3625 && !display_replaced_before_p)
3627 replaces_text_display_p = 1;
3629 /* Save current settings of IT so that we can restore them
3630 when we are finished with the glyph property value. */
3631 push_it (it);
3633 if (NILP (location))
3634 it->area = TEXT_AREA;
3635 else if (EQ (location, Qleft_margin))
3636 it->area = LEFT_MARGIN_AREA;
3637 else
3638 it->area = RIGHT_MARGIN_AREA;
3640 if (STRINGP (value))
3642 it->string = value;
3643 it->multibyte_p = STRING_MULTIBYTE (it->string);
3644 it->current.overlay_string_index = -1;
3645 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
3646 it->end_charpos = it->string_nchars = SCHARS (it->string);
3647 it->method = next_element_from_string;
3648 it->stop_charpos = 0;
3649 it->string_from_display_prop_p = 1;
3650 /* Say that we haven't consumed the characters with
3651 `display' property yet. The call to pop_it in
3652 set_iterator_to_next will clean this up. */
3653 *position = start_pos;
3655 else if (CONSP (value) && EQ (XCAR (value), Qspace))
3657 it->method = next_element_from_stretch;
3658 it->object = value;
3659 it->current.pos = it->position = start_pos;
3661 #ifdef HAVE_WINDOW_SYSTEM
3662 else
3664 it->what = IT_IMAGE;
3665 it->image_id = lookup_image (it->f, value);
3666 it->position = start_pos;
3667 it->object = NILP (object) ? it->w->buffer : object;
3668 it->method = next_element_from_image;
3670 /* Say that we haven't consumed the characters with
3671 `display' property yet. The call to pop_it in
3672 set_iterator_to_next will clean this up. */
3673 *position = start_pos;
3675 #endif /* HAVE_WINDOW_SYSTEM */
3677 else
3678 /* Invalid property or property not supported. Restore
3679 the position to what it was before. */
3680 *position = start_pos;
3683 return replaces_text_display_p;
3687 /* Check if PROP is a display sub-property value whose text should be
3688 treated as intangible. */
3690 static int
3691 single_display_prop_intangible_p (prop)
3692 Lisp_Object prop;
3694 /* Skip over `when FORM'. */
3695 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3697 prop = XCDR (prop);
3698 if (!CONSP (prop))
3699 return 0;
3700 prop = XCDR (prop);
3703 if (STRINGP (prop))
3704 return 1;
3706 if (!CONSP (prop))
3707 return 0;
3709 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
3710 we don't need to treat text as intangible. */
3711 if (EQ (XCAR (prop), Qmargin))
3713 prop = XCDR (prop);
3714 if (!CONSP (prop))
3715 return 0;
3717 prop = XCDR (prop);
3718 if (!CONSP (prop)
3719 || EQ (XCAR (prop), Qleft_margin)
3720 || EQ (XCAR (prop), Qright_margin))
3721 return 0;
3724 return (CONSP (prop)
3725 && (EQ (XCAR (prop), Qimage)
3726 || EQ (XCAR (prop), Qspace)));
3730 /* Check if PROP is a display property value whose text should be
3731 treated as intangible. */
3734 display_prop_intangible_p (prop)
3735 Lisp_Object prop;
3737 if (CONSP (prop)
3738 && CONSP (XCAR (prop))
3739 && !EQ (Qmargin, XCAR (XCAR (prop))))
3741 /* A list of sub-properties. */
3742 while (CONSP (prop))
3744 if (single_display_prop_intangible_p (XCAR (prop)))
3745 return 1;
3746 prop = XCDR (prop);
3749 else if (VECTORP (prop))
3751 /* A vector of sub-properties. */
3752 int i;
3753 for (i = 0; i < ASIZE (prop); ++i)
3754 if (single_display_prop_intangible_p (AREF (prop, i)))
3755 return 1;
3757 else
3758 return single_display_prop_intangible_p (prop);
3760 return 0;
3764 /* Return 1 if PROP is a display sub-property value containing STRING. */
3766 static int
3767 single_display_prop_string_p (prop, string)
3768 Lisp_Object prop, string;
3770 if (EQ (string, prop))
3771 return 1;
3773 /* Skip over `when FORM'. */
3774 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3776 prop = XCDR (prop);
3777 if (!CONSP (prop))
3778 return 0;
3779 prop = XCDR (prop);
3782 if (CONSP (prop))
3783 /* Skip over `margin LOCATION'. */
3784 if (EQ (XCAR (prop), Qmargin))
3786 prop = XCDR (prop);
3787 if (!CONSP (prop))
3788 return 0;
3790 prop = XCDR (prop);
3791 if (!CONSP (prop))
3792 return 0;
3795 return CONSP (prop) && EQ (XCAR (prop), string);
3799 /* Return 1 if STRING appears in the `display' property PROP. */
3801 static int
3802 display_prop_string_p (prop, string)
3803 Lisp_Object prop, string;
3805 if (CONSP (prop)
3806 && CONSP (XCAR (prop))
3807 && !EQ (Qmargin, XCAR (XCAR (prop))))
3809 /* A list of sub-properties. */
3810 while (CONSP (prop))
3812 if (single_display_prop_string_p (XCAR (prop), string))
3813 return 1;
3814 prop = XCDR (prop);
3817 else if (VECTORP (prop))
3819 /* A vector of sub-properties. */
3820 int i;
3821 for (i = 0; i < ASIZE (prop); ++i)
3822 if (single_display_prop_string_p (AREF (prop, i), string))
3823 return 1;
3825 else
3826 return single_display_prop_string_p (prop, string);
3828 return 0;
3832 /* Determine from which buffer position in W's buffer STRING comes
3833 from. AROUND_CHARPOS is an approximate position where it could
3834 be from. Value is the buffer position or 0 if it couldn't be
3835 determined.
3837 W's buffer must be current.
3839 This function is necessary because we don't record buffer positions
3840 in glyphs generated from strings (to keep struct glyph small).
3841 This function may only use code that doesn't eval because it is
3842 called asynchronously from note_mouse_highlight. */
3845 string_buffer_position (w, string, around_charpos)
3846 struct window *w;
3847 Lisp_Object string;
3848 int around_charpos;
3850 Lisp_Object limit, prop, pos;
3851 const int MAX_DISTANCE = 1000;
3852 int found = 0;
3854 pos = make_number (around_charpos);
3855 limit = make_number (min (XINT (pos) + MAX_DISTANCE, ZV));
3856 while (!found && !EQ (pos, limit))
3858 prop = Fget_char_property (pos, Qdisplay, Qnil);
3859 if (!NILP (prop) && display_prop_string_p (prop, string))
3860 found = 1;
3861 else
3862 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil, limit);
3865 if (!found)
3867 pos = make_number (around_charpos);
3868 limit = make_number (max (XINT (pos) - MAX_DISTANCE, BEGV));
3869 while (!found && !EQ (pos, limit))
3871 prop = Fget_char_property (pos, Qdisplay, Qnil);
3872 if (!NILP (prop) && display_prop_string_p (prop, string))
3873 found = 1;
3874 else
3875 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
3876 limit);
3880 return found ? XINT (pos) : 0;
3885 /***********************************************************************
3886 `composition' property
3887 ***********************************************************************/
3889 /* Set up iterator IT from `composition' property at its current
3890 position. Called from handle_stop. */
3892 static enum prop_handled
3893 handle_composition_prop (it)
3894 struct it *it;
3896 Lisp_Object prop, string;
3897 int pos, pos_byte, end;
3898 enum prop_handled handled = HANDLED_NORMALLY;
3900 if (STRINGP (it->string))
3902 pos = IT_STRING_CHARPOS (*it);
3903 pos_byte = IT_STRING_BYTEPOS (*it);
3904 string = it->string;
3906 else
3908 pos = IT_CHARPOS (*it);
3909 pos_byte = IT_BYTEPOS (*it);
3910 string = Qnil;
3913 /* If there's a valid composition and point is not inside of the
3914 composition (in the case that the composition is from the current
3915 buffer), draw a glyph composed from the composition components. */
3916 if (find_composition (pos, -1, &pos, &end, &prop, string)
3917 && COMPOSITION_VALID_P (pos, end, prop)
3918 && (STRINGP (it->string) || (PT <= pos || PT >= end)))
3920 int id = get_composition_id (pos, pos_byte, end - pos, prop, string);
3922 if (id >= 0)
3924 it->method = next_element_from_composition;
3925 it->cmp_id = id;
3926 it->cmp_len = COMPOSITION_LENGTH (prop);
3927 /* For a terminal, draw only the first character of the
3928 components. */
3929 it->c = COMPOSITION_GLYPH (composition_table[id], 0);
3930 it->len = (STRINGP (it->string)
3931 ? string_char_to_byte (it->string, end)
3932 : CHAR_TO_BYTE (end)) - pos_byte;
3933 it->stop_charpos = end;
3934 handled = HANDLED_RETURN;
3938 return handled;
3943 /***********************************************************************
3944 Overlay strings
3945 ***********************************************************************/
3947 /* The following structure is used to record overlay strings for
3948 later sorting in load_overlay_strings. */
3950 struct overlay_entry
3952 Lisp_Object overlay;
3953 Lisp_Object string;
3954 int priority;
3955 int after_string_p;
3959 /* Set up iterator IT from overlay strings at its current position.
3960 Called from handle_stop. */
3962 static enum prop_handled
3963 handle_overlay_change (it)
3964 struct it *it;
3966 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
3967 return HANDLED_RECOMPUTE_PROPS;
3968 else
3969 return HANDLED_NORMALLY;
3973 /* Set up the next overlay string for delivery by IT, if there is an
3974 overlay string to deliver. Called by set_iterator_to_next when the
3975 end of the current overlay string is reached. If there are more
3976 overlay strings to display, IT->string and
3977 IT->current.overlay_string_index are set appropriately here.
3978 Otherwise IT->string is set to nil. */
3980 static void
3981 next_overlay_string (it)
3982 struct it *it;
3984 ++it->current.overlay_string_index;
3985 if (it->current.overlay_string_index == it->n_overlay_strings)
3987 /* No more overlay strings. Restore IT's settings to what
3988 they were before overlay strings were processed, and
3989 continue to deliver from current_buffer. */
3990 int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
3992 pop_it (it);
3993 xassert (it->stop_charpos >= BEGV
3994 && it->stop_charpos <= it->end_charpos);
3995 it->string = Qnil;
3996 it->current.overlay_string_index = -1;
3997 SET_TEXT_POS (it->current.string_pos, -1, -1);
3998 it->n_overlay_strings = 0;
3999 it->method = next_element_from_buffer;
4001 /* If we're at the end of the buffer, record that we have
4002 processed the overlay strings there already, so that
4003 next_element_from_buffer doesn't try it again. */
4004 if (IT_CHARPOS (*it) >= it->end_charpos)
4005 it->overlay_strings_at_end_processed_p = 1;
4007 /* If we have to display `...' for invisible text, set
4008 the iterator up for that. */
4009 if (display_ellipsis_p)
4010 setup_for_ellipsis (it);
4012 else
4014 /* There are more overlay strings to process. If
4015 IT->current.overlay_string_index has advanced to a position
4016 where we must load IT->overlay_strings with more strings, do
4017 it. */
4018 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
4020 if (it->current.overlay_string_index && i == 0)
4021 load_overlay_strings (it, 0);
4023 /* Initialize IT to deliver display elements from the overlay
4024 string. */
4025 it->string = it->overlay_strings[i];
4026 it->multibyte_p = STRING_MULTIBYTE (it->string);
4027 SET_TEXT_POS (it->current.string_pos, 0, 0);
4028 it->method = next_element_from_string;
4029 it->stop_charpos = 0;
4032 CHECK_IT (it);
4036 /* Compare two overlay_entry structures E1 and E2. Used as a
4037 comparison function for qsort in load_overlay_strings. Overlay
4038 strings for the same position are sorted so that
4040 1. All after-strings come in front of before-strings, except
4041 when they come from the same overlay.
4043 2. Within after-strings, strings are sorted so that overlay strings
4044 from overlays with higher priorities come first.
4046 2. Within before-strings, strings are sorted so that overlay
4047 strings from overlays with higher priorities come last.
4049 Value is analogous to strcmp. */
4052 static int
4053 compare_overlay_entries (e1, e2)
4054 void *e1, *e2;
4056 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4057 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4058 int result;
4060 if (entry1->after_string_p != entry2->after_string_p)
4062 /* Let after-strings appear in front of before-strings if
4063 they come from different overlays. */
4064 if (EQ (entry1->overlay, entry2->overlay))
4065 result = entry1->after_string_p ? 1 : -1;
4066 else
4067 result = entry1->after_string_p ? -1 : 1;
4069 else if (entry1->after_string_p)
4070 /* After-strings sorted in order of decreasing priority. */
4071 result = entry2->priority - entry1->priority;
4072 else
4073 /* Before-strings sorted in order of increasing priority. */
4074 result = entry1->priority - entry2->priority;
4076 return result;
4080 /* Load the vector IT->overlay_strings with overlay strings from IT's
4081 current buffer position, or from CHARPOS if that is > 0. Set
4082 IT->n_overlays to the total number of overlay strings found.
4084 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4085 a time. On entry into load_overlay_strings,
4086 IT->current.overlay_string_index gives the number of overlay
4087 strings that have already been loaded by previous calls to this
4088 function.
4090 IT->add_overlay_start contains an additional overlay start
4091 position to consider for taking overlay strings from, if non-zero.
4092 This position comes into play when the overlay has an `invisible'
4093 property, and both before and after-strings. When we've skipped to
4094 the end of the overlay, because of its `invisible' property, we
4095 nevertheless want its before-string to appear.
4096 IT->add_overlay_start will contain the overlay start position
4097 in this case.
4099 Overlay strings are sorted so that after-string strings come in
4100 front of before-string strings. Within before and after-strings,
4101 strings are sorted by overlay priority. See also function
4102 compare_overlay_entries. */
4104 static void
4105 load_overlay_strings (it, charpos)
4106 struct it *it;
4107 int charpos;
4109 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
4110 Lisp_Object overlay, window, str, invisible;
4111 struct Lisp_Overlay *ov;
4112 int start, end;
4113 int size = 20;
4114 int n = 0, i, j, invis_p;
4115 struct overlay_entry *entries
4116 = (struct overlay_entry *) alloca (size * sizeof *entries);
4118 if (charpos <= 0)
4119 charpos = IT_CHARPOS (*it);
4121 /* Append the overlay string STRING of overlay OVERLAY to vector
4122 `entries' which has size `size' and currently contains `n'
4123 elements. AFTER_P non-zero means STRING is an after-string of
4124 OVERLAY. */
4125 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4126 do \
4128 Lisp_Object priority; \
4130 if (n == size) \
4132 int new_size = 2 * size; \
4133 struct overlay_entry *old = entries; \
4134 entries = \
4135 (struct overlay_entry *) alloca (new_size \
4136 * sizeof *entries); \
4137 bcopy (old, entries, size * sizeof *entries); \
4138 size = new_size; \
4141 entries[n].string = (STRING); \
4142 entries[n].overlay = (OVERLAY); \
4143 priority = Foverlay_get ((OVERLAY), Qpriority); \
4144 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4145 entries[n].after_string_p = (AFTER_P); \
4146 ++n; \
4148 while (0)
4150 /* Process overlay before the overlay center. */
4151 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4153 XSETMISC (overlay, ov);
4154 xassert (OVERLAYP (overlay));
4155 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4156 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4158 if (end < charpos)
4159 break;
4161 /* Skip this overlay if it doesn't start or end at IT's current
4162 position. */
4163 if (end != charpos && start != charpos)
4164 continue;
4166 /* Skip this overlay if it doesn't apply to IT->w. */
4167 window = Foverlay_get (overlay, Qwindow);
4168 if (WINDOWP (window) && XWINDOW (window) != it->w)
4169 continue;
4171 /* If the text ``under'' the overlay is invisible, both before-
4172 and after-strings from this overlay are visible; start and
4173 end position are indistinguishable. */
4174 invisible = Foverlay_get (overlay, Qinvisible);
4175 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4177 /* If overlay has a non-empty before-string, record it. */
4178 if ((start == charpos || (end == charpos && invis_p))
4179 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4180 && SCHARS (str))
4181 RECORD_OVERLAY_STRING (overlay, str, 0);
4183 /* If overlay has a non-empty after-string, record it. */
4184 if ((end == charpos || (start == charpos && invis_p))
4185 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4186 && SCHARS (str))
4187 RECORD_OVERLAY_STRING (overlay, str, 1);
4190 /* Process overlays after the overlay center. */
4191 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
4193 XSETMISC (overlay, ov);
4194 xassert (OVERLAYP (overlay));
4195 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4196 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4198 if (start > charpos)
4199 break;
4201 /* Skip this overlay if it doesn't start or end at IT's current
4202 position. */
4203 if (end != charpos && start != charpos)
4204 continue;
4206 /* Skip this overlay if it doesn't apply to IT->w. */
4207 window = Foverlay_get (overlay, Qwindow);
4208 if (WINDOWP (window) && XWINDOW (window) != it->w)
4209 continue;
4211 /* If the text ``under'' the overlay is invisible, it has a zero
4212 dimension, and both before- and after-strings apply. */
4213 invisible = Foverlay_get (overlay, Qinvisible);
4214 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4216 /* If overlay has a non-empty before-string, record it. */
4217 if ((start == charpos || (end == charpos && invis_p))
4218 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4219 && SCHARS (str))
4220 RECORD_OVERLAY_STRING (overlay, str, 0);
4222 /* If overlay has a non-empty after-string, record it. */
4223 if ((end == charpos || (start == charpos && invis_p))
4224 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4225 && SCHARS (str))
4226 RECORD_OVERLAY_STRING (overlay, str, 1);
4229 #undef RECORD_OVERLAY_STRING
4231 /* Sort entries. */
4232 if (n > 1)
4233 qsort (entries, n, sizeof *entries, compare_overlay_entries);
4235 /* Record the total number of strings to process. */
4236 it->n_overlay_strings = n;
4238 /* IT->current.overlay_string_index is the number of overlay strings
4239 that have already been consumed by IT. Copy some of the
4240 remaining overlay strings to IT->overlay_strings. */
4241 i = 0;
4242 j = it->current.overlay_string_index;
4243 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
4244 it->overlay_strings[i++] = entries[j++].string;
4246 CHECK_IT (it);
4250 /* Get the first chunk of overlay strings at IT's current buffer
4251 position, or at CHARPOS if that is > 0. Value is non-zero if at
4252 least one overlay string was found. */
4254 static int
4255 get_overlay_strings (it, charpos)
4256 struct it *it;
4257 int charpos;
4259 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4260 process. This fills IT->overlay_strings with strings, and sets
4261 IT->n_overlay_strings to the total number of strings to process.
4262 IT->pos.overlay_string_index has to be set temporarily to zero
4263 because load_overlay_strings needs this; it must be set to -1
4264 when no overlay strings are found because a zero value would
4265 indicate a position in the first overlay string. */
4266 it->current.overlay_string_index = 0;
4267 load_overlay_strings (it, charpos);
4269 /* If we found overlay strings, set up IT to deliver display
4270 elements from the first one. Otherwise set up IT to deliver
4271 from current_buffer. */
4272 if (it->n_overlay_strings)
4274 /* Make sure we know settings in current_buffer, so that we can
4275 restore meaningful values when we're done with the overlay
4276 strings. */
4277 compute_stop_pos (it);
4278 xassert (it->face_id >= 0);
4280 /* Save IT's settings. They are restored after all overlay
4281 strings have been processed. */
4282 xassert (it->sp == 0);
4283 push_it (it);
4285 /* Set up IT to deliver display elements from the first overlay
4286 string. */
4287 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4288 it->string = it->overlay_strings[0];
4289 it->stop_charpos = 0;
4290 xassert (STRINGP (it->string));
4291 it->end_charpos = SCHARS (it->string);
4292 it->multibyte_p = STRING_MULTIBYTE (it->string);
4293 it->method = next_element_from_string;
4295 else
4297 it->string = Qnil;
4298 it->current.overlay_string_index = -1;
4299 it->method = next_element_from_buffer;
4302 CHECK_IT (it);
4304 /* Value is non-zero if we found at least one overlay string. */
4305 return STRINGP (it->string);
4310 /***********************************************************************
4311 Saving and restoring state
4312 ***********************************************************************/
4314 /* Save current settings of IT on IT->stack. Called, for example,
4315 before setting up IT for an overlay string, to be able to restore
4316 IT's settings to what they were after the overlay string has been
4317 processed. */
4319 static void
4320 push_it (it)
4321 struct it *it;
4323 struct iterator_stack_entry *p;
4325 xassert (it->sp < 2);
4326 p = it->stack + it->sp;
4328 p->stop_charpos = it->stop_charpos;
4329 xassert (it->face_id >= 0);
4330 p->face_id = it->face_id;
4331 p->string = it->string;
4332 p->pos = it->current;
4333 p->end_charpos = it->end_charpos;
4334 p->string_nchars = it->string_nchars;
4335 p->area = it->area;
4336 p->multibyte_p = it->multibyte_p;
4337 p->space_width = it->space_width;
4338 p->font_height = it->font_height;
4339 p->voffset = it->voffset;
4340 p->string_from_display_prop_p = it->string_from_display_prop_p;
4341 p->display_ellipsis_p = 0;
4342 ++it->sp;
4346 /* Restore IT's settings from IT->stack. Called, for example, when no
4347 more overlay strings must be processed, and we return to delivering
4348 display elements from a buffer, or when the end of a string from a
4349 `display' property is reached and we return to delivering display
4350 elements from an overlay string, or from a buffer. */
4352 static void
4353 pop_it (it)
4354 struct it *it;
4356 struct iterator_stack_entry *p;
4358 xassert (it->sp > 0);
4359 --it->sp;
4360 p = it->stack + it->sp;
4361 it->stop_charpos = p->stop_charpos;
4362 it->face_id = p->face_id;
4363 it->string = p->string;
4364 it->current = p->pos;
4365 it->end_charpos = p->end_charpos;
4366 it->string_nchars = p->string_nchars;
4367 it->area = p->area;
4368 it->multibyte_p = p->multibyte_p;
4369 it->space_width = p->space_width;
4370 it->font_height = p->font_height;
4371 it->voffset = p->voffset;
4372 it->string_from_display_prop_p = p->string_from_display_prop_p;
4377 /***********************************************************************
4378 Moving over lines
4379 ***********************************************************************/
4381 /* Set IT's current position to the previous line start. */
4383 static void
4384 back_to_previous_line_start (it)
4385 struct it *it;
4387 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
4388 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
4392 /* Move IT to the next line start.
4394 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
4395 we skipped over part of the text (as opposed to moving the iterator
4396 continuously over the text). Otherwise, don't change the value
4397 of *SKIPPED_P.
4399 Newlines may come from buffer text, overlay strings, or strings
4400 displayed via the `display' property. That's the reason we can't
4401 simply use find_next_newline_no_quit.
4403 Note that this function may not skip over invisible text that is so
4404 because of text properties and immediately follows a newline. If
4405 it would, function reseat_at_next_visible_line_start, when called
4406 from set_iterator_to_next, would effectively make invisible
4407 characters following a newline part of the wrong glyph row, which
4408 leads to wrong cursor motion. */
4410 static int
4411 forward_to_next_line_start (it, skipped_p)
4412 struct it *it;
4413 int *skipped_p;
4415 int old_selective, newline_found_p, n;
4416 const int MAX_NEWLINE_DISTANCE = 500;
4418 /* If already on a newline, just consume it to avoid unintended
4419 skipping over invisible text below. */
4420 if (it->what == IT_CHARACTER
4421 && it->c == '\n'
4422 && CHARPOS (it->position) == IT_CHARPOS (*it))
4424 set_iterator_to_next (it, 0);
4425 it->c = 0;
4426 return 1;
4429 /* Don't handle selective display in the following. It's (a)
4430 unnecessary because it's done by the caller, and (b) leads to an
4431 infinite recursion because next_element_from_ellipsis indirectly
4432 calls this function. */
4433 old_selective = it->selective;
4434 it->selective = 0;
4436 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
4437 from buffer text. */
4438 for (n = newline_found_p = 0;
4439 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
4440 n += STRINGP (it->string) ? 0 : 1)
4442 if (!get_next_display_element (it))
4443 return 0;
4444 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
4445 set_iterator_to_next (it, 0);
4448 /* If we didn't find a newline near enough, see if we can use a
4449 short-cut. */
4450 if (!newline_found_p)
4452 int start = IT_CHARPOS (*it);
4453 int limit = find_next_newline_no_quit (start, 1);
4454 Lisp_Object pos;
4456 xassert (!STRINGP (it->string));
4458 /* If there isn't any `display' property in sight, and no
4459 overlays, we can just use the position of the newline in
4460 buffer text. */
4461 if (it->stop_charpos >= limit
4462 || ((pos = Fnext_single_property_change (make_number (start),
4463 Qdisplay,
4464 Qnil, make_number (limit)),
4465 NILP (pos))
4466 && next_overlay_change (start) == ZV))
4468 IT_CHARPOS (*it) = limit;
4469 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
4470 *skipped_p = newline_found_p = 1;
4472 else
4474 while (get_next_display_element (it)
4475 && !newline_found_p)
4477 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
4478 set_iterator_to_next (it, 0);
4483 it->selective = old_selective;
4484 return newline_found_p;
4488 /* Set IT's current position to the previous visible line start. Skip
4489 invisible text that is so either due to text properties or due to
4490 selective display. Caution: this does not change IT->current_x and
4491 IT->hpos. */
4493 static void
4494 back_to_previous_visible_line_start (it)
4495 struct it *it;
4497 int visible_p = 0;
4499 /* Go back one newline if not on BEGV already. */
4500 if (IT_CHARPOS (*it) > BEGV)
4501 back_to_previous_line_start (it);
4503 /* Move over lines that are invisible because of selective display
4504 or text properties. */
4505 while (IT_CHARPOS (*it) > BEGV
4506 && !visible_p)
4508 visible_p = 1;
4510 /* If selective > 0, then lines indented more than that values
4511 are invisible. */
4512 if (it->selective > 0
4513 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4514 (double) it->selective)) /* iftc */
4515 visible_p = 0;
4516 else
4518 Lisp_Object prop;
4520 prop = Fget_char_property (make_number (IT_CHARPOS (*it)),
4521 Qinvisible, it->window);
4522 if (TEXT_PROP_MEANS_INVISIBLE (prop))
4523 visible_p = 0;
4526 /* Back one more newline if the current one is invisible. */
4527 if (!visible_p)
4528 back_to_previous_line_start (it);
4531 xassert (IT_CHARPOS (*it) >= BEGV);
4532 xassert (IT_CHARPOS (*it) == BEGV
4533 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4534 CHECK_IT (it);
4538 /* Reseat iterator IT at the previous visible line start. Skip
4539 invisible text that is so either due to text properties or due to
4540 selective display. At the end, update IT's overlay information,
4541 face information etc. */
4543 static void
4544 reseat_at_previous_visible_line_start (it)
4545 struct it *it;
4547 back_to_previous_visible_line_start (it);
4548 reseat (it, it->current.pos, 1);
4549 CHECK_IT (it);
4553 /* Reseat iterator IT on the next visible line start in the current
4554 buffer. ON_NEWLINE_P non-zero means position IT on the newline
4555 preceding the line start. Skip over invisible text that is so
4556 because of selective display. Compute faces, overlays etc at the
4557 new position. Note that this function does not skip over text that
4558 is invisible because of text properties. */
4560 static void
4561 reseat_at_next_visible_line_start (it, on_newline_p)
4562 struct it *it;
4563 int on_newline_p;
4565 int newline_found_p, skipped_p = 0;
4567 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4569 /* Skip over lines that are invisible because they are indented
4570 more than the value of IT->selective. */
4571 if (it->selective > 0)
4572 while (IT_CHARPOS (*it) < ZV
4573 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4574 (double) it->selective)) /* iftc */
4576 xassert (FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4577 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4580 /* Position on the newline if that's what's requested. */
4581 if (on_newline_p && newline_found_p)
4583 if (STRINGP (it->string))
4585 if (IT_STRING_CHARPOS (*it) > 0)
4587 --IT_STRING_CHARPOS (*it);
4588 --IT_STRING_BYTEPOS (*it);
4591 else if (IT_CHARPOS (*it) > BEGV)
4593 --IT_CHARPOS (*it);
4594 --IT_BYTEPOS (*it);
4595 reseat (it, it->current.pos, 0);
4598 else if (skipped_p)
4599 reseat (it, it->current.pos, 0);
4601 CHECK_IT (it);
4606 /***********************************************************************
4607 Changing an iterator's position
4608 ***********************************************************************/
4610 /* Change IT's current position to POS in current_buffer. If FORCE_P
4611 is non-zero, always check for text properties at the new position.
4612 Otherwise, text properties are only looked up if POS >=
4613 IT->check_charpos of a property. */
4615 static void
4616 reseat (it, pos, force_p)
4617 struct it *it;
4618 struct text_pos pos;
4619 int force_p;
4621 int original_pos = IT_CHARPOS (*it);
4623 reseat_1 (it, pos, 0);
4625 /* Determine where to check text properties. Avoid doing it
4626 where possible because text property lookup is very expensive. */
4627 if (force_p
4628 || CHARPOS (pos) > it->stop_charpos
4629 || CHARPOS (pos) < original_pos)
4630 handle_stop (it);
4632 CHECK_IT (it);
4636 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
4637 IT->stop_pos to POS, also. */
4639 static void
4640 reseat_1 (it, pos, set_stop_p)
4641 struct it *it;
4642 struct text_pos pos;
4643 int set_stop_p;
4645 /* Don't call this function when scanning a C string. */
4646 xassert (it->s == NULL);
4648 /* POS must be a reasonable value. */
4649 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
4651 it->current.pos = it->position = pos;
4652 XSETBUFFER (it->object, current_buffer);
4653 it->end_charpos = ZV;
4654 it->dpvec = NULL;
4655 it->current.dpvec_index = -1;
4656 it->current.overlay_string_index = -1;
4657 IT_STRING_CHARPOS (*it) = -1;
4658 IT_STRING_BYTEPOS (*it) = -1;
4659 it->string = Qnil;
4660 it->method = next_element_from_buffer;
4661 /* RMS: I added this to fix a bug in move_it_vertically_backward
4662 where it->area continued to relate to the starting point
4663 for the backward motion. Bug report from
4664 Nick Roberts <nick@nick.uklinux.net> on 19 May 2003.
4665 However, I am not sure whether reseat still does the right thing
4666 in general after this change. */
4667 it->area = TEXT_AREA;
4668 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
4669 it->sp = 0;
4670 it->face_before_selective_p = 0;
4672 if (set_stop_p)
4673 it->stop_charpos = CHARPOS (pos);
4677 /* Set up IT for displaying a string, starting at CHARPOS in window W.
4678 If S is non-null, it is a C string to iterate over. Otherwise,
4679 STRING gives a Lisp string to iterate over.
4681 If PRECISION > 0, don't return more then PRECISION number of
4682 characters from the string.
4684 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
4685 characters have been returned. FIELD_WIDTH < 0 means an infinite
4686 field width.
4688 MULTIBYTE = 0 means disable processing of multibyte characters,
4689 MULTIBYTE > 0 means enable it,
4690 MULTIBYTE < 0 means use IT->multibyte_p.
4692 IT must be initialized via a prior call to init_iterator before
4693 calling this function. */
4695 static void
4696 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
4697 struct it *it;
4698 unsigned char *s;
4699 Lisp_Object string;
4700 int charpos;
4701 int precision, field_width, multibyte;
4703 /* No region in strings. */
4704 it->region_beg_charpos = it->region_end_charpos = -1;
4706 /* No text property checks performed by default, but see below. */
4707 it->stop_charpos = -1;
4709 /* Set iterator position and end position. */
4710 bzero (&it->current, sizeof it->current);
4711 it->current.overlay_string_index = -1;
4712 it->current.dpvec_index = -1;
4713 xassert (charpos >= 0);
4715 /* If STRING is specified, use its multibyteness, otherwise use the
4716 setting of MULTIBYTE, if specified. */
4717 if (multibyte >= 0)
4718 it->multibyte_p = multibyte > 0;
4720 if (s == NULL)
4722 xassert (STRINGP (string));
4723 it->string = string;
4724 it->s = NULL;
4725 it->end_charpos = it->string_nchars = SCHARS (string);
4726 it->method = next_element_from_string;
4727 it->current.string_pos = string_pos (charpos, string);
4729 else
4731 it->s = s;
4732 it->string = Qnil;
4734 /* Note that we use IT->current.pos, not it->current.string_pos,
4735 for displaying C strings. */
4736 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
4737 if (it->multibyte_p)
4739 it->current.pos = c_string_pos (charpos, s, 1);
4740 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
4742 else
4744 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
4745 it->end_charpos = it->string_nchars = strlen (s);
4748 it->method = next_element_from_c_string;
4751 /* PRECISION > 0 means don't return more than PRECISION characters
4752 from the string. */
4753 if (precision > 0 && it->end_charpos - charpos > precision)
4754 it->end_charpos = it->string_nchars = charpos + precision;
4756 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
4757 characters have been returned. FIELD_WIDTH == 0 means don't pad,
4758 FIELD_WIDTH < 0 means infinite field width. This is useful for
4759 padding with `-' at the end of a mode line. */
4760 if (field_width < 0)
4761 field_width = INFINITY;
4762 if (field_width > it->end_charpos - charpos)
4763 it->end_charpos = charpos + field_width;
4765 /* Use the standard display table for displaying strings. */
4766 if (DISP_TABLE_P (Vstandard_display_table))
4767 it->dp = XCHAR_TABLE (Vstandard_display_table);
4769 it->stop_charpos = charpos;
4770 CHECK_IT (it);
4775 /***********************************************************************
4776 Iteration
4777 ***********************************************************************/
4779 /* Load IT's display element fields with information about the next
4780 display element from the current position of IT. Value is zero if
4781 end of buffer (or C string) is reached. */
4784 get_next_display_element (it)
4785 struct it *it;
4787 /* Non-zero means that we found a display element. Zero means that
4788 we hit the end of what we iterate over. Performance note: the
4789 function pointer `method' used here turns out to be faster than
4790 using a sequence of if-statements. */
4791 int success_p = (*it->method) (it);
4793 if (it->what == IT_CHARACTER)
4795 /* Map via display table or translate control characters.
4796 IT->c, IT->len etc. have been set to the next character by
4797 the function call above. If we have a display table, and it
4798 contains an entry for IT->c, translate it. Don't do this if
4799 IT->c itself comes from a display table, otherwise we could
4800 end up in an infinite recursion. (An alternative could be to
4801 count the recursion depth of this function and signal an
4802 error when a certain maximum depth is reached.) Is it worth
4803 it? */
4804 if (success_p && it->dpvec == NULL)
4806 Lisp_Object dv;
4808 if (it->dp
4809 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
4810 VECTORP (dv)))
4812 struct Lisp_Vector *v = XVECTOR (dv);
4814 /* Return the first character from the display table
4815 entry, if not empty. If empty, don't display the
4816 current character. */
4817 if (v->size)
4819 it->dpvec_char_len = it->len;
4820 it->dpvec = v->contents;
4821 it->dpend = v->contents + v->size;
4822 it->current.dpvec_index = 0;
4823 it->method = next_element_from_display_vector;
4824 success_p = get_next_display_element (it);
4826 else
4828 set_iterator_to_next (it, 0);
4829 success_p = get_next_display_element (it);
4833 /* Translate control characters into `\003' or `^C' form.
4834 Control characters coming from a display table entry are
4835 currently not translated because we use IT->dpvec to hold
4836 the translation. This could easily be changed but I
4837 don't believe that it is worth doing.
4839 If it->multibyte_p is nonzero, eight-bit characters and
4840 non-printable multibyte characters are also translated to
4841 octal form.
4843 If it->multibyte_p is zero, eight-bit characters that
4844 don't have corresponding multibyte char code are also
4845 translated to octal form. */
4846 else if ((it->c < ' '
4847 && (it->area != TEXT_AREA
4848 || (it->c != '\n' && it->c != '\t')))
4849 || (it->multibyte_p
4850 ? ((it->c >= 127
4851 && it->len == 1)
4852 || !CHAR_PRINTABLE_P (it->c))
4853 : (it->c >= 127
4854 && it->c == unibyte_char_to_multibyte (it->c))))
4856 /* IT->c is a control character which must be displayed
4857 either as '\003' or as `^C' where the '\\' and '^'
4858 can be defined in the display table. Fill
4859 IT->ctl_chars with glyphs for what we have to
4860 display. Then, set IT->dpvec to these glyphs. */
4861 GLYPH g;
4863 if (it->c < 128 && it->ctl_arrow_p)
4865 /* Set IT->ctl_chars[0] to the glyph for `^'. */
4866 if (it->dp
4867 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
4868 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
4869 g = XINT (DISP_CTRL_GLYPH (it->dp));
4870 else
4871 g = FAST_MAKE_GLYPH ('^', 0);
4872 XSETINT (it->ctl_chars[0], g);
4874 g = FAST_MAKE_GLYPH (it->c ^ 0100, 0);
4875 XSETINT (it->ctl_chars[1], g);
4877 /* Set up IT->dpvec and return first character from it. */
4878 it->dpvec_char_len = it->len;
4879 it->dpvec = it->ctl_chars;
4880 it->dpend = it->dpvec + 2;
4881 it->current.dpvec_index = 0;
4882 it->method = next_element_from_display_vector;
4883 get_next_display_element (it);
4885 else
4887 unsigned char str[MAX_MULTIBYTE_LENGTH];
4888 int len;
4889 int i;
4890 GLYPH escape_glyph;
4892 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
4893 if (it->dp
4894 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
4895 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
4896 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
4897 else
4898 escape_glyph = FAST_MAKE_GLYPH ('\\', 0);
4900 if (SINGLE_BYTE_CHAR_P (it->c))
4901 str[0] = it->c, len = 1;
4902 else
4904 len = CHAR_STRING_NO_SIGNAL (it->c, str);
4905 if (len < 0)
4907 /* It's an invalid character, which
4908 shouldn't happen actually, but due to
4909 bugs it may happen. Let's print the char
4910 as is, there's not much meaningful we can
4911 do with it. */
4912 str[0] = it->c;
4913 str[1] = it->c >> 8;
4914 str[2] = it->c >> 16;
4915 str[3] = it->c >> 24;
4916 len = 4;
4920 for (i = 0; i < len; i++)
4922 XSETINT (it->ctl_chars[i * 4], escape_glyph);
4923 /* Insert three more glyphs into IT->ctl_chars for
4924 the octal display of the character. */
4925 g = FAST_MAKE_GLYPH (((str[i] >> 6) & 7) + '0', 0);
4926 XSETINT (it->ctl_chars[i * 4 + 1], g);
4927 g = FAST_MAKE_GLYPH (((str[i] >> 3) & 7) + '0', 0);
4928 XSETINT (it->ctl_chars[i * 4 + 2], g);
4929 g = FAST_MAKE_GLYPH ((str[i] & 7) + '0', 0);
4930 XSETINT (it->ctl_chars[i * 4 + 3], g);
4933 /* Set up IT->dpvec and return the first character
4934 from it. */
4935 it->dpvec_char_len = it->len;
4936 it->dpvec = it->ctl_chars;
4937 it->dpend = it->dpvec + len * 4;
4938 it->current.dpvec_index = 0;
4939 it->method = next_element_from_display_vector;
4940 get_next_display_element (it);
4945 /* Adjust face id for a multibyte character. There are no
4946 multibyte character in unibyte text. */
4947 if (it->multibyte_p
4948 && success_p
4949 && FRAME_WINDOW_P (it->f))
4951 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4952 it->face_id = FACE_FOR_CHAR (it->f, face, it->c);
4956 /* Is this character the last one of a run of characters with
4957 box? If yes, set IT->end_of_box_run_p to 1. */
4958 if (it->face_box_p
4959 && it->s == NULL)
4961 int face_id;
4962 struct face *face;
4964 it->end_of_box_run_p
4965 = ((face_id = face_after_it_pos (it),
4966 face_id != it->face_id)
4967 && (face = FACE_FROM_ID (it->f, face_id),
4968 face->box == FACE_NO_BOX));
4971 /* Value is 0 if end of buffer or string reached. */
4972 return success_p;
4976 /* Move IT to the next display element.
4978 RESEAT_P non-zero means if called on a newline in buffer text,
4979 skip to the next visible line start.
4981 Functions get_next_display_element and set_iterator_to_next are
4982 separate because I find this arrangement easier to handle than a
4983 get_next_display_element function that also increments IT's
4984 position. The way it is we can first look at an iterator's current
4985 display element, decide whether it fits on a line, and if it does,
4986 increment the iterator position. The other way around we probably
4987 would either need a flag indicating whether the iterator has to be
4988 incremented the next time, or we would have to implement a
4989 decrement position function which would not be easy to write. */
4991 void
4992 set_iterator_to_next (it, reseat_p)
4993 struct it *it;
4994 int reseat_p;
4996 /* Reset flags indicating start and end of a sequence of characters
4997 with box. Reset them at the start of this function because
4998 moving the iterator to a new position might set them. */
4999 it->start_of_box_run_p = it->end_of_box_run_p = 0;
5001 if (it->method == next_element_from_buffer)
5003 /* The current display element of IT is a character from
5004 current_buffer. Advance in the buffer, and maybe skip over
5005 invisible lines that are so because of selective display. */
5006 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
5007 reseat_at_next_visible_line_start (it, 0);
5008 else
5010 xassert (it->len != 0);
5011 IT_BYTEPOS (*it) += it->len;
5012 IT_CHARPOS (*it) += 1;
5013 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
5016 else if (it->method == next_element_from_composition)
5018 xassert (it->cmp_id >= 0 && it ->cmp_id < n_compositions);
5019 if (STRINGP (it->string))
5021 IT_STRING_BYTEPOS (*it) += it->len;
5022 IT_STRING_CHARPOS (*it) += it->cmp_len;
5023 it->method = next_element_from_string;
5024 goto consider_string_end;
5026 else
5028 IT_BYTEPOS (*it) += it->len;
5029 IT_CHARPOS (*it) += it->cmp_len;
5030 it->method = next_element_from_buffer;
5033 else if (it->method == next_element_from_c_string)
5035 /* Current display element of IT is from a C string. */
5036 IT_BYTEPOS (*it) += it->len;
5037 IT_CHARPOS (*it) += 1;
5039 else if (it->method == next_element_from_display_vector)
5041 /* Current display element of IT is from a display table entry.
5042 Advance in the display table definition. Reset it to null if
5043 end reached, and continue with characters from buffers/
5044 strings. */
5045 ++it->current.dpvec_index;
5047 /* Restore face of the iterator to what they were before the
5048 display vector entry (these entries may contain faces). */
5049 it->face_id = it->saved_face_id;
5051 if (it->dpvec + it->current.dpvec_index == it->dpend)
5053 if (it->s)
5054 it->method = next_element_from_c_string;
5055 else if (STRINGP (it->string))
5056 it->method = next_element_from_string;
5057 else
5058 it->method = next_element_from_buffer;
5060 it->dpvec = NULL;
5061 it->current.dpvec_index = -1;
5063 /* Skip over characters which were displayed via IT->dpvec. */
5064 if (it->dpvec_char_len < 0)
5065 reseat_at_next_visible_line_start (it, 1);
5066 else if (it->dpvec_char_len > 0)
5068 it->len = it->dpvec_char_len;
5069 set_iterator_to_next (it, reseat_p);
5073 else if (it->method == next_element_from_string)
5075 /* Current display element is a character from a Lisp string. */
5076 xassert (it->s == NULL && STRINGP (it->string));
5077 IT_STRING_BYTEPOS (*it) += it->len;
5078 IT_STRING_CHARPOS (*it) += 1;
5080 consider_string_end:
5082 if (it->current.overlay_string_index >= 0)
5084 /* IT->string is an overlay string. Advance to the
5085 next, if there is one. */
5086 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5087 next_overlay_string (it);
5089 else
5091 /* IT->string is not an overlay string. If we reached
5092 its end, and there is something on IT->stack, proceed
5093 with what is on the stack. This can be either another
5094 string, this time an overlay string, or a buffer. */
5095 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
5096 && it->sp > 0)
5098 pop_it (it);
5099 if (!STRINGP (it->string))
5100 it->method = next_element_from_buffer;
5101 else
5102 goto consider_string_end;
5106 else if (it->method == next_element_from_image
5107 || it->method == next_element_from_stretch)
5109 /* The position etc with which we have to proceed are on
5110 the stack. The position may be at the end of a string,
5111 if the `display' property takes up the whole string. */
5112 pop_it (it);
5113 it->image_id = 0;
5114 if (STRINGP (it->string))
5116 it->method = next_element_from_string;
5117 goto consider_string_end;
5119 else
5120 it->method = next_element_from_buffer;
5122 else
5123 /* There are no other methods defined, so this should be a bug. */
5124 abort ();
5126 xassert (it->method != next_element_from_string
5127 || (STRINGP (it->string)
5128 && IT_STRING_CHARPOS (*it) >= 0));
5132 /* Load IT's display element fields with information about the next
5133 display element which comes from a display table entry or from the
5134 result of translating a control character to one of the forms `^C'
5135 or `\003'. IT->dpvec holds the glyphs to return as characters. */
5137 static int
5138 next_element_from_display_vector (it)
5139 struct it *it;
5141 /* Precondition. */
5142 xassert (it->dpvec && it->current.dpvec_index >= 0);
5144 /* Remember the current face id in case glyphs specify faces.
5145 IT's face is restored in set_iterator_to_next. */
5146 it->saved_face_id = it->face_id;
5148 if (INTEGERP (*it->dpvec)
5149 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
5151 int lface_id;
5152 GLYPH g;
5154 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
5155 it->c = FAST_GLYPH_CHAR (g);
5156 it->len = CHAR_BYTES (it->c);
5158 /* The entry may contain a face id to use. Such a face id is
5159 the id of a Lisp face, not a realized face. A face id of
5160 zero means no face is specified. */
5161 lface_id = FAST_GLYPH_FACE (g);
5162 if (lface_id)
5164 /* The function returns -1 if lface_id is invalid. */
5165 int face_id = ascii_face_of_lisp_face (it->f, lface_id);
5166 if (face_id >= 0)
5167 it->face_id = face_id;
5170 else
5171 /* Display table entry is invalid. Return a space. */
5172 it->c = ' ', it->len = 1;
5174 /* Don't change position and object of the iterator here. They are
5175 still the values of the character that had this display table
5176 entry or was translated, and that's what we want. */
5177 it->what = IT_CHARACTER;
5178 return 1;
5182 /* Load IT with the next display element from Lisp string IT->string.
5183 IT->current.string_pos is the current position within the string.
5184 If IT->current.overlay_string_index >= 0, the Lisp string is an
5185 overlay string. */
5187 static int
5188 next_element_from_string (it)
5189 struct it *it;
5191 struct text_pos position;
5193 xassert (STRINGP (it->string));
5194 xassert (IT_STRING_CHARPOS (*it) >= 0);
5195 position = it->current.string_pos;
5197 /* Time to check for invisible text? */
5198 if (IT_STRING_CHARPOS (*it) < it->end_charpos
5199 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
5201 handle_stop (it);
5203 /* Since a handler may have changed IT->method, we must
5204 recurse here. */
5205 return get_next_display_element (it);
5208 if (it->current.overlay_string_index >= 0)
5210 /* Get the next character from an overlay string. In overlay
5211 strings, There is no field width or padding with spaces to
5212 do. */
5213 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5215 it->what = IT_EOB;
5216 return 0;
5218 else if (STRING_MULTIBYTE (it->string))
5220 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5221 const unsigned char *s = (SDATA (it->string)
5222 + IT_STRING_BYTEPOS (*it));
5223 it->c = string_char_and_length (s, remaining, &it->len);
5225 else
5227 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5228 it->len = 1;
5231 else
5233 /* Get the next character from a Lisp string that is not an
5234 overlay string. Such strings come from the mode line, for
5235 example. We may have to pad with spaces, or truncate the
5236 string. See also next_element_from_c_string. */
5237 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
5239 it->what = IT_EOB;
5240 return 0;
5242 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
5244 /* Pad with spaces. */
5245 it->c = ' ', it->len = 1;
5246 CHARPOS (position) = BYTEPOS (position) = -1;
5248 else if (STRING_MULTIBYTE (it->string))
5250 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5251 const unsigned char *s = (SDATA (it->string)
5252 + IT_STRING_BYTEPOS (*it));
5253 it->c = string_char_and_length (s, maxlen, &it->len);
5255 else
5257 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5258 it->len = 1;
5262 /* Record what we have and where it came from. Note that we store a
5263 buffer position in IT->position although it could arguably be a
5264 string position. */
5265 it->what = IT_CHARACTER;
5266 it->object = it->string;
5267 it->position = position;
5268 return 1;
5272 /* Load IT with next display element from C string IT->s.
5273 IT->string_nchars is the maximum number of characters to return
5274 from the string. IT->end_charpos may be greater than
5275 IT->string_nchars when this function is called, in which case we
5276 may have to return padding spaces. Value is zero if end of string
5277 reached, including padding spaces. */
5279 static int
5280 next_element_from_c_string (it)
5281 struct it *it;
5283 int success_p = 1;
5285 xassert (it->s);
5286 it->what = IT_CHARACTER;
5287 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
5288 it->object = Qnil;
5290 /* IT's position can be greater IT->string_nchars in case a field
5291 width or precision has been specified when the iterator was
5292 initialized. */
5293 if (IT_CHARPOS (*it) >= it->end_charpos)
5295 /* End of the game. */
5296 it->what = IT_EOB;
5297 success_p = 0;
5299 else if (IT_CHARPOS (*it) >= it->string_nchars)
5301 /* Pad with spaces. */
5302 it->c = ' ', it->len = 1;
5303 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
5305 else if (it->multibyte_p)
5307 /* Implementation note: The calls to strlen apparently aren't a
5308 performance problem because there is no noticeable performance
5309 difference between Emacs running in unibyte or multibyte mode. */
5310 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
5311 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
5312 maxlen, &it->len);
5314 else
5315 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
5317 return success_p;
5321 /* Set up IT to return characters from an ellipsis, if appropriate.
5322 The definition of the ellipsis glyphs may come from a display table
5323 entry. This function Fills IT with the first glyph from the
5324 ellipsis if an ellipsis is to be displayed. */
5326 static int
5327 next_element_from_ellipsis (it)
5328 struct it *it;
5330 if (it->selective_display_ellipsis_p)
5332 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
5334 /* Use the display table definition for `...'. Invalid glyphs
5335 will be handled by the method returning elements from dpvec. */
5336 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
5337 it->dpvec_char_len = it->len;
5338 it->dpvec = v->contents;
5339 it->dpend = v->contents + v->size;
5340 it->current.dpvec_index = 0;
5341 it->method = next_element_from_display_vector;
5343 else
5345 /* Use default `...' which is stored in default_invis_vector. */
5346 it->dpvec_char_len = it->len;
5347 it->dpvec = default_invis_vector;
5348 it->dpend = default_invis_vector + 3;
5349 it->current.dpvec_index = 0;
5350 it->method = next_element_from_display_vector;
5353 else
5355 /* The face at the current position may be different from the
5356 face we find after the invisible text. Remember what it
5357 was in IT->saved_face_id, and signal that it's there by
5358 setting face_before_selective_p. */
5359 it->saved_face_id = it->face_id;
5360 it->method = next_element_from_buffer;
5361 reseat_at_next_visible_line_start (it, 1);
5362 it->face_before_selective_p = 1;
5365 return get_next_display_element (it);
5369 /* Deliver an image display element. The iterator IT is already
5370 filled with image information (done in handle_display_prop). Value
5371 is always 1. */
5374 static int
5375 next_element_from_image (it)
5376 struct it *it;
5378 it->what = IT_IMAGE;
5379 return 1;
5383 /* Fill iterator IT with next display element from a stretch glyph
5384 property. IT->object is the value of the text property. Value is
5385 always 1. */
5387 static int
5388 next_element_from_stretch (it)
5389 struct it *it;
5391 it->what = IT_STRETCH;
5392 return 1;
5396 /* Load IT with the next display element from current_buffer. Value
5397 is zero if end of buffer reached. IT->stop_charpos is the next
5398 position at which to stop and check for text properties or buffer
5399 end. */
5401 static int
5402 next_element_from_buffer (it)
5403 struct it *it;
5405 int success_p = 1;
5407 /* Check this assumption, otherwise, we would never enter the
5408 if-statement, below. */
5409 xassert (IT_CHARPOS (*it) >= BEGV
5410 && IT_CHARPOS (*it) <= it->stop_charpos);
5412 if (IT_CHARPOS (*it) >= it->stop_charpos)
5414 if (IT_CHARPOS (*it) >= it->end_charpos)
5416 int overlay_strings_follow_p;
5418 /* End of the game, except when overlay strings follow that
5419 haven't been returned yet. */
5420 if (it->overlay_strings_at_end_processed_p)
5421 overlay_strings_follow_p = 0;
5422 else
5424 it->overlay_strings_at_end_processed_p = 1;
5425 overlay_strings_follow_p = get_overlay_strings (it, 0);
5428 if (overlay_strings_follow_p)
5429 success_p = get_next_display_element (it);
5430 else
5432 it->what = IT_EOB;
5433 it->position = it->current.pos;
5434 success_p = 0;
5437 else
5439 handle_stop (it);
5440 return get_next_display_element (it);
5443 else
5445 /* No face changes, overlays etc. in sight, so just return a
5446 character from current_buffer. */
5447 unsigned char *p;
5449 /* Maybe run the redisplay end trigger hook. Performance note:
5450 This doesn't seem to cost measurable time. */
5451 if (it->redisplay_end_trigger_charpos
5452 && it->glyph_row
5453 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
5454 run_redisplay_end_trigger_hook (it);
5456 /* Get the next character, maybe multibyte. */
5457 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
5458 if (it->multibyte_p && !ASCII_BYTE_P (*p))
5460 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
5461 - IT_BYTEPOS (*it));
5462 it->c = string_char_and_length (p, maxlen, &it->len);
5464 else
5465 it->c = *p, it->len = 1;
5467 /* Record what we have and where it came from. */
5468 it->what = IT_CHARACTER;;
5469 it->object = it->w->buffer;
5470 it->position = it->current.pos;
5472 /* Normally we return the character found above, except when we
5473 really want to return an ellipsis for selective display. */
5474 if (it->selective)
5476 if (it->c == '\n')
5478 /* A value of selective > 0 means hide lines indented more
5479 than that number of columns. */
5480 if (it->selective > 0
5481 && IT_CHARPOS (*it) + 1 < ZV
5482 && indented_beyond_p (IT_CHARPOS (*it) + 1,
5483 IT_BYTEPOS (*it) + 1,
5484 (double) it->selective)) /* iftc */
5486 success_p = next_element_from_ellipsis (it);
5487 it->dpvec_char_len = -1;
5490 else if (it->c == '\r' && it->selective == -1)
5492 /* A value of selective == -1 means that everything from the
5493 CR to the end of the line is invisible, with maybe an
5494 ellipsis displayed for it. */
5495 success_p = next_element_from_ellipsis (it);
5496 it->dpvec_char_len = -1;
5501 /* Value is zero if end of buffer reached. */
5502 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
5503 return success_p;
5507 /* Run the redisplay end trigger hook for IT. */
5509 static void
5510 run_redisplay_end_trigger_hook (it)
5511 struct it *it;
5513 Lisp_Object args[3];
5515 /* IT->glyph_row should be non-null, i.e. we should be actually
5516 displaying something, or otherwise we should not run the hook. */
5517 xassert (it->glyph_row);
5519 /* Set up hook arguments. */
5520 args[0] = Qredisplay_end_trigger_functions;
5521 args[1] = it->window;
5522 XSETINT (args[2], it->redisplay_end_trigger_charpos);
5523 it->redisplay_end_trigger_charpos = 0;
5525 /* Since we are *trying* to run these functions, don't try to run
5526 them again, even if they get an error. */
5527 it->w->redisplay_end_trigger = Qnil;
5528 Frun_hook_with_args (3, args);
5530 /* Notice if it changed the face of the character we are on. */
5531 handle_face_prop (it);
5535 /* Deliver a composition display element. The iterator IT is already
5536 filled with composition information (done in
5537 handle_composition_prop). Value is always 1. */
5539 static int
5540 next_element_from_composition (it)
5541 struct it *it;
5543 it->what = IT_COMPOSITION;
5544 it->position = (STRINGP (it->string)
5545 ? it->current.string_pos
5546 : it->current.pos);
5547 return 1;
5552 /***********************************************************************
5553 Moving an iterator without producing glyphs
5554 ***********************************************************************/
5556 /* Move iterator IT to a specified buffer or X position within one
5557 line on the display without producing glyphs.
5559 OP should be a bit mask including some or all of these bits:
5560 MOVE_TO_X: Stop on reaching x-position TO_X.
5561 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
5562 Regardless of OP's value, stop in reaching the end of the display line.
5564 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
5565 This means, in particular, that TO_X includes window's horizontal
5566 scroll amount.
5568 The return value has several possible values that
5569 say what condition caused the scan to stop:
5571 MOVE_POS_MATCH_OR_ZV
5572 - when TO_POS or ZV was reached.
5574 MOVE_X_REACHED
5575 -when TO_X was reached before TO_POS or ZV were reached.
5577 MOVE_LINE_CONTINUED
5578 - when we reached the end of the display area and the line must
5579 be continued.
5581 MOVE_LINE_TRUNCATED
5582 - when we reached the end of the display area and the line is
5583 truncated.
5585 MOVE_NEWLINE_OR_CR
5586 - when we stopped at a line end, i.e. a newline or a CR and selective
5587 display is on. */
5589 static enum move_it_result
5590 move_it_in_display_line_to (it, to_charpos, to_x, op)
5591 struct it *it;
5592 int to_charpos, to_x, op;
5594 enum move_it_result result = MOVE_UNDEFINED;
5595 struct glyph_row *saved_glyph_row;
5597 /* Don't produce glyphs in produce_glyphs. */
5598 saved_glyph_row = it->glyph_row;
5599 it->glyph_row = NULL;
5601 while (1)
5603 int x, i, ascent = 0, descent = 0;
5605 /* Stop when ZV or TO_CHARPOS reached. */
5606 if (!get_next_display_element (it)
5607 || ((op & MOVE_TO_POS) != 0
5608 && BUFFERP (it->object)
5609 && IT_CHARPOS (*it) >= to_charpos))
5611 result = MOVE_POS_MATCH_OR_ZV;
5612 break;
5615 /* The call to produce_glyphs will get the metrics of the
5616 display element IT is loaded with. We record in x the
5617 x-position before this display element in case it does not
5618 fit on the line. */
5619 x = it->current_x;
5621 /* Remember the line height so far in case the next element doesn't
5622 fit on the line. */
5623 if (!it->truncate_lines_p)
5625 ascent = it->max_ascent;
5626 descent = it->max_descent;
5629 PRODUCE_GLYPHS (it);
5631 if (it->area != TEXT_AREA)
5633 set_iterator_to_next (it, 1);
5634 continue;
5637 /* The number of glyphs we get back in IT->nglyphs will normally
5638 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
5639 character on a terminal frame, or (iii) a line end. For the
5640 second case, IT->nglyphs - 1 padding glyphs will be present
5641 (on X frames, there is only one glyph produced for a
5642 composite character.
5644 The behavior implemented below means, for continuation lines,
5645 that as many spaces of a TAB as fit on the current line are
5646 displayed there. For terminal frames, as many glyphs of a
5647 multi-glyph character are displayed in the current line, too.
5648 This is what the old redisplay code did, and we keep it that
5649 way. Under X, the whole shape of a complex character must
5650 fit on the line or it will be completely displayed in the
5651 next line.
5653 Note that both for tabs and padding glyphs, all glyphs have
5654 the same width. */
5655 if (it->nglyphs)
5657 /* More than one glyph or glyph doesn't fit on line. All
5658 glyphs have the same width. */
5659 int single_glyph_width = it->pixel_width / it->nglyphs;
5660 int new_x;
5662 for (i = 0; i < it->nglyphs; ++i, x = new_x)
5664 new_x = x + single_glyph_width;
5666 /* We want to leave anything reaching TO_X to the caller. */
5667 if ((op & MOVE_TO_X) && new_x > to_x)
5669 it->current_x = x;
5670 result = MOVE_X_REACHED;
5671 break;
5673 else if (/* Lines are continued. */
5674 !it->truncate_lines_p
5675 && (/* And glyph doesn't fit on the line. */
5676 new_x > it->last_visible_x
5677 /* Or it fits exactly and we're on a window
5678 system frame. */
5679 || (new_x == it->last_visible_x
5680 && FRAME_WINDOW_P (it->f))))
5682 if (/* IT->hpos == 0 means the very first glyph
5683 doesn't fit on the line, e.g. a wide image. */
5684 it->hpos == 0
5685 || (new_x == it->last_visible_x
5686 && FRAME_WINDOW_P (it->f)))
5688 ++it->hpos;
5689 it->current_x = new_x;
5690 if (i == it->nglyphs - 1)
5692 set_iterator_to_next (it, 1);
5693 #ifdef HAVE_WINDOW_SYSTEM
5694 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
5696 if (!get_next_display_element (it))
5698 result = MOVE_POS_MATCH_OR_ZV;
5699 break;
5701 if (ITERATOR_AT_END_OF_LINE_P (it))
5703 result = MOVE_NEWLINE_OR_CR;
5704 break;
5707 #endif /* HAVE_WINDOW_SYSTEM */
5710 else
5712 it->current_x = x;
5713 it->max_ascent = ascent;
5714 it->max_descent = descent;
5717 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
5718 IT_CHARPOS (*it)));
5719 result = MOVE_LINE_CONTINUED;
5720 break;
5722 else if (new_x > it->first_visible_x)
5724 /* Glyph is visible. Increment number of glyphs that
5725 would be displayed. */
5726 ++it->hpos;
5728 else
5730 /* Glyph is completely off the left margin of the display
5731 area. Nothing to do. */
5735 if (result != MOVE_UNDEFINED)
5736 break;
5738 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
5740 /* Stop when TO_X specified and reached. This check is
5741 necessary here because of lines consisting of a line end,
5742 only. The line end will not produce any glyphs and we
5743 would never get MOVE_X_REACHED. */
5744 xassert (it->nglyphs == 0);
5745 result = MOVE_X_REACHED;
5746 break;
5749 /* Is this a line end? If yes, we're done. */
5750 if (ITERATOR_AT_END_OF_LINE_P (it))
5752 result = MOVE_NEWLINE_OR_CR;
5753 break;
5756 /* The current display element has been consumed. Advance
5757 to the next. */
5758 set_iterator_to_next (it, 1);
5760 /* Stop if lines are truncated and IT's current x-position is
5761 past the right edge of the window now. */
5762 if (it->truncate_lines_p
5763 && it->current_x >= it->last_visible_x)
5765 #ifdef HAVE_WINDOW_SYSTEM
5766 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
5768 if (!get_next_display_element (it))
5770 result = MOVE_POS_MATCH_OR_ZV;
5771 break;
5773 if (ITERATOR_AT_END_OF_LINE_P (it))
5775 result = MOVE_NEWLINE_OR_CR;
5776 break;
5779 #endif /* HAVE_WINDOW_SYSTEM */
5780 result = MOVE_LINE_TRUNCATED;
5781 break;
5785 /* Restore the iterator settings altered at the beginning of this
5786 function. */
5787 it->glyph_row = saved_glyph_row;
5788 return result;
5792 /* Move IT forward until it satisfies one or more of the criteria in
5793 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
5795 OP is a bit-mask that specifies where to stop, and in particular,
5796 which of those four position arguments makes a difference. See the
5797 description of enum move_operation_enum.
5799 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
5800 screen line, this function will set IT to the next position >
5801 TO_CHARPOS. */
5803 void
5804 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
5805 struct it *it;
5806 int to_charpos, to_x, to_y, to_vpos;
5807 int op;
5809 enum move_it_result skip, skip2 = MOVE_X_REACHED;
5810 int line_height;
5811 int reached = 0;
5813 for (;;)
5815 if (op & MOVE_TO_VPOS)
5817 /* If no TO_CHARPOS and no TO_X specified, stop at the
5818 start of the line TO_VPOS. */
5819 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
5821 if (it->vpos == to_vpos)
5823 reached = 1;
5824 break;
5826 else
5827 skip = move_it_in_display_line_to (it, -1, -1, 0);
5829 else
5831 /* TO_VPOS >= 0 means stop at TO_X in the line at
5832 TO_VPOS, or at TO_POS, whichever comes first. */
5833 if (it->vpos == to_vpos)
5835 reached = 2;
5836 break;
5839 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
5841 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
5843 reached = 3;
5844 break;
5846 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
5848 /* We have reached TO_X but not in the line we want. */
5849 skip = move_it_in_display_line_to (it, to_charpos,
5850 -1, MOVE_TO_POS);
5851 if (skip == MOVE_POS_MATCH_OR_ZV)
5853 reached = 4;
5854 break;
5859 else if (op & MOVE_TO_Y)
5861 struct it it_backup;
5863 /* TO_Y specified means stop at TO_X in the line containing
5864 TO_Y---or at TO_CHARPOS if this is reached first. The
5865 problem is that we can't really tell whether the line
5866 contains TO_Y before we have completely scanned it, and
5867 this may skip past TO_X. What we do is to first scan to
5868 TO_X.
5870 If TO_X is not specified, use a TO_X of zero. The reason
5871 is to make the outcome of this function more predictable.
5872 If we didn't use TO_X == 0, we would stop at the end of
5873 the line which is probably not what a caller would expect
5874 to happen. */
5875 skip = move_it_in_display_line_to (it, to_charpos,
5876 ((op & MOVE_TO_X)
5877 ? to_x : 0),
5878 (MOVE_TO_X
5879 | (op & MOVE_TO_POS)));
5881 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
5882 if (skip == MOVE_POS_MATCH_OR_ZV)
5884 reached = 5;
5885 break;
5888 /* If TO_X was reached, we would like to know whether TO_Y
5889 is in the line. This can only be said if we know the
5890 total line height which requires us to scan the rest of
5891 the line. */
5892 if (skip == MOVE_X_REACHED)
5894 it_backup = *it;
5895 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
5896 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
5897 op & MOVE_TO_POS);
5898 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
5901 /* Now, decide whether TO_Y is in this line. */
5902 line_height = it->max_ascent + it->max_descent;
5903 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
5905 if (to_y >= it->current_y
5906 && to_y < it->current_y + line_height)
5908 if (skip == MOVE_X_REACHED)
5909 /* If TO_Y is in this line and TO_X was reached above,
5910 we scanned too far. We have to restore IT's settings
5911 to the ones before skipping. */
5912 *it = it_backup;
5913 reached = 6;
5915 else if (skip == MOVE_X_REACHED)
5917 skip = skip2;
5918 if (skip == MOVE_POS_MATCH_OR_ZV)
5919 reached = 7;
5922 if (reached)
5923 break;
5925 else
5926 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
5928 switch (skip)
5930 case MOVE_POS_MATCH_OR_ZV:
5931 reached = 8;
5932 goto out;
5934 case MOVE_NEWLINE_OR_CR:
5935 set_iterator_to_next (it, 1);
5936 it->continuation_lines_width = 0;
5937 break;
5939 case MOVE_LINE_TRUNCATED:
5940 it->continuation_lines_width = 0;
5941 reseat_at_next_visible_line_start (it, 0);
5942 if ((op & MOVE_TO_POS) != 0
5943 && IT_CHARPOS (*it) > to_charpos)
5945 reached = 9;
5946 goto out;
5948 break;
5950 case MOVE_LINE_CONTINUED:
5951 it->continuation_lines_width += it->current_x;
5952 break;
5954 default:
5955 abort ();
5958 /* Reset/increment for the next run. */
5959 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
5960 it->current_x = it->hpos = 0;
5961 it->current_y += it->max_ascent + it->max_descent;
5962 ++it->vpos;
5963 last_height = it->max_ascent + it->max_descent;
5964 last_max_ascent = it->max_ascent;
5965 it->max_ascent = it->max_descent = 0;
5968 out:
5970 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
5974 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
5976 If DY > 0, move IT backward at least that many pixels. DY = 0
5977 means move IT backward to the preceding line start or BEGV. This
5978 function may move over more than DY pixels if IT->current_y - DY
5979 ends up in the middle of a line; in this case IT->current_y will be
5980 set to the top of the line moved to. */
5982 void
5983 move_it_vertically_backward (it, dy)
5984 struct it *it;
5985 int dy;
5987 int nlines, h;
5988 struct it it2, it3;
5989 int start_pos = IT_CHARPOS (*it);
5991 xassert (dy >= 0);
5993 /* Estimate how many newlines we must move back. */
5994 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
5996 /* Set the iterator's position that many lines back. */
5997 while (nlines-- && IT_CHARPOS (*it) > BEGV)
5998 back_to_previous_visible_line_start (it);
6000 /* Reseat the iterator here. When moving backward, we don't want
6001 reseat to skip forward over invisible text, set up the iterator
6002 to deliver from overlay strings at the new position etc. So,
6003 use reseat_1 here. */
6004 reseat_1 (it, it->current.pos, 1);
6006 /* We are now surely at a line start. */
6007 it->current_x = it->hpos = 0;
6008 it->continuation_lines_width = 0;
6010 /* Move forward and see what y-distance we moved. First move to the
6011 start of the next line so that we get its height. We need this
6012 height to be able to tell whether we reached the specified
6013 y-distance. */
6014 it2 = *it;
6015 it2.max_ascent = it2.max_descent = 0;
6016 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
6017 MOVE_TO_POS | MOVE_TO_VPOS);
6018 xassert (IT_CHARPOS (*it) >= BEGV);
6019 it3 = it2;
6021 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
6022 xassert (IT_CHARPOS (*it) >= BEGV);
6023 /* H is the actual vertical distance from the position in *IT
6024 and the starting position. */
6025 h = it2.current_y - it->current_y;
6026 /* NLINES is the distance in number of lines. */
6027 nlines = it2.vpos - it->vpos;
6029 /* Correct IT's y and vpos position
6030 so that they are relative to the starting point. */
6031 it->vpos -= nlines;
6032 it->current_y -= h;
6034 if (dy == 0)
6036 /* DY == 0 means move to the start of the screen line. The
6037 value of nlines is > 0 if continuation lines were involved. */
6038 if (nlines > 0)
6039 move_it_by_lines (it, nlines, 1);
6040 xassert (IT_CHARPOS (*it) <= start_pos);
6042 else
6044 /* The y-position we try to reach, relative to *IT.
6045 Note that H has been subtracted in front of the if-statement. */
6046 int target_y = it->current_y + h - dy;
6047 int y0 = it3.current_y;
6048 int y1 = line_bottom_y (&it3);
6049 int line_height = y1 - y0;
6051 /* If we did not reach target_y, try to move further backward if
6052 we can. If we moved too far backward, try to move forward. */
6053 if (target_y < it->current_y
6054 /* This is heuristic. In a window that's 3 lines high, with
6055 a line height of 13 pixels each, recentering with point
6056 on the bottom line will try to move -39/2 = 19 pixels
6057 backward. Try to avoid moving into the first line. */
6058 && it->current_y - target_y > line_height / 3 * 2
6059 && IT_CHARPOS (*it) > BEGV)
6061 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
6062 target_y - it->current_y));
6063 move_it_vertically (it, target_y - it->current_y);
6064 xassert (IT_CHARPOS (*it) >= BEGV);
6066 else if (target_y >= it->current_y + line_height
6067 && IT_CHARPOS (*it) < ZV)
6069 /* Should move forward by at least one line, maybe more.
6071 Note: Calling move_it_by_lines can be expensive on
6072 terminal frames, where compute_motion is used (via
6073 vmotion) to do the job, when there are very long lines
6074 and truncate-lines is nil. That's the reason for
6075 treating terminal frames specially here. */
6077 if (!FRAME_WINDOW_P (it->f))
6078 move_it_vertically (it, target_y - (it->current_y + line_height));
6079 else
6083 move_it_by_lines (it, 1, 1);
6085 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
6088 xassert (IT_CHARPOS (*it) >= BEGV);
6094 /* Move IT by a specified amount of pixel lines DY. DY negative means
6095 move backwards. DY = 0 means move to start of screen line. At the
6096 end, IT will be on the start of a screen line. */
6098 void
6099 move_it_vertically (it, dy)
6100 struct it *it;
6101 int dy;
6103 if (dy <= 0)
6104 move_it_vertically_backward (it, -dy);
6105 else if (dy > 0)
6107 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
6108 move_it_to (it, ZV, -1, it->current_y + dy, -1,
6109 MOVE_TO_POS | MOVE_TO_Y);
6110 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
6112 /* If buffer ends in ZV without a newline, move to the start of
6113 the line to satisfy the post-condition. */
6114 if (IT_CHARPOS (*it) == ZV
6115 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
6116 move_it_by_lines (it, 0, 0);
6121 /* Move iterator IT past the end of the text line it is in. */
6123 void
6124 move_it_past_eol (it)
6125 struct it *it;
6127 enum move_it_result rc;
6129 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
6130 if (rc == MOVE_NEWLINE_OR_CR)
6131 set_iterator_to_next (it, 0);
6135 #if 0 /* Currently not used. */
6137 /* Return non-zero if some text between buffer positions START_CHARPOS
6138 and END_CHARPOS is invisible. IT->window is the window for text
6139 property lookup. */
6141 static int
6142 invisible_text_between_p (it, start_charpos, end_charpos)
6143 struct it *it;
6144 int start_charpos, end_charpos;
6146 Lisp_Object prop, limit;
6147 int invisible_found_p;
6149 xassert (it != NULL && start_charpos <= end_charpos);
6151 /* Is text at START invisible? */
6152 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
6153 it->window);
6154 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6155 invisible_found_p = 1;
6156 else
6158 limit = Fnext_single_char_property_change (make_number (start_charpos),
6159 Qinvisible, Qnil,
6160 make_number (end_charpos));
6161 invisible_found_p = XFASTINT (limit) < end_charpos;
6164 return invisible_found_p;
6167 #endif /* 0 */
6170 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
6171 negative means move up. DVPOS == 0 means move to the start of the
6172 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
6173 NEED_Y_P is zero, IT->current_y will be left unchanged.
6175 Further optimization ideas: If we would know that IT->f doesn't use
6176 a face with proportional font, we could be faster for
6177 truncate-lines nil. */
6179 void
6180 move_it_by_lines (it, dvpos, need_y_p)
6181 struct it *it;
6182 int dvpos, need_y_p;
6184 struct position pos;
6186 if (!FRAME_WINDOW_P (it->f))
6188 struct text_pos textpos;
6190 /* We can use vmotion on frames without proportional fonts. */
6191 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
6192 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
6193 reseat (it, textpos, 1);
6194 it->vpos += pos.vpos;
6195 it->current_y += pos.vpos;
6197 else if (dvpos == 0)
6199 /* DVPOS == 0 means move to the start of the screen line. */
6200 move_it_vertically_backward (it, 0);
6201 xassert (it->current_x == 0 && it->hpos == 0);
6203 else if (dvpos > 0)
6204 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
6205 else
6207 struct it it2;
6208 int start_charpos, i;
6210 /* Start at the beginning of the screen line containing IT's
6211 position. */
6212 move_it_vertically_backward (it, 0);
6214 /* Go back -DVPOS visible lines and reseat the iterator there. */
6215 start_charpos = IT_CHARPOS (*it);
6216 for (i = -dvpos; i && IT_CHARPOS (*it) > BEGV; --i)
6217 back_to_previous_visible_line_start (it);
6218 reseat (it, it->current.pos, 1);
6219 it->current_x = it->hpos = 0;
6221 /* Above call may have moved too far if continuation lines
6222 are involved. Scan forward and see if it did. */
6223 it2 = *it;
6224 it2.vpos = it2.current_y = 0;
6225 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
6226 it->vpos -= it2.vpos;
6227 it->current_y -= it2.current_y;
6228 it->current_x = it->hpos = 0;
6230 /* If we moved too far, move IT some lines forward. */
6231 if (it2.vpos > -dvpos)
6233 int delta = it2.vpos + dvpos;
6234 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
6239 /* Return 1 if IT points into the middle of a display vector. */
6242 in_display_vector_p (it)
6243 struct it *it;
6245 return (it->method == next_element_from_display_vector
6246 && it->current.dpvec_index > 0
6247 && it->dpvec + it->current.dpvec_index != it->dpend);
6251 /***********************************************************************
6252 Messages
6253 ***********************************************************************/
6256 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
6257 to *Messages*. */
6259 void
6260 add_to_log (format, arg1, arg2)
6261 char *format;
6262 Lisp_Object arg1, arg2;
6264 Lisp_Object args[3];
6265 Lisp_Object msg, fmt;
6266 char *buffer;
6267 int len;
6268 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
6270 /* Do nothing if called asynchronously. Inserting text into
6271 a buffer may call after-change-functions and alike and
6272 that would means running Lisp asynchronously. */
6273 if (handling_signal)
6274 return;
6276 fmt = msg = Qnil;
6277 GCPRO4 (fmt, msg, arg1, arg2);
6279 args[0] = fmt = build_string (format);
6280 args[1] = arg1;
6281 args[2] = arg2;
6282 msg = Fformat (3, args);
6284 len = SBYTES (msg) + 1;
6285 buffer = (char *) alloca (len);
6286 bcopy (SDATA (msg), buffer, len);
6288 message_dolog (buffer, len - 1, 1, 0);
6289 UNGCPRO;
6293 /* Output a newline in the *Messages* buffer if "needs" one. */
6295 void
6296 message_log_maybe_newline ()
6298 if (message_log_need_newline)
6299 message_dolog ("", 0, 1, 0);
6303 /* Add a string M of length NBYTES to the message log, optionally
6304 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
6305 nonzero, means interpret the contents of M as multibyte. This
6306 function calls low-level routines in order to bypass text property
6307 hooks, etc. which might not be safe to run. */
6309 void
6310 message_dolog (m, nbytes, nlflag, multibyte)
6311 const char *m;
6312 int nbytes, nlflag, multibyte;
6314 if (!NILP (Vmemory_full))
6315 return;
6317 if (!NILP (Vmessage_log_max))
6319 struct buffer *oldbuf;
6320 Lisp_Object oldpoint, oldbegv, oldzv;
6321 int old_windows_or_buffers_changed = windows_or_buffers_changed;
6322 int point_at_end = 0;
6323 int zv_at_end = 0;
6324 Lisp_Object old_deactivate_mark, tem;
6325 struct gcpro gcpro1;
6327 old_deactivate_mark = Vdeactivate_mark;
6328 oldbuf = current_buffer;
6329 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
6330 current_buffer->undo_list = Qt;
6332 oldpoint = message_dolog_marker1;
6333 set_marker_restricted (oldpoint, make_number (PT), Qnil);
6334 oldbegv = message_dolog_marker2;
6335 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
6336 oldzv = message_dolog_marker3;
6337 set_marker_restricted (oldzv, make_number (ZV), Qnil);
6338 GCPRO1 (old_deactivate_mark);
6340 if (PT == Z)
6341 point_at_end = 1;
6342 if (ZV == Z)
6343 zv_at_end = 1;
6345 BEGV = BEG;
6346 BEGV_BYTE = BEG_BYTE;
6347 ZV = Z;
6348 ZV_BYTE = Z_BYTE;
6349 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6351 /* Insert the string--maybe converting multibyte to single byte
6352 or vice versa, so that all the text fits the buffer. */
6353 if (multibyte
6354 && NILP (current_buffer->enable_multibyte_characters))
6356 int i, c, char_bytes;
6357 unsigned char work[1];
6359 /* Convert a multibyte string to single-byte
6360 for the *Message* buffer. */
6361 for (i = 0; i < nbytes; i += char_bytes)
6363 c = string_char_and_length (m + i, nbytes - i, &char_bytes);
6364 work[0] = (SINGLE_BYTE_CHAR_P (c)
6366 : multibyte_char_to_unibyte (c, Qnil));
6367 insert_1_both (work, 1, 1, 1, 0, 0);
6370 else if (! multibyte
6371 && ! NILP (current_buffer->enable_multibyte_characters))
6373 int i, c, char_bytes;
6374 unsigned char *msg = (unsigned char *) m;
6375 unsigned char str[MAX_MULTIBYTE_LENGTH];
6376 /* Convert a single-byte string to multibyte
6377 for the *Message* buffer. */
6378 for (i = 0; i < nbytes; i++)
6380 c = unibyte_char_to_multibyte (msg[i]);
6381 char_bytes = CHAR_STRING (c, str);
6382 insert_1_both (str, 1, char_bytes, 1, 0, 0);
6385 else if (nbytes)
6386 insert_1 (m, nbytes, 1, 0, 0);
6388 if (nlflag)
6390 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
6391 insert_1 ("\n", 1, 1, 0, 0);
6393 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
6394 this_bol = PT;
6395 this_bol_byte = PT_BYTE;
6397 /* See if this line duplicates the previous one.
6398 If so, combine duplicates. */
6399 if (this_bol > BEG)
6401 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
6402 prev_bol = PT;
6403 prev_bol_byte = PT_BYTE;
6405 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
6406 this_bol, this_bol_byte);
6407 if (dup)
6409 del_range_both (prev_bol, prev_bol_byte,
6410 this_bol, this_bol_byte, 0);
6411 if (dup > 1)
6413 char dupstr[40];
6414 int duplen;
6416 /* If you change this format, don't forget to also
6417 change message_log_check_duplicate. */
6418 sprintf (dupstr, " [%d times]", dup);
6419 duplen = strlen (dupstr);
6420 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
6421 insert_1 (dupstr, duplen, 1, 0, 1);
6426 /* If we have more than the desired maximum number of lines
6427 in the *Messages* buffer now, delete the oldest ones.
6428 This is safe because we don't have undo in this buffer. */
6430 if (NATNUMP (Vmessage_log_max))
6432 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
6433 -XFASTINT (Vmessage_log_max) - 1, 0);
6434 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
6437 BEGV = XMARKER (oldbegv)->charpos;
6438 BEGV_BYTE = marker_byte_position (oldbegv);
6440 if (zv_at_end)
6442 ZV = Z;
6443 ZV_BYTE = Z_BYTE;
6445 else
6447 ZV = XMARKER (oldzv)->charpos;
6448 ZV_BYTE = marker_byte_position (oldzv);
6451 if (point_at_end)
6452 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6453 else
6454 /* We can't do Fgoto_char (oldpoint) because it will run some
6455 Lisp code. */
6456 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
6457 XMARKER (oldpoint)->bytepos);
6459 UNGCPRO;
6460 unchain_marker (XMARKER (oldpoint));
6461 unchain_marker (XMARKER (oldbegv));
6462 unchain_marker (XMARKER (oldzv));
6464 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
6465 set_buffer_internal (oldbuf);
6466 if (NILP (tem))
6467 windows_or_buffers_changed = old_windows_or_buffers_changed;
6468 message_log_need_newline = !nlflag;
6469 Vdeactivate_mark = old_deactivate_mark;
6474 /* We are at the end of the buffer after just having inserted a newline.
6475 (Note: We depend on the fact we won't be crossing the gap.)
6476 Check to see if the most recent message looks a lot like the previous one.
6477 Return 0 if different, 1 if the new one should just replace it, or a
6478 value N > 1 if we should also append " [N times]". */
6480 static int
6481 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
6482 int prev_bol, this_bol;
6483 int prev_bol_byte, this_bol_byte;
6485 int i;
6486 int len = Z_BYTE - 1 - this_bol_byte;
6487 int seen_dots = 0;
6488 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
6489 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
6491 for (i = 0; i < len; i++)
6493 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
6494 seen_dots = 1;
6495 if (p1[i] != p2[i])
6496 return seen_dots;
6498 p1 += len;
6499 if (*p1 == '\n')
6500 return 2;
6501 if (*p1++ == ' ' && *p1++ == '[')
6503 int n = 0;
6504 while (*p1 >= '0' && *p1 <= '9')
6505 n = n * 10 + *p1++ - '0';
6506 if (strncmp (p1, " times]\n", 8) == 0)
6507 return n+1;
6509 return 0;
6513 /* Display an echo area message M with a specified length of NBYTES
6514 bytes. The string may include null characters. If M is 0, clear
6515 out any existing message, and let the mini-buffer text show
6516 through.
6518 The buffer M must continue to exist until after the echo area gets
6519 cleared or some other message gets displayed there. This means do
6520 not pass text that is stored in a Lisp string; do not pass text in
6521 a buffer that was alloca'd. */
6523 void
6524 message2 (m, nbytes, multibyte)
6525 const char *m;
6526 int nbytes;
6527 int multibyte;
6529 /* First flush out any partial line written with print. */
6530 message_log_maybe_newline ();
6531 if (m)
6532 message_dolog (m, nbytes, 1, multibyte);
6533 message2_nolog (m, nbytes, multibyte);
6537 /* The non-logging counterpart of message2. */
6539 void
6540 message2_nolog (m, nbytes, multibyte)
6541 const char *m;
6542 int nbytes, multibyte;
6544 struct frame *sf = SELECTED_FRAME ();
6545 message_enable_multibyte = multibyte;
6547 if (noninteractive)
6549 if (noninteractive_need_newline)
6550 putc ('\n', stderr);
6551 noninteractive_need_newline = 0;
6552 if (m)
6553 fwrite (m, nbytes, 1, stderr);
6554 if (cursor_in_echo_area == 0)
6555 fprintf (stderr, "\n");
6556 fflush (stderr);
6558 /* A null message buffer means that the frame hasn't really been
6559 initialized yet. Error messages get reported properly by
6560 cmd_error, so this must be just an informative message; toss it. */
6561 else if (INTERACTIVE
6562 && sf->glyphs_initialized_p
6563 && FRAME_MESSAGE_BUF (sf))
6565 Lisp_Object mini_window;
6566 struct frame *f;
6568 /* Get the frame containing the mini-buffer
6569 that the selected frame is using. */
6570 mini_window = FRAME_MINIBUF_WINDOW (sf);
6571 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6573 FRAME_SAMPLE_VISIBILITY (f);
6574 if (FRAME_VISIBLE_P (sf)
6575 && ! FRAME_VISIBLE_P (f))
6576 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
6578 if (m)
6580 set_message (m, Qnil, nbytes, multibyte);
6581 if (minibuffer_auto_raise)
6582 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
6584 else
6585 clear_message (1, 1);
6587 do_pending_window_change (0);
6588 echo_area_display (1);
6589 do_pending_window_change (0);
6590 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6591 (*frame_up_to_date_hook) (f);
6596 /* Display an echo area message M with a specified length of NBYTES
6597 bytes. The string may include null characters. If M is not a
6598 string, clear out any existing message, and let the mini-buffer
6599 text show through. */
6601 void
6602 message3 (m, nbytes, multibyte)
6603 Lisp_Object m;
6604 int nbytes;
6605 int multibyte;
6607 struct gcpro gcpro1;
6609 GCPRO1 (m);
6611 /* First flush out any partial line written with print. */
6612 message_log_maybe_newline ();
6613 if (STRINGP (m))
6614 message_dolog (SDATA (m), nbytes, 1, multibyte);
6615 message3_nolog (m, nbytes, multibyte);
6617 UNGCPRO;
6621 /* The non-logging version of message3. */
6623 void
6624 message3_nolog (m, nbytes, multibyte)
6625 Lisp_Object m;
6626 int nbytes, multibyte;
6628 struct frame *sf = SELECTED_FRAME ();
6629 message_enable_multibyte = multibyte;
6631 if (noninteractive)
6633 if (noninteractive_need_newline)
6634 putc ('\n', stderr);
6635 noninteractive_need_newline = 0;
6636 if (STRINGP (m))
6637 fwrite (SDATA (m), nbytes, 1, stderr);
6638 if (cursor_in_echo_area == 0)
6639 fprintf (stderr, "\n");
6640 fflush (stderr);
6642 /* A null message buffer means that the frame hasn't really been
6643 initialized yet. Error messages get reported properly by
6644 cmd_error, so this must be just an informative message; toss it. */
6645 else if (INTERACTIVE
6646 && sf->glyphs_initialized_p
6647 && FRAME_MESSAGE_BUF (sf))
6649 Lisp_Object mini_window;
6650 Lisp_Object frame;
6651 struct frame *f;
6653 /* Get the frame containing the mini-buffer
6654 that the selected frame is using. */
6655 mini_window = FRAME_MINIBUF_WINDOW (sf);
6656 frame = XWINDOW (mini_window)->frame;
6657 f = XFRAME (frame);
6659 FRAME_SAMPLE_VISIBILITY (f);
6660 if (FRAME_VISIBLE_P (sf)
6661 && !FRAME_VISIBLE_P (f))
6662 Fmake_frame_visible (frame);
6664 if (STRINGP (m) && SCHARS (m) > 0)
6666 set_message (NULL, m, nbytes, multibyte);
6667 if (minibuffer_auto_raise)
6668 Fraise_frame (frame);
6670 else
6671 clear_message (1, 1);
6673 do_pending_window_change (0);
6674 echo_area_display (1);
6675 do_pending_window_change (0);
6676 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6677 (*frame_up_to_date_hook) (f);
6682 /* Display a null-terminated echo area message M. If M is 0, clear
6683 out any existing message, and let the mini-buffer text show through.
6685 The buffer M must continue to exist until after the echo area gets
6686 cleared or some other message gets displayed there. Do not pass
6687 text that is stored in a Lisp string. Do not pass text in a buffer
6688 that was alloca'd. */
6690 void
6691 message1 (m)
6692 char *m;
6694 message2 (m, (m ? strlen (m) : 0), 0);
6698 /* The non-logging counterpart of message1. */
6700 void
6701 message1_nolog (m)
6702 char *m;
6704 message2_nolog (m, (m ? strlen (m) : 0), 0);
6707 /* Display a message M which contains a single %s
6708 which gets replaced with STRING. */
6710 void
6711 message_with_string (m, string, log)
6712 char *m;
6713 Lisp_Object string;
6714 int log;
6716 CHECK_STRING (string);
6718 if (noninteractive)
6720 if (m)
6722 if (noninteractive_need_newline)
6723 putc ('\n', stderr);
6724 noninteractive_need_newline = 0;
6725 fprintf (stderr, m, SDATA (string));
6726 if (cursor_in_echo_area == 0)
6727 fprintf (stderr, "\n");
6728 fflush (stderr);
6731 else if (INTERACTIVE)
6733 /* The frame whose minibuffer we're going to display the message on.
6734 It may be larger than the selected frame, so we need
6735 to use its buffer, not the selected frame's buffer. */
6736 Lisp_Object mini_window;
6737 struct frame *f, *sf = SELECTED_FRAME ();
6739 /* Get the frame containing the minibuffer
6740 that the selected frame is using. */
6741 mini_window = FRAME_MINIBUF_WINDOW (sf);
6742 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6744 /* A null message buffer means that the frame hasn't really been
6745 initialized yet. Error messages get reported properly by
6746 cmd_error, so this must be just an informative message; toss it. */
6747 if (FRAME_MESSAGE_BUF (f))
6749 Lisp_Object args[2], message;
6750 struct gcpro gcpro1, gcpro2;
6752 args[0] = build_string (m);
6753 args[1] = message = string;
6754 GCPRO2 (args[0], message);
6755 gcpro1.nvars = 2;
6757 message = Fformat (2, args);
6759 if (log)
6760 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
6761 else
6762 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
6764 UNGCPRO;
6766 /* Print should start at the beginning of the message
6767 buffer next time. */
6768 message_buf_print = 0;
6774 /* Dump an informative message to the minibuf. If M is 0, clear out
6775 any existing message, and let the mini-buffer text show through. */
6777 /* VARARGS 1 */
6778 void
6779 message (m, a1, a2, a3)
6780 char *m;
6781 EMACS_INT a1, a2, a3;
6783 if (noninteractive)
6785 if (m)
6787 if (noninteractive_need_newline)
6788 putc ('\n', stderr);
6789 noninteractive_need_newline = 0;
6790 fprintf (stderr, m, a1, a2, a3);
6791 if (cursor_in_echo_area == 0)
6792 fprintf (stderr, "\n");
6793 fflush (stderr);
6796 else if (INTERACTIVE)
6798 /* The frame whose mini-buffer we're going to display the message
6799 on. It may be larger than the selected frame, so we need to
6800 use its buffer, not the selected frame's buffer. */
6801 Lisp_Object mini_window;
6802 struct frame *f, *sf = SELECTED_FRAME ();
6804 /* Get the frame containing the mini-buffer
6805 that the selected frame is using. */
6806 mini_window = FRAME_MINIBUF_WINDOW (sf);
6807 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6809 /* A null message buffer means that the frame hasn't really been
6810 initialized yet. Error messages get reported properly by
6811 cmd_error, so this must be just an informative message; toss
6812 it. */
6813 if (FRAME_MESSAGE_BUF (f))
6815 if (m)
6817 int len;
6818 #ifdef NO_ARG_ARRAY
6819 char *a[3];
6820 a[0] = (char *) a1;
6821 a[1] = (char *) a2;
6822 a[2] = (char *) a3;
6824 len = doprnt (FRAME_MESSAGE_BUF (f),
6825 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
6826 #else
6827 len = doprnt (FRAME_MESSAGE_BUF (f),
6828 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
6829 (char **) &a1);
6830 #endif /* NO_ARG_ARRAY */
6832 message2 (FRAME_MESSAGE_BUF (f), len, 0);
6834 else
6835 message1 (0);
6837 /* Print should start at the beginning of the message
6838 buffer next time. */
6839 message_buf_print = 0;
6845 /* The non-logging version of message. */
6847 void
6848 message_nolog (m, a1, a2, a3)
6849 char *m;
6850 EMACS_INT a1, a2, a3;
6852 Lisp_Object old_log_max;
6853 old_log_max = Vmessage_log_max;
6854 Vmessage_log_max = Qnil;
6855 message (m, a1, a2, a3);
6856 Vmessage_log_max = old_log_max;
6860 /* Display the current message in the current mini-buffer. This is
6861 only called from error handlers in process.c, and is not time
6862 critical. */
6864 void
6865 update_echo_area ()
6867 if (!NILP (echo_area_buffer[0]))
6869 Lisp_Object string;
6870 string = Fcurrent_message ();
6871 message3 (string, SBYTES (string),
6872 !NILP (current_buffer->enable_multibyte_characters));
6877 /* Make sure echo area buffers in `echo_buffers' are live.
6878 If they aren't, make new ones. */
6880 static void
6881 ensure_echo_area_buffers ()
6883 int i;
6885 for (i = 0; i < 2; ++i)
6886 if (!BUFFERP (echo_buffer[i])
6887 || NILP (XBUFFER (echo_buffer[i])->name))
6889 char name[30];
6890 Lisp_Object old_buffer;
6891 int j;
6893 old_buffer = echo_buffer[i];
6894 sprintf (name, " *Echo Area %d*", i);
6895 echo_buffer[i] = Fget_buffer_create (build_string (name));
6896 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
6898 for (j = 0; j < 2; ++j)
6899 if (EQ (old_buffer, echo_area_buffer[j]))
6900 echo_area_buffer[j] = echo_buffer[i];
6905 /* Call FN with args A1..A4 with either the current or last displayed
6906 echo_area_buffer as current buffer.
6908 WHICH zero means use the current message buffer
6909 echo_area_buffer[0]. If that is nil, choose a suitable buffer
6910 from echo_buffer[] and clear it.
6912 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
6913 suitable buffer from echo_buffer[] and clear it.
6915 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
6916 that the current message becomes the last displayed one, make
6917 choose a suitable buffer for echo_area_buffer[0], and clear it.
6919 Value is what FN returns. */
6921 static int
6922 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
6923 struct window *w;
6924 int which;
6925 int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
6926 EMACS_INT a1;
6927 Lisp_Object a2;
6928 EMACS_INT a3, a4;
6930 Lisp_Object buffer;
6931 int this_one, the_other, clear_buffer_p, rc;
6932 int count = SPECPDL_INDEX ();
6934 /* If buffers aren't live, make new ones. */
6935 ensure_echo_area_buffers ();
6937 clear_buffer_p = 0;
6939 if (which == 0)
6940 this_one = 0, the_other = 1;
6941 else if (which > 0)
6942 this_one = 1, the_other = 0;
6943 else
6945 this_one = 0, the_other = 1;
6946 clear_buffer_p = 1;
6948 /* We need a fresh one in case the current echo buffer equals
6949 the one containing the last displayed echo area message. */
6950 if (!NILP (echo_area_buffer[this_one])
6951 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
6952 echo_area_buffer[this_one] = Qnil;
6955 /* Choose a suitable buffer from echo_buffer[] is we don't
6956 have one. */
6957 if (NILP (echo_area_buffer[this_one]))
6959 echo_area_buffer[this_one]
6960 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
6961 ? echo_buffer[the_other]
6962 : echo_buffer[this_one]);
6963 clear_buffer_p = 1;
6966 buffer = echo_area_buffer[this_one];
6968 /* Don't get confused by reusing the buffer used for echoing
6969 for a different purpose. */
6970 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
6971 cancel_echoing ();
6973 record_unwind_protect (unwind_with_echo_area_buffer,
6974 with_echo_area_buffer_unwind_data (w));
6976 /* Make the echo area buffer current. Note that for display
6977 purposes, it is not necessary that the displayed window's buffer
6978 == current_buffer, except for text property lookup. So, let's
6979 only set that buffer temporarily here without doing a full
6980 Fset_window_buffer. We must also change w->pointm, though,
6981 because otherwise an assertions in unshow_buffer fails, and Emacs
6982 aborts. */
6983 set_buffer_internal_1 (XBUFFER (buffer));
6984 if (w)
6986 w->buffer = buffer;
6987 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
6990 current_buffer->undo_list = Qt;
6991 current_buffer->read_only = Qnil;
6992 specbind (Qinhibit_read_only, Qt);
6993 specbind (Qinhibit_modification_hooks, Qt);
6995 if (clear_buffer_p && Z > BEG)
6996 del_range (BEG, Z);
6998 xassert (BEGV >= BEG);
6999 xassert (ZV <= Z && ZV >= BEGV);
7001 rc = fn (a1, a2, a3, a4);
7003 xassert (BEGV >= BEG);
7004 xassert (ZV <= Z && ZV >= BEGV);
7006 unbind_to (count, Qnil);
7007 return rc;
7011 /* Save state that should be preserved around the call to the function
7012 FN called in with_echo_area_buffer. */
7014 static Lisp_Object
7015 with_echo_area_buffer_unwind_data (w)
7016 struct window *w;
7018 int i = 0;
7019 Lisp_Object vector;
7021 /* Reduce consing by keeping one vector in
7022 Vwith_echo_area_save_vector. */
7023 vector = Vwith_echo_area_save_vector;
7024 Vwith_echo_area_save_vector = Qnil;
7026 if (NILP (vector))
7027 vector = Fmake_vector (make_number (7), Qnil);
7029 XSETBUFFER (AREF (vector, i), current_buffer); ++i;
7030 AREF (vector, i) = Vdeactivate_mark, ++i;
7031 AREF (vector, i) = make_number (windows_or_buffers_changed), ++i;
7033 if (w)
7035 XSETWINDOW (AREF (vector, i), w); ++i;
7036 AREF (vector, i) = w->buffer; ++i;
7037 AREF (vector, i) = make_number (XMARKER (w->pointm)->charpos); ++i;
7038 AREF (vector, i) = make_number (XMARKER (w->pointm)->bytepos); ++i;
7040 else
7042 int end = i + 4;
7043 for (; i < end; ++i)
7044 AREF (vector, i) = Qnil;
7047 xassert (i == ASIZE (vector));
7048 return vector;
7052 /* Restore global state from VECTOR which was created by
7053 with_echo_area_buffer_unwind_data. */
7055 static Lisp_Object
7056 unwind_with_echo_area_buffer (vector)
7057 Lisp_Object vector;
7059 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
7060 Vdeactivate_mark = AREF (vector, 1);
7061 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
7063 if (WINDOWP (AREF (vector, 3)))
7065 struct window *w;
7066 Lisp_Object buffer, charpos, bytepos;
7068 w = XWINDOW (AREF (vector, 3));
7069 buffer = AREF (vector, 4);
7070 charpos = AREF (vector, 5);
7071 bytepos = AREF (vector, 6);
7073 w->buffer = buffer;
7074 set_marker_both (w->pointm, buffer,
7075 XFASTINT (charpos), XFASTINT (bytepos));
7078 Vwith_echo_area_save_vector = vector;
7079 return Qnil;
7083 /* Set up the echo area for use by print functions. MULTIBYTE_P
7084 non-zero means we will print multibyte. */
7086 void
7087 setup_echo_area_for_printing (multibyte_p)
7088 int multibyte_p;
7090 /* If we can't find an echo area any more, exit. */
7091 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
7092 Fkill_emacs (Qnil);
7094 ensure_echo_area_buffers ();
7096 if (!message_buf_print)
7098 /* A message has been output since the last time we printed.
7099 Choose a fresh echo area buffer. */
7100 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7101 echo_area_buffer[0] = echo_buffer[1];
7102 else
7103 echo_area_buffer[0] = echo_buffer[0];
7105 /* Switch to that buffer and clear it. */
7106 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7107 current_buffer->truncate_lines = Qnil;
7109 if (Z > BEG)
7111 int count = SPECPDL_INDEX ();
7112 specbind (Qinhibit_read_only, Qt);
7113 /* Note that undo recording is always disabled. */
7114 del_range (BEG, Z);
7115 unbind_to (count, Qnil);
7117 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7119 /* Set up the buffer for the multibyteness we need. */
7120 if (multibyte_p
7121 != !NILP (current_buffer->enable_multibyte_characters))
7122 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
7124 /* Raise the frame containing the echo area. */
7125 if (minibuffer_auto_raise)
7127 struct frame *sf = SELECTED_FRAME ();
7128 Lisp_Object mini_window;
7129 mini_window = FRAME_MINIBUF_WINDOW (sf);
7130 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
7133 message_log_maybe_newline ();
7134 message_buf_print = 1;
7136 else
7138 if (NILP (echo_area_buffer[0]))
7140 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7141 echo_area_buffer[0] = echo_buffer[1];
7142 else
7143 echo_area_buffer[0] = echo_buffer[0];
7146 if (current_buffer != XBUFFER (echo_area_buffer[0]))
7148 /* Someone switched buffers between print requests. */
7149 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7150 current_buffer->truncate_lines = Qnil;
7156 /* Display an echo area message in window W. Value is non-zero if W's
7157 height is changed. If display_last_displayed_message_p is
7158 non-zero, display the message that was last displayed, otherwise
7159 display the current message. */
7161 static int
7162 display_echo_area (w)
7163 struct window *w;
7165 int i, no_message_p, window_height_changed_p, count;
7167 /* Temporarily disable garbage collections while displaying the echo
7168 area. This is done because a GC can print a message itself.
7169 That message would modify the echo area buffer's contents while a
7170 redisplay of the buffer is going on, and seriously confuse
7171 redisplay. */
7172 count = inhibit_garbage_collection ();
7174 /* If there is no message, we must call display_echo_area_1
7175 nevertheless because it resizes the window. But we will have to
7176 reset the echo_area_buffer in question to nil at the end because
7177 with_echo_area_buffer will sets it to an empty buffer. */
7178 i = display_last_displayed_message_p ? 1 : 0;
7179 no_message_p = NILP (echo_area_buffer[i]);
7181 window_height_changed_p
7182 = with_echo_area_buffer (w, display_last_displayed_message_p,
7183 display_echo_area_1,
7184 (EMACS_INT) w, Qnil, 0, 0);
7186 if (no_message_p)
7187 echo_area_buffer[i] = Qnil;
7189 unbind_to (count, Qnil);
7190 return window_height_changed_p;
7194 /* Helper for display_echo_area. Display the current buffer which
7195 contains the current echo area message in window W, a mini-window,
7196 a pointer to which is passed in A1. A2..A4 are currently not used.
7197 Change the height of W so that all of the message is displayed.
7198 Value is non-zero if height of W was changed. */
7200 static int
7201 display_echo_area_1 (a1, a2, a3, a4)
7202 EMACS_INT a1;
7203 Lisp_Object a2;
7204 EMACS_INT a3, a4;
7206 struct window *w = (struct window *) a1;
7207 Lisp_Object window;
7208 struct text_pos start;
7209 int window_height_changed_p = 0;
7211 /* Do this before displaying, so that we have a large enough glyph
7212 matrix for the display. */
7213 window_height_changed_p = resize_mini_window (w, 0);
7215 /* Display. */
7216 clear_glyph_matrix (w->desired_matrix);
7217 XSETWINDOW (window, w);
7218 SET_TEXT_POS (start, BEG, BEG_BYTE);
7219 try_window (window, start);
7221 return window_height_changed_p;
7225 /* Resize the echo area window to exactly the size needed for the
7226 currently displayed message, if there is one. If a mini-buffer
7227 is active, don't shrink it. */
7229 void
7230 resize_echo_area_exactly ()
7232 if (BUFFERP (echo_area_buffer[0])
7233 && WINDOWP (echo_area_window))
7235 struct window *w = XWINDOW (echo_area_window);
7236 int resized_p;
7237 Lisp_Object resize_exactly;
7239 if (minibuf_level == 0)
7240 resize_exactly = Qt;
7241 else
7242 resize_exactly = Qnil;
7244 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
7245 (EMACS_INT) w, resize_exactly, 0, 0);
7246 if (resized_p)
7248 ++windows_or_buffers_changed;
7249 ++update_mode_lines;
7250 redisplay_internal (0);
7256 /* Callback function for with_echo_area_buffer, when used from
7257 resize_echo_area_exactly. A1 contains a pointer to the window to
7258 resize, EXACTLY non-nil means resize the mini-window exactly to the
7259 size of the text displayed. A3 and A4 are not used. Value is what
7260 resize_mini_window returns. */
7262 static int
7263 resize_mini_window_1 (a1, exactly, a3, a4)
7264 EMACS_INT a1;
7265 Lisp_Object exactly;
7266 EMACS_INT a3, a4;
7268 return resize_mini_window ((struct window *) a1, !NILP (exactly));
7272 /* Resize mini-window W to fit the size of its contents. EXACT:P
7273 means size the window exactly to the size needed. Otherwise, it's
7274 only enlarged until W's buffer is empty. Value is non-zero if
7275 the window height has been changed. */
7278 resize_mini_window (w, exact_p)
7279 struct window *w;
7280 int exact_p;
7282 struct frame *f = XFRAME (w->frame);
7283 int window_height_changed_p = 0;
7285 xassert (MINI_WINDOW_P (w));
7287 /* Don't resize windows while redisplaying a window; it would
7288 confuse redisplay functions when the size of the window they are
7289 displaying changes from under them. Such a resizing can happen,
7290 for instance, when which-func prints a long message while
7291 we are running fontification-functions. We're running these
7292 functions with safe_call which binds inhibit-redisplay to t. */
7293 if (!NILP (Vinhibit_redisplay))
7294 return 0;
7296 /* Nil means don't try to resize. */
7297 if (NILP (Vresize_mini_windows)
7298 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
7299 return 0;
7301 if (!FRAME_MINIBUF_ONLY_P (f))
7303 struct it it;
7304 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
7305 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
7306 int height, max_height;
7307 int unit = FRAME_LINE_HEIGHT (f);
7308 struct text_pos start;
7309 struct buffer *old_current_buffer = NULL;
7311 if (current_buffer != XBUFFER (w->buffer))
7313 old_current_buffer = current_buffer;
7314 set_buffer_internal (XBUFFER (w->buffer));
7317 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
7319 /* Compute the max. number of lines specified by the user. */
7320 if (FLOATP (Vmax_mini_window_height))
7321 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
7322 else if (INTEGERP (Vmax_mini_window_height))
7323 max_height = XINT (Vmax_mini_window_height);
7324 else
7325 max_height = total_height / 4;
7327 /* Correct that max. height if it's bogus. */
7328 max_height = max (1, max_height);
7329 max_height = min (total_height, max_height);
7331 /* Find out the height of the text in the window. */
7332 if (it.truncate_lines_p)
7333 height = 1;
7334 else
7336 last_height = 0;
7337 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
7338 if (it.max_ascent == 0 && it.max_descent == 0)
7339 height = it.current_y + last_height;
7340 else
7341 height = it.current_y + it.max_ascent + it.max_descent;
7342 height -= it.extra_line_spacing;
7343 height = (height + unit - 1) / unit;
7346 /* Compute a suitable window start. */
7347 if (height > max_height)
7349 height = max_height;
7350 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
7351 move_it_vertically_backward (&it, (height - 1) * unit);
7352 start = it.current.pos;
7354 else
7355 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
7356 SET_MARKER_FROM_TEXT_POS (w->start, start);
7358 if (EQ (Vresize_mini_windows, Qgrow_only))
7360 /* Let it grow only, until we display an empty message, in which
7361 case the window shrinks again. */
7362 if (height > WINDOW_TOTAL_LINES (w))
7364 int old_height = WINDOW_TOTAL_LINES (w);
7365 freeze_window_starts (f, 1);
7366 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7367 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7369 else if (height < WINDOW_TOTAL_LINES (w)
7370 && (exact_p || BEGV == ZV))
7372 int old_height = WINDOW_TOTAL_LINES (w);
7373 freeze_window_starts (f, 0);
7374 shrink_mini_window (w);
7375 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7378 else
7380 /* Always resize to exact size needed. */
7381 if (height > WINDOW_TOTAL_LINES (w))
7383 int old_height = WINDOW_TOTAL_LINES (w);
7384 freeze_window_starts (f, 1);
7385 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7386 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7388 else if (height < WINDOW_TOTAL_LINES (w))
7390 int old_height = WINDOW_TOTAL_LINES (w);
7391 freeze_window_starts (f, 0);
7392 shrink_mini_window (w);
7394 if (height)
7396 freeze_window_starts (f, 1);
7397 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7400 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7404 if (old_current_buffer)
7405 set_buffer_internal (old_current_buffer);
7408 return window_height_changed_p;
7412 /* Value is the current message, a string, or nil if there is no
7413 current message. */
7415 Lisp_Object
7416 current_message ()
7418 Lisp_Object msg;
7420 if (NILP (echo_area_buffer[0]))
7421 msg = Qnil;
7422 else
7424 with_echo_area_buffer (0, 0, current_message_1,
7425 (EMACS_INT) &msg, Qnil, 0, 0);
7426 if (NILP (msg))
7427 echo_area_buffer[0] = Qnil;
7430 return msg;
7434 static int
7435 current_message_1 (a1, a2, a3, a4)
7436 EMACS_INT a1;
7437 Lisp_Object a2;
7438 EMACS_INT a3, a4;
7440 Lisp_Object *msg = (Lisp_Object *) a1;
7442 if (Z > BEG)
7443 *msg = make_buffer_string (BEG, Z, 1);
7444 else
7445 *msg = Qnil;
7446 return 0;
7450 /* Push the current message on Vmessage_stack for later restauration
7451 by restore_message. Value is non-zero if the current message isn't
7452 empty. This is a relatively infrequent operation, so it's not
7453 worth optimizing. */
7456 push_message ()
7458 Lisp_Object msg;
7459 msg = current_message ();
7460 Vmessage_stack = Fcons (msg, Vmessage_stack);
7461 return STRINGP (msg);
7465 /* Restore message display from the top of Vmessage_stack. */
7467 void
7468 restore_message ()
7470 Lisp_Object msg;
7472 xassert (CONSP (Vmessage_stack));
7473 msg = XCAR (Vmessage_stack);
7474 if (STRINGP (msg))
7475 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
7476 else
7477 message3_nolog (msg, 0, 0);
7481 /* Handler for record_unwind_protect calling pop_message. */
7483 Lisp_Object
7484 pop_message_unwind (dummy)
7485 Lisp_Object dummy;
7487 pop_message ();
7488 return Qnil;
7491 /* Pop the top-most entry off Vmessage_stack. */
7493 void
7494 pop_message ()
7496 xassert (CONSP (Vmessage_stack));
7497 Vmessage_stack = XCDR (Vmessage_stack);
7501 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
7502 exits. If the stack is not empty, we have a missing pop_message
7503 somewhere. */
7505 void
7506 check_message_stack ()
7508 if (!NILP (Vmessage_stack))
7509 abort ();
7513 /* Truncate to NCHARS what will be displayed in the echo area the next
7514 time we display it---but don't redisplay it now. */
7516 void
7517 truncate_echo_area (nchars)
7518 int nchars;
7520 if (nchars == 0)
7521 echo_area_buffer[0] = Qnil;
7522 /* A null message buffer means that the frame hasn't really been
7523 initialized yet. Error messages get reported properly by
7524 cmd_error, so this must be just an informative message; toss it. */
7525 else if (!noninteractive
7526 && INTERACTIVE
7527 && !NILP (echo_area_buffer[0]))
7529 struct frame *sf = SELECTED_FRAME ();
7530 if (FRAME_MESSAGE_BUF (sf))
7531 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
7536 /* Helper function for truncate_echo_area. Truncate the current
7537 message to at most NCHARS characters. */
7539 static int
7540 truncate_message_1 (nchars, a2, a3, a4)
7541 EMACS_INT nchars;
7542 Lisp_Object a2;
7543 EMACS_INT a3, a4;
7545 if (BEG + nchars < Z)
7546 del_range (BEG + nchars, Z);
7547 if (Z == BEG)
7548 echo_area_buffer[0] = Qnil;
7549 return 0;
7553 /* Set the current message to a substring of S or STRING.
7555 If STRING is a Lisp string, set the message to the first NBYTES
7556 bytes from STRING. NBYTES zero means use the whole string. If
7557 STRING is multibyte, the message will be displayed multibyte.
7559 If S is not null, set the message to the first LEN bytes of S. LEN
7560 zero means use the whole string. MULTIBYTE_P non-zero means S is
7561 multibyte. Display the message multibyte in that case. */
7563 void
7564 set_message (s, string, nbytes, multibyte_p)
7565 const char *s;
7566 Lisp_Object string;
7567 int nbytes, multibyte_p;
7569 message_enable_multibyte
7570 = ((s && multibyte_p)
7571 || (STRINGP (string) && STRING_MULTIBYTE (string)));
7573 with_echo_area_buffer (0, -1, set_message_1,
7574 (EMACS_INT) s, string, nbytes, multibyte_p);
7575 message_buf_print = 0;
7576 help_echo_showing_p = 0;
7580 /* Helper function for set_message. Arguments have the same meaning
7581 as there, with A1 corresponding to S and A2 corresponding to STRING
7582 This function is called with the echo area buffer being
7583 current. */
7585 static int
7586 set_message_1 (a1, a2, nbytes, multibyte_p)
7587 EMACS_INT a1;
7588 Lisp_Object a2;
7589 EMACS_INT nbytes, multibyte_p;
7591 const char *s = (const char *) a1;
7592 Lisp_Object string = a2;
7594 xassert (BEG == Z);
7596 /* Change multibyteness of the echo buffer appropriately. */
7597 if (message_enable_multibyte
7598 != !NILP (current_buffer->enable_multibyte_characters))
7599 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
7601 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
7603 /* Insert new message at BEG. */
7604 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7606 if (STRINGP (string))
7608 int nchars;
7610 if (nbytes == 0)
7611 nbytes = SBYTES (string);
7612 nchars = string_byte_to_char (string, nbytes);
7614 /* This function takes care of single/multibyte conversion. We
7615 just have to ensure that the echo area buffer has the right
7616 setting of enable_multibyte_characters. */
7617 insert_from_string (string, 0, 0, nchars, nbytes, 1);
7619 else if (s)
7621 if (nbytes == 0)
7622 nbytes = strlen (s);
7624 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
7626 /* Convert from multi-byte to single-byte. */
7627 int i, c, n;
7628 unsigned char work[1];
7630 /* Convert a multibyte string to single-byte. */
7631 for (i = 0; i < nbytes; i += n)
7633 c = string_char_and_length (s + i, nbytes - i, &n);
7634 work[0] = (SINGLE_BYTE_CHAR_P (c)
7636 : multibyte_char_to_unibyte (c, Qnil));
7637 insert_1_both (work, 1, 1, 1, 0, 0);
7640 else if (!multibyte_p
7641 && !NILP (current_buffer->enable_multibyte_characters))
7643 /* Convert from single-byte to multi-byte. */
7644 int i, c, n;
7645 const unsigned char *msg = (const unsigned char *) s;
7646 unsigned char str[MAX_MULTIBYTE_LENGTH];
7648 /* Convert a single-byte string to multibyte. */
7649 for (i = 0; i < nbytes; i++)
7651 c = unibyte_char_to_multibyte (msg[i]);
7652 n = CHAR_STRING (c, str);
7653 insert_1_both (str, 1, n, 1, 0, 0);
7656 else
7657 insert_1 (s, nbytes, 1, 0, 0);
7660 return 0;
7664 /* Clear messages. CURRENT_P non-zero means clear the current
7665 message. LAST_DISPLAYED_P non-zero means clear the message
7666 last displayed. */
7668 void
7669 clear_message (current_p, last_displayed_p)
7670 int current_p, last_displayed_p;
7672 if (current_p)
7674 echo_area_buffer[0] = Qnil;
7675 message_cleared_p = 1;
7678 if (last_displayed_p)
7679 echo_area_buffer[1] = Qnil;
7681 message_buf_print = 0;
7684 /* Clear garbaged frames.
7686 This function is used where the old redisplay called
7687 redraw_garbaged_frames which in turn called redraw_frame which in
7688 turn called clear_frame. The call to clear_frame was a source of
7689 flickering. I believe a clear_frame is not necessary. It should
7690 suffice in the new redisplay to invalidate all current matrices,
7691 and ensure a complete redisplay of all windows. */
7693 static void
7694 clear_garbaged_frames ()
7696 if (frame_garbaged)
7698 Lisp_Object tail, frame;
7699 int changed_count = 0;
7701 FOR_EACH_FRAME (tail, frame)
7703 struct frame *f = XFRAME (frame);
7705 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
7707 if (f->resized_p)
7709 Fredraw_frame (frame);
7710 f->force_flush_display_p = 1;
7712 clear_current_matrices (f);
7713 changed_count++;
7714 f->garbaged = 0;
7715 f->resized_p = 0;
7719 frame_garbaged = 0;
7720 if (changed_count)
7721 ++windows_or_buffers_changed;
7726 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
7727 is non-zero update selected_frame. Value is non-zero if the
7728 mini-windows height has been changed. */
7730 static int
7731 echo_area_display (update_frame_p)
7732 int update_frame_p;
7734 Lisp_Object mini_window;
7735 struct window *w;
7736 struct frame *f;
7737 int window_height_changed_p = 0;
7738 struct frame *sf = SELECTED_FRAME ();
7740 mini_window = FRAME_MINIBUF_WINDOW (sf);
7741 w = XWINDOW (mini_window);
7742 f = XFRAME (WINDOW_FRAME (w));
7744 /* Don't display if frame is invisible or not yet initialized. */
7745 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
7746 return 0;
7748 /* The terminal frame is used as the first Emacs frame on the Mac OS. */
7749 #ifndef MAC_OS8
7750 #ifdef HAVE_WINDOW_SYSTEM
7751 /* When Emacs starts, selected_frame may be a visible terminal
7752 frame, even if we run under a window system. If we let this
7753 through, a message would be displayed on the terminal. */
7754 if (EQ (selected_frame, Vterminal_frame)
7755 && !NILP (Vwindow_system))
7756 return 0;
7757 #endif /* HAVE_WINDOW_SYSTEM */
7758 #endif
7760 /* Redraw garbaged frames. */
7761 if (frame_garbaged)
7762 clear_garbaged_frames ();
7764 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
7766 echo_area_window = mini_window;
7767 window_height_changed_p = display_echo_area (w);
7768 w->must_be_updated_p = 1;
7770 /* Update the display, unless called from redisplay_internal.
7771 Also don't update the screen during redisplay itself. The
7772 update will happen at the end of redisplay, and an update
7773 here could cause confusion. */
7774 if (update_frame_p && !redisplaying_p)
7776 int n = 0;
7778 /* If the display update has been interrupted by pending
7779 input, update mode lines in the frame. Due to the
7780 pending input, it might have been that redisplay hasn't
7781 been called, so that mode lines above the echo area are
7782 garbaged. This looks odd, so we prevent it here. */
7783 if (!display_completed)
7784 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
7786 if (window_height_changed_p
7787 /* Don't do this if Emacs is shutting down. Redisplay
7788 needs to run hooks. */
7789 && !NILP (Vrun_hooks))
7791 /* Must update other windows. Likewise as in other
7792 cases, don't let this update be interrupted by
7793 pending input. */
7794 int count = SPECPDL_INDEX ();
7795 specbind (Qredisplay_dont_pause, Qt);
7796 windows_or_buffers_changed = 1;
7797 redisplay_internal (0);
7798 unbind_to (count, Qnil);
7800 else if (FRAME_WINDOW_P (f) && n == 0)
7802 /* Window configuration is the same as before.
7803 Can do with a display update of the echo area,
7804 unless we displayed some mode lines. */
7805 update_single_window (w, 1);
7806 rif->flush_display (f);
7808 else
7809 update_frame (f, 1, 1);
7811 /* If cursor is in the echo area, make sure that the next
7812 redisplay displays the minibuffer, so that the cursor will
7813 be replaced with what the minibuffer wants. */
7814 if (cursor_in_echo_area)
7815 ++windows_or_buffers_changed;
7818 else if (!EQ (mini_window, selected_window))
7819 windows_or_buffers_changed++;
7821 /* Last displayed message is now the current message. */
7822 echo_area_buffer[1] = echo_area_buffer[0];
7824 /* Prevent redisplay optimization in redisplay_internal by resetting
7825 this_line_start_pos. This is done because the mini-buffer now
7826 displays the message instead of its buffer text. */
7827 if (EQ (mini_window, selected_window))
7828 CHARPOS (this_line_start_pos) = 0;
7830 return window_height_changed_p;
7835 /***********************************************************************
7836 Frame Titles
7837 ***********************************************************************/
7840 /* The frame title buffering code is also used by Fformat_mode_line.
7841 So it is not conditioned by HAVE_WINDOW_SYSTEM. */
7843 /* A buffer for constructing frame titles in it; allocated from the
7844 heap in init_xdisp and resized as needed in store_frame_title_char. */
7846 static char *frame_title_buf;
7848 /* The buffer's end, and a current output position in it. */
7850 static char *frame_title_buf_end;
7851 static char *frame_title_ptr;
7854 /* Store a single character C for the frame title in frame_title_buf.
7855 Re-allocate frame_title_buf if necessary. */
7857 static void
7858 #ifdef PROTOTYPES
7859 store_frame_title_char (char c)
7860 #else
7861 store_frame_title_char (c)
7862 char c;
7863 #endif
7865 /* If output position has reached the end of the allocated buffer,
7866 double the buffer's size. */
7867 if (frame_title_ptr == frame_title_buf_end)
7869 int len = frame_title_ptr - frame_title_buf;
7870 int new_size = 2 * len * sizeof *frame_title_buf;
7871 frame_title_buf = (char *) xrealloc (frame_title_buf, new_size);
7872 frame_title_buf_end = frame_title_buf + new_size;
7873 frame_title_ptr = frame_title_buf + len;
7876 *frame_title_ptr++ = c;
7880 /* Store part of a frame title in frame_title_buf, beginning at
7881 frame_title_ptr. STR is the string to store. Do not copy
7882 characters that yield more columns than PRECISION; PRECISION <= 0
7883 means copy the whole string. Pad with spaces until FIELD_WIDTH
7884 number of characters have been copied; FIELD_WIDTH <= 0 means don't
7885 pad. Called from display_mode_element when it is used to build a
7886 frame title. */
7888 static int
7889 store_frame_title (str, field_width, precision)
7890 const unsigned char *str;
7891 int field_width, precision;
7893 int n = 0;
7894 int dummy, nbytes;
7896 /* Copy at most PRECISION chars from STR. */
7897 nbytes = strlen (str);
7898 n+= c_string_width (str, nbytes, precision, &dummy, &nbytes);
7899 while (nbytes--)
7900 store_frame_title_char (*str++);
7902 /* Fill up with spaces until FIELD_WIDTH reached. */
7903 while (field_width > 0
7904 && n < field_width)
7906 store_frame_title_char (' ');
7907 ++n;
7910 return n;
7913 #ifdef HAVE_WINDOW_SYSTEM
7915 /* Set the title of FRAME, if it has changed. The title format is
7916 Vicon_title_format if FRAME is iconified, otherwise it is
7917 frame_title_format. */
7919 static void
7920 x_consider_frame_title (frame)
7921 Lisp_Object frame;
7923 struct frame *f = XFRAME (frame);
7925 if (FRAME_WINDOW_P (f)
7926 || FRAME_MINIBUF_ONLY_P (f)
7927 || f->explicit_name)
7929 /* Do we have more than one visible frame on this X display? */
7930 Lisp_Object tail;
7931 Lisp_Object fmt;
7932 struct buffer *obuf;
7933 int len;
7934 struct it it;
7936 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
7938 Lisp_Object other_frame = XCAR (tail);
7939 struct frame *tf = XFRAME (other_frame);
7941 if (tf != f
7942 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
7943 && !FRAME_MINIBUF_ONLY_P (tf)
7944 && !EQ (other_frame, tip_frame)
7945 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
7946 break;
7949 /* Set global variable indicating that multiple frames exist. */
7950 multiple_frames = CONSP (tail);
7952 /* Switch to the buffer of selected window of the frame. Set up
7953 frame_title_ptr so that display_mode_element will output into it;
7954 then display the title. */
7955 obuf = current_buffer;
7956 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
7957 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
7958 frame_title_ptr = frame_title_buf;
7959 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
7960 NULL, DEFAULT_FACE_ID);
7961 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
7962 len = frame_title_ptr - frame_title_buf;
7963 frame_title_ptr = NULL;
7964 set_buffer_internal_1 (obuf);
7966 /* Set the title only if it's changed. This avoids consing in
7967 the common case where it hasn't. (If it turns out that we've
7968 already wasted too much time by walking through the list with
7969 display_mode_element, then we might need to optimize at a
7970 higher level than this.) */
7971 if (! STRINGP (f->name)
7972 || SBYTES (f->name) != len
7973 || bcmp (frame_title_buf, SDATA (f->name), len) != 0)
7974 x_implicitly_set_name (f, make_string (frame_title_buf, len), Qnil);
7978 #endif /* not HAVE_WINDOW_SYSTEM */
7983 /***********************************************************************
7984 Menu Bars
7985 ***********************************************************************/
7988 /* Prepare for redisplay by updating menu-bar item lists when
7989 appropriate. This can call eval. */
7991 void
7992 prepare_menu_bars ()
7994 int all_windows;
7995 struct gcpro gcpro1, gcpro2;
7996 struct frame *f;
7997 Lisp_Object tooltip_frame;
7999 #ifdef HAVE_WINDOW_SYSTEM
8000 tooltip_frame = tip_frame;
8001 #else
8002 tooltip_frame = Qnil;
8003 #endif
8005 /* Update all frame titles based on their buffer names, etc. We do
8006 this before the menu bars so that the buffer-menu will show the
8007 up-to-date frame titles. */
8008 #ifdef HAVE_WINDOW_SYSTEM
8009 if (windows_or_buffers_changed || update_mode_lines)
8011 Lisp_Object tail, frame;
8013 FOR_EACH_FRAME (tail, frame)
8015 f = XFRAME (frame);
8016 if (!EQ (frame, tooltip_frame)
8017 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
8018 x_consider_frame_title (frame);
8021 #endif /* HAVE_WINDOW_SYSTEM */
8023 /* Update the menu bar item lists, if appropriate. This has to be
8024 done before any actual redisplay or generation of display lines. */
8025 all_windows = (update_mode_lines
8026 || buffer_shared > 1
8027 || windows_or_buffers_changed);
8028 if (all_windows)
8030 Lisp_Object tail, frame;
8031 int count = SPECPDL_INDEX ();
8033 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8035 FOR_EACH_FRAME (tail, frame)
8037 f = XFRAME (frame);
8039 /* Ignore tooltip frame. */
8040 if (EQ (frame, tooltip_frame))
8041 continue;
8043 /* If a window on this frame changed size, report that to
8044 the user and clear the size-change flag. */
8045 if (FRAME_WINDOW_SIZES_CHANGED (f))
8047 Lisp_Object functions;
8049 /* Clear flag first in case we get an error below. */
8050 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
8051 functions = Vwindow_size_change_functions;
8052 GCPRO2 (tail, functions);
8054 while (CONSP (functions))
8056 call1 (XCAR (functions), frame);
8057 functions = XCDR (functions);
8059 UNGCPRO;
8062 GCPRO1 (tail);
8063 update_menu_bar (f, 0);
8064 #ifdef HAVE_WINDOW_SYSTEM
8065 update_tool_bar (f, 0);
8066 #endif
8067 UNGCPRO;
8070 unbind_to (count, Qnil);
8072 else
8074 struct frame *sf = SELECTED_FRAME ();
8075 update_menu_bar (sf, 1);
8076 #ifdef HAVE_WINDOW_SYSTEM
8077 update_tool_bar (sf, 1);
8078 #endif
8081 /* Motif needs this. See comment in xmenu.c. Turn it off when
8082 pending_menu_activation is not defined. */
8083 #ifdef USE_X_TOOLKIT
8084 pending_menu_activation = 0;
8085 #endif
8089 /* Update the menu bar item list for frame F. This has to be done
8090 before we start to fill in any display lines, because it can call
8091 eval.
8093 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
8095 static void
8096 update_menu_bar (f, save_match_data)
8097 struct frame *f;
8098 int save_match_data;
8100 Lisp_Object window;
8101 register struct window *w;
8103 /* If called recursively during a menu update, do nothing. This can
8104 happen when, for instance, an activate-menubar-hook causes a
8105 redisplay. */
8106 if (inhibit_menubar_update)
8107 return;
8109 window = FRAME_SELECTED_WINDOW (f);
8110 w = XWINDOW (window);
8112 #if 0 /* The if statement below this if statement used to include the
8113 condition !NILP (w->update_mode_line), rather than using
8114 update_mode_lines directly, and this if statement may have
8115 been added to make that condition work. Now the if
8116 statement below matches its comment, this isn't needed. */
8117 if (update_mode_lines)
8118 w->update_mode_line = Qt;
8119 #endif
8121 if (FRAME_WINDOW_P (f)
8123 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8124 || defined (USE_GTK)
8125 FRAME_EXTERNAL_MENU_BAR (f)
8126 #else
8127 FRAME_MENU_BAR_LINES (f) > 0
8128 #endif
8129 : FRAME_MENU_BAR_LINES (f) > 0)
8131 /* If the user has switched buffers or windows, we need to
8132 recompute to reflect the new bindings. But we'll
8133 recompute when update_mode_lines is set too; that means
8134 that people can use force-mode-line-update to request
8135 that the menu bar be recomputed. The adverse effect on
8136 the rest of the redisplay algorithm is about the same as
8137 windows_or_buffers_changed anyway. */
8138 if (windows_or_buffers_changed
8139 /* This used to test w->update_mode_line, but we believe
8140 there is no need to recompute the menu in that case. */
8141 || update_mode_lines
8142 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8143 < BUF_MODIFF (XBUFFER (w->buffer)))
8144 != !NILP (w->last_had_star))
8145 || ((!NILP (Vtransient_mark_mode)
8146 && !NILP (XBUFFER (w->buffer)->mark_active))
8147 != !NILP (w->region_showing)))
8149 struct buffer *prev = current_buffer;
8150 int count = SPECPDL_INDEX ();
8152 specbind (Qinhibit_menubar_update, Qt);
8154 set_buffer_internal_1 (XBUFFER (w->buffer));
8155 if (save_match_data)
8156 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8157 if (NILP (Voverriding_local_map_menu_flag))
8159 specbind (Qoverriding_terminal_local_map, Qnil);
8160 specbind (Qoverriding_local_map, Qnil);
8163 /* Run the Lucid hook. */
8164 safe_run_hooks (Qactivate_menubar_hook);
8166 /* If it has changed current-menubar from previous value,
8167 really recompute the menu-bar from the value. */
8168 if (! NILP (Vlucid_menu_bar_dirty_flag))
8169 call0 (Qrecompute_lucid_menubar);
8171 safe_run_hooks (Qmenu_bar_update_hook);
8172 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
8174 /* Redisplay the menu bar in case we changed it. */
8175 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8176 || defined (USE_GTK)
8177 if (FRAME_WINDOW_P (f)
8178 #if defined (MAC_OS)
8179 /* All frames on Mac OS share the same menubar. So only the
8180 selected frame should be allowed to set it. */
8181 && f == SELECTED_FRAME ()
8182 #endif
8184 set_frame_menubar (f, 0, 0);
8185 else
8186 /* On a terminal screen, the menu bar is an ordinary screen
8187 line, and this makes it get updated. */
8188 w->update_mode_line = Qt;
8189 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8190 /* In the non-toolkit version, the menu bar is an ordinary screen
8191 line, and this makes it get updated. */
8192 w->update_mode_line = Qt;
8193 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8195 unbind_to (count, Qnil);
8196 set_buffer_internal_1 (prev);
8203 /***********************************************************************
8204 Output Cursor
8205 ***********************************************************************/
8207 #ifdef HAVE_WINDOW_SYSTEM
8209 /* EXPORT:
8210 Nominal cursor position -- where to draw output.
8211 HPOS and VPOS are window relative glyph matrix coordinates.
8212 X and Y are window relative pixel coordinates. */
8214 struct cursor_pos output_cursor;
8217 /* EXPORT:
8218 Set the global variable output_cursor to CURSOR. All cursor
8219 positions are relative to updated_window. */
8221 void
8222 set_output_cursor (cursor)
8223 struct cursor_pos *cursor;
8225 output_cursor.hpos = cursor->hpos;
8226 output_cursor.vpos = cursor->vpos;
8227 output_cursor.x = cursor->x;
8228 output_cursor.y = cursor->y;
8232 /* EXPORT for RIF:
8233 Set a nominal cursor position.
8235 HPOS and VPOS are column/row positions in a window glyph matrix. X
8236 and Y are window text area relative pixel positions.
8238 If this is done during an update, updated_window will contain the
8239 window that is being updated and the position is the future output
8240 cursor position for that window. If updated_window is null, use
8241 selected_window and display the cursor at the given position. */
8243 void
8244 x_cursor_to (vpos, hpos, y, x)
8245 int vpos, hpos, y, x;
8247 struct window *w;
8249 /* If updated_window is not set, work on selected_window. */
8250 if (updated_window)
8251 w = updated_window;
8252 else
8253 w = XWINDOW (selected_window);
8255 /* Set the output cursor. */
8256 output_cursor.hpos = hpos;
8257 output_cursor.vpos = vpos;
8258 output_cursor.x = x;
8259 output_cursor.y = y;
8261 /* If not called as part of an update, really display the cursor.
8262 This will also set the cursor position of W. */
8263 if (updated_window == NULL)
8265 BLOCK_INPUT;
8266 display_and_set_cursor (w, 1, hpos, vpos, x, y);
8267 if (rif->flush_display_optional)
8268 rif->flush_display_optional (SELECTED_FRAME ());
8269 UNBLOCK_INPUT;
8273 #endif /* HAVE_WINDOW_SYSTEM */
8276 /***********************************************************************
8277 Tool-bars
8278 ***********************************************************************/
8280 #ifdef HAVE_WINDOW_SYSTEM
8282 /* Where the mouse was last time we reported a mouse event. */
8284 FRAME_PTR last_mouse_frame;
8286 /* Tool-bar item index of the item on which a mouse button was pressed
8287 or -1. */
8289 int last_tool_bar_item;
8292 /* Update the tool-bar item list for frame F. This has to be done
8293 before we start to fill in any display lines. Called from
8294 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
8295 and restore it here. */
8297 static void
8298 update_tool_bar (f, save_match_data)
8299 struct frame *f;
8300 int save_match_data;
8302 #ifdef USE_GTK
8303 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
8304 #else
8305 int do_update = WINDOWP (f->tool_bar_window)
8306 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
8307 #endif
8309 if (do_update)
8311 Lisp_Object window;
8312 struct window *w;
8314 window = FRAME_SELECTED_WINDOW (f);
8315 w = XWINDOW (window);
8317 /* If the user has switched buffers or windows, we need to
8318 recompute to reflect the new bindings. But we'll
8319 recompute when update_mode_lines is set too; that means
8320 that people can use force-mode-line-update to request
8321 that the menu bar be recomputed. The adverse effect on
8322 the rest of the redisplay algorithm is about the same as
8323 windows_or_buffers_changed anyway. */
8324 if (windows_or_buffers_changed
8325 || !NILP (w->update_mode_line)
8326 || update_mode_lines
8327 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8328 < BUF_MODIFF (XBUFFER (w->buffer)))
8329 != !NILP (w->last_had_star))
8330 || ((!NILP (Vtransient_mark_mode)
8331 && !NILP (XBUFFER (w->buffer)->mark_active))
8332 != !NILP (w->region_showing)))
8334 struct buffer *prev = current_buffer;
8335 int count = SPECPDL_INDEX ();
8336 Lisp_Object old_tool_bar;
8337 struct gcpro gcpro1;
8339 /* Set current_buffer to the buffer of the selected
8340 window of the frame, so that we get the right local
8341 keymaps. */
8342 set_buffer_internal_1 (XBUFFER (w->buffer));
8344 /* Save match data, if we must. */
8345 if (save_match_data)
8346 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8348 /* Make sure that we don't accidentally use bogus keymaps. */
8349 if (NILP (Voverriding_local_map_menu_flag))
8351 specbind (Qoverriding_terminal_local_map, Qnil);
8352 specbind (Qoverriding_local_map, Qnil);
8355 old_tool_bar = f->tool_bar_items;
8356 GCPRO1 (old_tool_bar);
8358 /* Build desired tool-bar items from keymaps. */
8359 BLOCK_INPUT;
8360 f->tool_bar_items
8361 = tool_bar_items (f->tool_bar_items, &f->n_tool_bar_items);
8362 UNBLOCK_INPUT;
8364 /* Redisplay the tool-bar if we changed it. */
8365 if (! NILP (Fequal (old_tool_bar, f->tool_bar_items)))
8366 w->update_mode_line = Qt;
8368 UNGCPRO;
8370 unbind_to (count, Qnil);
8371 set_buffer_internal_1 (prev);
8377 /* Set F->desired_tool_bar_string to a Lisp string representing frame
8378 F's desired tool-bar contents. F->tool_bar_items must have
8379 been set up previously by calling prepare_menu_bars. */
8381 static void
8382 build_desired_tool_bar_string (f)
8383 struct frame *f;
8385 int i, size, size_needed;
8386 struct gcpro gcpro1, gcpro2, gcpro3;
8387 Lisp_Object image, plist, props;
8389 image = plist = props = Qnil;
8390 GCPRO3 (image, plist, props);
8392 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
8393 Otherwise, make a new string. */
8395 /* The size of the string we might be able to reuse. */
8396 size = (STRINGP (f->desired_tool_bar_string)
8397 ? SCHARS (f->desired_tool_bar_string)
8398 : 0);
8400 /* We need one space in the string for each image. */
8401 size_needed = f->n_tool_bar_items;
8403 /* Reuse f->desired_tool_bar_string, if possible. */
8404 if (size < size_needed || NILP (f->desired_tool_bar_string))
8405 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
8406 make_number (' '));
8407 else
8409 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
8410 Fremove_text_properties (make_number (0), make_number (size),
8411 props, f->desired_tool_bar_string);
8414 /* Put a `display' property on the string for the images to display,
8415 put a `menu_item' property on tool-bar items with a value that
8416 is the index of the item in F's tool-bar item vector. */
8417 for (i = 0; i < f->n_tool_bar_items; ++i)
8419 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
8421 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
8422 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
8423 int hmargin, vmargin, relief, idx, end;
8424 extern Lisp_Object QCrelief, QCmargin, QCconversion;
8426 /* If image is a vector, choose the image according to the
8427 button state. */
8428 image = PROP (TOOL_BAR_ITEM_IMAGES);
8429 if (VECTORP (image))
8431 if (enabled_p)
8432 idx = (selected_p
8433 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
8434 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
8435 else
8436 idx = (selected_p
8437 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
8438 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
8440 xassert (ASIZE (image) >= idx);
8441 image = AREF (image, idx);
8443 else
8444 idx = -1;
8446 /* Ignore invalid image specifications. */
8447 if (!valid_image_p (image))
8448 continue;
8450 /* Display the tool-bar button pressed, or depressed. */
8451 plist = Fcopy_sequence (XCDR (image));
8453 /* Compute margin and relief to draw. */
8454 relief = (tool_bar_button_relief >= 0
8455 ? tool_bar_button_relief
8456 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
8457 hmargin = vmargin = relief;
8459 if (INTEGERP (Vtool_bar_button_margin)
8460 && XINT (Vtool_bar_button_margin) > 0)
8462 hmargin += XFASTINT (Vtool_bar_button_margin);
8463 vmargin += XFASTINT (Vtool_bar_button_margin);
8465 else if (CONSP (Vtool_bar_button_margin))
8467 if (INTEGERP (XCAR (Vtool_bar_button_margin))
8468 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
8469 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
8471 if (INTEGERP (XCDR (Vtool_bar_button_margin))
8472 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
8473 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
8476 if (auto_raise_tool_bar_buttons_p)
8478 /* Add a `:relief' property to the image spec if the item is
8479 selected. */
8480 if (selected_p)
8482 plist = Fplist_put (plist, QCrelief, make_number (-relief));
8483 hmargin -= relief;
8484 vmargin -= relief;
8487 else
8489 /* If image is selected, display it pressed, i.e. with a
8490 negative relief. If it's not selected, display it with a
8491 raised relief. */
8492 plist = Fplist_put (plist, QCrelief,
8493 (selected_p
8494 ? make_number (-relief)
8495 : make_number (relief)));
8496 hmargin -= relief;
8497 vmargin -= relief;
8500 /* Put a margin around the image. */
8501 if (hmargin || vmargin)
8503 if (hmargin == vmargin)
8504 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
8505 else
8506 plist = Fplist_put (plist, QCmargin,
8507 Fcons (make_number (hmargin),
8508 make_number (vmargin)));
8511 /* If button is not enabled, and we don't have special images
8512 for the disabled state, make the image appear disabled by
8513 applying an appropriate algorithm to it. */
8514 if (!enabled_p && idx < 0)
8515 plist = Fplist_put (plist, QCconversion, Qdisabled);
8517 /* Put a `display' text property on the string for the image to
8518 display. Put a `menu-item' property on the string that gives
8519 the start of this item's properties in the tool-bar items
8520 vector. */
8521 image = Fcons (Qimage, plist);
8522 props = list4 (Qdisplay, image,
8523 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
8525 /* Let the last image hide all remaining spaces in the tool bar
8526 string. The string can be longer than needed when we reuse a
8527 previous string. */
8528 if (i + 1 == f->n_tool_bar_items)
8529 end = SCHARS (f->desired_tool_bar_string);
8530 else
8531 end = i + 1;
8532 Fadd_text_properties (make_number (i), make_number (end),
8533 props, f->desired_tool_bar_string);
8534 #undef PROP
8537 UNGCPRO;
8541 /* Display one line of the tool-bar of frame IT->f. */
8543 static void
8544 display_tool_bar_line (it)
8545 struct it *it;
8547 struct glyph_row *row = it->glyph_row;
8548 int max_x = it->last_visible_x;
8549 struct glyph *last;
8551 prepare_desired_row (row);
8552 row->y = it->current_y;
8554 /* Note that this isn't made use of if the face hasn't a box,
8555 so there's no need to check the face here. */
8556 it->start_of_box_run_p = 1;
8558 while (it->current_x < max_x)
8560 int x_before, x, n_glyphs_before, i, nglyphs;
8562 /* Get the next display element. */
8563 if (!get_next_display_element (it))
8564 break;
8566 /* Produce glyphs. */
8567 x_before = it->current_x;
8568 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
8569 PRODUCE_GLYPHS (it);
8571 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
8572 i = 0;
8573 x = x_before;
8574 while (i < nglyphs)
8576 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
8578 if (x + glyph->pixel_width > max_x)
8580 /* Glyph doesn't fit on line. */
8581 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
8582 it->current_x = x;
8583 goto out;
8586 ++it->hpos;
8587 x += glyph->pixel_width;
8588 ++i;
8591 /* Stop at line ends. */
8592 if (ITERATOR_AT_END_OF_LINE_P (it))
8593 break;
8595 set_iterator_to_next (it, 1);
8598 out:;
8600 row->displays_text_p = row->used[TEXT_AREA] != 0;
8601 extend_face_to_end_of_line (it);
8602 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
8603 last->right_box_line_p = 1;
8604 if (last == row->glyphs[TEXT_AREA])
8605 last->left_box_line_p = 1;
8606 compute_line_metrics (it);
8608 /* If line is empty, make it occupy the rest of the tool-bar. */
8609 if (!row->displays_text_p)
8611 row->height = row->phys_height = it->last_visible_y - row->y;
8612 row->ascent = row->phys_ascent = 0;
8615 row->full_width_p = 1;
8616 row->continued_p = 0;
8617 row->truncated_on_left_p = 0;
8618 row->truncated_on_right_p = 0;
8620 it->current_x = it->hpos = 0;
8621 it->current_y += row->height;
8622 ++it->vpos;
8623 ++it->glyph_row;
8627 /* Value is the number of screen lines needed to make all tool-bar
8628 items of frame F visible. */
8630 static int
8631 tool_bar_lines_needed (f)
8632 struct frame *f;
8634 struct window *w = XWINDOW (f->tool_bar_window);
8635 struct it it;
8637 /* Initialize an iterator for iteration over
8638 F->desired_tool_bar_string in the tool-bar window of frame F. */
8639 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8640 it.first_visible_x = 0;
8641 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8642 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8644 while (!ITERATOR_AT_END_P (&it))
8646 it.glyph_row = w->desired_matrix->rows;
8647 clear_glyph_row (it.glyph_row);
8648 display_tool_bar_line (&it);
8651 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
8655 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
8656 0, 1, 0,
8657 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
8658 (frame)
8659 Lisp_Object frame;
8661 struct frame *f;
8662 struct window *w;
8663 int nlines = 0;
8665 if (NILP (frame))
8666 frame = selected_frame;
8667 else
8668 CHECK_FRAME (frame);
8669 f = XFRAME (frame);
8671 if (WINDOWP (f->tool_bar_window)
8672 || (w = XWINDOW (f->tool_bar_window),
8673 WINDOW_TOTAL_LINES (w) > 0))
8675 update_tool_bar (f, 1);
8676 if (f->n_tool_bar_items)
8678 build_desired_tool_bar_string (f);
8679 nlines = tool_bar_lines_needed (f);
8683 return make_number (nlines);
8687 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
8688 height should be changed. */
8690 static int
8691 redisplay_tool_bar (f)
8692 struct frame *f;
8694 struct window *w;
8695 struct it it;
8696 struct glyph_row *row;
8697 int change_height_p = 0;
8699 #ifdef USE_GTK
8700 if (FRAME_EXTERNAL_TOOL_BAR (f))
8701 update_frame_tool_bar (f);
8702 return 0;
8703 #endif
8705 /* If frame hasn't a tool-bar window or if it is zero-height, don't
8706 do anything. This means you must start with tool-bar-lines
8707 non-zero to get the auto-sizing effect. Or in other words, you
8708 can turn off tool-bars by specifying tool-bar-lines zero. */
8709 if (!WINDOWP (f->tool_bar_window)
8710 || (w = XWINDOW (f->tool_bar_window),
8711 WINDOW_TOTAL_LINES (w) == 0))
8712 return 0;
8714 /* Set up an iterator for the tool-bar window. */
8715 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8716 it.first_visible_x = 0;
8717 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8718 row = it.glyph_row;
8720 /* Build a string that represents the contents of the tool-bar. */
8721 build_desired_tool_bar_string (f);
8722 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8724 /* Display as many lines as needed to display all tool-bar items. */
8725 while (it.current_y < it.last_visible_y)
8726 display_tool_bar_line (&it);
8728 /* It doesn't make much sense to try scrolling in the tool-bar
8729 window, so don't do it. */
8730 w->desired_matrix->no_scrolling_p = 1;
8731 w->must_be_updated_p = 1;
8733 if (auto_resize_tool_bars_p)
8735 int nlines;
8737 /* If we couldn't display everything, change the tool-bar's
8738 height. */
8739 if (IT_STRING_CHARPOS (it) < it.end_charpos)
8740 change_height_p = 1;
8742 /* If there are blank lines at the end, except for a partially
8743 visible blank line at the end that is smaller than
8744 FRAME_LINE_HEIGHT, change the tool-bar's height. */
8745 row = it.glyph_row - 1;
8746 if (!row->displays_text_p
8747 && row->height >= FRAME_LINE_HEIGHT (f))
8748 change_height_p = 1;
8750 /* If row displays tool-bar items, but is partially visible,
8751 change the tool-bar's height. */
8752 if (row->displays_text_p
8753 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
8754 change_height_p = 1;
8756 /* Resize windows as needed by changing the `tool-bar-lines'
8757 frame parameter. */
8758 if (change_height_p
8759 && (nlines = tool_bar_lines_needed (f),
8760 nlines != WINDOW_TOTAL_LINES (w)))
8762 extern Lisp_Object Qtool_bar_lines;
8763 Lisp_Object frame;
8764 int old_height = WINDOW_TOTAL_LINES (w);
8766 XSETFRAME (frame, f);
8767 clear_glyph_matrix (w->desired_matrix);
8768 Fmodify_frame_parameters (frame,
8769 Fcons (Fcons (Qtool_bar_lines,
8770 make_number (nlines)),
8771 Qnil));
8772 if (WINDOW_TOTAL_LINES (w) != old_height)
8773 fonts_changed_p = 1;
8777 return change_height_p;
8781 /* Get information about the tool-bar item which is displayed in GLYPH
8782 on frame F. Return in *PROP_IDX the index where tool-bar item
8783 properties start in F->tool_bar_items. Value is zero if
8784 GLYPH doesn't display a tool-bar item. */
8786 static int
8787 tool_bar_item_info (f, glyph, prop_idx)
8788 struct frame *f;
8789 struct glyph *glyph;
8790 int *prop_idx;
8792 Lisp_Object prop;
8793 int success_p;
8794 int charpos;
8796 /* This function can be called asynchronously, which means we must
8797 exclude any possibility that Fget_text_property signals an
8798 error. */
8799 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
8800 charpos = max (0, charpos);
8802 /* Get the text property `menu-item' at pos. The value of that
8803 property is the start index of this item's properties in
8804 F->tool_bar_items. */
8805 prop = Fget_text_property (make_number (charpos),
8806 Qmenu_item, f->current_tool_bar_string);
8807 if (INTEGERP (prop))
8809 *prop_idx = XINT (prop);
8810 success_p = 1;
8812 else
8813 success_p = 0;
8815 return success_p;
8819 /* Get information about the tool-bar item at position X/Y on frame F.
8820 Return in *GLYPH a pointer to the glyph of the tool-bar item in
8821 the current matrix of the tool-bar window of F, or NULL if not
8822 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
8823 item in F->tool_bar_items. Value is
8825 -1 if X/Y is not on a tool-bar item
8826 0 if X/Y is on the same item that was highlighted before.
8827 1 otherwise. */
8829 static int
8830 get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
8831 struct frame *f;
8832 int x, y;
8833 struct glyph **glyph;
8834 int *hpos, *vpos, *prop_idx;
8836 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8837 struct window *w = XWINDOW (f->tool_bar_window);
8838 int area;
8840 /* Find the glyph under X/Y. */
8841 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
8842 if (*glyph == NULL)
8843 return -1;
8845 /* Get the start of this tool-bar item's properties in
8846 f->tool_bar_items. */
8847 if (!tool_bar_item_info (f, *glyph, prop_idx))
8848 return -1;
8850 /* Is mouse on the highlighted item? */
8851 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
8852 && *vpos >= dpyinfo->mouse_face_beg_row
8853 && *vpos <= dpyinfo->mouse_face_end_row
8854 && (*vpos > dpyinfo->mouse_face_beg_row
8855 || *hpos >= dpyinfo->mouse_face_beg_col)
8856 && (*vpos < dpyinfo->mouse_face_end_row
8857 || *hpos < dpyinfo->mouse_face_end_col
8858 || dpyinfo->mouse_face_past_end))
8859 return 0;
8861 return 1;
8865 /* EXPORT:
8866 Handle mouse button event on the tool-bar of frame F, at
8867 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
8868 0 for button release. MODIFIERS is event modifiers for button
8869 release. */
8871 void
8872 handle_tool_bar_click (f, x, y, down_p, modifiers)
8873 struct frame *f;
8874 int x, y, down_p;
8875 unsigned int modifiers;
8877 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8878 struct window *w = XWINDOW (f->tool_bar_window);
8879 int hpos, vpos, prop_idx;
8880 struct glyph *glyph;
8881 Lisp_Object enabled_p;
8883 /* If not on the highlighted tool-bar item, return. */
8884 frame_to_window_pixel_xy (w, &x, &y);
8885 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
8886 return;
8888 /* If item is disabled, do nothing. */
8889 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
8890 if (NILP (enabled_p))
8891 return;
8893 if (down_p)
8895 /* Show item in pressed state. */
8896 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
8897 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
8898 last_tool_bar_item = prop_idx;
8900 else
8902 Lisp_Object key, frame;
8903 struct input_event event;
8904 EVENT_INIT (event);
8906 /* Show item in released state. */
8907 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
8908 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
8910 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
8912 XSETFRAME (frame, f);
8913 event.kind = TOOL_BAR_EVENT;
8914 event.frame_or_window = frame;
8915 event.arg = frame;
8916 kbd_buffer_store_event (&event);
8918 event.kind = TOOL_BAR_EVENT;
8919 event.frame_or_window = frame;
8920 event.arg = key;
8921 event.modifiers = modifiers;
8922 kbd_buffer_store_event (&event);
8923 last_tool_bar_item = -1;
8928 /* Possibly highlight a tool-bar item on frame F when mouse moves to
8929 tool-bar window-relative coordinates X/Y. Called from
8930 note_mouse_highlight. */
8932 static void
8933 note_tool_bar_highlight (f, x, y)
8934 struct frame *f;
8935 int x, y;
8937 Lisp_Object window = f->tool_bar_window;
8938 struct window *w = XWINDOW (window);
8939 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8940 int hpos, vpos;
8941 struct glyph *glyph;
8942 struct glyph_row *row;
8943 int i;
8944 Lisp_Object enabled_p;
8945 int prop_idx;
8946 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
8947 int mouse_down_p, rc;
8949 /* Function note_mouse_highlight is called with negative x(y
8950 values when mouse moves outside of the frame. */
8951 if (x <= 0 || y <= 0)
8953 clear_mouse_face (dpyinfo);
8954 return;
8957 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
8958 if (rc < 0)
8960 /* Not on tool-bar item. */
8961 clear_mouse_face (dpyinfo);
8962 return;
8964 else if (rc == 0)
8965 /* On same tool-bar item as before. */
8966 goto set_help_echo;
8968 clear_mouse_face (dpyinfo);
8970 /* Mouse is down, but on different tool-bar item? */
8971 mouse_down_p = (dpyinfo->grabbed
8972 && f == last_mouse_frame
8973 && FRAME_LIVE_P (f));
8974 if (mouse_down_p
8975 && last_tool_bar_item != prop_idx)
8976 return;
8978 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
8979 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
8981 /* If tool-bar item is not enabled, don't highlight it. */
8982 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
8983 if (!NILP (enabled_p))
8985 /* Compute the x-position of the glyph. In front and past the
8986 image is a space. We include this in the highlighted area. */
8987 row = MATRIX_ROW (w->current_matrix, vpos);
8988 for (i = x = 0; i < hpos; ++i)
8989 x += row->glyphs[TEXT_AREA][i].pixel_width;
8991 /* Record this as the current active region. */
8992 dpyinfo->mouse_face_beg_col = hpos;
8993 dpyinfo->mouse_face_beg_row = vpos;
8994 dpyinfo->mouse_face_beg_x = x;
8995 dpyinfo->mouse_face_beg_y = row->y;
8996 dpyinfo->mouse_face_past_end = 0;
8998 dpyinfo->mouse_face_end_col = hpos + 1;
8999 dpyinfo->mouse_face_end_row = vpos;
9000 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
9001 dpyinfo->mouse_face_end_y = row->y;
9002 dpyinfo->mouse_face_window = window;
9003 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
9005 /* Display it as active. */
9006 show_mouse_face (dpyinfo, draw);
9007 dpyinfo->mouse_face_image_state = draw;
9010 set_help_echo:
9012 /* Set help_echo_string to a help string to display for this tool-bar item.
9013 XTread_socket does the rest. */
9014 help_echo_object = help_echo_window = Qnil;
9015 help_echo_pos = -1;
9016 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
9017 if (NILP (help_echo_string))
9018 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
9021 #endif /* HAVE_WINDOW_SYSTEM */
9025 /************************************************************************
9026 Horizontal scrolling
9027 ************************************************************************/
9029 static int hscroll_window_tree P_ ((Lisp_Object));
9030 static int hscroll_windows P_ ((Lisp_Object));
9032 /* For all leaf windows in the window tree rooted at WINDOW, set their
9033 hscroll value so that PT is (i) visible in the window, and (ii) so
9034 that it is not within a certain margin at the window's left and
9035 right border. Value is non-zero if any window's hscroll has been
9036 changed. */
9038 static int
9039 hscroll_window_tree (window)
9040 Lisp_Object window;
9042 int hscrolled_p = 0;
9043 int hscroll_relative_p = FLOATP (Vhscroll_step);
9044 int hscroll_step_abs = 0;
9045 double hscroll_step_rel = 0;
9047 if (hscroll_relative_p)
9049 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
9050 if (hscroll_step_rel < 0)
9052 hscroll_relative_p = 0;
9053 hscroll_step_abs = 0;
9056 else if (INTEGERP (Vhscroll_step))
9058 hscroll_step_abs = XINT (Vhscroll_step);
9059 if (hscroll_step_abs < 0)
9060 hscroll_step_abs = 0;
9062 else
9063 hscroll_step_abs = 0;
9065 while (WINDOWP (window))
9067 struct window *w = XWINDOW (window);
9069 if (WINDOWP (w->hchild))
9070 hscrolled_p |= hscroll_window_tree (w->hchild);
9071 else if (WINDOWP (w->vchild))
9072 hscrolled_p |= hscroll_window_tree (w->vchild);
9073 else if (w->cursor.vpos >= 0)
9075 int h_margin;
9076 int text_area_width;
9077 struct glyph_row *current_cursor_row
9078 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
9079 struct glyph_row *desired_cursor_row
9080 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
9081 struct glyph_row *cursor_row
9082 = (desired_cursor_row->enabled_p
9083 ? desired_cursor_row
9084 : current_cursor_row);
9086 text_area_width = window_box_width (w, TEXT_AREA);
9088 /* Scroll when cursor is inside this scroll margin. */
9089 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
9091 if ((XFASTINT (w->hscroll)
9092 && w->cursor.x <= h_margin)
9093 || (cursor_row->enabled_p
9094 && cursor_row->truncated_on_right_p
9095 && (w->cursor.x >= text_area_width - h_margin)))
9097 struct it it;
9098 int hscroll;
9099 struct buffer *saved_current_buffer;
9100 int pt;
9101 int wanted_x;
9103 /* Find point in a display of infinite width. */
9104 saved_current_buffer = current_buffer;
9105 current_buffer = XBUFFER (w->buffer);
9107 if (w == XWINDOW (selected_window))
9108 pt = BUF_PT (current_buffer);
9109 else
9111 pt = marker_position (w->pointm);
9112 pt = max (BEGV, pt);
9113 pt = min (ZV, pt);
9116 /* Move iterator to pt starting at cursor_row->start in
9117 a line with infinite width. */
9118 init_to_row_start (&it, w, cursor_row);
9119 it.last_visible_x = INFINITY;
9120 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
9121 current_buffer = saved_current_buffer;
9123 /* Position cursor in window. */
9124 if (!hscroll_relative_p && hscroll_step_abs == 0)
9125 hscroll = max (0, (it.current_x
9126 - (ITERATOR_AT_END_OF_LINE_P (&it)
9127 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
9128 : (text_area_width / 2))))
9129 / FRAME_COLUMN_WIDTH (it.f);
9130 else if (w->cursor.x >= text_area_width - h_margin)
9132 if (hscroll_relative_p)
9133 wanted_x = text_area_width * (1 - hscroll_step_rel)
9134 - h_margin;
9135 else
9136 wanted_x = text_area_width
9137 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9138 - h_margin;
9139 hscroll
9140 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9142 else
9144 if (hscroll_relative_p)
9145 wanted_x = text_area_width * hscroll_step_rel
9146 + h_margin;
9147 else
9148 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9149 + h_margin;
9150 hscroll
9151 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9153 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
9155 /* Don't call Fset_window_hscroll if value hasn't
9156 changed because it will prevent redisplay
9157 optimizations. */
9158 if (XFASTINT (w->hscroll) != hscroll)
9160 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
9161 w->hscroll = make_number (hscroll);
9162 hscrolled_p = 1;
9167 window = w->next;
9170 /* Value is non-zero if hscroll of any leaf window has been changed. */
9171 return hscrolled_p;
9175 /* Set hscroll so that cursor is visible and not inside horizontal
9176 scroll margins for all windows in the tree rooted at WINDOW. See
9177 also hscroll_window_tree above. Value is non-zero if any window's
9178 hscroll has been changed. If it has, desired matrices on the frame
9179 of WINDOW are cleared. */
9181 static int
9182 hscroll_windows (window)
9183 Lisp_Object window;
9185 int hscrolled_p;
9187 if (automatic_hscrolling_p)
9189 hscrolled_p = hscroll_window_tree (window);
9190 if (hscrolled_p)
9191 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
9193 else
9194 hscrolled_p = 0;
9195 return hscrolled_p;
9200 /************************************************************************
9201 Redisplay
9202 ************************************************************************/
9204 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
9205 to a non-zero value. This is sometimes handy to have in a debugger
9206 session. */
9208 #if GLYPH_DEBUG
9210 /* First and last unchanged row for try_window_id. */
9212 int debug_first_unchanged_at_end_vpos;
9213 int debug_last_unchanged_at_beg_vpos;
9215 /* Delta vpos and y. */
9217 int debug_dvpos, debug_dy;
9219 /* Delta in characters and bytes for try_window_id. */
9221 int debug_delta, debug_delta_bytes;
9223 /* Values of window_end_pos and window_end_vpos at the end of
9224 try_window_id. */
9226 EMACS_INT debug_end_pos, debug_end_vpos;
9228 /* Append a string to W->desired_matrix->method. FMT is a printf
9229 format string. A1...A9 are a supplement for a variable-length
9230 argument list. If trace_redisplay_p is non-zero also printf the
9231 resulting string to stderr. */
9233 static void
9234 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
9235 struct window *w;
9236 char *fmt;
9237 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
9239 char buffer[512];
9240 char *method = w->desired_matrix->method;
9241 int len = strlen (method);
9242 int size = sizeof w->desired_matrix->method;
9243 int remaining = size - len - 1;
9245 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
9246 if (len && remaining)
9248 method[len] = '|';
9249 --remaining, ++len;
9252 strncpy (method + len, buffer, remaining);
9254 if (trace_redisplay_p)
9255 fprintf (stderr, "%p (%s): %s\n",
9257 ((BUFFERP (w->buffer)
9258 && STRINGP (XBUFFER (w->buffer)->name))
9259 ? (char *) SDATA (XBUFFER (w->buffer)->name)
9260 : "no buffer"),
9261 buffer);
9264 #endif /* GLYPH_DEBUG */
9267 /* Value is non-zero if all changes in window W, which displays
9268 current_buffer, are in the text between START and END. START is a
9269 buffer position, END is given as a distance from Z. Used in
9270 redisplay_internal for display optimization. */
9272 static INLINE int
9273 text_outside_line_unchanged_p (w, start, end)
9274 struct window *w;
9275 int start, end;
9277 int unchanged_p = 1;
9279 /* If text or overlays have changed, see where. */
9280 if (XFASTINT (w->last_modified) < MODIFF
9281 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9283 /* Gap in the line? */
9284 if (GPT < start || Z - GPT < end)
9285 unchanged_p = 0;
9287 /* Changes start in front of the line, or end after it? */
9288 if (unchanged_p
9289 && (BEG_UNCHANGED < start - 1
9290 || END_UNCHANGED < end))
9291 unchanged_p = 0;
9293 /* If selective display, can't optimize if changes start at the
9294 beginning of the line. */
9295 if (unchanged_p
9296 && INTEGERP (current_buffer->selective_display)
9297 && XINT (current_buffer->selective_display) > 0
9298 && (BEG_UNCHANGED < start || GPT <= start))
9299 unchanged_p = 0;
9301 /* If there are overlays at the start or end of the line, these
9302 may have overlay strings with newlines in them. A change at
9303 START, for instance, may actually concern the display of such
9304 overlay strings as well, and they are displayed on different
9305 lines. So, quickly rule out this case. (For the future, it
9306 might be desirable to implement something more telling than
9307 just BEG/END_UNCHANGED.) */
9308 if (unchanged_p)
9310 if (BEG + BEG_UNCHANGED == start
9311 && overlay_touches_p (start))
9312 unchanged_p = 0;
9313 if (END_UNCHANGED == end
9314 && overlay_touches_p (Z - end))
9315 unchanged_p = 0;
9319 return unchanged_p;
9323 /* Do a frame update, taking possible shortcuts into account. This is
9324 the main external entry point for redisplay.
9326 If the last redisplay displayed an echo area message and that message
9327 is no longer requested, we clear the echo area or bring back the
9328 mini-buffer if that is in use. */
9330 void
9331 redisplay ()
9333 redisplay_internal (0);
9337 static Lisp_Object
9338 overlay_arrow_string_or_property (var, pbitmap)
9339 Lisp_Object var;
9340 int *pbitmap;
9342 Lisp_Object pstr = Fget (var, Qoverlay_arrow_string);
9343 Lisp_Object bitmap;
9345 if (pbitmap)
9347 *pbitmap = 0;
9348 if (bitmap = Fget (var, Qoverlay_arrow_bitmap), INTEGERP (bitmap))
9349 *pbitmap = XINT (bitmap);
9352 if (!NILP (pstr))
9353 return pstr;
9354 return Voverlay_arrow_string;
9357 /* Return 1 if there are any overlay-arrows in current_buffer. */
9358 static int
9359 overlay_arrow_in_current_buffer_p ()
9361 Lisp_Object vlist;
9363 for (vlist = Voverlay_arrow_variable_list;
9364 CONSP (vlist);
9365 vlist = XCDR (vlist))
9367 Lisp_Object var = XCAR (vlist);
9368 Lisp_Object val;
9370 if (!SYMBOLP (var))
9371 continue;
9372 val = find_symbol_value (var);
9373 if (MARKERP (val)
9374 && current_buffer == XMARKER (val)->buffer)
9375 return 1;
9377 return 0;
9381 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
9382 has changed. */
9384 static int
9385 overlay_arrows_changed_p ()
9387 Lisp_Object vlist;
9389 for (vlist = Voverlay_arrow_variable_list;
9390 CONSP (vlist);
9391 vlist = XCDR (vlist))
9393 Lisp_Object var = XCAR (vlist);
9394 Lisp_Object val, pstr;
9396 if (!SYMBOLP (var))
9397 continue;
9398 val = find_symbol_value (var);
9399 if (!MARKERP (val))
9400 continue;
9401 if (! EQ (COERCE_MARKER (val),
9402 Fget (var, Qlast_arrow_position))
9403 || ! (pstr = overlay_arrow_string_or_property (var, 0),
9404 EQ (pstr, Fget (var, Qlast_arrow_string))))
9405 return 1;
9407 return 0;
9410 /* Mark overlay arrows to be updated on next redisplay. */
9412 static void
9413 update_overlay_arrows (up_to_date)
9414 int up_to_date;
9416 Lisp_Object vlist;
9418 for (vlist = Voverlay_arrow_variable_list;
9419 CONSP (vlist);
9420 vlist = XCDR (vlist))
9422 Lisp_Object var = XCAR (vlist);
9424 if (!SYMBOLP (var))
9425 continue;
9427 if (up_to_date)
9429 Lisp_Object val = find_symbol_value (var);
9430 Fput (var, Qlast_arrow_position,
9431 COERCE_MARKER (val));
9432 Fput (var, Qlast_arrow_string,
9433 overlay_arrow_string_or_property (var, 0));
9435 else if (up_to_date < 0
9436 || !NILP (Fget (var, Qlast_arrow_position)))
9438 Fput (var, Qlast_arrow_position, Qt);
9439 Fput (var, Qlast_arrow_string, Qt);
9445 /* Return overlay arrow string at row, or nil. */
9447 static Lisp_Object
9448 overlay_arrow_at_row (f, row, pbitmap)
9449 struct frame *f;
9450 struct glyph_row *row;
9451 int *pbitmap;
9453 Lisp_Object vlist;
9455 for (vlist = Voverlay_arrow_variable_list;
9456 CONSP (vlist);
9457 vlist = XCDR (vlist))
9459 Lisp_Object var = XCAR (vlist);
9460 Lisp_Object val;
9462 if (!SYMBOLP (var))
9463 continue;
9465 val = find_symbol_value (var);
9467 if (MARKERP (val)
9468 && current_buffer == XMARKER (val)->buffer
9469 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
9471 val = overlay_arrow_string_or_property (var, pbitmap);
9472 if (FRAME_WINDOW_P (f))
9473 return Qt;
9474 else if (STRINGP (val))
9475 return val;
9476 break;
9480 *pbitmap = 0;
9481 return Qnil;
9484 /* Return 1 if point moved out of or into a composition. Otherwise
9485 return 0. PREV_BUF and PREV_PT are the last point buffer and
9486 position. BUF and PT are the current point buffer and position. */
9489 check_point_in_composition (prev_buf, prev_pt, buf, pt)
9490 struct buffer *prev_buf, *buf;
9491 int prev_pt, pt;
9493 int start, end;
9494 Lisp_Object prop;
9495 Lisp_Object buffer;
9497 XSETBUFFER (buffer, buf);
9498 /* Check a composition at the last point if point moved within the
9499 same buffer. */
9500 if (prev_buf == buf)
9502 if (prev_pt == pt)
9503 /* Point didn't move. */
9504 return 0;
9506 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
9507 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
9508 && COMPOSITION_VALID_P (start, end, prop)
9509 && start < prev_pt && end > prev_pt)
9510 /* The last point was within the composition. Return 1 iff
9511 point moved out of the composition. */
9512 return (pt <= start || pt >= end);
9515 /* Check a composition at the current point. */
9516 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
9517 && find_composition (pt, -1, &start, &end, &prop, buffer)
9518 && COMPOSITION_VALID_P (start, end, prop)
9519 && start < pt && end > pt);
9523 /* Reconsider the setting of B->clip_changed which is displayed
9524 in window W. */
9526 static INLINE void
9527 reconsider_clip_changes (w, b)
9528 struct window *w;
9529 struct buffer *b;
9531 if (b->clip_changed
9532 && !NILP (w->window_end_valid)
9533 && w->current_matrix->buffer == b
9534 && w->current_matrix->zv == BUF_ZV (b)
9535 && w->current_matrix->begv == BUF_BEGV (b))
9536 b->clip_changed = 0;
9538 /* If display wasn't paused, and W is not a tool bar window, see if
9539 point has been moved into or out of a composition. In that case,
9540 we set b->clip_changed to 1 to force updating the screen. If
9541 b->clip_changed has already been set to 1, we can skip this
9542 check. */
9543 if (!b->clip_changed
9544 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
9546 int pt;
9548 if (w == XWINDOW (selected_window))
9549 pt = BUF_PT (current_buffer);
9550 else
9551 pt = marker_position (w->pointm);
9553 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
9554 || pt != XINT (w->last_point))
9555 && check_point_in_composition (w->current_matrix->buffer,
9556 XINT (w->last_point),
9557 XBUFFER (w->buffer), pt))
9558 b->clip_changed = 1;
9563 /* Select FRAME to forward the values of frame-local variables into C
9564 variables so that the redisplay routines can access those values
9565 directly. */
9567 static void
9568 select_frame_for_redisplay (frame)
9569 Lisp_Object frame;
9571 Lisp_Object tail, sym, val;
9572 Lisp_Object old = selected_frame;
9574 selected_frame = frame;
9576 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
9577 if (CONSP (XCAR (tail))
9578 && (sym = XCAR (XCAR (tail)),
9579 SYMBOLP (sym))
9580 && (sym = indirect_variable (sym),
9581 val = SYMBOL_VALUE (sym),
9582 (BUFFER_LOCAL_VALUEP (val)
9583 || SOME_BUFFER_LOCAL_VALUEP (val)))
9584 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9585 Fsymbol_value (sym);
9587 for (tail = XFRAME (old)->param_alist; CONSP (tail); tail = XCDR (tail))
9588 if (CONSP (XCAR (tail))
9589 && (sym = XCAR (XCAR (tail)),
9590 SYMBOLP (sym))
9591 && (sym = indirect_variable (sym),
9592 val = SYMBOL_VALUE (sym),
9593 (BUFFER_LOCAL_VALUEP (val)
9594 || SOME_BUFFER_LOCAL_VALUEP (val)))
9595 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9596 Fsymbol_value (sym);
9600 #define STOP_POLLING \
9601 do { if (! polling_stopped_here) stop_polling (); \
9602 polling_stopped_here = 1; } while (0)
9604 #define RESUME_POLLING \
9605 do { if (polling_stopped_here) start_polling (); \
9606 polling_stopped_here = 0; } while (0)
9609 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
9610 response to any user action; therefore, we should preserve the echo
9611 area. (Actually, our caller does that job.) Perhaps in the future
9612 avoid recentering windows if it is not necessary; currently that
9613 causes some problems. */
9615 static void
9616 redisplay_internal (preserve_echo_area)
9617 int preserve_echo_area;
9619 struct window *w = XWINDOW (selected_window);
9620 struct frame *f = XFRAME (w->frame);
9621 int pause;
9622 int must_finish = 0;
9623 struct text_pos tlbufpos, tlendpos;
9624 int number_of_visible_frames;
9625 int count;
9626 struct frame *sf = SELECTED_FRAME ();
9627 int polling_stopped_here = 0;
9629 /* Non-zero means redisplay has to consider all windows on all
9630 frames. Zero means, only selected_window is considered. */
9631 int consider_all_windows_p;
9633 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
9635 /* No redisplay if running in batch mode or frame is not yet fully
9636 initialized, or redisplay is explicitly turned off by setting
9637 Vinhibit_redisplay. */
9638 if (noninteractive
9639 || !NILP (Vinhibit_redisplay)
9640 || !f->glyphs_initialized_p)
9641 return;
9643 /* The flag redisplay_performed_directly_p is set by
9644 direct_output_for_insert when it already did the whole screen
9645 update necessary. */
9646 if (redisplay_performed_directly_p)
9648 redisplay_performed_directly_p = 0;
9649 if (!hscroll_windows (selected_window))
9650 return;
9653 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
9654 if (popup_activated ())
9655 return;
9656 #endif
9658 /* I don't think this happens but let's be paranoid. */
9659 if (redisplaying_p)
9660 return;
9662 /* Record a function that resets redisplaying_p to its old value
9663 when we leave this function. */
9664 count = SPECPDL_INDEX ();
9665 record_unwind_protect (unwind_redisplay,
9666 Fcons (make_number (redisplaying_p), selected_frame));
9667 ++redisplaying_p;
9668 specbind (Qinhibit_free_realized_faces, Qnil);
9670 retry:
9671 pause = 0;
9672 reconsider_clip_changes (w, current_buffer);
9674 /* If new fonts have been loaded that make a glyph matrix adjustment
9675 necessary, do it. */
9676 if (fonts_changed_p)
9678 adjust_glyphs (NULL);
9679 ++windows_or_buffers_changed;
9680 fonts_changed_p = 0;
9683 /* If face_change_count is non-zero, init_iterator will free all
9684 realized faces, which includes the faces referenced from current
9685 matrices. So, we can't reuse current matrices in this case. */
9686 if (face_change_count)
9687 ++windows_or_buffers_changed;
9689 if (! FRAME_WINDOW_P (sf)
9690 && previous_terminal_frame != sf)
9692 /* Since frames on an ASCII terminal share the same display
9693 area, displaying a different frame means redisplay the whole
9694 thing. */
9695 windows_or_buffers_changed++;
9696 SET_FRAME_GARBAGED (sf);
9697 XSETFRAME (Vterminal_frame, sf);
9699 previous_terminal_frame = sf;
9701 /* Set the visible flags for all frames. Do this before checking
9702 for resized or garbaged frames; they want to know if their frames
9703 are visible. See the comment in frame.h for
9704 FRAME_SAMPLE_VISIBILITY. */
9706 Lisp_Object tail, frame;
9708 number_of_visible_frames = 0;
9710 FOR_EACH_FRAME (tail, frame)
9712 struct frame *f = XFRAME (frame);
9714 FRAME_SAMPLE_VISIBILITY (f);
9715 if (FRAME_VISIBLE_P (f))
9716 ++number_of_visible_frames;
9717 clear_desired_matrices (f);
9721 /* Notice any pending interrupt request to change frame size. */
9722 do_pending_window_change (1);
9724 /* Clear frames marked as garbaged. */
9725 if (frame_garbaged)
9726 clear_garbaged_frames ();
9728 /* Build menubar and tool-bar items. */
9729 prepare_menu_bars ();
9731 if (windows_or_buffers_changed)
9732 update_mode_lines++;
9734 /* Detect case that we need to write or remove a star in the mode line. */
9735 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
9737 w->update_mode_line = Qt;
9738 if (buffer_shared > 1)
9739 update_mode_lines++;
9742 /* If %c is in the mode line, update it if needed. */
9743 if (!NILP (w->column_number_displayed)
9744 /* This alternative quickly identifies a common case
9745 where no change is needed. */
9746 && !(PT == XFASTINT (w->last_point)
9747 && XFASTINT (w->last_modified) >= MODIFF
9748 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
9749 && (XFASTINT (w->column_number_displayed)
9750 != (int) current_column ())) /* iftc */
9751 w->update_mode_line = Qt;
9753 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
9755 /* The variable buffer_shared is set in redisplay_window and
9756 indicates that we redisplay a buffer in different windows. See
9757 there. */
9758 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
9759 || cursor_type_changed);
9761 /* If specs for an arrow have changed, do thorough redisplay
9762 to ensure we remove any arrow that should no longer exist. */
9763 if (overlay_arrows_changed_p ())
9764 consider_all_windows_p = windows_or_buffers_changed = 1;
9766 /* Normally the message* functions will have already displayed and
9767 updated the echo area, but the frame may have been trashed, or
9768 the update may have been preempted, so display the echo area
9769 again here. Checking message_cleared_p captures the case that
9770 the echo area should be cleared. */
9771 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
9772 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
9773 || (message_cleared_p
9774 && minibuf_level == 0
9775 /* If the mini-window is currently selected, this means the
9776 echo-area doesn't show through. */
9777 && !MINI_WINDOW_P (XWINDOW (selected_window))))
9779 int window_height_changed_p = echo_area_display (0);
9780 must_finish = 1;
9782 /* If we don't display the current message, don't clear the
9783 message_cleared_p flag, because, if we did, we wouldn't clear
9784 the echo area in the next redisplay which doesn't preserve
9785 the echo area. */
9786 if (!display_last_displayed_message_p)
9787 message_cleared_p = 0;
9789 if (fonts_changed_p)
9790 goto retry;
9791 else if (window_height_changed_p)
9793 consider_all_windows_p = 1;
9794 ++update_mode_lines;
9795 ++windows_or_buffers_changed;
9797 /* If window configuration was changed, frames may have been
9798 marked garbaged. Clear them or we will experience
9799 surprises wrt scrolling. */
9800 if (frame_garbaged)
9801 clear_garbaged_frames ();
9804 else if (EQ (selected_window, minibuf_window)
9805 && (current_buffer->clip_changed
9806 || XFASTINT (w->last_modified) < MODIFF
9807 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9808 && resize_mini_window (w, 0))
9810 /* Resized active mini-window to fit the size of what it is
9811 showing if its contents might have changed. */
9812 must_finish = 1;
9813 consider_all_windows_p = 1;
9814 ++windows_or_buffers_changed;
9815 ++update_mode_lines;
9817 /* If window configuration was changed, frames may have been
9818 marked garbaged. Clear them or we will experience
9819 surprises wrt scrolling. */
9820 if (frame_garbaged)
9821 clear_garbaged_frames ();
9825 /* If showing the region, and mark has changed, we must redisplay
9826 the whole window. The assignment to this_line_start_pos prevents
9827 the optimization directly below this if-statement. */
9828 if (((!NILP (Vtransient_mark_mode)
9829 && !NILP (XBUFFER (w->buffer)->mark_active))
9830 != !NILP (w->region_showing))
9831 || (!NILP (w->region_showing)
9832 && !EQ (w->region_showing,
9833 Fmarker_position (XBUFFER (w->buffer)->mark))))
9834 CHARPOS (this_line_start_pos) = 0;
9836 /* Optimize the case that only the line containing the cursor in the
9837 selected window has changed. Variables starting with this_ are
9838 set in display_line and record information about the line
9839 containing the cursor. */
9840 tlbufpos = this_line_start_pos;
9841 tlendpos = this_line_end_pos;
9842 if (!consider_all_windows_p
9843 && CHARPOS (tlbufpos) > 0
9844 && NILP (w->update_mode_line)
9845 && !current_buffer->clip_changed
9846 && !current_buffer->prevent_redisplay_optimizations_p
9847 && FRAME_VISIBLE_P (XFRAME (w->frame))
9848 && !FRAME_OBSCURED_P (XFRAME (w->frame))
9849 /* Make sure recorded data applies to current buffer, etc. */
9850 && this_line_buffer == current_buffer
9851 && current_buffer == XBUFFER (w->buffer)
9852 && NILP (w->force_start)
9853 && NILP (w->optional_new_start)
9854 /* Point must be on the line that we have info recorded about. */
9855 && PT >= CHARPOS (tlbufpos)
9856 && PT <= Z - CHARPOS (tlendpos)
9857 /* All text outside that line, including its final newline,
9858 must be unchanged */
9859 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
9860 CHARPOS (tlendpos)))
9862 if (CHARPOS (tlbufpos) > BEGV
9863 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
9864 && (CHARPOS (tlbufpos) == ZV
9865 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
9866 /* Former continuation line has disappeared by becoming empty */
9867 goto cancel;
9868 else if (XFASTINT (w->last_modified) < MODIFF
9869 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
9870 || MINI_WINDOW_P (w))
9872 /* We have to handle the case of continuation around a
9873 wide-column character (See the comment in indent.c around
9874 line 885).
9876 For instance, in the following case:
9878 -------- Insert --------
9879 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
9880 J_I_ ==> J_I_ `^^' are cursors.
9881 ^^ ^^
9882 -------- --------
9884 As we have to redraw the line above, we should goto cancel. */
9886 struct it it;
9887 int line_height_before = this_line_pixel_height;
9889 /* Note that start_display will handle the case that the
9890 line starting at tlbufpos is a continuation lines. */
9891 start_display (&it, w, tlbufpos);
9893 /* Implementation note: It this still necessary? */
9894 if (it.current_x != this_line_start_x)
9895 goto cancel;
9897 TRACE ((stderr, "trying display optimization 1\n"));
9898 w->cursor.vpos = -1;
9899 overlay_arrow_seen = 0;
9900 it.vpos = this_line_vpos;
9901 it.current_y = this_line_y;
9902 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
9903 display_line (&it);
9905 /* If line contains point, is not continued,
9906 and ends at same distance from eob as before, we win */
9907 if (w->cursor.vpos >= 0
9908 /* Line is not continued, otherwise this_line_start_pos
9909 would have been set to 0 in display_line. */
9910 && CHARPOS (this_line_start_pos)
9911 /* Line ends as before. */
9912 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
9913 /* Line has same height as before. Otherwise other lines
9914 would have to be shifted up or down. */
9915 && this_line_pixel_height == line_height_before)
9917 /* If this is not the window's last line, we must adjust
9918 the charstarts of the lines below. */
9919 if (it.current_y < it.last_visible_y)
9921 struct glyph_row *row
9922 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
9923 int delta, delta_bytes;
9925 if (Z - CHARPOS (tlendpos) == ZV)
9927 /* This line ends at end of (accessible part of)
9928 buffer. There is no newline to count. */
9929 delta = (Z
9930 - CHARPOS (tlendpos)
9931 - MATRIX_ROW_START_CHARPOS (row));
9932 delta_bytes = (Z_BYTE
9933 - BYTEPOS (tlendpos)
9934 - MATRIX_ROW_START_BYTEPOS (row));
9936 else
9938 /* This line ends in a newline. Must take
9939 account of the newline and the rest of the
9940 text that follows. */
9941 delta = (Z
9942 - CHARPOS (tlendpos)
9943 - MATRIX_ROW_START_CHARPOS (row));
9944 delta_bytes = (Z_BYTE
9945 - BYTEPOS (tlendpos)
9946 - MATRIX_ROW_START_BYTEPOS (row));
9949 increment_matrix_positions (w->current_matrix,
9950 this_line_vpos + 1,
9951 w->current_matrix->nrows,
9952 delta, delta_bytes);
9955 /* If this row displays text now but previously didn't,
9956 or vice versa, w->window_end_vpos may have to be
9957 adjusted. */
9958 if ((it.glyph_row - 1)->displays_text_p)
9960 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
9961 XSETINT (w->window_end_vpos, this_line_vpos);
9963 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
9964 && this_line_vpos > 0)
9965 XSETINT (w->window_end_vpos, this_line_vpos - 1);
9966 w->window_end_valid = Qnil;
9968 /* Update hint: No need to try to scroll in update_window. */
9969 w->desired_matrix->no_scrolling_p = 1;
9971 #if GLYPH_DEBUG
9972 *w->desired_matrix->method = 0;
9973 debug_method_add (w, "optimization 1");
9974 #endif
9975 #ifdef HAVE_WINDOW_SYSTEM
9976 update_window_fringes (w, 0);
9977 #endif
9978 goto update;
9980 else
9981 goto cancel;
9983 else if (/* Cursor position hasn't changed. */
9984 PT == XFASTINT (w->last_point)
9985 /* Make sure the cursor was last displayed
9986 in this window. Otherwise we have to reposition it. */
9987 && 0 <= w->cursor.vpos
9988 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
9990 if (!must_finish)
9992 do_pending_window_change (1);
9994 /* We used to always goto end_of_redisplay here, but this
9995 isn't enough if we have a blinking cursor. */
9996 if (w->cursor_off_p == w->last_cursor_off_p)
9997 goto end_of_redisplay;
9999 goto update;
10001 /* If highlighting the region, or if the cursor is in the echo area,
10002 then we can't just move the cursor. */
10003 else if (! (!NILP (Vtransient_mark_mode)
10004 && !NILP (current_buffer->mark_active))
10005 && (EQ (selected_window, current_buffer->last_selected_window)
10006 || highlight_nonselected_windows)
10007 && NILP (w->region_showing)
10008 && NILP (Vshow_trailing_whitespace)
10009 && !cursor_in_echo_area)
10011 struct it it;
10012 struct glyph_row *row;
10014 /* Skip from tlbufpos to PT and see where it is. Note that
10015 PT may be in invisible text. If so, we will end at the
10016 next visible position. */
10017 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
10018 NULL, DEFAULT_FACE_ID);
10019 it.current_x = this_line_start_x;
10020 it.current_y = this_line_y;
10021 it.vpos = this_line_vpos;
10023 /* The call to move_it_to stops in front of PT, but
10024 moves over before-strings. */
10025 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
10027 if (it.vpos == this_line_vpos
10028 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
10029 row->enabled_p))
10031 xassert (this_line_vpos == it.vpos);
10032 xassert (this_line_y == it.current_y);
10033 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
10034 #if GLYPH_DEBUG
10035 *w->desired_matrix->method = 0;
10036 debug_method_add (w, "optimization 3");
10037 #endif
10038 goto update;
10040 else
10041 goto cancel;
10044 cancel:
10045 /* Text changed drastically or point moved off of line. */
10046 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
10049 CHARPOS (this_line_start_pos) = 0;
10050 consider_all_windows_p |= buffer_shared > 1;
10051 ++clear_face_cache_count;
10054 /* Build desired matrices, and update the display. If
10055 consider_all_windows_p is non-zero, do it for all windows on all
10056 frames. Otherwise do it for selected_window, only. */
10058 if (consider_all_windows_p)
10060 Lisp_Object tail, frame;
10061 int i, n = 0, size = 50;
10062 struct frame **updated
10063 = (struct frame **) alloca (size * sizeof *updated);
10065 /* Clear the face cache eventually. */
10066 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
10068 clear_face_cache (0);
10069 clear_face_cache_count = 0;
10072 /* Recompute # windows showing selected buffer. This will be
10073 incremented each time such a window is displayed. */
10074 buffer_shared = 0;
10076 FOR_EACH_FRAME (tail, frame)
10078 struct frame *f = XFRAME (frame);
10080 if (FRAME_WINDOW_P (f) || f == sf)
10082 if (! EQ (frame, selected_frame))
10083 /* Select the frame, for the sake of frame-local
10084 variables. */
10085 select_frame_for_redisplay (frame);
10087 #ifdef HAVE_WINDOW_SYSTEM
10088 if (clear_face_cache_count % 50 == 0
10089 && FRAME_WINDOW_P (f))
10090 clear_image_cache (f, 0);
10091 #endif /* HAVE_WINDOW_SYSTEM */
10093 /* Mark all the scroll bars to be removed; we'll redeem
10094 the ones we want when we redisplay their windows. */
10095 if (condemn_scroll_bars_hook)
10096 condemn_scroll_bars_hook (f);
10098 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10099 redisplay_windows (FRAME_ROOT_WINDOW (f));
10101 /* Any scroll bars which redisplay_windows should have
10102 nuked should now go away. */
10103 if (judge_scroll_bars_hook)
10104 judge_scroll_bars_hook (f);
10106 /* If fonts changed, display again. */
10107 /* ??? rms: I suspect it is a mistake to jump all the way
10108 back to retry here. It should just retry this frame. */
10109 if (fonts_changed_p)
10110 goto retry;
10112 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10114 /* See if we have to hscroll. */
10115 if (hscroll_windows (f->root_window))
10116 goto retry;
10118 /* Prevent various kinds of signals during display
10119 update. stdio is not robust about handling
10120 signals, which can cause an apparent I/O
10121 error. */
10122 if (interrupt_input)
10123 unrequest_sigio ();
10124 STOP_POLLING;
10126 /* Update the display. */
10127 set_window_update_flags (XWINDOW (f->root_window), 1);
10128 pause |= update_frame (f, 0, 0);
10129 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
10130 if (pause)
10131 break;
10132 #endif
10134 if (n == size)
10136 int nbytes = size * sizeof *updated;
10137 struct frame **p = (struct frame **) alloca (2 * nbytes);
10138 bcopy (updated, p, nbytes);
10139 size *= 2;
10142 updated[n++] = f;
10147 if (!pause)
10149 /* Do the mark_window_display_accurate after all windows have
10150 been redisplayed because this call resets flags in buffers
10151 which are needed for proper redisplay. */
10152 for (i = 0; i < n; ++i)
10154 struct frame *f = updated[i];
10155 mark_window_display_accurate (f->root_window, 1);
10156 if (frame_up_to_date_hook)
10157 frame_up_to_date_hook (f);
10161 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10163 Lisp_Object mini_window;
10164 struct frame *mini_frame;
10166 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
10167 /* Use list_of_error, not Qerror, so that
10168 we catch only errors and don't run the debugger. */
10169 internal_condition_case_1 (redisplay_window_1, selected_window,
10170 list_of_error,
10171 redisplay_window_error);
10173 /* Compare desired and current matrices, perform output. */
10175 update:
10176 /* If fonts changed, display again. */
10177 if (fonts_changed_p)
10178 goto retry;
10180 /* Prevent various kinds of signals during display update.
10181 stdio is not robust about handling signals,
10182 which can cause an apparent I/O error. */
10183 if (interrupt_input)
10184 unrequest_sigio ();
10185 STOP_POLLING;
10187 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10189 if (hscroll_windows (selected_window))
10190 goto retry;
10192 XWINDOW (selected_window)->must_be_updated_p = 1;
10193 pause = update_frame (sf, 0, 0);
10196 /* We may have called echo_area_display at the top of this
10197 function. If the echo area is on another frame, that may
10198 have put text on a frame other than the selected one, so the
10199 above call to update_frame would not have caught it. Catch
10200 it here. */
10201 mini_window = FRAME_MINIBUF_WINDOW (sf);
10202 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10204 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
10206 XWINDOW (mini_window)->must_be_updated_p = 1;
10207 pause |= update_frame (mini_frame, 0, 0);
10208 if (!pause && hscroll_windows (mini_window))
10209 goto retry;
10213 /* If display was paused because of pending input, make sure we do a
10214 thorough update the next time. */
10215 if (pause)
10217 /* Prevent the optimization at the beginning of
10218 redisplay_internal that tries a single-line update of the
10219 line containing the cursor in the selected window. */
10220 CHARPOS (this_line_start_pos) = 0;
10222 /* Let the overlay arrow be updated the next time. */
10223 update_overlay_arrows (0);
10225 /* If we pause after scrolling, some rows in the current
10226 matrices of some windows are not valid. */
10227 if (!WINDOW_FULL_WIDTH_P (w)
10228 && !FRAME_WINDOW_P (XFRAME (w->frame)))
10229 update_mode_lines = 1;
10231 else
10233 if (!consider_all_windows_p)
10235 /* This has already been done above if
10236 consider_all_windows_p is set. */
10237 mark_window_display_accurate_1 (w, 1);
10239 /* Say overlay arrows are up to date. */
10240 update_overlay_arrows (1);
10242 if (frame_up_to_date_hook != 0)
10243 frame_up_to_date_hook (sf);
10246 update_mode_lines = 0;
10247 windows_or_buffers_changed = 0;
10248 cursor_type_changed = 0;
10251 /* Start SIGIO interrupts coming again. Having them off during the
10252 code above makes it less likely one will discard output, but not
10253 impossible, since there might be stuff in the system buffer here.
10254 But it is much hairier to try to do anything about that. */
10255 if (interrupt_input)
10256 request_sigio ();
10257 RESUME_POLLING;
10259 /* If a frame has become visible which was not before, redisplay
10260 again, so that we display it. Expose events for such a frame
10261 (which it gets when becoming visible) don't call the parts of
10262 redisplay constructing glyphs, so simply exposing a frame won't
10263 display anything in this case. So, we have to display these
10264 frames here explicitly. */
10265 if (!pause)
10267 Lisp_Object tail, frame;
10268 int new_count = 0;
10270 FOR_EACH_FRAME (tail, frame)
10272 int this_is_visible = 0;
10274 if (XFRAME (frame)->visible)
10275 this_is_visible = 1;
10276 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
10277 if (XFRAME (frame)->visible)
10278 this_is_visible = 1;
10280 if (this_is_visible)
10281 new_count++;
10284 if (new_count != number_of_visible_frames)
10285 windows_or_buffers_changed++;
10288 /* Change frame size now if a change is pending. */
10289 do_pending_window_change (1);
10291 /* If we just did a pending size change, or have additional
10292 visible frames, redisplay again. */
10293 if (windows_or_buffers_changed && !pause)
10294 goto retry;
10296 end_of_redisplay:
10297 unbind_to (count, Qnil);
10298 RESUME_POLLING;
10302 /* Redisplay, but leave alone any recent echo area message unless
10303 another message has been requested in its place.
10305 This is useful in situations where you need to redisplay but no
10306 user action has occurred, making it inappropriate for the message
10307 area to be cleared. See tracking_off and
10308 wait_reading_process_input for examples of these situations.
10310 FROM_WHERE is an integer saying from where this function was
10311 called. This is useful for debugging. */
10313 void
10314 redisplay_preserve_echo_area (from_where)
10315 int from_where;
10317 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
10319 if (!NILP (echo_area_buffer[1]))
10321 /* We have a previously displayed message, but no current
10322 message. Redisplay the previous message. */
10323 display_last_displayed_message_p = 1;
10324 redisplay_internal (1);
10325 display_last_displayed_message_p = 0;
10327 else
10328 redisplay_internal (1);
10332 /* Function registered with record_unwind_protect in
10333 redisplay_internal. Reset redisplaying_p to the value it had
10334 before redisplay_internal was called, and clear
10335 prevent_freeing_realized_faces_p. It also selects the previously
10336 selected frame. */
10338 static Lisp_Object
10339 unwind_redisplay (val)
10340 Lisp_Object val;
10342 Lisp_Object old_redisplaying_p, old_frame;
10344 old_redisplaying_p = XCAR (val);
10345 redisplaying_p = XFASTINT (old_redisplaying_p);
10346 old_frame = XCDR (val);
10347 if (! EQ (old_frame, selected_frame))
10348 select_frame_for_redisplay (old_frame);
10349 return Qnil;
10353 /* Mark the display of window W as accurate or inaccurate. If
10354 ACCURATE_P is non-zero mark display of W as accurate. If
10355 ACCURATE_P is zero, arrange for W to be redisplayed the next time
10356 redisplay_internal is called. */
10358 static void
10359 mark_window_display_accurate_1 (w, accurate_p)
10360 struct window *w;
10361 int accurate_p;
10363 if (BUFFERP (w->buffer))
10365 struct buffer *b = XBUFFER (w->buffer);
10367 w->last_modified
10368 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
10369 w->last_overlay_modified
10370 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
10371 w->last_had_star
10372 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
10374 if (accurate_p)
10376 b->clip_changed = 0;
10377 b->prevent_redisplay_optimizations_p = 0;
10379 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
10380 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
10381 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
10382 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
10384 w->current_matrix->buffer = b;
10385 w->current_matrix->begv = BUF_BEGV (b);
10386 w->current_matrix->zv = BUF_ZV (b);
10388 w->last_cursor = w->cursor;
10389 w->last_cursor_off_p = w->cursor_off_p;
10391 if (w == XWINDOW (selected_window))
10392 w->last_point = make_number (BUF_PT (b));
10393 else
10394 w->last_point = make_number (XMARKER (w->pointm)->charpos);
10398 if (accurate_p)
10400 w->window_end_valid = w->buffer;
10401 #if 0 /* This is incorrect with variable-height lines. */
10402 xassert (XINT (w->window_end_vpos)
10403 < (WINDOW_TOTAL_LINES (w)
10404 - (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
10405 #endif
10406 w->update_mode_line = Qnil;
10411 /* Mark the display of windows in the window tree rooted at WINDOW as
10412 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
10413 windows as accurate. If ACCURATE_P is zero, arrange for windows to
10414 be redisplayed the next time redisplay_internal is called. */
10416 void
10417 mark_window_display_accurate (window, accurate_p)
10418 Lisp_Object window;
10419 int accurate_p;
10421 struct window *w;
10423 for (; !NILP (window); window = w->next)
10425 w = XWINDOW (window);
10426 mark_window_display_accurate_1 (w, accurate_p);
10428 if (!NILP (w->vchild))
10429 mark_window_display_accurate (w->vchild, accurate_p);
10430 if (!NILP (w->hchild))
10431 mark_window_display_accurate (w->hchild, accurate_p);
10434 if (accurate_p)
10436 update_overlay_arrows (1);
10438 else
10440 /* Force a thorough redisplay the next time by setting
10441 last_arrow_position and last_arrow_string to t, which is
10442 unequal to any useful value of Voverlay_arrow_... */
10443 update_overlay_arrows (-1);
10448 /* Return value in display table DP (Lisp_Char_Table *) for character
10449 C. Since a display table doesn't have any parent, we don't have to
10450 follow parent. Do not call this function directly but use the
10451 macro DISP_CHAR_VECTOR. */
10453 Lisp_Object
10454 disp_char_vector (dp, c)
10455 struct Lisp_Char_Table *dp;
10456 int c;
10458 int code[4], i;
10459 Lisp_Object val;
10461 if (SINGLE_BYTE_CHAR_P (c))
10462 return (dp->contents[c]);
10464 SPLIT_CHAR (c, code[0], code[1], code[2]);
10465 if (code[1] < 32)
10466 code[1] = -1;
10467 else if (code[2] < 32)
10468 code[2] = -1;
10470 /* Here, the possible range of code[0] (== charset ID) is
10471 128..max_charset. Since the top level char table contains data
10472 for multibyte characters after 256th element, we must increment
10473 code[0] by 128 to get a correct index. */
10474 code[0] += 128;
10475 code[3] = -1; /* anchor */
10477 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
10479 val = dp->contents[code[i]];
10480 if (!SUB_CHAR_TABLE_P (val))
10481 return (NILP (val) ? dp->defalt : val);
10484 /* Here, val is a sub char table. We return the default value of
10485 it. */
10486 return (dp->defalt);
10491 /***********************************************************************
10492 Window Redisplay
10493 ***********************************************************************/
10495 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
10497 static void
10498 redisplay_windows (window)
10499 Lisp_Object window;
10501 while (!NILP (window))
10503 struct window *w = XWINDOW (window);
10505 if (!NILP (w->hchild))
10506 redisplay_windows (w->hchild);
10507 else if (!NILP (w->vchild))
10508 redisplay_windows (w->vchild);
10509 else
10511 displayed_buffer = XBUFFER (w->buffer);
10512 /* Use list_of_error, not Qerror, so that
10513 we catch only errors and don't run the debugger. */
10514 internal_condition_case_1 (redisplay_window_0, window,
10515 list_of_error,
10516 redisplay_window_error);
10519 window = w->next;
10523 static Lisp_Object
10524 redisplay_window_error ()
10526 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
10527 return Qnil;
10530 static Lisp_Object
10531 redisplay_window_0 (window)
10532 Lisp_Object window;
10534 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10535 redisplay_window (window, 0);
10536 return Qnil;
10539 static Lisp_Object
10540 redisplay_window_1 (window)
10541 Lisp_Object window;
10543 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10544 redisplay_window (window, 1);
10545 return Qnil;
10549 /* Increment GLYPH until it reaches END or CONDITION fails while
10550 adding (GLYPH)->pixel_width to X. */
10552 #define SKIP_GLYPHS(glyph, end, x, condition) \
10553 do \
10555 (x) += (glyph)->pixel_width; \
10556 ++(glyph); \
10558 while ((glyph) < (end) && (condition))
10561 /* Set cursor position of W. PT is assumed to be displayed in ROW.
10562 DELTA is the number of bytes by which positions recorded in ROW
10563 differ from current buffer positions. */
10565 void
10566 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
10567 struct window *w;
10568 struct glyph_row *row;
10569 struct glyph_matrix *matrix;
10570 int delta, delta_bytes, dy, dvpos;
10572 struct glyph *glyph = row->glyphs[TEXT_AREA];
10573 struct glyph *end = glyph + row->used[TEXT_AREA];
10574 /* The first glyph that starts a sequence of glyphs from string. */
10575 struct glyph *string_start;
10576 /* The X coordinate of string_start. */
10577 int string_start_x;
10578 /* The last known character position. */
10579 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
10580 /* The last known character position before string_start. */
10581 int string_before_pos;
10582 int x = row->x;
10583 int pt_old = PT - delta;
10585 /* Skip over glyphs not having an object at the start of the row.
10586 These are special glyphs like truncation marks on terminal
10587 frames. */
10588 if (row->displays_text_p)
10589 while (glyph < end
10590 && INTEGERP (glyph->object)
10591 && glyph->charpos < 0)
10593 x += glyph->pixel_width;
10594 ++glyph;
10597 string_start = NULL;
10598 while (glyph < end
10599 && !INTEGERP (glyph->object)
10600 && (!BUFFERP (glyph->object)
10601 || (last_pos = glyph->charpos) < pt_old))
10603 if (! STRINGP (glyph->object))
10605 string_start = NULL;
10606 x += glyph->pixel_width;
10607 ++glyph;
10609 else
10611 string_before_pos = last_pos;
10612 string_start = glyph;
10613 string_start_x = x;
10614 /* Skip all glyphs from string. */
10615 SKIP_GLYPHS (glyph, end, x, STRINGP (glyph->object));
10619 if (string_start
10620 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
10622 /* We may have skipped over point because the previous glyphs
10623 are from string. As there's no easy way to know the
10624 character position of the current glyph, find the correct
10625 glyph on point by scanning from string_start again. */
10626 Lisp_Object limit;
10627 Lisp_Object string;
10628 int pos;
10630 limit = make_number (pt_old + 1);
10631 end = glyph;
10632 glyph = string_start;
10633 x = string_start_x;
10634 string = glyph->object;
10635 pos = string_buffer_position (w, string, string_before_pos);
10636 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
10637 because we always put cursor after overlay strings. */
10638 while (pos == 0 && glyph < end)
10640 string = glyph->object;
10641 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10642 if (glyph < end)
10643 pos = string_buffer_position (w, glyph->object, string_before_pos);
10646 while (glyph < end)
10648 pos = XINT (Fnext_single_char_property_change
10649 (make_number (pos), Qdisplay, Qnil, limit));
10650 if (pos > pt_old)
10651 break;
10652 /* Skip glyphs from the same string. */
10653 string = glyph->object;
10654 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10655 /* Skip glyphs from an overlay. */
10656 while (glyph < end
10657 && ! string_buffer_position (w, glyph->object, pos))
10659 string = glyph->object;
10660 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10665 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
10666 w->cursor.x = x;
10667 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
10668 w->cursor.y = row->y + dy;
10670 if (w == XWINDOW (selected_window))
10672 if (!row->continued_p
10673 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
10674 && row->x == 0)
10676 this_line_buffer = XBUFFER (w->buffer);
10678 CHARPOS (this_line_start_pos)
10679 = MATRIX_ROW_START_CHARPOS (row) + delta;
10680 BYTEPOS (this_line_start_pos)
10681 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
10683 CHARPOS (this_line_end_pos)
10684 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
10685 BYTEPOS (this_line_end_pos)
10686 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
10688 this_line_y = w->cursor.y;
10689 this_line_pixel_height = row->height;
10690 this_line_vpos = w->cursor.vpos;
10691 this_line_start_x = row->x;
10693 else
10694 CHARPOS (this_line_start_pos) = 0;
10699 /* Run window scroll functions, if any, for WINDOW with new window
10700 start STARTP. Sets the window start of WINDOW to that position.
10702 We assume that the window's buffer is really current. */
10704 static INLINE struct text_pos
10705 run_window_scroll_functions (window, startp)
10706 Lisp_Object window;
10707 struct text_pos startp;
10709 struct window *w = XWINDOW (window);
10710 SET_MARKER_FROM_TEXT_POS (w->start, startp);
10712 if (current_buffer != XBUFFER (w->buffer))
10713 abort ();
10715 if (!NILP (Vwindow_scroll_functions))
10717 run_hook_with_args_2 (Qwindow_scroll_functions, window,
10718 make_number (CHARPOS (startp)));
10719 SET_TEXT_POS_FROM_MARKER (startp, w->start);
10720 /* In case the hook functions switch buffers. */
10721 if (current_buffer != XBUFFER (w->buffer))
10722 set_buffer_internal_1 (XBUFFER (w->buffer));
10725 return startp;
10729 /* Make sure the line containing the cursor is fully visible.
10730 A value of 1 means there is nothing to be done.
10731 (Either the line is fully visible, or it cannot be made so,
10732 or we cannot tell.)
10733 A value of 0 means the caller should do scrolling
10734 as if point had gone off the screen. */
10736 static int
10737 make_cursor_line_fully_visible (w)
10738 struct window *w;
10740 struct glyph_matrix *matrix;
10741 struct glyph_row *row;
10742 int window_height;
10744 /* It's not always possible to find the cursor, e.g, when a window
10745 is full of overlay strings. Don't do anything in that case. */
10746 if (w->cursor.vpos < 0)
10747 return 1;
10749 matrix = w->desired_matrix;
10750 row = MATRIX_ROW (matrix, w->cursor.vpos);
10752 /* If the cursor row is not partially visible, there's nothing to do. */
10753 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
10754 return 1;
10756 /* If the row the cursor is in is taller than the window's height,
10757 it's not clear what to do, so do nothing. */
10758 window_height = window_box_height (w);
10759 if (row->height >= window_height)
10760 return 1;
10762 return 0;
10764 #if 0
10765 /* This code used to try to scroll the window just enough to make
10766 the line visible. It returned 0 to say that the caller should
10767 allocate larger glyph matrices. */
10769 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
10771 int dy = row->height - row->visible_height;
10772 w->vscroll = 0;
10773 w->cursor.y += dy;
10774 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
10776 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
10778 int dy = - (row->height - row->visible_height);
10779 w->vscroll = dy;
10780 w->cursor.y += dy;
10781 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
10784 /* When we change the cursor y-position of the selected window,
10785 change this_line_y as well so that the display optimization for
10786 the cursor line of the selected window in redisplay_internal uses
10787 the correct y-position. */
10788 if (w == XWINDOW (selected_window))
10789 this_line_y = w->cursor.y;
10791 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
10792 redisplay with larger matrices. */
10793 if (matrix->nrows < required_matrix_height (w))
10795 fonts_changed_p = 1;
10796 return 0;
10799 return 1;
10800 #endif /* 0 */
10804 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
10805 non-zero means only WINDOW is redisplayed in redisplay_internal.
10806 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
10807 in redisplay_window to bring a partially visible line into view in
10808 the case that only the cursor has moved.
10810 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
10811 last screen line's vertical height extends past the end of the screen.
10813 Value is
10815 1 if scrolling succeeded
10817 0 if scrolling didn't find point.
10819 -1 if new fonts have been loaded so that we must interrupt
10820 redisplay, adjust glyph matrices, and try again. */
10822 enum
10824 SCROLLING_SUCCESS,
10825 SCROLLING_FAILED,
10826 SCROLLING_NEED_LARGER_MATRICES
10829 static int
10830 try_scrolling (window, just_this_one_p, scroll_conservatively,
10831 scroll_step, temp_scroll_step, last_line_misfit)
10832 Lisp_Object window;
10833 int just_this_one_p;
10834 EMACS_INT scroll_conservatively, scroll_step;
10835 int temp_scroll_step;
10836 int last_line_misfit;
10838 struct window *w = XWINDOW (window);
10839 struct frame *f = XFRAME (w->frame);
10840 struct text_pos scroll_margin_pos;
10841 struct text_pos pos;
10842 struct text_pos startp;
10843 struct it it;
10844 Lisp_Object window_end;
10845 int this_scroll_margin;
10846 int dy = 0;
10847 int scroll_max;
10848 int rc;
10849 int amount_to_scroll = 0;
10850 Lisp_Object aggressive;
10851 int height;
10852 int end_scroll_margin;
10854 #if GLYPH_DEBUG
10855 debug_method_add (w, "try_scrolling");
10856 #endif
10858 SET_TEXT_POS_FROM_MARKER (startp, w->start);
10860 /* Compute scroll margin height in pixels. We scroll when point is
10861 within this distance from the top or bottom of the window. */
10862 if (scroll_margin > 0)
10864 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
10865 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
10867 else
10868 this_scroll_margin = 0;
10870 /* Compute how much we should try to scroll maximally to bring point
10871 into view. */
10872 if (scroll_step || scroll_conservatively || temp_scroll_step)
10873 scroll_max = max (scroll_step,
10874 max (scroll_conservatively, temp_scroll_step));
10875 else if (NUMBERP (current_buffer->scroll_down_aggressively)
10876 || NUMBERP (current_buffer->scroll_up_aggressively))
10877 /* We're trying to scroll because of aggressive scrolling
10878 but no scroll_step is set. Choose an arbitrary one. Maybe
10879 there should be a variable for this. */
10880 scroll_max = 10;
10881 else
10882 scroll_max = 0;
10883 scroll_max *= FRAME_LINE_HEIGHT (f);
10885 /* Decide whether we have to scroll down. Start at the window end
10886 and move this_scroll_margin up to find the position of the scroll
10887 margin. */
10888 window_end = Fwindow_end (window, Qt);
10890 too_near_end:
10892 CHARPOS (scroll_margin_pos) = XINT (window_end);
10893 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
10895 end_scroll_margin = this_scroll_margin + !!last_line_misfit;
10896 if (end_scroll_margin)
10898 start_display (&it, w, scroll_margin_pos);
10899 move_it_vertically (&it, - end_scroll_margin);
10900 scroll_margin_pos = it.current.pos;
10903 if (PT >= CHARPOS (scroll_margin_pos))
10905 int y0;
10907 /* Point is in the scroll margin at the bottom of the window, or
10908 below. Compute a new window start that makes point visible. */
10910 /* Compute the distance from the scroll margin to PT.
10911 Give up if the distance is greater than scroll_max. */
10912 start_display (&it, w, scroll_margin_pos);
10913 y0 = it.current_y;
10914 move_it_to (&it, PT, 0, it.last_visible_y, -1,
10915 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
10917 /* To make point visible, we have to move the window start
10918 down so that the line the cursor is in is visible, which
10919 means we have to add in the height of the cursor line. */
10920 dy = line_bottom_y (&it) - y0;
10922 if (dy > scroll_max)
10923 return SCROLLING_FAILED;
10925 /* Move the window start down. If scrolling conservatively,
10926 move it just enough down to make point visible. If
10927 scroll_step is set, move it down by scroll_step. */
10928 start_display (&it, w, startp);
10930 if (scroll_conservatively)
10931 /* Set AMOUNT_TO_SCROLL to at least one line,
10932 and at most scroll_conservatively lines. */
10933 amount_to_scroll
10934 = min (max (dy, FRAME_LINE_HEIGHT (f)),
10935 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
10936 else if (scroll_step || temp_scroll_step)
10937 amount_to_scroll = scroll_max;
10938 else
10940 aggressive = current_buffer->scroll_up_aggressively;
10941 height = WINDOW_BOX_TEXT_HEIGHT (w);
10942 if (NUMBERP (aggressive))
10943 amount_to_scroll = XFLOATINT (aggressive) * height;
10946 if (amount_to_scroll <= 0)
10947 return SCROLLING_FAILED;
10949 /* If moving by amount_to_scroll leaves STARTP unchanged,
10950 move it down one screen line. */
10952 move_it_vertically (&it, amount_to_scroll);
10953 if (CHARPOS (it.current.pos) == CHARPOS (startp))
10954 move_it_by_lines (&it, 1, 1);
10955 startp = it.current.pos;
10957 else
10959 /* See if point is inside the scroll margin at the top of the
10960 window. */
10961 scroll_margin_pos = startp;
10962 if (this_scroll_margin)
10964 start_display (&it, w, startp);
10965 move_it_vertically (&it, this_scroll_margin);
10966 scroll_margin_pos = it.current.pos;
10969 if (PT < CHARPOS (scroll_margin_pos))
10971 /* Point is in the scroll margin at the top of the window or
10972 above what is displayed in the window. */
10973 int y0;
10975 /* Compute the vertical distance from PT to the scroll
10976 margin position. Give up if distance is greater than
10977 scroll_max. */
10978 SET_TEXT_POS (pos, PT, PT_BYTE);
10979 start_display (&it, w, pos);
10980 y0 = it.current_y;
10981 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
10982 it.last_visible_y, -1,
10983 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
10984 dy = it.current_y - y0;
10985 if (dy > scroll_max)
10986 return SCROLLING_FAILED;
10988 /* Compute new window start. */
10989 start_display (&it, w, startp);
10991 if (scroll_conservatively)
10992 amount_to_scroll =
10993 max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
10994 else if (scroll_step || temp_scroll_step)
10995 amount_to_scroll = scroll_max;
10996 else
10998 aggressive = current_buffer->scroll_down_aggressively;
10999 height = WINDOW_BOX_TEXT_HEIGHT (w);
11000 if (NUMBERP (aggressive))
11001 amount_to_scroll = XFLOATINT (aggressive) * height;
11004 if (amount_to_scroll <= 0)
11005 return SCROLLING_FAILED;
11007 move_it_vertically (&it, - amount_to_scroll);
11008 startp = it.current.pos;
11012 /* Run window scroll functions. */
11013 startp = run_window_scroll_functions (window, startp);
11015 /* Display the window. Give up if new fonts are loaded, or if point
11016 doesn't appear. */
11017 if (!try_window (window, startp))
11018 rc = SCROLLING_NEED_LARGER_MATRICES;
11019 else if (w->cursor.vpos < 0)
11021 clear_glyph_matrix (w->desired_matrix);
11022 rc = SCROLLING_FAILED;
11024 else
11026 /* Maybe forget recorded base line for line number display. */
11027 if (!just_this_one_p
11028 || current_buffer->clip_changed
11029 || BEG_UNCHANGED < CHARPOS (startp))
11030 w->base_line_number = Qnil;
11032 /* If cursor ends up on a partially visible line,
11033 treat that as being off the bottom of the screen. */
11034 if (! make_cursor_line_fully_visible (w))
11036 clear_glyph_matrix (w->desired_matrix);
11037 last_line_misfit = 1;
11038 goto too_near_end;
11040 rc = SCROLLING_SUCCESS;
11043 return rc;
11047 /* Compute a suitable window start for window W if display of W starts
11048 on a continuation line. Value is non-zero if a new window start
11049 was computed.
11051 The new window start will be computed, based on W's width, starting
11052 from the start of the continued line. It is the start of the
11053 screen line with the minimum distance from the old start W->start. */
11055 static int
11056 compute_window_start_on_continuation_line (w)
11057 struct window *w;
11059 struct text_pos pos, start_pos;
11060 int window_start_changed_p = 0;
11062 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
11064 /* If window start is on a continuation line... Window start may be
11065 < BEGV in case there's invisible text at the start of the
11066 buffer (M-x rmail, for example). */
11067 if (CHARPOS (start_pos) > BEGV
11068 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
11070 struct it it;
11071 struct glyph_row *row;
11073 /* Handle the case that the window start is out of range. */
11074 if (CHARPOS (start_pos) < BEGV)
11075 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
11076 else if (CHARPOS (start_pos) > ZV)
11077 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
11079 /* Find the start of the continued line. This should be fast
11080 because scan_buffer is fast (newline cache). */
11081 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
11082 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
11083 row, DEFAULT_FACE_ID);
11084 reseat_at_previous_visible_line_start (&it);
11086 /* If the line start is "too far" away from the window start,
11087 say it takes too much time to compute a new window start. */
11088 if (CHARPOS (start_pos) - IT_CHARPOS (it)
11089 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
11091 int min_distance, distance;
11093 /* Move forward by display lines to find the new window
11094 start. If window width was enlarged, the new start can
11095 be expected to be > the old start. If window width was
11096 decreased, the new window start will be < the old start.
11097 So, we're looking for the display line start with the
11098 minimum distance from the old window start. */
11099 pos = it.current.pos;
11100 min_distance = INFINITY;
11101 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
11102 distance < min_distance)
11104 min_distance = distance;
11105 pos = it.current.pos;
11106 move_it_by_lines (&it, 1, 0);
11109 /* Set the window start there. */
11110 SET_MARKER_FROM_TEXT_POS (w->start, pos);
11111 window_start_changed_p = 1;
11115 return window_start_changed_p;
11119 /* Try cursor movement in case text has not changed in window WINDOW,
11120 with window start STARTP. Value is
11122 CURSOR_MOVEMENT_SUCCESS if successful
11124 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
11126 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
11127 display. *SCROLL_STEP is set to 1, under certain circumstances, if
11128 we want to scroll as if scroll-step were set to 1. See the code.
11130 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
11131 which case we have to abort this redisplay, and adjust matrices
11132 first. */
11134 enum
11136 CURSOR_MOVEMENT_SUCCESS,
11137 CURSOR_MOVEMENT_CANNOT_BE_USED,
11138 CURSOR_MOVEMENT_MUST_SCROLL,
11139 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
11142 static int
11143 try_cursor_movement (window, startp, scroll_step)
11144 Lisp_Object window;
11145 struct text_pos startp;
11146 int *scroll_step;
11148 struct window *w = XWINDOW (window);
11149 struct frame *f = XFRAME (w->frame);
11150 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
11152 #if GLYPH_DEBUG
11153 if (inhibit_try_cursor_movement)
11154 return rc;
11155 #endif
11157 /* Handle case where text has not changed, only point, and it has
11158 not moved off the frame. */
11159 if (/* Point may be in this window. */
11160 PT >= CHARPOS (startp)
11161 /* Selective display hasn't changed. */
11162 && !current_buffer->clip_changed
11163 /* Function force-mode-line-update is used to force a thorough
11164 redisplay. It sets either windows_or_buffers_changed or
11165 update_mode_lines. So don't take a shortcut here for these
11166 cases. */
11167 && !update_mode_lines
11168 && !windows_or_buffers_changed
11169 && !cursor_type_changed
11170 /* Can't use this case if highlighting a region. When a
11171 region exists, cursor movement has to do more than just
11172 set the cursor. */
11173 && !(!NILP (Vtransient_mark_mode)
11174 && !NILP (current_buffer->mark_active))
11175 && NILP (w->region_showing)
11176 && NILP (Vshow_trailing_whitespace)
11177 /* Right after splitting windows, last_point may be nil. */
11178 && INTEGERP (w->last_point)
11179 /* This code is not used for mini-buffer for the sake of the case
11180 of redisplaying to replace an echo area message; since in
11181 that case the mini-buffer contents per se are usually
11182 unchanged. This code is of no real use in the mini-buffer
11183 since the handling of this_line_start_pos, etc., in redisplay
11184 handles the same cases. */
11185 && !EQ (window, minibuf_window)
11186 /* When splitting windows or for new windows, it happens that
11187 redisplay is called with a nil window_end_vpos or one being
11188 larger than the window. This should really be fixed in
11189 window.c. I don't have this on my list, now, so we do
11190 approximately the same as the old redisplay code. --gerd. */
11191 && INTEGERP (w->window_end_vpos)
11192 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
11193 && (FRAME_WINDOW_P (f)
11194 || !overlay_arrow_in_current_buffer_p ()))
11196 int this_scroll_margin;
11197 struct glyph_row *row = NULL;
11199 #if GLYPH_DEBUG
11200 debug_method_add (w, "cursor movement");
11201 #endif
11203 /* Scroll if point within this distance from the top or bottom
11204 of the window. This is a pixel value. */
11205 this_scroll_margin = max (0, scroll_margin);
11206 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
11207 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
11209 /* Start with the row the cursor was displayed during the last
11210 not paused redisplay. Give up if that row is not valid. */
11211 if (w->last_cursor.vpos < 0
11212 || w->last_cursor.vpos >= w->current_matrix->nrows)
11213 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11214 else
11216 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
11217 if (row->mode_line_p)
11218 ++row;
11219 if (!row->enabled_p)
11220 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11223 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
11225 int scroll_p = 0;
11226 int last_y = window_text_bottom_y (w) - this_scroll_margin;
11228 if (PT > XFASTINT (w->last_point))
11230 /* Point has moved forward. */
11231 while (MATRIX_ROW_END_CHARPOS (row) < PT
11232 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
11234 xassert (row->enabled_p);
11235 ++row;
11238 /* The end position of a row equals the start position
11239 of the next row. If PT is there, we would rather
11240 display it in the next line. */
11241 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11242 && MATRIX_ROW_END_CHARPOS (row) == PT
11243 && !cursor_row_p (w, row))
11244 ++row;
11246 /* If within the scroll margin, scroll. Note that
11247 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
11248 the next line would be drawn, and that
11249 this_scroll_margin can be zero. */
11250 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
11251 || PT > MATRIX_ROW_END_CHARPOS (row)
11252 /* Line is completely visible last line in window
11253 and PT is to be set in the next line. */
11254 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
11255 && PT == MATRIX_ROW_END_CHARPOS (row)
11256 && !row->ends_at_zv_p
11257 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
11258 scroll_p = 1;
11260 else if (PT < XFASTINT (w->last_point))
11262 /* Cursor has to be moved backward. Note that PT >=
11263 CHARPOS (startp) because of the outer
11264 if-statement. */
11265 while (!row->mode_line_p
11266 && (MATRIX_ROW_START_CHARPOS (row) > PT
11267 || (MATRIX_ROW_START_CHARPOS (row) == PT
11268 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)))
11269 && (row->y > this_scroll_margin
11270 || CHARPOS (startp) == BEGV))
11272 xassert (row->enabled_p);
11273 --row;
11276 /* Consider the following case: Window starts at BEGV,
11277 there is invisible, intangible text at BEGV, so that
11278 display starts at some point START > BEGV. It can
11279 happen that we are called with PT somewhere between
11280 BEGV and START. Try to handle that case. */
11281 if (row < w->current_matrix->rows
11282 || row->mode_line_p)
11284 row = w->current_matrix->rows;
11285 if (row->mode_line_p)
11286 ++row;
11289 /* Due to newlines in overlay strings, we may have to
11290 skip forward over overlay strings. */
11291 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11292 && MATRIX_ROW_END_CHARPOS (row) == PT
11293 && !cursor_row_p (w, row))
11294 ++row;
11296 /* If within the scroll margin, scroll. */
11297 if (row->y < this_scroll_margin
11298 && CHARPOS (startp) != BEGV)
11299 scroll_p = 1;
11302 if (PT < MATRIX_ROW_START_CHARPOS (row)
11303 || PT > MATRIX_ROW_END_CHARPOS (row))
11305 /* if PT is not in the glyph row, give up. */
11306 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11308 else if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
11310 if (PT == MATRIX_ROW_END_CHARPOS (row)
11311 && !row->ends_at_zv_p
11312 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
11313 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11314 else if (row->height > window_box_height (w))
11316 /* If we end up in a partially visible line, let's
11317 make it fully visible, except when it's taller
11318 than the window, in which case we can't do much
11319 about it. */
11320 *scroll_step = 1;
11321 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11323 else
11325 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11326 if (!make_cursor_line_fully_visible (w))
11327 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11328 else
11329 rc = CURSOR_MOVEMENT_SUCCESS;
11332 else if (scroll_p)
11333 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11334 else
11336 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11337 rc = CURSOR_MOVEMENT_SUCCESS;
11342 return rc;
11345 void
11346 set_vertical_scroll_bar (w)
11347 struct window *w;
11349 int start, end, whole;
11351 /* Calculate the start and end positions for the current window.
11352 At some point, it would be nice to choose between scrollbars
11353 which reflect the whole buffer size, with special markers
11354 indicating narrowing, and scrollbars which reflect only the
11355 visible region.
11357 Note that mini-buffers sometimes aren't displaying any text. */
11358 if (!MINI_WINDOW_P (w)
11359 || (w == XWINDOW (minibuf_window)
11360 && NILP (echo_area_buffer[0])))
11362 struct buffer *buf = XBUFFER (w->buffer);
11363 whole = BUF_ZV (buf) - BUF_BEGV (buf);
11364 start = marker_position (w->start) - BUF_BEGV (buf);
11365 /* I don't think this is guaranteed to be right. For the
11366 moment, we'll pretend it is. */
11367 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
11369 if (end < start)
11370 end = start;
11371 if (whole < (end - start))
11372 whole = end - start;
11374 else
11375 start = end = whole = 0;
11377 /* Indicate what this scroll bar ought to be displaying now. */
11378 set_vertical_scroll_bar_hook (w, end - start, whole, start);
11382 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
11383 selected_window is redisplayed.
11385 We can return without actually redisplaying the window if
11386 fonts_changed_p is nonzero. In that case, redisplay_internal will
11387 retry. */
11389 static void
11390 redisplay_window (window, just_this_one_p)
11391 Lisp_Object window;
11392 int just_this_one_p;
11394 struct window *w = XWINDOW (window);
11395 struct frame *f = XFRAME (w->frame);
11396 struct buffer *buffer = XBUFFER (w->buffer);
11397 struct buffer *old = current_buffer;
11398 struct text_pos lpoint, opoint, startp;
11399 int update_mode_line;
11400 int tem;
11401 struct it it;
11402 /* Record it now because it's overwritten. */
11403 int current_matrix_up_to_date_p = 0;
11404 int used_current_matrix_p = 0;
11405 /* This is less strict than current_matrix_up_to_date_p.
11406 It indictes that the buffer contents and narrowing are unchanged. */
11407 int buffer_unchanged_p = 0;
11408 int temp_scroll_step = 0;
11409 int count = SPECPDL_INDEX ();
11410 int rc;
11411 int centering_position;
11412 int last_line_misfit = 0;
11414 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11415 opoint = lpoint;
11417 /* W must be a leaf window here. */
11418 xassert (!NILP (w->buffer));
11419 #if GLYPH_DEBUG
11420 *w->desired_matrix->method = 0;
11421 #endif
11423 specbind (Qinhibit_point_motion_hooks, Qt);
11425 reconsider_clip_changes (w, buffer);
11427 /* Has the mode line to be updated? */
11428 update_mode_line = (!NILP (w->update_mode_line)
11429 || update_mode_lines
11430 || buffer->clip_changed
11431 || buffer->prevent_redisplay_optimizations_p);
11433 if (MINI_WINDOW_P (w))
11435 if (w == XWINDOW (echo_area_window)
11436 && !NILP (echo_area_buffer[0]))
11438 if (update_mode_line)
11439 /* We may have to update a tty frame's menu bar or a
11440 tool-bar. Example `M-x C-h C-h C-g'. */
11441 goto finish_menu_bars;
11442 else
11443 /* We've already displayed the echo area glyphs in this window. */
11444 goto finish_scroll_bars;
11446 else if ((w != XWINDOW (minibuf_window)
11447 || minibuf_level == 0)
11448 /* When buffer is nonempty, redisplay window normally. */
11449 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
11450 /* Quail displays non-mini buffers in minibuffer window.
11451 In that case, redisplay the window normally. */
11452 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
11454 /* W is a mini-buffer window, but it's not active, so clear
11455 it. */
11456 int yb = window_text_bottom_y (w);
11457 struct glyph_row *row;
11458 int y;
11460 for (y = 0, row = w->desired_matrix->rows;
11461 y < yb;
11462 y += row->height, ++row)
11463 blank_row (w, row, y);
11464 goto finish_scroll_bars;
11467 clear_glyph_matrix (w->desired_matrix);
11470 /* Otherwise set up data on this window; select its buffer and point
11471 value. */
11472 /* Really select the buffer, for the sake of buffer-local
11473 variables. */
11474 set_buffer_internal_1 (XBUFFER (w->buffer));
11475 SET_TEXT_POS (opoint, PT, PT_BYTE);
11477 current_matrix_up_to_date_p
11478 = (!NILP (w->window_end_valid)
11479 && !current_buffer->clip_changed
11480 && !current_buffer->prevent_redisplay_optimizations_p
11481 && XFASTINT (w->last_modified) >= MODIFF
11482 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11484 buffer_unchanged_p
11485 = (!NILP (w->window_end_valid)
11486 && !current_buffer->clip_changed
11487 && XFASTINT (w->last_modified) >= MODIFF
11488 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11490 /* When windows_or_buffers_changed is non-zero, we can't rely on
11491 the window end being valid, so set it to nil there. */
11492 if (windows_or_buffers_changed)
11494 /* If window starts on a continuation line, maybe adjust the
11495 window start in case the window's width changed. */
11496 if (XMARKER (w->start)->buffer == current_buffer)
11497 compute_window_start_on_continuation_line (w);
11499 w->window_end_valid = Qnil;
11502 /* Some sanity checks. */
11503 CHECK_WINDOW_END (w);
11504 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
11505 abort ();
11506 if (BYTEPOS (opoint) < CHARPOS (opoint))
11507 abort ();
11509 /* If %c is in mode line, update it if needed. */
11510 if (!NILP (w->column_number_displayed)
11511 /* This alternative quickly identifies a common case
11512 where no change is needed. */
11513 && !(PT == XFASTINT (w->last_point)
11514 && XFASTINT (w->last_modified) >= MODIFF
11515 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
11516 && (XFASTINT (w->column_number_displayed)
11517 != (int) current_column ())) /* iftc */
11518 update_mode_line = 1;
11520 /* Count number of windows showing the selected buffer. An indirect
11521 buffer counts as its base buffer. */
11522 if (!just_this_one_p)
11524 struct buffer *current_base, *window_base;
11525 current_base = current_buffer;
11526 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
11527 if (current_base->base_buffer)
11528 current_base = current_base->base_buffer;
11529 if (window_base->base_buffer)
11530 window_base = window_base->base_buffer;
11531 if (current_base == window_base)
11532 buffer_shared++;
11535 /* Point refers normally to the selected window. For any other
11536 window, set up appropriate value. */
11537 if (!EQ (window, selected_window))
11539 int new_pt = XMARKER (w->pointm)->charpos;
11540 int new_pt_byte = marker_byte_position (w->pointm);
11541 if (new_pt < BEGV)
11543 new_pt = BEGV;
11544 new_pt_byte = BEGV_BYTE;
11545 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
11547 else if (new_pt > (ZV - 1))
11549 new_pt = ZV;
11550 new_pt_byte = ZV_BYTE;
11551 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
11554 /* We don't use SET_PT so that the point-motion hooks don't run. */
11555 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
11558 /* If any of the character widths specified in the display table
11559 have changed, invalidate the width run cache. It's true that
11560 this may be a bit late to catch such changes, but the rest of
11561 redisplay goes (non-fatally) haywire when the display table is
11562 changed, so why should we worry about doing any better? */
11563 if (current_buffer->width_run_cache)
11565 struct Lisp_Char_Table *disptab = buffer_display_table ();
11567 if (! disptab_matches_widthtab (disptab,
11568 XVECTOR (current_buffer->width_table)))
11570 invalidate_region_cache (current_buffer,
11571 current_buffer->width_run_cache,
11572 BEG, Z);
11573 recompute_width_table (current_buffer, disptab);
11577 /* If window-start is screwed up, choose a new one. */
11578 if (XMARKER (w->start)->buffer != current_buffer)
11579 goto recenter;
11581 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11583 /* If someone specified a new starting point but did not insist,
11584 check whether it can be used. */
11585 if (!NILP (w->optional_new_start)
11586 && CHARPOS (startp) >= BEGV
11587 && CHARPOS (startp) <= ZV)
11589 w->optional_new_start = Qnil;
11590 start_display (&it, w, startp);
11591 move_it_to (&it, PT, 0, it.last_visible_y, -1,
11592 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11593 if (IT_CHARPOS (it) == PT)
11594 w->force_start = Qt;
11595 /* IT may overshoot PT if text at PT is invisible. */
11596 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
11597 w->force_start = Qt;
11602 /* Handle case where place to start displaying has been specified,
11603 unless the specified location is outside the accessible range. */
11604 if (!NILP (w->force_start)
11605 || w->frozen_window_start_p)
11607 /* We set this later on if we have to adjust point. */
11608 int new_vpos = -1;
11610 w->force_start = Qnil;
11611 w->vscroll = 0;
11612 w->window_end_valid = Qnil;
11614 /* Forget any recorded base line for line number display. */
11615 if (!buffer_unchanged_p)
11616 w->base_line_number = Qnil;
11618 /* Redisplay the mode line. Select the buffer properly for that.
11619 Also, run the hook window-scroll-functions
11620 because we have scrolled. */
11621 /* Note, we do this after clearing force_start because
11622 if there's an error, it is better to forget about force_start
11623 than to get into an infinite loop calling the hook functions
11624 and having them get more errors. */
11625 if (!update_mode_line
11626 || ! NILP (Vwindow_scroll_functions))
11628 update_mode_line = 1;
11629 w->update_mode_line = Qt;
11630 startp = run_window_scroll_functions (window, startp);
11633 w->last_modified = make_number (0);
11634 w->last_overlay_modified = make_number (0);
11635 if (CHARPOS (startp) < BEGV)
11636 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
11637 else if (CHARPOS (startp) > ZV)
11638 SET_TEXT_POS (startp, ZV, ZV_BYTE);
11640 /* Redisplay, then check if cursor has been set during the
11641 redisplay. Give up if new fonts were loaded. */
11642 if (!try_window (window, startp))
11644 w->force_start = Qt;
11645 clear_glyph_matrix (w->desired_matrix);
11646 goto need_larger_matrices;
11649 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
11651 /* If point does not appear, try to move point so it does
11652 appear. The desired matrix has been built above, so we
11653 can use it here. */
11654 new_vpos = window_box_height (w) / 2;
11657 if (!make_cursor_line_fully_visible (w))
11659 /* Point does appear, but on a line partly visible at end of window.
11660 Move it back to a fully-visible line. */
11661 new_vpos = window_box_height (w);
11664 /* If we need to move point for either of the above reasons,
11665 now actually do it. */
11666 if (new_vpos >= 0)
11668 struct glyph_row *row;
11670 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
11671 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
11672 ++row;
11674 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
11675 MATRIX_ROW_START_BYTEPOS (row));
11677 if (w != XWINDOW (selected_window))
11678 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
11679 else if (current_buffer == old)
11680 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11682 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
11684 /* If we are highlighting the region, then we just changed
11685 the region, so redisplay to show it. */
11686 if (!NILP (Vtransient_mark_mode)
11687 && !NILP (current_buffer->mark_active))
11689 clear_glyph_matrix (w->desired_matrix);
11690 if (!try_window (window, startp))
11691 goto need_larger_matrices;
11695 #if GLYPH_DEBUG
11696 debug_method_add (w, "forced window start");
11697 #endif
11698 goto done;
11701 /* Handle case where text has not changed, only point, and it has
11702 not moved off the frame, and we are not retrying after hscroll.
11703 (current_matrix_up_to_date_p is nonzero when retrying.) */
11704 if (current_matrix_up_to_date_p
11705 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
11706 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
11708 switch (rc)
11710 case CURSOR_MOVEMENT_SUCCESS:
11711 used_current_matrix_p = 1;
11712 goto done;
11714 #if 0 /* try_cursor_movement never returns this value. */
11715 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES:
11716 goto need_larger_matrices;
11717 #endif
11719 case CURSOR_MOVEMENT_MUST_SCROLL:
11720 goto try_to_scroll;
11722 default:
11723 abort ();
11726 /* If current starting point was originally the beginning of a line
11727 but no longer is, find a new starting point. */
11728 else if (!NILP (w->start_at_line_beg)
11729 && !(CHARPOS (startp) <= BEGV
11730 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
11732 #if GLYPH_DEBUG
11733 debug_method_add (w, "recenter 1");
11734 #endif
11735 goto recenter;
11738 /* Try scrolling with try_window_id. Value is > 0 if update has
11739 been done, it is -1 if we know that the same window start will
11740 not work. It is 0 if unsuccessful for some other reason. */
11741 else if ((tem = try_window_id (w)) != 0)
11743 #if GLYPH_DEBUG
11744 debug_method_add (w, "try_window_id %d", tem);
11745 #endif
11747 if (fonts_changed_p)
11748 goto need_larger_matrices;
11749 if (tem > 0)
11750 goto done;
11752 /* Otherwise try_window_id has returned -1 which means that we
11753 don't want the alternative below this comment to execute. */
11755 else if (CHARPOS (startp) >= BEGV
11756 && CHARPOS (startp) <= ZV
11757 && PT >= CHARPOS (startp)
11758 && (CHARPOS (startp) < ZV
11759 /* Avoid starting at end of buffer. */
11760 || CHARPOS (startp) == BEGV
11761 || (XFASTINT (w->last_modified) >= MODIFF
11762 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
11764 #if GLYPH_DEBUG
11765 debug_method_add (w, "same window start");
11766 #endif
11768 /* Try to redisplay starting at same place as before.
11769 If point has not moved off frame, accept the results. */
11770 if (!current_matrix_up_to_date_p
11771 /* Don't use try_window_reusing_current_matrix in this case
11772 because a window scroll function can have changed the
11773 buffer. */
11774 || !NILP (Vwindow_scroll_functions)
11775 || MINI_WINDOW_P (w)
11776 || !(used_current_matrix_p =
11777 try_window_reusing_current_matrix (w)))
11779 IF_DEBUG (debug_method_add (w, "1"));
11780 try_window (window, startp);
11783 if (fonts_changed_p)
11784 goto need_larger_matrices;
11786 if (w->cursor.vpos >= 0)
11788 if (!just_this_one_p
11789 || current_buffer->clip_changed
11790 || BEG_UNCHANGED < CHARPOS (startp))
11791 /* Forget any recorded base line for line number display. */
11792 w->base_line_number = Qnil;
11794 if (!make_cursor_line_fully_visible (w))
11796 clear_glyph_matrix (w->desired_matrix);
11797 last_line_misfit = 1;
11799 /* Drop through and scroll. */
11800 else
11801 goto done;
11803 else
11804 clear_glyph_matrix (w->desired_matrix);
11807 try_to_scroll:
11809 w->last_modified = make_number (0);
11810 w->last_overlay_modified = make_number (0);
11812 /* Redisplay the mode line. Select the buffer properly for that. */
11813 if (!update_mode_line)
11815 update_mode_line = 1;
11816 w->update_mode_line = Qt;
11819 /* Try to scroll by specified few lines. */
11820 if ((scroll_conservatively
11821 || scroll_step
11822 || temp_scroll_step
11823 || NUMBERP (current_buffer->scroll_up_aggressively)
11824 || NUMBERP (current_buffer->scroll_down_aggressively))
11825 && !current_buffer->clip_changed
11826 && CHARPOS (startp) >= BEGV
11827 && CHARPOS (startp) <= ZV)
11829 /* The function returns -1 if new fonts were loaded, 1 if
11830 successful, 0 if not successful. */
11831 int rc = try_scrolling (window, just_this_one_p,
11832 scroll_conservatively,
11833 scroll_step,
11834 temp_scroll_step, last_line_misfit);
11835 switch (rc)
11837 case SCROLLING_SUCCESS:
11838 goto done;
11840 case SCROLLING_NEED_LARGER_MATRICES:
11841 goto need_larger_matrices;
11843 case SCROLLING_FAILED:
11844 break;
11846 default:
11847 abort ();
11851 /* Finally, just choose place to start which centers point */
11853 recenter:
11854 centering_position = window_box_height (w) / 2;
11856 point_at_top:
11857 /* Jump here with centering_position already set to 0. */
11859 #if GLYPH_DEBUG
11860 debug_method_add (w, "recenter");
11861 #endif
11863 /* w->vscroll = 0; */
11865 /* Forget any previously recorded base line for line number display. */
11866 if (!buffer_unchanged_p)
11867 w->base_line_number = Qnil;
11869 /* Move backward half the height of the window. */
11870 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
11871 it.current_y = it.last_visible_y;
11872 move_it_vertically_backward (&it, centering_position);
11873 xassert (IT_CHARPOS (it) >= BEGV);
11875 /* The function move_it_vertically_backward may move over more
11876 than the specified y-distance. If it->w is small, e.g. a
11877 mini-buffer window, we may end up in front of the window's
11878 display area. Start displaying at the start of the line
11879 containing PT in this case. */
11880 if (it.current_y <= 0)
11882 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
11883 move_it_vertically (&it, 0);
11884 xassert (IT_CHARPOS (it) <= PT);
11885 it.current_y = 0;
11888 it.current_x = it.hpos = 0;
11890 /* Set startp here explicitly in case that helps avoid an infinite loop
11891 in case the window-scroll-functions functions get errors. */
11892 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
11894 /* Run scroll hooks. */
11895 startp = run_window_scroll_functions (window, it.current.pos);
11897 /* Redisplay the window. */
11898 if (!current_matrix_up_to_date_p
11899 || windows_or_buffers_changed
11900 || cursor_type_changed
11901 /* Don't use try_window_reusing_current_matrix in this case
11902 because it can have changed the buffer. */
11903 || !NILP (Vwindow_scroll_functions)
11904 || !just_this_one_p
11905 || MINI_WINDOW_P (w)
11906 || !(used_current_matrix_p =
11907 try_window_reusing_current_matrix (w)))
11908 try_window (window, startp);
11910 /* If new fonts have been loaded (due to fontsets), give up. We
11911 have to start a new redisplay since we need to re-adjust glyph
11912 matrices. */
11913 if (fonts_changed_p)
11914 goto need_larger_matrices;
11916 /* If cursor did not appear assume that the middle of the window is
11917 in the first line of the window. Do it again with the next line.
11918 (Imagine a window of height 100, displaying two lines of height
11919 60. Moving back 50 from it->last_visible_y will end in the first
11920 line.) */
11921 if (w->cursor.vpos < 0)
11923 if (!NILP (w->window_end_valid)
11924 && PT >= Z - XFASTINT (w->window_end_pos))
11926 clear_glyph_matrix (w->desired_matrix);
11927 move_it_by_lines (&it, 1, 0);
11928 try_window (window, it.current.pos);
11930 else if (PT < IT_CHARPOS (it))
11932 clear_glyph_matrix (w->desired_matrix);
11933 move_it_by_lines (&it, -1, 0);
11934 try_window (window, it.current.pos);
11936 else
11938 /* Not much we can do about it. */
11942 /* Consider the following case: Window starts at BEGV, there is
11943 invisible, intangible text at BEGV, so that display starts at
11944 some point START > BEGV. It can happen that we are called with
11945 PT somewhere between BEGV and START. Try to handle that case. */
11946 if (w->cursor.vpos < 0)
11948 struct glyph_row *row = w->current_matrix->rows;
11949 if (row->mode_line_p)
11950 ++row;
11951 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11954 if (!make_cursor_line_fully_visible (w))
11956 /* If vscroll is enabled, disable it and try again. */
11957 if (w->vscroll)
11959 w->vscroll = 0;
11960 clear_glyph_matrix (w->desired_matrix);
11961 goto recenter;
11964 /* If centering point failed to make the whole line visible,
11965 put point at the top instead. That has to make the whole line
11966 visible, if it can be done. */
11967 centering_position = 0;
11968 goto point_at_top;
11971 done:
11973 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11974 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
11975 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
11976 ? Qt : Qnil);
11978 /* Display the mode line, if we must. */
11979 if ((update_mode_line
11980 /* If window not full width, must redo its mode line
11981 if (a) the window to its side is being redone and
11982 (b) we do a frame-based redisplay. This is a consequence
11983 of how inverted lines are drawn in frame-based redisplay. */
11984 || (!just_this_one_p
11985 && !FRAME_WINDOW_P (f)
11986 && !WINDOW_FULL_WIDTH_P (w))
11987 /* Line number to display. */
11988 || INTEGERP (w->base_line_pos)
11989 /* Column number is displayed and different from the one displayed. */
11990 || (!NILP (w->column_number_displayed)
11991 && (XFASTINT (w->column_number_displayed)
11992 != (int) current_column ()))) /* iftc */
11993 /* This means that the window has a mode line. */
11994 && (WINDOW_WANTS_MODELINE_P (w)
11995 || WINDOW_WANTS_HEADER_LINE_P (w)))
11997 display_mode_lines (w);
11999 /* If mode line height has changed, arrange for a thorough
12000 immediate redisplay using the correct mode line height. */
12001 if (WINDOW_WANTS_MODELINE_P (w)
12002 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
12004 fonts_changed_p = 1;
12005 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
12006 = DESIRED_MODE_LINE_HEIGHT (w);
12009 /* If top line height has changed, arrange for a thorough
12010 immediate redisplay using the correct mode line height. */
12011 if (WINDOW_WANTS_HEADER_LINE_P (w)
12012 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
12014 fonts_changed_p = 1;
12015 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
12016 = DESIRED_HEADER_LINE_HEIGHT (w);
12019 if (fonts_changed_p)
12020 goto need_larger_matrices;
12023 if (!line_number_displayed
12024 && !BUFFERP (w->base_line_pos))
12026 w->base_line_pos = Qnil;
12027 w->base_line_number = Qnil;
12030 finish_menu_bars:
12032 /* When we reach a frame's selected window, redo the frame's menu bar. */
12033 if (update_mode_line
12034 && EQ (FRAME_SELECTED_WINDOW (f), window))
12036 int redisplay_menu_p = 0;
12037 int redisplay_tool_bar_p = 0;
12039 if (FRAME_WINDOW_P (f))
12041 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
12042 || defined (USE_GTK)
12043 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
12044 #else
12045 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12046 #endif
12048 else
12049 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12051 if (redisplay_menu_p)
12052 display_menu_bar (w);
12054 #ifdef HAVE_WINDOW_SYSTEM
12055 #ifdef USE_GTK
12056 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
12057 #else
12058 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
12059 && (FRAME_TOOL_BAR_LINES (f) > 0
12060 || auto_resize_tool_bars_p);
12062 #endif
12064 if (redisplay_tool_bar_p)
12065 redisplay_tool_bar (f);
12066 #endif
12069 #ifdef HAVE_WINDOW_SYSTEM
12070 if (update_window_fringes (w, 0)
12071 && !just_this_one_p
12072 && (used_current_matrix_p || overlay_arrow_seen)
12073 && !w->pseudo_window_p)
12075 update_begin (f);
12076 BLOCK_INPUT;
12077 draw_window_fringes (w);
12078 UNBLOCK_INPUT;
12079 update_end (f);
12081 #endif /* HAVE_WINDOW_SYSTEM */
12083 /* We go to this label, with fonts_changed_p nonzero,
12084 if it is necessary to try again using larger glyph matrices.
12085 We have to redeem the scroll bar even in this case,
12086 because the loop in redisplay_internal expects that. */
12087 need_larger_matrices:
12089 finish_scroll_bars:
12091 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
12093 /* Set the thumb's position and size. */
12094 set_vertical_scroll_bar (w);
12096 /* Note that we actually used the scroll bar attached to this
12097 window, so it shouldn't be deleted at the end of redisplay. */
12098 redeem_scroll_bar_hook (w);
12101 /* Restore current_buffer and value of point in it. */
12102 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
12103 set_buffer_internal_1 (old);
12104 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
12106 unbind_to (count, Qnil);
12110 /* Build the complete desired matrix of WINDOW with a window start
12111 buffer position POS. Value is non-zero if successful. It is zero
12112 if fonts were loaded during redisplay which makes re-adjusting
12113 glyph matrices necessary. */
12116 try_window (window, pos)
12117 Lisp_Object window;
12118 struct text_pos pos;
12120 struct window *w = XWINDOW (window);
12121 struct it it;
12122 struct glyph_row *last_text_row = NULL;
12124 /* Make POS the new window start. */
12125 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
12127 /* Mark cursor position as unknown. No overlay arrow seen. */
12128 w->cursor.vpos = -1;
12129 overlay_arrow_seen = 0;
12131 /* Initialize iterator and info to start at POS. */
12132 start_display (&it, w, pos);
12134 /* Display all lines of W. */
12135 while (it.current_y < it.last_visible_y)
12137 if (display_line (&it))
12138 last_text_row = it.glyph_row - 1;
12139 if (fonts_changed_p)
12140 return 0;
12143 /* If bottom moved off end of frame, change mode line percentage. */
12144 if (XFASTINT (w->window_end_pos) <= 0
12145 && Z != IT_CHARPOS (it))
12146 w->update_mode_line = Qt;
12148 /* Set window_end_pos to the offset of the last character displayed
12149 on the window from the end of current_buffer. Set
12150 window_end_vpos to its row number. */
12151 if (last_text_row)
12153 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
12154 w->window_end_bytepos
12155 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12156 w->window_end_pos
12157 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12158 w->window_end_vpos
12159 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12160 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
12161 ->displays_text_p);
12163 else
12165 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12166 w->window_end_pos = make_number (Z - ZV);
12167 w->window_end_vpos = make_number (0);
12170 /* But that is not valid info until redisplay finishes. */
12171 w->window_end_valid = Qnil;
12172 return 1;
12177 /************************************************************************
12178 Window redisplay reusing current matrix when buffer has not changed
12179 ************************************************************************/
12181 /* Try redisplay of window W showing an unchanged buffer with a
12182 different window start than the last time it was displayed by
12183 reusing its current matrix. Value is non-zero if successful.
12184 W->start is the new window start. */
12186 static int
12187 try_window_reusing_current_matrix (w)
12188 struct window *w;
12190 struct frame *f = XFRAME (w->frame);
12191 struct glyph_row *row, *bottom_row;
12192 struct it it;
12193 struct run run;
12194 struct text_pos start, new_start;
12195 int nrows_scrolled, i;
12196 struct glyph_row *last_text_row;
12197 struct glyph_row *last_reused_text_row;
12198 struct glyph_row *start_row;
12199 int start_vpos, min_y, max_y;
12201 #if GLYPH_DEBUG
12202 if (inhibit_try_window_reusing)
12203 return 0;
12204 #endif
12206 if (/* This function doesn't handle terminal frames. */
12207 !FRAME_WINDOW_P (f)
12208 /* Don't try to reuse the display if windows have been split
12209 or such. */
12210 || windows_or_buffers_changed
12211 || cursor_type_changed)
12212 return 0;
12214 /* Can't do this if region may have changed. */
12215 if ((!NILP (Vtransient_mark_mode)
12216 && !NILP (current_buffer->mark_active))
12217 || !NILP (w->region_showing)
12218 || !NILP (Vshow_trailing_whitespace))
12219 return 0;
12221 /* If top-line visibility has changed, give up. */
12222 if (WINDOW_WANTS_HEADER_LINE_P (w)
12223 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
12224 return 0;
12226 /* Give up if old or new display is scrolled vertically. We could
12227 make this function handle this, but right now it doesn't. */
12228 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12229 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row))
12230 return 0;
12232 /* The variable new_start now holds the new window start. The old
12233 start `start' can be determined from the current matrix. */
12234 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
12235 start = start_row->start.pos;
12236 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
12238 /* Clear the desired matrix for the display below. */
12239 clear_glyph_matrix (w->desired_matrix);
12241 if (CHARPOS (new_start) <= CHARPOS (start))
12243 int first_row_y;
12245 /* Don't use this method if the display starts with an ellipsis
12246 displayed for invisible text. It's not easy to handle that case
12247 below, and it's certainly not worth the effort since this is
12248 not a frequent case. */
12249 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
12250 return 0;
12252 IF_DEBUG (debug_method_add (w, "twu1"));
12254 /* Display up to a row that can be reused. The variable
12255 last_text_row is set to the last row displayed that displays
12256 text. Note that it.vpos == 0 if or if not there is a
12257 header-line; it's not the same as the MATRIX_ROW_VPOS! */
12258 start_display (&it, w, new_start);
12259 first_row_y = it.current_y;
12260 w->cursor.vpos = -1;
12261 last_text_row = last_reused_text_row = NULL;
12263 while (it.current_y < it.last_visible_y
12264 && IT_CHARPOS (it) < CHARPOS (start)
12265 && !fonts_changed_p)
12266 if (display_line (&it))
12267 last_text_row = it.glyph_row - 1;
12269 /* A value of current_y < last_visible_y means that we stopped
12270 at the previous window start, which in turn means that we
12271 have at least one reusable row. */
12272 if (it.current_y < it.last_visible_y)
12274 /* IT.vpos always starts from 0; it counts text lines. */
12275 nrows_scrolled = it.vpos;
12277 /* Find PT if not already found in the lines displayed. */
12278 if (w->cursor.vpos < 0)
12280 int dy = it.current_y - first_row_y;
12282 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12283 row = row_containing_pos (w, PT, row, NULL, dy);
12284 if (row)
12285 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
12286 dy, nrows_scrolled);
12287 else
12289 clear_glyph_matrix (w->desired_matrix);
12290 return 0;
12294 /* Scroll the display. Do it before the current matrix is
12295 changed. The problem here is that update has not yet
12296 run, i.e. part of the current matrix is not up to date.
12297 scroll_run_hook will clear the cursor, and use the
12298 current matrix to get the height of the row the cursor is
12299 in. */
12300 run.current_y = first_row_y;
12301 run.desired_y = it.current_y;
12302 run.height = it.last_visible_y - it.current_y;
12304 if (run.height > 0 && run.current_y != run.desired_y)
12306 update_begin (f);
12307 rif->update_window_begin_hook (w);
12308 rif->clear_window_mouse_face (w);
12309 rif->scroll_run_hook (w, &run);
12310 rif->update_window_end_hook (w, 0, 0);
12311 update_end (f);
12314 /* Shift current matrix down by nrows_scrolled lines. */
12315 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12316 rotate_matrix (w->current_matrix,
12317 start_vpos,
12318 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12319 nrows_scrolled);
12321 /* Disable lines that must be updated. */
12322 for (i = 0; i < it.vpos; ++i)
12323 (start_row + i)->enabled_p = 0;
12325 /* Re-compute Y positions. */
12326 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12327 max_y = it.last_visible_y;
12328 for (row = start_row + nrows_scrolled;
12329 row < bottom_row;
12330 ++row)
12332 row->y = it.current_y;
12333 row->visible_height = row->height;
12335 if (row->y < min_y)
12336 row->visible_height -= min_y - row->y;
12337 if (row->y + row->height > max_y)
12338 row->visible_height -= row->y + row->height - max_y;
12339 row->redraw_fringe_bitmaps_p = 1;
12341 it.current_y += row->height;
12343 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12344 last_reused_text_row = row;
12345 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
12346 break;
12349 /* Disable lines in the current matrix which are now
12350 below the window. */
12351 for (++row; row < bottom_row; ++row)
12352 row->enabled_p = 0;
12355 /* Update window_end_pos etc.; last_reused_text_row is the last
12356 reused row from the current matrix containing text, if any.
12357 The value of last_text_row is the last displayed line
12358 containing text. */
12359 if (last_reused_text_row)
12361 w->window_end_bytepos
12362 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
12363 w->window_end_pos
12364 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
12365 w->window_end_vpos
12366 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
12367 w->current_matrix));
12369 else if (last_text_row)
12371 w->window_end_bytepos
12372 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12373 w->window_end_pos
12374 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12375 w->window_end_vpos
12376 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12378 else
12380 /* This window must be completely empty. */
12381 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12382 w->window_end_pos = make_number (Z - ZV);
12383 w->window_end_vpos = make_number (0);
12385 w->window_end_valid = Qnil;
12387 /* Update hint: don't try scrolling again in update_window. */
12388 w->desired_matrix->no_scrolling_p = 1;
12390 #if GLYPH_DEBUG
12391 debug_method_add (w, "try_window_reusing_current_matrix 1");
12392 #endif
12393 return 1;
12395 else if (CHARPOS (new_start) > CHARPOS (start))
12397 struct glyph_row *pt_row, *row;
12398 struct glyph_row *first_reusable_row;
12399 struct glyph_row *first_row_to_display;
12400 int dy;
12401 int yb = window_text_bottom_y (w);
12403 /* Find the row starting at new_start, if there is one. Don't
12404 reuse a partially visible line at the end. */
12405 first_reusable_row = start_row;
12406 while (first_reusable_row->enabled_p
12407 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
12408 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12409 < CHARPOS (new_start)))
12410 ++first_reusable_row;
12412 /* Give up if there is no row to reuse. */
12413 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
12414 || !first_reusable_row->enabled_p
12415 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12416 != CHARPOS (new_start)))
12417 return 0;
12419 /* We can reuse fully visible rows beginning with
12420 first_reusable_row to the end of the window. Set
12421 first_row_to_display to the first row that cannot be reused.
12422 Set pt_row to the row containing point, if there is any. */
12423 pt_row = NULL;
12424 for (first_row_to_display = first_reusable_row;
12425 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
12426 ++first_row_to_display)
12428 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
12429 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
12430 pt_row = first_row_to_display;
12433 /* Start displaying at the start of first_row_to_display. */
12434 xassert (first_row_to_display->y < yb);
12435 init_to_row_start (&it, w, first_row_to_display);
12437 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
12438 - start_vpos);
12439 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
12440 - nrows_scrolled);
12441 it.current_y = (first_row_to_display->y - first_reusable_row->y
12442 + WINDOW_HEADER_LINE_HEIGHT (w));
12444 /* Display lines beginning with first_row_to_display in the
12445 desired matrix. Set last_text_row to the last row displayed
12446 that displays text. */
12447 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
12448 if (pt_row == NULL)
12449 w->cursor.vpos = -1;
12450 last_text_row = NULL;
12451 while (it.current_y < it.last_visible_y && !fonts_changed_p)
12452 if (display_line (&it))
12453 last_text_row = it.glyph_row - 1;
12455 /* Give up If point isn't in a row displayed or reused. */
12456 if (w->cursor.vpos < 0)
12458 clear_glyph_matrix (w->desired_matrix);
12459 return 0;
12462 /* If point is in a reused row, adjust y and vpos of the cursor
12463 position. */
12464 if (pt_row)
12466 w->cursor.vpos -= MATRIX_ROW_VPOS (first_reusable_row,
12467 w->current_matrix);
12468 w->cursor.y -= first_reusable_row->y;
12471 /* Scroll the display. */
12472 run.current_y = first_reusable_row->y;
12473 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
12474 run.height = it.last_visible_y - run.current_y;
12475 dy = run.current_y - run.desired_y;
12477 if (run.height)
12479 update_begin (f);
12480 rif->update_window_begin_hook (w);
12481 rif->clear_window_mouse_face (w);
12482 rif->scroll_run_hook (w, &run);
12483 rif->update_window_end_hook (w, 0, 0);
12484 update_end (f);
12487 /* Adjust Y positions of reused rows. */
12488 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12489 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12490 max_y = it.last_visible_y;
12491 for (row = first_reusable_row; row < first_row_to_display; ++row)
12493 row->y -= dy;
12494 row->visible_height = row->height;
12495 if (row->y < min_y)
12496 row->visible_height -= min_y - row->y;
12497 if (row->y + row->height > max_y)
12498 row->visible_height -= row->y + row->height - max_y;
12499 row->redraw_fringe_bitmaps_p = 1;
12502 /* Scroll the current matrix. */
12503 xassert (nrows_scrolled > 0);
12504 rotate_matrix (w->current_matrix,
12505 start_vpos,
12506 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12507 -nrows_scrolled);
12509 /* Disable rows not reused. */
12510 for (row -= nrows_scrolled; row < bottom_row; ++row)
12511 row->enabled_p = 0;
12513 /* Adjust window end. A null value of last_text_row means that
12514 the window end is in reused rows which in turn means that
12515 only its vpos can have changed. */
12516 if (last_text_row)
12518 w->window_end_bytepos
12519 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12520 w->window_end_pos
12521 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12522 w->window_end_vpos
12523 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12525 else
12527 w->window_end_vpos
12528 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
12531 w->window_end_valid = Qnil;
12532 w->desired_matrix->no_scrolling_p = 1;
12534 #if GLYPH_DEBUG
12535 debug_method_add (w, "try_window_reusing_current_matrix 2");
12536 #endif
12537 return 1;
12540 return 0;
12545 /************************************************************************
12546 Window redisplay reusing current matrix when buffer has changed
12547 ************************************************************************/
12549 static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *));
12550 static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *,
12551 int *, int *));
12552 static struct glyph_row *
12553 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
12554 struct glyph_row *));
12557 /* Return the last row in MATRIX displaying text. If row START is
12558 non-null, start searching with that row. IT gives the dimensions
12559 of the display. Value is null if matrix is empty; otherwise it is
12560 a pointer to the row found. */
12562 static struct glyph_row *
12563 find_last_row_displaying_text (matrix, it, start)
12564 struct glyph_matrix *matrix;
12565 struct it *it;
12566 struct glyph_row *start;
12568 struct glyph_row *row, *row_found;
12570 /* Set row_found to the last row in IT->w's current matrix
12571 displaying text. The loop looks funny but think of partially
12572 visible lines. */
12573 row_found = NULL;
12574 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
12575 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12577 xassert (row->enabled_p);
12578 row_found = row;
12579 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
12580 break;
12581 ++row;
12584 return row_found;
12588 /* Return the last row in the current matrix of W that is not affected
12589 by changes at the start of current_buffer that occurred since W's
12590 current matrix was built. Value is null if no such row exists.
12592 BEG_UNCHANGED us the number of characters unchanged at the start of
12593 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
12594 first changed character in current_buffer. Characters at positions <
12595 BEG + BEG_UNCHANGED are at the same buffer positions as they were
12596 when the current matrix was built. */
12598 static struct glyph_row *
12599 find_last_unchanged_at_beg_row (w)
12600 struct window *w;
12602 int first_changed_pos = BEG + BEG_UNCHANGED;
12603 struct glyph_row *row;
12604 struct glyph_row *row_found = NULL;
12605 int yb = window_text_bottom_y (w);
12607 /* Find the last row displaying unchanged text. */
12608 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12609 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12610 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
12612 if (/* If row ends before first_changed_pos, it is unchanged,
12613 except in some case. */
12614 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
12615 /* When row ends in ZV and we write at ZV it is not
12616 unchanged. */
12617 && !row->ends_at_zv_p
12618 /* When first_changed_pos is the end of a continued line,
12619 row is not unchanged because it may be no longer
12620 continued. */
12621 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
12622 && (row->continued_p
12623 || row->exact_window_width_line_p)))
12624 row_found = row;
12626 /* Stop if last visible row. */
12627 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
12628 break;
12630 ++row;
12633 return row_found;
12637 /* Find the first glyph row in the current matrix of W that is not
12638 affected by changes at the end of current_buffer since the
12639 time W's current matrix was built.
12641 Return in *DELTA the number of chars by which buffer positions in
12642 unchanged text at the end of current_buffer must be adjusted.
12644 Return in *DELTA_BYTES the corresponding number of bytes.
12646 Value is null if no such row exists, i.e. all rows are affected by
12647 changes. */
12649 static struct glyph_row *
12650 find_first_unchanged_at_end_row (w, delta, delta_bytes)
12651 struct window *w;
12652 int *delta, *delta_bytes;
12654 struct glyph_row *row;
12655 struct glyph_row *row_found = NULL;
12657 *delta = *delta_bytes = 0;
12659 /* Display must not have been paused, otherwise the current matrix
12660 is not up to date. */
12661 if (NILP (w->window_end_valid))
12662 abort ();
12664 /* A value of window_end_pos >= END_UNCHANGED means that the window
12665 end is in the range of changed text. If so, there is no
12666 unchanged row at the end of W's current matrix. */
12667 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
12668 return NULL;
12670 /* Set row to the last row in W's current matrix displaying text. */
12671 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
12673 /* If matrix is entirely empty, no unchanged row exists. */
12674 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12676 /* The value of row is the last glyph row in the matrix having a
12677 meaningful buffer position in it. The end position of row
12678 corresponds to window_end_pos. This allows us to translate
12679 buffer positions in the current matrix to current buffer
12680 positions for characters not in changed text. */
12681 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
12682 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
12683 int last_unchanged_pos, last_unchanged_pos_old;
12684 struct glyph_row *first_text_row
12685 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12687 *delta = Z - Z_old;
12688 *delta_bytes = Z_BYTE - Z_BYTE_old;
12690 /* Set last_unchanged_pos to the buffer position of the last
12691 character in the buffer that has not been changed. Z is the
12692 index + 1 of the last character in current_buffer, i.e. by
12693 subtracting END_UNCHANGED we get the index of the last
12694 unchanged character, and we have to add BEG to get its buffer
12695 position. */
12696 last_unchanged_pos = Z - END_UNCHANGED + BEG;
12697 last_unchanged_pos_old = last_unchanged_pos - *delta;
12699 /* Search backward from ROW for a row displaying a line that
12700 starts at a minimum position >= last_unchanged_pos_old. */
12701 for (; row > first_text_row; --row)
12703 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
12704 abort ();
12706 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
12707 row_found = row;
12711 if (row_found && !MATRIX_ROW_DISPLAYS_TEXT_P (row_found))
12712 abort ();
12714 return row_found;
12718 /* Make sure that glyph rows in the current matrix of window W
12719 reference the same glyph memory as corresponding rows in the
12720 frame's frame matrix. This function is called after scrolling W's
12721 current matrix on a terminal frame in try_window_id and
12722 try_window_reusing_current_matrix. */
12724 static void
12725 sync_frame_with_window_matrix_rows (w)
12726 struct window *w;
12728 struct frame *f = XFRAME (w->frame);
12729 struct glyph_row *window_row, *window_row_end, *frame_row;
12731 /* Preconditions: W must be a leaf window and full-width. Its frame
12732 must have a frame matrix. */
12733 xassert (NILP (w->hchild) && NILP (w->vchild));
12734 xassert (WINDOW_FULL_WIDTH_P (w));
12735 xassert (!FRAME_WINDOW_P (f));
12737 /* If W is a full-width window, glyph pointers in W's current matrix
12738 have, by definition, to be the same as glyph pointers in the
12739 corresponding frame matrix. Note that frame matrices have no
12740 marginal areas (see build_frame_matrix). */
12741 window_row = w->current_matrix->rows;
12742 window_row_end = window_row + w->current_matrix->nrows;
12743 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
12744 while (window_row < window_row_end)
12746 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
12747 struct glyph *end = window_row->glyphs[LAST_AREA];
12749 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
12750 frame_row->glyphs[TEXT_AREA] = start;
12751 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
12752 frame_row->glyphs[LAST_AREA] = end;
12754 /* Disable frame rows whose corresponding window rows have
12755 been disabled in try_window_id. */
12756 if (!window_row->enabled_p)
12757 frame_row->enabled_p = 0;
12759 ++window_row, ++frame_row;
12764 /* Find the glyph row in window W containing CHARPOS. Consider all
12765 rows between START and END (not inclusive). END null means search
12766 all rows to the end of the display area of W. Value is the row
12767 containing CHARPOS or null. */
12769 struct glyph_row *
12770 row_containing_pos (w, charpos, start, end, dy)
12771 struct window *w;
12772 int charpos;
12773 struct glyph_row *start, *end;
12774 int dy;
12776 struct glyph_row *row = start;
12777 int last_y;
12779 /* If we happen to start on a header-line, skip that. */
12780 if (row->mode_line_p)
12781 ++row;
12783 if ((end && row >= end) || !row->enabled_p)
12784 return NULL;
12786 last_y = window_text_bottom_y (w) - dy;
12788 while (1)
12790 /* Give up if we have gone too far. */
12791 if (end && row >= end)
12792 return NULL;
12793 /* This formerly returned if they were equal.
12794 I think that both quantities are of a "last plus one" type;
12795 if so, when they are equal, the row is within the screen. -- rms. */
12796 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
12797 return NULL;
12799 /* If it is in this row, return this row. */
12800 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
12801 || (MATRIX_ROW_END_CHARPOS (row) == charpos
12802 /* The end position of a row equals the start
12803 position of the next row. If CHARPOS is there, we
12804 would rather display it in the next line, except
12805 when this line ends in ZV. */
12806 && !row->ends_at_zv_p
12807 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
12808 && charpos >= MATRIX_ROW_START_CHARPOS (row))
12809 return row;
12810 ++row;
12815 /* Try to redisplay window W by reusing its existing display. W's
12816 current matrix must be up to date when this function is called,
12817 i.e. window_end_valid must not be nil.
12819 Value is
12821 1 if display has been updated
12822 0 if otherwise unsuccessful
12823 -1 if redisplay with same window start is known not to succeed
12825 The following steps are performed:
12827 1. Find the last row in the current matrix of W that is not
12828 affected by changes at the start of current_buffer. If no such row
12829 is found, give up.
12831 2. Find the first row in W's current matrix that is not affected by
12832 changes at the end of current_buffer. Maybe there is no such row.
12834 3. Display lines beginning with the row + 1 found in step 1 to the
12835 row found in step 2 or, if step 2 didn't find a row, to the end of
12836 the window.
12838 4. If cursor is not known to appear on the window, give up.
12840 5. If display stopped at the row found in step 2, scroll the
12841 display and current matrix as needed.
12843 6. Maybe display some lines at the end of W, if we must. This can
12844 happen under various circumstances, like a partially visible line
12845 becoming fully visible, or because newly displayed lines are displayed
12846 in smaller font sizes.
12848 7. Update W's window end information. */
12850 static int
12851 try_window_id (w)
12852 struct window *w;
12854 struct frame *f = XFRAME (w->frame);
12855 struct glyph_matrix *current_matrix = w->current_matrix;
12856 struct glyph_matrix *desired_matrix = w->desired_matrix;
12857 struct glyph_row *last_unchanged_at_beg_row;
12858 struct glyph_row *first_unchanged_at_end_row;
12859 struct glyph_row *row;
12860 struct glyph_row *bottom_row;
12861 int bottom_vpos;
12862 struct it it;
12863 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
12864 struct text_pos start_pos;
12865 struct run run;
12866 int first_unchanged_at_end_vpos = 0;
12867 struct glyph_row *last_text_row, *last_text_row_at_end;
12868 struct text_pos start;
12869 int first_changed_charpos, last_changed_charpos;
12871 #if GLYPH_DEBUG
12872 if (inhibit_try_window_id)
12873 return 0;
12874 #endif
12876 /* This is handy for debugging. */
12877 #if 0
12878 #define GIVE_UP(X) \
12879 do { \
12880 fprintf (stderr, "try_window_id give up %d\n", (X)); \
12881 return 0; \
12882 } while (0)
12883 #else
12884 #define GIVE_UP(X) return 0
12885 #endif
12887 SET_TEXT_POS_FROM_MARKER (start, w->start);
12889 /* Don't use this for mini-windows because these can show
12890 messages and mini-buffers, and we don't handle that here. */
12891 if (MINI_WINDOW_P (w))
12892 GIVE_UP (1);
12894 /* This flag is used to prevent redisplay optimizations. */
12895 if (windows_or_buffers_changed || cursor_type_changed)
12896 GIVE_UP (2);
12898 /* Verify that narrowing has not changed.
12899 Also verify that we were not told to prevent redisplay optimizations.
12900 It would be nice to further
12901 reduce the number of cases where this prevents try_window_id. */
12902 if (current_buffer->clip_changed
12903 || current_buffer->prevent_redisplay_optimizations_p)
12904 GIVE_UP (3);
12906 /* Window must either use window-based redisplay or be full width. */
12907 if (!FRAME_WINDOW_P (f)
12908 && (!line_ins_del_ok
12909 || !WINDOW_FULL_WIDTH_P (w)))
12910 GIVE_UP (4);
12912 /* Give up if point is not known NOT to appear in W. */
12913 if (PT < CHARPOS (start))
12914 GIVE_UP (5);
12916 /* Another way to prevent redisplay optimizations. */
12917 if (XFASTINT (w->last_modified) == 0)
12918 GIVE_UP (6);
12920 /* Verify that window is not hscrolled. */
12921 if (XFASTINT (w->hscroll) != 0)
12922 GIVE_UP (7);
12924 /* Verify that display wasn't paused. */
12925 if (NILP (w->window_end_valid))
12926 GIVE_UP (8);
12928 /* Can't use this if highlighting a region because a cursor movement
12929 will do more than just set the cursor. */
12930 if (!NILP (Vtransient_mark_mode)
12931 && !NILP (current_buffer->mark_active))
12932 GIVE_UP (9);
12934 /* Likewise if highlighting trailing whitespace. */
12935 if (!NILP (Vshow_trailing_whitespace))
12936 GIVE_UP (11);
12938 /* Likewise if showing a region. */
12939 if (!NILP (w->region_showing))
12940 GIVE_UP (10);
12942 /* Can use this if overlay arrow position and or string have changed. */
12943 if (overlay_arrows_changed_p ())
12944 GIVE_UP (12);
12947 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
12948 only if buffer has really changed. The reason is that the gap is
12949 initially at Z for freshly visited files. The code below would
12950 set end_unchanged to 0 in that case. */
12951 if (MODIFF > SAVE_MODIFF
12952 /* This seems to happen sometimes after saving a buffer. */
12953 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
12955 if (GPT - BEG < BEG_UNCHANGED)
12956 BEG_UNCHANGED = GPT - BEG;
12957 if (Z - GPT < END_UNCHANGED)
12958 END_UNCHANGED = Z - GPT;
12961 /* The position of the first and last character that has been changed. */
12962 first_changed_charpos = BEG + BEG_UNCHANGED;
12963 last_changed_charpos = Z - END_UNCHANGED;
12965 /* If window starts after a line end, and the last change is in
12966 front of that newline, then changes don't affect the display.
12967 This case happens with stealth-fontification. Note that although
12968 the display is unchanged, glyph positions in the matrix have to
12969 be adjusted, of course. */
12970 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
12971 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12972 && ((last_changed_charpos < CHARPOS (start)
12973 && CHARPOS (start) == BEGV)
12974 || (last_changed_charpos < CHARPOS (start) - 1
12975 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
12977 int Z_old, delta, Z_BYTE_old, delta_bytes;
12978 struct glyph_row *r0;
12980 /* Compute how many chars/bytes have been added to or removed
12981 from the buffer. */
12982 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
12983 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
12984 delta = Z - Z_old;
12985 delta_bytes = Z_BYTE - Z_BYTE_old;
12987 /* Give up if PT is not in the window. Note that it already has
12988 been checked at the start of try_window_id that PT is not in
12989 front of the window start. */
12990 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
12991 GIVE_UP (13);
12993 /* If window start is unchanged, we can reuse the whole matrix
12994 as is, after adjusting glyph positions. No need to compute
12995 the window end again, since its offset from Z hasn't changed. */
12996 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
12997 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
12998 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
12999 /* PT must not be in a partially visible line. */
13000 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
13001 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13003 /* Adjust positions in the glyph matrix. */
13004 if (delta || delta_bytes)
13006 struct glyph_row *r1
13007 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13008 increment_matrix_positions (w->current_matrix,
13009 MATRIX_ROW_VPOS (r0, current_matrix),
13010 MATRIX_ROW_VPOS (r1, current_matrix),
13011 delta, delta_bytes);
13014 /* Set the cursor. */
13015 row = row_containing_pos (w, PT, r0, NULL, 0);
13016 if (row)
13017 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13018 else
13019 abort ();
13020 return 1;
13024 /* Handle the case that changes are all below what is displayed in
13025 the window, and that PT is in the window. This shortcut cannot
13026 be taken if ZV is visible in the window, and text has been added
13027 there that is visible in the window. */
13028 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
13029 /* ZV is not visible in the window, or there are no
13030 changes at ZV, actually. */
13031 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
13032 || first_changed_charpos == last_changed_charpos))
13034 struct glyph_row *r0;
13036 /* Give up if PT is not in the window. Note that it already has
13037 been checked at the start of try_window_id that PT is not in
13038 front of the window start. */
13039 if (PT >= MATRIX_ROW_END_CHARPOS (row))
13040 GIVE_UP (14);
13042 /* If window start is unchanged, we can reuse the whole matrix
13043 as is, without changing glyph positions since no text has
13044 been added/removed in front of the window end. */
13045 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13046 if (TEXT_POS_EQUAL_P (start, r0->start.pos)
13047 /* PT must not be in a partially visible line. */
13048 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
13049 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13051 /* We have to compute the window end anew since text
13052 can have been added/removed after it. */
13053 w->window_end_pos
13054 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13055 w->window_end_bytepos
13056 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13058 /* Set the cursor. */
13059 row = row_containing_pos (w, PT, r0, NULL, 0);
13060 if (row)
13061 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13062 else
13063 abort ();
13064 return 2;
13068 /* Give up if window start is in the changed area.
13070 The condition used to read
13072 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
13074 but why that was tested escapes me at the moment. */
13075 if (CHARPOS (start) >= first_changed_charpos
13076 && CHARPOS (start) <= last_changed_charpos)
13077 GIVE_UP (15);
13079 /* Check that window start agrees with the start of the first glyph
13080 row in its current matrix. Check this after we know the window
13081 start is not in changed text, otherwise positions would not be
13082 comparable. */
13083 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
13084 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
13085 GIVE_UP (16);
13087 /* Give up if the window ends in strings. Overlay strings
13088 at the end are difficult to handle, so don't try. */
13089 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
13090 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
13091 GIVE_UP (20);
13093 /* Compute the position at which we have to start displaying new
13094 lines. Some of the lines at the top of the window might be
13095 reusable because they are not displaying changed text. Find the
13096 last row in W's current matrix not affected by changes at the
13097 start of current_buffer. Value is null if changes start in the
13098 first line of window. */
13099 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
13100 if (last_unchanged_at_beg_row)
13102 /* Avoid starting to display in the moddle of a character, a TAB
13103 for instance. This is easier than to set up the iterator
13104 exactly, and it's not a frequent case, so the additional
13105 effort wouldn't really pay off. */
13106 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
13107 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
13108 && last_unchanged_at_beg_row > w->current_matrix->rows)
13109 --last_unchanged_at_beg_row;
13111 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
13112 GIVE_UP (17);
13114 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
13115 GIVE_UP (18);
13116 start_pos = it.current.pos;
13118 /* Start displaying new lines in the desired matrix at the same
13119 vpos we would use in the current matrix, i.e. below
13120 last_unchanged_at_beg_row. */
13121 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
13122 current_matrix);
13123 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13124 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
13126 xassert (it.hpos == 0 && it.current_x == 0);
13128 else
13130 /* There are no reusable lines at the start of the window.
13131 Start displaying in the first text line. */
13132 start_display (&it, w, start);
13133 it.vpos = it.first_vpos;
13134 start_pos = it.current.pos;
13137 /* Find the first row that is not affected by changes at the end of
13138 the buffer. Value will be null if there is no unchanged row, in
13139 which case we must redisplay to the end of the window. delta
13140 will be set to the value by which buffer positions beginning with
13141 first_unchanged_at_end_row have to be adjusted due to text
13142 changes. */
13143 first_unchanged_at_end_row
13144 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
13145 IF_DEBUG (debug_delta = delta);
13146 IF_DEBUG (debug_delta_bytes = delta_bytes);
13148 /* Set stop_pos to the buffer position up to which we will have to
13149 display new lines. If first_unchanged_at_end_row != NULL, this
13150 is the buffer position of the start of the line displayed in that
13151 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
13152 that we don't stop at a buffer position. */
13153 stop_pos = 0;
13154 if (first_unchanged_at_end_row)
13156 xassert (last_unchanged_at_beg_row == NULL
13157 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
13159 /* If this is a continuation line, move forward to the next one
13160 that isn't. Changes in lines above affect this line.
13161 Caution: this may move first_unchanged_at_end_row to a row
13162 not displaying text. */
13163 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
13164 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13165 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13166 < it.last_visible_y))
13167 ++first_unchanged_at_end_row;
13169 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13170 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13171 >= it.last_visible_y))
13172 first_unchanged_at_end_row = NULL;
13173 else
13175 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
13176 + delta);
13177 first_unchanged_at_end_vpos
13178 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
13179 xassert (stop_pos >= Z - END_UNCHANGED);
13182 else if (last_unchanged_at_beg_row == NULL)
13183 GIVE_UP (19);
13186 #if GLYPH_DEBUG
13188 /* Either there is no unchanged row at the end, or the one we have
13189 now displays text. This is a necessary condition for the window
13190 end pos calculation at the end of this function. */
13191 xassert (first_unchanged_at_end_row == NULL
13192 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
13194 debug_last_unchanged_at_beg_vpos
13195 = (last_unchanged_at_beg_row
13196 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
13197 : -1);
13198 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
13200 #endif /* GLYPH_DEBUG != 0 */
13203 /* Display new lines. Set last_text_row to the last new line
13204 displayed which has text on it, i.e. might end up as being the
13205 line where the window_end_vpos is. */
13206 w->cursor.vpos = -1;
13207 last_text_row = NULL;
13208 overlay_arrow_seen = 0;
13209 while (it.current_y < it.last_visible_y
13210 && !fonts_changed_p
13211 && (first_unchanged_at_end_row == NULL
13212 || IT_CHARPOS (it) < stop_pos))
13214 if (display_line (&it))
13215 last_text_row = it.glyph_row - 1;
13218 if (fonts_changed_p)
13219 return -1;
13222 /* Compute differences in buffer positions, y-positions etc. for
13223 lines reused at the bottom of the window. Compute what we can
13224 scroll. */
13225 if (first_unchanged_at_end_row
13226 /* No lines reused because we displayed everything up to the
13227 bottom of the window. */
13228 && it.current_y < it.last_visible_y)
13230 dvpos = (it.vpos
13231 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
13232 current_matrix));
13233 dy = it.current_y - first_unchanged_at_end_row->y;
13234 run.current_y = first_unchanged_at_end_row->y;
13235 run.desired_y = run.current_y + dy;
13236 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
13238 else
13240 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
13241 first_unchanged_at_end_row = NULL;
13243 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
13246 /* Find the cursor if not already found. We have to decide whether
13247 PT will appear on this window (it sometimes doesn't, but this is
13248 not a very frequent case.) This decision has to be made before
13249 the current matrix is altered. A value of cursor.vpos < 0 means
13250 that PT is either in one of the lines beginning at
13251 first_unchanged_at_end_row or below the window. Don't care for
13252 lines that might be displayed later at the window end; as
13253 mentioned, this is not a frequent case. */
13254 if (w->cursor.vpos < 0)
13256 /* Cursor in unchanged rows at the top? */
13257 if (PT < CHARPOS (start_pos)
13258 && last_unchanged_at_beg_row)
13260 row = row_containing_pos (w, PT,
13261 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
13262 last_unchanged_at_beg_row + 1, 0);
13263 if (row)
13264 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13267 /* Start from first_unchanged_at_end_row looking for PT. */
13268 else if (first_unchanged_at_end_row)
13270 row = row_containing_pos (w, PT - delta,
13271 first_unchanged_at_end_row, NULL, 0);
13272 if (row)
13273 set_cursor_from_row (w, row, w->current_matrix, delta,
13274 delta_bytes, dy, dvpos);
13277 /* Give up if cursor was not found. */
13278 if (w->cursor.vpos < 0)
13280 clear_glyph_matrix (w->desired_matrix);
13281 return -1;
13285 /* Don't let the cursor end in the scroll margins. */
13287 int this_scroll_margin, cursor_height;
13289 this_scroll_margin = max (0, scroll_margin);
13290 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13291 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
13292 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
13294 if ((w->cursor.y < this_scroll_margin
13295 && CHARPOS (start) > BEGV)
13296 /* Don't take scroll margin into account at the bottom because
13297 old redisplay didn't do it either. */
13298 || w->cursor.y + cursor_height > it.last_visible_y)
13300 w->cursor.vpos = -1;
13301 clear_glyph_matrix (w->desired_matrix);
13302 return -1;
13306 /* Scroll the display. Do it before changing the current matrix so
13307 that xterm.c doesn't get confused about where the cursor glyph is
13308 found. */
13309 if (dy && run.height)
13311 update_begin (f);
13313 if (FRAME_WINDOW_P (f))
13315 rif->update_window_begin_hook (w);
13316 rif->clear_window_mouse_face (w);
13317 rif->scroll_run_hook (w, &run);
13318 rif->update_window_end_hook (w, 0, 0);
13320 else
13322 /* Terminal frame. In this case, dvpos gives the number of
13323 lines to scroll by; dvpos < 0 means scroll up. */
13324 int first_unchanged_at_end_vpos
13325 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
13326 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
13327 int end = (WINDOW_TOP_EDGE_LINE (w)
13328 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
13329 + window_internal_height (w));
13331 /* Perform the operation on the screen. */
13332 if (dvpos > 0)
13334 /* Scroll last_unchanged_at_beg_row to the end of the
13335 window down dvpos lines. */
13336 set_terminal_window (end);
13338 /* On dumb terminals delete dvpos lines at the end
13339 before inserting dvpos empty lines. */
13340 if (!scroll_region_ok)
13341 ins_del_lines (end - dvpos, -dvpos);
13343 /* Insert dvpos empty lines in front of
13344 last_unchanged_at_beg_row. */
13345 ins_del_lines (from, dvpos);
13347 else if (dvpos < 0)
13349 /* Scroll up last_unchanged_at_beg_vpos to the end of
13350 the window to last_unchanged_at_beg_vpos - |dvpos|. */
13351 set_terminal_window (end);
13353 /* Delete dvpos lines in front of
13354 last_unchanged_at_beg_vpos. ins_del_lines will set
13355 the cursor to the given vpos and emit |dvpos| delete
13356 line sequences. */
13357 ins_del_lines (from + dvpos, dvpos);
13359 /* On a dumb terminal insert dvpos empty lines at the
13360 end. */
13361 if (!scroll_region_ok)
13362 ins_del_lines (end + dvpos, -dvpos);
13365 set_terminal_window (0);
13368 update_end (f);
13371 /* Shift reused rows of the current matrix to the right position.
13372 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
13373 text. */
13374 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13375 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
13376 if (dvpos < 0)
13378 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
13379 bottom_vpos, dvpos);
13380 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
13381 bottom_vpos, 0);
13383 else if (dvpos > 0)
13385 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
13386 bottom_vpos, dvpos);
13387 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
13388 first_unchanged_at_end_vpos + dvpos, 0);
13391 /* For frame-based redisplay, make sure that current frame and window
13392 matrix are in sync with respect to glyph memory. */
13393 if (!FRAME_WINDOW_P (f))
13394 sync_frame_with_window_matrix_rows (w);
13396 /* Adjust buffer positions in reused rows. */
13397 if (delta)
13398 increment_matrix_positions (current_matrix,
13399 first_unchanged_at_end_vpos + dvpos,
13400 bottom_vpos, delta, delta_bytes);
13402 /* Adjust Y positions. */
13403 if (dy)
13404 shift_glyph_matrix (w, current_matrix,
13405 first_unchanged_at_end_vpos + dvpos,
13406 bottom_vpos, dy);
13408 if (first_unchanged_at_end_row)
13409 first_unchanged_at_end_row += dvpos;
13411 /* If scrolling up, there may be some lines to display at the end of
13412 the window. */
13413 last_text_row_at_end = NULL;
13414 if (dy < 0)
13416 /* Scrolling up can leave for example a partially visible line
13417 at the end of the window to be redisplayed. */
13418 /* Set last_row to the glyph row in the current matrix where the
13419 window end line is found. It has been moved up or down in
13420 the matrix by dvpos. */
13421 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
13422 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
13424 /* If last_row is the window end line, it should display text. */
13425 xassert (last_row->displays_text_p);
13427 /* If window end line was partially visible before, begin
13428 displaying at that line. Otherwise begin displaying with the
13429 line following it. */
13430 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
13432 init_to_row_start (&it, w, last_row);
13433 it.vpos = last_vpos;
13434 it.current_y = last_row->y;
13436 else
13438 init_to_row_end (&it, w, last_row);
13439 it.vpos = 1 + last_vpos;
13440 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
13441 ++last_row;
13444 /* We may start in a continuation line. If so, we have to
13445 get the right continuation_lines_width and current_x. */
13446 it.continuation_lines_width = last_row->continuation_lines_width;
13447 it.hpos = it.current_x = 0;
13449 /* Display the rest of the lines at the window end. */
13450 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13451 while (it.current_y < it.last_visible_y
13452 && !fonts_changed_p)
13454 /* Is it always sure that the display agrees with lines in
13455 the current matrix? I don't think so, so we mark rows
13456 displayed invalid in the current matrix by setting their
13457 enabled_p flag to zero. */
13458 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
13459 if (display_line (&it))
13460 last_text_row_at_end = it.glyph_row - 1;
13464 /* Update window_end_pos and window_end_vpos. */
13465 if (first_unchanged_at_end_row
13466 && first_unchanged_at_end_row->y < it.last_visible_y
13467 && !last_text_row_at_end)
13469 /* Window end line if one of the preserved rows from the current
13470 matrix. Set row to the last row displaying text in current
13471 matrix starting at first_unchanged_at_end_row, after
13472 scrolling. */
13473 xassert (first_unchanged_at_end_row->displays_text_p);
13474 row = find_last_row_displaying_text (w->current_matrix, &it,
13475 first_unchanged_at_end_row);
13476 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
13478 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13479 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13480 w->window_end_vpos
13481 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
13482 xassert (w->window_end_bytepos >= 0);
13483 IF_DEBUG (debug_method_add (w, "A"));
13485 else if (last_text_row_at_end)
13487 w->window_end_pos
13488 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
13489 w->window_end_bytepos
13490 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
13491 w->window_end_vpos
13492 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
13493 xassert (w->window_end_bytepos >= 0);
13494 IF_DEBUG (debug_method_add (w, "B"));
13496 else if (last_text_row)
13498 /* We have displayed either to the end of the window or at the
13499 end of the window, i.e. the last row with text is to be found
13500 in the desired matrix. */
13501 w->window_end_pos
13502 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13503 w->window_end_bytepos
13504 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13505 w->window_end_vpos
13506 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
13507 xassert (w->window_end_bytepos >= 0);
13509 else if (first_unchanged_at_end_row == NULL
13510 && last_text_row == NULL
13511 && last_text_row_at_end == NULL)
13513 /* Displayed to end of window, but no line containing text was
13514 displayed. Lines were deleted at the end of the window. */
13515 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
13516 int vpos = XFASTINT (w->window_end_vpos);
13517 struct glyph_row *current_row = current_matrix->rows + vpos;
13518 struct glyph_row *desired_row = desired_matrix->rows + vpos;
13520 for (row = NULL;
13521 row == NULL && vpos >= first_vpos;
13522 --vpos, --current_row, --desired_row)
13524 if (desired_row->enabled_p)
13526 if (desired_row->displays_text_p)
13527 row = desired_row;
13529 else if (current_row->displays_text_p)
13530 row = current_row;
13533 xassert (row != NULL);
13534 w->window_end_vpos = make_number (vpos + 1);
13535 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13536 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13537 xassert (w->window_end_bytepos >= 0);
13538 IF_DEBUG (debug_method_add (w, "C"));
13540 else
13541 abort ();
13543 #if 0 /* This leads to problems, for instance when the cursor is
13544 at ZV, and the cursor line displays no text. */
13545 /* Disable rows below what's displayed in the window. This makes
13546 debugging easier. */
13547 enable_glyph_matrix_rows (current_matrix,
13548 XFASTINT (w->window_end_vpos) + 1,
13549 bottom_vpos, 0);
13550 #endif
13552 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
13553 debug_end_vpos = XFASTINT (w->window_end_vpos));
13555 /* Record that display has not been completed. */
13556 w->window_end_valid = Qnil;
13557 w->desired_matrix->no_scrolling_p = 1;
13558 return 3;
13560 #undef GIVE_UP
13565 /***********************************************************************
13566 More debugging support
13567 ***********************************************************************/
13569 #if GLYPH_DEBUG
13571 void dump_glyph_row P_ ((struct glyph_row *, int, int));
13572 void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
13573 void dump_glyph P_ ((struct glyph_row *, struct glyph *, int));
13576 /* Dump the contents of glyph matrix MATRIX on stderr.
13578 GLYPHS 0 means don't show glyph contents.
13579 GLYPHS 1 means show glyphs in short form
13580 GLYPHS > 1 means show glyphs in long form. */
13582 void
13583 dump_glyph_matrix (matrix, glyphs)
13584 struct glyph_matrix *matrix;
13585 int glyphs;
13587 int i;
13588 for (i = 0; i < matrix->nrows; ++i)
13589 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
13593 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
13594 the glyph row and area where the glyph comes from. */
13596 void
13597 dump_glyph (row, glyph, area)
13598 struct glyph_row *row;
13599 struct glyph *glyph;
13600 int area;
13602 if (glyph->type == CHAR_GLYPH)
13604 fprintf (stderr,
13605 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13606 glyph - row->glyphs[TEXT_AREA],
13607 'C',
13608 glyph->charpos,
13609 (BUFFERP (glyph->object)
13610 ? 'B'
13611 : (STRINGP (glyph->object)
13612 ? 'S'
13613 : '-')),
13614 glyph->pixel_width,
13615 glyph->u.ch,
13616 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
13617 ? glyph->u.ch
13618 : '.'),
13619 glyph->face_id,
13620 glyph->left_box_line_p,
13621 glyph->right_box_line_p);
13623 else if (glyph->type == STRETCH_GLYPH)
13625 fprintf (stderr,
13626 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13627 glyph - row->glyphs[TEXT_AREA],
13628 'S',
13629 glyph->charpos,
13630 (BUFFERP (glyph->object)
13631 ? 'B'
13632 : (STRINGP (glyph->object)
13633 ? 'S'
13634 : '-')),
13635 glyph->pixel_width,
13637 '.',
13638 glyph->face_id,
13639 glyph->left_box_line_p,
13640 glyph->right_box_line_p);
13642 else if (glyph->type == IMAGE_GLYPH)
13644 fprintf (stderr,
13645 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13646 glyph - row->glyphs[TEXT_AREA],
13647 'I',
13648 glyph->charpos,
13649 (BUFFERP (glyph->object)
13650 ? 'B'
13651 : (STRINGP (glyph->object)
13652 ? 'S'
13653 : '-')),
13654 glyph->pixel_width,
13655 glyph->u.img_id,
13656 '.',
13657 glyph->face_id,
13658 glyph->left_box_line_p,
13659 glyph->right_box_line_p);
13664 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
13665 GLYPHS 0 means don't show glyph contents.
13666 GLYPHS 1 means show glyphs in short form
13667 GLYPHS > 1 means show glyphs in long form. */
13669 void
13670 dump_glyph_row (row, vpos, glyphs)
13671 struct glyph_row *row;
13672 int vpos, glyphs;
13674 if (glyphs != 1)
13676 fprintf (stderr, "Row Start End Used oEI><O\\CTZFesm X Y W H V A P\n");
13677 fprintf (stderr, "=======================================================================\n");
13679 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d%1.1d\
13680 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
13681 vpos,
13682 MATRIX_ROW_START_CHARPOS (row),
13683 MATRIX_ROW_END_CHARPOS (row),
13684 row->used[TEXT_AREA],
13685 row->contains_overlapping_glyphs_p,
13686 row->enabled_p,
13687 row->truncated_on_left_p,
13688 row->truncated_on_right_p,
13689 row->overlay_arrow_p,
13690 row->continued_p,
13691 MATRIX_ROW_CONTINUATION_LINE_P (row),
13692 row->displays_text_p,
13693 row->ends_at_zv_p,
13694 row->fill_line_p,
13695 row->ends_in_middle_of_char_p,
13696 row->starts_in_middle_of_char_p,
13697 row->mouse_face_p,
13698 row->x,
13699 row->y,
13700 row->pixel_width,
13701 row->height,
13702 row->visible_height,
13703 row->ascent,
13704 row->phys_ascent);
13705 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
13706 row->end.overlay_string_index,
13707 row->continuation_lines_width);
13708 fprintf (stderr, "%9d %5d\n",
13709 CHARPOS (row->start.string_pos),
13710 CHARPOS (row->end.string_pos));
13711 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
13712 row->end.dpvec_index);
13715 if (glyphs > 1)
13717 int area;
13719 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
13721 struct glyph *glyph = row->glyphs[area];
13722 struct glyph *glyph_end = glyph + row->used[area];
13724 /* Glyph for a line end in text. */
13725 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
13726 ++glyph_end;
13728 if (glyph < glyph_end)
13729 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
13731 for (; glyph < glyph_end; ++glyph)
13732 dump_glyph (row, glyph, area);
13735 else if (glyphs == 1)
13737 int area;
13739 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
13741 char *s = (char *) alloca (row->used[area] + 1);
13742 int i;
13744 for (i = 0; i < row->used[area]; ++i)
13746 struct glyph *glyph = row->glyphs[area] + i;
13747 if (glyph->type == CHAR_GLYPH
13748 && glyph->u.ch < 0x80
13749 && glyph->u.ch >= ' ')
13750 s[i] = glyph->u.ch;
13751 else
13752 s[i] = '.';
13755 s[i] = '\0';
13756 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
13762 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
13763 Sdump_glyph_matrix, 0, 1, "p",
13764 doc: /* Dump the current matrix of the selected window to stderr.
13765 Shows contents of glyph row structures. With non-nil
13766 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
13767 glyphs in short form, otherwise show glyphs in long form. */)
13768 (glyphs)
13769 Lisp_Object glyphs;
13771 struct window *w = XWINDOW (selected_window);
13772 struct buffer *buffer = XBUFFER (w->buffer);
13774 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
13775 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
13776 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
13777 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
13778 fprintf (stderr, "=============================================\n");
13779 dump_glyph_matrix (w->current_matrix,
13780 NILP (glyphs) ? 0 : XINT (glyphs));
13781 return Qnil;
13785 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
13786 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
13789 struct frame *f = XFRAME (selected_frame);
13790 dump_glyph_matrix (f->current_matrix, 1);
13791 return Qnil;
13795 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
13796 doc: /* Dump glyph row ROW to stderr.
13797 GLYPH 0 means don't dump glyphs.
13798 GLYPH 1 means dump glyphs in short form.
13799 GLYPH > 1 or omitted means dump glyphs in long form. */)
13800 (row, glyphs)
13801 Lisp_Object row, glyphs;
13803 struct glyph_matrix *matrix;
13804 int vpos;
13806 CHECK_NUMBER (row);
13807 matrix = XWINDOW (selected_window)->current_matrix;
13808 vpos = XINT (row);
13809 if (vpos >= 0 && vpos < matrix->nrows)
13810 dump_glyph_row (MATRIX_ROW (matrix, vpos),
13811 vpos,
13812 INTEGERP (glyphs) ? XINT (glyphs) : 2);
13813 return Qnil;
13817 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
13818 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
13819 GLYPH 0 means don't dump glyphs.
13820 GLYPH 1 means dump glyphs in short form.
13821 GLYPH > 1 or omitted means dump glyphs in long form. */)
13822 (row, glyphs)
13823 Lisp_Object row, glyphs;
13825 struct frame *sf = SELECTED_FRAME ();
13826 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
13827 int vpos;
13829 CHECK_NUMBER (row);
13830 vpos = XINT (row);
13831 if (vpos >= 0 && vpos < m->nrows)
13832 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
13833 INTEGERP (glyphs) ? XINT (glyphs) : 2);
13834 return Qnil;
13838 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
13839 doc: /* Toggle tracing of redisplay.
13840 With ARG, turn tracing on if and only if ARG is positive. */)
13841 (arg)
13842 Lisp_Object arg;
13844 if (NILP (arg))
13845 trace_redisplay_p = !trace_redisplay_p;
13846 else
13848 arg = Fprefix_numeric_value (arg);
13849 trace_redisplay_p = XINT (arg) > 0;
13852 return Qnil;
13856 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
13857 doc: /* Like `format', but print result to stderr.
13858 usage: (trace-to-stderr STRING &rest OBJECTS) */)
13859 (nargs, args)
13860 int nargs;
13861 Lisp_Object *args;
13863 Lisp_Object s = Fformat (nargs, args);
13864 fprintf (stderr, "%s", SDATA (s));
13865 return Qnil;
13868 #endif /* GLYPH_DEBUG */
13872 /***********************************************************************
13873 Building Desired Matrix Rows
13874 ***********************************************************************/
13876 /* Return a temporary glyph row holding the glyphs of an overlay
13877 arrow. Only used for non-window-redisplay windows. */
13879 static struct glyph_row *
13880 get_overlay_arrow_glyph_row (w, overlay_arrow_string)
13881 struct window *w;
13882 Lisp_Object overlay_arrow_string;
13884 struct frame *f = XFRAME (WINDOW_FRAME (w));
13885 struct buffer *buffer = XBUFFER (w->buffer);
13886 struct buffer *old = current_buffer;
13887 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
13888 int arrow_len = SCHARS (overlay_arrow_string);
13889 const unsigned char *arrow_end = arrow_string + arrow_len;
13890 const unsigned char *p;
13891 struct it it;
13892 int multibyte_p;
13893 int n_glyphs_before;
13895 set_buffer_temp (buffer);
13896 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
13897 it.glyph_row->used[TEXT_AREA] = 0;
13898 SET_TEXT_POS (it.position, 0, 0);
13900 multibyte_p = !NILP (buffer->enable_multibyte_characters);
13901 p = arrow_string;
13902 while (p < arrow_end)
13904 Lisp_Object face, ilisp;
13906 /* Get the next character. */
13907 if (multibyte_p)
13908 it.c = string_char_and_length (p, arrow_len, &it.len);
13909 else
13910 it.c = *p, it.len = 1;
13911 p += it.len;
13913 /* Get its face. */
13914 ilisp = make_number (p - arrow_string);
13915 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
13916 it.face_id = compute_char_face (f, it.c, face);
13918 /* Compute its width, get its glyphs. */
13919 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
13920 SET_TEXT_POS (it.position, -1, -1);
13921 PRODUCE_GLYPHS (&it);
13923 /* If this character doesn't fit any more in the line, we have
13924 to remove some glyphs. */
13925 if (it.current_x > it.last_visible_x)
13927 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
13928 break;
13932 set_buffer_temp (old);
13933 return it.glyph_row;
13937 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
13938 glyphs are only inserted for terminal frames since we can't really
13939 win with truncation glyphs when partially visible glyphs are
13940 involved. Which glyphs to insert is determined by
13941 produce_special_glyphs. */
13943 static void
13944 insert_left_trunc_glyphs (it)
13945 struct it *it;
13947 struct it truncate_it;
13948 struct glyph *from, *end, *to, *toend;
13950 xassert (!FRAME_WINDOW_P (it->f));
13952 /* Get the truncation glyphs. */
13953 truncate_it = *it;
13954 truncate_it.current_x = 0;
13955 truncate_it.face_id = DEFAULT_FACE_ID;
13956 truncate_it.glyph_row = &scratch_glyph_row;
13957 truncate_it.glyph_row->used[TEXT_AREA] = 0;
13958 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
13959 truncate_it.object = make_number (0);
13960 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
13962 /* Overwrite glyphs from IT with truncation glyphs. */
13963 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
13964 end = from + truncate_it.glyph_row->used[TEXT_AREA];
13965 to = it->glyph_row->glyphs[TEXT_AREA];
13966 toend = to + it->glyph_row->used[TEXT_AREA];
13968 while (from < end)
13969 *to++ = *from++;
13971 /* There may be padding glyphs left over. Overwrite them too. */
13972 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
13974 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
13975 while (from < end)
13976 *to++ = *from++;
13979 if (to > toend)
13980 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
13984 /* Compute the pixel height and width of IT->glyph_row.
13986 Most of the time, ascent and height of a display line will be equal
13987 to the max_ascent and max_height values of the display iterator
13988 structure. This is not the case if
13990 1. We hit ZV without displaying anything. In this case, max_ascent
13991 and max_height will be zero.
13993 2. We have some glyphs that don't contribute to the line height.
13994 (The glyph row flag contributes_to_line_height_p is for future
13995 pixmap extensions).
13997 The first case is easily covered by using default values because in
13998 these cases, the line height does not really matter, except that it
13999 must not be zero. */
14001 static void
14002 compute_line_metrics (it)
14003 struct it *it;
14005 struct glyph_row *row = it->glyph_row;
14006 int area, i;
14008 if (FRAME_WINDOW_P (it->f))
14010 int i, min_y, max_y;
14012 /* The line may consist of one space only, that was added to
14013 place the cursor on it. If so, the row's height hasn't been
14014 computed yet. */
14015 if (row->height == 0)
14017 if (it->max_ascent + it->max_descent == 0)
14018 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
14019 row->ascent = it->max_ascent;
14020 row->height = it->max_ascent + it->max_descent;
14021 row->phys_ascent = it->max_phys_ascent;
14022 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14025 /* Compute the width of this line. */
14026 row->pixel_width = row->x;
14027 for (i = 0; i < row->used[TEXT_AREA]; ++i)
14028 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
14030 xassert (row->pixel_width >= 0);
14031 xassert (row->ascent >= 0 && row->height > 0);
14033 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
14034 || MATRIX_ROW_OVERLAPS_PRED_P (row));
14036 /* If first line's physical ascent is larger than its logical
14037 ascent, use the physical ascent, and make the row taller.
14038 This makes accented characters fully visible. */
14039 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
14040 && row->phys_ascent > row->ascent)
14042 row->height += row->phys_ascent - row->ascent;
14043 row->ascent = row->phys_ascent;
14046 /* Compute how much of the line is visible. */
14047 row->visible_height = row->height;
14049 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
14050 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
14052 if (row->y < min_y)
14053 row->visible_height -= min_y - row->y;
14054 if (row->y + row->height > max_y)
14055 row->visible_height -= row->y + row->height - max_y;
14057 else
14059 row->pixel_width = row->used[TEXT_AREA];
14060 if (row->continued_p)
14061 row->pixel_width -= it->continuation_pixel_width;
14062 else if (row->truncated_on_right_p)
14063 row->pixel_width -= it->truncation_pixel_width;
14064 row->ascent = row->phys_ascent = 0;
14065 row->height = row->phys_height = row->visible_height = 1;
14068 /* Compute a hash code for this row. */
14069 row->hash = 0;
14070 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14071 for (i = 0; i < row->used[area]; ++i)
14072 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
14073 + row->glyphs[area][i].u.val
14074 + row->glyphs[area][i].face_id
14075 + row->glyphs[area][i].padding_p
14076 + (row->glyphs[area][i].type << 2));
14078 it->max_ascent = it->max_descent = 0;
14079 it->max_phys_ascent = it->max_phys_descent = 0;
14083 /* Append one space to the glyph row of iterator IT if doing a
14084 window-based redisplay. DEFAULT_FACE_P non-zero means let the
14085 space have the default face, otherwise let it have the same face as
14086 IT->face_id. Value is non-zero if a space was added.
14088 This function is called to make sure that there is always one glyph
14089 at the end of a glyph row that the cursor can be set on under
14090 window-systems. (If there weren't such a glyph we would not know
14091 how wide and tall a box cursor should be displayed).
14093 At the same time this space let's a nicely handle clearing to the
14094 end of the line if the row ends in italic text. */
14096 static int
14097 append_space (it, default_face_p)
14098 struct it *it;
14099 int default_face_p;
14101 if (FRAME_WINDOW_P (it->f))
14103 int n = it->glyph_row->used[TEXT_AREA];
14105 if (it->glyph_row->glyphs[TEXT_AREA] + n
14106 < it->glyph_row->glyphs[1 + TEXT_AREA])
14108 /* Save some values that must not be changed.
14109 Must save IT->c and IT->len because otherwise
14110 ITERATOR_AT_END_P wouldn't work anymore after
14111 append_space has been called. */
14112 enum display_element_type saved_what = it->what;
14113 int saved_c = it->c, saved_len = it->len;
14114 int saved_x = it->current_x;
14115 int saved_face_id = it->face_id;
14116 struct text_pos saved_pos;
14117 Lisp_Object saved_object;
14118 struct face *face;
14120 saved_object = it->object;
14121 saved_pos = it->position;
14123 it->what = IT_CHARACTER;
14124 bzero (&it->position, sizeof it->position);
14125 it->object = make_number (0);
14126 it->c = ' ';
14127 it->len = 1;
14129 if (default_face_p)
14130 it->face_id = DEFAULT_FACE_ID;
14131 else if (it->face_before_selective_p)
14132 it->face_id = it->saved_face_id;
14133 face = FACE_FROM_ID (it->f, it->face_id);
14134 it->face_id = FACE_FOR_CHAR (it->f, face, 0);
14136 PRODUCE_GLYPHS (it);
14138 it->current_x = saved_x;
14139 it->object = saved_object;
14140 it->position = saved_pos;
14141 it->what = saved_what;
14142 it->face_id = saved_face_id;
14143 it->len = saved_len;
14144 it->c = saved_c;
14145 return 1;
14149 return 0;
14153 /* Extend the face of the last glyph in the text area of IT->glyph_row
14154 to the end of the display line. Called from display_line.
14155 If the glyph row is empty, add a space glyph to it so that we
14156 know the face to draw. Set the glyph row flag fill_line_p. */
14158 static void
14159 extend_face_to_end_of_line (it)
14160 struct it *it;
14162 struct face *face;
14163 struct frame *f = it->f;
14165 /* If line is already filled, do nothing. */
14166 if (it->current_x >= it->last_visible_x)
14167 return;
14169 /* Face extension extends the background and box of IT->face_id
14170 to the end of the line. If the background equals the background
14171 of the frame, we don't have to do anything. */
14172 if (it->face_before_selective_p)
14173 face = FACE_FROM_ID (it->f, it->saved_face_id);
14174 else
14175 face = FACE_FROM_ID (f, it->face_id);
14177 if (FRAME_WINDOW_P (f)
14178 && face->box == FACE_NO_BOX
14179 && face->background == FRAME_BACKGROUND_PIXEL (f)
14180 && !face->stipple)
14181 return;
14183 /* Set the glyph row flag indicating that the face of the last glyph
14184 in the text area has to be drawn to the end of the text area. */
14185 it->glyph_row->fill_line_p = 1;
14187 /* If current character of IT is not ASCII, make sure we have the
14188 ASCII face. This will be automatically undone the next time
14189 get_next_display_element returns a multibyte character. Note
14190 that the character will always be single byte in unibyte text. */
14191 if (!SINGLE_BYTE_CHAR_P (it->c))
14193 it->face_id = FACE_FOR_CHAR (f, face, 0);
14196 if (FRAME_WINDOW_P (f))
14198 /* If the row is empty, add a space with the current face of IT,
14199 so that we know which face to draw. */
14200 if (it->glyph_row->used[TEXT_AREA] == 0)
14202 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
14203 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
14204 it->glyph_row->used[TEXT_AREA] = 1;
14207 else
14209 /* Save some values that must not be changed. */
14210 int saved_x = it->current_x;
14211 struct text_pos saved_pos;
14212 Lisp_Object saved_object;
14213 enum display_element_type saved_what = it->what;
14214 int saved_face_id = it->face_id;
14216 saved_object = it->object;
14217 saved_pos = it->position;
14219 it->what = IT_CHARACTER;
14220 bzero (&it->position, sizeof it->position);
14221 it->object = make_number (0);
14222 it->c = ' ';
14223 it->len = 1;
14224 it->face_id = face->id;
14226 PRODUCE_GLYPHS (it);
14228 while (it->current_x <= it->last_visible_x)
14229 PRODUCE_GLYPHS (it);
14231 /* Don't count these blanks really. It would let us insert a left
14232 truncation glyph below and make us set the cursor on them, maybe. */
14233 it->current_x = saved_x;
14234 it->object = saved_object;
14235 it->position = saved_pos;
14236 it->what = saved_what;
14237 it->face_id = saved_face_id;
14242 /* Value is non-zero if text starting at CHARPOS in current_buffer is
14243 trailing whitespace. */
14245 static int
14246 trailing_whitespace_p (charpos)
14247 int charpos;
14249 int bytepos = CHAR_TO_BYTE (charpos);
14250 int c = 0;
14252 while (bytepos < ZV_BYTE
14253 && (c = FETCH_CHAR (bytepos),
14254 c == ' ' || c == '\t'))
14255 ++bytepos;
14257 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
14259 if (bytepos != PT_BYTE)
14260 return 1;
14262 return 0;
14266 /* Highlight trailing whitespace, if any, in ROW. */
14268 void
14269 highlight_trailing_whitespace (f, row)
14270 struct frame *f;
14271 struct glyph_row *row;
14273 int used = row->used[TEXT_AREA];
14275 if (used)
14277 struct glyph *start = row->glyphs[TEXT_AREA];
14278 struct glyph *glyph = start + used - 1;
14280 /* Skip over glyphs inserted to display the cursor at the
14281 end of a line, for extending the face of the last glyph
14282 to the end of the line on terminals, and for truncation
14283 and continuation glyphs. */
14284 while (glyph >= start
14285 && glyph->type == CHAR_GLYPH
14286 && INTEGERP (glyph->object))
14287 --glyph;
14289 /* If last glyph is a space or stretch, and it's trailing
14290 whitespace, set the face of all trailing whitespace glyphs in
14291 IT->glyph_row to `trailing-whitespace'. */
14292 if (glyph >= start
14293 && BUFFERP (glyph->object)
14294 && (glyph->type == STRETCH_GLYPH
14295 || (glyph->type == CHAR_GLYPH
14296 && glyph->u.ch == ' '))
14297 && trailing_whitespace_p (glyph->charpos))
14299 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
14301 while (glyph >= start
14302 && BUFFERP (glyph->object)
14303 && (glyph->type == STRETCH_GLYPH
14304 || (glyph->type == CHAR_GLYPH
14305 && glyph->u.ch == ' ')))
14306 (glyph--)->face_id = face_id;
14312 /* Value is non-zero if glyph row ROW in window W should be
14313 used to hold the cursor. */
14315 static int
14316 cursor_row_p (w, row)
14317 struct window *w;
14318 struct glyph_row *row;
14320 int cursor_row_p = 1;
14322 if (PT == MATRIX_ROW_END_CHARPOS (row))
14324 /* If the row ends with a newline from a string, we don't want
14325 the cursor there (if the row is continued it doesn't end in a
14326 newline). */
14327 if (CHARPOS (row->end.string_pos) >= 0
14328 || MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
14329 cursor_row_p = row->continued_p;
14331 /* If the row ends at ZV, display the cursor at the end of that
14332 row instead of at the start of the row below. */
14333 else if (row->ends_at_zv_p)
14334 cursor_row_p = 1;
14335 else
14336 cursor_row_p = 0;
14339 return cursor_row_p;
14343 /* Construct the glyph row IT->glyph_row in the desired matrix of
14344 IT->w from text at the current position of IT. See dispextern.h
14345 for an overview of struct it. Value is non-zero if
14346 IT->glyph_row displays text, as opposed to a line displaying ZV
14347 only. */
14349 static int
14350 display_line (it)
14351 struct it *it;
14353 struct glyph_row *row = it->glyph_row;
14354 int overlay_arrow_bitmap;
14355 Lisp_Object overlay_arrow_string;
14357 /* We always start displaying at hpos zero even if hscrolled. */
14358 xassert (it->hpos == 0 && it->current_x == 0);
14360 /* We must not display in a row that's not a text row. */
14361 xassert (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
14362 < it->w->desired_matrix->nrows);
14364 /* Is IT->w showing the region? */
14365 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
14367 /* Clear the result glyph row and enable it. */
14368 prepare_desired_row (row);
14370 row->y = it->current_y;
14371 row->start = it->start;
14372 row->continuation_lines_width = it->continuation_lines_width;
14373 row->displays_text_p = 1;
14374 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
14375 it->starts_in_middle_of_char_p = 0;
14377 /* Arrange the overlays nicely for our purposes. Usually, we call
14378 display_line on only one line at a time, in which case this
14379 can't really hurt too much, or we call it on lines which appear
14380 one after another in the buffer, in which case all calls to
14381 recenter_overlay_lists but the first will be pretty cheap. */
14382 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
14384 /* Move over display elements that are not visible because we are
14385 hscrolled. This may stop at an x-position < IT->first_visible_x
14386 if the first glyph is partially visible or if we hit a line end. */
14387 if (it->current_x < it->first_visible_x)
14388 move_it_in_display_line_to (it, ZV, it->first_visible_x,
14389 MOVE_TO_POS | MOVE_TO_X);
14391 /* Get the initial row height. This is either the height of the
14392 text hscrolled, if there is any, or zero. */
14393 row->ascent = it->max_ascent;
14394 row->height = it->max_ascent + it->max_descent;
14395 row->phys_ascent = it->max_phys_ascent;
14396 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14398 /* Loop generating characters. The loop is left with IT on the next
14399 character to display. */
14400 while (1)
14402 int n_glyphs_before, hpos_before, x_before;
14403 int x, i, nglyphs;
14404 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
14406 /* Retrieve the next thing to display. Value is zero if end of
14407 buffer reached. */
14408 if (!get_next_display_element (it))
14410 /* Maybe add a space at the end of this line that is used to
14411 display the cursor there under X. Set the charpos of the
14412 first glyph of blank lines not corresponding to any text
14413 to -1. */
14414 #ifdef HAVE_WINDOW_SYSTEM
14415 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14416 row->exact_window_width_line_p = 1;
14417 else
14418 #endif /* HAVE_WINDOW_SYSTEM */
14419 if ((append_space (it, 1) && row->used[TEXT_AREA] == 1)
14420 || row->used[TEXT_AREA] == 0)
14422 row->glyphs[TEXT_AREA]->charpos = -1;
14423 row->displays_text_p = 0;
14425 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
14426 && (!MINI_WINDOW_P (it->w)
14427 || (minibuf_level && EQ (it->window, minibuf_window))))
14428 row->indicate_empty_line_p = 1;
14431 it->continuation_lines_width = 0;
14432 row->ends_at_zv_p = 1;
14433 break;
14436 /* Now, get the metrics of what we want to display. This also
14437 generates glyphs in `row' (which is IT->glyph_row). */
14438 n_glyphs_before = row->used[TEXT_AREA];
14439 x = it->current_x;
14441 /* Remember the line height so far in case the next element doesn't
14442 fit on the line. */
14443 if (!it->truncate_lines_p)
14445 ascent = it->max_ascent;
14446 descent = it->max_descent;
14447 phys_ascent = it->max_phys_ascent;
14448 phys_descent = it->max_phys_descent;
14451 PRODUCE_GLYPHS (it);
14453 /* If this display element was in marginal areas, continue with
14454 the next one. */
14455 if (it->area != TEXT_AREA)
14457 row->ascent = max (row->ascent, it->max_ascent);
14458 row->height = max (row->height, it->max_ascent + it->max_descent);
14459 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14460 row->phys_height = max (row->phys_height,
14461 it->max_phys_ascent + it->max_phys_descent);
14462 set_iterator_to_next (it, 1);
14463 continue;
14466 /* Does the display element fit on the line? If we truncate
14467 lines, we should draw past the right edge of the window. If
14468 we don't truncate, we want to stop so that we can display the
14469 continuation glyph before the right margin. If lines are
14470 continued, there are two possible strategies for characters
14471 resulting in more than 1 glyph (e.g. tabs): Display as many
14472 glyphs as possible in this line and leave the rest for the
14473 continuation line, or display the whole element in the next
14474 line. Original redisplay did the former, so we do it also. */
14475 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
14476 hpos_before = it->hpos;
14477 x_before = x;
14479 if (/* Not a newline. */
14480 nglyphs > 0
14481 /* Glyphs produced fit entirely in the line. */
14482 && it->current_x < it->last_visible_x)
14484 it->hpos += nglyphs;
14485 row->ascent = max (row->ascent, it->max_ascent);
14486 row->height = max (row->height, it->max_ascent + it->max_descent);
14487 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14488 row->phys_height = max (row->phys_height,
14489 it->max_phys_ascent + it->max_phys_descent);
14490 if (it->current_x - it->pixel_width < it->first_visible_x)
14491 row->x = x - it->first_visible_x;
14493 else
14495 int new_x;
14496 struct glyph *glyph;
14498 for (i = 0; i < nglyphs; ++i, x = new_x)
14500 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
14501 new_x = x + glyph->pixel_width;
14503 if (/* Lines are continued. */
14504 !it->truncate_lines_p
14505 && (/* Glyph doesn't fit on the line. */
14506 new_x > it->last_visible_x
14507 /* Or it fits exactly on a window system frame. */
14508 || (new_x == it->last_visible_x
14509 && FRAME_WINDOW_P (it->f))))
14511 /* End of a continued line. */
14513 if (it->hpos == 0
14514 || (new_x == it->last_visible_x
14515 && FRAME_WINDOW_P (it->f)))
14517 /* Current glyph is the only one on the line or
14518 fits exactly on the line. We must continue
14519 the line because we can't draw the cursor
14520 after the glyph. */
14521 row->continued_p = 1;
14522 it->current_x = new_x;
14523 it->continuation_lines_width += new_x;
14524 ++it->hpos;
14525 if (i == nglyphs - 1)
14527 set_iterator_to_next (it, 1);
14528 #ifdef HAVE_WINDOW_SYSTEM
14529 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14531 if (!get_next_display_element (it))
14533 row->exact_window_width_line_p = 1;
14534 it->continuation_lines_width = 0;
14535 row->continued_p = 0;
14536 row->ends_at_zv_p = 1;
14538 else if (ITERATOR_AT_END_OF_LINE_P (it))
14540 row->continued_p = 0;
14541 row->exact_window_width_line_p = 1;
14544 #endif /* HAVE_WINDOW_SYSTEM */
14547 else if (CHAR_GLYPH_PADDING_P (*glyph)
14548 && !FRAME_WINDOW_P (it->f))
14550 /* A padding glyph that doesn't fit on this line.
14551 This means the whole character doesn't fit
14552 on the line. */
14553 row->used[TEXT_AREA] = n_glyphs_before;
14555 /* Fill the rest of the row with continuation
14556 glyphs like in 20.x. */
14557 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
14558 < row->glyphs[1 + TEXT_AREA])
14559 produce_special_glyphs (it, IT_CONTINUATION);
14561 row->continued_p = 1;
14562 it->current_x = x_before;
14563 it->continuation_lines_width += x_before;
14565 /* Restore the height to what it was before the
14566 element not fitting on the line. */
14567 it->max_ascent = ascent;
14568 it->max_descent = descent;
14569 it->max_phys_ascent = phys_ascent;
14570 it->max_phys_descent = phys_descent;
14572 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
14574 /* A TAB that extends past the right edge of the
14575 window. This produces a single glyph on
14576 window system frames. We leave the glyph in
14577 this row and let it fill the row, but don't
14578 consume the TAB. */
14579 it->continuation_lines_width += it->last_visible_x;
14580 row->ends_in_middle_of_char_p = 1;
14581 row->continued_p = 1;
14582 glyph->pixel_width = it->last_visible_x - x;
14583 it->starts_in_middle_of_char_p = 1;
14585 else
14587 /* Something other than a TAB that draws past
14588 the right edge of the window. Restore
14589 positions to values before the element. */
14590 row->used[TEXT_AREA] = n_glyphs_before + i;
14592 /* Display continuation glyphs. */
14593 if (!FRAME_WINDOW_P (it->f))
14594 produce_special_glyphs (it, IT_CONTINUATION);
14595 row->continued_p = 1;
14597 it->continuation_lines_width += x;
14599 if (nglyphs > 1 && i > 0)
14601 row->ends_in_middle_of_char_p = 1;
14602 it->starts_in_middle_of_char_p = 1;
14605 /* Restore the height to what it was before the
14606 element not fitting on the line. */
14607 it->max_ascent = ascent;
14608 it->max_descent = descent;
14609 it->max_phys_ascent = phys_ascent;
14610 it->max_phys_descent = phys_descent;
14613 break;
14615 else if (new_x > it->first_visible_x)
14617 /* Increment number of glyphs actually displayed. */
14618 ++it->hpos;
14620 if (x < it->first_visible_x)
14621 /* Glyph is partially visible, i.e. row starts at
14622 negative X position. */
14623 row->x = x - it->first_visible_x;
14625 else
14627 /* Glyph is completely off the left margin of the
14628 window. This should not happen because of the
14629 move_it_in_display_line at the start of this
14630 function, unless the text display area of the
14631 window is empty. */
14632 xassert (it->first_visible_x <= it->last_visible_x);
14636 row->ascent = max (row->ascent, it->max_ascent);
14637 row->height = max (row->height, it->max_ascent + it->max_descent);
14638 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14639 row->phys_height = max (row->phys_height,
14640 it->max_phys_ascent + it->max_phys_descent);
14642 /* End of this display line if row is continued. */
14643 if (row->continued_p || row->ends_at_zv_p)
14644 break;
14647 at_end_of_line:
14648 /* Is this a line end? If yes, we're also done, after making
14649 sure that a non-default face is extended up to the right
14650 margin of the window. */
14651 if (ITERATOR_AT_END_OF_LINE_P (it))
14653 int used_before = row->used[TEXT_AREA];
14655 row->ends_in_newline_from_string_p = STRINGP (it->object);
14657 #ifdef HAVE_WINDOW_SYSTEM
14658 /* Add a space at the end of the line that is used to
14659 display the cursor there. */
14660 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14661 append_space (it, 0);
14662 #endif /* HAVE_WINDOW_SYSTEM */
14664 /* Extend the face to the end of the line. */
14665 extend_face_to_end_of_line (it);
14667 /* Make sure we have the position. */
14668 if (used_before == 0)
14669 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
14671 /* Consume the line end. This skips over invisible lines. */
14672 set_iterator_to_next (it, 1);
14673 it->continuation_lines_width = 0;
14674 break;
14677 /* Proceed with next display element. Note that this skips
14678 over lines invisible because of selective display. */
14679 set_iterator_to_next (it, 1);
14681 /* If we truncate lines, we are done when the last displayed
14682 glyphs reach past the right margin of the window. */
14683 if (it->truncate_lines_p
14684 && (FRAME_WINDOW_P (it->f)
14685 ? (it->current_x >= it->last_visible_x)
14686 : (it->current_x > it->last_visible_x)))
14688 /* Maybe add truncation glyphs. */
14689 if (!FRAME_WINDOW_P (it->f))
14691 int i, n;
14693 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
14694 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
14695 break;
14697 for (n = row->used[TEXT_AREA]; i < n; ++i)
14699 row->used[TEXT_AREA] = i;
14700 produce_special_glyphs (it, IT_TRUNCATION);
14703 #ifdef HAVE_WINDOW_SYSTEM
14704 else
14706 /* Don't truncate if we can overflow newline into fringe. */
14707 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14709 if (!get_next_display_element (it))
14711 #ifdef HAVE_WINDOW_SYSTEM
14712 it->continuation_lines_width = 0;
14713 row->ends_at_zv_p = 1;
14714 row->exact_window_width_line_p = 1;
14715 break;
14716 #endif /* HAVE_WINDOW_SYSTEM */
14718 if (ITERATOR_AT_END_OF_LINE_P (it))
14720 row->exact_window_width_line_p = 1;
14721 goto at_end_of_line;
14725 #endif /* HAVE_WINDOW_SYSTEM */
14727 row->truncated_on_right_p = 1;
14728 it->continuation_lines_width = 0;
14729 reseat_at_next_visible_line_start (it, 0);
14730 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
14731 it->hpos = hpos_before;
14732 it->current_x = x_before;
14733 break;
14737 /* If line is not empty and hscrolled, maybe insert truncation glyphs
14738 at the left window margin. */
14739 if (it->first_visible_x
14740 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
14742 if (!FRAME_WINDOW_P (it->f))
14743 insert_left_trunc_glyphs (it);
14744 row->truncated_on_left_p = 1;
14747 /* If the start of this line is the overlay arrow-position, then
14748 mark this glyph row as the one containing the overlay arrow.
14749 This is clearly a mess with variable size fonts. It would be
14750 better to let it be displayed like cursors under X. */
14751 if (! overlay_arrow_seen
14752 && (overlay_arrow_string
14753 = overlay_arrow_at_row (it->f, row, &overlay_arrow_bitmap),
14754 !NILP (overlay_arrow_string)))
14756 /* Overlay arrow in window redisplay is a fringe bitmap. */
14757 if (!FRAME_WINDOW_P (it->f))
14759 struct glyph_row *arrow_row
14760 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
14761 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
14762 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
14763 struct glyph *p = row->glyphs[TEXT_AREA];
14764 struct glyph *p2, *end;
14766 /* Copy the arrow glyphs. */
14767 while (glyph < arrow_end)
14768 *p++ = *glyph++;
14770 /* Throw away padding glyphs. */
14771 p2 = p;
14772 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
14773 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
14774 ++p2;
14775 if (p2 > p)
14777 while (p2 < end)
14778 *p++ = *p2++;
14779 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
14783 overlay_arrow_seen = 1;
14784 it->w->overlay_arrow_bitmap = overlay_arrow_bitmap;
14785 row->overlay_arrow_p = 1;
14788 /* Compute pixel dimensions of this line. */
14789 compute_line_metrics (it);
14791 /* Remember the position at which this line ends. */
14792 row->end = it->current;
14794 /* Save fringe bitmaps in this row. */
14795 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
14796 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
14797 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
14798 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
14800 it->left_user_fringe_bitmap = 0;
14801 it->left_user_fringe_face_id = 0;
14802 it->right_user_fringe_bitmap = 0;
14803 it->right_user_fringe_face_id = 0;
14805 /* Maybe set the cursor. */
14806 if (it->w->cursor.vpos < 0
14807 && PT >= MATRIX_ROW_START_CHARPOS (row)
14808 && PT <= MATRIX_ROW_END_CHARPOS (row)
14809 && cursor_row_p (it->w, row))
14810 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
14812 /* Highlight trailing whitespace. */
14813 if (!NILP (Vshow_trailing_whitespace))
14814 highlight_trailing_whitespace (it->f, it->glyph_row);
14816 /* Prepare for the next line. This line starts horizontally at (X
14817 HPOS) = (0 0). Vertical positions are incremented. As a
14818 convenience for the caller, IT->glyph_row is set to the next
14819 row to be used. */
14820 it->current_x = it->hpos = 0;
14821 it->current_y += row->height;
14822 ++it->vpos;
14823 ++it->glyph_row;
14824 it->start = it->current;
14825 return row->displays_text_p;
14830 /***********************************************************************
14831 Menu Bar
14832 ***********************************************************************/
14834 /* Redisplay the menu bar in the frame for window W.
14836 The menu bar of X frames that don't have X toolkit support is
14837 displayed in a special window W->frame->menu_bar_window.
14839 The menu bar of terminal frames is treated specially as far as
14840 glyph matrices are concerned. Menu bar lines are not part of
14841 windows, so the update is done directly on the frame matrix rows
14842 for the menu bar. */
14844 static void
14845 display_menu_bar (w)
14846 struct window *w;
14848 struct frame *f = XFRAME (WINDOW_FRAME (w));
14849 struct it it;
14850 Lisp_Object items;
14851 int i;
14853 /* Don't do all this for graphical frames. */
14854 #ifdef HAVE_NTGUI
14855 if (!NILP (Vwindow_system))
14856 return;
14857 #endif
14858 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
14859 if (FRAME_X_P (f))
14860 return;
14861 #endif
14862 #ifdef MAC_OS
14863 if (FRAME_MAC_P (f))
14864 return;
14865 #endif
14867 #ifdef USE_X_TOOLKIT
14868 xassert (!FRAME_WINDOW_P (f));
14869 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
14870 it.first_visible_x = 0;
14871 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
14872 #else /* not USE_X_TOOLKIT */
14873 if (FRAME_WINDOW_P (f))
14875 /* Menu bar lines are displayed in the desired matrix of the
14876 dummy window menu_bar_window. */
14877 struct window *menu_w;
14878 xassert (WINDOWP (f->menu_bar_window));
14879 menu_w = XWINDOW (f->menu_bar_window);
14880 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
14881 MENU_FACE_ID);
14882 it.first_visible_x = 0;
14883 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
14885 else
14887 /* This is a TTY frame, i.e. character hpos/vpos are used as
14888 pixel x/y. */
14889 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
14890 MENU_FACE_ID);
14891 it.first_visible_x = 0;
14892 it.last_visible_x = FRAME_COLS (f);
14894 #endif /* not USE_X_TOOLKIT */
14896 if (! mode_line_inverse_video)
14897 /* Force the menu-bar to be displayed in the default face. */
14898 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
14900 /* Clear all rows of the menu bar. */
14901 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
14903 struct glyph_row *row = it.glyph_row + i;
14904 clear_glyph_row (row);
14905 row->enabled_p = 1;
14906 row->full_width_p = 1;
14909 /* Display all items of the menu bar. */
14910 items = FRAME_MENU_BAR_ITEMS (it.f);
14911 for (i = 0; i < XVECTOR (items)->size; i += 4)
14913 Lisp_Object string;
14915 /* Stop at nil string. */
14916 string = AREF (items, i + 1);
14917 if (NILP (string))
14918 break;
14920 /* Remember where item was displayed. */
14921 AREF (items, i + 3) = make_number (it.hpos);
14923 /* Display the item, pad with one space. */
14924 if (it.current_x < it.last_visible_x)
14925 display_string (NULL, string, Qnil, 0, 0, &it,
14926 SCHARS (string) + 1, 0, 0, -1);
14929 /* Fill out the line with spaces. */
14930 if (it.current_x < it.last_visible_x)
14931 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
14933 /* Compute the total height of the lines. */
14934 compute_line_metrics (&it);
14939 /***********************************************************************
14940 Mode Line
14941 ***********************************************************************/
14943 /* Redisplay mode lines in the window tree whose root is WINDOW. If
14944 FORCE is non-zero, redisplay mode lines unconditionally.
14945 Otherwise, redisplay only mode lines that are garbaged. Value is
14946 the number of windows whose mode lines were redisplayed. */
14948 static int
14949 redisplay_mode_lines (window, force)
14950 Lisp_Object window;
14951 int force;
14953 int nwindows = 0;
14955 while (!NILP (window))
14957 struct window *w = XWINDOW (window);
14959 if (WINDOWP (w->hchild))
14960 nwindows += redisplay_mode_lines (w->hchild, force);
14961 else if (WINDOWP (w->vchild))
14962 nwindows += redisplay_mode_lines (w->vchild, force);
14963 else if (force
14964 || FRAME_GARBAGED_P (XFRAME (w->frame))
14965 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
14967 struct text_pos lpoint;
14968 struct buffer *old = current_buffer;
14970 /* Set the window's buffer for the mode line display. */
14971 SET_TEXT_POS (lpoint, PT, PT_BYTE);
14972 set_buffer_internal_1 (XBUFFER (w->buffer));
14974 /* Point refers normally to the selected window. For any
14975 other window, set up appropriate value. */
14976 if (!EQ (window, selected_window))
14978 struct text_pos pt;
14980 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
14981 if (CHARPOS (pt) < BEGV)
14982 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
14983 else if (CHARPOS (pt) > (ZV - 1))
14984 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
14985 else
14986 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
14989 /* Display mode lines. */
14990 clear_glyph_matrix (w->desired_matrix);
14991 if (display_mode_lines (w))
14993 ++nwindows;
14994 w->must_be_updated_p = 1;
14997 /* Restore old settings. */
14998 set_buffer_internal_1 (old);
14999 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
15002 window = w->next;
15005 return nwindows;
15009 /* Display the mode and/or top line of window W. Value is the number
15010 of mode lines displayed. */
15012 static int
15013 display_mode_lines (w)
15014 struct window *w;
15016 Lisp_Object old_selected_window, old_selected_frame;
15017 int n = 0;
15019 old_selected_frame = selected_frame;
15020 selected_frame = w->frame;
15021 old_selected_window = selected_window;
15022 XSETWINDOW (selected_window, w);
15024 /* These will be set while the mode line specs are processed. */
15025 line_number_displayed = 0;
15026 w->column_number_displayed = Qnil;
15028 if (WINDOW_WANTS_MODELINE_P (w))
15030 struct window *sel_w = XWINDOW (old_selected_window);
15032 /* Select mode line face based on the real selected window. */
15033 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
15034 current_buffer->mode_line_format);
15035 ++n;
15038 if (WINDOW_WANTS_HEADER_LINE_P (w))
15040 display_mode_line (w, HEADER_LINE_FACE_ID,
15041 current_buffer->header_line_format);
15042 ++n;
15045 selected_frame = old_selected_frame;
15046 selected_window = old_selected_window;
15047 return n;
15051 /* Display mode or top line of window W. FACE_ID specifies which line
15052 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
15053 FORMAT is the mode line format to display. Value is the pixel
15054 height of the mode line displayed. */
15056 static int
15057 display_mode_line (w, face_id, format)
15058 struct window *w;
15059 enum face_id face_id;
15060 Lisp_Object format;
15062 struct it it;
15063 struct face *face;
15065 init_iterator (&it, w, -1, -1, NULL, face_id);
15066 prepare_desired_row (it.glyph_row);
15068 if (! mode_line_inverse_video)
15069 /* Force the mode-line to be displayed in the default face. */
15070 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
15072 /* Temporarily make frame's keyboard the current kboard so that
15073 kboard-local variables in the mode_line_format will get the right
15074 values. */
15075 push_frame_kboard (it.f);
15076 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
15077 pop_frame_kboard ();
15079 /* Fill up with spaces. */
15080 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
15082 compute_line_metrics (&it);
15083 it.glyph_row->full_width_p = 1;
15084 it.glyph_row->mode_line_p = 1;
15085 it.glyph_row->continued_p = 0;
15086 it.glyph_row->truncated_on_left_p = 0;
15087 it.glyph_row->truncated_on_right_p = 0;
15089 /* Make a 3D mode-line have a shadow at its right end. */
15090 face = FACE_FROM_ID (it.f, face_id);
15091 extend_face_to_end_of_line (&it);
15092 if (face->box != FACE_NO_BOX)
15094 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
15095 + it.glyph_row->used[TEXT_AREA] - 1);
15096 last->right_box_line_p = 1;
15099 return it.glyph_row->height;
15102 /* Alist that caches the results of :propertize.
15103 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
15104 Lisp_Object mode_line_proptrans_alist;
15106 /* List of strings making up the mode-line. */
15107 Lisp_Object mode_line_string_list;
15109 /* Base face property when building propertized mode line string. */
15110 static Lisp_Object mode_line_string_face;
15111 static Lisp_Object mode_line_string_face_prop;
15114 /* Contribute ELT to the mode line for window IT->w. How it
15115 translates into text depends on its data type.
15117 IT describes the display environment in which we display, as usual.
15119 DEPTH is the depth in recursion. It is used to prevent
15120 infinite recursion here.
15122 FIELD_WIDTH is the number of characters the display of ELT should
15123 occupy in the mode line, and PRECISION is the maximum number of
15124 characters to display from ELT's representation. See
15125 display_string for details.
15127 Returns the hpos of the end of the text generated by ELT.
15129 PROPS is a property list to add to any string we encounter.
15131 If RISKY is nonzero, remove (disregard) any properties in any string
15132 we encounter, and ignore :eval and :propertize.
15134 If the global variable `frame_title_ptr' is non-NULL, then the output
15135 is passed to `store_frame_title' instead of `display_string'. */
15137 static int
15138 display_mode_element (it, depth, field_width, precision, elt, props, risky)
15139 struct it *it;
15140 int depth;
15141 int field_width, precision;
15142 Lisp_Object elt, props;
15143 int risky;
15145 int n = 0, field, prec;
15146 int literal = 0;
15148 tail_recurse:
15149 if (depth > 100)
15150 elt = build_string ("*too-deep*");
15152 depth++;
15154 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
15156 case Lisp_String:
15158 /* A string: output it and check for %-constructs within it. */
15159 unsigned char c;
15160 const unsigned char *this, *lisp_string;
15162 if (!NILP (props) || risky)
15164 Lisp_Object oprops, aelt;
15165 oprops = Ftext_properties_at (make_number (0), elt);
15167 if (NILP (Fequal (props, oprops)) || risky)
15169 /* If the starting string has properties,
15170 merge the specified ones onto the existing ones. */
15171 if (! NILP (oprops) && !risky)
15173 Lisp_Object tem;
15175 oprops = Fcopy_sequence (oprops);
15176 tem = props;
15177 while (CONSP (tem))
15179 oprops = Fplist_put (oprops, XCAR (tem),
15180 XCAR (XCDR (tem)));
15181 tem = XCDR (XCDR (tem));
15183 props = oprops;
15186 aelt = Fassoc (elt, mode_line_proptrans_alist);
15187 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
15189 mode_line_proptrans_alist
15190 = Fcons (aelt, Fdelq (aelt, mode_line_proptrans_alist));
15191 elt = XCAR (aelt);
15193 else
15195 Lisp_Object tem;
15197 elt = Fcopy_sequence (elt);
15198 Fset_text_properties (make_number (0), Flength (elt),
15199 props, elt);
15200 /* Add this item to mode_line_proptrans_alist. */
15201 mode_line_proptrans_alist
15202 = Fcons (Fcons (elt, props),
15203 mode_line_proptrans_alist);
15204 /* Truncate mode_line_proptrans_alist
15205 to at most 50 elements. */
15206 tem = Fnthcdr (make_number (50),
15207 mode_line_proptrans_alist);
15208 if (! NILP (tem))
15209 XSETCDR (tem, Qnil);
15214 this = SDATA (elt);
15215 lisp_string = this;
15217 if (literal)
15219 prec = precision - n;
15220 if (frame_title_ptr)
15221 n += store_frame_title (SDATA (elt), -1, prec);
15222 else if (!NILP (mode_line_string_list))
15223 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
15224 else
15225 n += display_string (NULL, elt, Qnil, 0, 0, it,
15226 0, prec, 0, STRING_MULTIBYTE (elt));
15228 break;
15231 while ((precision <= 0 || n < precision)
15232 && *this
15233 && (frame_title_ptr
15234 || !NILP (mode_line_string_list)
15235 || it->current_x < it->last_visible_x))
15237 const unsigned char *last = this;
15239 /* Advance to end of string or next format specifier. */
15240 while ((c = *this++) != '\0' && c != '%')
15243 if (this - 1 != last)
15245 /* Output to end of string or up to '%'. Field width
15246 is length of string. Don't output more than
15247 PRECISION allows us. */
15248 --this;
15250 prec = chars_in_text (last, this - last);
15251 if (precision > 0 && prec > precision - n)
15252 prec = precision - n;
15254 if (frame_title_ptr)
15255 n += store_frame_title (last, 0, prec);
15256 else if (!NILP (mode_line_string_list))
15258 int bytepos = last - lisp_string;
15259 int charpos = string_byte_to_char (elt, bytepos);
15260 n += store_mode_line_string (NULL,
15261 Fsubstring (elt, make_number (charpos),
15262 make_number (charpos + prec)),
15263 0, 0, 0, Qnil);
15265 else
15267 int bytepos = last - lisp_string;
15268 int charpos = string_byte_to_char (elt, bytepos);
15269 n += display_string (NULL, elt, Qnil, 0, charpos,
15270 it, 0, prec, 0,
15271 STRING_MULTIBYTE (elt));
15274 else /* c == '%' */
15276 const unsigned char *percent_position = this;
15278 /* Get the specified minimum width. Zero means
15279 don't pad. */
15280 field = 0;
15281 while ((c = *this++) >= '0' && c <= '9')
15282 field = field * 10 + c - '0';
15284 /* Don't pad beyond the total padding allowed. */
15285 if (field_width - n > 0 && field > field_width - n)
15286 field = field_width - n;
15288 /* Note that either PRECISION <= 0 or N < PRECISION. */
15289 prec = precision - n;
15291 if (c == 'M')
15292 n += display_mode_element (it, depth, field, prec,
15293 Vglobal_mode_string, props,
15294 risky);
15295 else if (c != 0)
15297 int multibyte;
15298 int bytepos, charpos;
15299 unsigned char *spec;
15301 bytepos = percent_position - lisp_string;
15302 charpos = (STRING_MULTIBYTE (elt)
15303 ? string_byte_to_char (elt, bytepos)
15304 : bytepos);
15306 spec
15307 = decode_mode_spec (it->w, c, field, prec, &multibyte);
15309 if (frame_title_ptr)
15310 n += store_frame_title (spec, field, prec);
15311 else if (!NILP (mode_line_string_list))
15313 int len = strlen (spec);
15314 Lisp_Object tem = make_string (spec, len);
15315 props = Ftext_properties_at (make_number (charpos), elt);
15316 /* Should only keep face property in props */
15317 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
15319 else
15321 int nglyphs_before, nwritten;
15323 nglyphs_before = it->glyph_row->used[TEXT_AREA];
15324 nwritten = display_string (spec, Qnil, elt,
15325 charpos, 0, it,
15326 field, prec, 0,
15327 multibyte);
15329 /* Assign to the glyphs written above the
15330 string where the `%x' came from, position
15331 of the `%'. */
15332 if (nwritten > 0)
15334 struct glyph *glyph
15335 = (it->glyph_row->glyphs[TEXT_AREA]
15336 + nglyphs_before);
15337 int i;
15339 for (i = 0; i < nwritten; ++i)
15341 glyph[i].object = elt;
15342 glyph[i].charpos = charpos;
15345 n += nwritten;
15349 else /* c == 0 */
15350 break;
15354 break;
15356 case Lisp_Symbol:
15357 /* A symbol: process the value of the symbol recursively
15358 as if it appeared here directly. Avoid error if symbol void.
15359 Special case: if value of symbol is a string, output the string
15360 literally. */
15362 register Lisp_Object tem;
15364 /* If the variable is not marked as risky to set
15365 then its contents are risky to use. */
15366 if (NILP (Fget (elt, Qrisky_local_variable)))
15367 risky = 1;
15369 tem = Fboundp (elt);
15370 if (!NILP (tem))
15372 tem = Fsymbol_value (elt);
15373 /* If value is a string, output that string literally:
15374 don't check for % within it. */
15375 if (STRINGP (tem))
15376 literal = 1;
15378 if (!EQ (tem, elt))
15380 /* Give up right away for nil or t. */
15381 elt = tem;
15382 goto tail_recurse;
15386 break;
15388 case Lisp_Cons:
15390 register Lisp_Object car, tem;
15392 /* A cons cell: five distinct cases.
15393 If first element is :eval or :propertize, do something special.
15394 If first element is a string or a cons, process all the elements
15395 and effectively concatenate them.
15396 If first element is a negative number, truncate displaying cdr to
15397 at most that many characters. If positive, pad (with spaces)
15398 to at least that many characters.
15399 If first element is a symbol, process the cadr or caddr recursively
15400 according to whether the symbol's value is non-nil or nil. */
15401 car = XCAR (elt);
15402 if (EQ (car, QCeval))
15404 /* An element of the form (:eval FORM) means evaluate FORM
15405 and use the result as mode line elements. */
15407 if (risky)
15408 break;
15410 if (CONSP (XCDR (elt)))
15412 Lisp_Object spec;
15413 spec = safe_eval (XCAR (XCDR (elt)));
15414 n += display_mode_element (it, depth, field_width - n,
15415 precision - n, spec, props,
15416 risky);
15419 else if (EQ (car, QCpropertize))
15421 /* An element of the form (:propertize ELT PROPS...)
15422 means display ELT but applying properties PROPS. */
15424 if (risky)
15425 break;
15427 if (CONSP (XCDR (elt)))
15428 n += display_mode_element (it, depth, field_width - n,
15429 precision - n, XCAR (XCDR (elt)),
15430 XCDR (XCDR (elt)), risky);
15432 else if (SYMBOLP (car))
15434 tem = Fboundp (car);
15435 elt = XCDR (elt);
15436 if (!CONSP (elt))
15437 goto invalid;
15438 /* elt is now the cdr, and we know it is a cons cell.
15439 Use its car if CAR has a non-nil value. */
15440 if (!NILP (tem))
15442 tem = Fsymbol_value (car);
15443 if (!NILP (tem))
15445 elt = XCAR (elt);
15446 goto tail_recurse;
15449 /* Symbol's value is nil (or symbol is unbound)
15450 Get the cddr of the original list
15451 and if possible find the caddr and use that. */
15452 elt = XCDR (elt);
15453 if (NILP (elt))
15454 break;
15455 else if (!CONSP (elt))
15456 goto invalid;
15457 elt = XCAR (elt);
15458 goto tail_recurse;
15460 else if (INTEGERP (car))
15462 register int lim = XINT (car);
15463 elt = XCDR (elt);
15464 if (lim < 0)
15466 /* Negative int means reduce maximum width. */
15467 if (precision <= 0)
15468 precision = -lim;
15469 else
15470 precision = min (precision, -lim);
15472 else if (lim > 0)
15474 /* Padding specified. Don't let it be more than
15475 current maximum. */
15476 if (precision > 0)
15477 lim = min (precision, lim);
15479 /* If that's more padding than already wanted, queue it.
15480 But don't reduce padding already specified even if
15481 that is beyond the current truncation point. */
15482 field_width = max (lim, field_width);
15484 goto tail_recurse;
15486 else if (STRINGP (car) || CONSP (car))
15488 register int limit = 50;
15489 /* Limit is to protect against circular lists. */
15490 while (CONSP (elt)
15491 && --limit > 0
15492 && (precision <= 0 || n < precision))
15494 n += display_mode_element (it, depth, field_width - n,
15495 precision - n, XCAR (elt),
15496 props, risky);
15497 elt = XCDR (elt);
15501 break;
15503 default:
15504 invalid:
15505 elt = build_string ("*invalid*");
15506 goto tail_recurse;
15509 /* Pad to FIELD_WIDTH. */
15510 if (field_width > 0 && n < field_width)
15512 if (frame_title_ptr)
15513 n += store_frame_title ("", field_width - n, 0);
15514 else if (!NILP (mode_line_string_list))
15515 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
15516 else
15517 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
15518 0, 0, 0);
15521 return n;
15524 /* Store a mode-line string element in mode_line_string_list.
15526 If STRING is non-null, display that C string. Otherwise, the Lisp
15527 string LISP_STRING is displayed.
15529 FIELD_WIDTH is the minimum number of output glyphs to produce.
15530 If STRING has fewer characters than FIELD_WIDTH, pad to the right
15531 with spaces. FIELD_WIDTH <= 0 means don't pad.
15533 PRECISION is the maximum number of characters to output from
15534 STRING. PRECISION <= 0 means don't truncate the string.
15536 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
15537 properties to the string.
15539 PROPS are the properties to add to the string.
15540 The mode_line_string_face face property is always added to the string.
15543 static int store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
15544 char *string;
15545 Lisp_Object lisp_string;
15546 int copy_string;
15547 int field_width;
15548 int precision;
15549 Lisp_Object props;
15551 int len;
15552 int n = 0;
15554 if (string != NULL)
15556 len = strlen (string);
15557 if (precision > 0 && len > precision)
15558 len = precision;
15559 lisp_string = make_string (string, len);
15560 if (NILP (props))
15561 props = mode_line_string_face_prop;
15562 else if (!NILP (mode_line_string_face))
15564 Lisp_Object face = Fplist_get (props, Qface);
15565 props = Fcopy_sequence (props);
15566 if (NILP (face))
15567 face = mode_line_string_face;
15568 else
15569 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15570 props = Fplist_put (props, Qface, face);
15572 Fadd_text_properties (make_number (0), make_number (len),
15573 props, lisp_string);
15575 else
15577 len = XFASTINT (Flength (lisp_string));
15578 if (precision > 0 && len > precision)
15580 len = precision;
15581 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
15582 precision = -1;
15584 if (!NILP (mode_line_string_face))
15586 Lisp_Object face;
15587 if (NILP (props))
15588 props = Ftext_properties_at (make_number (0), lisp_string);
15589 face = Fplist_get (props, Qface);
15590 if (NILP (face))
15591 face = mode_line_string_face;
15592 else
15593 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15594 props = Fcons (Qface, Fcons (face, Qnil));
15595 if (copy_string)
15596 lisp_string = Fcopy_sequence (lisp_string);
15598 if (!NILP (props))
15599 Fadd_text_properties (make_number (0), make_number (len),
15600 props, lisp_string);
15603 if (len > 0)
15605 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15606 n += len;
15609 if (field_width > len)
15611 field_width -= len;
15612 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
15613 if (!NILP (props))
15614 Fadd_text_properties (make_number (0), make_number (field_width),
15615 props, lisp_string);
15616 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15617 n += field_width;
15620 return n;
15624 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
15625 0, 3, 0,
15626 doc: /* Return the mode-line of selected window as a string.
15627 First optional arg FORMAT specifies a different format string (see
15628 `mode-line-format' for details) to use. If FORMAT is t, return
15629 the buffer's header-line. Second optional arg WINDOW specifies a
15630 different window to use as the context for the formatting.
15631 If third optional arg NO-PROPS is non-nil, string is not propertized. */)
15632 (format, window, no_props)
15633 Lisp_Object format, window, no_props;
15635 struct it it;
15636 int len;
15637 struct window *w;
15638 struct buffer *old_buffer = NULL;
15639 enum face_id face_id = DEFAULT_FACE_ID;
15641 if (NILP (window))
15642 window = selected_window;
15643 CHECK_WINDOW (window);
15644 w = XWINDOW (window);
15645 CHECK_BUFFER (w->buffer);
15647 if (XBUFFER (w->buffer) != current_buffer)
15649 old_buffer = current_buffer;
15650 set_buffer_internal_1 (XBUFFER (w->buffer));
15653 if (NILP (format) || EQ (format, Qt))
15655 face_id = NILP (format)
15656 ? CURRENT_MODE_LINE_FACE_ID (w) :
15657 HEADER_LINE_FACE_ID;
15658 format = NILP (format)
15659 ? current_buffer->mode_line_format
15660 : current_buffer->header_line_format;
15663 init_iterator (&it, w, -1, -1, NULL, face_id);
15665 if (NILP (no_props))
15667 mode_line_string_face =
15668 (face_id == MODE_LINE_FACE_ID ? Qmode_line :
15669 face_id == MODE_LINE_INACTIVE_FACE_ID ? Qmode_line_inactive :
15670 face_id == HEADER_LINE_FACE_ID ? Qheader_line : Qnil);
15672 mode_line_string_face_prop =
15673 NILP (mode_line_string_face) ? Qnil :
15674 Fcons (Qface, Fcons (mode_line_string_face, Qnil));
15676 /* We need a dummy last element in mode_line_string_list to
15677 indicate we are building the propertized mode-line string.
15678 Using mode_line_string_face_prop here GC protects it. */
15679 mode_line_string_list =
15680 Fcons (mode_line_string_face_prop, Qnil);
15681 frame_title_ptr = NULL;
15683 else
15685 mode_line_string_face_prop = Qnil;
15686 mode_line_string_list = Qnil;
15687 frame_title_ptr = frame_title_buf;
15690 push_frame_kboard (it.f);
15691 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
15692 pop_frame_kboard ();
15694 if (old_buffer)
15695 set_buffer_internal_1 (old_buffer);
15697 if (NILP (no_props))
15699 Lisp_Object str;
15700 mode_line_string_list = Fnreverse (mode_line_string_list);
15701 str = Fmapconcat (intern ("identity"), XCDR (mode_line_string_list),
15702 make_string ("", 0));
15703 mode_line_string_face_prop = Qnil;
15704 mode_line_string_list = Qnil;
15705 return str;
15708 len = frame_title_ptr - frame_title_buf;
15709 if (len > 0 && frame_title_ptr[-1] == '-')
15711 /* Mode lines typically ends with numerous dashes; reduce to two dashes. */
15712 while (frame_title_ptr > frame_title_buf && *--frame_title_ptr == '-')
15714 frame_title_ptr += 3; /* restore last non-dash + two dashes */
15715 if (len > frame_title_ptr - frame_title_buf)
15716 len = frame_title_ptr - frame_title_buf;
15719 frame_title_ptr = NULL;
15720 return make_string (frame_title_buf, len);
15723 /* Write a null-terminated, right justified decimal representation of
15724 the positive integer D to BUF using a minimal field width WIDTH. */
15726 static void
15727 pint2str (buf, width, d)
15728 register char *buf;
15729 register int width;
15730 register int d;
15732 register char *p = buf;
15734 if (d <= 0)
15735 *p++ = '0';
15736 else
15738 while (d > 0)
15740 *p++ = d % 10 + '0';
15741 d /= 10;
15745 for (width -= (int) (p - buf); width > 0; --width)
15746 *p++ = ' ';
15747 *p-- = '\0';
15748 while (p > buf)
15750 d = *buf;
15751 *buf++ = *p;
15752 *p-- = d;
15756 /* Write a null-terminated, right justified decimal and "human
15757 readable" representation of the nonnegative integer D to BUF using
15758 a minimal field width WIDTH. D should be smaller than 999.5e24. */
15760 static const char power_letter[] =
15762 0, /* not used */
15763 'k', /* kilo */
15764 'M', /* mega */
15765 'G', /* giga */
15766 'T', /* tera */
15767 'P', /* peta */
15768 'E', /* exa */
15769 'Z', /* zetta */
15770 'Y' /* yotta */
15773 static void
15774 pint2hrstr (buf, width, d)
15775 char *buf;
15776 int width;
15777 int d;
15779 /* We aim to represent the nonnegative integer D as
15780 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
15781 int quotient = d;
15782 int remainder = 0;
15783 /* -1 means: do not use TENTHS. */
15784 int tenths = -1;
15785 int exponent = 0;
15787 /* Length of QUOTIENT.TENTHS as a string. */
15788 int length;
15790 char * psuffix;
15791 char * p;
15793 if (1000 <= quotient)
15795 /* Scale to the appropriate EXPONENT. */
15798 remainder = quotient % 1000;
15799 quotient /= 1000;
15800 exponent++;
15802 while (1000 <= quotient);
15804 /* Round to nearest and decide whether to use TENTHS or not. */
15805 if (quotient <= 9)
15807 tenths = remainder / 100;
15808 if (50 <= remainder % 100)
15809 if (tenths < 9)
15810 tenths++;
15811 else
15813 quotient++;
15814 if (quotient == 10)
15815 tenths = -1;
15816 else
15817 tenths = 0;
15820 else
15821 if (500 <= remainder)
15822 if (quotient < 999)
15823 quotient++;
15824 else
15826 quotient = 1;
15827 exponent++;
15828 tenths = 0;
15832 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
15833 if (tenths == -1 && quotient <= 99)
15834 if (quotient <= 9)
15835 length = 1;
15836 else
15837 length = 2;
15838 else
15839 length = 3;
15840 p = psuffix = buf + max (width, length);
15842 /* Print EXPONENT. */
15843 if (exponent)
15844 *psuffix++ = power_letter[exponent];
15845 *psuffix = '\0';
15847 /* Print TENTHS. */
15848 if (tenths >= 0)
15850 *--p = '0' + tenths;
15851 *--p = '.';
15854 /* Print QUOTIENT. */
15857 int digit = quotient % 10;
15858 *--p = '0' + digit;
15860 while ((quotient /= 10) != 0);
15862 /* Print leading spaces. */
15863 while (buf < p)
15864 *--p = ' ';
15867 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
15868 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
15869 type of CODING_SYSTEM. Return updated pointer into BUF. */
15871 static unsigned char invalid_eol_type[] = "(*invalid*)";
15873 static char *
15874 decode_mode_spec_coding (coding_system, buf, eol_flag)
15875 Lisp_Object coding_system;
15876 register char *buf;
15877 int eol_flag;
15879 Lisp_Object val;
15880 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
15881 const unsigned char *eol_str;
15882 int eol_str_len;
15883 /* The EOL conversion we are using. */
15884 Lisp_Object eoltype;
15886 val = Fget (coding_system, Qcoding_system);
15887 eoltype = Qnil;
15889 if (!VECTORP (val)) /* Not yet decided. */
15891 if (multibyte)
15892 *buf++ = '-';
15893 if (eol_flag)
15894 eoltype = eol_mnemonic_undecided;
15895 /* Don't mention EOL conversion if it isn't decided. */
15897 else
15899 Lisp_Object eolvalue;
15901 eolvalue = Fget (coding_system, Qeol_type);
15903 if (multibyte)
15904 *buf++ = XFASTINT (AREF (val, 1));
15906 if (eol_flag)
15908 /* The EOL conversion that is normal on this system. */
15910 if (NILP (eolvalue)) /* Not yet decided. */
15911 eoltype = eol_mnemonic_undecided;
15912 else if (VECTORP (eolvalue)) /* Not yet decided. */
15913 eoltype = eol_mnemonic_undecided;
15914 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
15915 eoltype = (XFASTINT (eolvalue) == 0
15916 ? eol_mnemonic_unix
15917 : (XFASTINT (eolvalue) == 1
15918 ? eol_mnemonic_dos : eol_mnemonic_mac));
15922 if (eol_flag)
15924 /* Mention the EOL conversion if it is not the usual one. */
15925 if (STRINGP (eoltype))
15927 eol_str = SDATA (eoltype);
15928 eol_str_len = SBYTES (eoltype);
15930 else if (INTEGERP (eoltype)
15931 && CHAR_VALID_P (XINT (eoltype), 0))
15933 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
15934 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
15935 eol_str = tmp;
15937 else
15939 eol_str = invalid_eol_type;
15940 eol_str_len = sizeof (invalid_eol_type) - 1;
15942 bcopy (eol_str, buf, eol_str_len);
15943 buf += eol_str_len;
15946 return buf;
15949 /* Return a string for the output of a mode line %-spec for window W,
15950 generated by character C. PRECISION >= 0 means don't return a
15951 string longer than that value. FIELD_WIDTH > 0 means pad the
15952 string returned with spaces to that value. Return 1 in *MULTIBYTE
15953 if the result is multibyte text. */
15955 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
15957 static char *
15958 decode_mode_spec (w, c, field_width, precision, multibyte)
15959 struct window *w;
15960 register int c;
15961 int field_width, precision;
15962 int *multibyte;
15964 Lisp_Object obj;
15965 struct frame *f = XFRAME (WINDOW_FRAME (w));
15966 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
15967 struct buffer *b = XBUFFER (w->buffer);
15969 obj = Qnil;
15970 *multibyte = 0;
15972 switch (c)
15974 case '*':
15975 if (!NILP (b->read_only))
15976 return "%";
15977 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
15978 return "*";
15979 return "-";
15981 case '+':
15982 /* This differs from %* only for a modified read-only buffer. */
15983 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
15984 return "*";
15985 if (!NILP (b->read_only))
15986 return "%";
15987 return "-";
15989 case '&':
15990 /* This differs from %* in ignoring read-only-ness. */
15991 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
15992 return "*";
15993 return "-";
15995 case '%':
15996 return "%";
15998 case '[':
16000 int i;
16001 char *p;
16003 if (command_loop_level > 5)
16004 return "[[[... ";
16005 p = decode_mode_spec_buf;
16006 for (i = 0; i < command_loop_level; i++)
16007 *p++ = '[';
16008 *p = 0;
16009 return decode_mode_spec_buf;
16012 case ']':
16014 int i;
16015 char *p;
16017 if (command_loop_level > 5)
16018 return " ...]]]";
16019 p = decode_mode_spec_buf;
16020 for (i = 0; i < command_loop_level; i++)
16021 *p++ = ']';
16022 *p = 0;
16023 return decode_mode_spec_buf;
16026 case '-':
16028 register int i;
16030 /* Let lots_of_dashes be a string of infinite length. */
16031 if (!NILP (mode_line_string_list))
16032 return "--";
16033 if (field_width <= 0
16034 || field_width > sizeof (lots_of_dashes))
16036 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
16037 decode_mode_spec_buf[i] = '-';
16038 decode_mode_spec_buf[i] = '\0';
16039 return decode_mode_spec_buf;
16041 else
16042 return lots_of_dashes;
16045 case 'b':
16046 obj = b->name;
16047 break;
16049 case 'c':
16051 int col = (int) current_column (); /* iftc */
16052 w->column_number_displayed = make_number (col);
16053 pint2str (decode_mode_spec_buf, field_width, col);
16054 return decode_mode_spec_buf;
16057 case 'F':
16058 /* %F displays the frame name. */
16059 if (!NILP (f->title))
16060 return (char *) SDATA (f->title);
16061 if (f->explicit_name || ! FRAME_WINDOW_P (f))
16062 return (char *) SDATA (f->name);
16063 return "Emacs";
16065 case 'f':
16066 obj = b->filename;
16067 break;
16069 case 'i':
16071 int size = ZV - BEGV;
16072 pint2str (decode_mode_spec_buf, field_width, size);
16073 return decode_mode_spec_buf;
16076 case 'I':
16078 int size = ZV - BEGV;
16079 pint2hrstr (decode_mode_spec_buf, field_width, size);
16080 return decode_mode_spec_buf;
16083 case 'l':
16085 int startpos = XMARKER (w->start)->charpos;
16086 int startpos_byte = marker_byte_position (w->start);
16087 int line, linepos, linepos_byte, topline;
16088 int nlines, junk;
16089 int height = WINDOW_TOTAL_LINES (w);
16091 /* If we decided that this buffer isn't suitable for line numbers,
16092 don't forget that too fast. */
16093 if (EQ (w->base_line_pos, w->buffer))
16094 goto no_value;
16095 /* But do forget it, if the window shows a different buffer now. */
16096 else if (BUFFERP (w->base_line_pos))
16097 w->base_line_pos = Qnil;
16099 /* If the buffer is very big, don't waste time. */
16100 if (INTEGERP (Vline_number_display_limit)
16101 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
16103 w->base_line_pos = Qnil;
16104 w->base_line_number = Qnil;
16105 goto no_value;
16108 if (!NILP (w->base_line_number)
16109 && !NILP (w->base_line_pos)
16110 && XFASTINT (w->base_line_pos) <= startpos)
16112 line = XFASTINT (w->base_line_number);
16113 linepos = XFASTINT (w->base_line_pos);
16114 linepos_byte = buf_charpos_to_bytepos (b, linepos);
16116 else
16118 line = 1;
16119 linepos = BUF_BEGV (b);
16120 linepos_byte = BUF_BEGV_BYTE (b);
16123 /* Count lines from base line to window start position. */
16124 nlines = display_count_lines (linepos, linepos_byte,
16125 startpos_byte,
16126 startpos, &junk);
16128 topline = nlines + line;
16130 /* Determine a new base line, if the old one is too close
16131 or too far away, or if we did not have one.
16132 "Too close" means it's plausible a scroll-down would
16133 go back past it. */
16134 if (startpos == BUF_BEGV (b))
16136 w->base_line_number = make_number (topline);
16137 w->base_line_pos = make_number (BUF_BEGV (b));
16139 else if (nlines < height + 25 || nlines > height * 3 + 50
16140 || linepos == BUF_BEGV (b))
16142 int limit = BUF_BEGV (b);
16143 int limit_byte = BUF_BEGV_BYTE (b);
16144 int position;
16145 int distance = (height * 2 + 30) * line_number_display_limit_width;
16147 if (startpos - distance > limit)
16149 limit = startpos - distance;
16150 limit_byte = CHAR_TO_BYTE (limit);
16153 nlines = display_count_lines (startpos, startpos_byte,
16154 limit_byte,
16155 - (height * 2 + 30),
16156 &position);
16157 /* If we couldn't find the lines we wanted within
16158 line_number_display_limit_width chars per line,
16159 give up on line numbers for this window. */
16160 if (position == limit_byte && limit == startpos - distance)
16162 w->base_line_pos = w->buffer;
16163 w->base_line_number = Qnil;
16164 goto no_value;
16167 w->base_line_number = make_number (topline - nlines);
16168 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
16171 /* Now count lines from the start pos to point. */
16172 nlines = display_count_lines (startpos, startpos_byte,
16173 PT_BYTE, PT, &junk);
16175 /* Record that we did display the line number. */
16176 line_number_displayed = 1;
16178 /* Make the string to show. */
16179 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
16180 return decode_mode_spec_buf;
16181 no_value:
16183 char* p = decode_mode_spec_buf;
16184 int pad = field_width - 2;
16185 while (pad-- > 0)
16186 *p++ = ' ';
16187 *p++ = '?';
16188 *p++ = '?';
16189 *p = '\0';
16190 return decode_mode_spec_buf;
16193 break;
16195 case 'm':
16196 obj = b->mode_name;
16197 break;
16199 case 'n':
16200 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
16201 return " Narrow";
16202 break;
16204 case 'p':
16206 int pos = marker_position (w->start);
16207 int total = BUF_ZV (b) - BUF_BEGV (b);
16209 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
16211 if (pos <= BUF_BEGV (b))
16212 return "All";
16213 else
16214 return "Bottom";
16216 else if (pos <= BUF_BEGV (b))
16217 return "Top";
16218 else
16220 if (total > 1000000)
16221 /* Do it differently for a large value, to avoid overflow. */
16222 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16223 else
16224 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
16225 /* We can't normally display a 3-digit number,
16226 so get us a 2-digit number that is close. */
16227 if (total == 100)
16228 total = 99;
16229 sprintf (decode_mode_spec_buf, "%2d%%", total);
16230 return decode_mode_spec_buf;
16234 /* Display percentage of size above the bottom of the screen. */
16235 case 'P':
16237 int toppos = marker_position (w->start);
16238 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
16239 int total = BUF_ZV (b) - BUF_BEGV (b);
16241 if (botpos >= BUF_ZV (b))
16243 if (toppos <= BUF_BEGV (b))
16244 return "All";
16245 else
16246 return "Bottom";
16248 else
16250 if (total > 1000000)
16251 /* Do it differently for a large value, to avoid overflow. */
16252 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16253 else
16254 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
16255 /* We can't normally display a 3-digit number,
16256 so get us a 2-digit number that is close. */
16257 if (total == 100)
16258 total = 99;
16259 if (toppos <= BUF_BEGV (b))
16260 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
16261 else
16262 sprintf (decode_mode_spec_buf, "%2d%%", total);
16263 return decode_mode_spec_buf;
16267 case 's':
16268 /* status of process */
16269 obj = Fget_buffer_process (w->buffer);
16270 if (NILP (obj))
16271 return "no process";
16272 #ifdef subprocesses
16273 obj = Fsymbol_name (Fprocess_status (obj));
16274 #endif
16275 break;
16277 case 't': /* indicate TEXT or BINARY */
16278 #ifdef MODE_LINE_BINARY_TEXT
16279 return MODE_LINE_BINARY_TEXT (b);
16280 #else
16281 return "T";
16282 #endif
16284 case 'z':
16285 /* coding-system (not including end-of-line format) */
16286 case 'Z':
16287 /* coding-system (including end-of-line type) */
16289 int eol_flag = (c == 'Z');
16290 char *p = decode_mode_spec_buf;
16292 if (! FRAME_WINDOW_P (f))
16294 /* No need to mention EOL here--the terminal never needs
16295 to do EOL conversion. */
16296 p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
16297 p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
16299 p = decode_mode_spec_coding (b->buffer_file_coding_system,
16300 p, eol_flag);
16302 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
16303 #ifdef subprocesses
16304 obj = Fget_buffer_process (Fcurrent_buffer ());
16305 if (PROCESSP (obj))
16307 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
16308 p, eol_flag);
16309 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
16310 p, eol_flag);
16312 #endif /* subprocesses */
16313 #endif /* 0 */
16314 *p = 0;
16315 return decode_mode_spec_buf;
16319 if (STRINGP (obj))
16321 *multibyte = STRING_MULTIBYTE (obj);
16322 return (char *) SDATA (obj);
16324 else
16325 return "";
16329 /* Count up to COUNT lines starting from START / START_BYTE.
16330 But don't go beyond LIMIT_BYTE.
16331 Return the number of lines thus found (always nonnegative).
16333 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
16335 static int
16336 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
16337 int start, start_byte, limit_byte, count;
16338 int *byte_pos_ptr;
16340 register unsigned char *cursor;
16341 unsigned char *base;
16343 register int ceiling;
16344 register unsigned char *ceiling_addr;
16345 int orig_count = count;
16347 /* If we are not in selective display mode,
16348 check only for newlines. */
16349 int selective_display = (!NILP (current_buffer->selective_display)
16350 && !INTEGERP (current_buffer->selective_display));
16352 if (count > 0)
16354 while (start_byte < limit_byte)
16356 ceiling = BUFFER_CEILING_OF (start_byte);
16357 ceiling = min (limit_byte - 1, ceiling);
16358 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
16359 base = (cursor = BYTE_POS_ADDR (start_byte));
16360 while (1)
16362 if (selective_display)
16363 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
16365 else
16366 while (*cursor != '\n' && ++cursor != ceiling_addr)
16369 if (cursor != ceiling_addr)
16371 if (--count == 0)
16373 start_byte += cursor - base + 1;
16374 *byte_pos_ptr = start_byte;
16375 return orig_count;
16377 else
16378 if (++cursor == ceiling_addr)
16379 break;
16381 else
16382 break;
16384 start_byte += cursor - base;
16387 else
16389 while (start_byte > limit_byte)
16391 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
16392 ceiling = max (limit_byte, ceiling);
16393 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
16394 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
16395 while (1)
16397 if (selective_display)
16398 while (--cursor != ceiling_addr
16399 && *cursor != '\n' && *cursor != 015)
16401 else
16402 while (--cursor != ceiling_addr && *cursor != '\n')
16405 if (cursor != ceiling_addr)
16407 if (++count == 0)
16409 start_byte += cursor - base + 1;
16410 *byte_pos_ptr = start_byte;
16411 /* When scanning backwards, we should
16412 not count the newline posterior to which we stop. */
16413 return - orig_count - 1;
16416 else
16417 break;
16419 /* Here we add 1 to compensate for the last decrement
16420 of CURSOR, which took it past the valid range. */
16421 start_byte += cursor - base + 1;
16425 *byte_pos_ptr = limit_byte;
16427 if (count < 0)
16428 return - orig_count + count;
16429 return orig_count - count;
16435 /***********************************************************************
16436 Displaying strings
16437 ***********************************************************************/
16439 /* Display a NUL-terminated string, starting with index START.
16441 If STRING is non-null, display that C string. Otherwise, the Lisp
16442 string LISP_STRING is displayed.
16444 If FACE_STRING is not nil, FACE_STRING_POS is a position in
16445 FACE_STRING. Display STRING or LISP_STRING with the face at
16446 FACE_STRING_POS in FACE_STRING:
16448 Display the string in the environment given by IT, but use the
16449 standard display table, temporarily.
16451 FIELD_WIDTH is the minimum number of output glyphs to produce.
16452 If STRING has fewer characters than FIELD_WIDTH, pad to the right
16453 with spaces. If STRING has more characters, more than FIELD_WIDTH
16454 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
16456 PRECISION is the maximum number of characters to output from
16457 STRING. PRECISION < 0 means don't truncate the string.
16459 This is roughly equivalent to printf format specifiers:
16461 FIELD_WIDTH PRECISION PRINTF
16462 ----------------------------------------
16463 -1 -1 %s
16464 -1 10 %.10s
16465 10 -1 %10s
16466 20 10 %20.10s
16468 MULTIBYTE zero means do not display multibyte chars, > 0 means do
16469 display them, and < 0 means obey the current buffer's value of
16470 enable_multibyte_characters.
16472 Value is the number of glyphs produced. */
16474 static int
16475 display_string (string, lisp_string, face_string, face_string_pos,
16476 start, it, field_width, precision, max_x, multibyte)
16477 unsigned char *string;
16478 Lisp_Object lisp_string;
16479 Lisp_Object face_string;
16480 int face_string_pos;
16481 int start;
16482 struct it *it;
16483 int field_width, precision, max_x;
16484 int multibyte;
16486 int hpos_at_start = it->hpos;
16487 int saved_face_id = it->face_id;
16488 struct glyph_row *row = it->glyph_row;
16490 /* Initialize the iterator IT for iteration over STRING beginning
16491 with index START. */
16492 reseat_to_string (it, string, lisp_string, start,
16493 precision, field_width, multibyte);
16495 /* If displaying STRING, set up the face of the iterator
16496 from LISP_STRING, if that's given. */
16497 if (STRINGP (face_string))
16499 int endptr;
16500 struct face *face;
16502 it->face_id
16503 = face_at_string_position (it->w, face_string, face_string_pos,
16504 0, it->region_beg_charpos,
16505 it->region_end_charpos,
16506 &endptr, it->base_face_id, 0);
16507 face = FACE_FROM_ID (it->f, it->face_id);
16508 it->face_box_p = face->box != FACE_NO_BOX;
16511 /* Set max_x to the maximum allowed X position. Don't let it go
16512 beyond the right edge of the window. */
16513 if (max_x <= 0)
16514 max_x = it->last_visible_x;
16515 else
16516 max_x = min (max_x, it->last_visible_x);
16518 /* Skip over display elements that are not visible. because IT->w is
16519 hscrolled. */
16520 if (it->current_x < it->first_visible_x)
16521 move_it_in_display_line_to (it, 100000, it->first_visible_x,
16522 MOVE_TO_POS | MOVE_TO_X);
16524 row->ascent = it->max_ascent;
16525 row->height = it->max_ascent + it->max_descent;
16526 row->phys_ascent = it->max_phys_ascent;
16527 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
16529 /* This condition is for the case that we are called with current_x
16530 past last_visible_x. */
16531 while (it->current_x < max_x)
16533 int x_before, x, n_glyphs_before, i, nglyphs;
16535 /* Get the next display element. */
16536 if (!get_next_display_element (it))
16537 break;
16539 /* Produce glyphs. */
16540 x_before = it->current_x;
16541 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
16542 PRODUCE_GLYPHS (it);
16544 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
16545 i = 0;
16546 x = x_before;
16547 while (i < nglyphs)
16549 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
16551 if (!it->truncate_lines_p
16552 && x + glyph->pixel_width > max_x)
16554 /* End of continued line or max_x reached. */
16555 if (CHAR_GLYPH_PADDING_P (*glyph))
16557 /* A wide character is unbreakable. */
16558 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
16559 it->current_x = x_before;
16561 else
16563 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
16564 it->current_x = x;
16566 break;
16568 else if (x + glyph->pixel_width > it->first_visible_x)
16570 /* Glyph is at least partially visible. */
16571 ++it->hpos;
16572 if (x < it->first_visible_x)
16573 it->glyph_row->x = x - it->first_visible_x;
16575 else
16577 /* Glyph is off the left margin of the display area.
16578 Should not happen. */
16579 abort ();
16582 row->ascent = max (row->ascent, it->max_ascent);
16583 row->height = max (row->height, it->max_ascent + it->max_descent);
16584 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16585 row->phys_height = max (row->phys_height,
16586 it->max_phys_ascent + it->max_phys_descent);
16587 x += glyph->pixel_width;
16588 ++i;
16591 /* Stop if max_x reached. */
16592 if (i < nglyphs)
16593 break;
16595 /* Stop at line ends. */
16596 if (ITERATOR_AT_END_OF_LINE_P (it))
16598 it->continuation_lines_width = 0;
16599 break;
16602 set_iterator_to_next (it, 1);
16604 /* Stop if truncating at the right edge. */
16605 if (it->truncate_lines_p
16606 && it->current_x >= it->last_visible_x)
16608 /* Add truncation mark, but don't do it if the line is
16609 truncated at a padding space. */
16610 if (IT_CHARPOS (*it) < it->string_nchars)
16612 if (!FRAME_WINDOW_P (it->f))
16614 int i, n;
16616 if (it->current_x > it->last_visible_x)
16618 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
16619 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
16620 break;
16621 for (n = row->used[TEXT_AREA]; i < n; ++i)
16623 row->used[TEXT_AREA] = i;
16624 produce_special_glyphs (it, IT_TRUNCATION);
16627 produce_special_glyphs (it, IT_TRUNCATION);
16629 it->glyph_row->truncated_on_right_p = 1;
16631 break;
16635 /* Maybe insert a truncation at the left. */
16636 if (it->first_visible_x
16637 && IT_CHARPOS (*it) > 0)
16639 if (!FRAME_WINDOW_P (it->f))
16640 insert_left_trunc_glyphs (it);
16641 it->glyph_row->truncated_on_left_p = 1;
16644 it->face_id = saved_face_id;
16646 /* Value is number of columns displayed. */
16647 return it->hpos - hpos_at_start;
16652 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
16653 appears as an element of LIST or as the car of an element of LIST.
16654 If PROPVAL is a list, compare each element against LIST in that
16655 way, and return 1/2 if any element of PROPVAL is found in LIST.
16656 Otherwise return 0. This function cannot quit.
16657 The return value is 2 if the text is invisible but with an ellipsis
16658 and 1 if it's invisible and without an ellipsis. */
16661 invisible_p (propval, list)
16662 register Lisp_Object propval;
16663 Lisp_Object list;
16665 register Lisp_Object tail, proptail;
16667 for (tail = list; CONSP (tail); tail = XCDR (tail))
16669 register Lisp_Object tem;
16670 tem = XCAR (tail);
16671 if (EQ (propval, tem))
16672 return 1;
16673 if (CONSP (tem) && EQ (propval, XCAR (tem)))
16674 return NILP (XCDR (tem)) ? 1 : 2;
16677 if (CONSP (propval))
16679 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
16681 Lisp_Object propelt;
16682 propelt = XCAR (proptail);
16683 for (tail = list; CONSP (tail); tail = XCDR (tail))
16685 register Lisp_Object tem;
16686 tem = XCAR (tail);
16687 if (EQ (propelt, tem))
16688 return 1;
16689 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
16690 return NILP (XCDR (tem)) ? 1 : 2;
16695 return 0;
16699 /***********************************************************************
16700 Glyph Display
16701 ***********************************************************************/
16703 #ifdef HAVE_WINDOW_SYSTEM
16705 #if GLYPH_DEBUG
16707 void
16708 dump_glyph_string (s)
16709 struct glyph_string *s;
16711 fprintf (stderr, "glyph string\n");
16712 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
16713 s->x, s->y, s->width, s->height);
16714 fprintf (stderr, " ybase = %d\n", s->ybase);
16715 fprintf (stderr, " hl = %d\n", s->hl);
16716 fprintf (stderr, " left overhang = %d, right = %d\n",
16717 s->left_overhang, s->right_overhang);
16718 fprintf (stderr, " nchars = %d\n", s->nchars);
16719 fprintf (stderr, " extends to end of line = %d\n",
16720 s->extends_to_end_of_line_p);
16721 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
16722 fprintf (stderr, " bg width = %d\n", s->background_width);
16725 #endif /* GLYPH_DEBUG */
16727 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
16728 of XChar2b structures for S; it can't be allocated in
16729 init_glyph_string because it must be allocated via `alloca'. W
16730 is the window on which S is drawn. ROW and AREA are the glyph row
16731 and area within the row from which S is constructed. START is the
16732 index of the first glyph structure covered by S. HL is a
16733 face-override for drawing S. */
16735 #ifdef HAVE_NTGUI
16736 #define OPTIONAL_HDC(hdc) hdc,
16737 #define DECLARE_HDC(hdc) HDC hdc;
16738 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
16739 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
16740 #endif
16742 #ifndef OPTIONAL_HDC
16743 #define OPTIONAL_HDC(hdc)
16744 #define DECLARE_HDC(hdc)
16745 #define ALLOCATE_HDC(hdc, f)
16746 #define RELEASE_HDC(hdc, f)
16747 #endif
16749 static void
16750 init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
16751 struct glyph_string *s;
16752 DECLARE_HDC (hdc)
16753 XChar2b *char2b;
16754 struct window *w;
16755 struct glyph_row *row;
16756 enum glyph_row_area area;
16757 int start;
16758 enum draw_glyphs_face hl;
16760 bzero (s, sizeof *s);
16761 s->w = w;
16762 s->f = XFRAME (w->frame);
16763 #ifdef HAVE_NTGUI
16764 s->hdc = hdc;
16765 #endif
16766 s->display = FRAME_X_DISPLAY (s->f);
16767 s->window = FRAME_X_WINDOW (s->f);
16768 s->char2b = char2b;
16769 s->hl = hl;
16770 s->row = row;
16771 s->area = area;
16772 s->first_glyph = row->glyphs[area] + start;
16773 s->height = row->height;
16774 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
16776 /* Display the internal border below the tool-bar window. */
16777 if (s->w == XWINDOW (s->f->tool_bar_window))
16778 s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
16780 s->ybase = s->y + row->ascent;
16784 /* Append the list of glyph strings with head H and tail T to the list
16785 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
16787 static INLINE void
16788 append_glyph_string_lists (head, tail, h, t)
16789 struct glyph_string **head, **tail;
16790 struct glyph_string *h, *t;
16792 if (h)
16794 if (*head)
16795 (*tail)->next = h;
16796 else
16797 *head = h;
16798 h->prev = *tail;
16799 *tail = t;
16804 /* Prepend the list of glyph strings with head H and tail T to the
16805 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
16806 result. */
16808 static INLINE void
16809 prepend_glyph_string_lists (head, tail, h, t)
16810 struct glyph_string **head, **tail;
16811 struct glyph_string *h, *t;
16813 if (h)
16815 if (*head)
16816 (*head)->prev = t;
16817 else
16818 *tail = t;
16819 t->next = *head;
16820 *head = h;
16825 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
16826 Set *HEAD and *TAIL to the resulting list. */
16828 static INLINE void
16829 append_glyph_string (head, tail, s)
16830 struct glyph_string **head, **tail;
16831 struct glyph_string *s;
16833 s->next = s->prev = NULL;
16834 append_glyph_string_lists (head, tail, s, s);
16838 /* Get face and two-byte form of character glyph GLYPH on frame F.
16839 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
16840 a pointer to a realized face that is ready for display. */
16842 static INLINE struct face *
16843 get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
16844 struct frame *f;
16845 struct glyph *glyph;
16846 XChar2b *char2b;
16847 int *two_byte_p;
16849 struct face *face;
16851 xassert (glyph->type == CHAR_GLYPH);
16852 face = FACE_FROM_ID (f, glyph->face_id);
16854 if (two_byte_p)
16855 *two_byte_p = 0;
16857 if (!glyph->multibyte_p)
16859 /* Unibyte case. We don't have to encode, but we have to make
16860 sure to use a face suitable for unibyte. */
16861 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
16863 else if (glyph->u.ch < 128
16864 && glyph->face_id < BASIC_FACE_ID_SENTINEL)
16866 /* Case of ASCII in a face known to fit ASCII. */
16867 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
16869 else
16871 int c1, c2, charset;
16873 /* Split characters into bytes. If c2 is -1 afterwards, C is
16874 really a one-byte character so that byte1 is zero. */
16875 SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
16876 if (c2 > 0)
16877 STORE_XCHAR2B (char2b, c1, c2);
16878 else
16879 STORE_XCHAR2B (char2b, 0, c1);
16881 /* Maybe encode the character in *CHAR2B. */
16882 if (charset != CHARSET_ASCII)
16884 struct font_info *font_info
16885 = FONT_INFO_FROM_ID (f, face->font_info_id);
16886 if (font_info)
16887 glyph->font_type
16888 = rif->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
16892 /* Make sure X resources of the face are allocated. */
16893 xassert (face != NULL);
16894 PREPARE_FACE_FOR_DISPLAY (f, face);
16895 return face;
16899 /* Fill glyph string S with composition components specified by S->cmp.
16901 FACES is an array of faces for all components of this composition.
16902 S->gidx is the index of the first component for S.
16903 OVERLAPS_P non-zero means S should draw the foreground only, and
16904 use its physical height for clipping.
16906 Value is the index of a component not in S. */
16908 static int
16909 fill_composite_glyph_string (s, faces, overlaps_p)
16910 struct glyph_string *s;
16911 struct face **faces;
16912 int overlaps_p;
16914 int i;
16916 xassert (s);
16918 s->for_overlaps_p = overlaps_p;
16920 s->face = faces[s->gidx];
16921 s->font = s->face->font;
16922 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
16924 /* For all glyphs of this composition, starting at the offset
16925 S->gidx, until we reach the end of the definition or encounter a
16926 glyph that requires the different face, add it to S. */
16927 ++s->nchars;
16928 for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
16929 ++s->nchars;
16931 /* All glyph strings for the same composition has the same width,
16932 i.e. the width set for the first component of the composition. */
16934 s->width = s->first_glyph->pixel_width;
16936 /* If the specified font could not be loaded, use the frame's
16937 default font, but record the fact that we couldn't load it in
16938 the glyph string so that we can draw rectangles for the
16939 characters of the glyph string. */
16940 if (s->font == NULL)
16942 s->font_not_found_p = 1;
16943 s->font = FRAME_FONT (s->f);
16946 /* Adjust base line for subscript/superscript text. */
16947 s->ybase += s->first_glyph->voffset;
16949 xassert (s->face && s->face->gc);
16951 /* This glyph string must always be drawn with 16-bit functions. */
16952 s->two_byte_p = 1;
16954 return s->gidx + s->nchars;
16958 /* Fill glyph string S from a sequence of character glyphs.
16960 FACE_ID is the face id of the string. START is the index of the
16961 first glyph to consider, END is the index of the last + 1.
16962 OVERLAPS_P non-zero means S should draw the foreground only, and
16963 use its physical height for clipping.
16965 Value is the index of the first glyph not in S. */
16967 static int
16968 fill_glyph_string (s, face_id, start, end, overlaps_p)
16969 struct glyph_string *s;
16970 int face_id;
16971 int start, end, overlaps_p;
16973 struct glyph *glyph, *last;
16974 int voffset;
16975 int glyph_not_available_p;
16977 xassert (s->f == XFRAME (s->w->frame));
16978 xassert (s->nchars == 0);
16979 xassert (start >= 0 && end > start);
16981 s->for_overlaps_p = overlaps_p,
16982 glyph = s->row->glyphs[s->area] + start;
16983 last = s->row->glyphs[s->area] + end;
16984 voffset = glyph->voffset;
16986 glyph_not_available_p = glyph->glyph_not_available_p;
16988 while (glyph < last
16989 && glyph->type == CHAR_GLYPH
16990 && glyph->voffset == voffset
16991 /* Same face id implies same font, nowadays. */
16992 && glyph->face_id == face_id
16993 && glyph->glyph_not_available_p == glyph_not_available_p)
16995 int two_byte_p;
16997 s->face = get_glyph_face_and_encoding (s->f, glyph,
16998 s->char2b + s->nchars,
16999 &two_byte_p);
17000 s->two_byte_p = two_byte_p;
17001 ++s->nchars;
17002 xassert (s->nchars <= end - start);
17003 s->width += glyph->pixel_width;
17004 ++glyph;
17007 s->font = s->face->font;
17008 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17010 /* If the specified font could not be loaded, use the frame's font,
17011 but record the fact that we couldn't load it in
17012 S->font_not_found_p so that we can draw rectangles for the
17013 characters of the glyph string. */
17014 if (s->font == NULL || glyph_not_available_p)
17016 s->font_not_found_p = 1;
17017 s->font = FRAME_FONT (s->f);
17020 /* Adjust base line for subscript/superscript text. */
17021 s->ybase += voffset;
17023 xassert (s->face && s->face->gc);
17024 return glyph - s->row->glyphs[s->area];
17028 /* Fill glyph string S from image glyph S->first_glyph. */
17030 static void
17031 fill_image_glyph_string (s)
17032 struct glyph_string *s;
17034 xassert (s->first_glyph->type == IMAGE_GLYPH);
17035 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
17036 xassert (s->img);
17037 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
17038 s->font = s->face->font;
17039 s->width = s->first_glyph->pixel_width;
17041 /* Adjust base line for subscript/superscript text. */
17042 s->ybase += s->first_glyph->voffset;
17046 /* Fill glyph string S from a sequence of stretch glyphs.
17048 ROW is the glyph row in which the glyphs are found, AREA is the
17049 area within the row. START is the index of the first glyph to
17050 consider, END is the index of the last + 1.
17052 Value is the index of the first glyph not in S. */
17054 static int
17055 fill_stretch_glyph_string (s, row, area, start, end)
17056 struct glyph_string *s;
17057 struct glyph_row *row;
17058 enum glyph_row_area area;
17059 int start, end;
17061 struct glyph *glyph, *last;
17062 int voffset, face_id;
17064 xassert (s->first_glyph->type == STRETCH_GLYPH);
17066 glyph = s->row->glyphs[s->area] + start;
17067 last = s->row->glyphs[s->area] + end;
17068 face_id = glyph->face_id;
17069 s->face = FACE_FROM_ID (s->f, face_id);
17070 s->font = s->face->font;
17071 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17072 s->width = glyph->pixel_width;
17073 voffset = glyph->voffset;
17075 for (++glyph;
17076 (glyph < last
17077 && glyph->type == STRETCH_GLYPH
17078 && glyph->voffset == voffset
17079 && glyph->face_id == face_id);
17080 ++glyph)
17081 s->width += glyph->pixel_width;
17083 /* Adjust base line for subscript/superscript text. */
17084 s->ybase += voffset;
17086 /* The case that face->gc == 0 is handled when drawing the glyph
17087 string by calling PREPARE_FACE_FOR_DISPLAY. */
17088 xassert (s->face);
17089 return glyph - s->row->glyphs[s->area];
17093 /* EXPORT for RIF:
17094 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
17095 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
17096 assumed to be zero. */
17098 void
17099 x_get_glyph_overhangs (glyph, f, left, right)
17100 struct glyph *glyph;
17101 struct frame *f;
17102 int *left, *right;
17104 *left = *right = 0;
17106 if (glyph->type == CHAR_GLYPH)
17108 XFontStruct *font;
17109 struct face *face;
17110 struct font_info *font_info;
17111 XChar2b char2b;
17112 XCharStruct *pcm;
17114 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
17115 font = face->font;
17116 font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
17117 if (font /* ++KFS: Should this be font_info ? */
17118 && (pcm = rif->per_char_metric (font, &char2b, glyph->font_type)))
17120 if (pcm->rbearing > pcm->width)
17121 *right = pcm->rbearing - pcm->width;
17122 if (pcm->lbearing < 0)
17123 *left = -pcm->lbearing;
17129 /* Return the index of the first glyph preceding glyph string S that
17130 is overwritten by S because of S's left overhang. Value is -1
17131 if no glyphs are overwritten. */
17133 static int
17134 left_overwritten (s)
17135 struct glyph_string *s;
17137 int k;
17139 if (s->left_overhang)
17141 int x = 0, i;
17142 struct glyph *glyphs = s->row->glyphs[s->area];
17143 int first = s->first_glyph - glyphs;
17145 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
17146 x -= glyphs[i].pixel_width;
17148 k = i + 1;
17150 else
17151 k = -1;
17153 return k;
17157 /* Return the index of the first glyph preceding glyph string S that
17158 is overwriting S because of its right overhang. Value is -1 if no
17159 glyph in front of S overwrites S. */
17161 static int
17162 left_overwriting (s)
17163 struct glyph_string *s;
17165 int i, k, x;
17166 struct glyph *glyphs = s->row->glyphs[s->area];
17167 int first = s->first_glyph - glyphs;
17169 k = -1;
17170 x = 0;
17171 for (i = first - 1; i >= 0; --i)
17173 int left, right;
17174 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
17175 if (x + right > 0)
17176 k = i;
17177 x -= glyphs[i].pixel_width;
17180 return k;
17184 /* Return the index of the last glyph following glyph string S that is
17185 not overwritten by S because of S's right overhang. Value is -1 if
17186 no such glyph is found. */
17188 static int
17189 right_overwritten (s)
17190 struct glyph_string *s;
17192 int k = -1;
17194 if (s->right_overhang)
17196 int x = 0, i;
17197 struct glyph *glyphs = s->row->glyphs[s->area];
17198 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17199 int end = s->row->used[s->area];
17201 for (i = first; i < end && s->right_overhang > x; ++i)
17202 x += glyphs[i].pixel_width;
17204 k = i;
17207 return k;
17211 /* Return the index of the last glyph following glyph string S that
17212 overwrites S because of its left overhang. Value is negative
17213 if no such glyph is found. */
17215 static int
17216 right_overwriting (s)
17217 struct glyph_string *s;
17219 int i, k, x;
17220 int end = s->row->used[s->area];
17221 struct glyph *glyphs = s->row->glyphs[s->area];
17222 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17224 k = -1;
17225 x = 0;
17226 for (i = first; i < end; ++i)
17228 int left, right;
17229 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
17230 if (x - left < 0)
17231 k = i;
17232 x += glyphs[i].pixel_width;
17235 return k;
17239 /* Get face and two-byte form of character C in face FACE_ID on frame
17240 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
17241 means we want to display multibyte text. DISPLAY_P non-zero means
17242 make sure that X resources for the face returned are allocated.
17243 Value is a pointer to a realized face that is ready for display if
17244 DISPLAY_P is non-zero. */
17246 static INLINE struct face *
17247 get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
17248 struct frame *f;
17249 int c, face_id;
17250 XChar2b *char2b;
17251 int multibyte_p, display_p;
17253 struct face *face = FACE_FROM_ID (f, face_id);
17255 if (!multibyte_p)
17257 /* Unibyte case. We don't have to encode, but we have to make
17258 sure to use a face suitable for unibyte. */
17259 STORE_XCHAR2B (char2b, 0, c);
17260 face_id = FACE_FOR_CHAR (f, face, c);
17261 face = FACE_FROM_ID (f, face_id);
17263 else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL)
17265 /* Case of ASCII in a face known to fit ASCII. */
17266 STORE_XCHAR2B (char2b, 0, c);
17268 else
17270 int c1, c2, charset;
17272 /* Split characters into bytes. If c2 is -1 afterwards, C is
17273 really a one-byte character so that byte1 is zero. */
17274 SPLIT_CHAR (c, charset, c1, c2);
17275 if (c2 > 0)
17276 STORE_XCHAR2B (char2b, c1, c2);
17277 else
17278 STORE_XCHAR2B (char2b, 0, c1);
17280 /* Maybe encode the character in *CHAR2B. */
17281 if (face->font != NULL)
17283 struct font_info *font_info
17284 = FONT_INFO_FROM_ID (f, face->font_info_id);
17285 if (font_info)
17286 rif->encode_char (c, char2b, font_info, 0);
17290 /* Make sure X resources of the face are allocated. */
17291 #ifdef HAVE_X_WINDOWS
17292 if (display_p)
17293 #endif
17295 xassert (face != NULL);
17296 PREPARE_FACE_FOR_DISPLAY (f, face);
17299 return face;
17303 /* Set background width of glyph string S. START is the index of the
17304 first glyph following S. LAST_X is the right-most x-position + 1
17305 in the drawing area. */
17307 static INLINE void
17308 set_glyph_string_background_width (s, start, last_x)
17309 struct glyph_string *s;
17310 int start;
17311 int last_x;
17313 /* If the face of this glyph string has to be drawn to the end of
17314 the drawing area, set S->extends_to_end_of_line_p. */
17315 struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID);
17317 if (start == s->row->used[s->area]
17318 && s->area == TEXT_AREA
17319 && ((s->hl == DRAW_NORMAL_TEXT
17320 && (s->row->fill_line_p
17321 || s->face->background != default_face->background
17322 || s->face->stipple != default_face->stipple
17323 || s->row->mouse_face_p))
17324 || s->hl == DRAW_MOUSE_FACE
17325 || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN)
17326 && s->row->fill_line_p)))
17327 s->extends_to_end_of_line_p = 1;
17329 /* If S extends its face to the end of the line, set its
17330 background_width to the distance to the right edge of the drawing
17331 area. */
17332 if (s->extends_to_end_of_line_p)
17333 s->background_width = last_x - s->x + 1;
17334 else
17335 s->background_width = s->width;
17339 /* Compute overhangs and x-positions for glyph string S and its
17340 predecessors, or successors. X is the starting x-position for S.
17341 BACKWARD_P non-zero means process predecessors. */
17343 static void
17344 compute_overhangs_and_x (s, x, backward_p)
17345 struct glyph_string *s;
17346 int x;
17347 int backward_p;
17349 if (backward_p)
17351 while (s)
17353 if (rif->compute_glyph_string_overhangs)
17354 rif->compute_glyph_string_overhangs (s);
17355 x -= s->width;
17356 s->x = x;
17357 s = s->prev;
17360 else
17362 while (s)
17364 if (rif->compute_glyph_string_overhangs)
17365 rif->compute_glyph_string_overhangs (s);
17366 s->x = x;
17367 x += s->width;
17368 s = s->next;
17375 /* The following macros are only called from draw_glyphs below.
17376 They reference the following parameters of that function directly:
17377 `w', `row', `area', and `overlap_p'
17378 as well as the following local variables:
17379 `s', `f', and `hdc' (in W32) */
17381 #ifdef HAVE_NTGUI
17382 /* On W32, silently add local `hdc' variable to argument list of
17383 init_glyph_string. */
17384 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17385 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
17386 #else
17387 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17388 init_glyph_string (s, char2b, w, row, area, start, hl)
17389 #endif
17391 /* Add a glyph string for a stretch glyph to the list of strings
17392 between HEAD and TAIL. START is the index of the stretch glyph in
17393 row area AREA of glyph row ROW. END is the index of the last glyph
17394 in that glyph row area. X is the current output position assigned
17395 to the new glyph string constructed. HL overrides that face of the
17396 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17397 is the right-most x-position of the drawing area. */
17399 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
17400 and below -- keep them on one line. */
17401 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17402 do \
17404 s = (struct glyph_string *) alloca (sizeof *s); \
17405 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17406 START = fill_stretch_glyph_string (s, row, area, START, END); \
17407 append_glyph_string (&HEAD, &TAIL, s); \
17408 s->x = (X); \
17410 while (0)
17413 /* Add a glyph string for an image glyph to the list of strings
17414 between HEAD and TAIL. START is the index of the image glyph in
17415 row area AREA of glyph row ROW. END is the index of the last glyph
17416 in that glyph row area. X is the current output position assigned
17417 to the new glyph string constructed. HL overrides that face of the
17418 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17419 is the right-most x-position of the drawing area. */
17421 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17422 do \
17424 s = (struct glyph_string *) alloca (sizeof *s); \
17425 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17426 fill_image_glyph_string (s); \
17427 append_glyph_string (&HEAD, &TAIL, s); \
17428 ++START; \
17429 s->x = (X); \
17431 while (0)
17434 /* Add a glyph string for a sequence of character glyphs to the list
17435 of strings between HEAD and TAIL. START is the index of the first
17436 glyph in row area AREA of glyph row ROW that is part of the new
17437 glyph string. END is the index of the last glyph in that glyph row
17438 area. X is the current output position assigned to the new glyph
17439 string constructed. HL overrides that face of the glyph; e.g. it
17440 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
17441 right-most x-position of the drawing area. */
17443 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17444 do \
17446 int c, face_id; \
17447 XChar2b *char2b; \
17449 c = (row)->glyphs[area][START].u.ch; \
17450 face_id = (row)->glyphs[area][START].face_id; \
17452 s = (struct glyph_string *) alloca (sizeof *s); \
17453 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
17454 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
17455 append_glyph_string (&HEAD, &TAIL, s); \
17456 s->x = (X); \
17457 START = fill_glyph_string (s, face_id, START, END, overlaps_p); \
17459 while (0)
17462 /* Add a glyph string for a composite sequence to the list of strings
17463 between HEAD and TAIL. START is the index of the first glyph in
17464 row area AREA of glyph row ROW that is part of the new glyph
17465 string. END is the index of the last glyph in that glyph row area.
17466 X is the current output position assigned to the new glyph string
17467 constructed. HL overrides that face of the glyph; e.g. it is
17468 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
17469 x-position of the drawing area. */
17471 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17472 do { \
17473 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
17474 int face_id = (row)->glyphs[area][START].face_id; \
17475 struct face *base_face = FACE_FROM_ID (f, face_id); \
17476 struct composition *cmp = composition_table[cmp_id]; \
17477 int glyph_len = cmp->glyph_len; \
17478 XChar2b *char2b; \
17479 struct face **faces; \
17480 struct glyph_string *first_s = NULL; \
17481 int n; \
17483 base_face = base_face->ascii_face; \
17484 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
17485 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
17486 /* At first, fill in `char2b' and `faces'. */ \
17487 for (n = 0; n < glyph_len; n++) \
17489 int c = COMPOSITION_GLYPH (cmp, n); \
17490 int this_face_id = FACE_FOR_CHAR (f, base_face, c); \
17491 faces[n] = FACE_FROM_ID (f, this_face_id); \
17492 get_char_face_and_encoding (f, c, this_face_id, \
17493 char2b + n, 1, 1); \
17496 /* Make glyph_strings for each glyph sequence that is drawable by \
17497 the same face, and append them to HEAD/TAIL. */ \
17498 for (n = 0; n < cmp->glyph_len;) \
17500 s = (struct glyph_string *) alloca (sizeof *s); \
17501 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \
17502 append_glyph_string (&(HEAD), &(TAIL), s); \
17503 s->cmp = cmp; \
17504 s->gidx = n; \
17505 s->x = (X); \
17507 if (n == 0) \
17508 first_s = s; \
17510 n = fill_composite_glyph_string (s, faces, overlaps_p); \
17513 ++START; \
17514 s = first_s; \
17515 } while (0)
17518 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
17519 of AREA of glyph row ROW on window W between indices START and END.
17520 HL overrides the face for drawing glyph strings, e.g. it is
17521 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
17522 x-positions of the drawing area.
17524 This is an ugly monster macro construct because we must use alloca
17525 to allocate glyph strings (because draw_glyphs can be called
17526 asynchronously). */
17528 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17529 do \
17531 HEAD = TAIL = NULL; \
17532 while (START < END) \
17534 struct glyph *first_glyph = (row)->glyphs[area] + START; \
17535 switch (first_glyph->type) \
17537 case CHAR_GLYPH: \
17538 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
17539 HL, X, LAST_X); \
17540 break; \
17542 case COMPOSITE_GLYPH: \
17543 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
17544 HL, X, LAST_X); \
17545 break; \
17547 case STRETCH_GLYPH: \
17548 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
17549 HL, X, LAST_X); \
17550 break; \
17552 case IMAGE_GLYPH: \
17553 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
17554 HL, X, LAST_X); \
17555 break; \
17557 default: \
17558 abort (); \
17561 set_glyph_string_background_width (s, START, LAST_X); \
17562 (X) += s->width; \
17565 while (0)
17568 /* Draw glyphs between START and END in AREA of ROW on window W,
17569 starting at x-position X. X is relative to AREA in W. HL is a
17570 face-override with the following meaning:
17572 DRAW_NORMAL_TEXT draw normally
17573 DRAW_CURSOR draw in cursor face
17574 DRAW_MOUSE_FACE draw in mouse face.
17575 DRAW_INVERSE_VIDEO draw in mode line face
17576 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
17577 DRAW_IMAGE_RAISED draw an image with a raised relief around it
17579 If OVERLAPS_P is non-zero, draw only the foreground of characters
17580 and clip to the physical height of ROW.
17582 Value is the x-position reached, relative to AREA of W. */
17584 static int
17585 draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
17586 struct window *w;
17587 int x;
17588 struct glyph_row *row;
17589 enum glyph_row_area area;
17590 int start, end;
17591 enum draw_glyphs_face hl;
17592 int overlaps_p;
17594 struct glyph_string *head, *tail;
17595 struct glyph_string *s;
17596 int last_x, area_width;
17597 int x_reached;
17598 int i, j;
17599 struct frame *f = XFRAME (WINDOW_FRAME (w));
17600 DECLARE_HDC (hdc);
17602 ALLOCATE_HDC (hdc, f);
17604 /* Let's rather be paranoid than getting a SEGV. */
17605 end = min (end, row->used[area]);
17606 start = max (0, start);
17607 start = min (end, start);
17609 /* Translate X to frame coordinates. Set last_x to the right
17610 end of the drawing area. */
17611 if (row->full_width_p)
17613 /* X is relative to the left edge of W, without scroll bars
17614 or fringes. */
17615 x += WINDOW_LEFT_EDGE_X (w);
17616 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
17618 else
17620 int area_left = window_box_left (w, area);
17621 x += area_left;
17622 area_width = window_box_width (w, area);
17623 last_x = area_left + area_width;
17626 /* Build a doubly-linked list of glyph_string structures between
17627 head and tail from what we have to draw. Note that the macro
17628 BUILD_GLYPH_STRINGS will modify its start parameter. That's
17629 the reason we use a separate variable `i'. */
17630 i = start;
17631 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
17632 if (tail)
17633 x_reached = tail->x + tail->background_width;
17634 else
17635 x_reached = x;
17637 /* If there are any glyphs with lbearing < 0 or rbearing > width in
17638 the row, redraw some glyphs in front or following the glyph
17639 strings built above. */
17640 if (head && !overlaps_p && row->contains_overlapping_glyphs_p)
17642 int dummy_x = 0;
17643 struct glyph_string *h, *t;
17645 /* Compute overhangs for all glyph strings. */
17646 if (rif->compute_glyph_string_overhangs)
17647 for (s = head; s; s = s->next)
17648 rif->compute_glyph_string_overhangs (s);
17650 /* Prepend glyph strings for glyphs in front of the first glyph
17651 string that are overwritten because of the first glyph
17652 string's left overhang. The background of all strings
17653 prepended must be drawn because the first glyph string
17654 draws over it. */
17655 i = left_overwritten (head);
17656 if (i >= 0)
17658 j = i;
17659 BUILD_GLYPH_STRINGS (j, start, h, t,
17660 DRAW_NORMAL_TEXT, dummy_x, last_x);
17661 start = i;
17662 compute_overhangs_and_x (t, head->x, 1);
17663 prepend_glyph_string_lists (&head, &tail, h, t);
17666 /* Prepend glyph strings for glyphs in front of the first glyph
17667 string that overwrite that glyph string because of their
17668 right overhang. For these strings, only the foreground must
17669 be drawn, because it draws over the glyph string at `head'.
17670 The background must not be drawn because this would overwrite
17671 right overhangs of preceding glyphs for which no glyph
17672 strings exist. */
17673 i = left_overwriting (head);
17674 if (i >= 0)
17676 BUILD_GLYPH_STRINGS (i, start, h, t,
17677 DRAW_NORMAL_TEXT, dummy_x, last_x);
17678 for (s = h; s; s = s->next)
17679 s->background_filled_p = 1;
17680 compute_overhangs_and_x (t, head->x, 1);
17681 prepend_glyph_string_lists (&head, &tail, h, t);
17684 /* Append glyphs strings for glyphs following the last glyph
17685 string tail that are overwritten by tail. The background of
17686 these strings has to be drawn because tail's foreground draws
17687 over it. */
17688 i = right_overwritten (tail);
17689 if (i >= 0)
17691 BUILD_GLYPH_STRINGS (end, i, h, t,
17692 DRAW_NORMAL_TEXT, x, last_x);
17693 compute_overhangs_and_x (h, tail->x + tail->width, 0);
17694 append_glyph_string_lists (&head, &tail, h, t);
17697 /* Append glyph strings for glyphs following the last glyph
17698 string tail that overwrite tail. The foreground of such
17699 glyphs has to be drawn because it writes into the background
17700 of tail. The background must not be drawn because it could
17701 paint over the foreground of following glyphs. */
17702 i = right_overwriting (tail);
17703 if (i >= 0)
17705 BUILD_GLYPH_STRINGS (end, i, h, t,
17706 DRAW_NORMAL_TEXT, x, last_x);
17707 for (s = h; s; s = s->next)
17708 s->background_filled_p = 1;
17709 compute_overhangs_and_x (h, tail->x + tail->width, 0);
17710 append_glyph_string_lists (&head, &tail, h, t);
17714 /* Draw all strings. */
17715 for (s = head; s; s = s->next)
17716 rif->draw_glyph_string (s);
17718 if (area == TEXT_AREA
17719 && !row->full_width_p
17720 /* When drawing overlapping rows, only the glyph strings'
17721 foreground is drawn, which doesn't erase a cursor
17722 completely. */
17723 && !overlaps_p)
17725 int x0 = head ? head->x : x;
17726 int x1 = tail ? tail->x + tail->background_width : x;
17728 int text_left = window_box_left (w, TEXT_AREA);
17729 x0 -= text_left;
17730 x1 -= text_left;
17732 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
17733 row->y, MATRIX_ROW_BOTTOM_Y (row));
17736 /* Value is the x-position up to which drawn, relative to AREA of W.
17737 This doesn't include parts drawn because of overhangs. */
17738 if (row->full_width_p)
17739 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
17740 else
17741 x_reached -= window_box_left (w, area);
17743 RELEASE_HDC (hdc, f);
17745 return x_reached;
17749 /* Store one glyph for IT->char_to_display in IT->glyph_row.
17750 Called from x_produce_glyphs when IT->glyph_row is non-null. */
17752 static INLINE void
17753 append_glyph (it)
17754 struct it *it;
17756 struct glyph *glyph;
17757 enum glyph_row_area area = it->area;
17759 xassert (it->glyph_row);
17760 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
17762 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
17763 if (glyph < it->glyph_row->glyphs[area + 1])
17765 glyph->charpos = CHARPOS (it->position);
17766 glyph->object = it->object;
17767 glyph->pixel_width = it->pixel_width;
17768 glyph->ascent = it->ascent;
17769 glyph->descent = it->descent;
17770 glyph->voffset = it->voffset;
17771 glyph->type = CHAR_GLYPH;
17772 glyph->multibyte_p = it->multibyte_p;
17773 glyph->left_box_line_p = it->start_of_box_run_p;
17774 glyph->right_box_line_p = it->end_of_box_run_p;
17775 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
17776 || it->phys_descent > it->descent);
17777 glyph->padding_p = 0;
17778 glyph->glyph_not_available_p = it->glyph_not_available_p;
17779 glyph->face_id = it->face_id;
17780 glyph->u.ch = it->char_to_display;
17781 glyph->font_type = FONT_TYPE_UNKNOWN;
17782 ++it->glyph_row->used[area];
17786 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
17787 Called from x_produce_glyphs when IT->glyph_row is non-null. */
17789 static INLINE void
17790 append_composite_glyph (it)
17791 struct it *it;
17793 struct glyph *glyph;
17794 enum glyph_row_area area = it->area;
17796 xassert (it->glyph_row);
17798 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
17799 if (glyph < it->glyph_row->glyphs[area + 1])
17801 glyph->charpos = CHARPOS (it->position);
17802 glyph->object = it->object;
17803 glyph->pixel_width = it->pixel_width;
17804 glyph->ascent = it->ascent;
17805 glyph->descent = it->descent;
17806 glyph->voffset = it->voffset;
17807 glyph->type = COMPOSITE_GLYPH;
17808 glyph->multibyte_p = it->multibyte_p;
17809 glyph->left_box_line_p = it->start_of_box_run_p;
17810 glyph->right_box_line_p = it->end_of_box_run_p;
17811 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
17812 || it->phys_descent > it->descent);
17813 glyph->padding_p = 0;
17814 glyph->glyph_not_available_p = 0;
17815 glyph->face_id = it->face_id;
17816 glyph->u.cmp_id = it->cmp_id;
17817 glyph->font_type = FONT_TYPE_UNKNOWN;
17818 ++it->glyph_row->used[area];
17823 /* Change IT->ascent and IT->height according to the setting of
17824 IT->voffset. */
17826 static INLINE void
17827 take_vertical_position_into_account (it)
17828 struct it *it;
17830 if (it->voffset)
17832 if (it->voffset < 0)
17833 /* Increase the ascent so that we can display the text higher
17834 in the line. */
17835 it->ascent += abs (it->voffset);
17836 else
17837 /* Increase the descent so that we can display the text lower
17838 in the line. */
17839 it->descent += it->voffset;
17844 /* Produce glyphs/get display metrics for the image IT is loaded with.
17845 See the description of struct display_iterator in dispextern.h for
17846 an overview of struct display_iterator. */
17848 static void
17849 produce_image_glyph (it)
17850 struct it *it;
17852 struct image *img;
17853 struct face *face;
17854 int face_ascent, glyph_ascent;
17856 xassert (it->what == IT_IMAGE);
17858 face = FACE_FROM_ID (it->f, it->face_id);
17859 xassert (face);
17860 /* Make sure X resources of the face is loaded. */
17861 PREPARE_FACE_FOR_DISPLAY (it->f, face);
17863 if (it->image_id < 0)
17865 /* Fringe bitmap. */
17866 it->ascent = it->phys_ascent = 0;
17867 it->descent = it->phys_descent = 0;
17868 it->pixel_width = 0;
17869 it->nglyphs = 0;
17870 return;
17873 img = IMAGE_FROM_ID (it->f, it->image_id);
17874 xassert (img);
17875 /* Make sure X resources of the image is loaded. */
17876 prepare_image_for_display (it->f, img);
17878 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face);
17879 it->descent = it->phys_descent = img->height + 2 * img->vmargin - it->ascent;
17880 it->pixel_width = img->width + 2 * img->hmargin;
17882 /* It's quite possible for images to have an ascent greater than
17883 their height, so don't get confused in that case. */
17884 if (it->descent < 0)
17885 it->descent = 0;
17887 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
17888 face_ascent = face->font ? FONT_BASE (face->font) : FRAME_BASELINE_OFFSET (it->f);
17889 if (face_ascent > it->ascent)
17890 it->ascent = it->phys_ascent = face_ascent;
17892 it->nglyphs = 1;
17894 if (face->box != FACE_NO_BOX)
17896 if (face->box_line_width > 0)
17898 it->ascent += face->box_line_width;
17899 it->descent += face->box_line_width;
17902 if (it->start_of_box_run_p)
17903 it->pixel_width += abs (face->box_line_width);
17904 if (it->end_of_box_run_p)
17905 it->pixel_width += abs (face->box_line_width);
17908 take_vertical_position_into_account (it);
17910 if (it->glyph_row)
17912 struct glyph *glyph;
17913 enum glyph_row_area area = it->area;
17915 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
17916 if (glyph < it->glyph_row->glyphs[area + 1])
17918 glyph->charpos = CHARPOS (it->position);
17919 glyph->object = it->object;
17920 glyph->pixel_width = it->pixel_width;
17921 glyph->ascent = glyph_ascent;
17922 glyph->descent = it->descent;
17923 glyph->voffset = it->voffset;
17924 glyph->type = IMAGE_GLYPH;
17925 glyph->multibyte_p = it->multibyte_p;
17926 glyph->left_box_line_p = it->start_of_box_run_p;
17927 glyph->right_box_line_p = it->end_of_box_run_p;
17928 glyph->overlaps_vertically_p = 0;
17929 glyph->padding_p = 0;
17930 glyph->glyph_not_available_p = 0;
17931 glyph->face_id = it->face_id;
17932 glyph->u.img_id = img->id;
17933 glyph->font_type = FONT_TYPE_UNKNOWN;
17934 ++it->glyph_row->used[area];
17940 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
17941 of the glyph, WIDTH and HEIGHT are the width and height of the
17942 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
17944 static void
17945 append_stretch_glyph (it, object, width, height, ascent)
17946 struct it *it;
17947 Lisp_Object object;
17948 int width, height;
17949 int ascent;
17951 struct glyph *glyph;
17952 enum glyph_row_area area = it->area;
17954 xassert (ascent >= 0 && ascent <= height);
17956 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
17957 if (glyph < it->glyph_row->glyphs[area + 1])
17959 glyph->charpos = CHARPOS (it->position);
17960 glyph->object = object;
17961 glyph->pixel_width = width;
17962 glyph->ascent = ascent;
17963 glyph->descent = height - ascent;
17964 glyph->voffset = it->voffset;
17965 glyph->type = STRETCH_GLYPH;
17966 glyph->multibyte_p = it->multibyte_p;
17967 glyph->left_box_line_p = it->start_of_box_run_p;
17968 glyph->right_box_line_p = it->end_of_box_run_p;
17969 glyph->overlaps_vertically_p = 0;
17970 glyph->padding_p = 0;
17971 glyph->glyph_not_available_p = 0;
17972 glyph->face_id = it->face_id;
17973 glyph->u.stretch.ascent = ascent;
17974 glyph->u.stretch.height = height;
17975 glyph->font_type = FONT_TYPE_UNKNOWN;
17976 ++it->glyph_row->used[area];
17981 /* Calculate a width or height in pixels from a specification using
17982 the following elements:
17984 SPEC ::=
17985 NUM - a (fractional) multiple of the default font width/height
17986 (NUM) - specifies exactly NUM pixels
17987 UNIT - a fixed number of pixels, see below.
17988 ELEMENT - size of a display element in pixels, see below.
17989 (NUM . SPEC) - equals NUM * SPEC
17990 (+ SPEC SPEC ...) - add pixel values
17991 (- SPEC SPEC ...) - subtract pixel values
17992 (- SPEC) - negate pixel value
17994 NUM ::=
17995 INT or FLOAT - a number constant
17996 SYMBOL - use symbol's (buffer local) variable binding.
17998 UNIT ::=
17999 in - pixels per inch *)
18000 mm - pixels per 1/1000 meter *)
18001 cm - pixels per 1/100 meter *)
18002 width - width of current font in pixels.
18003 height - height of current font in pixels.
18005 *) using the ratio(s) defined in display-pixels-per-inch.
18007 ELEMENT ::=
18009 left-fringe - left fringe width in pixels
18010 (left-fringe . nil) - left fringe width if inside margins, else 0
18011 (left-fringe . t) - left fringe width if outside margins, else 0
18013 right-fringe - right fringe width in pixels
18014 (right-fringe . nil) - right fringe width if inside margins, else 0
18015 (right-fringe . t) - right fringe width if outside margins, else 0
18017 left-margin - left margin width in pixels
18018 right-margin - right margin width in pixels
18020 scroll-bar - scroll-bar area width in pixels
18021 (scroll-bar . left) - scroll-bar width if on left, else 0
18022 (scroll-bar . right) - scroll-bar width if on right, else 0
18024 Examples:
18026 Pixels corresponding to 5 inches:
18027 (5 . in)
18029 Total width of non-text areas on left side of window:
18030 (+ left-fringe left-margin (scroll-bar . left))
18032 Total width of fringes if inside display margins:
18033 (+ (left-fringe) (right-fringe))
18035 Width of left margin minus width of 1 character in the default font:
18036 (- left-margin 1)
18038 Width of left margin minus width of 2 characters in the current font:
18039 (- left-margin (2 . width))
18041 Width of left fringe plus left margin minus one pixel:
18042 (- (+ left-fringe left-margin) (1))
18043 (+ left-fringe left-margin (- (1)))
18044 (+ left-fringe left-margin (-1))
18048 #define NUMVAL(X) \
18049 ((INTEGERP (X) || FLOATP (X)) \
18050 ? XFLOATINT (X) \
18051 : - 1)
18053 static int
18054 calc_pixel_width_or_height (res, it, prop, font, width_p)
18055 double *res;
18056 struct it *it;
18057 Lisp_Object prop;
18058 XFontStruct *font;
18059 int width_p;
18061 double pixels;
18063 #define OK_PIXELS(val) ((*res = (val)), 1)
18065 if (SYMBOLP (prop))
18067 if (SCHARS (SYMBOL_NAME (prop)) == 2)
18069 char *unit = SDATA (SYMBOL_NAME (prop));
18071 if (unit[0] == 'i' && unit[1] == 'n')
18072 pixels = 1.0;
18073 else if (unit[0] == 'm' && unit[1] == 'm')
18074 pixels = 25.4;
18075 else if (unit[0] == 'c' && unit[1] == 'm')
18076 pixels = 2.54;
18077 else
18078 pixels = 0;
18079 if (pixels > 0)
18081 double ppi;
18082 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
18083 || (CONSP (Vdisplay_pixels_per_inch)
18084 && (ppi = (width_p
18085 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
18086 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
18087 ppi > 0)))
18088 return OK_PIXELS (ppi / pixels);
18090 return 0;
18094 if (EQ (prop, Qheight))
18095 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
18096 if (EQ (prop, Qwidth))
18097 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
18098 if (EQ (prop, Qleft_fringe))
18099 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
18100 if (EQ (prop, Qright_fringe))
18101 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
18102 if (EQ (prop, Qleft_margin))
18103 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
18104 if (EQ (prop, Qright_margin))
18105 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
18106 if (EQ (prop, Qscroll_bar))
18107 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
18109 prop = Fbuffer_local_value (prop, it->w->buffer);
18112 if (INTEGERP (prop) || FLOATP (prop))
18114 int base_unit = (width_p
18115 ? FRAME_COLUMN_WIDTH (it->f)
18116 : FRAME_LINE_HEIGHT (it->f));
18117 return OK_PIXELS (XFLOATINT (prop) * base_unit);
18120 if (CONSP (prop))
18122 Lisp_Object car = XCAR (prop);
18123 Lisp_Object cdr = XCDR (prop);
18125 if (SYMBOLP (car))
18127 if (EQ (car, Qplus) || EQ (car, Qminus))
18129 int first = 1;
18130 double px;
18132 pixels = 0;
18133 while (CONSP (cdr))
18135 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr), font, width_p))
18136 return 0;
18137 if (first)
18138 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
18139 else
18140 pixels += px;
18141 cdr = XCDR (cdr);
18143 if (EQ (car, Qminus))
18144 pixels = -pixels;
18145 return OK_PIXELS (pixels);
18148 if (EQ (car, Qleft_fringe))
18149 return OK_PIXELS ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
18150 == !NILP (cdr))
18151 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
18152 : 0);
18153 if (EQ (car, Qright_fringe))
18154 return OK_PIXELS ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
18155 == !NILP (cdr))
18156 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
18157 : 0);
18158 if (EQ (car, Qscroll_bar))
18159 return OK_PIXELS ((WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
18160 == EQ (cdr, Qleft))
18161 ? WINDOW_SCROLL_BAR_AREA_WIDTH (it->w)
18162 : 0);
18164 car = Fbuffer_local_value (car, it->w->buffer);
18167 if (INTEGERP (car) || FLOATP (car))
18169 double fact;
18170 pixels = XFLOATINT (car);
18171 if (NILP (cdr))
18172 return OK_PIXELS (pixels);
18173 if (calc_pixel_width_or_height (&fact, it, cdr, font, width_p))
18174 return OK_PIXELS (pixels * fact);
18175 return 0;
18178 return 0;
18181 return 0;
18184 /* Produce a stretch glyph for iterator IT. IT->object is the value
18185 of the glyph property displayed. The value must be a list
18186 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
18187 being recognized:
18189 1. `:width WIDTH' specifies that the space should be WIDTH *
18190 canonical char width wide. WIDTH may be an integer or floating
18191 point number.
18193 2. `:relative-width FACTOR' specifies that the width of the stretch
18194 should be computed from the width of the first character having the
18195 `glyph' property, and should be FACTOR times that width.
18197 3. `:align-to HPOS' specifies that the space should be wide enough
18198 to reach HPOS, a value in canonical character units.
18200 Exactly one of the above pairs must be present.
18202 4. `:height HEIGHT' specifies that the height of the stretch produced
18203 should be HEIGHT, measured in canonical character units.
18205 5. `:relative-height FACTOR' specifies that the height of the
18206 stretch should be FACTOR times the height of the characters having
18207 the glyph property.
18209 Either none or exactly one of 4 or 5 must be present.
18211 6. `:ascent ASCENT' specifies that ASCENT percent of the height
18212 of the stretch should be used for the ascent of the stretch.
18213 ASCENT must be in the range 0 <= ASCENT <= 100. */
18215 static void
18216 produce_stretch_glyph (it)
18217 struct it *it;
18219 /* (space :width WIDTH :height HEIGHT ...) */
18220 Lisp_Object prop, plist;
18221 int width = 0, height = 0;
18222 int zero_width_ok_p = 0, zero_height_ok_p = 0;
18223 int ascent = 0;
18224 double tem;
18225 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18226 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
18228 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18230 /* List should start with `space'. */
18231 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
18232 plist = XCDR (it->object);
18234 /* Compute the width of the stretch. */
18235 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
18236 && calc_pixel_width_or_height (&tem, it, prop, font, 1))
18238 /* Absolute width `:width WIDTH' specified and valid. */
18239 zero_width_ok_p = 1;
18240 width = (int)tem;
18242 else if (prop = Fplist_get (plist, QCrelative_width),
18243 NUMVAL (prop) > 0)
18245 /* Relative width `:relative-width FACTOR' specified and valid.
18246 Compute the width of the characters having the `glyph'
18247 property. */
18248 struct it it2;
18249 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
18251 it2 = *it;
18252 if (it->multibyte_p)
18254 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
18255 - IT_BYTEPOS (*it));
18256 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
18258 else
18259 it2.c = *p, it2.len = 1;
18261 it2.glyph_row = NULL;
18262 it2.what = IT_CHARACTER;
18263 x_produce_glyphs (&it2);
18264 width = NUMVAL (prop) * it2.pixel_width;
18266 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
18267 && calc_pixel_width_or_height (&tem, it, prop, font, 1))
18269 width = max (0, (int)tem - it->current_x);
18270 zero_width_ok_p = 1;
18272 else
18273 /* Nothing specified -> width defaults to canonical char width. */
18274 width = FRAME_COLUMN_WIDTH (it->f);
18276 if (width <= 0 && (width < 0 || !zero_width_ok_p))
18277 width = 1;
18279 /* Compute height. */
18280 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
18281 && calc_pixel_width_or_height (&tem, it, prop, font, 0))
18283 height = (int)tem;
18284 zero_height_ok_p = 1;
18286 else if (prop = Fplist_get (plist, QCrelative_height),
18287 NUMVAL (prop) > 0)
18288 height = FONT_HEIGHT (font) * NUMVAL (prop);
18289 else
18290 height = FONT_HEIGHT (font);
18292 if (height <= 0 && (height < 0 || !zero_height_ok_p))
18293 height = 1;
18295 /* Compute percentage of height used for ascent. If
18296 `:ascent ASCENT' is present and valid, use that. Otherwise,
18297 derive the ascent from the font in use. */
18298 if (prop = Fplist_get (plist, QCascent),
18299 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
18300 ascent = height * NUMVAL (prop) / 100.0;
18301 else if (!NILP (prop)
18302 && calc_pixel_width_or_height (&tem, it, prop, font, 0))
18303 ascent = min (max (0, (int)tem), height);
18304 else
18305 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
18307 if (width > 0 && height > 0 && it->glyph_row)
18309 Lisp_Object object = it->stack[it->sp - 1].string;
18310 if (!STRINGP (object))
18311 object = it->w->buffer;
18312 append_stretch_glyph (it, object, width, height, ascent);
18315 it->pixel_width = width;
18316 it->ascent = it->phys_ascent = ascent;
18317 it->descent = it->phys_descent = height - it->ascent;
18318 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
18320 if (width > 0 && height > 0 && face->box != FACE_NO_BOX)
18322 if (face->box_line_width > 0)
18324 it->ascent += face->box_line_width;
18325 it->descent += face->box_line_width;
18328 if (it->start_of_box_run_p)
18329 it->pixel_width += abs (face->box_line_width);
18330 if (it->end_of_box_run_p)
18331 it->pixel_width += abs (face->box_line_width);
18334 take_vertical_position_into_account (it);
18337 /* RIF:
18338 Produce glyphs/get display metrics for the display element IT is
18339 loaded with. See the description of struct display_iterator in
18340 dispextern.h for an overview of struct display_iterator. */
18342 void
18343 x_produce_glyphs (it)
18344 struct it *it;
18346 it->glyph_not_available_p = 0;
18348 if (it->what == IT_CHARACTER)
18350 XChar2b char2b;
18351 XFontStruct *font;
18352 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18353 XCharStruct *pcm;
18354 int font_not_found_p;
18355 struct font_info *font_info;
18356 int boff; /* baseline offset */
18357 /* We may change it->multibyte_p upon unibyte<->multibyte
18358 conversion. So, save the current value now and restore it
18359 later.
18361 Note: It seems that we don't have to record multibyte_p in
18362 struct glyph because the character code itself tells if or
18363 not the character is multibyte. Thus, in the future, we must
18364 consider eliminating the field `multibyte_p' in the struct
18365 glyph. */
18366 int saved_multibyte_p = it->multibyte_p;
18368 /* Maybe translate single-byte characters to multibyte, or the
18369 other way. */
18370 it->char_to_display = it->c;
18371 if (!ASCII_BYTE_P (it->c))
18373 if (unibyte_display_via_language_environment
18374 && SINGLE_BYTE_CHAR_P (it->c)
18375 && (it->c >= 0240
18376 || !NILP (Vnonascii_translation_table)))
18378 it->char_to_display = unibyte_char_to_multibyte (it->c);
18379 it->multibyte_p = 1;
18380 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18381 face = FACE_FROM_ID (it->f, it->face_id);
18383 else if (!SINGLE_BYTE_CHAR_P (it->c)
18384 && !it->multibyte_p)
18386 it->multibyte_p = 1;
18387 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18388 face = FACE_FROM_ID (it->f, it->face_id);
18392 /* Get font to use. Encode IT->char_to_display. */
18393 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
18394 &char2b, it->multibyte_p, 0);
18395 font = face->font;
18397 /* When no suitable font found, use the default font. */
18398 font_not_found_p = font == NULL;
18399 if (font_not_found_p)
18401 font = FRAME_FONT (it->f);
18402 boff = FRAME_BASELINE_OFFSET (it->f);
18403 font_info = NULL;
18405 else
18407 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18408 boff = font_info->baseline_offset;
18409 if (font_info->vertical_centering)
18410 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18413 if (it->char_to_display >= ' '
18414 && (!it->multibyte_p || it->char_to_display < 128))
18416 /* Either unibyte or ASCII. */
18417 int stretched_p;
18419 it->nglyphs = 1;
18421 pcm = rif->per_char_metric (font, &char2b,
18422 FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
18423 it->ascent = FONT_BASE (font) + boff;
18424 it->descent = FONT_DESCENT (font) - boff;
18426 if (pcm)
18428 it->phys_ascent = pcm->ascent + boff;
18429 it->phys_descent = pcm->descent - boff;
18430 it->pixel_width = pcm->width;
18432 else
18434 it->glyph_not_available_p = 1;
18435 it->phys_ascent = FONT_BASE (font) + boff;
18436 it->phys_descent = FONT_DESCENT (font) - boff;
18437 it->pixel_width = FONT_WIDTH (font);
18440 /* If this is a space inside a region of text with
18441 `space-width' property, change its width. */
18442 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
18443 if (stretched_p)
18444 it->pixel_width *= XFLOATINT (it->space_width);
18446 /* If face has a box, add the box thickness to the character
18447 height. If character has a box line to the left and/or
18448 right, add the box line width to the character's width. */
18449 if (face->box != FACE_NO_BOX)
18451 int thick = face->box_line_width;
18453 if (thick > 0)
18455 it->ascent += thick;
18456 it->descent += thick;
18458 else
18459 thick = -thick;
18461 if (it->start_of_box_run_p)
18462 it->pixel_width += thick;
18463 if (it->end_of_box_run_p)
18464 it->pixel_width += thick;
18467 /* If face has an overline, add the height of the overline
18468 (1 pixel) and a 1 pixel margin to the character height. */
18469 if (face->overline_p)
18470 it->ascent += 2;
18472 take_vertical_position_into_account (it);
18474 /* If we have to actually produce glyphs, do it. */
18475 if (it->glyph_row)
18477 if (stretched_p)
18479 /* Translate a space with a `space-width' property
18480 into a stretch glyph. */
18481 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
18482 / FONT_HEIGHT (font));
18483 append_stretch_glyph (it, it->object, it->pixel_width,
18484 it->ascent + it->descent, ascent);
18486 else
18487 append_glyph (it);
18489 /* If characters with lbearing or rbearing are displayed
18490 in this line, record that fact in a flag of the
18491 glyph row. This is used to optimize X output code. */
18492 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
18493 it->glyph_row->contains_overlapping_glyphs_p = 1;
18496 else if (it->char_to_display == '\n')
18498 /* A newline has no width but we need the height of the line. */
18499 it->pixel_width = 0;
18500 it->nglyphs = 0;
18501 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
18502 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
18504 if (face->box != FACE_NO_BOX
18505 && face->box_line_width > 0)
18507 it->ascent += face->box_line_width;
18508 it->descent += face->box_line_width;
18511 else if (it->char_to_display == '\t')
18513 int tab_width = it->tab_width * FRAME_COLUMN_WIDTH (it->f);
18514 int x = it->current_x + it->continuation_lines_width;
18515 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
18517 /* If the distance from the current position to the next tab
18518 stop is less than a canonical character width, use the
18519 tab stop after that. */
18520 if (next_tab_x - x < FRAME_COLUMN_WIDTH (it->f))
18521 next_tab_x += tab_width;
18523 it->pixel_width = next_tab_x - x;
18524 it->nglyphs = 1;
18525 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
18526 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
18528 if (it->glyph_row)
18530 append_stretch_glyph (it, it->object, it->pixel_width,
18531 it->ascent + it->descent, it->ascent);
18534 else
18536 /* A multi-byte character. Assume that the display width of the
18537 character is the width of the character multiplied by the
18538 width of the font. */
18540 /* If we found a font, this font should give us the right
18541 metrics. If we didn't find a font, use the frame's
18542 default font and calculate the width of the character
18543 from the charset width; this is what old redisplay code
18544 did. */
18546 pcm = rif->per_char_metric (font, &char2b,
18547 FONT_TYPE_FOR_MULTIBYTE (font, it->c));
18549 if (font_not_found_p || !pcm)
18551 int charset = CHAR_CHARSET (it->char_to_display);
18553 it->glyph_not_available_p = 1;
18554 it->pixel_width = (FRAME_COLUMN_WIDTH (it->f)
18555 * CHARSET_WIDTH (charset));
18556 it->phys_ascent = FONT_BASE (font) + boff;
18557 it->phys_descent = FONT_DESCENT (font) - boff;
18559 else
18561 it->pixel_width = pcm->width;
18562 it->phys_ascent = pcm->ascent + boff;
18563 it->phys_descent = pcm->descent - boff;
18564 if (it->glyph_row
18565 && (pcm->lbearing < 0
18566 || pcm->rbearing > pcm->width))
18567 it->glyph_row->contains_overlapping_glyphs_p = 1;
18569 it->nglyphs = 1;
18570 it->ascent = FONT_BASE (font) + boff;
18571 it->descent = FONT_DESCENT (font) - boff;
18572 if (face->box != FACE_NO_BOX)
18574 int thick = face->box_line_width;
18576 if (thick > 0)
18578 it->ascent += thick;
18579 it->descent += thick;
18581 else
18582 thick = - thick;
18584 if (it->start_of_box_run_p)
18585 it->pixel_width += thick;
18586 if (it->end_of_box_run_p)
18587 it->pixel_width += thick;
18590 /* If face has an overline, add the height of the overline
18591 (1 pixel) and a 1 pixel margin to the character height. */
18592 if (face->overline_p)
18593 it->ascent += 2;
18595 take_vertical_position_into_account (it);
18597 if (it->glyph_row)
18598 append_glyph (it);
18600 it->multibyte_p = saved_multibyte_p;
18602 else if (it->what == IT_COMPOSITION)
18604 /* Note: A composition is represented as one glyph in the
18605 glyph matrix. There are no padding glyphs. */
18606 XChar2b char2b;
18607 XFontStruct *font;
18608 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18609 XCharStruct *pcm;
18610 int font_not_found_p;
18611 struct font_info *font_info;
18612 int boff; /* baseline offset */
18613 struct composition *cmp = composition_table[it->cmp_id];
18615 /* Maybe translate single-byte characters to multibyte. */
18616 it->char_to_display = it->c;
18617 if (unibyte_display_via_language_environment
18618 && SINGLE_BYTE_CHAR_P (it->c)
18619 && (it->c >= 0240
18620 || (it->c >= 0200
18621 && !NILP (Vnonascii_translation_table))))
18623 it->char_to_display = unibyte_char_to_multibyte (it->c);
18626 /* Get face and font to use. Encode IT->char_to_display. */
18627 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18628 face = FACE_FROM_ID (it->f, it->face_id);
18629 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
18630 &char2b, it->multibyte_p, 0);
18631 font = face->font;
18633 /* When no suitable font found, use the default font. */
18634 font_not_found_p = font == NULL;
18635 if (font_not_found_p)
18637 font = FRAME_FONT (it->f);
18638 boff = FRAME_BASELINE_OFFSET (it->f);
18639 font_info = NULL;
18641 else
18643 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18644 boff = font_info->baseline_offset;
18645 if (font_info->vertical_centering)
18646 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18649 /* There are no padding glyphs, so there is only one glyph to
18650 produce for the composition. Important is that pixel_width,
18651 ascent and descent are the values of what is drawn by
18652 draw_glyphs (i.e. the values of the overall glyphs composed). */
18653 it->nglyphs = 1;
18655 /* If we have not yet calculated pixel size data of glyphs of
18656 the composition for the current face font, calculate them
18657 now. Theoretically, we have to check all fonts for the
18658 glyphs, but that requires much time and memory space. So,
18659 here we check only the font of the first glyph. This leads
18660 to incorrect display very rarely, and C-l (recenter) can
18661 correct the display anyway. */
18662 if (cmp->font != (void *) font)
18664 /* Ascent and descent of the font of the first character of
18665 this composition (adjusted by baseline offset). Ascent
18666 and descent of overall glyphs should not be less than
18667 them respectively. */
18668 int font_ascent = FONT_BASE (font) + boff;
18669 int font_descent = FONT_DESCENT (font) - boff;
18670 /* Bounding box of the overall glyphs. */
18671 int leftmost, rightmost, lowest, highest;
18672 int i, width, ascent, descent;
18674 cmp->font = (void *) font;
18676 /* Initialize the bounding box. */
18677 if (font_info
18678 && (pcm = rif->per_char_metric (font, &char2b,
18679 FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
18681 width = pcm->width;
18682 ascent = pcm->ascent;
18683 descent = pcm->descent;
18685 else
18687 width = FONT_WIDTH (font);
18688 ascent = FONT_BASE (font);
18689 descent = FONT_DESCENT (font);
18692 rightmost = width;
18693 lowest = - descent + boff;
18694 highest = ascent + boff;
18695 leftmost = 0;
18697 if (font_info
18698 && font_info->default_ascent
18699 && CHAR_TABLE_P (Vuse_default_ascent)
18700 && !NILP (Faref (Vuse_default_ascent,
18701 make_number (it->char_to_display))))
18702 highest = font_info->default_ascent + boff;
18704 /* Draw the first glyph at the normal position. It may be
18705 shifted to right later if some other glyphs are drawn at
18706 the left. */
18707 cmp->offsets[0] = 0;
18708 cmp->offsets[1] = boff;
18710 /* Set cmp->offsets for the remaining glyphs. */
18711 for (i = 1; i < cmp->glyph_len; i++)
18713 int left, right, btm, top;
18714 int ch = COMPOSITION_GLYPH (cmp, i);
18715 int face_id = FACE_FOR_CHAR (it->f, face, ch);
18717 face = FACE_FROM_ID (it->f, face_id);
18718 get_char_face_and_encoding (it->f, ch, face->id,
18719 &char2b, it->multibyte_p, 0);
18720 font = face->font;
18721 if (font == NULL)
18723 font = FRAME_FONT (it->f);
18724 boff = FRAME_BASELINE_OFFSET (it->f);
18725 font_info = NULL;
18727 else
18729 font_info
18730 = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18731 boff = font_info->baseline_offset;
18732 if (font_info->vertical_centering)
18733 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18736 if (font_info
18737 && (pcm = rif->per_char_metric (font, &char2b,
18738 FONT_TYPE_FOR_MULTIBYTE (font, ch))))
18740 width = pcm->width;
18741 ascent = pcm->ascent;
18742 descent = pcm->descent;
18744 else
18746 width = FONT_WIDTH (font);
18747 ascent = 1;
18748 descent = 0;
18751 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
18753 /* Relative composition with or without
18754 alternate chars. */
18755 left = (leftmost + rightmost - width) / 2;
18756 btm = - descent + boff;
18757 if (font_info && font_info->relative_compose
18758 && (! CHAR_TABLE_P (Vignore_relative_composition)
18759 || NILP (Faref (Vignore_relative_composition,
18760 make_number (ch)))))
18763 if (- descent >= font_info->relative_compose)
18764 /* One extra pixel between two glyphs. */
18765 btm = highest + 1;
18766 else if (ascent <= 0)
18767 /* One extra pixel between two glyphs. */
18768 btm = lowest - 1 - ascent - descent;
18771 else
18773 /* A composition rule is specified by an integer
18774 value that encodes global and new reference
18775 points (GREF and NREF). GREF and NREF are
18776 specified by numbers as below:
18778 0---1---2 -- ascent
18782 9--10--11 -- center
18784 ---3---4---5--- baseline
18786 6---7---8 -- descent
18788 int rule = COMPOSITION_RULE (cmp, i);
18789 int gref, nref, grefx, grefy, nrefx, nrefy;
18791 COMPOSITION_DECODE_RULE (rule, gref, nref);
18792 grefx = gref % 3, nrefx = nref % 3;
18793 grefy = gref / 3, nrefy = nref / 3;
18795 left = (leftmost
18796 + grefx * (rightmost - leftmost) / 2
18797 - nrefx * width / 2);
18798 btm = ((grefy == 0 ? highest
18799 : grefy == 1 ? 0
18800 : grefy == 2 ? lowest
18801 : (highest + lowest) / 2)
18802 - (nrefy == 0 ? ascent + descent
18803 : nrefy == 1 ? descent - boff
18804 : nrefy == 2 ? 0
18805 : (ascent + descent) / 2));
18808 cmp->offsets[i * 2] = left;
18809 cmp->offsets[i * 2 + 1] = btm + descent;
18811 /* Update the bounding box of the overall glyphs. */
18812 right = left + width;
18813 top = btm + descent + ascent;
18814 if (left < leftmost)
18815 leftmost = left;
18816 if (right > rightmost)
18817 rightmost = right;
18818 if (top > highest)
18819 highest = top;
18820 if (btm < lowest)
18821 lowest = btm;
18824 /* If there are glyphs whose x-offsets are negative,
18825 shift all glyphs to the right and make all x-offsets
18826 non-negative. */
18827 if (leftmost < 0)
18829 for (i = 0; i < cmp->glyph_len; i++)
18830 cmp->offsets[i * 2] -= leftmost;
18831 rightmost -= leftmost;
18834 cmp->pixel_width = rightmost;
18835 cmp->ascent = highest;
18836 cmp->descent = - lowest;
18837 if (cmp->ascent < font_ascent)
18838 cmp->ascent = font_ascent;
18839 if (cmp->descent < font_descent)
18840 cmp->descent = font_descent;
18843 it->pixel_width = cmp->pixel_width;
18844 it->ascent = it->phys_ascent = cmp->ascent;
18845 it->descent = it->phys_descent = cmp->descent;
18847 if (face->box != FACE_NO_BOX)
18849 int thick = face->box_line_width;
18851 if (thick > 0)
18853 it->ascent += thick;
18854 it->descent += thick;
18856 else
18857 thick = - thick;
18859 if (it->start_of_box_run_p)
18860 it->pixel_width += thick;
18861 if (it->end_of_box_run_p)
18862 it->pixel_width += thick;
18865 /* If face has an overline, add the height of the overline
18866 (1 pixel) and a 1 pixel margin to the character height. */
18867 if (face->overline_p)
18868 it->ascent += 2;
18870 take_vertical_position_into_account (it);
18872 if (it->glyph_row)
18873 append_composite_glyph (it);
18875 else if (it->what == IT_IMAGE)
18876 produce_image_glyph (it);
18877 else if (it->what == IT_STRETCH)
18878 produce_stretch_glyph (it);
18880 /* Accumulate dimensions. Note: can't assume that it->descent > 0
18881 because this isn't true for images with `:ascent 100'. */
18882 xassert (it->ascent >= 0 && it->descent >= 0);
18883 if (it->area == TEXT_AREA)
18884 it->current_x += it->pixel_width;
18886 it->descent += it->extra_line_spacing;
18888 it->max_ascent = max (it->max_ascent, it->ascent);
18889 it->max_descent = max (it->max_descent, it->descent);
18890 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
18891 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
18894 /* EXPORT for RIF:
18895 Output LEN glyphs starting at START at the nominal cursor position.
18896 Advance the nominal cursor over the text. The global variable
18897 updated_window contains the window being updated, updated_row is
18898 the glyph row being updated, and updated_area is the area of that
18899 row being updated. */
18901 void
18902 x_write_glyphs (start, len)
18903 struct glyph *start;
18904 int len;
18906 int x, hpos;
18908 xassert (updated_window && updated_row);
18909 BLOCK_INPUT;
18911 /* Write glyphs. */
18913 hpos = start - updated_row->glyphs[updated_area];
18914 x = draw_glyphs (updated_window, output_cursor.x,
18915 updated_row, updated_area,
18916 hpos, hpos + len,
18917 DRAW_NORMAL_TEXT, 0);
18919 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
18920 if (updated_area == TEXT_AREA
18921 && updated_window->phys_cursor_on_p
18922 && updated_window->phys_cursor.vpos == output_cursor.vpos
18923 && updated_window->phys_cursor.hpos >= hpos
18924 && updated_window->phys_cursor.hpos < hpos + len)
18925 updated_window->phys_cursor_on_p = 0;
18927 UNBLOCK_INPUT;
18929 /* Advance the output cursor. */
18930 output_cursor.hpos += len;
18931 output_cursor.x = x;
18935 /* EXPORT for RIF:
18936 Insert LEN glyphs from START at the nominal cursor position. */
18938 void
18939 x_insert_glyphs (start, len)
18940 struct glyph *start;
18941 int len;
18943 struct frame *f;
18944 struct window *w;
18945 int line_height, shift_by_width, shifted_region_width;
18946 struct glyph_row *row;
18947 struct glyph *glyph;
18948 int frame_x, frame_y, hpos;
18950 xassert (updated_window && updated_row);
18951 BLOCK_INPUT;
18952 w = updated_window;
18953 f = XFRAME (WINDOW_FRAME (w));
18955 /* Get the height of the line we are in. */
18956 row = updated_row;
18957 line_height = row->height;
18959 /* Get the width of the glyphs to insert. */
18960 shift_by_width = 0;
18961 for (glyph = start; glyph < start + len; ++glyph)
18962 shift_by_width += glyph->pixel_width;
18964 /* Get the width of the region to shift right. */
18965 shifted_region_width = (window_box_width (w, updated_area)
18966 - output_cursor.x
18967 - shift_by_width);
18969 /* Shift right. */
18970 frame_x = window_box_left (w, updated_area) + output_cursor.x;
18971 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
18973 rif->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
18974 line_height, shift_by_width);
18976 /* Write the glyphs. */
18977 hpos = start - row->glyphs[updated_area];
18978 draw_glyphs (w, output_cursor.x, row, updated_area,
18979 hpos, hpos + len,
18980 DRAW_NORMAL_TEXT, 0);
18982 /* Advance the output cursor. */
18983 output_cursor.hpos += len;
18984 output_cursor.x += shift_by_width;
18985 UNBLOCK_INPUT;
18989 /* EXPORT for RIF:
18990 Erase the current text line from the nominal cursor position
18991 (inclusive) to pixel column TO_X (exclusive). The idea is that
18992 everything from TO_X onward is already erased.
18994 TO_X is a pixel position relative to updated_area of
18995 updated_window. TO_X == -1 means clear to the end of this area. */
18997 void
18998 x_clear_end_of_line (to_x)
18999 int to_x;
19001 struct frame *f;
19002 struct window *w = updated_window;
19003 int max_x, min_y, max_y;
19004 int from_x, from_y, to_y;
19006 xassert (updated_window && updated_row);
19007 f = XFRAME (w->frame);
19009 if (updated_row->full_width_p)
19010 max_x = WINDOW_TOTAL_WIDTH (w);
19011 else
19012 max_x = window_box_width (w, updated_area);
19013 max_y = window_text_bottom_y (w);
19015 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
19016 of window. For TO_X > 0, truncate to end of drawing area. */
19017 if (to_x == 0)
19018 return;
19019 else if (to_x < 0)
19020 to_x = max_x;
19021 else
19022 to_x = min (to_x, max_x);
19024 to_y = min (max_y, output_cursor.y + updated_row->height);
19026 /* Notice if the cursor will be cleared by this operation. */
19027 if (!updated_row->full_width_p)
19028 notice_overwritten_cursor (w, updated_area,
19029 output_cursor.x, -1,
19030 updated_row->y,
19031 MATRIX_ROW_BOTTOM_Y (updated_row));
19033 from_x = output_cursor.x;
19035 /* Translate to frame coordinates. */
19036 if (updated_row->full_width_p)
19038 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
19039 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
19041 else
19043 int area_left = window_box_left (w, updated_area);
19044 from_x += area_left;
19045 to_x += area_left;
19048 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
19049 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
19050 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
19052 /* Prevent inadvertently clearing to end of the X window. */
19053 if (to_x > from_x && to_y > from_y)
19055 BLOCK_INPUT;
19056 rif->clear_frame_area (f, from_x, from_y,
19057 to_x - from_x, to_y - from_y);
19058 UNBLOCK_INPUT;
19062 #endif /* HAVE_WINDOW_SYSTEM */
19066 /***********************************************************************
19067 Cursor types
19068 ***********************************************************************/
19070 /* Value is the internal representation of the specified cursor type
19071 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
19072 of the bar cursor. */
19074 static enum text_cursor_kinds
19075 get_specified_cursor_type (arg, width)
19076 Lisp_Object arg;
19077 int *width;
19079 enum text_cursor_kinds type;
19081 if (NILP (arg))
19082 return NO_CURSOR;
19084 if (EQ (arg, Qbox))
19085 return FILLED_BOX_CURSOR;
19087 if (EQ (arg, Qhollow))
19088 return HOLLOW_BOX_CURSOR;
19090 if (EQ (arg, Qbar))
19092 *width = 2;
19093 return BAR_CURSOR;
19096 if (CONSP (arg)
19097 && EQ (XCAR (arg), Qbar)
19098 && INTEGERP (XCDR (arg))
19099 && XINT (XCDR (arg)) >= 0)
19101 *width = XINT (XCDR (arg));
19102 return BAR_CURSOR;
19105 if (EQ (arg, Qhbar))
19107 *width = 2;
19108 return HBAR_CURSOR;
19111 if (CONSP (arg)
19112 && EQ (XCAR (arg), Qhbar)
19113 && INTEGERP (XCDR (arg))
19114 && XINT (XCDR (arg)) >= 0)
19116 *width = XINT (XCDR (arg));
19117 return HBAR_CURSOR;
19120 /* Treat anything unknown as "hollow box cursor".
19121 It was bad to signal an error; people have trouble fixing
19122 .Xdefaults with Emacs, when it has something bad in it. */
19123 type = HOLLOW_BOX_CURSOR;
19125 return type;
19128 /* Set the default cursor types for specified frame. */
19129 void
19130 set_frame_cursor_types (f, arg)
19131 struct frame *f;
19132 Lisp_Object arg;
19134 int width;
19135 Lisp_Object tem;
19137 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
19138 FRAME_CURSOR_WIDTH (f) = width;
19140 /* By default, set up the blink-off state depending on the on-state. */
19142 tem = Fassoc (arg, Vblink_cursor_alist);
19143 if (!NILP (tem))
19145 FRAME_BLINK_OFF_CURSOR (f)
19146 = get_specified_cursor_type (XCDR (tem), &width);
19147 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
19149 else
19150 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
19154 /* Return the cursor we want to be displayed in window W. Return
19155 width of bar/hbar cursor through WIDTH arg. Return with
19156 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
19157 (i.e. if the `system caret' should track this cursor).
19159 In a mini-buffer window, we want the cursor only to appear if we
19160 are reading input from this window. For the selected window, we
19161 want the cursor type given by the frame parameter or buffer local
19162 setting of cursor-type. If explicitly marked off, draw no cursor.
19163 In all other cases, we want a hollow box cursor. */
19165 static enum text_cursor_kinds
19166 get_window_cursor_type (w, glyph, width, active_cursor)
19167 struct window *w;
19168 struct glyph *glyph;
19169 int *width;
19170 int *active_cursor;
19172 struct frame *f = XFRAME (w->frame);
19173 struct buffer *b = XBUFFER (w->buffer);
19174 int cursor_type = DEFAULT_CURSOR;
19175 Lisp_Object alt_cursor;
19176 int non_selected = 0;
19178 *active_cursor = 1;
19180 /* Echo area */
19181 if (cursor_in_echo_area
19182 && FRAME_HAS_MINIBUF_P (f)
19183 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
19185 if (w == XWINDOW (echo_area_window))
19187 *width = FRAME_CURSOR_WIDTH (f);
19188 return FRAME_DESIRED_CURSOR (f);
19191 *active_cursor = 0;
19192 non_selected = 1;
19195 /* Nonselected window or nonselected frame. */
19196 else if (w != XWINDOW (f->selected_window)
19197 #ifdef HAVE_WINDOW_SYSTEM
19198 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
19199 #endif
19202 *active_cursor = 0;
19204 if (MINI_WINDOW_P (w) && minibuf_level == 0)
19205 return NO_CURSOR;
19207 non_selected = 1;
19210 /* Never display a cursor in a window in which cursor-type is nil. */
19211 if (NILP (b->cursor_type))
19212 return NO_CURSOR;
19214 /* Use cursor-in-non-selected-windows for non-selected window or frame. */
19215 if (non_selected)
19217 alt_cursor = Fbuffer_local_value (Qcursor_in_non_selected_windows, w->buffer);
19218 return get_specified_cursor_type (alt_cursor, width);
19221 /* Get the normal cursor type for this window. */
19222 if (EQ (b->cursor_type, Qt))
19224 cursor_type = FRAME_DESIRED_CURSOR (f);
19225 *width = FRAME_CURSOR_WIDTH (f);
19227 else
19228 cursor_type = get_specified_cursor_type (b->cursor_type, width);
19230 /* Use normal cursor if not blinked off. */
19231 if (!w->cursor_off_p)
19233 if (glyph != NULL && glyph->type == IMAGE_GLYPH) {
19234 if (cursor_type == FILLED_BOX_CURSOR)
19235 cursor_type = HOLLOW_BOX_CURSOR;
19237 return cursor_type;
19240 /* Cursor is blinked off, so determine how to "toggle" it. */
19242 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
19243 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
19244 return get_specified_cursor_type (XCDR (alt_cursor), width);
19246 /* Then see if frame has specified a specific blink off cursor type. */
19247 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
19249 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
19250 return FRAME_BLINK_OFF_CURSOR (f);
19253 #if 0
19254 /* Some people liked having a permanently visible blinking cursor,
19255 while others had very strong opinions against it. So it was
19256 decided to remove it. KFS 2003-09-03 */
19258 /* Finally perform built-in cursor blinking:
19259 filled box <-> hollow box
19260 wide [h]bar <-> narrow [h]bar
19261 narrow [h]bar <-> no cursor
19262 other type <-> no cursor */
19264 if (cursor_type == FILLED_BOX_CURSOR)
19265 return HOLLOW_BOX_CURSOR;
19267 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
19269 *width = 1;
19270 return cursor_type;
19272 #endif
19274 return NO_CURSOR;
19278 #ifdef HAVE_WINDOW_SYSTEM
19280 /* Notice when the text cursor of window W has been completely
19281 overwritten by a drawing operation that outputs glyphs in AREA
19282 starting at X0 and ending at X1 in the line starting at Y0 and
19283 ending at Y1. X coordinates are area-relative. X1 < 0 means all
19284 the rest of the line after X0 has been written. Y coordinates
19285 are window-relative. */
19287 static void
19288 notice_overwritten_cursor (w, area, x0, x1, y0, y1)
19289 struct window *w;
19290 enum glyph_row_area area;
19291 int x0, y0, x1, y1;
19293 int cx0, cx1, cy0, cy1;
19294 struct glyph_row *row;
19296 if (!w->phys_cursor_on_p)
19297 return;
19298 if (area != TEXT_AREA)
19299 return;
19301 row = w->current_matrix->rows + w->phys_cursor.vpos;
19302 if (!row->displays_text_p)
19303 return;
19305 if (row->cursor_in_fringe_p)
19307 row->cursor_in_fringe_p = 0;
19308 draw_fringe_bitmap (w, row, 0);
19309 w->phys_cursor_on_p = 0;
19310 return;
19313 cx0 = w->phys_cursor.x;
19314 cx1 = cx0 + w->phys_cursor_width;
19315 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
19316 return;
19318 /* The cursor image will be completely removed from the
19319 screen if the output area intersects the cursor area in
19320 y-direction. When we draw in [y0 y1[, and some part of
19321 the cursor is at y < y0, that part must have been drawn
19322 before. When scrolling, the cursor is erased before
19323 actually scrolling, so we don't come here. When not
19324 scrolling, the rows above the old cursor row must have
19325 changed, and in this case these rows must have written
19326 over the cursor image.
19328 Likewise if part of the cursor is below y1, with the
19329 exception of the cursor being in the first blank row at
19330 the buffer and window end because update_text_area
19331 doesn't draw that row. (Except when it does, but
19332 that's handled in update_text_area.) */
19334 cy0 = w->phys_cursor.y;
19335 cy1 = cy0 + w->phys_cursor_height;
19336 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
19337 return;
19339 w->phys_cursor_on_p = 0;
19342 #endif /* HAVE_WINDOW_SYSTEM */
19345 /************************************************************************
19346 Mouse Face
19347 ************************************************************************/
19349 #ifdef HAVE_WINDOW_SYSTEM
19351 /* EXPORT for RIF:
19352 Fix the display of area AREA of overlapping row ROW in window W. */
19354 void
19355 x_fix_overlapping_area (w, row, area)
19356 struct window *w;
19357 struct glyph_row *row;
19358 enum glyph_row_area area;
19360 int i, x;
19362 BLOCK_INPUT;
19364 x = 0;
19365 for (i = 0; i < row->used[area];)
19367 if (row->glyphs[area][i].overlaps_vertically_p)
19369 int start = i, start_x = x;
19373 x += row->glyphs[area][i].pixel_width;
19374 ++i;
19376 while (i < row->used[area]
19377 && row->glyphs[area][i].overlaps_vertically_p);
19379 draw_glyphs (w, start_x, row, area,
19380 start, i,
19381 DRAW_NORMAL_TEXT, 1);
19383 else
19385 x += row->glyphs[area][i].pixel_width;
19386 ++i;
19390 UNBLOCK_INPUT;
19394 /* EXPORT:
19395 Draw the cursor glyph of window W in glyph row ROW. See the
19396 comment of draw_glyphs for the meaning of HL. */
19398 void
19399 draw_phys_cursor_glyph (w, row, hl)
19400 struct window *w;
19401 struct glyph_row *row;
19402 enum draw_glyphs_face hl;
19404 /* If cursor hpos is out of bounds, don't draw garbage. This can
19405 happen in mini-buffer windows when switching between echo area
19406 glyphs and mini-buffer. */
19407 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
19409 int on_p = w->phys_cursor_on_p;
19410 int x1;
19411 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
19412 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
19413 hl, 0);
19414 w->phys_cursor_on_p = on_p;
19416 if (hl == DRAW_CURSOR)
19417 w->phys_cursor_width = x1 - w->phys_cursor.x;
19418 /* When we erase the cursor, and ROW is overlapped by other
19419 rows, make sure that these overlapping parts of other rows
19420 are redrawn. */
19421 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
19423 if (row > w->current_matrix->rows
19424 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
19425 x_fix_overlapping_area (w, row - 1, TEXT_AREA);
19427 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
19428 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
19429 x_fix_overlapping_area (w, row + 1, TEXT_AREA);
19435 /* EXPORT:
19436 Erase the image of a cursor of window W from the screen. */
19438 void
19439 erase_phys_cursor (w)
19440 struct window *w;
19442 struct frame *f = XFRAME (w->frame);
19443 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
19444 int hpos = w->phys_cursor.hpos;
19445 int vpos = w->phys_cursor.vpos;
19446 int mouse_face_here_p = 0;
19447 struct glyph_matrix *active_glyphs = w->current_matrix;
19448 struct glyph_row *cursor_row;
19449 struct glyph *cursor_glyph;
19450 enum draw_glyphs_face hl;
19452 /* No cursor displayed or row invalidated => nothing to do on the
19453 screen. */
19454 if (w->phys_cursor_type == NO_CURSOR)
19455 goto mark_cursor_off;
19457 /* VPOS >= active_glyphs->nrows means that window has been resized.
19458 Don't bother to erase the cursor. */
19459 if (vpos >= active_glyphs->nrows)
19460 goto mark_cursor_off;
19462 /* If row containing cursor is marked invalid, there is nothing we
19463 can do. */
19464 cursor_row = MATRIX_ROW (active_glyphs, vpos);
19465 if (!cursor_row->enabled_p)
19466 goto mark_cursor_off;
19468 /* If row is completely invisible, don't attempt to delete a cursor which
19469 isn't there. This can happen if cursor is at top of a window, and
19470 we switch to a buffer with a header line in that window. */
19471 if (cursor_row->visible_height <= 0)
19472 goto mark_cursor_off;
19474 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
19475 if (cursor_row->cursor_in_fringe_p)
19477 cursor_row->cursor_in_fringe_p = 0;
19478 draw_fringe_bitmap (w, cursor_row, 0);
19479 goto mark_cursor_off;
19482 /* This can happen when the new row is shorter than the old one.
19483 In this case, either draw_glyphs or clear_end_of_line
19484 should have cleared the cursor. Note that we wouldn't be
19485 able to erase the cursor in this case because we don't have a
19486 cursor glyph at hand. */
19487 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
19488 goto mark_cursor_off;
19490 /* If the cursor is in the mouse face area, redisplay that when
19491 we clear the cursor. */
19492 if (! NILP (dpyinfo->mouse_face_window)
19493 && w == XWINDOW (dpyinfo->mouse_face_window)
19494 && (vpos > dpyinfo->mouse_face_beg_row
19495 || (vpos == dpyinfo->mouse_face_beg_row
19496 && hpos >= dpyinfo->mouse_face_beg_col))
19497 && (vpos < dpyinfo->mouse_face_end_row
19498 || (vpos == dpyinfo->mouse_face_end_row
19499 && hpos < dpyinfo->mouse_face_end_col))
19500 /* Don't redraw the cursor's spot in mouse face if it is at the
19501 end of a line (on a newline). The cursor appears there, but
19502 mouse highlighting does not. */
19503 && cursor_row->used[TEXT_AREA] > hpos)
19504 mouse_face_here_p = 1;
19506 /* Maybe clear the display under the cursor. */
19507 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
19509 int x, y;
19510 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
19512 cursor_glyph = get_phys_cursor_glyph (w);
19513 if (cursor_glyph == NULL)
19514 goto mark_cursor_off;
19516 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
19517 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
19519 rif->clear_frame_area (f, x, y,
19520 cursor_glyph->pixel_width, cursor_row->visible_height);
19523 /* Erase the cursor by redrawing the character underneath it. */
19524 if (mouse_face_here_p)
19525 hl = DRAW_MOUSE_FACE;
19526 else
19527 hl = DRAW_NORMAL_TEXT;
19528 draw_phys_cursor_glyph (w, cursor_row, hl);
19530 mark_cursor_off:
19531 w->phys_cursor_on_p = 0;
19532 w->phys_cursor_type = NO_CURSOR;
19536 /* EXPORT:
19537 Display or clear cursor of window W. If ON is zero, clear the
19538 cursor. If it is non-zero, display the cursor. If ON is nonzero,
19539 where to put the cursor is specified by HPOS, VPOS, X and Y. */
19541 void
19542 display_and_set_cursor (w, on, hpos, vpos, x, y)
19543 struct window *w;
19544 int on, hpos, vpos, x, y;
19546 struct frame *f = XFRAME (w->frame);
19547 int new_cursor_type;
19548 int new_cursor_width;
19549 int active_cursor;
19550 struct glyph_row *glyph_row;
19551 struct glyph *glyph;
19553 /* This is pointless on invisible frames, and dangerous on garbaged
19554 windows and frames; in the latter case, the frame or window may
19555 be in the midst of changing its size, and x and y may be off the
19556 window. */
19557 if (! FRAME_VISIBLE_P (f)
19558 || FRAME_GARBAGED_P (f)
19559 || vpos >= w->current_matrix->nrows
19560 || hpos >= w->current_matrix->matrix_w)
19561 return;
19563 /* If cursor is off and we want it off, return quickly. */
19564 if (!on && !w->phys_cursor_on_p)
19565 return;
19567 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
19568 /* If cursor row is not enabled, we don't really know where to
19569 display the cursor. */
19570 if (!glyph_row->enabled_p)
19572 w->phys_cursor_on_p = 0;
19573 return;
19576 glyph = NULL;
19577 if (!glyph_row->exact_window_width_line_p
19578 || hpos < glyph_row->used[TEXT_AREA])
19579 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
19581 xassert (interrupt_input_blocked);
19583 /* Set new_cursor_type to the cursor we want to be displayed. */
19584 new_cursor_type = get_window_cursor_type (w, glyph,
19585 &new_cursor_width, &active_cursor);
19587 /* If cursor is currently being shown and we don't want it to be or
19588 it is in the wrong place, or the cursor type is not what we want,
19589 erase it. */
19590 if (w->phys_cursor_on_p
19591 && (!on
19592 || w->phys_cursor.x != x
19593 || w->phys_cursor.y != y
19594 || new_cursor_type != w->phys_cursor_type
19595 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
19596 && new_cursor_width != w->phys_cursor_width)))
19597 erase_phys_cursor (w);
19599 /* Don't check phys_cursor_on_p here because that flag is only set
19600 to zero in some cases where we know that the cursor has been
19601 completely erased, to avoid the extra work of erasing the cursor
19602 twice. In other words, phys_cursor_on_p can be 1 and the cursor
19603 still not be visible, or it has only been partly erased. */
19604 if (on)
19606 w->phys_cursor_ascent = glyph_row->ascent;
19607 w->phys_cursor_height = glyph_row->height;
19609 /* Set phys_cursor_.* before x_draw_.* is called because some
19610 of them may need the information. */
19611 w->phys_cursor.x = x;
19612 w->phys_cursor.y = glyph_row->y;
19613 w->phys_cursor.hpos = hpos;
19614 w->phys_cursor.vpos = vpos;
19617 rif->draw_window_cursor (w, glyph_row, x, y,
19618 new_cursor_type, new_cursor_width,
19619 on, active_cursor);
19623 /* Switch the display of W's cursor on or off, according to the value
19624 of ON. */
19626 static void
19627 update_window_cursor (w, on)
19628 struct window *w;
19629 int on;
19631 /* Don't update cursor in windows whose frame is in the process
19632 of being deleted. */
19633 if (w->current_matrix)
19635 BLOCK_INPUT;
19636 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
19637 w->phys_cursor.x, w->phys_cursor.y);
19638 UNBLOCK_INPUT;
19643 /* Call update_window_cursor with parameter ON_P on all leaf windows
19644 in the window tree rooted at W. */
19646 static void
19647 update_cursor_in_window_tree (w, on_p)
19648 struct window *w;
19649 int on_p;
19651 while (w)
19653 if (!NILP (w->hchild))
19654 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
19655 else if (!NILP (w->vchild))
19656 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
19657 else
19658 update_window_cursor (w, on_p);
19660 w = NILP (w->next) ? 0 : XWINDOW (w->next);
19665 /* EXPORT:
19666 Display the cursor on window W, or clear it, according to ON_P.
19667 Don't change the cursor's position. */
19669 void
19670 x_update_cursor (f, on_p)
19671 struct frame *f;
19672 int on_p;
19674 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
19678 /* EXPORT:
19679 Clear the cursor of window W to background color, and mark the
19680 cursor as not shown. This is used when the text where the cursor
19681 is is about to be rewritten. */
19683 void
19684 x_clear_cursor (w)
19685 struct window *w;
19687 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
19688 update_window_cursor (w, 0);
19692 /* EXPORT:
19693 Display the active region described by mouse_face_* according to DRAW. */
19695 void
19696 show_mouse_face (dpyinfo, draw)
19697 Display_Info *dpyinfo;
19698 enum draw_glyphs_face draw;
19700 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
19701 struct frame *f = XFRAME (WINDOW_FRAME (w));
19703 if (/* If window is in the process of being destroyed, don't bother
19704 to do anything. */
19705 w->current_matrix != NULL
19706 /* Don't update mouse highlight if hidden */
19707 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
19708 /* Recognize when we are called to operate on rows that don't exist
19709 anymore. This can happen when a window is split. */
19710 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
19712 int phys_cursor_on_p = w->phys_cursor_on_p;
19713 struct glyph_row *row, *first, *last;
19715 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
19716 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
19718 for (row = first; row <= last && row->enabled_p; ++row)
19720 int start_hpos, end_hpos, start_x;
19722 /* For all but the first row, the highlight starts at column 0. */
19723 if (row == first)
19725 start_hpos = dpyinfo->mouse_face_beg_col;
19726 start_x = dpyinfo->mouse_face_beg_x;
19728 else
19730 start_hpos = 0;
19731 start_x = 0;
19734 if (row == last)
19735 end_hpos = dpyinfo->mouse_face_end_col;
19736 else
19737 end_hpos = row->used[TEXT_AREA];
19739 if (end_hpos > start_hpos)
19741 draw_glyphs (w, start_x, row, TEXT_AREA,
19742 start_hpos, end_hpos,
19743 draw, 0);
19745 row->mouse_face_p
19746 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
19750 /* When we've written over the cursor, arrange for it to
19751 be displayed again. */
19752 if (phys_cursor_on_p && !w->phys_cursor_on_p)
19754 BLOCK_INPUT;
19755 display_and_set_cursor (w, 1,
19756 w->phys_cursor.hpos, w->phys_cursor.vpos,
19757 w->phys_cursor.x, w->phys_cursor.y);
19758 UNBLOCK_INPUT;
19762 /* Change the mouse cursor. */
19763 if (draw == DRAW_NORMAL_TEXT)
19764 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
19765 else if (draw == DRAW_MOUSE_FACE)
19766 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
19767 else
19768 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
19771 /* EXPORT:
19772 Clear out the mouse-highlighted active region.
19773 Redraw it un-highlighted first. Value is non-zero if mouse
19774 face was actually drawn unhighlighted. */
19777 clear_mouse_face (dpyinfo)
19778 Display_Info *dpyinfo;
19780 int cleared = 0;
19782 if (!NILP (dpyinfo->mouse_face_window))
19784 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
19785 cleared = 1;
19788 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
19789 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
19790 dpyinfo->mouse_face_window = Qnil;
19791 dpyinfo->mouse_face_overlay = Qnil;
19792 return cleared;
19796 /* EXPORT:
19797 Non-zero if physical cursor of window W is within mouse face. */
19800 cursor_in_mouse_face_p (w)
19801 struct window *w;
19803 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
19804 int in_mouse_face = 0;
19806 if (WINDOWP (dpyinfo->mouse_face_window)
19807 && XWINDOW (dpyinfo->mouse_face_window) == w)
19809 int hpos = w->phys_cursor.hpos;
19810 int vpos = w->phys_cursor.vpos;
19812 if (vpos >= dpyinfo->mouse_face_beg_row
19813 && vpos <= dpyinfo->mouse_face_end_row
19814 && (vpos > dpyinfo->mouse_face_beg_row
19815 || hpos >= dpyinfo->mouse_face_beg_col)
19816 && (vpos < dpyinfo->mouse_face_end_row
19817 || hpos < dpyinfo->mouse_face_end_col
19818 || dpyinfo->mouse_face_past_end))
19819 in_mouse_face = 1;
19822 return in_mouse_face;
19828 /* Find the glyph matrix position of buffer position CHARPOS in window
19829 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
19830 current glyphs must be up to date. If CHARPOS is above window
19831 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
19832 of last line in W. In the row containing CHARPOS, stop before glyphs
19833 having STOP as object. */
19835 #if 1 /* This is a version of fast_find_position that's more correct
19836 in the presence of hscrolling, for example. I didn't install
19837 it right away because the problem fixed is minor, it failed
19838 in 20.x as well, and I think it's too risky to install
19839 so near the release of 21.1. 2001-09-25 gerd. */
19841 static int
19842 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
19843 struct window *w;
19844 int charpos;
19845 int *hpos, *vpos, *x, *y;
19846 Lisp_Object stop;
19848 struct glyph_row *row, *first;
19849 struct glyph *glyph, *end;
19850 int past_end = 0;
19852 first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
19853 row = row_containing_pos (w, charpos, first, NULL, 0);
19854 if (row == NULL)
19856 if (charpos < MATRIX_ROW_START_CHARPOS (first))
19858 *x = *y = *hpos = *vpos = 0;
19859 return 1;
19861 else
19863 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
19864 past_end = 1;
19868 *x = row->x;
19869 *y = row->y;
19870 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
19872 glyph = row->glyphs[TEXT_AREA];
19873 end = glyph + row->used[TEXT_AREA];
19875 /* Skip over glyphs not having an object at the start of the row.
19876 These are special glyphs like truncation marks on terminal
19877 frames. */
19878 if (row->displays_text_p)
19879 while (glyph < end
19880 && INTEGERP (glyph->object)
19881 && !EQ (stop, glyph->object)
19882 && glyph->charpos < 0)
19884 *x += glyph->pixel_width;
19885 ++glyph;
19888 while (glyph < end
19889 && !INTEGERP (glyph->object)
19890 && !EQ (stop, glyph->object)
19891 && (!BUFFERP (glyph->object)
19892 || glyph->charpos < charpos))
19894 *x += glyph->pixel_width;
19895 ++glyph;
19898 *hpos = glyph - row->glyphs[TEXT_AREA];
19899 return !past_end;
19902 #else /* not 1 */
19904 static int
19905 fast_find_position (w, pos, hpos, vpos, x, y, stop)
19906 struct window *w;
19907 int pos;
19908 int *hpos, *vpos, *x, *y;
19909 Lisp_Object stop;
19911 int i;
19912 int lastcol;
19913 int maybe_next_line_p = 0;
19914 int line_start_position;
19915 int yb = window_text_bottom_y (w);
19916 struct glyph_row *row, *best_row;
19917 int row_vpos, best_row_vpos;
19918 int current_x;
19920 row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
19921 row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
19923 while (row->y < yb)
19925 if (row->used[TEXT_AREA])
19926 line_start_position = row->glyphs[TEXT_AREA]->charpos;
19927 else
19928 line_start_position = 0;
19930 if (line_start_position > pos)
19931 break;
19932 /* If the position sought is the end of the buffer,
19933 don't include the blank lines at the bottom of the window. */
19934 else if (line_start_position == pos
19935 && pos == BUF_ZV (XBUFFER (w->buffer)))
19937 maybe_next_line_p = 1;
19938 break;
19940 else if (line_start_position > 0)
19942 best_row = row;
19943 best_row_vpos = row_vpos;
19946 if (row->y + row->height >= yb)
19947 break;
19949 ++row;
19950 ++row_vpos;
19953 /* Find the right column within BEST_ROW. */
19954 lastcol = 0;
19955 current_x = best_row->x;
19956 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
19958 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
19959 int charpos = glyph->charpos;
19961 if (BUFFERP (glyph->object))
19963 if (charpos == pos)
19965 *hpos = i;
19966 *vpos = best_row_vpos;
19967 *x = current_x;
19968 *y = best_row->y;
19969 return 1;
19971 else if (charpos > pos)
19972 break;
19974 else if (EQ (glyph->object, stop))
19975 break;
19977 if (charpos > 0)
19978 lastcol = i;
19979 current_x += glyph->pixel_width;
19982 /* If we're looking for the end of the buffer,
19983 and we didn't find it in the line we scanned,
19984 use the start of the following line. */
19985 if (maybe_next_line_p)
19987 ++best_row;
19988 ++best_row_vpos;
19989 lastcol = 0;
19990 current_x = best_row->x;
19993 *vpos = best_row_vpos;
19994 *hpos = lastcol + 1;
19995 *x = current_x;
19996 *y = best_row->y;
19997 return 0;
20000 #endif /* not 1 */
20003 /* Find the position of the glyph for position POS in OBJECT in
20004 window W's current matrix, and return in *X, *Y the pixel
20005 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
20007 RIGHT_P non-zero means return the position of the right edge of the
20008 glyph, RIGHT_P zero means return the left edge position.
20010 If no glyph for POS exists in the matrix, return the position of
20011 the glyph with the next smaller position that is in the matrix, if
20012 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
20013 exists in the matrix, return the position of the glyph with the
20014 next larger position in OBJECT.
20016 Value is non-zero if a glyph was found. */
20018 static int
20019 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
20020 struct window *w;
20021 int pos;
20022 Lisp_Object object;
20023 int *hpos, *vpos, *x, *y;
20024 int right_p;
20026 int yb = window_text_bottom_y (w);
20027 struct glyph_row *r;
20028 struct glyph *best_glyph = NULL;
20029 struct glyph_row *best_row = NULL;
20030 int best_x = 0;
20032 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20033 r->enabled_p && r->y < yb;
20034 ++r)
20036 struct glyph *g = r->glyphs[TEXT_AREA];
20037 struct glyph *e = g + r->used[TEXT_AREA];
20038 int gx;
20040 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
20041 if (EQ (g->object, object))
20043 if (g->charpos == pos)
20045 best_glyph = g;
20046 best_x = gx;
20047 best_row = r;
20048 goto found;
20050 else if (best_glyph == NULL
20051 || ((abs (g->charpos - pos)
20052 < abs (best_glyph->charpos - pos))
20053 && (right_p
20054 ? g->charpos < pos
20055 : g->charpos > pos)))
20057 best_glyph = g;
20058 best_x = gx;
20059 best_row = r;
20064 found:
20066 if (best_glyph)
20068 *x = best_x;
20069 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
20071 if (right_p)
20073 *x += best_glyph->pixel_width;
20074 ++*hpos;
20077 *y = best_row->y;
20078 *vpos = best_row - w->current_matrix->rows;
20081 return best_glyph != NULL;
20085 /* See if position X, Y is within a hot-spot of an image. */
20087 static int
20088 on_hot_spot_p (hot_spot, x, y)
20089 Lisp_Object hot_spot;
20090 int x, y;
20092 if (!CONSP (hot_spot))
20093 return 0;
20095 if (EQ (XCAR (hot_spot), Qrect))
20097 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
20098 Lisp_Object rect = XCDR (hot_spot);
20099 Lisp_Object tem;
20100 if (!CONSP (rect))
20101 return 0;
20102 if (!CONSP (XCAR (rect)))
20103 return 0;
20104 if (!CONSP (XCDR (rect)))
20105 return 0;
20106 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
20107 return 0;
20108 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
20109 return 0;
20110 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
20111 return 0;
20112 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
20113 return 0;
20114 return 1;
20116 else if (EQ (XCAR (hot_spot), Qcircle))
20118 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
20119 Lisp_Object circ = XCDR (hot_spot);
20120 Lisp_Object lr, lx0, ly0;
20121 if (CONSP (circ)
20122 && CONSP (XCAR (circ))
20123 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
20124 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
20125 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
20127 double r = XFLOATINT (lr);
20128 double dx = XINT (lx0) - x;
20129 double dy = XINT (ly0) - y;
20130 return (dx * dx + dy * dy <= r * r);
20133 else if (EQ (XCAR (hot_spot), Qpoly))
20135 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
20136 if (VECTORP (XCDR (hot_spot)))
20138 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
20139 Lisp_Object *poly = v->contents;
20140 int n = v->size;
20141 int i;
20142 int inside = 0;
20143 Lisp_Object lx, ly;
20144 int x0, y0;
20146 /* Need an even number of coordinates, and at least 3 edges. */
20147 if (n < 6 || n & 1)
20148 return 0;
20150 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
20151 If count is odd, we are inside polygon. Pixels on edges
20152 may or may not be included depending on actual geometry of the
20153 polygon. */
20154 if ((lx = poly[n-2], !INTEGERP (lx))
20155 || (ly = poly[n-1], !INTEGERP (lx)))
20156 return 0;
20157 x0 = XINT (lx), y0 = XINT (ly);
20158 for (i = 0; i < n; i += 2)
20160 int x1 = x0, y1 = y0;
20161 if ((lx = poly[i], !INTEGERP (lx))
20162 || (ly = poly[i+1], !INTEGERP (ly)))
20163 return 0;
20164 x0 = XINT (lx), y0 = XINT (ly);
20166 /* Does this segment cross the X line? */
20167 if (x0 >= x)
20169 if (x1 >= x)
20170 continue;
20172 else if (x1 < x)
20173 continue;
20174 if (y > y0 && y > y1)
20175 continue;
20176 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
20177 inside = !inside;
20179 return inside;
20182 else
20183 return 0;
20186 Lisp_Object
20187 find_hot_spot (map, x, y)
20188 Lisp_Object map;
20189 int x, y;
20191 while (CONSP (map))
20193 if (CONSP (XCAR (map))
20194 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
20195 return XCAR (map);
20196 map = XCDR (map);
20199 return Qnil;
20202 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
20203 3, 3, 0,
20204 doc: /* Lookup in image map MAP coordinates X and Y.
20205 An image map is an alist where each element has the format (AREA ID PLIST).
20206 An AREA is specified as either a rectangle, a circle, or a polygon:
20207 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
20208 pixel coordinates of the upper left and bottom right corners.
20209 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
20210 and the radius of the circle; r may be a float or integer.
20211 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
20212 vector describes one corner in the polygon.
20213 Returns the alist element for the first matching AREA in MAP. */)
20214 (map, x, y)
20215 Lisp_Object map;
20216 Lisp_Object x, y;
20218 int ix, iy;
20219 if (NILP (map))
20220 return Qnil;
20222 CHECK_NUMBER (x);
20223 CHECK_NUMBER (y);
20225 return find_hot_spot (map, XINT (x), XINT (y));
20229 /* Display frame CURSOR, optionally using shape defined by POINTER. */
20230 static void
20231 define_frame_cursor1 (f, cursor, pointer)
20232 struct frame *f;
20233 Cursor cursor;
20234 Lisp_Object pointer;
20236 if (!NILP (pointer))
20238 if (EQ (pointer, Qarrow))
20239 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20240 else if (EQ (pointer, Qhand))
20241 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
20242 else if (EQ (pointer, Qtext))
20243 cursor = FRAME_X_OUTPUT (f)->text_cursor;
20244 else if (EQ (pointer, intern ("hdrag")))
20245 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
20246 #ifdef HAVE_X_WINDOWS
20247 else if (EQ (pointer, intern ("vdrag")))
20248 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
20249 #endif
20250 else if (EQ (pointer, intern ("hourglass")))
20251 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
20252 else if (EQ (pointer, Qmodeline))
20253 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
20254 else
20255 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20258 #ifndef HAVE_CARBON
20259 if (cursor != No_Cursor)
20260 #else
20261 if (bcmp (&cursor, &No_Cursor, sizeof (Cursor)))
20262 #endif
20263 rif->define_frame_cursor (f, cursor);
20266 /* Take proper action when mouse has moved to the mode or header line
20267 or marginal area AREA of window W, x-position X and y-position Y.
20268 X is relative to the start of the text display area of W, so the
20269 width of bitmap areas and scroll bars must be subtracted to get a
20270 position relative to the start of the mode line. */
20272 static void
20273 note_mode_line_or_margin_highlight (w, x, y, area)
20274 struct window *w;
20275 int x, y;
20276 enum window_part area;
20278 struct frame *f = XFRAME (w->frame);
20279 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20280 Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20281 Lisp_Object pointer = Qnil;
20282 int charpos, dx, dy, width, height;
20283 Lisp_Object string, object = Qnil;
20284 Lisp_Object pos, help, image;
20286 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
20287 string = mode_line_string (w, area, &x, &y, &charpos,
20288 &object, &dx, &dy, &width, &height);
20289 else
20291 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
20292 string = marginal_area_string (w, area, &x, &y, &charpos,
20293 &object, &dx, &dy, &width, &height);
20296 help = Qnil;
20298 if (IMAGEP (object))
20300 Lisp_Object image_map, hotspot;
20301 if ((image_map = Fplist_get (XCDR (object), QCmap),
20302 !NILP (image_map))
20303 && (hotspot = find_hot_spot (image_map, dx, dy),
20304 CONSP (hotspot))
20305 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
20307 Lisp_Object area_id, plist;
20309 area_id = XCAR (hotspot);
20310 /* Could check AREA_ID to see if we enter/leave this hot-spot.
20311 If so, we could look for mouse-enter, mouse-leave
20312 properties in PLIST (and do something...). */
20313 if ((plist = XCDR (hotspot), CONSP (plist)))
20315 pointer = Fplist_get (plist, Qpointer);
20316 if (NILP (pointer))
20317 pointer = Qhand;
20318 help = Fplist_get (plist, Qhelp_echo);
20319 if (!NILP (help))
20321 help_echo_string = help;
20322 /* Is this correct? ++kfs */
20323 XSETWINDOW (help_echo_window, w);
20324 help_echo_object = w->buffer;
20325 help_echo_pos = charpos;
20328 if (NILP (pointer))
20329 pointer = Fplist_get (XCDR (object), QCpointer);
20333 if (STRINGP (string))
20335 pos = make_number (charpos);
20336 /* If we're on a string with `help-echo' text property, arrange
20337 for the help to be displayed. This is done by setting the
20338 global variable help_echo_string to the help string. */
20339 help = Fget_text_property (pos, Qhelp_echo, string);
20340 if (!NILP (help))
20342 help_echo_string = help;
20343 XSETWINDOW (help_echo_window, w);
20344 help_echo_object = string;
20345 help_echo_pos = charpos;
20348 if (NILP (pointer))
20349 pointer = Fget_text_property (pos, Qpointer, string);
20351 /* Change the mouse pointer according to what is under X/Y. */
20352 if (NILP (pointer) && area == ON_MODE_LINE)
20354 Lisp_Object map;
20355 map = Fget_text_property (pos, Qlocal_map, string);
20356 if (!KEYMAPP (map))
20357 map = Fget_text_property (pos, Qkeymap, string);
20358 if (!KEYMAPP (map))
20359 cursor = dpyinfo->vertical_scroll_bar_cursor;
20363 define_frame_cursor1 (f, cursor, pointer);
20367 /* EXPORT:
20368 Take proper action when the mouse has moved to position X, Y on
20369 frame F as regards highlighting characters that have mouse-face
20370 properties. Also de-highlighting chars where the mouse was before.
20371 X and Y can be negative or out of range. */
20373 void
20374 note_mouse_highlight (f, x, y)
20375 struct frame *f;
20376 int x, y;
20378 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20379 enum window_part part;
20380 Lisp_Object window;
20381 struct window *w;
20382 Cursor cursor = No_Cursor;
20383 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
20384 struct buffer *b;
20386 /* When a menu is active, don't highlight because this looks odd. */
20387 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
20388 if (popup_activated ())
20389 return;
20390 #endif
20392 if (NILP (Vmouse_highlight)
20393 || !f->glyphs_initialized_p)
20394 return;
20396 dpyinfo->mouse_face_mouse_x = x;
20397 dpyinfo->mouse_face_mouse_y = y;
20398 dpyinfo->mouse_face_mouse_frame = f;
20400 if (dpyinfo->mouse_face_defer)
20401 return;
20403 if (gc_in_progress)
20405 dpyinfo->mouse_face_deferred_gc = 1;
20406 return;
20409 /* Which window is that in? */
20410 window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
20412 /* If we were displaying active text in another window, clear that. */
20413 if (! EQ (window, dpyinfo->mouse_face_window))
20414 clear_mouse_face (dpyinfo);
20416 /* Not on a window -> return. */
20417 if (!WINDOWP (window))
20418 return;
20420 /* Reset help_echo_string. It will get recomputed below. */
20421 help_echo_string = Qnil;
20423 /* Convert to window-relative pixel coordinates. */
20424 w = XWINDOW (window);
20425 frame_to_window_pixel_xy (w, &x, &y);
20427 /* Handle tool-bar window differently since it doesn't display a
20428 buffer. */
20429 if (EQ (window, f->tool_bar_window))
20431 note_tool_bar_highlight (f, x, y);
20432 return;
20435 /* Mouse is on the mode, header line or margin? */
20436 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
20437 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
20439 note_mode_line_or_margin_highlight (w, x, y, part);
20440 return;
20443 if (part == ON_VERTICAL_BORDER)
20444 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
20445 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE)
20446 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20447 else
20448 cursor = FRAME_X_OUTPUT (f)->text_cursor;
20450 /* Are we in a window whose display is up to date?
20451 And verify the buffer's text has not changed. */
20452 b = XBUFFER (w->buffer);
20453 if (part == ON_TEXT
20454 && EQ (w->window_end_valid, w->buffer)
20455 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
20456 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
20458 int hpos, vpos, pos, i, dx, dy, area;
20459 struct glyph *glyph;
20460 Lisp_Object object;
20461 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
20462 Lisp_Object *overlay_vec = NULL;
20463 int len, noverlays;
20464 struct buffer *obuf;
20465 int obegv, ozv, same_region;
20467 /* Find the glyph under X/Y. */
20468 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
20470 /* Look for :pointer property on image. */
20471 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
20473 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
20474 if (img != NULL && IMAGEP (img->spec))
20476 Lisp_Object image_map, hotspot;
20477 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
20478 !NILP (image_map))
20479 && (hotspot = find_hot_spot (image_map, dx, dy),
20480 CONSP (hotspot))
20481 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
20483 Lisp_Object area_id, plist;
20485 area_id = XCAR (hotspot);
20486 /* Could check AREA_ID to see if we enter/leave this hot-spot.
20487 If so, we could look for mouse-enter, mouse-leave
20488 properties in PLIST (and do something...). */
20489 if ((plist = XCDR (hotspot), CONSP (plist)))
20491 pointer = Fplist_get (plist, Qpointer);
20492 if (NILP (pointer))
20493 pointer = Qhand;
20494 help_echo_string = Fplist_get (plist, Qhelp_echo);
20495 if (!NILP (help_echo_string))
20497 help_echo_window = window;
20498 help_echo_object = glyph->object;
20499 help_echo_pos = glyph->charpos;
20503 if (NILP (pointer))
20504 pointer = Fplist_get (XCDR (img->spec), QCpointer);
20508 /* Clear mouse face if X/Y not over text. */
20509 if (glyph == NULL
20510 || area != TEXT_AREA
20511 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
20513 if (clear_mouse_face (dpyinfo))
20514 cursor = No_Cursor;
20515 if (NILP (pointer))
20517 if (area != TEXT_AREA)
20518 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20519 else
20520 pointer = Vvoid_text_area_pointer;
20522 goto set_cursor;
20525 pos = glyph->charpos;
20526 object = glyph->object;
20527 if (!STRINGP (object) && !BUFFERP (object))
20528 goto set_cursor;
20530 /* If we get an out-of-range value, return now; avoid an error. */
20531 if (BUFFERP (object) && pos > BUF_Z (b))
20532 goto set_cursor;
20534 /* Make the window's buffer temporarily current for
20535 overlays_at and compute_char_face. */
20536 obuf = current_buffer;
20537 current_buffer = b;
20538 obegv = BEGV;
20539 ozv = ZV;
20540 BEGV = BEG;
20541 ZV = Z;
20543 /* Is this char mouse-active or does it have help-echo? */
20544 position = make_number (pos);
20546 if (BUFFERP (object))
20548 /* Put all the overlays we want in a vector in overlay_vec.
20549 Store the length in len. If there are more than 10, make
20550 enough space for all, and try again. */
20551 len = 10;
20552 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
20553 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL, 0);
20554 if (noverlays > len)
20556 len = noverlays;
20557 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
20558 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL,0);
20561 /* Sort overlays into increasing priority order. */
20562 noverlays = sort_overlays (overlay_vec, noverlays, w);
20564 else
20565 noverlays = 0;
20567 same_region = (EQ (window, dpyinfo->mouse_face_window)
20568 && vpos >= dpyinfo->mouse_face_beg_row
20569 && vpos <= dpyinfo->mouse_face_end_row
20570 && (vpos > dpyinfo->mouse_face_beg_row
20571 || hpos >= dpyinfo->mouse_face_beg_col)
20572 && (vpos < dpyinfo->mouse_face_end_row
20573 || hpos < dpyinfo->mouse_face_end_col
20574 || dpyinfo->mouse_face_past_end));
20576 if (same_region)
20577 cursor = No_Cursor;
20579 /* Check mouse-face highlighting. */
20580 if (! same_region
20581 /* If there exists an overlay with mouse-face overlapping
20582 the one we are currently highlighting, we have to
20583 check if we enter the overlapping overlay, and then
20584 highlight only that. */
20585 || (OVERLAYP (dpyinfo->mouse_face_overlay)
20586 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
20588 /* Find the highest priority overlay that has a mouse-face
20589 property. */
20590 overlay = Qnil;
20591 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
20593 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
20594 if (!NILP (mouse_face))
20595 overlay = overlay_vec[i];
20598 /* If we're actually highlighting the same overlay as
20599 before, there's no need to do that again. */
20600 if (!NILP (overlay)
20601 && EQ (overlay, dpyinfo->mouse_face_overlay))
20602 goto check_help_echo;
20604 dpyinfo->mouse_face_overlay = overlay;
20606 /* Clear the display of the old active region, if any. */
20607 if (clear_mouse_face (dpyinfo))
20608 cursor = No_Cursor;
20610 /* If no overlay applies, get a text property. */
20611 if (NILP (overlay))
20612 mouse_face = Fget_text_property (position, Qmouse_face, object);
20614 /* Handle the overlay case. */
20615 if (!NILP (overlay))
20617 /* Find the range of text around this char that
20618 should be active. */
20619 Lisp_Object before, after;
20620 int ignore;
20622 before = Foverlay_start (overlay);
20623 after = Foverlay_end (overlay);
20624 /* Record this as the current active region. */
20625 fast_find_position (w, XFASTINT (before),
20626 &dpyinfo->mouse_face_beg_col,
20627 &dpyinfo->mouse_face_beg_row,
20628 &dpyinfo->mouse_face_beg_x,
20629 &dpyinfo->mouse_face_beg_y, Qnil);
20631 dpyinfo->mouse_face_past_end
20632 = !fast_find_position (w, XFASTINT (after),
20633 &dpyinfo->mouse_face_end_col,
20634 &dpyinfo->mouse_face_end_row,
20635 &dpyinfo->mouse_face_end_x,
20636 &dpyinfo->mouse_face_end_y, Qnil);
20637 dpyinfo->mouse_face_window = window;
20639 dpyinfo->mouse_face_face_id
20640 = face_at_buffer_position (w, pos, 0, 0,
20641 &ignore, pos + 1,
20642 !dpyinfo->mouse_face_hidden);
20644 /* Display it as active. */
20645 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
20646 cursor = No_Cursor;
20648 /* Handle the text property case. */
20649 else if (!NILP (mouse_face) && BUFFERP (object))
20651 /* Find the range of text around this char that
20652 should be active. */
20653 Lisp_Object before, after, beginning, end;
20654 int ignore;
20656 beginning = Fmarker_position (w->start);
20657 end = make_number (BUF_Z (XBUFFER (object))
20658 - XFASTINT (w->window_end_pos));
20659 before
20660 = Fprevious_single_property_change (make_number (pos + 1),
20661 Qmouse_face,
20662 object, beginning);
20663 after
20664 = Fnext_single_property_change (position, Qmouse_face,
20665 object, end);
20667 /* Record this as the current active region. */
20668 fast_find_position (w, XFASTINT (before),
20669 &dpyinfo->mouse_face_beg_col,
20670 &dpyinfo->mouse_face_beg_row,
20671 &dpyinfo->mouse_face_beg_x,
20672 &dpyinfo->mouse_face_beg_y, Qnil);
20673 dpyinfo->mouse_face_past_end
20674 = !fast_find_position (w, XFASTINT (after),
20675 &dpyinfo->mouse_face_end_col,
20676 &dpyinfo->mouse_face_end_row,
20677 &dpyinfo->mouse_face_end_x,
20678 &dpyinfo->mouse_face_end_y, Qnil);
20679 dpyinfo->mouse_face_window = window;
20681 if (BUFFERP (object))
20682 dpyinfo->mouse_face_face_id
20683 = face_at_buffer_position (w, pos, 0, 0,
20684 &ignore, pos + 1,
20685 !dpyinfo->mouse_face_hidden);
20687 /* Display it as active. */
20688 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
20689 cursor = No_Cursor;
20691 else if (!NILP (mouse_face) && STRINGP (object))
20693 Lisp_Object b, e;
20694 int ignore;
20696 b = Fprevious_single_property_change (make_number (pos + 1),
20697 Qmouse_face,
20698 object, Qnil);
20699 e = Fnext_single_property_change (position, Qmouse_face,
20700 object, Qnil);
20701 if (NILP (b))
20702 b = make_number (0);
20703 if (NILP (e))
20704 e = make_number (SCHARS (object) - 1);
20705 fast_find_string_pos (w, XINT (b), object,
20706 &dpyinfo->mouse_face_beg_col,
20707 &dpyinfo->mouse_face_beg_row,
20708 &dpyinfo->mouse_face_beg_x,
20709 &dpyinfo->mouse_face_beg_y, 0);
20710 fast_find_string_pos (w, XINT (e), object,
20711 &dpyinfo->mouse_face_end_col,
20712 &dpyinfo->mouse_face_end_row,
20713 &dpyinfo->mouse_face_end_x,
20714 &dpyinfo->mouse_face_end_y, 1);
20715 dpyinfo->mouse_face_past_end = 0;
20716 dpyinfo->mouse_face_window = window;
20717 dpyinfo->mouse_face_face_id
20718 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
20719 glyph->face_id, 1);
20720 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
20721 cursor = No_Cursor;
20723 else if (STRINGP (object) && NILP (mouse_face))
20725 /* A string which doesn't have mouse-face, but
20726 the text ``under'' it might have. */
20727 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
20728 int start = MATRIX_ROW_START_CHARPOS (r);
20730 pos = string_buffer_position (w, object, start);
20731 if (pos > 0)
20732 mouse_face = get_char_property_and_overlay (make_number (pos),
20733 Qmouse_face,
20734 w->buffer,
20735 &overlay);
20736 if (!NILP (mouse_face) && !NILP (overlay))
20738 Lisp_Object before = Foverlay_start (overlay);
20739 Lisp_Object after = Foverlay_end (overlay);
20740 int ignore;
20742 /* Note that we might not be able to find position
20743 BEFORE in the glyph matrix if the overlay is
20744 entirely covered by a `display' property. In
20745 this case, we overshoot. So let's stop in
20746 the glyph matrix before glyphs for OBJECT. */
20747 fast_find_position (w, XFASTINT (before),
20748 &dpyinfo->mouse_face_beg_col,
20749 &dpyinfo->mouse_face_beg_row,
20750 &dpyinfo->mouse_face_beg_x,
20751 &dpyinfo->mouse_face_beg_y,
20752 object);
20754 dpyinfo->mouse_face_past_end
20755 = !fast_find_position (w, XFASTINT (after),
20756 &dpyinfo->mouse_face_end_col,
20757 &dpyinfo->mouse_face_end_row,
20758 &dpyinfo->mouse_face_end_x,
20759 &dpyinfo->mouse_face_end_y,
20760 Qnil);
20761 dpyinfo->mouse_face_window = window;
20762 dpyinfo->mouse_face_face_id
20763 = face_at_buffer_position (w, pos, 0, 0,
20764 &ignore, pos + 1,
20765 !dpyinfo->mouse_face_hidden);
20767 /* Display it as active. */
20768 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
20769 cursor = No_Cursor;
20774 check_help_echo:
20776 /* Look for a `help-echo' property. */
20777 if (NILP (help_echo_string)) {
20778 Lisp_Object help, overlay;
20780 /* Check overlays first. */
20781 help = overlay = Qnil;
20782 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
20784 overlay = overlay_vec[i];
20785 help = Foverlay_get (overlay, Qhelp_echo);
20788 if (!NILP (help))
20790 help_echo_string = help;
20791 help_echo_window = window;
20792 help_echo_object = overlay;
20793 help_echo_pos = pos;
20795 else
20797 Lisp_Object object = glyph->object;
20798 int charpos = glyph->charpos;
20800 /* Try text properties. */
20801 if (STRINGP (object)
20802 && charpos >= 0
20803 && charpos < SCHARS (object))
20805 help = Fget_text_property (make_number (charpos),
20806 Qhelp_echo, object);
20807 if (NILP (help))
20809 /* If the string itself doesn't specify a help-echo,
20810 see if the buffer text ``under'' it does. */
20811 struct glyph_row *r
20812 = MATRIX_ROW (w->current_matrix, vpos);
20813 int start = MATRIX_ROW_START_CHARPOS (r);
20814 int pos = string_buffer_position (w, object, start);
20815 if (pos > 0)
20817 help = Fget_char_property (make_number (pos),
20818 Qhelp_echo, w->buffer);
20819 if (!NILP (help))
20821 charpos = pos;
20822 object = w->buffer;
20827 else if (BUFFERP (object)
20828 && charpos >= BEGV
20829 && charpos < ZV)
20830 help = Fget_text_property (make_number (charpos), Qhelp_echo,
20831 object);
20833 if (!NILP (help))
20835 help_echo_string = help;
20836 help_echo_window = window;
20837 help_echo_object = object;
20838 help_echo_pos = charpos;
20843 /* Look for a `pointer' property. */
20844 if (NILP (pointer))
20846 /* Check overlays first. */
20847 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
20848 pointer = Foverlay_get (overlay_vec[i], Qpointer);
20850 if (NILP (pointer))
20852 Lisp_Object object = glyph->object;
20853 int charpos = glyph->charpos;
20855 /* Try text properties. */
20856 if (STRINGP (object)
20857 && charpos >= 0
20858 && charpos < SCHARS (object))
20860 pointer = Fget_text_property (make_number (charpos),
20861 Qpointer, object);
20862 if (NILP (pointer))
20864 /* If the string itself doesn't specify a pointer,
20865 see if the buffer text ``under'' it does. */
20866 struct glyph_row *r
20867 = MATRIX_ROW (w->current_matrix, vpos);
20868 int start = MATRIX_ROW_START_CHARPOS (r);
20869 int pos = string_buffer_position (w, object, start);
20870 if (pos > 0)
20871 pointer = Fget_char_property (make_number (pos),
20872 Qpointer, w->buffer);
20875 else if (BUFFERP (object)
20876 && charpos >= BEGV
20877 && charpos < ZV)
20878 pointer = Fget_text_property (make_number (charpos),
20879 Qpointer, object);
20883 BEGV = obegv;
20884 ZV = ozv;
20885 current_buffer = obuf;
20888 set_cursor:
20890 define_frame_cursor1 (f, cursor, pointer);
20894 /* EXPORT for RIF:
20895 Clear any mouse-face on window W. This function is part of the
20896 redisplay interface, and is called from try_window_id and similar
20897 functions to ensure the mouse-highlight is off. */
20899 void
20900 x_clear_window_mouse_face (w)
20901 struct window *w;
20903 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
20904 Lisp_Object window;
20906 BLOCK_INPUT;
20907 XSETWINDOW (window, w);
20908 if (EQ (window, dpyinfo->mouse_face_window))
20909 clear_mouse_face (dpyinfo);
20910 UNBLOCK_INPUT;
20914 /* EXPORT:
20915 Just discard the mouse face information for frame F, if any.
20916 This is used when the size of F is changed. */
20918 void
20919 cancel_mouse_face (f)
20920 struct frame *f;
20922 Lisp_Object window;
20923 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20925 window = dpyinfo->mouse_face_window;
20926 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
20928 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
20929 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
20930 dpyinfo->mouse_face_window = Qnil;
20935 #endif /* HAVE_WINDOW_SYSTEM */
20938 /***********************************************************************
20939 Exposure Events
20940 ***********************************************************************/
20942 #ifdef HAVE_WINDOW_SYSTEM
20944 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
20945 which intersects rectangle R. R is in window-relative coordinates. */
20947 static void
20948 expose_area (w, row, r, area)
20949 struct window *w;
20950 struct glyph_row *row;
20951 XRectangle *r;
20952 enum glyph_row_area area;
20954 struct glyph *first = row->glyphs[area];
20955 struct glyph *end = row->glyphs[area] + row->used[area];
20956 struct glyph *last;
20957 int first_x, start_x, x;
20959 if (area == TEXT_AREA && row->fill_line_p)
20960 /* If row extends face to end of line write the whole line. */
20961 draw_glyphs (w, 0, row, area,
20962 0, row->used[area],
20963 DRAW_NORMAL_TEXT, 0);
20964 else
20966 /* Set START_X to the window-relative start position for drawing glyphs of
20967 AREA. The first glyph of the text area can be partially visible.
20968 The first glyphs of other areas cannot. */
20969 start_x = window_box_left_offset (w, area);
20970 x = start_x;
20971 if (area == TEXT_AREA)
20972 x += row->x;
20974 /* Find the first glyph that must be redrawn. */
20975 while (first < end
20976 && x + first->pixel_width < r->x)
20978 x += first->pixel_width;
20979 ++first;
20982 /* Find the last one. */
20983 last = first;
20984 first_x = x;
20985 while (last < end
20986 && x < r->x + r->width)
20988 x += last->pixel_width;
20989 ++last;
20992 /* Repaint. */
20993 if (last > first)
20994 draw_glyphs (w, first_x - start_x, row, area,
20995 first - row->glyphs[area], last - row->glyphs[area],
20996 DRAW_NORMAL_TEXT, 0);
21001 /* Redraw the parts of the glyph row ROW on window W intersecting
21002 rectangle R. R is in window-relative coordinates. Value is
21003 non-zero if mouse-face was overwritten. */
21005 static int
21006 expose_line (w, row, r)
21007 struct window *w;
21008 struct glyph_row *row;
21009 XRectangle *r;
21011 xassert (row->enabled_p);
21013 if (row->mode_line_p || w->pseudo_window_p)
21014 draw_glyphs (w, 0, row, TEXT_AREA,
21015 0, row->used[TEXT_AREA],
21016 DRAW_NORMAL_TEXT, 0);
21017 else
21019 if (row->used[LEFT_MARGIN_AREA])
21020 expose_area (w, row, r, LEFT_MARGIN_AREA);
21021 if (row->used[TEXT_AREA])
21022 expose_area (w, row, r, TEXT_AREA);
21023 if (row->used[RIGHT_MARGIN_AREA])
21024 expose_area (w, row, r, RIGHT_MARGIN_AREA);
21025 draw_row_fringe_bitmaps (w, row);
21028 return row->mouse_face_p;
21032 /* Redraw those parts of glyphs rows during expose event handling that
21033 overlap other rows. Redrawing of an exposed line writes over parts
21034 of lines overlapping that exposed line; this function fixes that.
21036 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
21037 row in W's current matrix that is exposed and overlaps other rows.
21038 LAST_OVERLAPPING_ROW is the last such row. */
21040 static void
21041 expose_overlaps (w, first_overlapping_row, last_overlapping_row)
21042 struct window *w;
21043 struct glyph_row *first_overlapping_row;
21044 struct glyph_row *last_overlapping_row;
21046 struct glyph_row *row;
21048 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
21049 if (row->overlapping_p)
21051 xassert (row->enabled_p && !row->mode_line_p);
21053 if (row->used[LEFT_MARGIN_AREA])
21054 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
21056 if (row->used[TEXT_AREA])
21057 x_fix_overlapping_area (w, row, TEXT_AREA);
21059 if (row->used[RIGHT_MARGIN_AREA])
21060 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
21065 /* Return non-zero if W's cursor intersects rectangle R. */
21067 static int
21068 phys_cursor_in_rect_p (w, r)
21069 struct window *w;
21070 XRectangle *r;
21072 XRectangle cr, result;
21073 struct glyph *cursor_glyph;
21075 cursor_glyph = get_phys_cursor_glyph (w);
21076 if (cursor_glyph)
21078 /* r is relative to W's box, but w->phys_cursor.x is relative
21079 to left edge of W's TEXT area. Adjust it. */
21080 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
21081 cr.y = w->phys_cursor.y;
21082 cr.width = cursor_glyph->pixel_width;
21083 cr.height = w->phys_cursor_height;
21084 /* ++KFS: W32 version used W32-specific IntersectRect here, but
21085 I assume the effect is the same -- and this is portable. */
21086 return x_intersect_rectangles (&cr, r, &result);
21088 else
21089 return 0;
21093 /* EXPORT:
21094 Draw a vertical window border to the right of window W if W doesn't
21095 have vertical scroll bars. */
21097 void
21098 x_draw_vertical_border (w)
21099 struct window *w;
21101 /* We could do better, if we knew what type of scroll-bar the adjacent
21102 windows (on either side) have... But we don't :-(
21103 However, I think this works ok. ++KFS 2003-04-25 */
21105 /* Redraw borders between horizontally adjacent windows. Don't
21106 do it for frames with vertical scroll bars because either the
21107 right scroll bar of a window, or the left scroll bar of its
21108 neighbor will suffice as a border. */
21109 if (!WINDOW_RIGHTMOST_P (w)
21110 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
21112 int x0, x1, y0, y1;
21114 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
21115 y1 -= 1;
21117 rif->draw_vertical_window_border (w, x1, y0, y1);
21119 else if (!WINDOW_LEFTMOST_P (w)
21120 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
21122 int x0, x1, y0, y1;
21124 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
21125 y1 -= 1;
21127 rif->draw_vertical_window_border (w, x0, y0, y1);
21132 /* Redraw the part of window W intersection rectangle FR. Pixel
21133 coordinates in FR are frame-relative. Call this function with
21134 input blocked. Value is non-zero if the exposure overwrites
21135 mouse-face. */
21137 static int
21138 expose_window (w, fr)
21139 struct window *w;
21140 XRectangle *fr;
21142 struct frame *f = XFRAME (w->frame);
21143 XRectangle wr, r;
21144 int mouse_face_overwritten_p = 0;
21146 /* If window is not yet fully initialized, do nothing. This can
21147 happen when toolkit scroll bars are used and a window is split.
21148 Reconfiguring the scroll bar will generate an expose for a newly
21149 created window. */
21150 if (w->current_matrix == NULL)
21151 return 0;
21153 /* When we're currently updating the window, display and current
21154 matrix usually don't agree. Arrange for a thorough display
21155 later. */
21156 if (w == updated_window)
21158 SET_FRAME_GARBAGED (f);
21159 return 0;
21162 /* Frame-relative pixel rectangle of W. */
21163 wr.x = WINDOW_LEFT_EDGE_X (w);
21164 wr.y = WINDOW_TOP_EDGE_Y (w);
21165 wr.width = WINDOW_TOTAL_WIDTH (w);
21166 wr.height = WINDOW_TOTAL_HEIGHT (w);
21168 if (x_intersect_rectangles (fr, &wr, &r))
21170 int yb = window_text_bottom_y (w);
21171 struct glyph_row *row;
21172 int cursor_cleared_p;
21173 struct glyph_row *first_overlapping_row, *last_overlapping_row;
21175 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
21176 r.x, r.y, r.width, r.height));
21178 /* Convert to window coordinates. */
21179 r.x -= WINDOW_LEFT_EDGE_X (w);
21180 r.y -= WINDOW_TOP_EDGE_Y (w);
21182 /* Turn off the cursor. */
21183 if (!w->pseudo_window_p
21184 && phys_cursor_in_rect_p (w, &r))
21186 x_clear_cursor (w);
21187 cursor_cleared_p = 1;
21189 else
21190 cursor_cleared_p = 0;
21192 /* Update lines intersecting rectangle R. */
21193 first_overlapping_row = last_overlapping_row = NULL;
21194 for (row = w->current_matrix->rows;
21195 row->enabled_p;
21196 ++row)
21198 int y0 = row->y;
21199 int y1 = MATRIX_ROW_BOTTOM_Y (row);
21201 if ((y0 >= r.y && y0 < r.y + r.height)
21202 || (y1 > r.y && y1 < r.y + r.height)
21203 || (r.y >= y0 && r.y < y1)
21204 || (r.y + r.height > y0 && r.y + r.height < y1))
21206 if (row->overlapping_p)
21208 if (first_overlapping_row == NULL)
21209 first_overlapping_row = row;
21210 last_overlapping_row = row;
21213 if (expose_line (w, row, &r))
21214 mouse_face_overwritten_p = 1;
21217 if (y1 >= yb)
21218 break;
21221 /* Display the mode line if there is one. */
21222 if (WINDOW_WANTS_MODELINE_P (w)
21223 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
21224 row->enabled_p)
21225 && row->y < r.y + r.height)
21227 if (expose_line (w, row, &r))
21228 mouse_face_overwritten_p = 1;
21231 if (!w->pseudo_window_p)
21233 /* Fix the display of overlapping rows. */
21234 if (first_overlapping_row)
21235 expose_overlaps (w, first_overlapping_row, last_overlapping_row);
21237 /* Draw border between windows. */
21238 x_draw_vertical_border (w);
21240 /* Turn the cursor on again. */
21241 if (cursor_cleared_p)
21242 update_window_cursor (w, 1);
21246 #ifdef HAVE_CARBON
21247 /* Display scroll bar for this window. */
21248 if (!NILP (w->vertical_scroll_bar))
21250 /* ++KFS:
21251 If this doesn't work here (maybe some header files are missing),
21252 make a function in macterm.c and call it to do the job! */
21253 ControlHandle ch
21254 = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (w->vertical_scroll_bar));
21256 Draw1Control (ch);
21258 #endif
21260 return mouse_face_overwritten_p;
21265 /* Redraw (parts) of all windows in the window tree rooted at W that
21266 intersect R. R contains frame pixel coordinates. Value is
21267 non-zero if the exposure overwrites mouse-face. */
21269 static int
21270 expose_window_tree (w, r)
21271 struct window *w;
21272 XRectangle *r;
21274 struct frame *f = XFRAME (w->frame);
21275 int mouse_face_overwritten_p = 0;
21277 while (w && !FRAME_GARBAGED_P (f))
21279 if (!NILP (w->hchild))
21280 mouse_face_overwritten_p
21281 |= expose_window_tree (XWINDOW (w->hchild), r);
21282 else if (!NILP (w->vchild))
21283 mouse_face_overwritten_p
21284 |= expose_window_tree (XWINDOW (w->vchild), r);
21285 else
21286 mouse_face_overwritten_p |= expose_window (w, r);
21288 w = NILP (w->next) ? NULL : XWINDOW (w->next);
21291 return mouse_face_overwritten_p;
21295 /* EXPORT:
21296 Redisplay an exposed area of frame F. X and Y are the upper-left
21297 corner of the exposed rectangle. W and H are width and height of
21298 the exposed area. All are pixel values. W or H zero means redraw
21299 the entire frame. */
21301 void
21302 expose_frame (f, x, y, w, h)
21303 struct frame *f;
21304 int x, y, w, h;
21306 XRectangle r;
21307 int mouse_face_overwritten_p = 0;
21309 TRACE ((stderr, "expose_frame "));
21311 /* No need to redraw if frame will be redrawn soon. */
21312 if (FRAME_GARBAGED_P (f))
21314 TRACE ((stderr, " garbaged\n"));
21315 return;
21318 #ifdef HAVE_CARBON
21319 /* MAC_TODO: this is a kludge, but if scroll bars are not activated
21320 or deactivated here, for unknown reasons, activated scroll bars
21321 are shown in deactivated frames in some instances. */
21322 if (f == FRAME_MAC_DISPLAY_INFO (f)->x_focus_frame)
21323 activate_scroll_bars (f);
21324 else
21325 deactivate_scroll_bars (f);
21326 #endif
21328 /* If basic faces haven't been realized yet, there is no point in
21329 trying to redraw anything. This can happen when we get an expose
21330 event while Emacs is starting, e.g. by moving another window. */
21331 if (FRAME_FACE_CACHE (f) == NULL
21332 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
21334 TRACE ((stderr, " no faces\n"));
21335 return;
21338 if (w == 0 || h == 0)
21340 r.x = r.y = 0;
21341 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
21342 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
21344 else
21346 r.x = x;
21347 r.y = y;
21348 r.width = w;
21349 r.height = h;
21352 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
21353 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
21355 if (WINDOWP (f->tool_bar_window))
21356 mouse_face_overwritten_p
21357 |= expose_window (XWINDOW (f->tool_bar_window), &r);
21359 #ifdef HAVE_X_WINDOWS
21360 #ifndef MSDOS
21361 #ifndef USE_X_TOOLKIT
21362 if (WINDOWP (f->menu_bar_window))
21363 mouse_face_overwritten_p
21364 |= expose_window (XWINDOW (f->menu_bar_window), &r);
21365 #endif /* not USE_X_TOOLKIT */
21366 #endif
21367 #endif
21369 /* Some window managers support a focus-follows-mouse style with
21370 delayed raising of frames. Imagine a partially obscured frame,
21371 and moving the mouse into partially obscured mouse-face on that
21372 frame. The visible part of the mouse-face will be highlighted,
21373 then the WM raises the obscured frame. With at least one WM, KDE
21374 2.1, Emacs is not getting any event for the raising of the frame
21375 (even tried with SubstructureRedirectMask), only Expose events.
21376 These expose events will draw text normally, i.e. not
21377 highlighted. Which means we must redo the highlight here.
21378 Subsume it under ``we love X''. --gerd 2001-08-15 */
21379 /* Included in Windows version because Windows most likely does not
21380 do the right thing if any third party tool offers
21381 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
21382 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
21384 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21385 if (f == dpyinfo->mouse_face_mouse_frame)
21387 int x = dpyinfo->mouse_face_mouse_x;
21388 int y = dpyinfo->mouse_face_mouse_y;
21389 clear_mouse_face (dpyinfo);
21390 note_mouse_highlight (f, x, y);
21396 /* EXPORT:
21397 Determine the intersection of two rectangles R1 and R2. Return
21398 the intersection in *RESULT. Value is non-zero if RESULT is not
21399 empty. */
21402 x_intersect_rectangles (r1, r2, result)
21403 XRectangle *r1, *r2, *result;
21405 XRectangle *left, *right;
21406 XRectangle *upper, *lower;
21407 int intersection_p = 0;
21409 /* Rearrange so that R1 is the left-most rectangle. */
21410 if (r1->x < r2->x)
21411 left = r1, right = r2;
21412 else
21413 left = r2, right = r1;
21415 /* X0 of the intersection is right.x0, if this is inside R1,
21416 otherwise there is no intersection. */
21417 if (right->x <= left->x + left->width)
21419 result->x = right->x;
21421 /* The right end of the intersection is the minimum of the
21422 the right ends of left and right. */
21423 result->width = (min (left->x + left->width, right->x + right->width)
21424 - result->x);
21426 /* Same game for Y. */
21427 if (r1->y < r2->y)
21428 upper = r1, lower = r2;
21429 else
21430 upper = r2, lower = r1;
21432 /* The upper end of the intersection is lower.y0, if this is inside
21433 of upper. Otherwise, there is no intersection. */
21434 if (lower->y <= upper->y + upper->height)
21436 result->y = lower->y;
21438 /* The lower end of the intersection is the minimum of the lower
21439 ends of upper and lower. */
21440 result->height = (min (lower->y + lower->height,
21441 upper->y + upper->height)
21442 - result->y);
21443 intersection_p = 1;
21447 return intersection_p;
21450 #endif /* HAVE_WINDOW_SYSTEM */
21453 /***********************************************************************
21454 Initialization
21455 ***********************************************************************/
21457 void
21458 syms_of_xdisp ()
21460 Vwith_echo_area_save_vector = Qnil;
21461 staticpro (&Vwith_echo_area_save_vector);
21463 Vmessage_stack = Qnil;
21464 staticpro (&Vmessage_stack);
21466 Qinhibit_redisplay = intern ("inhibit-redisplay");
21467 staticpro (&Qinhibit_redisplay);
21469 message_dolog_marker1 = Fmake_marker ();
21470 staticpro (&message_dolog_marker1);
21471 message_dolog_marker2 = Fmake_marker ();
21472 staticpro (&message_dolog_marker2);
21473 message_dolog_marker3 = Fmake_marker ();
21474 staticpro (&message_dolog_marker3);
21476 #if GLYPH_DEBUG
21477 defsubr (&Sdump_frame_glyph_matrix);
21478 defsubr (&Sdump_glyph_matrix);
21479 defsubr (&Sdump_glyph_row);
21480 defsubr (&Sdump_tool_bar_row);
21481 defsubr (&Strace_redisplay);
21482 defsubr (&Strace_to_stderr);
21483 #endif
21484 #ifdef HAVE_WINDOW_SYSTEM
21485 defsubr (&Stool_bar_lines_needed);
21486 defsubr (&Slookup_image_map);
21487 #endif
21488 defsubr (&Sformat_mode_line);
21490 staticpro (&Qmenu_bar_update_hook);
21491 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
21493 staticpro (&Qoverriding_terminal_local_map);
21494 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
21496 staticpro (&Qoverriding_local_map);
21497 Qoverriding_local_map = intern ("overriding-local-map");
21499 staticpro (&Qwindow_scroll_functions);
21500 Qwindow_scroll_functions = intern ("window-scroll-functions");
21502 staticpro (&Qredisplay_end_trigger_functions);
21503 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
21505 staticpro (&Qinhibit_point_motion_hooks);
21506 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
21508 QCdata = intern (":data");
21509 staticpro (&QCdata);
21510 Qdisplay = intern ("display");
21511 staticpro (&Qdisplay);
21512 Qspace_width = intern ("space-width");
21513 staticpro (&Qspace_width);
21514 Qraise = intern ("raise");
21515 staticpro (&Qraise);
21516 Qspace = intern ("space");
21517 staticpro (&Qspace);
21518 Qmargin = intern ("margin");
21519 staticpro (&Qmargin);
21520 Qpointer = intern ("pointer");
21521 staticpro (&Qpointer);
21522 Qleft_margin = intern ("left-margin");
21523 staticpro (&Qleft_margin);
21524 Qright_margin = intern ("right-margin");
21525 staticpro (&Qright_margin);
21526 QCalign_to = intern (":align-to");
21527 staticpro (&QCalign_to);
21528 QCrelative_width = intern (":relative-width");
21529 staticpro (&QCrelative_width);
21530 QCrelative_height = intern (":relative-height");
21531 staticpro (&QCrelative_height);
21532 QCeval = intern (":eval");
21533 staticpro (&QCeval);
21534 QCpropertize = intern (":propertize");
21535 staticpro (&QCpropertize);
21536 QCfile = intern (":file");
21537 staticpro (&QCfile);
21538 Qfontified = intern ("fontified");
21539 staticpro (&Qfontified);
21540 Qfontification_functions = intern ("fontification-functions");
21541 staticpro (&Qfontification_functions);
21542 Qtrailing_whitespace = intern ("trailing-whitespace");
21543 staticpro (&Qtrailing_whitespace);
21544 Qimage = intern ("image");
21545 staticpro (&Qimage);
21546 QCmap = intern (":map");
21547 staticpro (&QCmap);
21548 QCpointer = intern (":pointer");
21549 staticpro (&QCpointer);
21550 Qrect = intern ("rect");
21551 staticpro (&Qrect);
21552 Qcircle = intern ("circle");
21553 staticpro (&Qcircle);
21554 Qpoly = intern ("poly");
21555 staticpro (&Qpoly);
21556 Qmessage_truncate_lines = intern ("message-truncate-lines");
21557 staticpro (&Qmessage_truncate_lines);
21558 Qcursor_in_non_selected_windows = intern ("cursor-in-non-selected-windows");
21559 staticpro (&Qcursor_in_non_selected_windows);
21560 Qgrow_only = intern ("grow-only");
21561 staticpro (&Qgrow_only);
21562 Qinhibit_menubar_update = intern ("inhibit-menubar-update");
21563 staticpro (&Qinhibit_menubar_update);
21564 Qinhibit_eval_during_redisplay = intern ("inhibit-eval-during-redisplay");
21565 staticpro (&Qinhibit_eval_during_redisplay);
21566 Qposition = intern ("position");
21567 staticpro (&Qposition);
21568 Qbuffer_position = intern ("buffer-position");
21569 staticpro (&Qbuffer_position);
21570 Qobject = intern ("object");
21571 staticpro (&Qobject);
21572 Qbar = intern ("bar");
21573 staticpro (&Qbar);
21574 Qhbar = intern ("hbar");
21575 staticpro (&Qhbar);
21576 Qbox = intern ("box");
21577 staticpro (&Qbox);
21578 Qhollow = intern ("hollow");
21579 staticpro (&Qhollow);
21580 Qhand = intern ("hand");
21581 staticpro (&Qhand);
21582 Qarrow = intern ("arrow");
21583 staticpro (&Qarrow);
21584 Qtext = intern ("text");
21585 staticpro (&Qtext);
21586 Qrisky_local_variable = intern ("risky-local-variable");
21587 staticpro (&Qrisky_local_variable);
21588 Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
21589 staticpro (&Qinhibit_free_realized_faces);
21591 list_of_error = Fcons (intern ("error"), Qnil);
21592 staticpro (&list_of_error);
21594 Qlast_arrow_position = intern ("last-arrow-position");
21595 staticpro (&Qlast_arrow_position);
21596 Qlast_arrow_string = intern ("last-arrow-string");
21597 staticpro (&Qlast_arrow_string);
21599 Qoverlay_arrow_string = intern ("overlay-arrow-string");
21600 staticpro (&Qoverlay_arrow_string);
21601 Qoverlay_arrow_bitmap = intern ("overlay-arrow-bitmap");
21602 staticpro (&Qoverlay_arrow_bitmap);
21604 echo_buffer[0] = echo_buffer[1] = Qnil;
21605 staticpro (&echo_buffer[0]);
21606 staticpro (&echo_buffer[1]);
21608 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
21609 staticpro (&echo_area_buffer[0]);
21610 staticpro (&echo_area_buffer[1]);
21612 Vmessages_buffer_name = build_string ("*Messages*");
21613 staticpro (&Vmessages_buffer_name);
21615 mode_line_proptrans_alist = Qnil;
21616 staticpro (&mode_line_proptrans_alist);
21618 mode_line_string_list = Qnil;
21619 staticpro (&mode_line_string_list);
21621 help_echo_string = Qnil;
21622 staticpro (&help_echo_string);
21623 help_echo_object = Qnil;
21624 staticpro (&help_echo_object);
21625 help_echo_window = Qnil;
21626 staticpro (&help_echo_window);
21627 previous_help_echo_string = Qnil;
21628 staticpro (&previous_help_echo_string);
21629 help_echo_pos = -1;
21631 #ifdef HAVE_WINDOW_SYSTEM
21632 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
21633 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
21634 For example, if a block cursor is over a tab, it will be drawn as
21635 wide as that tab on the display. */);
21636 x_stretch_cursor_p = 0;
21637 #endif
21639 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
21640 doc: /* *Non-nil means highlight trailing whitespace.
21641 The face used for trailing whitespace is `trailing-whitespace'. */);
21642 Vshow_trailing_whitespace = Qnil;
21644 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
21645 doc: /* *The pointer shape to show in void text areas.
21646 Nil means to show the text pointer. Other options are `arrow', `text',
21647 `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
21648 Vvoid_text_area_pointer = Qarrow;
21650 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
21651 doc: /* Non-nil means don't actually do any redisplay.
21652 This is used for internal purposes. */);
21653 Vinhibit_redisplay = Qnil;
21655 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
21656 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
21657 Vglobal_mode_string = Qnil;
21659 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
21660 doc: /* Marker for where to display an arrow on top of the buffer text.
21661 This must be the beginning of a line in order to work.
21662 See also `overlay-arrow-string'. */);
21663 Voverlay_arrow_position = Qnil;
21665 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
21666 doc: /* String to display as an arrow in non-window frames.
21667 See also `overlay-arrow-position'. */);
21668 Voverlay_arrow_string = Qnil;
21670 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list,
21671 doc: /* List of variables (symbols) which hold markers for overlay arrows.
21672 The symbols on this list are examined during redisplay to determine
21673 where to display overlay arrows. */);
21674 Voverlay_arrow_variable_list
21675 = Fcons (intern ("overlay-arrow-position"), Qnil);
21677 DEFVAR_INT ("scroll-step", &scroll_step,
21678 doc: /* *The number of lines to try scrolling a window by when point moves out.
21679 If that fails to bring point back on frame, point is centered instead.
21680 If this is zero, point is always centered after it moves off frame.
21681 If you want scrolling to always be a line at a time, you should set
21682 `scroll-conservatively' to a large value rather than set this to 1. */);
21684 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
21685 doc: /* *Scroll up to this many lines, to bring point back on screen.
21686 A value of zero means to scroll the text to center point vertically
21687 in the window. */);
21688 scroll_conservatively = 0;
21690 DEFVAR_INT ("scroll-margin", &scroll_margin,
21691 doc: /* *Number of lines of margin at the top and bottom of a window.
21692 Recenter the window whenever point gets within this many lines
21693 of the top or bottom of the window. */);
21694 scroll_margin = 0;
21696 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch,
21697 doc: /* Pixels per inch on current display.
21698 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
21699 Vdisplay_pixels_per_inch = make_float (72.0);
21701 #if GLYPH_DEBUG
21702 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
21703 #endif
21705 DEFVAR_BOOL ("truncate-partial-width-windows",
21706 &truncate_partial_width_windows,
21707 doc: /* *Non-nil means truncate lines in all windows less than full frame wide. */);
21708 truncate_partial_width_windows = 1;
21710 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
21711 doc: /* nil means display the mode-line/header-line/menu-bar in the default face.
21712 Any other value means to use the appropriate face, `mode-line',
21713 `header-line', or `menu' respectively. */);
21714 mode_line_inverse_video = 1;
21716 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
21717 doc: /* *Maximum buffer size for which line number should be displayed.
21718 If the buffer is bigger than this, the line number does not appear
21719 in the mode line. A value of nil means no limit. */);
21720 Vline_number_display_limit = Qnil;
21722 DEFVAR_INT ("line-number-display-limit-width",
21723 &line_number_display_limit_width,
21724 doc: /* *Maximum line width (in characters) for line number display.
21725 If the average length of the lines near point is bigger than this, then the
21726 line number may be omitted from the mode line. */);
21727 line_number_display_limit_width = 200;
21729 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
21730 doc: /* *Non-nil means highlight region even in nonselected windows. */);
21731 highlight_nonselected_windows = 0;
21733 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
21734 doc: /* Non-nil if more than one frame is visible on this display.
21735 Minibuffer-only frames don't count, but iconified frames do.
21736 This variable is not guaranteed to be accurate except while processing
21737 `frame-title-format' and `icon-title-format'. */);
21739 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
21740 doc: /* Template for displaying the title bar of visible frames.
21741 \(Assuming the window manager supports this feature.)
21742 This variable has the same structure as `mode-line-format' (which see),
21743 and is used only on frames for which no explicit name has been set
21744 \(see `modify-frame-parameters'). */);
21746 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
21747 doc: /* Template for displaying the title bar of an iconified frame.
21748 \(Assuming the window manager supports this feature.)
21749 This variable has the same structure as `mode-line-format' (which see),
21750 and is used only on frames for which no explicit name has been set
21751 \(see `modify-frame-parameters'). */);
21752 Vicon_title_format
21753 = Vframe_title_format
21754 = Fcons (intern ("multiple-frames"),
21755 Fcons (build_string ("%b"),
21756 Fcons (Fcons (empty_string,
21757 Fcons (intern ("invocation-name"),
21758 Fcons (build_string ("@"),
21759 Fcons (intern ("system-name"),
21760 Qnil)))),
21761 Qnil)));
21763 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
21764 doc: /* Maximum number of lines to keep in the message log buffer.
21765 If nil, disable message logging. If t, log messages but don't truncate
21766 the buffer when it becomes large. */);
21767 Vmessage_log_max = make_number (50);
21769 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
21770 doc: /* Functions called before redisplay, if window sizes have changed.
21771 The value should be a list of functions that take one argument.
21772 Just before redisplay, for each frame, if any of its windows have changed
21773 size since the last redisplay, or have been split or deleted,
21774 all the functions in the list are called, with the frame as argument. */);
21775 Vwindow_size_change_functions = Qnil;
21777 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
21778 doc: /* List of Functions to call before redisplaying a window with scrolling.
21779 Each function is called with two arguments, the window
21780 and its new display-start position. Note that the value of `window-end'
21781 is not valid when these functions are called. */);
21782 Vwindow_scroll_functions = Qnil;
21784 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window,
21785 doc: /* *Non-nil means autoselect window with mouse pointer. */);
21786 mouse_autoselect_window = 0;
21788 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
21789 doc: /* *Non-nil means automatically resize tool-bars.
21790 This increases a tool-bar's height if not all tool-bar items are visible.
21791 It decreases a tool-bar's height when it would display blank lines
21792 otherwise. */);
21793 auto_resize_tool_bars_p = 1;
21795 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
21796 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
21797 auto_raise_tool_bar_buttons_p = 1;
21799 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
21800 doc: /* *Margin around tool-bar buttons in pixels.
21801 If an integer, use that for both horizontal and vertical margins.
21802 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
21803 HORZ specifying the horizontal margin, and VERT specifying the
21804 vertical margin. */);
21805 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
21807 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
21808 doc: /* *Relief thickness of tool-bar buttons. */);
21809 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
21811 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
21812 doc: /* List of functions to call to fontify regions of text.
21813 Each function is called with one argument POS. Functions must
21814 fontify a region starting at POS in the current buffer, and give
21815 fontified regions the property `fontified'. */);
21816 Vfontification_functions = Qnil;
21817 Fmake_variable_buffer_local (Qfontification_functions);
21819 DEFVAR_BOOL ("unibyte-display-via-language-environment",
21820 &unibyte_display_via_language_environment,
21821 doc: /* *Non-nil means display unibyte text according to language environment.
21822 Specifically this means that unibyte non-ASCII characters
21823 are displayed by converting them to the equivalent multibyte characters
21824 according to the current language environment. As a result, they are
21825 displayed according to the current fontset. */);
21826 unibyte_display_via_language_environment = 0;
21828 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
21829 doc: /* *Maximum height for resizing mini-windows.
21830 If a float, it specifies a fraction of the mini-window frame's height.
21831 If an integer, it specifies a number of lines. */);
21832 Vmax_mini_window_height = make_float (0.25);
21834 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
21835 doc: /* *How to resize mini-windows.
21836 A value of nil means don't automatically resize mini-windows.
21837 A value of t means resize them to fit the text displayed in them.
21838 A value of `grow-only', the default, means let mini-windows grow
21839 only, until their display becomes empty, at which point the windows
21840 go back to their normal size. */);
21841 Vresize_mini_windows = Qgrow_only;
21843 DEFVAR_LISP ("cursor-in-non-selected-windows",
21844 &Vcursor_in_non_selected_windows,
21845 doc: /* *Cursor type to display in non-selected windows.
21846 t means to use hollow box cursor. See `cursor-type' for other values. */);
21847 Vcursor_in_non_selected_windows = Qt;
21849 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
21850 doc: /* Alist specifying how to blink the cursor off.
21851 Each element has the form (ON-STATE . OFF-STATE). Whenever the
21852 `cursor-type' frame-parameter or variable equals ON-STATE,
21853 comparing using `equal', Emacs uses OFF-STATE to specify
21854 how to blink it off. */);
21855 Vblink_cursor_alist = Qnil;
21857 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
21858 doc: /* *Non-nil means scroll the display automatically to make point visible. */);
21859 automatic_hscrolling_p = 1;
21861 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
21862 doc: /* *How many columns away from the window edge point is allowed to get
21863 before automatic hscrolling will horizontally scroll the window. */);
21864 hscroll_margin = 5;
21866 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
21867 doc: /* *How many columns to scroll the window when point gets too close to the edge.
21868 When point is less than `automatic-hscroll-margin' columns from the window
21869 edge, automatic hscrolling will scroll the window by the amount of columns
21870 determined by this variable. If its value is a positive integer, scroll that
21871 many columns. If it's a positive floating-point number, it specifies the
21872 fraction of the window's width to scroll. If it's nil or zero, point will be
21873 centered horizontally after the scroll. Any other value, including negative
21874 numbers, are treated as if the value were zero.
21876 Automatic hscrolling always moves point outside the scroll margin, so if
21877 point was more than scroll step columns inside the margin, the window will
21878 scroll more than the value given by the scroll step.
21880 Note that the lower bound for automatic hscrolling specified by `scroll-left'
21881 and `scroll-right' overrides this variable's effect. */);
21882 Vhscroll_step = make_number (0);
21884 DEFVAR_LISP ("image-types", &Vimage_types,
21885 doc: /* List of supported image types.
21886 Each element of the list is a symbol for a supported image type. */);
21887 Vimage_types = Qnil;
21889 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
21890 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
21891 Bind this around calls to `message' to let it take effect. */);
21892 message_truncate_lines = 0;
21894 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
21895 doc: /* Normal hook run for clicks on menu bar, before displaying a submenu.
21896 Can be used to update submenus whose contents should vary. */);
21897 Vmenu_bar_update_hook = Qnil;
21899 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
21900 doc: /* Non-nil means don't update menu bars. Internal use only. */);
21901 inhibit_menubar_update = 0;
21903 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
21904 doc: /* Non-nil means don't eval Lisp during redisplay. */);
21905 inhibit_eval_during_redisplay = 0;
21907 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
21908 doc: /* Non-nil means don't free realized faces. Internal use only. */);
21909 inhibit_free_realized_faces = 0;
21911 #if GLYPH_DEBUG
21912 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
21913 doc: /* Inhibit try_window_id display optimization. */);
21914 inhibit_try_window_id = 0;
21916 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
21917 doc: /* Inhibit try_window_reusing display optimization. */);
21918 inhibit_try_window_reusing = 0;
21920 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
21921 doc: /* Inhibit try_cursor_movement display optimization. */);
21922 inhibit_try_cursor_movement = 0;
21923 #endif /* GLYPH_DEBUG */
21927 /* Initialize this module when Emacs starts. */
21929 void
21930 init_xdisp ()
21932 Lisp_Object root_window;
21933 struct window *mini_w;
21935 current_header_line_height = current_mode_line_height = -1;
21937 CHARPOS (this_line_start_pos) = 0;
21939 mini_w = XWINDOW (minibuf_window);
21940 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
21942 if (!noninteractive)
21944 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
21945 int i;
21947 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
21948 set_window_height (root_window,
21949 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
21951 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
21952 set_window_height (minibuf_window, 1, 0);
21954 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
21955 mini_w->total_cols = make_number (FRAME_COLS (f));
21957 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
21958 scratch_glyph_row.glyphs[TEXT_AREA + 1]
21959 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
21961 /* The default ellipsis glyphs `...'. */
21962 for (i = 0; i < 3; ++i)
21963 default_invis_vector[i] = make_number ('.');
21967 /* Allocate the buffer for frame titles.
21968 Also used for `format-mode-line'. */
21969 int size = 100;
21970 frame_title_buf = (char *) xmalloc (size);
21971 frame_title_buf_end = frame_title_buf + size;
21972 frame_title_ptr = NULL;
21975 help_echo_showing_p = 0;
21979 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
21980 (do not change this comment) */