(interprogram-cut-function)
[emacs.git] / src / xdisp.c
blob0967041f3b65fe7e0be928899e8fe3d007ac5846
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;
406 /* Marker for where to display an arrow on top of the buffer text. */
408 Lisp_Object Voverlay_arrow_position;
410 /* String to display for the arrow. Only used on terminal frames. */
412 Lisp_Object Voverlay_arrow_string;
414 /* Values of those variables at last redisplay. However, if
415 Voverlay_arrow_position is a marker, last_arrow_position is its
416 numerical position. */
418 static Lisp_Object last_arrow_position, last_arrow_string;
420 /* Like mode-line-format, but for the title bar on a visible frame. */
422 Lisp_Object Vframe_title_format;
424 /* Like mode-line-format, but for the title bar on an iconified frame. */
426 Lisp_Object Vicon_title_format;
428 /* List of functions to call when a window's size changes. These
429 functions get one arg, a frame on which one or more windows' sizes
430 have changed. */
432 static Lisp_Object Vwindow_size_change_functions;
434 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
436 /* Nonzero if overlay arrow has been displayed once in this window. */
438 static int overlay_arrow_seen;
440 /* Nonzero means highlight the region even in nonselected windows. */
442 int highlight_nonselected_windows;
444 /* If cursor motion alone moves point off frame, try scrolling this
445 many lines up or down if that will bring it back. */
447 static EMACS_INT scroll_step;
449 /* Nonzero means scroll just far enough to bring point back on the
450 screen, when appropriate. */
452 static EMACS_INT scroll_conservatively;
454 /* Recenter the window whenever point gets within this many lines of
455 the top or bottom of the window. This value is translated into a
456 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
457 that there is really a fixed pixel height scroll margin. */
459 EMACS_INT scroll_margin;
461 /* Number of windows showing the buffer of the selected window (or
462 another buffer with the same base buffer). keyboard.c refers to
463 this. */
465 int buffer_shared;
467 /* Vector containing glyphs for an ellipsis `...'. */
469 static Lisp_Object default_invis_vector[3];
471 /* Zero means display the mode-line/header-line/menu-bar in the default face
472 (this slightly odd definition is for compatibility with previous versions
473 of emacs), non-zero means display them using their respective faces.
475 This variable is deprecated. */
477 int mode_line_inverse_video;
479 /* Prompt to display in front of the mini-buffer contents. */
481 Lisp_Object minibuf_prompt;
483 /* Width of current mini-buffer prompt. Only set after display_line
484 of the line that contains the prompt. */
486 int minibuf_prompt_width;
488 /* This is the window where the echo area message was displayed. It
489 is always a mini-buffer window, but it may not be the same window
490 currently active as a mini-buffer. */
492 Lisp_Object echo_area_window;
494 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
495 pushes the current message and the value of
496 message_enable_multibyte on the stack, the function restore_message
497 pops the stack and displays MESSAGE again. */
499 Lisp_Object Vmessage_stack;
501 /* Nonzero means multibyte characters were enabled when the echo area
502 message was specified. */
504 int message_enable_multibyte;
506 /* Nonzero if we should redraw the mode lines on the next redisplay. */
508 int update_mode_lines;
510 /* Nonzero if window sizes or contents have changed since last
511 redisplay that finished. */
513 int windows_or_buffers_changed;
515 /* Nonzero means a frame's cursor type has been changed. */
517 int cursor_type_changed;
519 /* Nonzero after display_mode_line if %l was used and it displayed a
520 line number. */
522 int line_number_displayed;
524 /* Maximum buffer size for which to display line numbers. */
526 Lisp_Object Vline_number_display_limit;
528 /* Line width to consider when repositioning for line number display. */
530 static EMACS_INT line_number_display_limit_width;
532 /* Number of lines to keep in the message log buffer. t means
533 infinite. nil means don't log at all. */
535 Lisp_Object Vmessage_log_max;
537 /* The name of the *Messages* buffer, a string. */
539 static Lisp_Object Vmessages_buffer_name;
541 /* Current, index 0, and last displayed echo area message. Either
542 buffers from echo_buffers, or nil to indicate no message. */
544 Lisp_Object echo_area_buffer[2];
546 /* The buffers referenced from echo_area_buffer. */
548 static Lisp_Object echo_buffer[2];
550 /* A vector saved used in with_area_buffer to reduce consing. */
552 static Lisp_Object Vwith_echo_area_save_vector;
554 /* Non-zero means display_echo_area should display the last echo area
555 message again. Set by redisplay_preserve_echo_area. */
557 static int display_last_displayed_message_p;
559 /* Nonzero if echo area is being used by print; zero if being used by
560 message. */
562 int message_buf_print;
564 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
566 Lisp_Object Qinhibit_menubar_update;
567 int inhibit_menubar_update;
569 /* Maximum height for resizing mini-windows. Either a float
570 specifying a fraction of the available height, or an integer
571 specifying a number of lines. */
573 Lisp_Object Vmax_mini_window_height;
575 /* Non-zero means messages should be displayed with truncated
576 lines instead of being continued. */
578 int message_truncate_lines;
579 Lisp_Object Qmessage_truncate_lines;
581 /* Set to 1 in clear_message to make redisplay_internal aware
582 of an emptied echo area. */
584 static int message_cleared_p;
586 /* Non-zero means we want a hollow cursor in windows that are not
587 selected. Zero means there's no cursor in such windows. */
589 Lisp_Object Vcursor_in_non_selected_windows;
590 Lisp_Object Qcursor_in_non_selected_windows;
592 /* How to blink the default frame cursor off. */
593 Lisp_Object Vblink_cursor_alist;
595 /* A scratch glyph row with contents used for generating truncation
596 glyphs. Also used in direct_output_for_insert. */
598 #define MAX_SCRATCH_GLYPHS 100
599 struct glyph_row scratch_glyph_row;
600 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
602 /* Ascent and height of the last line processed by move_it_to. */
604 static int last_max_ascent, last_height;
606 /* Non-zero if there's a help-echo in the echo area. */
608 int help_echo_showing_p;
610 /* If >= 0, computed, exact values of mode-line and header-line height
611 to use in the macros CURRENT_MODE_LINE_HEIGHT and
612 CURRENT_HEADER_LINE_HEIGHT. */
614 int current_mode_line_height, current_header_line_height;
616 /* The maximum distance to look ahead for text properties. Values
617 that are too small let us call compute_char_face and similar
618 functions too often which is expensive. Values that are too large
619 let us call compute_char_face and alike too often because we
620 might not be interested in text properties that far away. */
622 #define TEXT_PROP_DISTANCE_LIMIT 100
624 #if GLYPH_DEBUG
626 /* Variables to turn off display optimizations from Lisp. */
628 int inhibit_try_window_id, inhibit_try_window_reusing;
629 int inhibit_try_cursor_movement;
631 /* Non-zero means print traces of redisplay if compiled with
632 GLYPH_DEBUG != 0. */
634 int trace_redisplay_p;
636 #endif /* GLYPH_DEBUG */
638 #ifdef DEBUG_TRACE_MOVE
639 /* Non-zero means trace with TRACE_MOVE to stderr. */
640 int trace_move;
642 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
643 #else
644 #define TRACE_MOVE(x) (void) 0
645 #endif
647 /* Non-zero means automatically scroll windows horizontally to make
648 point visible. */
650 int automatic_hscrolling_p;
652 /* How close to the margin can point get before the window is scrolled
653 horizontally. */
654 EMACS_INT hscroll_margin;
656 /* How much to scroll horizontally when point is inside the above margin. */
657 Lisp_Object Vhscroll_step;
659 /* A list of symbols, one for each supported image type. */
661 Lisp_Object Vimage_types;
663 /* The variable `resize-mini-windows'. If nil, don't resize
664 mini-windows. If t, always resize them to fit the text they
665 display. If `grow-only', let mini-windows grow only until they
666 become empty. */
668 Lisp_Object Vresize_mini_windows;
670 /* Buffer being redisplayed -- for redisplay_window_error. */
672 struct buffer *displayed_buffer;
674 /* Value returned from text property handlers (see below). */
676 enum prop_handled
678 HANDLED_NORMALLY,
679 HANDLED_RECOMPUTE_PROPS,
680 HANDLED_OVERLAY_STRING_CONSUMED,
681 HANDLED_RETURN
684 /* A description of text properties that redisplay is interested
685 in. */
687 struct props
689 /* The name of the property. */
690 Lisp_Object *name;
692 /* A unique index for the property. */
693 enum prop_idx idx;
695 /* A handler function called to set up iterator IT from the property
696 at IT's current position. Value is used to steer handle_stop. */
697 enum prop_handled (*handler) P_ ((struct it *it));
700 static enum prop_handled handle_face_prop P_ ((struct it *));
701 static enum prop_handled handle_invisible_prop P_ ((struct it *));
702 static enum prop_handled handle_display_prop P_ ((struct it *));
703 static enum prop_handled handle_composition_prop P_ ((struct it *));
704 static enum prop_handled handle_overlay_change P_ ((struct it *));
705 static enum prop_handled handle_fontified_prop P_ ((struct it *));
707 /* Properties handled by iterators. */
709 static struct props it_props[] =
711 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
712 /* Handle `face' before `display' because some sub-properties of
713 `display' need to know the face. */
714 {&Qface, FACE_PROP_IDX, handle_face_prop},
715 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
716 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
717 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
718 {NULL, 0, NULL}
721 /* Value is the position described by X. If X is a marker, value is
722 the marker_position of X. Otherwise, value is X. */
724 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
726 /* Enumeration returned by some move_it_.* functions internally. */
728 enum move_it_result
730 /* Not used. Undefined value. */
731 MOVE_UNDEFINED,
733 /* Move ended at the requested buffer position or ZV. */
734 MOVE_POS_MATCH_OR_ZV,
736 /* Move ended at the requested X pixel position. */
737 MOVE_X_REACHED,
739 /* Move within a line ended at the end of a line that must be
740 continued. */
741 MOVE_LINE_CONTINUED,
743 /* Move within a line ended at the end of a line that would
744 be displayed truncated. */
745 MOVE_LINE_TRUNCATED,
747 /* Move within a line ended at a line end. */
748 MOVE_NEWLINE_OR_CR
751 /* This counter is used to clear the face cache every once in a while
752 in redisplay_internal. It is incremented for each redisplay.
753 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
754 cleared. */
756 #define CLEAR_FACE_CACHE_COUNT 500
757 static int clear_face_cache_count;
759 /* Record the previous terminal frame we displayed. */
761 static struct frame *previous_terminal_frame;
763 /* Non-zero while redisplay_internal is in progress. */
765 int redisplaying_p;
767 /* Non-zero means don't free realized faces. Bound while freeing
768 realized faces is dangerous because glyph matrices might still
769 reference them. */
771 int inhibit_free_realized_faces;
772 Lisp_Object Qinhibit_free_realized_faces;
774 /* If a string, XTread_socket generates an event to display that string.
775 (The display is done in read_char.) */
777 Lisp_Object help_echo_string;
778 Lisp_Object help_echo_window;
779 Lisp_Object help_echo_object;
780 int help_echo_pos;
782 /* Temporary variable for XTread_socket. */
784 Lisp_Object previous_help_echo_string;
788 /* Function prototypes. */
790 static void setup_for_ellipsis P_ ((struct it *));
791 static void mark_window_display_accurate_1 P_ ((struct window *, int));
792 static int single_display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
793 static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
794 static int cursor_row_p P_ ((struct window *, struct glyph_row *));
795 static int redisplay_mode_lines P_ ((Lisp_Object, int));
796 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
798 #if 0
799 static int invisible_text_between_p P_ ((struct it *, int, int));
800 #endif
802 static int next_element_from_ellipsis P_ ((struct it *));
803 static void pint2str P_ ((char *, int, int));
804 static void pint2hrstr P_ ((char *, int, int));
805 static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
806 struct text_pos));
807 static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
808 static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
809 static void store_frame_title_char P_ ((char));
810 static int store_frame_title P_ ((const unsigned char *, int, int));
811 static void x_consider_frame_title P_ ((Lisp_Object));
812 static void handle_stop P_ ((struct it *));
813 static int tool_bar_lines_needed P_ ((struct frame *));
814 static int single_display_prop_intangible_p P_ ((Lisp_Object));
815 static void ensure_echo_area_buffers P_ ((void));
816 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
817 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
818 static int with_echo_area_buffer P_ ((struct window *, int,
819 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
820 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
821 static void clear_garbaged_frames P_ ((void));
822 static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
823 static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
824 static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
825 static int display_echo_area P_ ((struct window *));
826 static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
827 static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
828 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
829 static int string_char_and_length P_ ((const unsigned char *, int, int *));
830 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
831 struct text_pos));
832 static int compute_window_start_on_continuation_line P_ ((struct window *));
833 static Lisp_Object safe_eval_handler P_ ((Lisp_Object));
834 static void insert_left_trunc_glyphs P_ ((struct it *));
835 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *));
836 static void extend_face_to_end_of_line P_ ((struct it *));
837 static int append_space P_ ((struct it *, int));
838 static int make_cursor_line_fully_visible P_ ((struct window *));
839 static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
840 static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
841 static int trailing_whitespace_p P_ ((int));
842 static int message_log_check_duplicate P_ ((int, int, int, int));
843 static void push_it P_ ((struct it *));
844 static void pop_it P_ ((struct it *));
845 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
846 static void select_frame_for_redisplay P_ ((Lisp_Object));
847 static void redisplay_internal P_ ((int));
848 static int echo_area_display P_ ((int));
849 static void redisplay_windows P_ ((Lisp_Object));
850 static void redisplay_window P_ ((Lisp_Object, int));
851 static Lisp_Object redisplay_window_error ();
852 static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
853 static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
854 static void update_menu_bar P_ ((struct frame *, int));
855 static int try_window_reusing_current_matrix P_ ((struct window *));
856 static int try_window_id P_ ((struct window *));
857 static int display_line P_ ((struct it *));
858 static int display_mode_lines P_ ((struct window *));
859 static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
860 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
861 static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
862 static char *decode_mode_spec P_ ((struct window *, int, int, int, int *));
863 static void display_menu_bar P_ ((struct window *));
864 static int display_count_lines P_ ((int, int, int, int, int *));
865 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
866 int, int, struct it *, int, int, int, int));
867 static void compute_line_metrics P_ ((struct it *));
868 static void run_redisplay_end_trigger_hook P_ ((struct it *));
869 static int get_overlay_strings P_ ((struct it *, int));
870 static void next_overlay_string P_ ((struct it *));
871 static void reseat P_ ((struct it *, struct text_pos, int));
872 static void reseat_1 P_ ((struct it *, struct text_pos, int));
873 static void back_to_previous_visible_line_start P_ ((struct it *));
874 static void reseat_at_previous_visible_line_start P_ ((struct it *));
875 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
876 static int next_element_from_display_vector P_ ((struct it *));
877 static int next_element_from_string P_ ((struct it *));
878 static int next_element_from_c_string P_ ((struct it *));
879 static int next_element_from_buffer P_ ((struct it *));
880 static int next_element_from_composition P_ ((struct it *));
881 static int next_element_from_image P_ ((struct it *));
882 static int next_element_from_stretch P_ ((struct it *));
883 static void load_overlay_strings P_ ((struct it *, int));
884 static int init_from_display_pos P_ ((struct it *, struct window *,
885 struct display_pos *));
886 static void reseat_to_string P_ ((struct it *, unsigned char *,
887 Lisp_Object, int, int, int, int));
888 static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
889 int, int, int));
890 void move_it_vertically_backward P_ ((struct it *, int));
891 static void init_to_row_start P_ ((struct it *, struct window *,
892 struct glyph_row *));
893 static int init_to_row_end P_ ((struct it *, struct window *,
894 struct glyph_row *));
895 static void back_to_previous_line_start P_ ((struct it *));
896 static int forward_to_next_line_start P_ ((struct it *, int *));
897 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
898 Lisp_Object, int));
899 static struct text_pos string_pos P_ ((int, Lisp_Object));
900 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
901 static int number_of_chars P_ ((unsigned char *, int));
902 static void compute_stop_pos P_ ((struct it *));
903 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
904 Lisp_Object));
905 static int face_before_or_after_it_pos P_ ((struct it *, int));
906 static int next_overlay_change P_ ((int));
907 static int handle_single_display_prop P_ ((struct it *, Lisp_Object,
908 Lisp_Object, struct text_pos *,
909 int));
910 static int underlying_face_id P_ ((struct it *));
911 static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
912 struct window *));
914 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
915 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
917 #ifdef HAVE_WINDOW_SYSTEM
919 static void update_tool_bar P_ ((struct frame *, int));
920 static void build_desired_tool_bar_string P_ ((struct frame *f));
921 static int redisplay_tool_bar P_ ((struct frame *));
922 static void display_tool_bar_line P_ ((struct it *));
923 static void notice_overwritten_cursor P_ ((struct window *,
924 enum glyph_row_area,
925 int, int, int, int));
929 #endif /* HAVE_WINDOW_SYSTEM */
932 /***********************************************************************
933 Window display dimensions
934 ***********************************************************************/
936 /* Return the bottom boundary y-position for text lines in window W.
937 This is the first y position at which a line cannot start.
938 It is relative to the top of the window.
940 This is the height of W minus the height of a mode line, if any. */
942 INLINE int
943 window_text_bottom_y (w)
944 struct window *w;
946 int height = WINDOW_TOTAL_HEIGHT (w);
948 if (WINDOW_WANTS_MODELINE_P (w))
949 height -= CURRENT_MODE_LINE_HEIGHT (w);
950 return height;
953 /* Return the pixel width of display area AREA of window W. AREA < 0
954 means return the total width of W, not including fringes to
955 the left and right of the window. */
957 INLINE int
958 window_box_width (w, area)
959 struct window *w;
960 int area;
962 int cols = XFASTINT (w->total_cols);
963 int pixels = 0;
965 if (!w->pseudo_window_p)
967 cols -= WINDOW_SCROLL_BAR_COLS (w);
969 if (area == TEXT_AREA)
971 if (INTEGERP (w->left_margin_cols))
972 cols -= XFASTINT (w->left_margin_cols);
973 if (INTEGERP (w->right_margin_cols))
974 cols -= XFASTINT (w->right_margin_cols);
975 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
977 else if (area == LEFT_MARGIN_AREA)
979 cols = (INTEGERP (w->left_margin_cols)
980 ? XFASTINT (w->left_margin_cols) : 0);
981 pixels = 0;
983 else if (area == RIGHT_MARGIN_AREA)
985 cols = (INTEGERP (w->right_margin_cols)
986 ? XFASTINT (w->right_margin_cols) : 0);
987 pixels = 0;
991 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
995 /* Return the pixel height of the display area of window W, not
996 including mode lines of W, if any. */
998 INLINE int
999 window_box_height (w)
1000 struct window *w;
1002 struct frame *f = XFRAME (w->frame);
1003 int height = WINDOW_TOTAL_HEIGHT (w);
1005 xassert (height >= 0);
1007 /* Note: the code below that determines the mode-line/header-line
1008 height is essentially the same as that contained in the macro
1009 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1010 the appropriate glyph row has its `mode_line_p' flag set,
1011 and if it doesn't, uses estimate_mode_line_height instead. */
1013 if (WINDOW_WANTS_MODELINE_P (w))
1015 struct glyph_row *ml_row
1016 = (w->current_matrix && w->current_matrix->rows
1017 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1018 : 0);
1019 if (ml_row && ml_row->mode_line_p)
1020 height -= ml_row->height;
1021 else
1022 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1025 if (WINDOW_WANTS_HEADER_LINE_P (w))
1027 struct glyph_row *hl_row
1028 = (w->current_matrix && w->current_matrix->rows
1029 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1030 : 0);
1031 if (hl_row && hl_row->mode_line_p)
1032 height -= hl_row->height;
1033 else
1034 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1037 /* With a very small font and a mode-line that's taller than
1038 default, we might end up with a negative height. */
1039 return max (0, height);
1042 /* Return the window-relative coordinate of the left edge of display
1043 area AREA of window W. AREA < 0 means return the left edge of the
1044 whole window, to the right of the left fringe of W. */
1046 INLINE int
1047 window_box_left_offset (w, area)
1048 struct window *w;
1049 int area;
1051 int x;
1053 if (w->pseudo_window_p)
1054 return 0;
1056 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1058 if (area == TEXT_AREA)
1059 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1060 + window_box_width (w, LEFT_MARGIN_AREA));
1061 else if (area == RIGHT_MARGIN_AREA)
1062 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1063 + window_box_width (w, LEFT_MARGIN_AREA)
1064 + window_box_width (w, TEXT_AREA)
1065 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1067 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1068 else if (area == LEFT_MARGIN_AREA
1069 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1070 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1072 return x;
1076 /* Return the window-relative coordinate of the right edge of display
1077 area AREA of window W. AREA < 0 means return the left edge of the
1078 whole window, to the left of the right fringe of W. */
1080 INLINE int
1081 window_box_right_offset (w, area)
1082 struct window *w;
1083 int area;
1085 return window_box_left_offset (w, area) + window_box_width (w, area);
1088 /* Return the frame-relative coordinate of the left edge of display
1089 area AREA of window W. AREA < 0 means return the left edge of the
1090 whole window, to the right of the left fringe of W. */
1092 INLINE int
1093 window_box_left (w, area)
1094 struct window *w;
1095 int area;
1097 struct frame *f = XFRAME (w->frame);
1098 int x;
1100 if (w->pseudo_window_p)
1101 return FRAME_INTERNAL_BORDER_WIDTH (f);
1103 x = (WINDOW_LEFT_EDGE_X (w)
1104 + window_box_left_offset (w, area));
1106 return x;
1110 /* Return the frame-relative coordinate of the right edge of display
1111 area AREA of window W. AREA < 0 means return the left edge of the
1112 whole window, to the left of the right fringe of W. */
1114 INLINE int
1115 window_box_right (w, area)
1116 struct window *w;
1117 int area;
1119 return window_box_left (w, area) + window_box_width (w, area);
1122 /* Get the bounding box of the display area AREA of window W, without
1123 mode lines, in frame-relative coordinates. AREA < 0 means the
1124 whole window, not including the left and right fringes of
1125 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1126 coordinates of the upper-left corner of the box. Return in
1127 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1129 INLINE void
1130 window_box (w, area, box_x, box_y, box_width, box_height)
1131 struct window *w;
1132 int area;
1133 int *box_x, *box_y, *box_width, *box_height;
1135 if (box_width)
1136 *box_width = window_box_width (w, area);
1137 if (box_height)
1138 *box_height = window_box_height (w);
1139 if (box_x)
1140 *box_x = window_box_left (w, area);
1141 if (box_y)
1143 *box_y = WINDOW_TOP_EDGE_Y (w);
1144 if (WINDOW_WANTS_HEADER_LINE_P (w))
1145 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1150 /* Get the bounding box of the display area AREA of window W, without
1151 mode lines. AREA < 0 means the whole window, not including the
1152 left and right fringe of the window. Return in *TOP_LEFT_X
1153 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1154 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1155 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1156 box. */
1158 INLINE void
1159 window_box_edges (w, area, top_left_x, top_left_y,
1160 bottom_right_x, bottom_right_y)
1161 struct window *w;
1162 int area;
1163 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
1165 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1166 bottom_right_y);
1167 *bottom_right_x += *top_left_x;
1168 *bottom_right_y += *top_left_y;
1173 /***********************************************************************
1174 Utilities
1175 ***********************************************************************/
1177 /* Return the bottom y-position of the line the iterator IT is in.
1178 This can modify IT's settings. */
1181 line_bottom_y (it)
1182 struct it *it;
1184 int line_height = it->max_ascent + it->max_descent;
1185 int line_top_y = it->current_y;
1187 if (line_height == 0)
1189 if (last_height)
1190 line_height = last_height;
1191 else if (IT_CHARPOS (*it) < ZV)
1193 move_it_by_lines (it, 1, 1);
1194 line_height = (it->max_ascent || it->max_descent
1195 ? it->max_ascent + it->max_descent
1196 : last_height);
1198 else
1200 struct glyph_row *row = it->glyph_row;
1202 /* Use the default character height. */
1203 it->glyph_row = NULL;
1204 it->what = IT_CHARACTER;
1205 it->c = ' ';
1206 it->len = 1;
1207 PRODUCE_GLYPHS (it);
1208 line_height = it->ascent + it->descent;
1209 it->glyph_row = row;
1213 return line_top_y + line_height;
1217 /* Return 1 if position CHARPOS is visible in window W. Set *FULLY to
1218 1 if POS is visible and the line containing POS is fully visible.
1219 EXACT_MODE_LINE_HEIGHTS_P non-zero means compute exact mode-line
1220 and header-lines heights. */
1223 pos_visible_p (w, charpos, fully, exact_mode_line_heights_p)
1224 struct window *w;
1225 int charpos, *fully, exact_mode_line_heights_p;
1227 struct it it;
1228 struct text_pos top;
1229 int visible_p;
1230 struct buffer *old_buffer = NULL;
1232 if (XBUFFER (w->buffer) != current_buffer)
1234 old_buffer = current_buffer;
1235 set_buffer_internal_1 (XBUFFER (w->buffer));
1238 *fully = visible_p = 0;
1239 SET_TEXT_POS_FROM_MARKER (top, w->start);
1241 /* Compute exact mode line heights, if requested. */
1242 if (exact_mode_line_heights_p)
1244 if (WINDOW_WANTS_MODELINE_P (w))
1245 current_mode_line_height
1246 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1247 current_buffer->mode_line_format);
1249 if (WINDOW_WANTS_HEADER_LINE_P (w))
1250 current_header_line_height
1251 = display_mode_line (w, HEADER_LINE_FACE_ID,
1252 current_buffer->header_line_format);
1255 start_display (&it, w, top);
1256 move_it_to (&it, charpos, 0, it.last_visible_y, -1,
1257 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
1259 /* Note that we may overshoot because of invisible text. */
1260 if (IT_CHARPOS (it) >= charpos)
1262 int top_y = it.current_y;
1263 int bottom_y = line_bottom_y (&it);
1264 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1266 if (top_y < window_top_y)
1267 visible_p = bottom_y > window_top_y;
1268 else if (top_y < it.last_visible_y)
1270 visible_p = 1;
1271 *fully = bottom_y <= it.last_visible_y;
1274 else if (it.current_y + it.max_ascent + it.max_descent > it.last_visible_y)
1276 move_it_by_lines (&it, 1, 0);
1277 if (charpos < IT_CHARPOS (it))
1279 visible_p = 1;
1280 *fully = 0;
1284 if (old_buffer)
1285 set_buffer_internal_1 (old_buffer);
1287 current_header_line_height = current_mode_line_height = -1;
1288 return visible_p;
1292 /* Return the next character from STR which is MAXLEN bytes long.
1293 Return in *LEN the length of the character. This is like
1294 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1295 we find one, we return a `?', but with the length of the invalid
1296 character. */
1298 static INLINE int
1299 string_char_and_length (str, maxlen, len)
1300 const unsigned char *str;
1301 int maxlen, *len;
1303 int c;
1305 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
1306 if (!CHAR_VALID_P (c, 1))
1307 /* We may not change the length here because other places in Emacs
1308 don't use this function, i.e. they silently accept invalid
1309 characters. */
1310 c = '?';
1312 return c;
1317 /* Given a position POS containing a valid character and byte position
1318 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1320 static struct text_pos
1321 string_pos_nchars_ahead (pos, string, nchars)
1322 struct text_pos pos;
1323 Lisp_Object string;
1324 int nchars;
1326 xassert (STRINGP (string) && nchars >= 0);
1328 if (STRING_MULTIBYTE (string))
1330 int rest = SBYTES (string) - BYTEPOS (pos);
1331 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1332 int len;
1334 while (nchars--)
1336 string_char_and_length (p, rest, &len);
1337 p += len, rest -= len;
1338 xassert (rest >= 0);
1339 CHARPOS (pos) += 1;
1340 BYTEPOS (pos) += len;
1343 else
1344 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1346 return pos;
1350 /* Value is the text position, i.e. character and byte position,
1351 for character position CHARPOS in STRING. */
1353 static INLINE struct text_pos
1354 string_pos (charpos, string)
1355 int charpos;
1356 Lisp_Object string;
1358 struct text_pos pos;
1359 xassert (STRINGP (string));
1360 xassert (charpos >= 0);
1361 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1362 return pos;
1366 /* Value is a text position, i.e. character and byte position, for
1367 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1368 means recognize multibyte characters. */
1370 static struct text_pos
1371 c_string_pos (charpos, s, multibyte_p)
1372 int charpos;
1373 unsigned char *s;
1374 int multibyte_p;
1376 struct text_pos pos;
1378 xassert (s != NULL);
1379 xassert (charpos >= 0);
1381 if (multibyte_p)
1383 int rest = strlen (s), len;
1385 SET_TEXT_POS (pos, 0, 0);
1386 while (charpos--)
1388 string_char_and_length (s, rest, &len);
1389 s += len, rest -= len;
1390 xassert (rest >= 0);
1391 CHARPOS (pos) += 1;
1392 BYTEPOS (pos) += len;
1395 else
1396 SET_TEXT_POS (pos, charpos, charpos);
1398 return pos;
1402 /* Value is the number of characters in C string S. MULTIBYTE_P
1403 non-zero means recognize multibyte characters. */
1405 static int
1406 number_of_chars (s, multibyte_p)
1407 unsigned char *s;
1408 int multibyte_p;
1410 int nchars;
1412 if (multibyte_p)
1414 int rest = strlen (s), len;
1415 unsigned char *p = (unsigned char *) s;
1417 for (nchars = 0; rest > 0; ++nchars)
1419 string_char_and_length (p, rest, &len);
1420 rest -= len, p += len;
1423 else
1424 nchars = strlen (s);
1426 return nchars;
1430 /* Compute byte position NEWPOS->bytepos corresponding to
1431 NEWPOS->charpos. POS is a known position in string STRING.
1432 NEWPOS->charpos must be >= POS.charpos. */
1434 static void
1435 compute_string_pos (newpos, pos, string)
1436 struct text_pos *newpos, pos;
1437 Lisp_Object string;
1439 xassert (STRINGP (string));
1440 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1442 if (STRING_MULTIBYTE (string))
1443 *newpos = string_pos_nchars_ahead (pos, string,
1444 CHARPOS (*newpos) - CHARPOS (pos));
1445 else
1446 BYTEPOS (*newpos) = CHARPOS (*newpos);
1449 /* EXPORT:
1450 Return an estimation of the pixel height of mode or top lines on
1451 frame F. FACE_ID specifies what line's height to estimate. */
1454 estimate_mode_line_height (f, face_id)
1455 struct frame *f;
1456 enum face_id face_id;
1458 #ifdef HAVE_WINDOW_SYSTEM
1459 if (FRAME_WINDOW_P (f))
1461 int height = FONT_HEIGHT (FRAME_FONT (f));
1463 /* This function is called so early when Emacs starts that the face
1464 cache and mode line face are not yet initialized. */
1465 if (FRAME_FACE_CACHE (f))
1467 struct face *face = FACE_FROM_ID (f, face_id);
1468 if (face)
1470 if (face->font)
1471 height = FONT_HEIGHT (face->font);
1472 if (face->box_line_width > 0)
1473 height += 2 * face->box_line_width;
1477 return height;
1479 #endif
1481 return 1;
1484 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1485 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1486 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1487 not force the value into range. */
1489 void
1490 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
1491 FRAME_PTR f;
1492 register int pix_x, pix_y;
1493 int *x, *y;
1494 NativeRectangle *bounds;
1495 int noclip;
1498 #ifdef HAVE_WINDOW_SYSTEM
1499 if (FRAME_WINDOW_P (f))
1501 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1502 even for negative values. */
1503 if (pix_x < 0)
1504 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1505 if (pix_y < 0)
1506 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1508 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1509 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1511 if (bounds)
1512 STORE_NATIVE_RECT (*bounds,
1513 FRAME_COL_TO_PIXEL_X (f, pix_x),
1514 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1515 FRAME_COLUMN_WIDTH (f) - 1,
1516 FRAME_LINE_HEIGHT (f) - 1);
1518 if (!noclip)
1520 if (pix_x < 0)
1521 pix_x = 0;
1522 else if (pix_x > FRAME_TOTAL_COLS (f))
1523 pix_x = FRAME_TOTAL_COLS (f);
1525 if (pix_y < 0)
1526 pix_y = 0;
1527 else if (pix_y > FRAME_LINES (f))
1528 pix_y = FRAME_LINES (f);
1531 #endif
1533 *x = pix_x;
1534 *y = pix_y;
1538 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1539 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1540 can't tell the positions because W's display is not up to date,
1541 return 0. */
1544 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
1545 struct window *w;
1546 int hpos, vpos;
1547 int *frame_x, *frame_y;
1549 #ifdef HAVE_WINDOW_SYSTEM
1550 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1552 int success_p;
1554 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1555 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1557 if (display_completed)
1559 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1560 struct glyph *glyph = row->glyphs[TEXT_AREA];
1561 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1563 hpos = row->x;
1564 vpos = row->y;
1565 while (glyph < end)
1567 hpos += glyph->pixel_width;
1568 ++glyph;
1571 /* If first glyph is partially visible, its first visible position is still 0. */
1572 if (hpos < 0)
1573 hpos = 0;
1575 success_p = 1;
1577 else
1579 hpos = vpos = 0;
1580 success_p = 0;
1583 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1584 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1585 return success_p;
1587 #endif
1589 *frame_x = hpos;
1590 *frame_y = vpos;
1591 return 1;
1595 #ifdef HAVE_WINDOW_SYSTEM
1597 /* Find the glyph under window-relative coordinates X/Y in window W.
1598 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1599 strings. Return in *HPOS and *VPOS the row and column number of
1600 the glyph found. Return in *AREA the glyph area containing X.
1601 Value is a pointer to the glyph found or null if X/Y is not on
1602 text, or we can't tell because W's current matrix is not up to
1603 date. */
1605 static struct glyph *
1606 x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
1607 struct window *w;
1608 int x, y;
1609 int *hpos, *vpos, *dx, *dy, *area;
1611 struct glyph *glyph, *end;
1612 struct glyph_row *row = NULL;
1613 int x0, i;
1615 /* Find row containing Y. Give up if some row is not enabled. */
1616 for (i = 0; i < w->current_matrix->nrows; ++i)
1618 row = MATRIX_ROW (w->current_matrix, i);
1619 if (!row->enabled_p)
1620 return NULL;
1621 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1622 break;
1625 *vpos = i;
1626 *hpos = 0;
1628 /* Give up if Y is not in the window. */
1629 if (i == w->current_matrix->nrows)
1630 return NULL;
1632 /* Get the glyph area containing X. */
1633 if (w->pseudo_window_p)
1635 *area = TEXT_AREA;
1636 x0 = 0;
1638 else
1640 if (x < window_box_left_offset (w, TEXT_AREA))
1642 *area = LEFT_MARGIN_AREA;
1643 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1645 else if (x < window_box_right_offset (w, TEXT_AREA))
1647 *area = TEXT_AREA;
1648 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1650 else
1652 *area = RIGHT_MARGIN_AREA;
1653 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1657 /* Find glyph containing X. */
1658 glyph = row->glyphs[*area];
1659 end = glyph + row->used[*area];
1660 x -= x0;
1661 while (glyph < end && x >= glyph->pixel_width)
1663 x -= glyph->pixel_width;
1664 ++glyph;
1667 if (glyph == end)
1668 return NULL;
1670 if (dx)
1672 *dx = x;
1673 *dy = y - (row->y + row->ascent - glyph->ascent);
1676 *hpos = glyph - row->glyphs[*area];
1677 return glyph;
1681 /* EXPORT:
1682 Convert frame-relative x/y to coordinates relative to window W.
1683 Takes pseudo-windows into account. */
1685 void
1686 frame_to_window_pixel_xy (w, x, y)
1687 struct window *w;
1688 int *x, *y;
1690 if (w->pseudo_window_p)
1692 /* A pseudo-window is always full-width, and starts at the
1693 left edge of the frame, plus a frame border. */
1694 struct frame *f = XFRAME (w->frame);
1695 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1696 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1698 else
1700 *x -= WINDOW_LEFT_EDGE_X (w);
1701 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1705 /* EXPORT:
1706 Return in *R the clipping rectangle for glyph string S. */
1708 void
1709 get_glyph_string_clip_rect (s, nr)
1710 struct glyph_string *s;
1711 NativeRectangle *nr;
1713 XRectangle r;
1715 if (s->row->full_width_p)
1717 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1718 r.x = WINDOW_LEFT_EDGE_X (s->w);
1719 r.width = WINDOW_TOTAL_WIDTH (s->w);
1721 /* Unless displaying a mode or menu bar line, which are always
1722 fully visible, clip to the visible part of the row. */
1723 if (s->w->pseudo_window_p)
1724 r.height = s->row->visible_height;
1725 else
1726 r.height = s->height;
1728 else
1730 /* This is a text line that may be partially visible. */
1731 r.x = window_box_left (s->w, s->area);
1732 r.width = window_box_width (s->w, s->area);
1733 r.height = s->row->visible_height;
1736 /* If S draws overlapping rows, it's sufficient to use the top and
1737 bottom of the window for clipping because this glyph string
1738 intentionally draws over other lines. */
1739 if (s->for_overlaps_p)
1741 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1742 r.height = window_text_bottom_y (s->w) - r.y;
1744 else
1746 /* Don't use S->y for clipping because it doesn't take partially
1747 visible lines into account. For example, it can be negative for
1748 partially visible lines at the top of a window. */
1749 if (!s->row->full_width_p
1750 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1751 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1752 else
1753 r.y = max (0, s->row->y);
1755 /* If drawing a tool-bar window, draw it over the internal border
1756 at the top of the window. */
1757 if (s->w == XWINDOW (s->f->tool_bar_window))
1758 r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
1761 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1763 /* If drawing the cursor, don't let glyph draw outside its
1764 advertised boundaries. Cleartype does this under some circumstances. */
1765 if (s->hl == DRAW_CURSOR)
1767 struct glyph *glyph = s->first_glyph;
1768 int height;
1770 if (s->x > r.x)
1772 r.width -= s->x - r.x;
1773 r.x = s->x;
1775 r.width = min (r.width, glyph->pixel_width);
1777 /* Don't draw cursor glyph taller than our actual glyph. */
1778 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
1779 if (height < r.height)
1781 r.y = s->ybase + glyph->descent - height;
1782 r.height = height;
1786 #ifdef CONVERT_FROM_XRECT
1787 CONVERT_FROM_XRECT (r, *nr);
1788 #else
1789 *nr = r;
1790 #endif
1793 #endif /* HAVE_WINDOW_SYSTEM */
1796 /***********************************************************************
1797 Lisp form evaluation
1798 ***********************************************************************/
1800 /* Error handler for safe_eval and safe_call. */
1802 static Lisp_Object
1803 safe_eval_handler (arg)
1804 Lisp_Object arg;
1806 add_to_log ("Error during redisplay: %s", arg, Qnil);
1807 return Qnil;
1811 /* Evaluate SEXPR and return the result, or nil if something went
1812 wrong. Prevent redisplay during the evaluation. */
1814 Lisp_Object
1815 safe_eval (sexpr)
1816 Lisp_Object sexpr;
1818 Lisp_Object val;
1820 if (inhibit_eval_during_redisplay)
1821 val = Qnil;
1822 else
1824 int count = SPECPDL_INDEX ();
1825 struct gcpro gcpro1;
1827 GCPRO1 (sexpr);
1828 specbind (Qinhibit_redisplay, Qt);
1829 /* Use Qt to ensure debugger does not run,
1830 so there is no possibility of wanting to redisplay. */
1831 val = internal_condition_case_1 (Feval, sexpr, Qt,
1832 safe_eval_handler);
1833 UNGCPRO;
1834 val = unbind_to (count, val);
1837 return val;
1841 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
1842 Return the result, or nil if something went wrong. Prevent
1843 redisplay during the evaluation. */
1845 Lisp_Object
1846 safe_call (nargs, args)
1847 int nargs;
1848 Lisp_Object *args;
1850 Lisp_Object val;
1852 if (inhibit_eval_during_redisplay)
1853 val = Qnil;
1854 else
1856 int count = SPECPDL_INDEX ();
1857 struct gcpro gcpro1;
1859 GCPRO1 (args[0]);
1860 gcpro1.nvars = nargs;
1861 specbind (Qinhibit_redisplay, Qt);
1862 /* Use Qt to ensure debugger does not run,
1863 so there is no possibility of wanting to redisplay. */
1864 val = internal_condition_case_2 (Ffuncall, nargs, args, Qt,
1865 safe_eval_handler);
1866 UNGCPRO;
1867 val = unbind_to (count, val);
1870 return val;
1874 /* Call function FN with one argument ARG.
1875 Return the result, or nil if something went wrong. */
1877 Lisp_Object
1878 safe_call1 (fn, arg)
1879 Lisp_Object fn, arg;
1881 Lisp_Object args[2];
1882 args[0] = fn;
1883 args[1] = arg;
1884 return safe_call (2, args);
1889 /***********************************************************************
1890 Debugging
1891 ***********************************************************************/
1893 #if 0
1895 /* Define CHECK_IT to perform sanity checks on iterators.
1896 This is for debugging. It is too slow to do unconditionally. */
1898 static void
1899 check_it (it)
1900 struct it *it;
1902 if (it->method == next_element_from_string)
1904 xassert (STRINGP (it->string));
1905 xassert (IT_STRING_CHARPOS (*it) >= 0);
1907 else if (it->method == next_element_from_buffer)
1909 /* Check that character and byte positions agree. */
1910 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
1913 if (it->dpvec)
1914 xassert (it->current.dpvec_index >= 0);
1915 else
1916 xassert (it->current.dpvec_index < 0);
1919 #define CHECK_IT(IT) check_it ((IT))
1921 #else /* not 0 */
1923 #define CHECK_IT(IT) (void) 0
1925 #endif /* not 0 */
1928 #if GLYPH_DEBUG
1930 /* Check that the window end of window W is what we expect it
1931 to be---the last row in the current matrix displaying text. */
1933 static void
1934 check_window_end (w)
1935 struct window *w;
1937 if (!MINI_WINDOW_P (w)
1938 && !NILP (w->window_end_valid))
1940 struct glyph_row *row;
1941 xassert ((row = MATRIX_ROW (w->current_matrix,
1942 XFASTINT (w->window_end_vpos)),
1943 !row->enabled_p
1944 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
1945 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
1949 #define CHECK_WINDOW_END(W) check_window_end ((W))
1951 #else /* not GLYPH_DEBUG */
1953 #define CHECK_WINDOW_END(W) (void) 0
1955 #endif /* not GLYPH_DEBUG */
1959 /***********************************************************************
1960 Iterator initialization
1961 ***********************************************************************/
1963 /* Initialize IT for displaying current_buffer in window W, starting
1964 at character position CHARPOS. CHARPOS < 0 means that no buffer
1965 position is specified which is useful when the iterator is assigned
1966 a position later. BYTEPOS is the byte position corresponding to
1967 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
1969 If ROW is not null, calls to produce_glyphs with IT as parameter
1970 will produce glyphs in that row.
1972 BASE_FACE_ID is the id of a base face to use. It must be one of
1973 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
1974 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
1975 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
1977 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
1978 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
1979 will be initialized to use the corresponding mode line glyph row of
1980 the desired matrix of W. */
1982 void
1983 init_iterator (it, w, charpos, bytepos, row, base_face_id)
1984 struct it *it;
1985 struct window *w;
1986 int charpos, bytepos;
1987 struct glyph_row *row;
1988 enum face_id base_face_id;
1990 int highlight_region_p;
1992 /* Some precondition checks. */
1993 xassert (w != NULL && it != NULL);
1994 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
1995 && charpos <= ZV));
1997 /* If face attributes have been changed since the last redisplay,
1998 free realized faces now because they depend on face definitions
1999 that might have changed. Don't free faces while there might be
2000 desired matrices pending which reference these faces. */
2001 if (face_change_count && !inhibit_free_realized_faces)
2003 face_change_count = 0;
2004 free_all_realized_faces (Qnil);
2007 /* Use one of the mode line rows of W's desired matrix if
2008 appropriate. */
2009 if (row == NULL)
2011 if (base_face_id == MODE_LINE_FACE_ID
2012 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2013 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2014 else if (base_face_id == HEADER_LINE_FACE_ID)
2015 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2018 /* Clear IT. */
2019 bzero (it, sizeof *it);
2020 it->current.overlay_string_index = -1;
2021 it->current.dpvec_index = -1;
2022 it->base_face_id = base_face_id;
2024 /* The window in which we iterate over current_buffer: */
2025 XSETWINDOW (it->window, w);
2026 it->w = w;
2027 it->f = XFRAME (w->frame);
2029 /* Extra space between lines (on window systems only). */
2030 if (base_face_id == DEFAULT_FACE_ID
2031 && FRAME_WINDOW_P (it->f))
2033 if (NATNUMP (current_buffer->extra_line_spacing))
2034 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
2035 else if (it->f->extra_line_spacing > 0)
2036 it->extra_line_spacing = it->f->extra_line_spacing;
2039 /* If realized faces have been removed, e.g. because of face
2040 attribute changes of named faces, recompute them. When running
2041 in batch mode, the face cache of Vterminal_frame is null. If
2042 we happen to get called, make a dummy face cache. */
2043 if (noninteractive && FRAME_FACE_CACHE (it->f) == NULL)
2044 init_frame_faces (it->f);
2045 if (FRAME_FACE_CACHE (it->f)->used == 0)
2046 recompute_basic_faces (it->f);
2048 /* Current value of the `space-width', and 'height' properties. */
2049 it->space_width = Qnil;
2050 it->font_height = Qnil;
2052 /* Are control characters displayed as `^C'? */
2053 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
2055 /* -1 means everything between a CR and the following line end
2056 is invisible. >0 means lines indented more than this value are
2057 invisible. */
2058 it->selective = (INTEGERP (current_buffer->selective_display)
2059 ? XFASTINT (current_buffer->selective_display)
2060 : (!NILP (current_buffer->selective_display)
2061 ? -1 : 0));
2062 it->selective_display_ellipsis_p
2063 = !NILP (current_buffer->selective_display_ellipses);
2065 /* Display table to use. */
2066 it->dp = window_display_table (w);
2068 /* Are multibyte characters enabled in current_buffer? */
2069 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2071 /* Non-zero if we should highlight the region. */
2072 highlight_region_p
2073 = (!NILP (Vtransient_mark_mode)
2074 && !NILP (current_buffer->mark_active)
2075 && XMARKER (current_buffer->mark)->buffer != 0);
2077 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2078 start and end of a visible region in window IT->w. Set both to
2079 -1 to indicate no region. */
2080 if (highlight_region_p
2081 /* Maybe highlight only in selected window. */
2082 && (/* Either show region everywhere. */
2083 highlight_nonselected_windows
2084 /* Or show region in the selected window. */
2085 || w == XWINDOW (selected_window)
2086 /* Or show the region if we are in the mini-buffer and W is
2087 the window the mini-buffer refers to. */
2088 || (MINI_WINDOW_P (XWINDOW (selected_window))
2089 && WINDOWP (minibuf_selected_window)
2090 && w == XWINDOW (minibuf_selected_window))))
2092 int charpos = marker_position (current_buffer->mark);
2093 it->region_beg_charpos = min (PT, charpos);
2094 it->region_end_charpos = max (PT, charpos);
2096 else
2097 it->region_beg_charpos = it->region_end_charpos = -1;
2099 /* Get the position at which the redisplay_end_trigger hook should
2100 be run, if it is to be run at all. */
2101 if (MARKERP (w->redisplay_end_trigger)
2102 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2103 it->redisplay_end_trigger_charpos
2104 = marker_position (w->redisplay_end_trigger);
2105 else if (INTEGERP (w->redisplay_end_trigger))
2106 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2108 /* Correct bogus values of tab_width. */
2109 it->tab_width = XINT (current_buffer->tab_width);
2110 if (it->tab_width <= 0 || it->tab_width > 1000)
2111 it->tab_width = 8;
2113 /* Are lines in the display truncated? */
2114 it->truncate_lines_p
2115 = (base_face_id != DEFAULT_FACE_ID
2116 || XINT (it->w->hscroll)
2117 || (truncate_partial_width_windows
2118 && !WINDOW_FULL_WIDTH_P (it->w))
2119 || !NILP (current_buffer->truncate_lines));
2121 /* Get dimensions of truncation and continuation glyphs. These are
2122 displayed as fringe bitmaps under X, so we don't need them for such
2123 frames. */
2124 if (!FRAME_WINDOW_P (it->f))
2126 if (it->truncate_lines_p)
2128 /* We will need the truncation glyph. */
2129 xassert (it->glyph_row == NULL);
2130 produce_special_glyphs (it, IT_TRUNCATION);
2131 it->truncation_pixel_width = it->pixel_width;
2133 else
2135 /* We will need the continuation glyph. */
2136 xassert (it->glyph_row == NULL);
2137 produce_special_glyphs (it, IT_CONTINUATION);
2138 it->continuation_pixel_width = it->pixel_width;
2141 /* Reset these values to zero because the produce_special_glyphs
2142 above has changed them. */
2143 it->pixel_width = it->ascent = it->descent = 0;
2144 it->phys_ascent = it->phys_descent = 0;
2147 /* Set this after getting the dimensions of truncation and
2148 continuation glyphs, so that we don't produce glyphs when calling
2149 produce_special_glyphs, above. */
2150 it->glyph_row = row;
2151 it->area = TEXT_AREA;
2153 /* Get the dimensions of the display area. The display area
2154 consists of the visible window area plus a horizontally scrolled
2155 part to the left of the window. All x-values are relative to the
2156 start of this total display area. */
2157 if (base_face_id != DEFAULT_FACE_ID)
2159 /* Mode lines, menu bar in terminal frames. */
2160 it->first_visible_x = 0;
2161 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2163 else
2165 it->first_visible_x
2166 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2167 it->last_visible_x = (it->first_visible_x
2168 + window_box_width (w, TEXT_AREA));
2170 /* If we truncate lines, leave room for the truncator glyph(s) at
2171 the right margin. Otherwise, leave room for the continuation
2172 glyph(s). Truncation and continuation glyphs are not inserted
2173 for window-based redisplay. */
2174 if (!FRAME_WINDOW_P (it->f))
2176 if (it->truncate_lines_p)
2177 it->last_visible_x -= it->truncation_pixel_width;
2178 else
2179 it->last_visible_x -= it->continuation_pixel_width;
2182 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2183 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2186 /* Leave room for a border glyph. */
2187 if (!FRAME_WINDOW_P (it->f)
2188 && !WINDOW_RIGHTMOST_P (it->w))
2189 it->last_visible_x -= 1;
2191 it->last_visible_y = window_text_bottom_y (w);
2193 /* For mode lines and alike, arrange for the first glyph having a
2194 left box line if the face specifies a box. */
2195 if (base_face_id != DEFAULT_FACE_ID)
2197 struct face *face;
2199 it->face_id = base_face_id;
2201 /* If we have a boxed mode line, make the first character appear
2202 with a left box line. */
2203 face = FACE_FROM_ID (it->f, base_face_id);
2204 if (face->box != FACE_NO_BOX)
2205 it->start_of_box_run_p = 1;
2208 /* If a buffer position was specified, set the iterator there,
2209 getting overlays and face properties from that position. */
2210 if (charpos >= BUF_BEG (current_buffer))
2212 it->end_charpos = ZV;
2213 it->face_id = -1;
2214 IT_CHARPOS (*it) = charpos;
2216 /* Compute byte position if not specified. */
2217 if (bytepos < charpos)
2218 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2219 else
2220 IT_BYTEPOS (*it) = bytepos;
2222 it->start = it->current;
2224 /* Compute faces etc. */
2225 reseat (it, it->current.pos, 1);
2228 CHECK_IT (it);
2232 /* Initialize IT for the display of window W with window start POS. */
2234 void
2235 start_display (it, w, pos)
2236 struct it *it;
2237 struct window *w;
2238 struct text_pos pos;
2240 struct glyph_row *row;
2241 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2243 row = w->desired_matrix->rows + first_vpos;
2244 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2245 it->first_vpos = first_vpos;
2247 if (!it->truncate_lines_p)
2249 int start_at_line_beg_p;
2250 int first_y = it->current_y;
2252 /* If window start is not at a line start, skip forward to POS to
2253 get the correct continuation lines width. */
2254 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2255 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2256 if (!start_at_line_beg_p)
2258 int new_x;
2260 reseat_at_previous_visible_line_start (it);
2261 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2263 new_x = it->current_x + it->pixel_width;
2265 /* If lines are continued, this line may end in the middle
2266 of a multi-glyph character (e.g. a control character
2267 displayed as \003, or in the middle of an overlay
2268 string). In this case move_it_to above will not have
2269 taken us to the start of the continuation line but to the
2270 end of the continued line. */
2271 if (it->current_x > 0
2272 && !it->truncate_lines_p /* Lines are continued. */
2273 && (/* And glyph doesn't fit on the line. */
2274 new_x > it->last_visible_x
2275 /* Or it fits exactly and we're on a window
2276 system frame. */
2277 || (new_x == it->last_visible_x
2278 && FRAME_WINDOW_P (it->f))))
2280 if (it->current.dpvec_index >= 0
2281 || it->current.overlay_string_index >= 0)
2283 set_iterator_to_next (it, 1);
2284 move_it_in_display_line_to (it, -1, -1, 0);
2287 it->continuation_lines_width += it->current_x;
2290 /* We're starting a new display line, not affected by the
2291 height of the continued line, so clear the appropriate
2292 fields in the iterator structure. */
2293 it->max_ascent = it->max_descent = 0;
2294 it->max_phys_ascent = it->max_phys_descent = 0;
2296 it->current_y = first_y;
2297 it->vpos = 0;
2298 it->current_x = it->hpos = 0;
2302 #if 0 /* Don't assert the following because start_display is sometimes
2303 called intentionally with a window start that is not at a
2304 line start. Please leave this code in as a comment. */
2306 /* Window start should be on a line start, now. */
2307 xassert (it->continuation_lines_width
2308 || IT_CHARPOS (it) == BEGV
2309 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
2310 #endif /* 0 */
2314 /* Return 1 if POS is a position in ellipses displayed for invisible
2315 text. W is the window we display, for text property lookup. */
2317 static int
2318 in_ellipses_for_invisible_text_p (pos, w)
2319 struct display_pos *pos;
2320 struct window *w;
2322 Lisp_Object prop, window;
2323 int ellipses_p = 0;
2324 int charpos = CHARPOS (pos->pos);
2326 /* If POS specifies a position in a display vector, this might
2327 be for an ellipsis displayed for invisible text. We won't
2328 get the iterator set up for delivering that ellipsis unless
2329 we make sure that it gets aware of the invisible text. */
2330 if (pos->dpvec_index >= 0
2331 && pos->overlay_string_index < 0
2332 && CHARPOS (pos->string_pos) < 0
2333 && charpos > BEGV
2334 && (XSETWINDOW (window, w),
2335 prop = Fget_char_property (make_number (charpos),
2336 Qinvisible, window),
2337 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2339 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2340 window);
2341 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2344 return ellipses_p;
2348 /* Initialize IT for stepping through current_buffer in window W,
2349 starting at position POS that includes overlay string and display
2350 vector/ control character translation position information. Value
2351 is zero if there are overlay strings with newlines at POS. */
2353 static int
2354 init_from_display_pos (it, w, pos)
2355 struct it *it;
2356 struct window *w;
2357 struct display_pos *pos;
2359 int charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2360 int i, overlay_strings_with_newlines = 0;
2362 /* If POS specifies a position in a display vector, this might
2363 be for an ellipsis displayed for invisible text. We won't
2364 get the iterator set up for delivering that ellipsis unless
2365 we make sure that it gets aware of the invisible text. */
2366 if (in_ellipses_for_invisible_text_p (pos, w))
2368 --charpos;
2369 bytepos = 0;
2372 /* Keep in mind: the call to reseat in init_iterator skips invisible
2373 text, so we might end up at a position different from POS. This
2374 is only a problem when POS is a row start after a newline and an
2375 overlay starts there with an after-string, and the overlay has an
2376 invisible property. Since we don't skip invisible text in
2377 display_line and elsewhere immediately after consuming the
2378 newline before the row start, such a POS will not be in a string,
2379 but the call to init_iterator below will move us to the
2380 after-string. */
2381 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2383 for (i = 0; i < it->n_overlay_strings; ++i)
2385 const char *s = SDATA (it->overlay_strings[i]);
2386 const char *e = s + SBYTES (it->overlay_strings[i]);
2388 while (s < e && *s != '\n')
2389 ++s;
2391 if (s < e)
2393 overlay_strings_with_newlines = 1;
2394 break;
2398 /* If position is within an overlay string, set up IT to the right
2399 overlay string. */
2400 if (pos->overlay_string_index >= 0)
2402 int relative_index;
2404 /* If the first overlay string happens to have a `display'
2405 property for an image, the iterator will be set up for that
2406 image, and we have to undo that setup first before we can
2407 correct the overlay string index. */
2408 if (it->method == next_element_from_image)
2409 pop_it (it);
2411 /* We already have the first chunk of overlay strings in
2412 IT->overlay_strings. Load more until the one for
2413 pos->overlay_string_index is in IT->overlay_strings. */
2414 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
2416 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
2417 it->current.overlay_string_index = 0;
2418 while (n--)
2420 load_overlay_strings (it, 0);
2421 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
2425 it->current.overlay_string_index = pos->overlay_string_index;
2426 relative_index = (it->current.overlay_string_index
2427 % OVERLAY_STRING_CHUNK_SIZE);
2428 it->string = it->overlay_strings[relative_index];
2429 xassert (STRINGP (it->string));
2430 it->current.string_pos = pos->string_pos;
2431 it->method = next_element_from_string;
2434 #if 0 /* This is bogus because POS not having an overlay string
2435 position does not mean it's after the string. Example: A
2436 line starting with a before-string and initialization of IT
2437 to the previous row's end position. */
2438 else if (it->current.overlay_string_index >= 0)
2440 /* If POS says we're already after an overlay string ending at
2441 POS, make sure to pop the iterator because it will be in
2442 front of that overlay string. When POS is ZV, we've thereby
2443 also ``processed'' overlay strings at ZV. */
2444 while (it->sp)
2445 pop_it (it);
2446 it->current.overlay_string_index = -1;
2447 it->method = next_element_from_buffer;
2448 if (CHARPOS (pos->pos) == ZV)
2449 it->overlay_strings_at_end_processed_p = 1;
2451 #endif /* 0 */
2453 if (CHARPOS (pos->string_pos) >= 0)
2455 /* Recorded position is not in an overlay string, but in another
2456 string. This can only be a string from a `display' property.
2457 IT should already be filled with that string. */
2458 it->current.string_pos = pos->string_pos;
2459 xassert (STRINGP (it->string));
2462 /* Restore position in display vector translations, control
2463 character translations or ellipses. */
2464 if (pos->dpvec_index >= 0)
2466 if (it->dpvec == NULL)
2467 get_next_display_element (it);
2468 xassert (it->dpvec && it->current.dpvec_index == 0);
2469 it->current.dpvec_index = pos->dpvec_index;
2472 CHECK_IT (it);
2473 return !overlay_strings_with_newlines;
2477 /* Initialize IT for stepping through current_buffer in window W
2478 starting at ROW->start. */
2480 static void
2481 init_to_row_start (it, w, row)
2482 struct it *it;
2483 struct window *w;
2484 struct glyph_row *row;
2486 init_from_display_pos (it, w, &row->start);
2487 it->start = row->start;
2488 it->continuation_lines_width = row->continuation_lines_width;
2489 CHECK_IT (it);
2493 /* Initialize IT for stepping through current_buffer in window W
2494 starting in the line following ROW, i.e. starting at ROW->end.
2495 Value is zero if there are overlay strings with newlines at ROW's
2496 end position. */
2498 static int
2499 init_to_row_end (it, w, row)
2500 struct it *it;
2501 struct window *w;
2502 struct glyph_row *row;
2504 int success = 0;
2506 if (init_from_display_pos (it, w, &row->end))
2508 if (row->continued_p)
2509 it->continuation_lines_width
2510 = row->continuation_lines_width + row->pixel_width;
2511 CHECK_IT (it);
2512 success = 1;
2515 return success;
2521 /***********************************************************************
2522 Text properties
2523 ***********************************************************************/
2525 /* Called when IT reaches IT->stop_charpos. Handle text property and
2526 overlay changes. Set IT->stop_charpos to the next position where
2527 to stop. */
2529 static void
2530 handle_stop (it)
2531 struct it *it;
2533 enum prop_handled handled;
2534 int handle_overlay_change_p = 1;
2535 struct props *p;
2537 it->dpvec = NULL;
2538 it->current.dpvec_index = -1;
2542 handled = HANDLED_NORMALLY;
2544 /* Call text property handlers. */
2545 for (p = it_props; p->handler; ++p)
2547 handled = p->handler (it);
2549 if (handled == HANDLED_RECOMPUTE_PROPS)
2550 break;
2551 else if (handled == HANDLED_RETURN)
2552 return;
2553 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
2554 handle_overlay_change_p = 0;
2557 if (handled != HANDLED_RECOMPUTE_PROPS)
2559 /* Don't check for overlay strings below when set to deliver
2560 characters from a display vector. */
2561 if (it->method == next_element_from_display_vector)
2562 handle_overlay_change_p = 0;
2564 /* Handle overlay changes. */
2565 if (handle_overlay_change_p)
2566 handled = handle_overlay_change (it);
2568 /* Determine where to stop next. */
2569 if (handled == HANDLED_NORMALLY)
2570 compute_stop_pos (it);
2573 while (handled == HANDLED_RECOMPUTE_PROPS);
2577 /* Compute IT->stop_charpos from text property and overlay change
2578 information for IT's current position. */
2580 static void
2581 compute_stop_pos (it)
2582 struct it *it;
2584 register INTERVAL iv, next_iv;
2585 Lisp_Object object, limit, position;
2587 /* If nowhere else, stop at the end. */
2588 it->stop_charpos = it->end_charpos;
2590 if (STRINGP (it->string))
2592 /* Strings are usually short, so don't limit the search for
2593 properties. */
2594 object = it->string;
2595 limit = Qnil;
2596 position = make_number (IT_STRING_CHARPOS (*it));
2598 else
2600 int charpos;
2602 /* If next overlay change is in front of the current stop pos
2603 (which is IT->end_charpos), stop there. Note: value of
2604 next_overlay_change is point-max if no overlay change
2605 follows. */
2606 charpos = next_overlay_change (IT_CHARPOS (*it));
2607 if (charpos < it->stop_charpos)
2608 it->stop_charpos = charpos;
2610 /* If showing the region, we have to stop at the region
2611 start or end because the face might change there. */
2612 if (it->region_beg_charpos > 0)
2614 if (IT_CHARPOS (*it) < it->region_beg_charpos)
2615 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
2616 else if (IT_CHARPOS (*it) < it->region_end_charpos)
2617 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
2620 /* Set up variables for computing the stop position from text
2621 property changes. */
2622 XSETBUFFER (object, current_buffer);
2623 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
2624 position = make_number (IT_CHARPOS (*it));
2628 /* Get the interval containing IT's position. Value is a null
2629 interval if there isn't such an interval. */
2630 iv = validate_interval_range (object, &position, &position, 0);
2631 if (!NULL_INTERVAL_P (iv))
2633 Lisp_Object values_here[LAST_PROP_IDX];
2634 struct props *p;
2636 /* Get properties here. */
2637 for (p = it_props; p->handler; ++p)
2638 values_here[p->idx] = textget (iv->plist, *p->name);
2640 /* Look for an interval following iv that has different
2641 properties. */
2642 for (next_iv = next_interval (iv);
2643 (!NULL_INTERVAL_P (next_iv)
2644 && (NILP (limit)
2645 || XFASTINT (limit) > next_iv->position));
2646 next_iv = next_interval (next_iv))
2648 for (p = it_props; p->handler; ++p)
2650 Lisp_Object new_value;
2652 new_value = textget (next_iv->plist, *p->name);
2653 if (!EQ (values_here[p->idx], new_value))
2654 break;
2657 if (p->handler)
2658 break;
2661 if (!NULL_INTERVAL_P (next_iv))
2663 if (INTEGERP (limit)
2664 && next_iv->position >= XFASTINT (limit))
2665 /* No text property change up to limit. */
2666 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
2667 else
2668 /* Text properties change in next_iv. */
2669 it->stop_charpos = min (it->stop_charpos, next_iv->position);
2673 xassert (STRINGP (it->string)
2674 || (it->stop_charpos >= BEGV
2675 && it->stop_charpos >= IT_CHARPOS (*it)));
2679 /* Return the position of the next overlay change after POS in
2680 current_buffer. Value is point-max if no overlay change
2681 follows. This is like `next-overlay-change' but doesn't use
2682 xmalloc. */
2684 static int
2685 next_overlay_change (pos)
2686 int pos;
2688 int noverlays;
2689 int endpos;
2690 Lisp_Object *overlays;
2691 int len;
2692 int i;
2694 /* Get all overlays at the given position. */
2695 len = 10;
2696 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
2697 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL, 1);
2698 if (noverlays > len)
2700 len = noverlays;
2701 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
2702 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL, 1);
2705 /* If any of these overlays ends before endpos,
2706 use its ending point instead. */
2707 for (i = 0; i < noverlays; ++i)
2709 Lisp_Object oend;
2710 int oendpos;
2712 oend = OVERLAY_END (overlays[i]);
2713 oendpos = OVERLAY_POSITION (oend);
2714 endpos = min (endpos, oendpos);
2717 return endpos;
2722 /***********************************************************************
2723 Fontification
2724 ***********************************************************************/
2726 /* Handle changes in the `fontified' property of the current buffer by
2727 calling hook functions from Qfontification_functions to fontify
2728 regions of text. */
2730 static enum prop_handled
2731 handle_fontified_prop (it)
2732 struct it *it;
2734 Lisp_Object prop, pos;
2735 enum prop_handled handled = HANDLED_NORMALLY;
2737 /* Get the value of the `fontified' property at IT's current buffer
2738 position. (The `fontified' property doesn't have a special
2739 meaning in strings.) If the value is nil, call functions from
2740 Qfontification_functions. */
2741 if (!STRINGP (it->string)
2742 && it->s == NULL
2743 && !NILP (Vfontification_functions)
2744 && !NILP (Vrun_hooks)
2745 && (pos = make_number (IT_CHARPOS (*it)),
2746 prop = Fget_char_property (pos, Qfontified, Qnil),
2747 NILP (prop)))
2749 int count = SPECPDL_INDEX ();
2750 Lisp_Object val;
2752 val = Vfontification_functions;
2753 specbind (Qfontification_functions, Qnil);
2755 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
2756 safe_call1 (val, pos);
2757 else
2759 Lisp_Object globals, fn;
2760 struct gcpro gcpro1, gcpro2;
2762 globals = Qnil;
2763 GCPRO2 (val, globals);
2765 for (; CONSP (val); val = XCDR (val))
2767 fn = XCAR (val);
2769 if (EQ (fn, Qt))
2771 /* A value of t indicates this hook has a local
2772 binding; it means to run the global binding too.
2773 In a global value, t should not occur. If it
2774 does, we must ignore it to avoid an endless
2775 loop. */
2776 for (globals = Fdefault_value (Qfontification_functions);
2777 CONSP (globals);
2778 globals = XCDR (globals))
2780 fn = XCAR (globals);
2781 if (!EQ (fn, Qt))
2782 safe_call1 (fn, pos);
2785 else
2786 safe_call1 (fn, pos);
2789 UNGCPRO;
2792 unbind_to (count, Qnil);
2794 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
2795 something. This avoids an endless loop if they failed to
2796 fontify the text for which reason ever. */
2797 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
2798 handled = HANDLED_RECOMPUTE_PROPS;
2801 return handled;
2806 /***********************************************************************
2807 Faces
2808 ***********************************************************************/
2810 /* Set up iterator IT from face properties at its current position.
2811 Called from handle_stop. */
2813 static enum prop_handled
2814 handle_face_prop (it)
2815 struct it *it;
2817 int new_face_id, next_stop;
2819 if (!STRINGP (it->string))
2821 new_face_id
2822 = face_at_buffer_position (it->w,
2823 IT_CHARPOS (*it),
2824 it->region_beg_charpos,
2825 it->region_end_charpos,
2826 &next_stop,
2827 (IT_CHARPOS (*it)
2828 + TEXT_PROP_DISTANCE_LIMIT),
2831 /* Is this a start of a run of characters with box face?
2832 Caveat: this can be called for a freshly initialized
2833 iterator; face_id is -1 in this case. We know that the new
2834 face will not change until limit, i.e. if the new face has a
2835 box, all characters up to limit will have one. But, as
2836 usual, we don't know whether limit is really the end. */
2837 if (new_face_id != it->face_id)
2839 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2841 /* If new face has a box but old face has not, this is
2842 the start of a run of characters with box, i.e. it has
2843 a shadow on the left side. The value of face_id of the
2844 iterator will be -1 if this is the initial call that gets
2845 the face. In this case, we have to look in front of IT's
2846 position and see whether there is a face != new_face_id. */
2847 it->start_of_box_run_p
2848 = (new_face->box != FACE_NO_BOX
2849 && (it->face_id >= 0
2850 || IT_CHARPOS (*it) == BEG
2851 || new_face_id != face_before_it_pos (it)));
2852 it->face_box_p = new_face->box != FACE_NO_BOX;
2855 else
2857 int base_face_id, bufpos;
2859 if (it->current.overlay_string_index >= 0)
2860 bufpos = IT_CHARPOS (*it);
2861 else
2862 bufpos = 0;
2864 /* For strings from a buffer, i.e. overlay strings or strings
2865 from a `display' property, use the face at IT's current
2866 buffer position as the base face to merge with, so that
2867 overlay strings appear in the same face as surrounding
2868 text, unless they specify their own faces. */
2869 base_face_id = underlying_face_id (it);
2871 new_face_id = face_at_string_position (it->w,
2872 it->string,
2873 IT_STRING_CHARPOS (*it),
2874 bufpos,
2875 it->region_beg_charpos,
2876 it->region_end_charpos,
2877 &next_stop,
2878 base_face_id, 0);
2880 #if 0 /* This shouldn't be neccessary. Let's check it. */
2881 /* If IT is used to display a mode line we would really like to
2882 use the mode line face instead of the frame's default face. */
2883 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
2884 && new_face_id == DEFAULT_FACE_ID)
2885 new_face_id = CURRENT_MODE_LINE_FACE_ID (it->w);
2886 #endif
2888 /* Is this a start of a run of characters with box? Caveat:
2889 this can be called for a freshly allocated iterator; face_id
2890 is -1 is this case. We know that the new face will not
2891 change until the next check pos, i.e. if the new face has a
2892 box, all characters up to that position will have a
2893 box. But, as usual, we don't know whether that position
2894 is really the end. */
2895 if (new_face_id != it->face_id)
2897 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2898 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
2900 /* If new face has a box but old face hasn't, this is the
2901 start of a run of characters with box, i.e. it has a
2902 shadow on the left side. */
2903 it->start_of_box_run_p
2904 = new_face->box && (old_face == NULL || !old_face->box);
2905 it->face_box_p = new_face->box != FACE_NO_BOX;
2909 it->face_id = new_face_id;
2910 return HANDLED_NORMALLY;
2914 /* Return the ID of the face ``underlying'' IT's current position,
2915 which is in a string. If the iterator is associated with a
2916 buffer, return the face at IT's current buffer position.
2917 Otherwise, use the iterator's base_face_id. */
2919 static int
2920 underlying_face_id (it)
2921 struct it *it;
2923 int face_id = it->base_face_id, i;
2925 xassert (STRINGP (it->string));
2927 for (i = it->sp - 1; i >= 0; --i)
2928 if (NILP (it->stack[i].string))
2929 face_id = it->stack[i].face_id;
2931 return face_id;
2935 /* Compute the face one character before or after the current position
2936 of IT. BEFORE_P non-zero means get the face in front of IT's
2937 position. Value is the id of the face. */
2939 static int
2940 face_before_or_after_it_pos (it, before_p)
2941 struct it *it;
2942 int before_p;
2944 int face_id, limit;
2945 int next_check_charpos;
2946 struct text_pos pos;
2948 xassert (it->s == NULL);
2950 if (STRINGP (it->string))
2952 int bufpos, base_face_id;
2954 /* No face change past the end of the string (for the case
2955 we are padding with spaces). No face change before the
2956 string start. */
2957 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
2958 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
2959 return it->face_id;
2961 /* Set pos to the position before or after IT's current position. */
2962 if (before_p)
2963 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
2964 else
2965 /* For composition, we must check the character after the
2966 composition. */
2967 pos = (it->what == IT_COMPOSITION
2968 ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string)
2969 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
2971 if (it->current.overlay_string_index >= 0)
2972 bufpos = IT_CHARPOS (*it);
2973 else
2974 bufpos = 0;
2976 base_face_id = underlying_face_id (it);
2978 /* Get the face for ASCII, or unibyte. */
2979 face_id = face_at_string_position (it->w,
2980 it->string,
2981 CHARPOS (pos),
2982 bufpos,
2983 it->region_beg_charpos,
2984 it->region_end_charpos,
2985 &next_check_charpos,
2986 base_face_id, 0);
2988 /* Correct the face for charsets different from ASCII. Do it
2989 for the multibyte case only. The face returned above is
2990 suitable for unibyte text if IT->string is unibyte. */
2991 if (STRING_MULTIBYTE (it->string))
2993 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
2994 int rest = SBYTES (it->string) - BYTEPOS (pos);
2995 int c, len;
2996 struct face *face = FACE_FROM_ID (it->f, face_id);
2998 c = string_char_and_length (p, rest, &len);
2999 face_id = FACE_FOR_CHAR (it->f, face, c);
3002 else
3004 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3005 || (IT_CHARPOS (*it) <= BEGV && before_p))
3006 return it->face_id;
3008 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3009 pos = it->current.pos;
3011 if (before_p)
3012 DEC_TEXT_POS (pos, it->multibyte_p);
3013 else
3015 if (it->what == IT_COMPOSITION)
3016 /* For composition, we must check the position after the
3017 composition. */
3018 pos.charpos += it->cmp_len, pos.bytepos += it->len;
3019 else
3020 INC_TEXT_POS (pos, it->multibyte_p);
3023 /* Determine face for CHARSET_ASCII, or unibyte. */
3024 face_id = face_at_buffer_position (it->w,
3025 CHARPOS (pos),
3026 it->region_beg_charpos,
3027 it->region_end_charpos,
3028 &next_check_charpos,
3029 limit, 0);
3031 /* Correct the face for charsets different from ASCII. Do it
3032 for the multibyte case only. The face returned above is
3033 suitable for unibyte text if current_buffer is unibyte. */
3034 if (it->multibyte_p)
3036 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3037 struct face *face = FACE_FROM_ID (it->f, face_id);
3038 face_id = FACE_FOR_CHAR (it->f, face, c);
3042 return face_id;
3047 /***********************************************************************
3048 Invisible text
3049 ***********************************************************************/
3051 /* Set up iterator IT from invisible properties at its current
3052 position. Called from handle_stop. */
3054 static enum prop_handled
3055 handle_invisible_prop (it)
3056 struct it *it;
3058 enum prop_handled handled = HANDLED_NORMALLY;
3060 if (STRINGP (it->string))
3062 extern Lisp_Object Qinvisible;
3063 Lisp_Object prop, end_charpos, limit, charpos;
3065 /* Get the value of the invisible text property at the
3066 current position. Value will be nil if there is no such
3067 property. */
3068 charpos = make_number (IT_STRING_CHARPOS (*it));
3069 prop = Fget_text_property (charpos, Qinvisible, it->string);
3071 if (!NILP (prop)
3072 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3074 handled = HANDLED_RECOMPUTE_PROPS;
3076 /* Get the position at which the next change of the
3077 invisible text property can be found in IT->string.
3078 Value will be nil if the property value is the same for
3079 all the rest of IT->string. */
3080 XSETINT (limit, SCHARS (it->string));
3081 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3082 it->string, limit);
3084 /* Text at current position is invisible. The next
3085 change in the property is at position end_charpos.
3086 Move IT's current position to that position. */
3087 if (INTEGERP (end_charpos)
3088 && XFASTINT (end_charpos) < XFASTINT (limit))
3090 struct text_pos old;
3091 old = it->current.string_pos;
3092 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3093 compute_string_pos (&it->current.string_pos, old, it->string);
3095 else
3097 /* The rest of the string is invisible. If this is an
3098 overlay string, proceed with the next overlay string
3099 or whatever comes and return a character from there. */
3100 if (it->current.overlay_string_index >= 0)
3102 next_overlay_string (it);
3103 /* Don't check for overlay strings when we just
3104 finished processing them. */
3105 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3107 else
3109 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3110 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3115 else
3117 int invis_p, newpos, next_stop, start_charpos;
3118 Lisp_Object pos, prop, overlay;
3120 /* First of all, is there invisible text at this position? */
3121 start_charpos = IT_CHARPOS (*it);
3122 pos = make_number (IT_CHARPOS (*it));
3123 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3124 &overlay);
3125 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3127 /* If we are on invisible text, skip over it. */
3128 if (invis_p && IT_CHARPOS (*it) < it->end_charpos)
3130 /* Record whether we have to display an ellipsis for the
3131 invisible text. */
3132 int display_ellipsis_p = invis_p == 2;
3134 handled = HANDLED_RECOMPUTE_PROPS;
3136 /* Loop skipping over invisible text. The loop is left at
3137 ZV or with IT on the first char being visible again. */
3140 /* Try to skip some invisible text. Return value is the
3141 position reached which can be equal to IT's position
3142 if there is nothing invisible here. This skips both
3143 over invisible text properties and overlays with
3144 invisible property. */
3145 newpos = skip_invisible (IT_CHARPOS (*it),
3146 &next_stop, ZV, it->window);
3148 /* If we skipped nothing at all we weren't at invisible
3149 text in the first place. If everything to the end of
3150 the buffer was skipped, end the loop. */
3151 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
3152 invis_p = 0;
3153 else
3155 /* We skipped some characters but not necessarily
3156 all there are. Check if we ended up on visible
3157 text. Fget_char_property returns the property of
3158 the char before the given position, i.e. if we
3159 get invis_p = 0, this means that the char at
3160 newpos is visible. */
3161 pos = make_number (newpos);
3162 prop = Fget_char_property (pos, Qinvisible, it->window);
3163 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3166 /* If we ended up on invisible text, proceed to
3167 skip starting with next_stop. */
3168 if (invis_p)
3169 IT_CHARPOS (*it) = next_stop;
3171 while (invis_p);
3173 /* The position newpos is now either ZV or on visible text. */
3174 IT_CHARPOS (*it) = newpos;
3175 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3177 /* If there are before-strings at the start of invisible
3178 text, and the text is invisible because of a text
3179 property, arrange to show before-strings because 20.x did
3180 it that way. (If the text is invisible because of an
3181 overlay property instead of a text property, this is
3182 already handled in the overlay code.) */
3183 if (NILP (overlay)
3184 && get_overlay_strings (it, start_charpos))
3186 handled = HANDLED_RECOMPUTE_PROPS;
3187 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3189 else if (display_ellipsis_p)
3190 setup_for_ellipsis (it);
3194 return handled;
3198 /* Make iterator IT return `...' next. */
3200 static void
3201 setup_for_ellipsis (it)
3202 struct it *it;
3204 if (it->dp
3205 && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3207 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3208 it->dpvec = v->contents;
3209 it->dpend = v->contents + v->size;
3211 else
3213 /* Default `...'. */
3214 it->dpvec = default_invis_vector;
3215 it->dpend = default_invis_vector + 3;
3218 /* The ellipsis display does not replace the display of the
3219 character at the new position. Indicate this by setting
3220 IT->dpvec_char_len to zero. */
3221 it->dpvec_char_len = 0;
3223 it->current.dpvec_index = 0;
3224 it->method = next_element_from_display_vector;
3229 /***********************************************************************
3230 'display' property
3231 ***********************************************************************/
3233 /* Set up iterator IT from `display' property at its current position.
3234 Called from handle_stop. */
3236 static enum prop_handled
3237 handle_display_prop (it)
3238 struct it *it;
3240 Lisp_Object prop, object;
3241 struct text_pos *position;
3242 int display_replaced_p = 0;
3244 if (STRINGP (it->string))
3246 object = it->string;
3247 position = &it->current.string_pos;
3249 else
3251 object = it->w->buffer;
3252 position = &it->current.pos;
3255 /* Reset those iterator values set from display property values. */
3256 it->font_height = Qnil;
3257 it->space_width = Qnil;
3258 it->voffset = 0;
3260 /* We don't support recursive `display' properties, i.e. string
3261 values that have a string `display' property, that have a string
3262 `display' property etc. */
3263 if (!it->string_from_display_prop_p)
3264 it->area = TEXT_AREA;
3266 prop = Fget_char_property (make_number (position->charpos),
3267 Qdisplay, object);
3268 if (NILP (prop))
3269 return HANDLED_NORMALLY;
3271 if (CONSP (prop)
3272 /* Simple properties. */
3273 && !EQ (XCAR (prop), Qimage)
3274 && !EQ (XCAR (prop), Qspace)
3275 && !EQ (XCAR (prop), Qwhen)
3276 && !EQ (XCAR (prop), Qspace_width)
3277 && !EQ (XCAR (prop), Qheight)
3278 && !EQ (XCAR (prop), Qraise)
3279 /* Marginal area specifications. */
3280 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
3281 && !EQ (XCAR (prop), Qleft_fringe)
3282 && !EQ (XCAR (prop), Qright_fringe)
3283 && !NILP (XCAR (prop)))
3285 for (; CONSP (prop); prop = XCDR (prop))
3287 if (handle_single_display_prop (it, XCAR (prop), object,
3288 position, display_replaced_p))
3289 display_replaced_p = 1;
3292 else if (VECTORP (prop))
3294 int i;
3295 for (i = 0; i < ASIZE (prop); ++i)
3296 if (handle_single_display_prop (it, AREF (prop, i), object,
3297 position, display_replaced_p))
3298 display_replaced_p = 1;
3300 else
3302 if (handle_single_display_prop (it, prop, object, position, 0))
3303 display_replaced_p = 1;
3306 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
3310 /* Value is the position of the end of the `display' property starting
3311 at START_POS in OBJECT. */
3313 static struct text_pos
3314 display_prop_end (it, object, start_pos)
3315 struct it *it;
3316 Lisp_Object object;
3317 struct text_pos start_pos;
3319 Lisp_Object end;
3320 struct text_pos end_pos;
3322 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
3323 Qdisplay, object, Qnil);
3324 CHARPOS (end_pos) = XFASTINT (end);
3325 if (STRINGP (object))
3326 compute_string_pos (&end_pos, start_pos, it->string);
3327 else
3328 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
3330 return end_pos;
3334 /* Set up IT from a single `display' sub-property value PROP. OBJECT
3335 is the object in which the `display' property was found. *POSITION
3336 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3337 means that we previously saw a display sub-property which already
3338 replaced text display with something else, for example an image;
3339 ignore such properties after the first one has been processed.
3341 If PROP is a `space' or `image' sub-property, set *POSITION to the
3342 end position of the `display' property.
3344 Value is non-zero if something was found which replaces the display
3345 of buffer or string text. */
3347 static int
3348 handle_single_display_prop (it, prop, object, position,
3349 display_replaced_before_p)
3350 struct it *it;
3351 Lisp_Object prop;
3352 Lisp_Object object;
3353 struct text_pos *position;
3354 int display_replaced_before_p;
3356 Lisp_Object value;
3357 int replaces_text_display_p = 0;
3358 Lisp_Object form;
3360 /* If PROP is a list of the form `(when FORM . VALUE)', FORM is
3361 evaluated. If the result is nil, VALUE is ignored. */
3362 form = Qt;
3363 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3365 prop = XCDR (prop);
3366 if (!CONSP (prop))
3367 return 0;
3368 form = XCAR (prop);
3369 prop = XCDR (prop);
3372 if (!NILP (form) && !EQ (form, Qt))
3374 int count = SPECPDL_INDEX ();
3375 struct gcpro gcpro1;
3377 /* Bind `object' to the object having the `display' property, a
3378 buffer or string. Bind `position' to the position in the
3379 object where the property was found, and `buffer-position'
3380 to the current position in the buffer. */
3381 specbind (Qobject, object);
3382 specbind (Qposition, make_number (CHARPOS (*position)));
3383 specbind (Qbuffer_position,
3384 make_number (STRINGP (object)
3385 ? IT_CHARPOS (*it) : CHARPOS (*position)));
3386 GCPRO1 (form);
3387 form = safe_eval (form);
3388 UNGCPRO;
3389 unbind_to (count, Qnil);
3392 if (NILP (form))
3393 return 0;
3395 if (CONSP (prop)
3396 && EQ (XCAR (prop), Qheight)
3397 && CONSP (XCDR (prop)))
3399 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3400 return 0;
3402 /* `(height HEIGHT)'. */
3403 it->font_height = XCAR (XCDR (prop));
3404 if (!NILP (it->font_height))
3406 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3407 int new_height = -1;
3409 if (CONSP (it->font_height)
3410 && (EQ (XCAR (it->font_height), Qplus)
3411 || EQ (XCAR (it->font_height), Qminus))
3412 && CONSP (XCDR (it->font_height))
3413 && INTEGERP (XCAR (XCDR (it->font_height))))
3415 /* `(+ N)' or `(- N)' where N is an integer. */
3416 int steps = XINT (XCAR (XCDR (it->font_height)));
3417 if (EQ (XCAR (it->font_height), Qplus))
3418 steps = - steps;
3419 it->face_id = smaller_face (it->f, it->face_id, steps);
3421 else if (FUNCTIONP (it->font_height))
3423 /* Call function with current height as argument.
3424 Value is the new height. */
3425 Lisp_Object height;
3426 height = safe_call1 (it->font_height,
3427 face->lface[LFACE_HEIGHT_INDEX]);
3428 if (NUMBERP (height))
3429 new_height = XFLOATINT (height);
3431 else if (NUMBERP (it->font_height))
3433 /* Value is a multiple of the canonical char height. */
3434 struct face *face;
3436 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
3437 new_height = (XFLOATINT (it->font_height)
3438 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
3440 else
3442 /* Evaluate IT->font_height with `height' bound to the
3443 current specified height to get the new height. */
3444 Lisp_Object value;
3445 int count = SPECPDL_INDEX ();
3447 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
3448 value = safe_eval (it->font_height);
3449 unbind_to (count, Qnil);
3451 if (NUMBERP (value))
3452 new_height = XFLOATINT (value);
3455 if (new_height > 0)
3456 it->face_id = face_with_height (it->f, it->face_id, new_height);
3459 else if (CONSP (prop)
3460 && EQ (XCAR (prop), Qspace_width)
3461 && CONSP (XCDR (prop)))
3463 /* `(space_width WIDTH)'. */
3464 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3465 return 0;
3467 value = XCAR (XCDR (prop));
3468 if (NUMBERP (value) && XFLOATINT (value) > 0)
3469 it->space_width = value;
3471 else if (CONSP (prop)
3472 && EQ (XCAR (prop), Qraise)
3473 && CONSP (XCDR (prop)))
3475 /* `(raise FACTOR)'. */
3476 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3477 return 0;
3479 #ifdef HAVE_WINDOW_SYSTEM
3480 value = XCAR (XCDR (prop));
3481 if (NUMBERP (value))
3483 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3484 it->voffset = - (XFLOATINT (value)
3485 * (FONT_HEIGHT (face->font)));
3487 #endif /* HAVE_WINDOW_SYSTEM */
3489 else if (CONSP (prop)
3490 && (EQ (XCAR (prop), Qleft_fringe)
3491 || EQ (XCAR (prop), Qright_fringe))
3492 && CONSP (XCDR (prop)))
3494 unsigned face_id = DEFAULT_FACE_ID;
3496 /* `(left-fringe BITMAP FACE)'. */
3497 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3498 return 0;
3500 #ifdef HAVE_WINDOW_SYSTEM
3501 value = XCAR (XCDR (prop));
3502 if (!NUMBERP (value)
3503 || !valid_fringe_bitmap_id_p (XINT (value)))
3504 return 0;
3506 if (CONSP (XCDR (XCDR (prop))))
3508 Lisp_Object face_name = XCAR (XCDR (XCDR (prop)));
3509 face_id = lookup_named_face (it->f, face_name, 'A');
3510 if (face_id < 0)
3511 return 0;
3514 if (EQ (XCAR (prop), Qleft_fringe))
3516 it->left_user_fringe_bitmap = XINT (value);
3517 it->left_user_fringe_face_id = face_id;
3519 else
3521 it->right_user_fringe_bitmap = XINT (value);
3522 it->right_user_fringe_face_id = face_id;
3524 #endif /* HAVE_WINDOW_SYSTEM */
3526 else if (!it->string_from_display_prop_p)
3528 /* `((margin left-margin) VALUE)' or `((margin right-margin)
3529 VALUE) or `((margin nil) VALUE)' or VALUE. */
3530 Lisp_Object location, value;
3531 struct text_pos start_pos;
3532 int valid_p;
3534 /* Characters having this form of property are not displayed, so
3535 we have to find the end of the property. */
3536 start_pos = *position;
3537 *position = display_prop_end (it, object, start_pos);
3538 value = Qnil;
3540 /* Let's stop at the new position and assume that all
3541 text properties change there. */
3542 it->stop_charpos = position->charpos;
3544 location = Qunbound;
3545 if (CONSP (prop) && CONSP (XCAR (prop)))
3547 Lisp_Object tem;
3549 value = XCDR (prop);
3550 if (CONSP (value))
3551 value = XCAR (value);
3553 tem = XCAR (prop);
3554 if (EQ (XCAR (tem), Qmargin)
3555 && (tem = XCDR (tem),
3556 tem = CONSP (tem) ? XCAR (tem) : Qnil,
3557 (NILP (tem)
3558 || EQ (tem, Qleft_margin)
3559 || EQ (tem, Qright_margin))))
3560 location = tem;
3563 if (EQ (location, Qunbound))
3565 location = Qnil;
3566 value = prop;
3569 #ifdef HAVE_WINDOW_SYSTEM
3570 if (FRAME_TERMCAP_P (it->f))
3571 valid_p = STRINGP (value);
3572 else
3573 valid_p = (STRINGP (value)
3574 || (CONSP (value) && EQ (XCAR (value), Qspace))
3575 || valid_image_p (value));
3576 #else /* not HAVE_WINDOW_SYSTEM */
3577 valid_p = STRINGP (value);
3578 #endif /* not HAVE_WINDOW_SYSTEM */
3580 if ((EQ (location, Qleft_margin)
3581 || EQ (location, Qright_margin)
3582 || NILP (location))
3583 && valid_p
3584 && !display_replaced_before_p)
3586 replaces_text_display_p = 1;
3588 /* Save current settings of IT so that we can restore them
3589 when we are finished with the glyph property value. */
3590 push_it (it);
3592 if (NILP (location))
3593 it->area = TEXT_AREA;
3594 else if (EQ (location, Qleft_margin))
3595 it->area = LEFT_MARGIN_AREA;
3596 else
3597 it->area = RIGHT_MARGIN_AREA;
3599 if (STRINGP (value))
3601 it->string = value;
3602 it->multibyte_p = STRING_MULTIBYTE (it->string);
3603 it->current.overlay_string_index = -1;
3604 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
3605 it->end_charpos = it->string_nchars = SCHARS (it->string);
3606 it->method = next_element_from_string;
3607 it->stop_charpos = 0;
3608 it->string_from_display_prop_p = 1;
3609 /* Say that we haven't consumed the characters with
3610 `display' property yet. The call to pop_it in
3611 set_iterator_to_next will clean this up. */
3612 *position = start_pos;
3614 else if (CONSP (value) && EQ (XCAR (value), Qspace))
3616 it->method = next_element_from_stretch;
3617 it->object = value;
3618 it->current.pos = it->position = start_pos;
3620 #ifdef HAVE_WINDOW_SYSTEM
3621 else
3623 it->what = IT_IMAGE;
3624 it->image_id = lookup_image (it->f, value);
3625 it->position = start_pos;
3626 it->object = NILP (object) ? it->w->buffer : object;
3627 it->method = next_element_from_image;
3629 /* Say that we haven't consumed the characters with
3630 `display' property yet. The call to pop_it in
3631 set_iterator_to_next will clean this up. */
3632 *position = start_pos;
3634 #endif /* HAVE_WINDOW_SYSTEM */
3636 else
3637 /* Invalid property or property not supported. Restore
3638 the position to what it was before. */
3639 *position = start_pos;
3642 return replaces_text_display_p;
3646 /* Check if PROP is a display sub-property value whose text should be
3647 treated as intangible. */
3649 static int
3650 single_display_prop_intangible_p (prop)
3651 Lisp_Object prop;
3653 /* Skip over `when FORM'. */
3654 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3656 prop = XCDR (prop);
3657 if (!CONSP (prop))
3658 return 0;
3659 prop = XCDR (prop);
3662 if (STRINGP (prop))
3663 return 1;
3665 if (!CONSP (prop))
3666 return 0;
3668 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
3669 we don't need to treat text as intangible. */
3670 if (EQ (XCAR (prop), Qmargin))
3672 prop = XCDR (prop);
3673 if (!CONSP (prop))
3674 return 0;
3676 prop = XCDR (prop);
3677 if (!CONSP (prop)
3678 || EQ (XCAR (prop), Qleft_margin)
3679 || EQ (XCAR (prop), Qright_margin))
3680 return 0;
3683 return (CONSP (prop)
3684 && (EQ (XCAR (prop), Qimage)
3685 || EQ (XCAR (prop), Qspace)));
3689 /* Check if PROP is a display property value whose text should be
3690 treated as intangible. */
3693 display_prop_intangible_p (prop)
3694 Lisp_Object prop;
3696 if (CONSP (prop)
3697 && CONSP (XCAR (prop))
3698 && !EQ (Qmargin, XCAR (XCAR (prop))))
3700 /* A list of sub-properties. */
3701 while (CONSP (prop))
3703 if (single_display_prop_intangible_p (XCAR (prop)))
3704 return 1;
3705 prop = XCDR (prop);
3708 else if (VECTORP (prop))
3710 /* A vector of sub-properties. */
3711 int i;
3712 for (i = 0; i < ASIZE (prop); ++i)
3713 if (single_display_prop_intangible_p (AREF (prop, i)))
3714 return 1;
3716 else
3717 return single_display_prop_intangible_p (prop);
3719 return 0;
3723 /* Return 1 if PROP is a display sub-property value containing STRING. */
3725 static int
3726 single_display_prop_string_p (prop, string)
3727 Lisp_Object prop, string;
3729 if (EQ (string, prop))
3730 return 1;
3732 /* Skip over `when FORM'. */
3733 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3735 prop = XCDR (prop);
3736 if (!CONSP (prop))
3737 return 0;
3738 prop = XCDR (prop);
3741 if (CONSP (prop))
3742 /* Skip over `margin LOCATION'. */
3743 if (EQ (XCAR (prop), Qmargin))
3745 prop = XCDR (prop);
3746 if (!CONSP (prop))
3747 return 0;
3749 prop = XCDR (prop);
3750 if (!CONSP (prop))
3751 return 0;
3754 return CONSP (prop) && EQ (XCAR (prop), string);
3758 /* Return 1 if STRING appears in the `display' property PROP. */
3760 static int
3761 display_prop_string_p (prop, string)
3762 Lisp_Object prop, string;
3764 if (CONSP (prop)
3765 && CONSP (XCAR (prop))
3766 && !EQ (Qmargin, XCAR (XCAR (prop))))
3768 /* A list of sub-properties. */
3769 while (CONSP (prop))
3771 if (single_display_prop_string_p (XCAR (prop), string))
3772 return 1;
3773 prop = XCDR (prop);
3776 else if (VECTORP (prop))
3778 /* A vector of sub-properties. */
3779 int i;
3780 for (i = 0; i < ASIZE (prop); ++i)
3781 if (single_display_prop_string_p (AREF (prop, i), string))
3782 return 1;
3784 else
3785 return single_display_prop_string_p (prop, string);
3787 return 0;
3791 /* Determine from which buffer position in W's buffer STRING comes
3792 from. AROUND_CHARPOS is an approximate position where it could
3793 be from. Value is the buffer position or 0 if it couldn't be
3794 determined.
3796 W's buffer must be current.
3798 This function is necessary because we don't record buffer positions
3799 in glyphs generated from strings (to keep struct glyph small).
3800 This function may only use code that doesn't eval because it is
3801 called asynchronously from note_mouse_highlight. */
3804 string_buffer_position (w, string, around_charpos)
3805 struct window *w;
3806 Lisp_Object string;
3807 int around_charpos;
3809 Lisp_Object limit, prop, pos;
3810 const int MAX_DISTANCE = 1000;
3811 int found = 0;
3813 pos = make_number (around_charpos);
3814 limit = make_number (min (XINT (pos) + MAX_DISTANCE, ZV));
3815 while (!found && !EQ (pos, limit))
3817 prop = Fget_char_property (pos, Qdisplay, Qnil);
3818 if (!NILP (prop) && display_prop_string_p (prop, string))
3819 found = 1;
3820 else
3821 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil, limit);
3824 if (!found)
3826 pos = make_number (around_charpos);
3827 limit = make_number (max (XINT (pos) - MAX_DISTANCE, BEGV));
3828 while (!found && !EQ (pos, limit))
3830 prop = Fget_char_property (pos, Qdisplay, Qnil);
3831 if (!NILP (prop) && display_prop_string_p (prop, string))
3832 found = 1;
3833 else
3834 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
3835 limit);
3839 return found ? XINT (pos) : 0;
3844 /***********************************************************************
3845 `composition' property
3846 ***********************************************************************/
3848 /* Set up iterator IT from `composition' property at its current
3849 position. Called from handle_stop. */
3851 static enum prop_handled
3852 handle_composition_prop (it)
3853 struct it *it;
3855 Lisp_Object prop, string;
3856 int pos, pos_byte, end;
3857 enum prop_handled handled = HANDLED_NORMALLY;
3859 if (STRINGP (it->string))
3861 pos = IT_STRING_CHARPOS (*it);
3862 pos_byte = IT_STRING_BYTEPOS (*it);
3863 string = it->string;
3865 else
3867 pos = IT_CHARPOS (*it);
3868 pos_byte = IT_BYTEPOS (*it);
3869 string = Qnil;
3872 /* If there's a valid composition and point is not inside of the
3873 composition (in the case that the composition is from the current
3874 buffer), draw a glyph composed from the composition components. */
3875 if (find_composition (pos, -1, &pos, &end, &prop, string)
3876 && COMPOSITION_VALID_P (pos, end, prop)
3877 && (STRINGP (it->string) || (PT <= pos || PT >= end)))
3879 int id = get_composition_id (pos, pos_byte, end - pos, prop, string);
3881 if (id >= 0)
3883 it->method = next_element_from_composition;
3884 it->cmp_id = id;
3885 it->cmp_len = COMPOSITION_LENGTH (prop);
3886 /* For a terminal, draw only the first character of the
3887 components. */
3888 it->c = COMPOSITION_GLYPH (composition_table[id], 0);
3889 it->len = (STRINGP (it->string)
3890 ? string_char_to_byte (it->string, end)
3891 : CHAR_TO_BYTE (end)) - pos_byte;
3892 it->stop_charpos = end;
3893 handled = HANDLED_RETURN;
3897 return handled;
3902 /***********************************************************************
3903 Overlay strings
3904 ***********************************************************************/
3906 /* The following structure is used to record overlay strings for
3907 later sorting in load_overlay_strings. */
3909 struct overlay_entry
3911 Lisp_Object overlay;
3912 Lisp_Object string;
3913 int priority;
3914 int after_string_p;
3918 /* Set up iterator IT from overlay strings at its current position.
3919 Called from handle_stop. */
3921 static enum prop_handled
3922 handle_overlay_change (it)
3923 struct it *it;
3925 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
3926 return HANDLED_RECOMPUTE_PROPS;
3927 else
3928 return HANDLED_NORMALLY;
3932 /* Set up the next overlay string for delivery by IT, if there is an
3933 overlay string to deliver. Called by set_iterator_to_next when the
3934 end of the current overlay string is reached. If there are more
3935 overlay strings to display, IT->string and
3936 IT->current.overlay_string_index are set appropriately here.
3937 Otherwise IT->string is set to nil. */
3939 static void
3940 next_overlay_string (it)
3941 struct it *it;
3943 ++it->current.overlay_string_index;
3944 if (it->current.overlay_string_index == it->n_overlay_strings)
3946 /* No more overlay strings. Restore IT's settings to what
3947 they were before overlay strings were processed, and
3948 continue to deliver from current_buffer. */
3949 int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
3951 pop_it (it);
3952 xassert (it->stop_charpos >= BEGV
3953 && it->stop_charpos <= it->end_charpos);
3954 it->string = Qnil;
3955 it->current.overlay_string_index = -1;
3956 SET_TEXT_POS (it->current.string_pos, -1, -1);
3957 it->n_overlay_strings = 0;
3958 it->method = next_element_from_buffer;
3960 /* If we're at the end of the buffer, record that we have
3961 processed the overlay strings there already, so that
3962 next_element_from_buffer doesn't try it again. */
3963 if (IT_CHARPOS (*it) >= it->end_charpos)
3964 it->overlay_strings_at_end_processed_p = 1;
3966 /* If we have to display `...' for invisible text, set
3967 the iterator up for that. */
3968 if (display_ellipsis_p)
3969 setup_for_ellipsis (it);
3971 else
3973 /* There are more overlay strings to process. If
3974 IT->current.overlay_string_index has advanced to a position
3975 where we must load IT->overlay_strings with more strings, do
3976 it. */
3977 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
3979 if (it->current.overlay_string_index && i == 0)
3980 load_overlay_strings (it, 0);
3982 /* Initialize IT to deliver display elements from the overlay
3983 string. */
3984 it->string = it->overlay_strings[i];
3985 it->multibyte_p = STRING_MULTIBYTE (it->string);
3986 SET_TEXT_POS (it->current.string_pos, 0, 0);
3987 it->method = next_element_from_string;
3988 it->stop_charpos = 0;
3991 CHECK_IT (it);
3995 /* Compare two overlay_entry structures E1 and E2. Used as a
3996 comparison function for qsort in load_overlay_strings. Overlay
3997 strings for the same position are sorted so that
3999 1. All after-strings come in front of before-strings, except
4000 when they come from the same overlay.
4002 2. Within after-strings, strings are sorted so that overlay strings
4003 from overlays with higher priorities come first.
4005 2. Within before-strings, strings are sorted so that overlay
4006 strings from overlays with higher priorities come last.
4008 Value is analogous to strcmp. */
4011 static int
4012 compare_overlay_entries (e1, e2)
4013 void *e1, *e2;
4015 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4016 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4017 int result;
4019 if (entry1->after_string_p != entry2->after_string_p)
4021 /* Let after-strings appear in front of before-strings if
4022 they come from different overlays. */
4023 if (EQ (entry1->overlay, entry2->overlay))
4024 result = entry1->after_string_p ? 1 : -1;
4025 else
4026 result = entry1->after_string_p ? -1 : 1;
4028 else if (entry1->after_string_p)
4029 /* After-strings sorted in order of decreasing priority. */
4030 result = entry2->priority - entry1->priority;
4031 else
4032 /* Before-strings sorted in order of increasing priority. */
4033 result = entry1->priority - entry2->priority;
4035 return result;
4039 /* Load the vector IT->overlay_strings with overlay strings from IT's
4040 current buffer position, or from CHARPOS if that is > 0. Set
4041 IT->n_overlays to the total number of overlay strings found.
4043 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4044 a time. On entry into load_overlay_strings,
4045 IT->current.overlay_string_index gives the number of overlay
4046 strings that have already been loaded by previous calls to this
4047 function.
4049 IT->add_overlay_start contains an additional overlay start
4050 position to consider for taking overlay strings from, if non-zero.
4051 This position comes into play when the overlay has an `invisible'
4052 property, and both before and after-strings. When we've skipped to
4053 the end of the overlay, because of its `invisible' property, we
4054 nevertheless want its before-string to appear.
4055 IT->add_overlay_start will contain the overlay start position
4056 in this case.
4058 Overlay strings are sorted so that after-string strings come in
4059 front of before-string strings. Within before and after-strings,
4060 strings are sorted by overlay priority. See also function
4061 compare_overlay_entries. */
4063 static void
4064 load_overlay_strings (it, charpos)
4065 struct it *it;
4066 int charpos;
4068 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
4069 Lisp_Object overlay, window, str, invisible;
4070 struct Lisp_Overlay *ov;
4071 int start, end;
4072 int size = 20;
4073 int n = 0, i, j, invis_p;
4074 struct overlay_entry *entries
4075 = (struct overlay_entry *) alloca (size * sizeof *entries);
4077 if (charpos <= 0)
4078 charpos = IT_CHARPOS (*it);
4080 /* Append the overlay string STRING of overlay OVERLAY to vector
4081 `entries' which has size `size' and currently contains `n'
4082 elements. AFTER_P non-zero means STRING is an after-string of
4083 OVERLAY. */
4084 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4085 do \
4087 Lisp_Object priority; \
4089 if (n == size) \
4091 int new_size = 2 * size; \
4092 struct overlay_entry *old = entries; \
4093 entries = \
4094 (struct overlay_entry *) alloca (new_size \
4095 * sizeof *entries); \
4096 bcopy (old, entries, size * sizeof *entries); \
4097 size = new_size; \
4100 entries[n].string = (STRING); \
4101 entries[n].overlay = (OVERLAY); \
4102 priority = Foverlay_get ((OVERLAY), Qpriority); \
4103 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4104 entries[n].after_string_p = (AFTER_P); \
4105 ++n; \
4107 while (0)
4109 /* Process overlay before the overlay center. */
4110 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4112 XSETMISC (overlay, ov);
4113 xassert (OVERLAYP (overlay));
4114 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4115 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4117 if (end < charpos)
4118 break;
4120 /* Skip this overlay if it doesn't start or end at IT's current
4121 position. */
4122 if (end != charpos && start != charpos)
4123 continue;
4125 /* Skip this overlay if it doesn't apply to IT->w. */
4126 window = Foverlay_get (overlay, Qwindow);
4127 if (WINDOWP (window) && XWINDOW (window) != it->w)
4128 continue;
4130 /* If the text ``under'' the overlay is invisible, both before-
4131 and after-strings from this overlay are visible; start and
4132 end position are indistinguishable. */
4133 invisible = Foverlay_get (overlay, Qinvisible);
4134 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4136 /* If overlay has a non-empty before-string, record it. */
4137 if ((start == charpos || (end == charpos && invis_p))
4138 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4139 && SCHARS (str))
4140 RECORD_OVERLAY_STRING (overlay, str, 0);
4142 /* If overlay has a non-empty after-string, record it. */
4143 if ((end == charpos || (start == charpos && invis_p))
4144 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4145 && SCHARS (str))
4146 RECORD_OVERLAY_STRING (overlay, str, 1);
4149 /* Process overlays after the overlay center. */
4150 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
4152 XSETMISC (overlay, ov);
4153 xassert (OVERLAYP (overlay));
4154 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4155 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4157 if (start > charpos)
4158 break;
4160 /* Skip this overlay if it doesn't start or end at IT's current
4161 position. */
4162 if (end != charpos && start != charpos)
4163 continue;
4165 /* Skip this overlay if it doesn't apply to IT->w. */
4166 window = Foverlay_get (overlay, Qwindow);
4167 if (WINDOWP (window) && XWINDOW (window) != it->w)
4168 continue;
4170 /* If the text ``under'' the overlay is invisible, it has a zero
4171 dimension, and both before- and after-strings apply. */
4172 invisible = Foverlay_get (overlay, Qinvisible);
4173 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4175 /* If overlay has a non-empty before-string, record it. */
4176 if ((start == charpos || (end == charpos && invis_p))
4177 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4178 && SCHARS (str))
4179 RECORD_OVERLAY_STRING (overlay, str, 0);
4181 /* If overlay has a non-empty after-string, record it. */
4182 if ((end == charpos || (start == charpos && invis_p))
4183 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4184 && SCHARS (str))
4185 RECORD_OVERLAY_STRING (overlay, str, 1);
4188 #undef RECORD_OVERLAY_STRING
4190 /* Sort entries. */
4191 if (n > 1)
4192 qsort (entries, n, sizeof *entries, compare_overlay_entries);
4194 /* Record the total number of strings to process. */
4195 it->n_overlay_strings = n;
4197 /* IT->current.overlay_string_index is the number of overlay strings
4198 that have already been consumed by IT. Copy some of the
4199 remaining overlay strings to IT->overlay_strings. */
4200 i = 0;
4201 j = it->current.overlay_string_index;
4202 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
4203 it->overlay_strings[i++] = entries[j++].string;
4205 CHECK_IT (it);
4209 /* Get the first chunk of overlay strings at IT's current buffer
4210 position, or at CHARPOS if that is > 0. Value is non-zero if at
4211 least one overlay string was found. */
4213 static int
4214 get_overlay_strings (it, charpos)
4215 struct it *it;
4216 int charpos;
4218 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4219 process. This fills IT->overlay_strings with strings, and sets
4220 IT->n_overlay_strings to the total number of strings to process.
4221 IT->pos.overlay_string_index has to be set temporarily to zero
4222 because load_overlay_strings needs this; it must be set to -1
4223 when no overlay strings are found because a zero value would
4224 indicate a position in the first overlay string. */
4225 it->current.overlay_string_index = 0;
4226 load_overlay_strings (it, charpos);
4228 /* If we found overlay strings, set up IT to deliver display
4229 elements from the first one. Otherwise set up IT to deliver
4230 from current_buffer. */
4231 if (it->n_overlay_strings)
4233 /* Make sure we know settings in current_buffer, so that we can
4234 restore meaningful values when we're done with the overlay
4235 strings. */
4236 compute_stop_pos (it);
4237 xassert (it->face_id >= 0);
4239 /* Save IT's settings. They are restored after all overlay
4240 strings have been processed. */
4241 xassert (it->sp == 0);
4242 push_it (it);
4244 /* Set up IT to deliver display elements from the first overlay
4245 string. */
4246 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4247 it->string = it->overlay_strings[0];
4248 it->stop_charpos = 0;
4249 xassert (STRINGP (it->string));
4250 it->end_charpos = SCHARS (it->string);
4251 it->multibyte_p = STRING_MULTIBYTE (it->string);
4252 it->method = next_element_from_string;
4254 else
4256 it->string = Qnil;
4257 it->current.overlay_string_index = -1;
4258 it->method = next_element_from_buffer;
4261 CHECK_IT (it);
4263 /* Value is non-zero if we found at least one overlay string. */
4264 return STRINGP (it->string);
4269 /***********************************************************************
4270 Saving and restoring state
4271 ***********************************************************************/
4273 /* Save current settings of IT on IT->stack. Called, for example,
4274 before setting up IT for an overlay string, to be able to restore
4275 IT's settings to what they were after the overlay string has been
4276 processed. */
4278 static void
4279 push_it (it)
4280 struct it *it;
4282 struct iterator_stack_entry *p;
4284 xassert (it->sp < 2);
4285 p = it->stack + it->sp;
4287 p->stop_charpos = it->stop_charpos;
4288 xassert (it->face_id >= 0);
4289 p->face_id = it->face_id;
4290 p->string = it->string;
4291 p->pos = it->current;
4292 p->end_charpos = it->end_charpos;
4293 p->string_nchars = it->string_nchars;
4294 p->area = it->area;
4295 p->multibyte_p = it->multibyte_p;
4296 p->space_width = it->space_width;
4297 p->font_height = it->font_height;
4298 p->voffset = it->voffset;
4299 p->string_from_display_prop_p = it->string_from_display_prop_p;
4300 p->display_ellipsis_p = 0;
4301 ++it->sp;
4305 /* Restore IT's settings from IT->stack. Called, for example, when no
4306 more overlay strings must be processed, and we return to delivering
4307 display elements from a buffer, or when the end of a string from a
4308 `display' property is reached and we return to delivering display
4309 elements from an overlay string, or from a buffer. */
4311 static void
4312 pop_it (it)
4313 struct it *it;
4315 struct iterator_stack_entry *p;
4317 xassert (it->sp > 0);
4318 --it->sp;
4319 p = it->stack + it->sp;
4320 it->stop_charpos = p->stop_charpos;
4321 it->face_id = p->face_id;
4322 it->string = p->string;
4323 it->current = p->pos;
4324 it->end_charpos = p->end_charpos;
4325 it->string_nchars = p->string_nchars;
4326 it->area = p->area;
4327 it->multibyte_p = p->multibyte_p;
4328 it->space_width = p->space_width;
4329 it->font_height = p->font_height;
4330 it->voffset = p->voffset;
4331 it->string_from_display_prop_p = p->string_from_display_prop_p;
4336 /***********************************************************************
4337 Moving over lines
4338 ***********************************************************************/
4340 /* Set IT's current position to the previous line start. */
4342 static void
4343 back_to_previous_line_start (it)
4344 struct it *it;
4346 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
4347 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
4351 /* Move IT to the next line start.
4353 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
4354 we skipped over part of the text (as opposed to moving the iterator
4355 continuously over the text). Otherwise, don't change the value
4356 of *SKIPPED_P.
4358 Newlines may come from buffer text, overlay strings, or strings
4359 displayed via the `display' property. That's the reason we can't
4360 simply use find_next_newline_no_quit.
4362 Note that this function may not skip over invisible text that is so
4363 because of text properties and immediately follows a newline. If
4364 it would, function reseat_at_next_visible_line_start, when called
4365 from set_iterator_to_next, would effectively make invisible
4366 characters following a newline part of the wrong glyph row, which
4367 leads to wrong cursor motion. */
4369 static int
4370 forward_to_next_line_start (it, skipped_p)
4371 struct it *it;
4372 int *skipped_p;
4374 int old_selective, newline_found_p, n;
4375 const int MAX_NEWLINE_DISTANCE = 500;
4377 /* If already on a newline, just consume it to avoid unintended
4378 skipping over invisible text below. */
4379 if (it->what == IT_CHARACTER
4380 && it->c == '\n'
4381 && CHARPOS (it->position) == IT_CHARPOS (*it))
4383 set_iterator_to_next (it, 0);
4384 it->c = 0;
4385 return 1;
4388 /* Don't handle selective display in the following. It's (a)
4389 unnecessary because it's done by the caller, and (b) leads to an
4390 infinite recursion because next_element_from_ellipsis indirectly
4391 calls this function. */
4392 old_selective = it->selective;
4393 it->selective = 0;
4395 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
4396 from buffer text. */
4397 for (n = newline_found_p = 0;
4398 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
4399 n += STRINGP (it->string) ? 0 : 1)
4401 if (!get_next_display_element (it))
4402 return 0;
4403 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
4404 set_iterator_to_next (it, 0);
4407 /* If we didn't find a newline near enough, see if we can use a
4408 short-cut. */
4409 if (!newline_found_p)
4411 int start = IT_CHARPOS (*it);
4412 int limit = find_next_newline_no_quit (start, 1);
4413 Lisp_Object pos;
4415 xassert (!STRINGP (it->string));
4417 /* If there isn't any `display' property in sight, and no
4418 overlays, we can just use the position of the newline in
4419 buffer text. */
4420 if (it->stop_charpos >= limit
4421 || ((pos = Fnext_single_property_change (make_number (start),
4422 Qdisplay,
4423 Qnil, make_number (limit)),
4424 NILP (pos))
4425 && next_overlay_change (start) == ZV))
4427 IT_CHARPOS (*it) = limit;
4428 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
4429 *skipped_p = newline_found_p = 1;
4431 else
4433 while (get_next_display_element (it)
4434 && !newline_found_p)
4436 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
4437 set_iterator_to_next (it, 0);
4442 it->selective = old_selective;
4443 return newline_found_p;
4447 /* Set IT's current position to the previous visible line start. Skip
4448 invisible text that is so either due to text properties or due to
4449 selective display. Caution: this does not change IT->current_x and
4450 IT->hpos. */
4452 static void
4453 back_to_previous_visible_line_start (it)
4454 struct it *it;
4456 int visible_p = 0;
4458 /* Go back one newline if not on BEGV already. */
4459 if (IT_CHARPOS (*it) > BEGV)
4460 back_to_previous_line_start (it);
4462 /* Move over lines that are invisible because of selective display
4463 or text properties. */
4464 while (IT_CHARPOS (*it) > BEGV
4465 && !visible_p)
4467 visible_p = 1;
4469 /* If selective > 0, then lines indented more than that values
4470 are invisible. */
4471 if (it->selective > 0
4472 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4473 (double) it->selective)) /* iftc */
4474 visible_p = 0;
4475 else
4477 Lisp_Object prop;
4479 prop = Fget_char_property (make_number (IT_CHARPOS (*it)),
4480 Qinvisible, it->window);
4481 if (TEXT_PROP_MEANS_INVISIBLE (prop))
4482 visible_p = 0;
4485 /* Back one more newline if the current one is invisible. */
4486 if (!visible_p)
4487 back_to_previous_line_start (it);
4490 xassert (IT_CHARPOS (*it) >= BEGV);
4491 xassert (IT_CHARPOS (*it) == BEGV
4492 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4493 CHECK_IT (it);
4497 /* Reseat iterator IT at the previous visible line start. Skip
4498 invisible text that is so either due to text properties or due to
4499 selective display. At the end, update IT's overlay information,
4500 face information etc. */
4502 static void
4503 reseat_at_previous_visible_line_start (it)
4504 struct it *it;
4506 back_to_previous_visible_line_start (it);
4507 reseat (it, it->current.pos, 1);
4508 CHECK_IT (it);
4512 /* Reseat iterator IT on the next visible line start in the current
4513 buffer. ON_NEWLINE_P non-zero means position IT on the newline
4514 preceding the line start. Skip over invisible text that is so
4515 because of selective display. Compute faces, overlays etc at the
4516 new position. Note that this function does not skip over text that
4517 is invisible because of text properties. */
4519 static void
4520 reseat_at_next_visible_line_start (it, on_newline_p)
4521 struct it *it;
4522 int on_newline_p;
4524 int newline_found_p, skipped_p = 0;
4526 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4528 /* Skip over lines that are invisible because they are indented
4529 more than the value of IT->selective. */
4530 if (it->selective > 0)
4531 while (IT_CHARPOS (*it) < ZV
4532 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4533 (double) it->selective)) /* iftc */
4535 xassert (FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4536 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4539 /* Position on the newline if that's what's requested. */
4540 if (on_newline_p && newline_found_p)
4542 if (STRINGP (it->string))
4544 if (IT_STRING_CHARPOS (*it) > 0)
4546 --IT_STRING_CHARPOS (*it);
4547 --IT_STRING_BYTEPOS (*it);
4550 else if (IT_CHARPOS (*it) > BEGV)
4552 --IT_CHARPOS (*it);
4553 --IT_BYTEPOS (*it);
4554 reseat (it, it->current.pos, 0);
4557 else if (skipped_p)
4558 reseat (it, it->current.pos, 0);
4560 CHECK_IT (it);
4565 /***********************************************************************
4566 Changing an iterator's position
4567 ***********************************************************************/
4569 /* Change IT's current position to POS in current_buffer. If FORCE_P
4570 is non-zero, always check for text properties at the new position.
4571 Otherwise, text properties are only looked up if POS >=
4572 IT->check_charpos of a property. */
4574 static void
4575 reseat (it, pos, force_p)
4576 struct it *it;
4577 struct text_pos pos;
4578 int force_p;
4580 int original_pos = IT_CHARPOS (*it);
4582 reseat_1 (it, pos, 0);
4584 /* Determine where to check text properties. Avoid doing it
4585 where possible because text property lookup is very expensive. */
4586 if (force_p
4587 || CHARPOS (pos) > it->stop_charpos
4588 || CHARPOS (pos) < original_pos)
4589 handle_stop (it);
4591 CHECK_IT (it);
4595 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
4596 IT->stop_pos to POS, also. */
4598 static void
4599 reseat_1 (it, pos, set_stop_p)
4600 struct it *it;
4601 struct text_pos pos;
4602 int set_stop_p;
4604 /* Don't call this function when scanning a C string. */
4605 xassert (it->s == NULL);
4607 /* POS must be a reasonable value. */
4608 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
4610 it->current.pos = it->position = pos;
4611 XSETBUFFER (it->object, current_buffer);
4612 it->end_charpos = ZV;
4613 it->dpvec = NULL;
4614 it->current.dpvec_index = -1;
4615 it->current.overlay_string_index = -1;
4616 IT_STRING_CHARPOS (*it) = -1;
4617 IT_STRING_BYTEPOS (*it) = -1;
4618 it->string = Qnil;
4619 it->method = next_element_from_buffer;
4620 /* RMS: I added this to fix a bug in move_it_vertically_backward
4621 where it->area continued to relate to the starting point
4622 for the backward motion. Bug report from
4623 Nick Roberts <nick@nick.uklinux.net> on 19 May 2003.
4624 However, I am not sure whether reseat still does the right thing
4625 in general after this change. */
4626 it->area = TEXT_AREA;
4627 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
4628 it->sp = 0;
4629 it->face_before_selective_p = 0;
4631 if (set_stop_p)
4632 it->stop_charpos = CHARPOS (pos);
4636 /* Set up IT for displaying a string, starting at CHARPOS in window W.
4637 If S is non-null, it is a C string to iterate over. Otherwise,
4638 STRING gives a Lisp string to iterate over.
4640 If PRECISION > 0, don't return more then PRECISION number of
4641 characters from the string.
4643 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
4644 characters have been returned. FIELD_WIDTH < 0 means an infinite
4645 field width.
4647 MULTIBYTE = 0 means disable processing of multibyte characters,
4648 MULTIBYTE > 0 means enable it,
4649 MULTIBYTE < 0 means use IT->multibyte_p.
4651 IT must be initialized via a prior call to init_iterator before
4652 calling this function. */
4654 static void
4655 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
4656 struct it *it;
4657 unsigned char *s;
4658 Lisp_Object string;
4659 int charpos;
4660 int precision, field_width, multibyte;
4662 /* No region in strings. */
4663 it->region_beg_charpos = it->region_end_charpos = -1;
4665 /* No text property checks performed by default, but see below. */
4666 it->stop_charpos = -1;
4668 /* Set iterator position and end position. */
4669 bzero (&it->current, sizeof it->current);
4670 it->current.overlay_string_index = -1;
4671 it->current.dpvec_index = -1;
4672 xassert (charpos >= 0);
4674 /* If STRING is specified, use its multibyteness, otherwise use the
4675 setting of MULTIBYTE, if specified. */
4676 if (multibyte >= 0)
4677 it->multibyte_p = multibyte > 0;
4679 if (s == NULL)
4681 xassert (STRINGP (string));
4682 it->string = string;
4683 it->s = NULL;
4684 it->end_charpos = it->string_nchars = SCHARS (string);
4685 it->method = next_element_from_string;
4686 it->current.string_pos = string_pos (charpos, string);
4688 else
4690 it->s = s;
4691 it->string = Qnil;
4693 /* Note that we use IT->current.pos, not it->current.string_pos,
4694 for displaying C strings. */
4695 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
4696 if (it->multibyte_p)
4698 it->current.pos = c_string_pos (charpos, s, 1);
4699 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
4701 else
4703 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
4704 it->end_charpos = it->string_nchars = strlen (s);
4707 it->method = next_element_from_c_string;
4710 /* PRECISION > 0 means don't return more than PRECISION characters
4711 from the string. */
4712 if (precision > 0 && it->end_charpos - charpos > precision)
4713 it->end_charpos = it->string_nchars = charpos + precision;
4715 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
4716 characters have been returned. FIELD_WIDTH == 0 means don't pad,
4717 FIELD_WIDTH < 0 means infinite field width. This is useful for
4718 padding with `-' at the end of a mode line. */
4719 if (field_width < 0)
4720 field_width = INFINITY;
4721 if (field_width > it->end_charpos - charpos)
4722 it->end_charpos = charpos + field_width;
4724 /* Use the standard display table for displaying strings. */
4725 if (DISP_TABLE_P (Vstandard_display_table))
4726 it->dp = XCHAR_TABLE (Vstandard_display_table);
4728 it->stop_charpos = charpos;
4729 CHECK_IT (it);
4734 /***********************************************************************
4735 Iteration
4736 ***********************************************************************/
4738 /* Load IT's display element fields with information about the next
4739 display element from the current position of IT. Value is zero if
4740 end of buffer (or C string) is reached. */
4743 get_next_display_element (it)
4744 struct it *it;
4746 /* Non-zero means that we found a display element. Zero means that
4747 we hit the end of what we iterate over. Performance note: the
4748 function pointer `method' used here turns out to be faster than
4749 using a sequence of if-statements. */
4750 int success_p = (*it->method) (it);
4752 if (it->what == IT_CHARACTER)
4754 /* Map via display table or translate control characters.
4755 IT->c, IT->len etc. have been set to the next character by
4756 the function call above. If we have a display table, and it
4757 contains an entry for IT->c, translate it. Don't do this if
4758 IT->c itself comes from a display table, otherwise we could
4759 end up in an infinite recursion. (An alternative could be to
4760 count the recursion depth of this function and signal an
4761 error when a certain maximum depth is reached.) Is it worth
4762 it? */
4763 if (success_p && it->dpvec == NULL)
4765 Lisp_Object dv;
4767 if (it->dp
4768 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
4769 VECTORP (dv)))
4771 struct Lisp_Vector *v = XVECTOR (dv);
4773 /* Return the first character from the display table
4774 entry, if not empty. If empty, don't display the
4775 current character. */
4776 if (v->size)
4778 it->dpvec_char_len = it->len;
4779 it->dpvec = v->contents;
4780 it->dpend = v->contents + v->size;
4781 it->current.dpvec_index = 0;
4782 it->method = next_element_from_display_vector;
4783 success_p = get_next_display_element (it);
4785 else
4787 set_iterator_to_next (it, 0);
4788 success_p = get_next_display_element (it);
4792 /* Translate control characters into `\003' or `^C' form.
4793 Control characters coming from a display table entry are
4794 currently not translated because we use IT->dpvec to hold
4795 the translation. This could easily be changed but I
4796 don't believe that it is worth doing.
4798 If it->multibyte_p is nonzero, eight-bit characters and
4799 non-printable multibyte characters are also translated to
4800 octal form.
4802 If it->multibyte_p is zero, eight-bit characters that
4803 don't have corresponding multibyte char code are also
4804 translated to octal form. */
4805 else if ((it->c < ' '
4806 && (it->area != TEXT_AREA
4807 || (it->c != '\n' && it->c != '\t')))
4808 || (it->multibyte_p
4809 ? ((it->c >= 127
4810 && it->len == 1)
4811 || !CHAR_PRINTABLE_P (it->c))
4812 : (it->c >= 127
4813 && it->c == unibyte_char_to_multibyte (it->c))))
4815 /* IT->c is a control character which must be displayed
4816 either as '\003' or as `^C' where the '\\' and '^'
4817 can be defined in the display table. Fill
4818 IT->ctl_chars with glyphs for what we have to
4819 display. Then, set IT->dpvec to these glyphs. */
4820 GLYPH g;
4822 if (it->c < 128 && it->ctl_arrow_p)
4824 /* Set IT->ctl_chars[0] to the glyph for `^'. */
4825 if (it->dp
4826 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
4827 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
4828 g = XINT (DISP_CTRL_GLYPH (it->dp));
4829 else
4830 g = FAST_MAKE_GLYPH ('^', 0);
4831 XSETINT (it->ctl_chars[0], g);
4833 g = FAST_MAKE_GLYPH (it->c ^ 0100, 0);
4834 XSETINT (it->ctl_chars[1], g);
4836 /* Set up IT->dpvec and return first character from it. */
4837 it->dpvec_char_len = it->len;
4838 it->dpvec = it->ctl_chars;
4839 it->dpend = it->dpvec + 2;
4840 it->current.dpvec_index = 0;
4841 it->method = next_element_from_display_vector;
4842 get_next_display_element (it);
4844 else
4846 unsigned char str[MAX_MULTIBYTE_LENGTH];
4847 int len;
4848 int i;
4849 GLYPH escape_glyph;
4851 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
4852 if (it->dp
4853 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
4854 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
4855 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
4856 else
4857 escape_glyph = FAST_MAKE_GLYPH ('\\', 0);
4859 if (SINGLE_BYTE_CHAR_P (it->c))
4860 str[0] = it->c, len = 1;
4861 else
4863 len = CHAR_STRING_NO_SIGNAL (it->c, str);
4864 if (len < 0)
4866 /* It's an invalid character, which
4867 shouldn't happen actually, but due to
4868 bugs it may happen. Let's print the char
4869 as is, there's not much meaningful we can
4870 do with it. */
4871 str[0] = it->c;
4872 str[1] = it->c >> 8;
4873 str[2] = it->c >> 16;
4874 str[3] = it->c >> 24;
4875 len = 4;
4879 for (i = 0; i < len; i++)
4881 XSETINT (it->ctl_chars[i * 4], escape_glyph);
4882 /* Insert three more glyphs into IT->ctl_chars for
4883 the octal display of the character. */
4884 g = FAST_MAKE_GLYPH (((str[i] >> 6) & 7) + '0', 0);
4885 XSETINT (it->ctl_chars[i * 4 + 1], g);
4886 g = FAST_MAKE_GLYPH (((str[i] >> 3) & 7) + '0', 0);
4887 XSETINT (it->ctl_chars[i * 4 + 2], g);
4888 g = FAST_MAKE_GLYPH ((str[i] & 7) + '0', 0);
4889 XSETINT (it->ctl_chars[i * 4 + 3], g);
4892 /* Set up IT->dpvec and return the first character
4893 from it. */
4894 it->dpvec_char_len = it->len;
4895 it->dpvec = it->ctl_chars;
4896 it->dpend = it->dpvec + len * 4;
4897 it->current.dpvec_index = 0;
4898 it->method = next_element_from_display_vector;
4899 get_next_display_element (it);
4904 /* Adjust face id for a multibyte character. There are no
4905 multibyte character in unibyte text. */
4906 if (it->multibyte_p
4907 && success_p
4908 && FRAME_WINDOW_P (it->f))
4910 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4911 it->face_id = FACE_FOR_CHAR (it->f, face, it->c);
4915 /* Is this character the last one of a run of characters with
4916 box? If yes, set IT->end_of_box_run_p to 1. */
4917 if (it->face_box_p
4918 && it->s == NULL)
4920 int face_id;
4921 struct face *face;
4923 it->end_of_box_run_p
4924 = ((face_id = face_after_it_pos (it),
4925 face_id != it->face_id)
4926 && (face = FACE_FROM_ID (it->f, face_id),
4927 face->box == FACE_NO_BOX));
4930 /* Value is 0 if end of buffer or string reached. */
4931 return success_p;
4935 /* Move IT to the next display element.
4937 RESEAT_P non-zero means if called on a newline in buffer text,
4938 skip to the next visible line start.
4940 Functions get_next_display_element and set_iterator_to_next are
4941 separate because I find this arrangement easier to handle than a
4942 get_next_display_element function that also increments IT's
4943 position. The way it is we can first look at an iterator's current
4944 display element, decide whether it fits on a line, and if it does,
4945 increment the iterator position. The other way around we probably
4946 would either need a flag indicating whether the iterator has to be
4947 incremented the next time, or we would have to implement a
4948 decrement position function which would not be easy to write. */
4950 void
4951 set_iterator_to_next (it, reseat_p)
4952 struct it *it;
4953 int reseat_p;
4955 /* Reset flags indicating start and end of a sequence of characters
4956 with box. Reset them at the start of this function because
4957 moving the iterator to a new position might set them. */
4958 it->start_of_box_run_p = it->end_of_box_run_p = 0;
4960 if (it->method == next_element_from_buffer)
4962 /* The current display element of IT is a character from
4963 current_buffer. Advance in the buffer, and maybe skip over
4964 invisible lines that are so because of selective display. */
4965 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
4966 reseat_at_next_visible_line_start (it, 0);
4967 else
4969 xassert (it->len != 0);
4970 IT_BYTEPOS (*it) += it->len;
4971 IT_CHARPOS (*it) += 1;
4972 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
4975 else if (it->method == next_element_from_composition)
4977 xassert (it->cmp_id >= 0 && it ->cmp_id < n_compositions);
4978 if (STRINGP (it->string))
4980 IT_STRING_BYTEPOS (*it) += it->len;
4981 IT_STRING_CHARPOS (*it) += it->cmp_len;
4982 it->method = next_element_from_string;
4983 goto consider_string_end;
4985 else
4987 IT_BYTEPOS (*it) += it->len;
4988 IT_CHARPOS (*it) += it->cmp_len;
4989 it->method = next_element_from_buffer;
4992 else if (it->method == next_element_from_c_string)
4994 /* Current display element of IT is from a C string. */
4995 IT_BYTEPOS (*it) += it->len;
4996 IT_CHARPOS (*it) += 1;
4998 else if (it->method == next_element_from_display_vector)
5000 /* Current display element of IT is from a display table entry.
5001 Advance in the display table definition. Reset it to null if
5002 end reached, and continue with characters from buffers/
5003 strings. */
5004 ++it->current.dpvec_index;
5006 /* Restore face of the iterator to what they were before the
5007 display vector entry (these entries may contain faces). */
5008 it->face_id = it->saved_face_id;
5010 if (it->dpvec + it->current.dpvec_index == it->dpend)
5012 if (it->s)
5013 it->method = next_element_from_c_string;
5014 else if (STRINGP (it->string))
5015 it->method = next_element_from_string;
5016 else
5017 it->method = next_element_from_buffer;
5019 it->dpvec = NULL;
5020 it->current.dpvec_index = -1;
5022 /* Skip over characters which were displayed via IT->dpvec. */
5023 if (it->dpvec_char_len < 0)
5024 reseat_at_next_visible_line_start (it, 1);
5025 else if (it->dpvec_char_len > 0)
5027 it->len = it->dpvec_char_len;
5028 set_iterator_to_next (it, reseat_p);
5032 else if (it->method == next_element_from_string)
5034 /* Current display element is a character from a Lisp string. */
5035 xassert (it->s == NULL && STRINGP (it->string));
5036 IT_STRING_BYTEPOS (*it) += it->len;
5037 IT_STRING_CHARPOS (*it) += 1;
5039 consider_string_end:
5041 if (it->current.overlay_string_index >= 0)
5043 /* IT->string is an overlay string. Advance to the
5044 next, if there is one. */
5045 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5046 next_overlay_string (it);
5048 else
5050 /* IT->string is not an overlay string. If we reached
5051 its end, and there is something on IT->stack, proceed
5052 with what is on the stack. This can be either another
5053 string, this time an overlay string, or a buffer. */
5054 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
5055 && it->sp > 0)
5057 pop_it (it);
5058 if (!STRINGP (it->string))
5059 it->method = next_element_from_buffer;
5060 else
5061 goto consider_string_end;
5065 else if (it->method == next_element_from_image
5066 || it->method == next_element_from_stretch)
5068 /* The position etc with which we have to proceed are on
5069 the stack. The position may be at the end of a string,
5070 if the `display' property takes up the whole string. */
5071 pop_it (it);
5072 it->image_id = 0;
5073 if (STRINGP (it->string))
5075 it->method = next_element_from_string;
5076 goto consider_string_end;
5078 else
5079 it->method = next_element_from_buffer;
5081 else
5082 /* There are no other methods defined, so this should be a bug. */
5083 abort ();
5085 xassert (it->method != next_element_from_string
5086 || (STRINGP (it->string)
5087 && IT_STRING_CHARPOS (*it) >= 0));
5091 /* Load IT's display element fields with information about the next
5092 display element which comes from a display table entry or from the
5093 result of translating a control character to one of the forms `^C'
5094 or `\003'. IT->dpvec holds the glyphs to return as characters. */
5096 static int
5097 next_element_from_display_vector (it)
5098 struct it *it;
5100 /* Precondition. */
5101 xassert (it->dpvec && it->current.dpvec_index >= 0);
5103 /* Remember the current face id in case glyphs specify faces.
5104 IT's face is restored in set_iterator_to_next. */
5105 it->saved_face_id = it->face_id;
5107 if (INTEGERP (*it->dpvec)
5108 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
5110 int lface_id;
5111 GLYPH g;
5113 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
5114 it->c = FAST_GLYPH_CHAR (g);
5115 it->len = CHAR_BYTES (it->c);
5117 /* The entry may contain a face id to use. Such a face id is
5118 the id of a Lisp face, not a realized face. A face id of
5119 zero means no face is specified. */
5120 lface_id = FAST_GLYPH_FACE (g);
5121 if (lface_id)
5123 /* The function returns -1 if lface_id is invalid. */
5124 int face_id = ascii_face_of_lisp_face (it->f, lface_id);
5125 if (face_id >= 0)
5126 it->face_id = face_id;
5129 else
5130 /* Display table entry is invalid. Return a space. */
5131 it->c = ' ', it->len = 1;
5133 /* Don't change position and object of the iterator here. They are
5134 still the values of the character that had this display table
5135 entry or was translated, and that's what we want. */
5136 it->what = IT_CHARACTER;
5137 return 1;
5141 /* Load IT with the next display element from Lisp string IT->string.
5142 IT->current.string_pos is the current position within the string.
5143 If IT->current.overlay_string_index >= 0, the Lisp string is an
5144 overlay string. */
5146 static int
5147 next_element_from_string (it)
5148 struct it *it;
5150 struct text_pos position;
5152 xassert (STRINGP (it->string));
5153 xassert (IT_STRING_CHARPOS (*it) >= 0);
5154 position = it->current.string_pos;
5156 /* Time to check for invisible text? */
5157 if (IT_STRING_CHARPOS (*it) < it->end_charpos
5158 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
5160 handle_stop (it);
5162 /* Since a handler may have changed IT->method, we must
5163 recurse here. */
5164 return get_next_display_element (it);
5167 if (it->current.overlay_string_index >= 0)
5169 /* Get the next character from an overlay string. In overlay
5170 strings, There is no field width or padding with spaces to
5171 do. */
5172 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5174 it->what = IT_EOB;
5175 return 0;
5177 else if (STRING_MULTIBYTE (it->string))
5179 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5180 const unsigned char *s = (SDATA (it->string)
5181 + IT_STRING_BYTEPOS (*it));
5182 it->c = string_char_and_length (s, remaining, &it->len);
5184 else
5186 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5187 it->len = 1;
5190 else
5192 /* Get the next character from a Lisp string that is not an
5193 overlay string. Such strings come from the mode line, for
5194 example. We may have to pad with spaces, or truncate the
5195 string. See also next_element_from_c_string. */
5196 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
5198 it->what = IT_EOB;
5199 return 0;
5201 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
5203 /* Pad with spaces. */
5204 it->c = ' ', it->len = 1;
5205 CHARPOS (position) = BYTEPOS (position) = -1;
5207 else if (STRING_MULTIBYTE (it->string))
5209 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5210 const unsigned char *s = (SDATA (it->string)
5211 + IT_STRING_BYTEPOS (*it));
5212 it->c = string_char_and_length (s, maxlen, &it->len);
5214 else
5216 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5217 it->len = 1;
5221 /* Record what we have and where it came from. Note that we store a
5222 buffer position in IT->position although it could arguably be a
5223 string position. */
5224 it->what = IT_CHARACTER;
5225 it->object = it->string;
5226 it->position = position;
5227 return 1;
5231 /* Load IT with next display element from C string IT->s.
5232 IT->string_nchars is the maximum number of characters to return
5233 from the string. IT->end_charpos may be greater than
5234 IT->string_nchars when this function is called, in which case we
5235 may have to return padding spaces. Value is zero if end of string
5236 reached, including padding spaces. */
5238 static int
5239 next_element_from_c_string (it)
5240 struct it *it;
5242 int success_p = 1;
5244 xassert (it->s);
5245 it->what = IT_CHARACTER;
5246 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
5247 it->object = Qnil;
5249 /* IT's position can be greater IT->string_nchars in case a field
5250 width or precision has been specified when the iterator was
5251 initialized. */
5252 if (IT_CHARPOS (*it) >= it->end_charpos)
5254 /* End of the game. */
5255 it->what = IT_EOB;
5256 success_p = 0;
5258 else if (IT_CHARPOS (*it) >= it->string_nchars)
5260 /* Pad with spaces. */
5261 it->c = ' ', it->len = 1;
5262 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
5264 else if (it->multibyte_p)
5266 /* Implementation note: The calls to strlen apparently aren't a
5267 performance problem because there is no noticeable performance
5268 difference between Emacs running in unibyte or multibyte mode. */
5269 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
5270 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
5271 maxlen, &it->len);
5273 else
5274 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
5276 return success_p;
5280 /* Set up IT to return characters from an ellipsis, if appropriate.
5281 The definition of the ellipsis glyphs may come from a display table
5282 entry. This function Fills IT with the first glyph from the
5283 ellipsis if an ellipsis is to be displayed. */
5285 static int
5286 next_element_from_ellipsis (it)
5287 struct it *it;
5289 if (it->selective_display_ellipsis_p)
5291 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
5293 /* Use the display table definition for `...'. Invalid glyphs
5294 will be handled by the method returning elements from dpvec. */
5295 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
5296 it->dpvec_char_len = it->len;
5297 it->dpvec = v->contents;
5298 it->dpend = v->contents + v->size;
5299 it->current.dpvec_index = 0;
5300 it->method = next_element_from_display_vector;
5302 else
5304 /* Use default `...' which is stored in default_invis_vector. */
5305 it->dpvec_char_len = it->len;
5306 it->dpvec = default_invis_vector;
5307 it->dpend = default_invis_vector + 3;
5308 it->current.dpvec_index = 0;
5309 it->method = next_element_from_display_vector;
5312 else
5314 /* The face at the current position may be different from the
5315 face we find after the invisible text. Remember what it
5316 was in IT->saved_face_id, and signal that it's there by
5317 setting face_before_selective_p. */
5318 it->saved_face_id = it->face_id;
5319 it->method = next_element_from_buffer;
5320 reseat_at_next_visible_line_start (it, 1);
5321 it->face_before_selective_p = 1;
5324 return get_next_display_element (it);
5328 /* Deliver an image display element. The iterator IT is already
5329 filled with image information (done in handle_display_prop). Value
5330 is always 1. */
5333 static int
5334 next_element_from_image (it)
5335 struct it *it;
5337 it->what = IT_IMAGE;
5338 return 1;
5342 /* Fill iterator IT with next display element from a stretch glyph
5343 property. IT->object is the value of the text property. Value is
5344 always 1. */
5346 static int
5347 next_element_from_stretch (it)
5348 struct it *it;
5350 it->what = IT_STRETCH;
5351 return 1;
5355 /* Load IT with the next display element from current_buffer. Value
5356 is zero if end of buffer reached. IT->stop_charpos is the next
5357 position at which to stop and check for text properties or buffer
5358 end. */
5360 static int
5361 next_element_from_buffer (it)
5362 struct it *it;
5364 int success_p = 1;
5366 /* Check this assumption, otherwise, we would never enter the
5367 if-statement, below. */
5368 xassert (IT_CHARPOS (*it) >= BEGV
5369 && IT_CHARPOS (*it) <= it->stop_charpos);
5371 if (IT_CHARPOS (*it) >= it->stop_charpos)
5373 if (IT_CHARPOS (*it) >= it->end_charpos)
5375 int overlay_strings_follow_p;
5377 /* End of the game, except when overlay strings follow that
5378 haven't been returned yet. */
5379 if (it->overlay_strings_at_end_processed_p)
5380 overlay_strings_follow_p = 0;
5381 else
5383 it->overlay_strings_at_end_processed_p = 1;
5384 overlay_strings_follow_p = get_overlay_strings (it, 0);
5387 if (overlay_strings_follow_p)
5388 success_p = get_next_display_element (it);
5389 else
5391 it->what = IT_EOB;
5392 it->position = it->current.pos;
5393 success_p = 0;
5396 else
5398 handle_stop (it);
5399 return get_next_display_element (it);
5402 else
5404 /* No face changes, overlays etc. in sight, so just return a
5405 character from current_buffer. */
5406 unsigned char *p;
5408 /* Maybe run the redisplay end trigger hook. Performance note:
5409 This doesn't seem to cost measurable time. */
5410 if (it->redisplay_end_trigger_charpos
5411 && it->glyph_row
5412 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
5413 run_redisplay_end_trigger_hook (it);
5415 /* Get the next character, maybe multibyte. */
5416 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
5417 if (it->multibyte_p && !ASCII_BYTE_P (*p))
5419 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
5420 - IT_BYTEPOS (*it));
5421 it->c = string_char_and_length (p, maxlen, &it->len);
5423 else
5424 it->c = *p, it->len = 1;
5426 /* Record what we have and where it came from. */
5427 it->what = IT_CHARACTER;;
5428 it->object = it->w->buffer;
5429 it->position = it->current.pos;
5431 /* Normally we return the character found above, except when we
5432 really want to return an ellipsis for selective display. */
5433 if (it->selective)
5435 if (it->c == '\n')
5437 /* A value of selective > 0 means hide lines indented more
5438 than that number of columns. */
5439 if (it->selective > 0
5440 && IT_CHARPOS (*it) + 1 < ZV
5441 && indented_beyond_p (IT_CHARPOS (*it) + 1,
5442 IT_BYTEPOS (*it) + 1,
5443 (double) it->selective)) /* iftc */
5445 success_p = next_element_from_ellipsis (it);
5446 it->dpvec_char_len = -1;
5449 else if (it->c == '\r' && it->selective == -1)
5451 /* A value of selective == -1 means that everything from the
5452 CR to the end of the line is invisible, with maybe an
5453 ellipsis displayed for it. */
5454 success_p = next_element_from_ellipsis (it);
5455 it->dpvec_char_len = -1;
5460 /* Value is zero if end of buffer reached. */
5461 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
5462 return success_p;
5466 /* Run the redisplay end trigger hook for IT. */
5468 static void
5469 run_redisplay_end_trigger_hook (it)
5470 struct it *it;
5472 Lisp_Object args[3];
5474 /* IT->glyph_row should be non-null, i.e. we should be actually
5475 displaying something, or otherwise we should not run the hook. */
5476 xassert (it->glyph_row);
5478 /* Set up hook arguments. */
5479 args[0] = Qredisplay_end_trigger_functions;
5480 args[1] = it->window;
5481 XSETINT (args[2], it->redisplay_end_trigger_charpos);
5482 it->redisplay_end_trigger_charpos = 0;
5484 /* Since we are *trying* to run these functions, don't try to run
5485 them again, even if they get an error. */
5486 it->w->redisplay_end_trigger = Qnil;
5487 Frun_hook_with_args (3, args);
5489 /* Notice if it changed the face of the character we are on. */
5490 handle_face_prop (it);
5494 /* Deliver a composition display element. The iterator IT is already
5495 filled with composition information (done in
5496 handle_composition_prop). Value is always 1. */
5498 static int
5499 next_element_from_composition (it)
5500 struct it *it;
5502 it->what = IT_COMPOSITION;
5503 it->position = (STRINGP (it->string)
5504 ? it->current.string_pos
5505 : it->current.pos);
5506 return 1;
5511 /***********************************************************************
5512 Moving an iterator without producing glyphs
5513 ***********************************************************************/
5515 /* Move iterator IT to a specified buffer or X position within one
5516 line on the display without producing glyphs.
5518 OP should be a bit mask including some or all of these bits:
5519 MOVE_TO_X: Stop on reaching x-position TO_X.
5520 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
5521 Regardless of OP's value, stop in reaching the end of the display line.
5523 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
5524 This means, in particular, that TO_X includes window's horizontal
5525 scroll amount.
5527 The return value has several possible values that
5528 say what condition caused the scan to stop:
5530 MOVE_POS_MATCH_OR_ZV
5531 - when TO_POS or ZV was reached.
5533 MOVE_X_REACHED
5534 -when TO_X was reached before TO_POS or ZV were reached.
5536 MOVE_LINE_CONTINUED
5537 - when we reached the end of the display area and the line must
5538 be continued.
5540 MOVE_LINE_TRUNCATED
5541 - when we reached the end of the display area and the line is
5542 truncated.
5544 MOVE_NEWLINE_OR_CR
5545 - when we stopped at a line end, i.e. a newline or a CR and selective
5546 display is on. */
5548 static enum move_it_result
5549 move_it_in_display_line_to (it, to_charpos, to_x, op)
5550 struct it *it;
5551 int to_charpos, to_x, op;
5553 enum move_it_result result = MOVE_UNDEFINED;
5554 struct glyph_row *saved_glyph_row;
5556 /* Don't produce glyphs in produce_glyphs. */
5557 saved_glyph_row = it->glyph_row;
5558 it->glyph_row = NULL;
5560 while (1)
5562 int x, i, ascent = 0, descent = 0;
5564 /* Stop when ZV or TO_CHARPOS reached. */
5565 if (!get_next_display_element (it)
5566 || ((op & MOVE_TO_POS) != 0
5567 && BUFFERP (it->object)
5568 && IT_CHARPOS (*it) >= to_charpos))
5570 result = MOVE_POS_MATCH_OR_ZV;
5571 break;
5574 /* The call to produce_glyphs will get the metrics of the
5575 display element IT is loaded with. We record in x the
5576 x-position before this display element in case it does not
5577 fit on the line. */
5578 x = it->current_x;
5580 /* Remember the line height so far in case the next element doesn't
5581 fit on the line. */
5582 if (!it->truncate_lines_p)
5584 ascent = it->max_ascent;
5585 descent = it->max_descent;
5588 PRODUCE_GLYPHS (it);
5590 if (it->area != TEXT_AREA)
5592 set_iterator_to_next (it, 1);
5593 continue;
5596 /* The number of glyphs we get back in IT->nglyphs will normally
5597 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
5598 character on a terminal frame, or (iii) a line end. For the
5599 second case, IT->nglyphs - 1 padding glyphs will be present
5600 (on X frames, there is only one glyph produced for a
5601 composite character.
5603 The behavior implemented below means, for continuation lines,
5604 that as many spaces of a TAB as fit on the current line are
5605 displayed there. For terminal frames, as many glyphs of a
5606 multi-glyph character are displayed in the current line, too.
5607 This is what the old redisplay code did, and we keep it that
5608 way. Under X, the whole shape of a complex character must
5609 fit on the line or it will be completely displayed in the
5610 next line.
5612 Note that both for tabs and padding glyphs, all glyphs have
5613 the same width. */
5614 if (it->nglyphs)
5616 /* More than one glyph or glyph doesn't fit on line. All
5617 glyphs have the same width. */
5618 int single_glyph_width = it->pixel_width / it->nglyphs;
5619 int new_x;
5621 for (i = 0; i < it->nglyphs; ++i, x = new_x)
5623 new_x = x + single_glyph_width;
5625 /* We want to leave anything reaching TO_X to the caller. */
5626 if ((op & MOVE_TO_X) && new_x > to_x)
5628 it->current_x = x;
5629 result = MOVE_X_REACHED;
5630 break;
5632 else if (/* Lines are continued. */
5633 !it->truncate_lines_p
5634 && (/* And glyph doesn't fit on the line. */
5635 new_x > it->last_visible_x
5636 /* Or it fits exactly and we're on a window
5637 system frame. */
5638 || (new_x == it->last_visible_x
5639 && FRAME_WINDOW_P (it->f))))
5641 if (/* IT->hpos == 0 means the very first glyph
5642 doesn't fit on the line, e.g. a wide image. */
5643 it->hpos == 0
5644 || (new_x == it->last_visible_x
5645 && FRAME_WINDOW_P (it->f)))
5647 ++it->hpos;
5648 it->current_x = new_x;
5649 if (i == it->nglyphs - 1)
5651 set_iterator_to_next (it, 1);
5652 #ifdef HAVE_WINDOW_SYSTEM
5653 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
5655 if (!get_next_display_element (it))
5657 result = MOVE_POS_MATCH_OR_ZV;
5658 break;
5660 if (ITERATOR_AT_END_OF_LINE_P (it))
5662 result = MOVE_NEWLINE_OR_CR;
5663 break;
5666 #endif /* HAVE_WINDOW_SYSTEM */
5669 else
5671 it->current_x = x;
5672 it->max_ascent = ascent;
5673 it->max_descent = descent;
5676 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
5677 IT_CHARPOS (*it)));
5678 result = MOVE_LINE_CONTINUED;
5679 break;
5681 else if (new_x > it->first_visible_x)
5683 /* Glyph is visible. Increment number of glyphs that
5684 would be displayed. */
5685 ++it->hpos;
5687 else
5689 /* Glyph is completely off the left margin of the display
5690 area. Nothing to do. */
5694 if (result != MOVE_UNDEFINED)
5695 break;
5697 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
5699 /* Stop when TO_X specified and reached. This check is
5700 necessary here because of lines consisting of a line end,
5701 only. The line end will not produce any glyphs and we
5702 would never get MOVE_X_REACHED. */
5703 xassert (it->nglyphs == 0);
5704 result = MOVE_X_REACHED;
5705 break;
5708 /* Is this a line end? If yes, we're done. */
5709 if (ITERATOR_AT_END_OF_LINE_P (it))
5711 result = MOVE_NEWLINE_OR_CR;
5712 break;
5715 /* The current display element has been consumed. Advance
5716 to the next. */
5717 set_iterator_to_next (it, 1);
5719 /* Stop if lines are truncated and IT's current x-position is
5720 past the right edge of the window now. */
5721 if (it->truncate_lines_p
5722 && it->current_x >= it->last_visible_x)
5724 #ifdef HAVE_WINDOW_SYSTEM
5725 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
5727 if (!get_next_display_element (it))
5729 result = MOVE_POS_MATCH_OR_ZV;
5730 break;
5732 if (ITERATOR_AT_END_OF_LINE_P (it))
5734 result = MOVE_NEWLINE_OR_CR;
5735 break;
5738 #endif /* HAVE_WINDOW_SYSTEM */
5739 result = MOVE_LINE_TRUNCATED;
5740 break;
5744 /* Restore the iterator settings altered at the beginning of this
5745 function. */
5746 it->glyph_row = saved_glyph_row;
5747 return result;
5751 /* Move IT forward until it satisfies one or more of the criteria in
5752 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
5754 OP is a bit-mask that specifies where to stop, and in particular,
5755 which of those four position arguments makes a difference. See the
5756 description of enum move_operation_enum.
5758 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
5759 screen line, this function will set IT to the next position >
5760 TO_CHARPOS. */
5762 void
5763 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
5764 struct it *it;
5765 int to_charpos, to_x, to_y, to_vpos;
5766 int op;
5768 enum move_it_result skip, skip2 = MOVE_X_REACHED;
5769 int line_height;
5770 int reached = 0;
5772 for (;;)
5774 if (op & MOVE_TO_VPOS)
5776 /* If no TO_CHARPOS and no TO_X specified, stop at the
5777 start of the line TO_VPOS. */
5778 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
5780 if (it->vpos == to_vpos)
5782 reached = 1;
5783 break;
5785 else
5786 skip = move_it_in_display_line_to (it, -1, -1, 0);
5788 else
5790 /* TO_VPOS >= 0 means stop at TO_X in the line at
5791 TO_VPOS, or at TO_POS, whichever comes first. */
5792 if (it->vpos == to_vpos)
5794 reached = 2;
5795 break;
5798 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
5800 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
5802 reached = 3;
5803 break;
5805 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
5807 /* We have reached TO_X but not in the line we want. */
5808 skip = move_it_in_display_line_to (it, to_charpos,
5809 -1, MOVE_TO_POS);
5810 if (skip == MOVE_POS_MATCH_OR_ZV)
5812 reached = 4;
5813 break;
5818 else if (op & MOVE_TO_Y)
5820 struct it it_backup;
5822 /* TO_Y specified means stop at TO_X in the line containing
5823 TO_Y---or at TO_CHARPOS if this is reached first. The
5824 problem is that we can't really tell whether the line
5825 contains TO_Y before we have completely scanned it, and
5826 this may skip past TO_X. What we do is to first scan to
5827 TO_X.
5829 If TO_X is not specified, use a TO_X of zero. The reason
5830 is to make the outcome of this function more predictable.
5831 If we didn't use TO_X == 0, we would stop at the end of
5832 the line which is probably not what a caller would expect
5833 to happen. */
5834 skip = move_it_in_display_line_to (it, to_charpos,
5835 ((op & MOVE_TO_X)
5836 ? to_x : 0),
5837 (MOVE_TO_X
5838 | (op & MOVE_TO_POS)));
5840 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
5841 if (skip == MOVE_POS_MATCH_OR_ZV)
5843 reached = 5;
5844 break;
5847 /* If TO_X was reached, we would like to know whether TO_Y
5848 is in the line. This can only be said if we know the
5849 total line height which requires us to scan the rest of
5850 the line. */
5851 if (skip == MOVE_X_REACHED)
5853 it_backup = *it;
5854 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
5855 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
5856 op & MOVE_TO_POS);
5857 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
5860 /* Now, decide whether TO_Y is in this line. */
5861 line_height = it->max_ascent + it->max_descent;
5862 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
5864 if (to_y >= it->current_y
5865 && to_y < it->current_y + line_height)
5867 if (skip == MOVE_X_REACHED)
5868 /* If TO_Y is in this line and TO_X was reached above,
5869 we scanned too far. We have to restore IT's settings
5870 to the ones before skipping. */
5871 *it = it_backup;
5872 reached = 6;
5874 else if (skip == MOVE_X_REACHED)
5876 skip = skip2;
5877 if (skip == MOVE_POS_MATCH_OR_ZV)
5878 reached = 7;
5881 if (reached)
5882 break;
5884 else
5885 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
5887 switch (skip)
5889 case MOVE_POS_MATCH_OR_ZV:
5890 reached = 8;
5891 goto out;
5893 case MOVE_NEWLINE_OR_CR:
5894 set_iterator_to_next (it, 1);
5895 it->continuation_lines_width = 0;
5896 break;
5898 case MOVE_LINE_TRUNCATED:
5899 it->continuation_lines_width = 0;
5900 reseat_at_next_visible_line_start (it, 0);
5901 if ((op & MOVE_TO_POS) != 0
5902 && IT_CHARPOS (*it) > to_charpos)
5904 reached = 9;
5905 goto out;
5907 break;
5909 case MOVE_LINE_CONTINUED:
5910 it->continuation_lines_width += it->current_x;
5911 break;
5913 default:
5914 abort ();
5917 /* Reset/increment for the next run. */
5918 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
5919 it->current_x = it->hpos = 0;
5920 it->current_y += it->max_ascent + it->max_descent;
5921 ++it->vpos;
5922 last_height = it->max_ascent + it->max_descent;
5923 last_max_ascent = it->max_ascent;
5924 it->max_ascent = it->max_descent = 0;
5927 out:
5929 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
5933 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
5935 If DY > 0, move IT backward at least that many pixels. DY = 0
5936 means move IT backward to the preceding line start or BEGV. This
5937 function may move over more than DY pixels if IT->current_y - DY
5938 ends up in the middle of a line; in this case IT->current_y will be
5939 set to the top of the line moved to. */
5941 void
5942 move_it_vertically_backward (it, dy)
5943 struct it *it;
5944 int dy;
5946 int nlines, h;
5947 struct it it2, it3;
5948 int start_pos = IT_CHARPOS (*it);
5950 xassert (dy >= 0);
5952 /* Estimate how many newlines we must move back. */
5953 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
5955 /* Set the iterator's position that many lines back. */
5956 while (nlines-- && IT_CHARPOS (*it) > BEGV)
5957 back_to_previous_visible_line_start (it);
5959 /* Reseat the iterator here. When moving backward, we don't want
5960 reseat to skip forward over invisible text, set up the iterator
5961 to deliver from overlay strings at the new position etc. So,
5962 use reseat_1 here. */
5963 reseat_1 (it, it->current.pos, 1);
5965 /* We are now surely at a line start. */
5966 it->current_x = it->hpos = 0;
5967 it->continuation_lines_width = 0;
5969 /* Move forward and see what y-distance we moved. First move to the
5970 start of the next line so that we get its height. We need this
5971 height to be able to tell whether we reached the specified
5972 y-distance. */
5973 it2 = *it;
5974 it2.max_ascent = it2.max_descent = 0;
5975 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
5976 MOVE_TO_POS | MOVE_TO_VPOS);
5977 xassert (IT_CHARPOS (*it) >= BEGV);
5978 it3 = it2;
5980 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
5981 xassert (IT_CHARPOS (*it) >= BEGV);
5982 /* H is the actual vertical distance from the position in *IT
5983 and the starting position. */
5984 h = it2.current_y - it->current_y;
5985 /* NLINES is the distance in number of lines. */
5986 nlines = it2.vpos - it->vpos;
5988 /* Correct IT's y and vpos position
5989 so that they are relative to the starting point. */
5990 it->vpos -= nlines;
5991 it->current_y -= h;
5993 if (dy == 0)
5995 /* DY == 0 means move to the start of the screen line. The
5996 value of nlines is > 0 if continuation lines were involved. */
5997 if (nlines > 0)
5998 move_it_by_lines (it, nlines, 1);
5999 xassert (IT_CHARPOS (*it) <= start_pos);
6001 else
6003 /* The y-position we try to reach, relative to *IT.
6004 Note that H has been subtracted in front of the if-statement. */
6005 int target_y = it->current_y + h - dy;
6006 int y0 = it3.current_y;
6007 int y1 = line_bottom_y (&it3);
6008 int line_height = y1 - y0;
6010 /* If we did not reach target_y, try to move further backward if
6011 we can. If we moved too far backward, try to move forward. */
6012 if (target_y < it->current_y
6013 /* This is heuristic. In a window that's 3 lines high, with
6014 a line height of 13 pixels each, recentering with point
6015 on the bottom line will try to move -39/2 = 19 pixels
6016 backward. Try to avoid moving into the first line. */
6017 && it->current_y - target_y > line_height / 3 * 2
6018 && IT_CHARPOS (*it) > BEGV)
6020 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
6021 target_y - it->current_y));
6022 move_it_vertically (it, target_y - it->current_y);
6023 xassert (IT_CHARPOS (*it) >= BEGV);
6025 else if (target_y >= it->current_y + line_height
6026 && IT_CHARPOS (*it) < ZV)
6028 /* Should move forward by at least one line, maybe more.
6030 Note: Calling move_it_by_lines can be expensive on
6031 terminal frames, where compute_motion is used (via
6032 vmotion) to do the job, when there are very long lines
6033 and truncate-lines is nil. That's the reason for
6034 treating terminal frames specially here. */
6036 if (!FRAME_WINDOW_P (it->f))
6037 move_it_vertically (it, target_y - (it->current_y + line_height));
6038 else
6042 move_it_by_lines (it, 1, 1);
6044 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
6047 xassert (IT_CHARPOS (*it) >= BEGV);
6053 /* Move IT by a specified amount of pixel lines DY. DY negative means
6054 move backwards. DY = 0 means move to start of screen line. At the
6055 end, IT will be on the start of a screen line. */
6057 void
6058 move_it_vertically (it, dy)
6059 struct it *it;
6060 int dy;
6062 if (dy <= 0)
6063 move_it_vertically_backward (it, -dy);
6064 else if (dy > 0)
6066 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
6067 move_it_to (it, ZV, -1, it->current_y + dy, -1,
6068 MOVE_TO_POS | MOVE_TO_Y);
6069 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
6071 /* If buffer ends in ZV without a newline, move to the start of
6072 the line to satisfy the post-condition. */
6073 if (IT_CHARPOS (*it) == ZV
6074 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
6075 move_it_by_lines (it, 0, 0);
6080 /* Move iterator IT past the end of the text line it is in. */
6082 void
6083 move_it_past_eol (it)
6084 struct it *it;
6086 enum move_it_result rc;
6088 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
6089 if (rc == MOVE_NEWLINE_OR_CR)
6090 set_iterator_to_next (it, 0);
6094 #if 0 /* Currently not used. */
6096 /* Return non-zero if some text between buffer positions START_CHARPOS
6097 and END_CHARPOS is invisible. IT->window is the window for text
6098 property lookup. */
6100 static int
6101 invisible_text_between_p (it, start_charpos, end_charpos)
6102 struct it *it;
6103 int start_charpos, end_charpos;
6105 Lisp_Object prop, limit;
6106 int invisible_found_p;
6108 xassert (it != NULL && start_charpos <= end_charpos);
6110 /* Is text at START invisible? */
6111 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
6112 it->window);
6113 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6114 invisible_found_p = 1;
6115 else
6117 limit = Fnext_single_char_property_change (make_number (start_charpos),
6118 Qinvisible, Qnil,
6119 make_number (end_charpos));
6120 invisible_found_p = XFASTINT (limit) < end_charpos;
6123 return invisible_found_p;
6126 #endif /* 0 */
6129 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
6130 negative means move up. DVPOS == 0 means move to the start of the
6131 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
6132 NEED_Y_P is zero, IT->current_y will be left unchanged.
6134 Further optimization ideas: If we would know that IT->f doesn't use
6135 a face with proportional font, we could be faster for
6136 truncate-lines nil. */
6138 void
6139 move_it_by_lines (it, dvpos, need_y_p)
6140 struct it *it;
6141 int dvpos, need_y_p;
6143 struct position pos;
6145 if (!FRAME_WINDOW_P (it->f))
6147 struct text_pos textpos;
6149 /* We can use vmotion on frames without proportional fonts. */
6150 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
6151 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
6152 reseat (it, textpos, 1);
6153 it->vpos += pos.vpos;
6154 it->current_y += pos.vpos;
6156 else if (dvpos == 0)
6158 /* DVPOS == 0 means move to the start of the screen line. */
6159 move_it_vertically_backward (it, 0);
6160 xassert (it->current_x == 0 && it->hpos == 0);
6162 else if (dvpos > 0)
6163 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
6164 else
6166 struct it it2;
6167 int start_charpos, i;
6169 /* Start at the beginning of the screen line containing IT's
6170 position. */
6171 move_it_vertically_backward (it, 0);
6173 /* Go back -DVPOS visible lines and reseat the iterator there. */
6174 start_charpos = IT_CHARPOS (*it);
6175 for (i = -dvpos; i && IT_CHARPOS (*it) > BEGV; --i)
6176 back_to_previous_visible_line_start (it);
6177 reseat (it, it->current.pos, 1);
6178 it->current_x = it->hpos = 0;
6180 /* Above call may have moved too far if continuation lines
6181 are involved. Scan forward and see if it did. */
6182 it2 = *it;
6183 it2.vpos = it2.current_y = 0;
6184 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
6185 it->vpos -= it2.vpos;
6186 it->current_y -= it2.current_y;
6187 it->current_x = it->hpos = 0;
6189 /* If we moved too far, move IT some lines forward. */
6190 if (it2.vpos > -dvpos)
6192 int delta = it2.vpos + dvpos;
6193 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
6198 /* Return 1 if IT points into the middle of a display vector. */
6201 in_display_vector_p (it)
6202 struct it *it;
6204 return (it->method == next_element_from_display_vector
6205 && it->current.dpvec_index > 0
6206 && it->dpvec + it->current.dpvec_index != it->dpend);
6210 /***********************************************************************
6211 Messages
6212 ***********************************************************************/
6215 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
6216 to *Messages*. */
6218 void
6219 add_to_log (format, arg1, arg2)
6220 char *format;
6221 Lisp_Object arg1, arg2;
6223 Lisp_Object args[3];
6224 Lisp_Object msg, fmt;
6225 char *buffer;
6226 int len;
6227 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
6229 /* Do nothing if called asynchronously. Inserting text into
6230 a buffer may call after-change-functions and alike and
6231 that would means running Lisp asynchronously. */
6232 if (handling_signal)
6233 return;
6235 fmt = msg = Qnil;
6236 GCPRO4 (fmt, msg, arg1, arg2);
6238 args[0] = fmt = build_string (format);
6239 args[1] = arg1;
6240 args[2] = arg2;
6241 msg = Fformat (3, args);
6243 len = SBYTES (msg) + 1;
6244 buffer = (char *) alloca (len);
6245 bcopy (SDATA (msg), buffer, len);
6247 message_dolog (buffer, len - 1, 1, 0);
6248 UNGCPRO;
6252 /* Output a newline in the *Messages* buffer if "needs" one. */
6254 void
6255 message_log_maybe_newline ()
6257 if (message_log_need_newline)
6258 message_dolog ("", 0, 1, 0);
6262 /* Add a string M of length NBYTES to the message log, optionally
6263 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
6264 nonzero, means interpret the contents of M as multibyte. This
6265 function calls low-level routines in order to bypass text property
6266 hooks, etc. which might not be safe to run. */
6268 void
6269 message_dolog (m, nbytes, nlflag, multibyte)
6270 const char *m;
6271 int nbytes, nlflag, multibyte;
6273 if (!NILP (Vmemory_full))
6274 return;
6276 if (!NILP (Vmessage_log_max))
6278 struct buffer *oldbuf;
6279 Lisp_Object oldpoint, oldbegv, oldzv;
6280 int old_windows_or_buffers_changed = windows_or_buffers_changed;
6281 int point_at_end = 0;
6282 int zv_at_end = 0;
6283 Lisp_Object old_deactivate_mark, tem;
6284 struct gcpro gcpro1;
6286 old_deactivate_mark = Vdeactivate_mark;
6287 oldbuf = current_buffer;
6288 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
6289 current_buffer->undo_list = Qt;
6291 oldpoint = message_dolog_marker1;
6292 set_marker_restricted (oldpoint, make_number (PT), Qnil);
6293 oldbegv = message_dolog_marker2;
6294 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
6295 oldzv = message_dolog_marker3;
6296 set_marker_restricted (oldzv, make_number (ZV), Qnil);
6297 GCPRO1 (old_deactivate_mark);
6299 if (PT == Z)
6300 point_at_end = 1;
6301 if (ZV == Z)
6302 zv_at_end = 1;
6304 BEGV = BEG;
6305 BEGV_BYTE = BEG_BYTE;
6306 ZV = Z;
6307 ZV_BYTE = Z_BYTE;
6308 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6310 /* Insert the string--maybe converting multibyte to single byte
6311 or vice versa, so that all the text fits the buffer. */
6312 if (multibyte
6313 && NILP (current_buffer->enable_multibyte_characters))
6315 int i, c, char_bytes;
6316 unsigned char work[1];
6318 /* Convert a multibyte string to single-byte
6319 for the *Message* buffer. */
6320 for (i = 0; i < nbytes; i += char_bytes)
6322 c = string_char_and_length (m + i, nbytes - i, &char_bytes);
6323 work[0] = (SINGLE_BYTE_CHAR_P (c)
6325 : multibyte_char_to_unibyte (c, Qnil));
6326 insert_1_both (work, 1, 1, 1, 0, 0);
6329 else if (! multibyte
6330 && ! NILP (current_buffer->enable_multibyte_characters))
6332 int i, c, char_bytes;
6333 unsigned char *msg = (unsigned char *) m;
6334 unsigned char str[MAX_MULTIBYTE_LENGTH];
6335 /* Convert a single-byte string to multibyte
6336 for the *Message* buffer. */
6337 for (i = 0; i < nbytes; i++)
6339 c = unibyte_char_to_multibyte (msg[i]);
6340 char_bytes = CHAR_STRING (c, str);
6341 insert_1_both (str, 1, char_bytes, 1, 0, 0);
6344 else if (nbytes)
6345 insert_1 (m, nbytes, 1, 0, 0);
6347 if (nlflag)
6349 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
6350 insert_1 ("\n", 1, 1, 0, 0);
6352 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
6353 this_bol = PT;
6354 this_bol_byte = PT_BYTE;
6356 /* See if this line duplicates the previous one.
6357 If so, combine duplicates. */
6358 if (this_bol > BEG)
6360 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
6361 prev_bol = PT;
6362 prev_bol_byte = PT_BYTE;
6364 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
6365 this_bol, this_bol_byte);
6366 if (dup)
6368 del_range_both (prev_bol, prev_bol_byte,
6369 this_bol, this_bol_byte, 0);
6370 if (dup > 1)
6372 char dupstr[40];
6373 int duplen;
6375 /* If you change this format, don't forget to also
6376 change message_log_check_duplicate. */
6377 sprintf (dupstr, " [%d times]", dup);
6378 duplen = strlen (dupstr);
6379 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
6380 insert_1 (dupstr, duplen, 1, 0, 1);
6385 /* If we have more than the desired maximum number of lines
6386 in the *Messages* buffer now, delete the oldest ones.
6387 This is safe because we don't have undo in this buffer. */
6389 if (NATNUMP (Vmessage_log_max))
6391 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
6392 -XFASTINT (Vmessage_log_max) - 1, 0);
6393 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
6396 BEGV = XMARKER (oldbegv)->charpos;
6397 BEGV_BYTE = marker_byte_position (oldbegv);
6399 if (zv_at_end)
6401 ZV = Z;
6402 ZV_BYTE = Z_BYTE;
6404 else
6406 ZV = XMARKER (oldzv)->charpos;
6407 ZV_BYTE = marker_byte_position (oldzv);
6410 if (point_at_end)
6411 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6412 else
6413 /* We can't do Fgoto_char (oldpoint) because it will run some
6414 Lisp code. */
6415 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
6416 XMARKER (oldpoint)->bytepos);
6418 UNGCPRO;
6419 unchain_marker (XMARKER (oldpoint));
6420 unchain_marker (XMARKER (oldbegv));
6421 unchain_marker (XMARKER (oldzv));
6423 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
6424 set_buffer_internal (oldbuf);
6425 if (NILP (tem))
6426 windows_or_buffers_changed = old_windows_or_buffers_changed;
6427 message_log_need_newline = !nlflag;
6428 Vdeactivate_mark = old_deactivate_mark;
6433 /* We are at the end of the buffer after just having inserted a newline.
6434 (Note: We depend on the fact we won't be crossing the gap.)
6435 Check to see if the most recent message looks a lot like the previous one.
6436 Return 0 if different, 1 if the new one should just replace it, or a
6437 value N > 1 if we should also append " [N times]". */
6439 static int
6440 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
6441 int prev_bol, this_bol;
6442 int prev_bol_byte, this_bol_byte;
6444 int i;
6445 int len = Z_BYTE - 1 - this_bol_byte;
6446 int seen_dots = 0;
6447 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
6448 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
6450 for (i = 0; i < len; i++)
6452 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
6453 seen_dots = 1;
6454 if (p1[i] != p2[i])
6455 return seen_dots;
6457 p1 += len;
6458 if (*p1 == '\n')
6459 return 2;
6460 if (*p1++ == ' ' && *p1++ == '[')
6462 int n = 0;
6463 while (*p1 >= '0' && *p1 <= '9')
6464 n = n * 10 + *p1++ - '0';
6465 if (strncmp (p1, " times]\n", 8) == 0)
6466 return n+1;
6468 return 0;
6472 /* Display an echo area message M with a specified length of NBYTES
6473 bytes. The string may include null characters. If M is 0, clear
6474 out any existing message, and let the mini-buffer text show
6475 through.
6477 The buffer M must continue to exist until after the echo area gets
6478 cleared or some other message gets displayed there. This means do
6479 not pass text that is stored in a Lisp string; do not pass text in
6480 a buffer that was alloca'd. */
6482 void
6483 message2 (m, nbytes, multibyte)
6484 const char *m;
6485 int nbytes;
6486 int multibyte;
6488 /* First flush out any partial line written with print. */
6489 message_log_maybe_newline ();
6490 if (m)
6491 message_dolog (m, nbytes, 1, multibyte);
6492 message2_nolog (m, nbytes, multibyte);
6496 /* The non-logging counterpart of message2. */
6498 void
6499 message2_nolog (m, nbytes, multibyte)
6500 const char *m;
6501 int nbytes, multibyte;
6503 struct frame *sf = SELECTED_FRAME ();
6504 message_enable_multibyte = multibyte;
6506 if (noninteractive)
6508 if (noninteractive_need_newline)
6509 putc ('\n', stderr);
6510 noninteractive_need_newline = 0;
6511 if (m)
6512 fwrite (m, nbytes, 1, stderr);
6513 if (cursor_in_echo_area == 0)
6514 fprintf (stderr, "\n");
6515 fflush (stderr);
6517 /* A null message buffer means that the frame hasn't really been
6518 initialized yet. Error messages get reported properly by
6519 cmd_error, so this must be just an informative message; toss it. */
6520 else if (INTERACTIVE
6521 && sf->glyphs_initialized_p
6522 && FRAME_MESSAGE_BUF (sf))
6524 Lisp_Object mini_window;
6525 struct frame *f;
6527 /* Get the frame containing the mini-buffer
6528 that the selected frame is using. */
6529 mini_window = FRAME_MINIBUF_WINDOW (sf);
6530 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6532 FRAME_SAMPLE_VISIBILITY (f);
6533 if (FRAME_VISIBLE_P (sf)
6534 && ! FRAME_VISIBLE_P (f))
6535 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
6537 if (m)
6539 set_message (m, Qnil, nbytes, multibyte);
6540 if (minibuffer_auto_raise)
6541 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
6543 else
6544 clear_message (1, 1);
6546 do_pending_window_change (0);
6547 echo_area_display (1);
6548 do_pending_window_change (0);
6549 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6550 (*frame_up_to_date_hook) (f);
6555 /* Display an echo area message M with a specified length of NBYTES
6556 bytes. The string may include null characters. If M is not a
6557 string, clear out any existing message, and let the mini-buffer
6558 text show through. */
6560 void
6561 message3 (m, nbytes, multibyte)
6562 Lisp_Object m;
6563 int nbytes;
6564 int multibyte;
6566 struct gcpro gcpro1;
6568 GCPRO1 (m);
6570 /* First flush out any partial line written with print. */
6571 message_log_maybe_newline ();
6572 if (STRINGP (m))
6573 message_dolog (SDATA (m), nbytes, 1, multibyte);
6574 message3_nolog (m, nbytes, multibyte);
6576 UNGCPRO;
6580 /* The non-logging version of message3. */
6582 void
6583 message3_nolog (m, nbytes, multibyte)
6584 Lisp_Object m;
6585 int nbytes, multibyte;
6587 struct frame *sf = SELECTED_FRAME ();
6588 message_enable_multibyte = multibyte;
6590 if (noninteractive)
6592 if (noninteractive_need_newline)
6593 putc ('\n', stderr);
6594 noninteractive_need_newline = 0;
6595 if (STRINGP (m))
6596 fwrite (SDATA (m), nbytes, 1, stderr);
6597 if (cursor_in_echo_area == 0)
6598 fprintf (stderr, "\n");
6599 fflush (stderr);
6601 /* A null message buffer means that the frame hasn't really been
6602 initialized yet. Error messages get reported properly by
6603 cmd_error, so this must be just an informative message; toss it. */
6604 else if (INTERACTIVE
6605 && sf->glyphs_initialized_p
6606 && FRAME_MESSAGE_BUF (sf))
6608 Lisp_Object mini_window;
6609 Lisp_Object frame;
6610 struct frame *f;
6612 /* Get the frame containing the mini-buffer
6613 that the selected frame is using. */
6614 mini_window = FRAME_MINIBUF_WINDOW (sf);
6615 frame = XWINDOW (mini_window)->frame;
6616 f = XFRAME (frame);
6618 FRAME_SAMPLE_VISIBILITY (f);
6619 if (FRAME_VISIBLE_P (sf)
6620 && !FRAME_VISIBLE_P (f))
6621 Fmake_frame_visible (frame);
6623 if (STRINGP (m) && SCHARS (m) > 0)
6625 set_message (NULL, m, nbytes, multibyte);
6626 if (minibuffer_auto_raise)
6627 Fraise_frame (frame);
6629 else
6630 clear_message (1, 1);
6632 do_pending_window_change (0);
6633 echo_area_display (1);
6634 do_pending_window_change (0);
6635 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6636 (*frame_up_to_date_hook) (f);
6641 /* Display a null-terminated echo area message M. If M is 0, clear
6642 out any existing message, and let the mini-buffer text show through.
6644 The buffer M must continue to exist until after the echo area gets
6645 cleared or some other message gets displayed there. Do not pass
6646 text that is stored in a Lisp string. Do not pass text in a buffer
6647 that was alloca'd. */
6649 void
6650 message1 (m)
6651 char *m;
6653 message2 (m, (m ? strlen (m) : 0), 0);
6657 /* The non-logging counterpart of message1. */
6659 void
6660 message1_nolog (m)
6661 char *m;
6663 message2_nolog (m, (m ? strlen (m) : 0), 0);
6666 /* Display a message M which contains a single %s
6667 which gets replaced with STRING. */
6669 void
6670 message_with_string (m, string, log)
6671 char *m;
6672 Lisp_Object string;
6673 int log;
6675 CHECK_STRING (string);
6677 if (noninteractive)
6679 if (m)
6681 if (noninteractive_need_newline)
6682 putc ('\n', stderr);
6683 noninteractive_need_newline = 0;
6684 fprintf (stderr, m, SDATA (string));
6685 if (cursor_in_echo_area == 0)
6686 fprintf (stderr, "\n");
6687 fflush (stderr);
6690 else if (INTERACTIVE)
6692 /* The frame whose minibuffer we're going to display the message on.
6693 It may be larger than the selected frame, so we need
6694 to use its buffer, not the selected frame's buffer. */
6695 Lisp_Object mini_window;
6696 struct frame *f, *sf = SELECTED_FRAME ();
6698 /* Get the frame containing the minibuffer
6699 that the selected frame is using. */
6700 mini_window = FRAME_MINIBUF_WINDOW (sf);
6701 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6703 /* A null message buffer means that the frame hasn't really been
6704 initialized yet. Error messages get reported properly by
6705 cmd_error, so this must be just an informative message; toss it. */
6706 if (FRAME_MESSAGE_BUF (f))
6708 Lisp_Object args[2], message;
6709 struct gcpro gcpro1, gcpro2;
6711 args[0] = build_string (m);
6712 args[1] = message = string;
6713 GCPRO2 (args[0], message);
6714 gcpro1.nvars = 2;
6716 message = Fformat (2, args);
6718 if (log)
6719 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
6720 else
6721 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
6723 UNGCPRO;
6725 /* Print should start at the beginning of the message
6726 buffer next time. */
6727 message_buf_print = 0;
6733 /* Dump an informative message to the minibuf. If M is 0, clear out
6734 any existing message, and let the mini-buffer text show through. */
6736 /* VARARGS 1 */
6737 void
6738 message (m, a1, a2, a3)
6739 char *m;
6740 EMACS_INT a1, a2, a3;
6742 if (noninteractive)
6744 if (m)
6746 if (noninteractive_need_newline)
6747 putc ('\n', stderr);
6748 noninteractive_need_newline = 0;
6749 fprintf (stderr, m, a1, a2, a3);
6750 if (cursor_in_echo_area == 0)
6751 fprintf (stderr, "\n");
6752 fflush (stderr);
6755 else if (INTERACTIVE)
6757 /* The frame whose mini-buffer we're going to display the message
6758 on. It may be larger than the selected frame, so we need to
6759 use its buffer, not the selected frame's buffer. */
6760 Lisp_Object mini_window;
6761 struct frame *f, *sf = SELECTED_FRAME ();
6763 /* Get the frame containing the mini-buffer
6764 that the selected frame is using. */
6765 mini_window = FRAME_MINIBUF_WINDOW (sf);
6766 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6768 /* A null message buffer means that the frame hasn't really been
6769 initialized yet. Error messages get reported properly by
6770 cmd_error, so this must be just an informative message; toss
6771 it. */
6772 if (FRAME_MESSAGE_BUF (f))
6774 if (m)
6776 int len;
6777 #ifdef NO_ARG_ARRAY
6778 char *a[3];
6779 a[0] = (char *) a1;
6780 a[1] = (char *) a2;
6781 a[2] = (char *) a3;
6783 len = doprnt (FRAME_MESSAGE_BUF (f),
6784 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
6785 #else
6786 len = doprnt (FRAME_MESSAGE_BUF (f),
6787 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
6788 (char **) &a1);
6789 #endif /* NO_ARG_ARRAY */
6791 message2 (FRAME_MESSAGE_BUF (f), len, 0);
6793 else
6794 message1 (0);
6796 /* Print should start at the beginning of the message
6797 buffer next time. */
6798 message_buf_print = 0;
6804 /* The non-logging version of message. */
6806 void
6807 message_nolog (m, a1, a2, a3)
6808 char *m;
6809 EMACS_INT a1, a2, a3;
6811 Lisp_Object old_log_max;
6812 old_log_max = Vmessage_log_max;
6813 Vmessage_log_max = Qnil;
6814 message (m, a1, a2, a3);
6815 Vmessage_log_max = old_log_max;
6819 /* Display the current message in the current mini-buffer. This is
6820 only called from error handlers in process.c, and is not time
6821 critical. */
6823 void
6824 update_echo_area ()
6826 if (!NILP (echo_area_buffer[0]))
6828 Lisp_Object string;
6829 string = Fcurrent_message ();
6830 message3 (string, SBYTES (string),
6831 !NILP (current_buffer->enable_multibyte_characters));
6836 /* Make sure echo area buffers in `echo_buffers' are live.
6837 If they aren't, make new ones. */
6839 static void
6840 ensure_echo_area_buffers ()
6842 int i;
6844 for (i = 0; i < 2; ++i)
6845 if (!BUFFERP (echo_buffer[i])
6846 || NILP (XBUFFER (echo_buffer[i])->name))
6848 char name[30];
6849 Lisp_Object old_buffer;
6850 int j;
6852 old_buffer = echo_buffer[i];
6853 sprintf (name, " *Echo Area %d*", i);
6854 echo_buffer[i] = Fget_buffer_create (build_string (name));
6855 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
6857 for (j = 0; j < 2; ++j)
6858 if (EQ (old_buffer, echo_area_buffer[j]))
6859 echo_area_buffer[j] = echo_buffer[i];
6864 /* Call FN with args A1..A4 with either the current or last displayed
6865 echo_area_buffer as current buffer.
6867 WHICH zero means use the current message buffer
6868 echo_area_buffer[0]. If that is nil, choose a suitable buffer
6869 from echo_buffer[] and clear it.
6871 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
6872 suitable buffer from echo_buffer[] and clear it.
6874 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
6875 that the current message becomes the last displayed one, make
6876 choose a suitable buffer for echo_area_buffer[0], and clear it.
6878 Value is what FN returns. */
6880 static int
6881 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
6882 struct window *w;
6883 int which;
6884 int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
6885 EMACS_INT a1;
6886 Lisp_Object a2;
6887 EMACS_INT a3, a4;
6889 Lisp_Object buffer;
6890 int this_one, the_other, clear_buffer_p, rc;
6891 int count = SPECPDL_INDEX ();
6893 /* If buffers aren't live, make new ones. */
6894 ensure_echo_area_buffers ();
6896 clear_buffer_p = 0;
6898 if (which == 0)
6899 this_one = 0, the_other = 1;
6900 else if (which > 0)
6901 this_one = 1, the_other = 0;
6902 else
6904 this_one = 0, the_other = 1;
6905 clear_buffer_p = 1;
6907 /* We need a fresh one in case the current echo buffer equals
6908 the one containing the last displayed echo area message. */
6909 if (!NILP (echo_area_buffer[this_one])
6910 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
6911 echo_area_buffer[this_one] = Qnil;
6914 /* Choose a suitable buffer from echo_buffer[] is we don't
6915 have one. */
6916 if (NILP (echo_area_buffer[this_one]))
6918 echo_area_buffer[this_one]
6919 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
6920 ? echo_buffer[the_other]
6921 : echo_buffer[this_one]);
6922 clear_buffer_p = 1;
6925 buffer = echo_area_buffer[this_one];
6927 /* Don't get confused by reusing the buffer used for echoing
6928 for a different purpose. */
6929 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
6930 cancel_echoing ();
6932 record_unwind_protect (unwind_with_echo_area_buffer,
6933 with_echo_area_buffer_unwind_data (w));
6935 /* Make the echo area buffer current. Note that for display
6936 purposes, it is not necessary that the displayed window's buffer
6937 == current_buffer, except for text property lookup. So, let's
6938 only set that buffer temporarily here without doing a full
6939 Fset_window_buffer. We must also change w->pointm, though,
6940 because otherwise an assertions in unshow_buffer fails, and Emacs
6941 aborts. */
6942 set_buffer_internal_1 (XBUFFER (buffer));
6943 if (w)
6945 w->buffer = buffer;
6946 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
6949 current_buffer->undo_list = Qt;
6950 current_buffer->read_only = Qnil;
6951 specbind (Qinhibit_read_only, Qt);
6952 specbind (Qinhibit_modification_hooks, Qt);
6954 if (clear_buffer_p && Z > BEG)
6955 del_range (BEG, Z);
6957 xassert (BEGV >= BEG);
6958 xassert (ZV <= Z && ZV >= BEGV);
6960 rc = fn (a1, a2, a3, a4);
6962 xassert (BEGV >= BEG);
6963 xassert (ZV <= Z && ZV >= BEGV);
6965 unbind_to (count, Qnil);
6966 return rc;
6970 /* Save state that should be preserved around the call to the function
6971 FN called in with_echo_area_buffer. */
6973 static Lisp_Object
6974 with_echo_area_buffer_unwind_data (w)
6975 struct window *w;
6977 int i = 0;
6978 Lisp_Object vector;
6980 /* Reduce consing by keeping one vector in
6981 Vwith_echo_area_save_vector. */
6982 vector = Vwith_echo_area_save_vector;
6983 Vwith_echo_area_save_vector = Qnil;
6985 if (NILP (vector))
6986 vector = Fmake_vector (make_number (7), Qnil);
6988 XSETBUFFER (AREF (vector, i), current_buffer); ++i;
6989 AREF (vector, i) = Vdeactivate_mark, ++i;
6990 AREF (vector, i) = make_number (windows_or_buffers_changed), ++i;
6992 if (w)
6994 XSETWINDOW (AREF (vector, i), w); ++i;
6995 AREF (vector, i) = w->buffer; ++i;
6996 AREF (vector, i) = make_number (XMARKER (w->pointm)->charpos); ++i;
6997 AREF (vector, i) = make_number (XMARKER (w->pointm)->bytepos); ++i;
6999 else
7001 int end = i + 4;
7002 for (; i < end; ++i)
7003 AREF (vector, i) = Qnil;
7006 xassert (i == ASIZE (vector));
7007 return vector;
7011 /* Restore global state from VECTOR which was created by
7012 with_echo_area_buffer_unwind_data. */
7014 static Lisp_Object
7015 unwind_with_echo_area_buffer (vector)
7016 Lisp_Object vector;
7018 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
7019 Vdeactivate_mark = AREF (vector, 1);
7020 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
7022 if (WINDOWP (AREF (vector, 3)))
7024 struct window *w;
7025 Lisp_Object buffer, charpos, bytepos;
7027 w = XWINDOW (AREF (vector, 3));
7028 buffer = AREF (vector, 4);
7029 charpos = AREF (vector, 5);
7030 bytepos = AREF (vector, 6);
7032 w->buffer = buffer;
7033 set_marker_both (w->pointm, buffer,
7034 XFASTINT (charpos), XFASTINT (bytepos));
7037 Vwith_echo_area_save_vector = vector;
7038 return Qnil;
7042 /* Set up the echo area for use by print functions. MULTIBYTE_P
7043 non-zero means we will print multibyte. */
7045 void
7046 setup_echo_area_for_printing (multibyte_p)
7047 int multibyte_p;
7049 /* If we can't find an echo area any more, exit. */
7050 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
7051 Fkill_emacs (Qnil);
7053 ensure_echo_area_buffers ();
7055 if (!message_buf_print)
7057 /* A message has been output since the last time we printed.
7058 Choose a fresh echo area buffer. */
7059 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7060 echo_area_buffer[0] = echo_buffer[1];
7061 else
7062 echo_area_buffer[0] = echo_buffer[0];
7064 /* Switch to that buffer and clear it. */
7065 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7066 current_buffer->truncate_lines = Qnil;
7068 if (Z > BEG)
7070 int count = SPECPDL_INDEX ();
7071 specbind (Qinhibit_read_only, Qt);
7072 /* Note that undo recording is always disabled. */
7073 del_range (BEG, Z);
7074 unbind_to (count, Qnil);
7076 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7078 /* Set up the buffer for the multibyteness we need. */
7079 if (multibyte_p
7080 != !NILP (current_buffer->enable_multibyte_characters))
7081 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
7083 /* Raise the frame containing the echo area. */
7084 if (minibuffer_auto_raise)
7086 struct frame *sf = SELECTED_FRAME ();
7087 Lisp_Object mini_window;
7088 mini_window = FRAME_MINIBUF_WINDOW (sf);
7089 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
7092 message_log_maybe_newline ();
7093 message_buf_print = 1;
7095 else
7097 if (NILP (echo_area_buffer[0]))
7099 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7100 echo_area_buffer[0] = echo_buffer[1];
7101 else
7102 echo_area_buffer[0] = echo_buffer[0];
7105 if (current_buffer != XBUFFER (echo_area_buffer[0]))
7107 /* Someone switched buffers between print requests. */
7108 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7109 current_buffer->truncate_lines = Qnil;
7115 /* Display an echo area message in window W. Value is non-zero if W's
7116 height is changed. If display_last_displayed_message_p is
7117 non-zero, display the message that was last displayed, otherwise
7118 display the current message. */
7120 static int
7121 display_echo_area (w)
7122 struct window *w;
7124 int i, no_message_p, window_height_changed_p, count;
7126 /* Temporarily disable garbage collections while displaying the echo
7127 area. This is done because a GC can print a message itself.
7128 That message would modify the echo area buffer's contents while a
7129 redisplay of the buffer is going on, and seriously confuse
7130 redisplay. */
7131 count = inhibit_garbage_collection ();
7133 /* If there is no message, we must call display_echo_area_1
7134 nevertheless because it resizes the window. But we will have to
7135 reset the echo_area_buffer in question to nil at the end because
7136 with_echo_area_buffer will sets it to an empty buffer. */
7137 i = display_last_displayed_message_p ? 1 : 0;
7138 no_message_p = NILP (echo_area_buffer[i]);
7140 window_height_changed_p
7141 = with_echo_area_buffer (w, display_last_displayed_message_p,
7142 display_echo_area_1,
7143 (EMACS_INT) w, Qnil, 0, 0);
7145 if (no_message_p)
7146 echo_area_buffer[i] = Qnil;
7148 unbind_to (count, Qnil);
7149 return window_height_changed_p;
7153 /* Helper for display_echo_area. Display the current buffer which
7154 contains the current echo area message in window W, a mini-window,
7155 a pointer to which is passed in A1. A2..A4 are currently not used.
7156 Change the height of W so that all of the message is displayed.
7157 Value is non-zero if height of W was changed. */
7159 static int
7160 display_echo_area_1 (a1, a2, a3, a4)
7161 EMACS_INT a1;
7162 Lisp_Object a2;
7163 EMACS_INT a3, a4;
7165 struct window *w = (struct window *) a1;
7166 Lisp_Object window;
7167 struct text_pos start;
7168 int window_height_changed_p = 0;
7170 /* Do this before displaying, so that we have a large enough glyph
7171 matrix for the display. */
7172 window_height_changed_p = resize_mini_window (w, 0);
7174 /* Display. */
7175 clear_glyph_matrix (w->desired_matrix);
7176 XSETWINDOW (window, w);
7177 SET_TEXT_POS (start, BEG, BEG_BYTE);
7178 try_window (window, start);
7180 return window_height_changed_p;
7184 /* Resize the echo area window to exactly the size needed for the
7185 currently displayed message, if there is one. If a mini-buffer
7186 is active, don't shrink it. */
7188 void
7189 resize_echo_area_exactly ()
7191 if (BUFFERP (echo_area_buffer[0])
7192 && WINDOWP (echo_area_window))
7194 struct window *w = XWINDOW (echo_area_window);
7195 int resized_p;
7196 Lisp_Object resize_exactly;
7198 if (minibuf_level == 0)
7199 resize_exactly = Qt;
7200 else
7201 resize_exactly = Qnil;
7203 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
7204 (EMACS_INT) w, resize_exactly, 0, 0);
7205 if (resized_p)
7207 ++windows_or_buffers_changed;
7208 ++update_mode_lines;
7209 redisplay_internal (0);
7215 /* Callback function for with_echo_area_buffer, when used from
7216 resize_echo_area_exactly. A1 contains a pointer to the window to
7217 resize, EXACTLY non-nil means resize the mini-window exactly to the
7218 size of the text displayed. A3 and A4 are not used. Value is what
7219 resize_mini_window returns. */
7221 static int
7222 resize_mini_window_1 (a1, exactly, a3, a4)
7223 EMACS_INT a1;
7224 Lisp_Object exactly;
7225 EMACS_INT a3, a4;
7227 return resize_mini_window ((struct window *) a1, !NILP (exactly));
7231 /* Resize mini-window W to fit the size of its contents. EXACT:P
7232 means size the window exactly to the size needed. Otherwise, it's
7233 only enlarged until W's buffer is empty. Value is non-zero if
7234 the window height has been changed. */
7237 resize_mini_window (w, exact_p)
7238 struct window *w;
7239 int exact_p;
7241 struct frame *f = XFRAME (w->frame);
7242 int window_height_changed_p = 0;
7244 xassert (MINI_WINDOW_P (w));
7246 /* Don't resize windows while redisplaying a window; it would
7247 confuse redisplay functions when the size of the window they are
7248 displaying changes from under them. Such a resizing can happen,
7249 for instance, when which-func prints a long message while
7250 we are running fontification-functions. We're running these
7251 functions with safe_call which binds inhibit-redisplay to t. */
7252 if (!NILP (Vinhibit_redisplay))
7253 return 0;
7255 /* Nil means don't try to resize. */
7256 if (NILP (Vresize_mini_windows)
7257 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
7258 return 0;
7260 if (!FRAME_MINIBUF_ONLY_P (f))
7262 struct it it;
7263 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
7264 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
7265 int height, max_height;
7266 int unit = FRAME_LINE_HEIGHT (f);
7267 struct text_pos start;
7268 struct buffer *old_current_buffer = NULL;
7270 if (current_buffer != XBUFFER (w->buffer))
7272 old_current_buffer = current_buffer;
7273 set_buffer_internal (XBUFFER (w->buffer));
7276 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
7278 /* Compute the max. number of lines specified by the user. */
7279 if (FLOATP (Vmax_mini_window_height))
7280 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
7281 else if (INTEGERP (Vmax_mini_window_height))
7282 max_height = XINT (Vmax_mini_window_height);
7283 else
7284 max_height = total_height / 4;
7286 /* Correct that max. height if it's bogus. */
7287 max_height = max (1, max_height);
7288 max_height = min (total_height, max_height);
7290 /* Find out the height of the text in the window. */
7291 if (it.truncate_lines_p)
7292 height = 1;
7293 else
7295 last_height = 0;
7296 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
7297 if (it.max_ascent == 0 && it.max_descent == 0)
7298 height = it.current_y + last_height;
7299 else
7300 height = it.current_y + it.max_ascent + it.max_descent;
7301 height -= it.extra_line_spacing;
7302 height = (height + unit - 1) / unit;
7305 /* Compute a suitable window start. */
7306 if (height > max_height)
7308 height = max_height;
7309 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
7310 move_it_vertically_backward (&it, (height - 1) * unit);
7311 start = it.current.pos;
7313 else
7314 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
7315 SET_MARKER_FROM_TEXT_POS (w->start, start);
7317 if (EQ (Vresize_mini_windows, Qgrow_only))
7319 /* Let it grow only, until we display an empty message, in which
7320 case the window shrinks again. */
7321 if (height > WINDOW_TOTAL_LINES (w))
7323 int old_height = WINDOW_TOTAL_LINES (w);
7324 freeze_window_starts (f, 1);
7325 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7326 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7328 else if (height < WINDOW_TOTAL_LINES (w)
7329 && (exact_p || BEGV == ZV))
7331 int old_height = WINDOW_TOTAL_LINES (w);
7332 freeze_window_starts (f, 0);
7333 shrink_mini_window (w);
7334 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7337 else
7339 /* Always resize to exact size needed. */
7340 if (height > WINDOW_TOTAL_LINES (w))
7342 int old_height = WINDOW_TOTAL_LINES (w);
7343 freeze_window_starts (f, 1);
7344 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7345 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7347 else if (height < WINDOW_TOTAL_LINES (w))
7349 int old_height = WINDOW_TOTAL_LINES (w);
7350 freeze_window_starts (f, 0);
7351 shrink_mini_window (w);
7353 if (height)
7355 freeze_window_starts (f, 1);
7356 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7359 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7363 if (old_current_buffer)
7364 set_buffer_internal (old_current_buffer);
7367 return window_height_changed_p;
7371 /* Value is the current message, a string, or nil if there is no
7372 current message. */
7374 Lisp_Object
7375 current_message ()
7377 Lisp_Object msg;
7379 if (NILP (echo_area_buffer[0]))
7380 msg = Qnil;
7381 else
7383 with_echo_area_buffer (0, 0, current_message_1,
7384 (EMACS_INT) &msg, Qnil, 0, 0);
7385 if (NILP (msg))
7386 echo_area_buffer[0] = Qnil;
7389 return msg;
7393 static int
7394 current_message_1 (a1, a2, a3, a4)
7395 EMACS_INT a1;
7396 Lisp_Object a2;
7397 EMACS_INT a3, a4;
7399 Lisp_Object *msg = (Lisp_Object *) a1;
7401 if (Z > BEG)
7402 *msg = make_buffer_string (BEG, Z, 1);
7403 else
7404 *msg = Qnil;
7405 return 0;
7409 /* Push the current message on Vmessage_stack for later restauration
7410 by restore_message. Value is non-zero if the current message isn't
7411 empty. This is a relatively infrequent operation, so it's not
7412 worth optimizing. */
7415 push_message ()
7417 Lisp_Object msg;
7418 msg = current_message ();
7419 Vmessage_stack = Fcons (msg, Vmessage_stack);
7420 return STRINGP (msg);
7424 /* Restore message display from the top of Vmessage_stack. */
7426 void
7427 restore_message ()
7429 Lisp_Object msg;
7431 xassert (CONSP (Vmessage_stack));
7432 msg = XCAR (Vmessage_stack);
7433 if (STRINGP (msg))
7434 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
7435 else
7436 message3_nolog (msg, 0, 0);
7440 /* Handler for record_unwind_protect calling pop_message. */
7442 Lisp_Object
7443 pop_message_unwind (dummy)
7444 Lisp_Object dummy;
7446 pop_message ();
7447 return Qnil;
7450 /* Pop the top-most entry off Vmessage_stack. */
7452 void
7453 pop_message ()
7455 xassert (CONSP (Vmessage_stack));
7456 Vmessage_stack = XCDR (Vmessage_stack);
7460 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
7461 exits. If the stack is not empty, we have a missing pop_message
7462 somewhere. */
7464 void
7465 check_message_stack ()
7467 if (!NILP (Vmessage_stack))
7468 abort ();
7472 /* Truncate to NCHARS what will be displayed in the echo area the next
7473 time we display it---but don't redisplay it now. */
7475 void
7476 truncate_echo_area (nchars)
7477 int nchars;
7479 if (nchars == 0)
7480 echo_area_buffer[0] = Qnil;
7481 /* A null message buffer means that the frame hasn't really been
7482 initialized yet. Error messages get reported properly by
7483 cmd_error, so this must be just an informative message; toss it. */
7484 else if (!noninteractive
7485 && INTERACTIVE
7486 && !NILP (echo_area_buffer[0]))
7488 struct frame *sf = SELECTED_FRAME ();
7489 if (FRAME_MESSAGE_BUF (sf))
7490 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
7495 /* Helper function for truncate_echo_area. Truncate the current
7496 message to at most NCHARS characters. */
7498 static int
7499 truncate_message_1 (nchars, a2, a3, a4)
7500 EMACS_INT nchars;
7501 Lisp_Object a2;
7502 EMACS_INT a3, a4;
7504 if (BEG + nchars < Z)
7505 del_range (BEG + nchars, Z);
7506 if (Z == BEG)
7507 echo_area_buffer[0] = Qnil;
7508 return 0;
7512 /* Set the current message to a substring of S or STRING.
7514 If STRING is a Lisp string, set the message to the first NBYTES
7515 bytes from STRING. NBYTES zero means use the whole string. If
7516 STRING is multibyte, the message will be displayed multibyte.
7518 If S is not null, set the message to the first LEN bytes of S. LEN
7519 zero means use the whole string. MULTIBYTE_P non-zero means S is
7520 multibyte. Display the message multibyte in that case. */
7522 void
7523 set_message (s, string, nbytes, multibyte_p)
7524 const char *s;
7525 Lisp_Object string;
7526 int nbytes, multibyte_p;
7528 message_enable_multibyte
7529 = ((s && multibyte_p)
7530 || (STRINGP (string) && STRING_MULTIBYTE (string)));
7532 with_echo_area_buffer (0, -1, set_message_1,
7533 (EMACS_INT) s, string, nbytes, multibyte_p);
7534 message_buf_print = 0;
7535 help_echo_showing_p = 0;
7539 /* Helper function for set_message. Arguments have the same meaning
7540 as there, with A1 corresponding to S and A2 corresponding to STRING
7541 This function is called with the echo area buffer being
7542 current. */
7544 static int
7545 set_message_1 (a1, a2, nbytes, multibyte_p)
7546 EMACS_INT a1;
7547 Lisp_Object a2;
7548 EMACS_INT nbytes, multibyte_p;
7550 const char *s = (const char *) a1;
7551 Lisp_Object string = a2;
7553 xassert (BEG == Z);
7555 /* Change multibyteness of the echo buffer appropriately. */
7556 if (message_enable_multibyte
7557 != !NILP (current_buffer->enable_multibyte_characters))
7558 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
7560 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
7562 /* Insert new message at BEG. */
7563 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7565 if (STRINGP (string))
7567 int nchars;
7569 if (nbytes == 0)
7570 nbytes = SBYTES (string);
7571 nchars = string_byte_to_char (string, nbytes);
7573 /* This function takes care of single/multibyte conversion. We
7574 just have to ensure that the echo area buffer has the right
7575 setting of enable_multibyte_characters. */
7576 insert_from_string (string, 0, 0, nchars, nbytes, 1);
7578 else if (s)
7580 if (nbytes == 0)
7581 nbytes = strlen (s);
7583 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
7585 /* Convert from multi-byte to single-byte. */
7586 int i, c, n;
7587 unsigned char work[1];
7589 /* Convert a multibyte string to single-byte. */
7590 for (i = 0; i < nbytes; i += n)
7592 c = string_char_and_length (s + i, nbytes - i, &n);
7593 work[0] = (SINGLE_BYTE_CHAR_P (c)
7595 : multibyte_char_to_unibyte (c, Qnil));
7596 insert_1_both (work, 1, 1, 1, 0, 0);
7599 else if (!multibyte_p
7600 && !NILP (current_buffer->enable_multibyte_characters))
7602 /* Convert from single-byte to multi-byte. */
7603 int i, c, n;
7604 const unsigned char *msg = (const unsigned char *) s;
7605 unsigned char str[MAX_MULTIBYTE_LENGTH];
7607 /* Convert a single-byte string to multibyte. */
7608 for (i = 0; i < nbytes; i++)
7610 c = unibyte_char_to_multibyte (msg[i]);
7611 n = CHAR_STRING (c, str);
7612 insert_1_both (str, 1, n, 1, 0, 0);
7615 else
7616 insert_1 (s, nbytes, 1, 0, 0);
7619 return 0;
7623 /* Clear messages. CURRENT_P non-zero means clear the current
7624 message. LAST_DISPLAYED_P non-zero means clear the message
7625 last displayed. */
7627 void
7628 clear_message (current_p, last_displayed_p)
7629 int current_p, last_displayed_p;
7631 if (current_p)
7633 echo_area_buffer[0] = Qnil;
7634 message_cleared_p = 1;
7637 if (last_displayed_p)
7638 echo_area_buffer[1] = Qnil;
7640 message_buf_print = 0;
7643 /* Clear garbaged frames.
7645 This function is used where the old redisplay called
7646 redraw_garbaged_frames which in turn called redraw_frame which in
7647 turn called clear_frame. The call to clear_frame was a source of
7648 flickering. I believe a clear_frame is not necessary. It should
7649 suffice in the new redisplay to invalidate all current matrices,
7650 and ensure a complete redisplay of all windows. */
7652 static void
7653 clear_garbaged_frames ()
7655 if (frame_garbaged)
7657 Lisp_Object tail, frame;
7658 int changed_count = 0;
7660 FOR_EACH_FRAME (tail, frame)
7662 struct frame *f = XFRAME (frame);
7664 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
7666 if (f->resized_p)
7668 Fredraw_frame (frame);
7669 f->force_flush_display_p = 1;
7671 clear_current_matrices (f);
7672 changed_count++;
7673 f->garbaged = 0;
7674 f->resized_p = 0;
7678 frame_garbaged = 0;
7679 if (changed_count)
7680 ++windows_or_buffers_changed;
7685 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
7686 is non-zero update selected_frame. Value is non-zero if the
7687 mini-windows height has been changed. */
7689 static int
7690 echo_area_display (update_frame_p)
7691 int update_frame_p;
7693 Lisp_Object mini_window;
7694 struct window *w;
7695 struct frame *f;
7696 int window_height_changed_p = 0;
7697 struct frame *sf = SELECTED_FRAME ();
7699 mini_window = FRAME_MINIBUF_WINDOW (sf);
7700 w = XWINDOW (mini_window);
7701 f = XFRAME (WINDOW_FRAME (w));
7703 /* Don't display if frame is invisible or not yet initialized. */
7704 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
7705 return 0;
7707 /* The terminal frame is used as the first Emacs frame on the Mac OS. */
7708 #ifndef MAC_OS8
7709 #ifdef HAVE_WINDOW_SYSTEM
7710 /* When Emacs starts, selected_frame may be a visible terminal
7711 frame, even if we run under a window system. If we let this
7712 through, a message would be displayed on the terminal. */
7713 if (EQ (selected_frame, Vterminal_frame)
7714 && !NILP (Vwindow_system))
7715 return 0;
7716 #endif /* HAVE_WINDOW_SYSTEM */
7717 #endif
7719 /* Redraw garbaged frames. */
7720 if (frame_garbaged)
7721 clear_garbaged_frames ();
7723 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
7725 echo_area_window = mini_window;
7726 window_height_changed_p = display_echo_area (w);
7727 w->must_be_updated_p = 1;
7729 /* Update the display, unless called from redisplay_internal.
7730 Also don't update the screen during redisplay itself. The
7731 update will happen at the end of redisplay, and an update
7732 here could cause confusion. */
7733 if (update_frame_p && !redisplaying_p)
7735 int n = 0;
7737 /* If the display update has been interrupted by pending
7738 input, update mode lines in the frame. Due to the
7739 pending input, it might have been that redisplay hasn't
7740 been called, so that mode lines above the echo area are
7741 garbaged. This looks odd, so we prevent it here. */
7742 if (!display_completed)
7743 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
7745 if (window_height_changed_p
7746 /* Don't do this if Emacs is shutting down. Redisplay
7747 needs to run hooks. */
7748 && !NILP (Vrun_hooks))
7750 /* Must update other windows. Likewise as in other
7751 cases, don't let this update be interrupted by
7752 pending input. */
7753 int count = SPECPDL_INDEX ();
7754 specbind (Qredisplay_dont_pause, Qt);
7755 windows_or_buffers_changed = 1;
7756 redisplay_internal (0);
7757 unbind_to (count, Qnil);
7759 else if (FRAME_WINDOW_P (f) && n == 0)
7761 /* Window configuration is the same as before.
7762 Can do with a display update of the echo area,
7763 unless we displayed some mode lines. */
7764 update_single_window (w, 1);
7765 rif->flush_display (f);
7767 else
7768 update_frame (f, 1, 1);
7770 /* If cursor is in the echo area, make sure that the next
7771 redisplay displays the minibuffer, so that the cursor will
7772 be replaced with what the minibuffer wants. */
7773 if (cursor_in_echo_area)
7774 ++windows_or_buffers_changed;
7777 else if (!EQ (mini_window, selected_window))
7778 windows_or_buffers_changed++;
7780 /* Last displayed message is now the current message. */
7781 echo_area_buffer[1] = echo_area_buffer[0];
7783 /* Prevent redisplay optimization in redisplay_internal by resetting
7784 this_line_start_pos. This is done because the mini-buffer now
7785 displays the message instead of its buffer text. */
7786 if (EQ (mini_window, selected_window))
7787 CHARPOS (this_line_start_pos) = 0;
7789 return window_height_changed_p;
7794 /***********************************************************************
7795 Frame Titles
7796 ***********************************************************************/
7799 /* The frame title buffering code is also used by Fformat_mode_line.
7800 So it is not conditioned by HAVE_WINDOW_SYSTEM. */
7802 /* A buffer for constructing frame titles in it; allocated from the
7803 heap in init_xdisp and resized as needed in store_frame_title_char. */
7805 static char *frame_title_buf;
7807 /* The buffer's end, and a current output position in it. */
7809 static char *frame_title_buf_end;
7810 static char *frame_title_ptr;
7813 /* Store a single character C for the frame title in frame_title_buf.
7814 Re-allocate frame_title_buf if necessary. */
7816 static void
7817 #ifdef PROTOTYPES
7818 store_frame_title_char (char c)
7819 #else
7820 store_frame_title_char (c)
7821 char c;
7822 #endif
7824 /* If output position has reached the end of the allocated buffer,
7825 double the buffer's size. */
7826 if (frame_title_ptr == frame_title_buf_end)
7828 int len = frame_title_ptr - frame_title_buf;
7829 int new_size = 2 * len * sizeof *frame_title_buf;
7830 frame_title_buf = (char *) xrealloc (frame_title_buf, new_size);
7831 frame_title_buf_end = frame_title_buf + new_size;
7832 frame_title_ptr = frame_title_buf + len;
7835 *frame_title_ptr++ = c;
7839 /* Store part of a frame title in frame_title_buf, beginning at
7840 frame_title_ptr. STR is the string to store. Do not copy
7841 characters that yield more columns than PRECISION; PRECISION <= 0
7842 means copy the whole string. Pad with spaces until FIELD_WIDTH
7843 number of characters have been copied; FIELD_WIDTH <= 0 means don't
7844 pad. Called from display_mode_element when it is used to build a
7845 frame title. */
7847 static int
7848 store_frame_title (str, field_width, precision)
7849 const unsigned char *str;
7850 int field_width, precision;
7852 int n = 0;
7853 int dummy, nbytes;
7855 /* Copy at most PRECISION chars from STR. */
7856 nbytes = strlen (str);
7857 n+= c_string_width (str, nbytes, precision, &dummy, &nbytes);
7858 while (nbytes--)
7859 store_frame_title_char (*str++);
7861 /* Fill up with spaces until FIELD_WIDTH reached. */
7862 while (field_width > 0
7863 && n < field_width)
7865 store_frame_title_char (' ');
7866 ++n;
7869 return n;
7872 #ifdef HAVE_WINDOW_SYSTEM
7874 /* Set the title of FRAME, if it has changed. The title format is
7875 Vicon_title_format if FRAME is iconified, otherwise it is
7876 frame_title_format. */
7878 static void
7879 x_consider_frame_title (frame)
7880 Lisp_Object frame;
7882 struct frame *f = XFRAME (frame);
7884 if (FRAME_WINDOW_P (f)
7885 || FRAME_MINIBUF_ONLY_P (f)
7886 || f->explicit_name)
7888 /* Do we have more than one visible frame on this X display? */
7889 Lisp_Object tail;
7890 Lisp_Object fmt;
7891 struct buffer *obuf;
7892 int len;
7893 struct it it;
7895 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
7897 Lisp_Object other_frame = XCAR (tail);
7898 struct frame *tf = XFRAME (other_frame);
7900 if (tf != f
7901 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
7902 && !FRAME_MINIBUF_ONLY_P (tf)
7903 && !EQ (other_frame, tip_frame)
7904 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
7905 break;
7908 /* Set global variable indicating that multiple frames exist. */
7909 multiple_frames = CONSP (tail);
7911 /* Switch to the buffer of selected window of the frame. Set up
7912 frame_title_ptr so that display_mode_element will output into it;
7913 then display the title. */
7914 obuf = current_buffer;
7915 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
7916 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
7917 frame_title_ptr = frame_title_buf;
7918 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
7919 NULL, DEFAULT_FACE_ID);
7920 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
7921 len = frame_title_ptr - frame_title_buf;
7922 frame_title_ptr = NULL;
7923 set_buffer_internal_1 (obuf);
7925 /* Set the title only if it's changed. This avoids consing in
7926 the common case where it hasn't. (If it turns out that we've
7927 already wasted too much time by walking through the list with
7928 display_mode_element, then we might need to optimize at a
7929 higher level than this.) */
7930 if (! STRINGP (f->name)
7931 || SBYTES (f->name) != len
7932 || bcmp (frame_title_buf, SDATA (f->name), len) != 0)
7933 x_implicitly_set_name (f, make_string (frame_title_buf, len), Qnil);
7937 #endif /* not HAVE_WINDOW_SYSTEM */
7942 /***********************************************************************
7943 Menu Bars
7944 ***********************************************************************/
7947 /* Prepare for redisplay by updating menu-bar item lists when
7948 appropriate. This can call eval. */
7950 void
7951 prepare_menu_bars ()
7953 int all_windows;
7954 struct gcpro gcpro1, gcpro2;
7955 struct frame *f;
7956 Lisp_Object tooltip_frame;
7958 #ifdef HAVE_WINDOW_SYSTEM
7959 tooltip_frame = tip_frame;
7960 #else
7961 tooltip_frame = Qnil;
7962 #endif
7964 /* Update all frame titles based on their buffer names, etc. We do
7965 this before the menu bars so that the buffer-menu will show the
7966 up-to-date frame titles. */
7967 #ifdef HAVE_WINDOW_SYSTEM
7968 if (windows_or_buffers_changed || update_mode_lines)
7970 Lisp_Object tail, frame;
7972 FOR_EACH_FRAME (tail, frame)
7974 f = XFRAME (frame);
7975 if (!EQ (frame, tooltip_frame)
7976 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
7977 x_consider_frame_title (frame);
7980 #endif /* HAVE_WINDOW_SYSTEM */
7982 /* Update the menu bar item lists, if appropriate. This has to be
7983 done before any actual redisplay or generation of display lines. */
7984 all_windows = (update_mode_lines
7985 || buffer_shared > 1
7986 || windows_or_buffers_changed);
7987 if (all_windows)
7989 Lisp_Object tail, frame;
7990 int count = SPECPDL_INDEX ();
7992 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
7994 FOR_EACH_FRAME (tail, frame)
7996 f = XFRAME (frame);
7998 /* Ignore tooltip frame. */
7999 if (EQ (frame, tooltip_frame))
8000 continue;
8002 /* If a window on this frame changed size, report that to
8003 the user and clear the size-change flag. */
8004 if (FRAME_WINDOW_SIZES_CHANGED (f))
8006 Lisp_Object functions;
8008 /* Clear flag first in case we get an error below. */
8009 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
8010 functions = Vwindow_size_change_functions;
8011 GCPRO2 (tail, functions);
8013 while (CONSP (functions))
8015 call1 (XCAR (functions), frame);
8016 functions = XCDR (functions);
8018 UNGCPRO;
8021 GCPRO1 (tail);
8022 update_menu_bar (f, 0);
8023 #ifdef HAVE_WINDOW_SYSTEM
8024 update_tool_bar (f, 0);
8025 #endif
8026 UNGCPRO;
8029 unbind_to (count, Qnil);
8031 else
8033 struct frame *sf = SELECTED_FRAME ();
8034 update_menu_bar (sf, 1);
8035 #ifdef HAVE_WINDOW_SYSTEM
8036 update_tool_bar (sf, 1);
8037 #endif
8040 /* Motif needs this. See comment in xmenu.c. Turn it off when
8041 pending_menu_activation is not defined. */
8042 #ifdef USE_X_TOOLKIT
8043 pending_menu_activation = 0;
8044 #endif
8048 /* Update the menu bar item list for frame F. This has to be done
8049 before we start to fill in any display lines, because it can call
8050 eval.
8052 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
8054 static void
8055 update_menu_bar (f, save_match_data)
8056 struct frame *f;
8057 int save_match_data;
8059 Lisp_Object window;
8060 register struct window *w;
8062 /* If called recursively during a menu update, do nothing. This can
8063 happen when, for instance, an activate-menubar-hook causes a
8064 redisplay. */
8065 if (inhibit_menubar_update)
8066 return;
8068 window = FRAME_SELECTED_WINDOW (f);
8069 w = XWINDOW (window);
8071 #if 0 /* The if statement below this if statement used to include the
8072 condition !NILP (w->update_mode_line), rather than using
8073 update_mode_lines directly, and this if statement may have
8074 been added to make that condition work. Now the if
8075 statement below matches its comment, this isn't needed. */
8076 if (update_mode_lines)
8077 w->update_mode_line = Qt;
8078 #endif
8080 if (FRAME_WINDOW_P (f)
8082 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8083 || defined (USE_GTK)
8084 FRAME_EXTERNAL_MENU_BAR (f)
8085 #else
8086 FRAME_MENU_BAR_LINES (f) > 0
8087 #endif
8088 : FRAME_MENU_BAR_LINES (f) > 0)
8090 /* If the user has switched buffers or windows, we need to
8091 recompute to reflect the new bindings. But we'll
8092 recompute when update_mode_lines is set too; that means
8093 that people can use force-mode-line-update to request
8094 that the menu bar be recomputed. The adverse effect on
8095 the rest of the redisplay algorithm is about the same as
8096 windows_or_buffers_changed anyway. */
8097 if (windows_or_buffers_changed
8098 /* This used to test w->update_mode_line, but we believe
8099 there is no need to recompute the menu in that case. */
8100 || update_mode_lines
8101 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8102 < BUF_MODIFF (XBUFFER (w->buffer)))
8103 != !NILP (w->last_had_star))
8104 || ((!NILP (Vtransient_mark_mode)
8105 && !NILP (XBUFFER (w->buffer)->mark_active))
8106 != !NILP (w->region_showing)))
8108 struct buffer *prev = current_buffer;
8109 int count = SPECPDL_INDEX ();
8111 specbind (Qinhibit_menubar_update, Qt);
8113 set_buffer_internal_1 (XBUFFER (w->buffer));
8114 if (save_match_data)
8115 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8116 if (NILP (Voverriding_local_map_menu_flag))
8118 specbind (Qoverriding_terminal_local_map, Qnil);
8119 specbind (Qoverriding_local_map, Qnil);
8122 /* Run the Lucid hook. */
8123 safe_run_hooks (Qactivate_menubar_hook);
8125 /* If it has changed current-menubar from previous value,
8126 really recompute the menu-bar from the value. */
8127 if (! NILP (Vlucid_menu_bar_dirty_flag))
8128 call0 (Qrecompute_lucid_menubar);
8130 safe_run_hooks (Qmenu_bar_update_hook);
8131 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
8133 /* Redisplay the menu bar in case we changed it. */
8134 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8135 || defined (USE_GTK)
8136 if (FRAME_WINDOW_P (f)
8137 #if defined (MAC_OS)
8138 /* All frames on Mac OS share the same menubar. So only the
8139 selected frame should be allowed to set it. */
8140 && f == SELECTED_FRAME ()
8141 #endif
8143 set_frame_menubar (f, 0, 0);
8144 else
8145 /* On a terminal screen, the menu bar is an ordinary screen
8146 line, and this makes it get updated. */
8147 w->update_mode_line = Qt;
8148 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8149 /* In the non-toolkit version, the menu bar is an ordinary screen
8150 line, and this makes it get updated. */
8151 w->update_mode_line = Qt;
8152 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8154 unbind_to (count, Qnil);
8155 set_buffer_internal_1 (prev);
8162 /***********************************************************************
8163 Output Cursor
8164 ***********************************************************************/
8166 #ifdef HAVE_WINDOW_SYSTEM
8168 /* EXPORT:
8169 Nominal cursor position -- where to draw output.
8170 HPOS and VPOS are window relative glyph matrix coordinates.
8171 X and Y are window relative pixel coordinates. */
8173 struct cursor_pos output_cursor;
8176 /* EXPORT:
8177 Set the global variable output_cursor to CURSOR. All cursor
8178 positions are relative to updated_window. */
8180 void
8181 set_output_cursor (cursor)
8182 struct cursor_pos *cursor;
8184 output_cursor.hpos = cursor->hpos;
8185 output_cursor.vpos = cursor->vpos;
8186 output_cursor.x = cursor->x;
8187 output_cursor.y = cursor->y;
8191 /* EXPORT for RIF:
8192 Set a nominal cursor position.
8194 HPOS and VPOS are column/row positions in a window glyph matrix. X
8195 and Y are window text area relative pixel positions.
8197 If this is done during an update, updated_window will contain the
8198 window that is being updated and the position is the future output
8199 cursor position for that window. If updated_window is null, use
8200 selected_window and display the cursor at the given position. */
8202 void
8203 x_cursor_to (vpos, hpos, y, x)
8204 int vpos, hpos, y, x;
8206 struct window *w;
8208 /* If updated_window is not set, work on selected_window. */
8209 if (updated_window)
8210 w = updated_window;
8211 else
8212 w = XWINDOW (selected_window);
8214 /* Set the output cursor. */
8215 output_cursor.hpos = hpos;
8216 output_cursor.vpos = vpos;
8217 output_cursor.x = x;
8218 output_cursor.y = y;
8220 /* If not called as part of an update, really display the cursor.
8221 This will also set the cursor position of W. */
8222 if (updated_window == NULL)
8224 BLOCK_INPUT;
8225 display_and_set_cursor (w, 1, hpos, vpos, x, y);
8226 if (rif->flush_display_optional)
8227 rif->flush_display_optional (SELECTED_FRAME ());
8228 UNBLOCK_INPUT;
8232 #endif /* HAVE_WINDOW_SYSTEM */
8235 /***********************************************************************
8236 Tool-bars
8237 ***********************************************************************/
8239 #ifdef HAVE_WINDOW_SYSTEM
8241 /* Where the mouse was last time we reported a mouse event. */
8243 FRAME_PTR last_mouse_frame;
8245 /* Tool-bar item index of the item on which a mouse button was pressed
8246 or -1. */
8248 int last_tool_bar_item;
8251 /* Update the tool-bar item list for frame F. This has to be done
8252 before we start to fill in any display lines. Called from
8253 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
8254 and restore it here. */
8256 static void
8257 update_tool_bar (f, save_match_data)
8258 struct frame *f;
8259 int save_match_data;
8261 #ifdef USE_GTK
8262 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
8263 #else
8264 int do_update = WINDOWP (f->tool_bar_window)
8265 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
8266 #endif
8268 if (do_update)
8270 Lisp_Object window;
8271 struct window *w;
8273 window = FRAME_SELECTED_WINDOW (f);
8274 w = XWINDOW (window);
8276 /* If the user has switched buffers or windows, we need to
8277 recompute to reflect the new bindings. But we'll
8278 recompute when update_mode_lines is set too; that means
8279 that people can use force-mode-line-update to request
8280 that the menu bar be recomputed. The adverse effect on
8281 the rest of the redisplay algorithm is about the same as
8282 windows_or_buffers_changed anyway. */
8283 if (windows_or_buffers_changed
8284 || !NILP (w->update_mode_line)
8285 || update_mode_lines
8286 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8287 < BUF_MODIFF (XBUFFER (w->buffer)))
8288 != !NILP (w->last_had_star))
8289 || ((!NILP (Vtransient_mark_mode)
8290 && !NILP (XBUFFER (w->buffer)->mark_active))
8291 != !NILP (w->region_showing)))
8293 struct buffer *prev = current_buffer;
8294 int count = SPECPDL_INDEX ();
8295 Lisp_Object old_tool_bar;
8296 struct gcpro gcpro1;
8298 /* Set current_buffer to the buffer of the selected
8299 window of the frame, so that we get the right local
8300 keymaps. */
8301 set_buffer_internal_1 (XBUFFER (w->buffer));
8303 /* Save match data, if we must. */
8304 if (save_match_data)
8305 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8307 /* Make sure that we don't accidentally use bogus keymaps. */
8308 if (NILP (Voverriding_local_map_menu_flag))
8310 specbind (Qoverriding_terminal_local_map, Qnil);
8311 specbind (Qoverriding_local_map, Qnil);
8314 old_tool_bar = f->tool_bar_items;
8315 GCPRO1 (old_tool_bar);
8317 /* Build desired tool-bar items from keymaps. */
8318 BLOCK_INPUT;
8319 f->tool_bar_items
8320 = tool_bar_items (f->tool_bar_items, &f->n_tool_bar_items);
8321 UNBLOCK_INPUT;
8323 /* Redisplay the tool-bar if we changed it. */
8324 if (! NILP (Fequal (old_tool_bar, f->tool_bar_items)))
8325 w->update_mode_line = Qt;
8327 UNGCPRO;
8329 unbind_to (count, Qnil);
8330 set_buffer_internal_1 (prev);
8336 /* Set F->desired_tool_bar_string to a Lisp string representing frame
8337 F's desired tool-bar contents. F->tool_bar_items must have
8338 been set up previously by calling prepare_menu_bars. */
8340 static void
8341 build_desired_tool_bar_string (f)
8342 struct frame *f;
8344 int i, size, size_needed;
8345 struct gcpro gcpro1, gcpro2, gcpro3;
8346 Lisp_Object image, plist, props;
8348 image = plist = props = Qnil;
8349 GCPRO3 (image, plist, props);
8351 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
8352 Otherwise, make a new string. */
8354 /* The size of the string we might be able to reuse. */
8355 size = (STRINGP (f->desired_tool_bar_string)
8356 ? SCHARS (f->desired_tool_bar_string)
8357 : 0);
8359 /* We need one space in the string for each image. */
8360 size_needed = f->n_tool_bar_items;
8362 /* Reuse f->desired_tool_bar_string, if possible. */
8363 if (size < size_needed || NILP (f->desired_tool_bar_string))
8364 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
8365 make_number (' '));
8366 else
8368 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
8369 Fremove_text_properties (make_number (0), make_number (size),
8370 props, f->desired_tool_bar_string);
8373 /* Put a `display' property on the string for the images to display,
8374 put a `menu_item' property on tool-bar items with a value that
8375 is the index of the item in F's tool-bar item vector. */
8376 for (i = 0; i < f->n_tool_bar_items; ++i)
8378 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
8380 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
8381 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
8382 int hmargin, vmargin, relief, idx, end;
8383 extern Lisp_Object QCrelief, QCmargin, QCconversion;
8385 /* If image is a vector, choose the image according to the
8386 button state. */
8387 image = PROP (TOOL_BAR_ITEM_IMAGES);
8388 if (VECTORP (image))
8390 if (enabled_p)
8391 idx = (selected_p
8392 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
8393 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
8394 else
8395 idx = (selected_p
8396 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
8397 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
8399 xassert (ASIZE (image) >= idx);
8400 image = AREF (image, idx);
8402 else
8403 idx = -1;
8405 /* Ignore invalid image specifications. */
8406 if (!valid_image_p (image))
8407 continue;
8409 /* Display the tool-bar button pressed, or depressed. */
8410 plist = Fcopy_sequence (XCDR (image));
8412 /* Compute margin and relief to draw. */
8413 relief = (tool_bar_button_relief >= 0
8414 ? tool_bar_button_relief
8415 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
8416 hmargin = vmargin = relief;
8418 if (INTEGERP (Vtool_bar_button_margin)
8419 && XINT (Vtool_bar_button_margin) > 0)
8421 hmargin += XFASTINT (Vtool_bar_button_margin);
8422 vmargin += XFASTINT (Vtool_bar_button_margin);
8424 else if (CONSP (Vtool_bar_button_margin))
8426 if (INTEGERP (XCAR (Vtool_bar_button_margin))
8427 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
8428 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
8430 if (INTEGERP (XCDR (Vtool_bar_button_margin))
8431 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
8432 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
8435 if (auto_raise_tool_bar_buttons_p)
8437 /* Add a `:relief' property to the image spec if the item is
8438 selected. */
8439 if (selected_p)
8441 plist = Fplist_put (plist, QCrelief, make_number (-relief));
8442 hmargin -= relief;
8443 vmargin -= relief;
8446 else
8448 /* If image is selected, display it pressed, i.e. with a
8449 negative relief. If it's not selected, display it with a
8450 raised relief. */
8451 plist = Fplist_put (plist, QCrelief,
8452 (selected_p
8453 ? make_number (-relief)
8454 : make_number (relief)));
8455 hmargin -= relief;
8456 vmargin -= relief;
8459 /* Put a margin around the image. */
8460 if (hmargin || vmargin)
8462 if (hmargin == vmargin)
8463 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
8464 else
8465 plist = Fplist_put (plist, QCmargin,
8466 Fcons (make_number (hmargin),
8467 make_number (vmargin)));
8470 /* If button is not enabled, and we don't have special images
8471 for the disabled state, make the image appear disabled by
8472 applying an appropriate algorithm to it. */
8473 if (!enabled_p && idx < 0)
8474 plist = Fplist_put (plist, QCconversion, Qdisabled);
8476 /* Put a `display' text property on the string for the image to
8477 display. Put a `menu-item' property on the string that gives
8478 the start of this item's properties in the tool-bar items
8479 vector. */
8480 image = Fcons (Qimage, plist);
8481 props = list4 (Qdisplay, image,
8482 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
8484 /* Let the last image hide all remaining spaces in the tool bar
8485 string. The string can be longer than needed when we reuse a
8486 previous string. */
8487 if (i + 1 == f->n_tool_bar_items)
8488 end = SCHARS (f->desired_tool_bar_string);
8489 else
8490 end = i + 1;
8491 Fadd_text_properties (make_number (i), make_number (end),
8492 props, f->desired_tool_bar_string);
8493 #undef PROP
8496 UNGCPRO;
8500 /* Display one line of the tool-bar of frame IT->f. */
8502 static void
8503 display_tool_bar_line (it)
8504 struct it *it;
8506 struct glyph_row *row = it->glyph_row;
8507 int max_x = it->last_visible_x;
8508 struct glyph *last;
8510 prepare_desired_row (row);
8511 row->y = it->current_y;
8513 /* Note that this isn't made use of if the face hasn't a box,
8514 so there's no need to check the face here. */
8515 it->start_of_box_run_p = 1;
8517 while (it->current_x < max_x)
8519 int x_before, x, n_glyphs_before, i, nglyphs;
8521 /* Get the next display element. */
8522 if (!get_next_display_element (it))
8523 break;
8525 /* Produce glyphs. */
8526 x_before = it->current_x;
8527 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
8528 PRODUCE_GLYPHS (it);
8530 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
8531 i = 0;
8532 x = x_before;
8533 while (i < nglyphs)
8535 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
8537 if (x + glyph->pixel_width > max_x)
8539 /* Glyph doesn't fit on line. */
8540 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
8541 it->current_x = x;
8542 goto out;
8545 ++it->hpos;
8546 x += glyph->pixel_width;
8547 ++i;
8550 /* Stop at line ends. */
8551 if (ITERATOR_AT_END_OF_LINE_P (it))
8552 break;
8554 set_iterator_to_next (it, 1);
8557 out:;
8559 row->displays_text_p = row->used[TEXT_AREA] != 0;
8560 extend_face_to_end_of_line (it);
8561 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
8562 last->right_box_line_p = 1;
8563 if (last == row->glyphs[TEXT_AREA])
8564 last->left_box_line_p = 1;
8565 compute_line_metrics (it);
8567 /* If line is empty, make it occupy the rest of the tool-bar. */
8568 if (!row->displays_text_p)
8570 row->height = row->phys_height = it->last_visible_y - row->y;
8571 row->ascent = row->phys_ascent = 0;
8574 row->full_width_p = 1;
8575 row->continued_p = 0;
8576 row->truncated_on_left_p = 0;
8577 row->truncated_on_right_p = 0;
8579 it->current_x = it->hpos = 0;
8580 it->current_y += row->height;
8581 ++it->vpos;
8582 ++it->glyph_row;
8586 /* Value is the number of screen lines needed to make all tool-bar
8587 items of frame F visible. */
8589 static int
8590 tool_bar_lines_needed (f)
8591 struct frame *f;
8593 struct window *w = XWINDOW (f->tool_bar_window);
8594 struct it it;
8596 /* Initialize an iterator for iteration over
8597 F->desired_tool_bar_string in the tool-bar window of frame F. */
8598 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8599 it.first_visible_x = 0;
8600 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8601 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8603 while (!ITERATOR_AT_END_P (&it))
8605 it.glyph_row = w->desired_matrix->rows;
8606 clear_glyph_row (it.glyph_row);
8607 display_tool_bar_line (&it);
8610 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
8614 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
8615 0, 1, 0,
8616 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
8617 (frame)
8618 Lisp_Object frame;
8620 struct frame *f;
8621 struct window *w;
8622 int nlines = 0;
8624 if (NILP (frame))
8625 frame = selected_frame;
8626 else
8627 CHECK_FRAME (frame);
8628 f = XFRAME (frame);
8630 if (WINDOWP (f->tool_bar_window)
8631 || (w = XWINDOW (f->tool_bar_window),
8632 WINDOW_TOTAL_LINES (w) > 0))
8634 update_tool_bar (f, 1);
8635 if (f->n_tool_bar_items)
8637 build_desired_tool_bar_string (f);
8638 nlines = tool_bar_lines_needed (f);
8642 return make_number (nlines);
8646 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
8647 height should be changed. */
8649 static int
8650 redisplay_tool_bar (f)
8651 struct frame *f;
8653 struct window *w;
8654 struct it it;
8655 struct glyph_row *row;
8656 int change_height_p = 0;
8658 #ifdef USE_GTK
8659 if (FRAME_EXTERNAL_TOOL_BAR (f))
8660 update_frame_tool_bar (f);
8661 return 0;
8662 #endif
8664 /* If frame hasn't a tool-bar window or if it is zero-height, don't
8665 do anything. This means you must start with tool-bar-lines
8666 non-zero to get the auto-sizing effect. Or in other words, you
8667 can turn off tool-bars by specifying tool-bar-lines zero. */
8668 if (!WINDOWP (f->tool_bar_window)
8669 || (w = XWINDOW (f->tool_bar_window),
8670 WINDOW_TOTAL_LINES (w) == 0))
8671 return 0;
8673 /* Set up an iterator for the tool-bar window. */
8674 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8675 it.first_visible_x = 0;
8676 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8677 row = it.glyph_row;
8679 /* Build a string that represents the contents of the tool-bar. */
8680 build_desired_tool_bar_string (f);
8681 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8683 /* Display as many lines as needed to display all tool-bar items. */
8684 while (it.current_y < it.last_visible_y)
8685 display_tool_bar_line (&it);
8687 /* It doesn't make much sense to try scrolling in the tool-bar
8688 window, so don't do it. */
8689 w->desired_matrix->no_scrolling_p = 1;
8690 w->must_be_updated_p = 1;
8692 if (auto_resize_tool_bars_p)
8694 int nlines;
8696 /* If we couldn't display everything, change the tool-bar's
8697 height. */
8698 if (IT_STRING_CHARPOS (it) < it.end_charpos)
8699 change_height_p = 1;
8701 /* If there are blank lines at the end, except for a partially
8702 visible blank line at the end that is smaller than
8703 FRAME_LINE_HEIGHT, change the tool-bar's height. */
8704 row = it.glyph_row - 1;
8705 if (!row->displays_text_p
8706 && row->height >= FRAME_LINE_HEIGHT (f))
8707 change_height_p = 1;
8709 /* If row displays tool-bar items, but is partially visible,
8710 change the tool-bar's height. */
8711 if (row->displays_text_p
8712 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
8713 change_height_p = 1;
8715 /* Resize windows as needed by changing the `tool-bar-lines'
8716 frame parameter. */
8717 if (change_height_p
8718 && (nlines = tool_bar_lines_needed (f),
8719 nlines != WINDOW_TOTAL_LINES (w)))
8721 extern Lisp_Object Qtool_bar_lines;
8722 Lisp_Object frame;
8723 int old_height = WINDOW_TOTAL_LINES (w);
8725 XSETFRAME (frame, f);
8726 clear_glyph_matrix (w->desired_matrix);
8727 Fmodify_frame_parameters (frame,
8728 Fcons (Fcons (Qtool_bar_lines,
8729 make_number (nlines)),
8730 Qnil));
8731 if (WINDOW_TOTAL_LINES (w) != old_height)
8732 fonts_changed_p = 1;
8736 return change_height_p;
8740 /* Get information about the tool-bar item which is displayed in GLYPH
8741 on frame F. Return in *PROP_IDX the index where tool-bar item
8742 properties start in F->tool_bar_items. Value is zero if
8743 GLYPH doesn't display a tool-bar item. */
8745 static int
8746 tool_bar_item_info (f, glyph, prop_idx)
8747 struct frame *f;
8748 struct glyph *glyph;
8749 int *prop_idx;
8751 Lisp_Object prop;
8752 int success_p;
8753 int charpos;
8755 /* This function can be called asynchronously, which means we must
8756 exclude any possibility that Fget_text_property signals an
8757 error. */
8758 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
8759 charpos = max (0, charpos);
8761 /* Get the text property `menu-item' at pos. The value of that
8762 property is the start index of this item's properties in
8763 F->tool_bar_items. */
8764 prop = Fget_text_property (make_number (charpos),
8765 Qmenu_item, f->current_tool_bar_string);
8766 if (INTEGERP (prop))
8768 *prop_idx = XINT (prop);
8769 success_p = 1;
8771 else
8772 success_p = 0;
8774 return success_p;
8778 /* Get information about the tool-bar item at position X/Y on frame F.
8779 Return in *GLYPH a pointer to the glyph of the tool-bar item in
8780 the current matrix of the tool-bar window of F, or NULL if not
8781 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
8782 item in F->tool_bar_items. Value is
8784 -1 if X/Y is not on a tool-bar item
8785 0 if X/Y is on the same item that was highlighted before.
8786 1 otherwise. */
8788 static int
8789 get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
8790 struct frame *f;
8791 int x, y;
8792 struct glyph **glyph;
8793 int *hpos, *vpos, *prop_idx;
8795 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8796 struct window *w = XWINDOW (f->tool_bar_window);
8797 int area;
8799 /* Find the glyph under X/Y. */
8800 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
8801 if (*glyph == NULL)
8802 return -1;
8804 /* Get the start of this tool-bar item's properties in
8805 f->tool_bar_items. */
8806 if (!tool_bar_item_info (f, *glyph, prop_idx))
8807 return -1;
8809 /* Is mouse on the highlighted item? */
8810 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
8811 && *vpos >= dpyinfo->mouse_face_beg_row
8812 && *vpos <= dpyinfo->mouse_face_end_row
8813 && (*vpos > dpyinfo->mouse_face_beg_row
8814 || *hpos >= dpyinfo->mouse_face_beg_col)
8815 && (*vpos < dpyinfo->mouse_face_end_row
8816 || *hpos < dpyinfo->mouse_face_end_col
8817 || dpyinfo->mouse_face_past_end))
8818 return 0;
8820 return 1;
8824 /* EXPORT:
8825 Handle mouse button event on the tool-bar of frame F, at
8826 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
8827 0 for button release. MODIFIERS is event modifiers for button
8828 release. */
8830 void
8831 handle_tool_bar_click (f, x, y, down_p, modifiers)
8832 struct frame *f;
8833 int x, y, down_p;
8834 unsigned int modifiers;
8836 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8837 struct window *w = XWINDOW (f->tool_bar_window);
8838 int hpos, vpos, prop_idx;
8839 struct glyph *glyph;
8840 Lisp_Object enabled_p;
8842 /* If not on the highlighted tool-bar item, return. */
8843 frame_to_window_pixel_xy (w, &x, &y);
8844 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
8845 return;
8847 /* If item is disabled, do nothing. */
8848 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
8849 if (NILP (enabled_p))
8850 return;
8852 if (down_p)
8854 /* Show item in pressed state. */
8855 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
8856 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
8857 last_tool_bar_item = prop_idx;
8859 else
8861 Lisp_Object key, frame;
8862 struct input_event event;
8863 EVENT_INIT (event);
8865 /* Show item in released state. */
8866 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
8867 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
8869 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
8871 XSETFRAME (frame, f);
8872 event.kind = TOOL_BAR_EVENT;
8873 event.frame_or_window = frame;
8874 event.arg = frame;
8875 kbd_buffer_store_event (&event);
8877 event.kind = TOOL_BAR_EVENT;
8878 event.frame_or_window = frame;
8879 event.arg = key;
8880 event.modifiers = modifiers;
8881 kbd_buffer_store_event (&event);
8882 last_tool_bar_item = -1;
8887 /* Possibly highlight a tool-bar item on frame F when mouse moves to
8888 tool-bar window-relative coordinates X/Y. Called from
8889 note_mouse_highlight. */
8891 static void
8892 note_tool_bar_highlight (f, x, y)
8893 struct frame *f;
8894 int x, y;
8896 Lisp_Object window = f->tool_bar_window;
8897 struct window *w = XWINDOW (window);
8898 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8899 int hpos, vpos;
8900 struct glyph *glyph;
8901 struct glyph_row *row;
8902 int i;
8903 Lisp_Object enabled_p;
8904 int prop_idx;
8905 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
8906 int mouse_down_p, rc;
8908 /* Function note_mouse_highlight is called with negative x(y
8909 values when mouse moves outside of the frame. */
8910 if (x <= 0 || y <= 0)
8912 clear_mouse_face (dpyinfo);
8913 return;
8916 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
8917 if (rc < 0)
8919 /* Not on tool-bar item. */
8920 clear_mouse_face (dpyinfo);
8921 return;
8923 else if (rc == 0)
8924 /* On same tool-bar item as before. */
8925 goto set_help_echo;
8927 clear_mouse_face (dpyinfo);
8929 /* Mouse is down, but on different tool-bar item? */
8930 mouse_down_p = (dpyinfo->grabbed
8931 && f == last_mouse_frame
8932 && FRAME_LIVE_P (f));
8933 if (mouse_down_p
8934 && last_tool_bar_item != prop_idx)
8935 return;
8937 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
8938 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
8940 /* If tool-bar item is not enabled, don't highlight it. */
8941 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
8942 if (!NILP (enabled_p))
8944 /* Compute the x-position of the glyph. In front and past the
8945 image is a space. We include this in the highlighted area. */
8946 row = MATRIX_ROW (w->current_matrix, vpos);
8947 for (i = x = 0; i < hpos; ++i)
8948 x += row->glyphs[TEXT_AREA][i].pixel_width;
8950 /* Record this as the current active region. */
8951 dpyinfo->mouse_face_beg_col = hpos;
8952 dpyinfo->mouse_face_beg_row = vpos;
8953 dpyinfo->mouse_face_beg_x = x;
8954 dpyinfo->mouse_face_beg_y = row->y;
8955 dpyinfo->mouse_face_past_end = 0;
8957 dpyinfo->mouse_face_end_col = hpos + 1;
8958 dpyinfo->mouse_face_end_row = vpos;
8959 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
8960 dpyinfo->mouse_face_end_y = row->y;
8961 dpyinfo->mouse_face_window = window;
8962 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
8964 /* Display it as active. */
8965 show_mouse_face (dpyinfo, draw);
8966 dpyinfo->mouse_face_image_state = draw;
8969 set_help_echo:
8971 /* Set help_echo_string to a help string to display for this tool-bar item.
8972 XTread_socket does the rest. */
8973 help_echo_object = help_echo_window = Qnil;
8974 help_echo_pos = -1;
8975 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
8976 if (NILP (help_echo_string))
8977 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
8980 #endif /* HAVE_WINDOW_SYSTEM */
8984 /************************************************************************
8985 Horizontal scrolling
8986 ************************************************************************/
8988 static int hscroll_window_tree P_ ((Lisp_Object));
8989 static int hscroll_windows P_ ((Lisp_Object));
8991 /* For all leaf windows in the window tree rooted at WINDOW, set their
8992 hscroll value so that PT is (i) visible in the window, and (ii) so
8993 that it is not within a certain margin at the window's left and
8994 right border. Value is non-zero if any window's hscroll has been
8995 changed. */
8997 static int
8998 hscroll_window_tree (window)
8999 Lisp_Object window;
9001 int hscrolled_p = 0;
9002 int hscroll_relative_p = FLOATP (Vhscroll_step);
9003 int hscroll_step_abs = 0;
9004 double hscroll_step_rel = 0;
9006 if (hscroll_relative_p)
9008 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
9009 if (hscroll_step_rel < 0)
9011 hscroll_relative_p = 0;
9012 hscroll_step_abs = 0;
9015 else if (INTEGERP (Vhscroll_step))
9017 hscroll_step_abs = XINT (Vhscroll_step);
9018 if (hscroll_step_abs < 0)
9019 hscroll_step_abs = 0;
9021 else
9022 hscroll_step_abs = 0;
9024 while (WINDOWP (window))
9026 struct window *w = XWINDOW (window);
9028 if (WINDOWP (w->hchild))
9029 hscrolled_p |= hscroll_window_tree (w->hchild);
9030 else if (WINDOWP (w->vchild))
9031 hscrolled_p |= hscroll_window_tree (w->vchild);
9032 else if (w->cursor.vpos >= 0)
9034 int h_margin;
9035 int text_area_width;
9036 struct glyph_row *current_cursor_row
9037 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
9038 struct glyph_row *desired_cursor_row
9039 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
9040 struct glyph_row *cursor_row
9041 = (desired_cursor_row->enabled_p
9042 ? desired_cursor_row
9043 : current_cursor_row);
9045 text_area_width = window_box_width (w, TEXT_AREA);
9047 /* Scroll when cursor is inside this scroll margin. */
9048 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
9050 if ((XFASTINT (w->hscroll)
9051 && w->cursor.x <= h_margin)
9052 || (cursor_row->enabled_p
9053 && cursor_row->truncated_on_right_p
9054 && (w->cursor.x >= text_area_width - h_margin)))
9056 struct it it;
9057 int hscroll;
9058 struct buffer *saved_current_buffer;
9059 int pt;
9060 int wanted_x;
9062 /* Find point in a display of infinite width. */
9063 saved_current_buffer = current_buffer;
9064 current_buffer = XBUFFER (w->buffer);
9066 if (w == XWINDOW (selected_window))
9067 pt = BUF_PT (current_buffer);
9068 else
9070 pt = marker_position (w->pointm);
9071 pt = max (BEGV, pt);
9072 pt = min (ZV, pt);
9075 /* Move iterator to pt starting at cursor_row->start in
9076 a line with infinite width. */
9077 init_to_row_start (&it, w, cursor_row);
9078 it.last_visible_x = INFINITY;
9079 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
9080 current_buffer = saved_current_buffer;
9082 /* Position cursor in window. */
9083 if (!hscroll_relative_p && hscroll_step_abs == 0)
9084 hscroll = max (0, (it.current_x
9085 - (ITERATOR_AT_END_OF_LINE_P (&it)
9086 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
9087 : (text_area_width / 2))))
9088 / FRAME_COLUMN_WIDTH (it.f);
9089 else if (w->cursor.x >= text_area_width - h_margin)
9091 if (hscroll_relative_p)
9092 wanted_x = text_area_width * (1 - hscroll_step_rel)
9093 - h_margin;
9094 else
9095 wanted_x = text_area_width
9096 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9097 - h_margin;
9098 hscroll
9099 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9101 else
9103 if (hscroll_relative_p)
9104 wanted_x = text_area_width * hscroll_step_rel
9105 + h_margin;
9106 else
9107 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9108 + h_margin;
9109 hscroll
9110 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9112 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
9114 /* Don't call Fset_window_hscroll if value hasn't
9115 changed because it will prevent redisplay
9116 optimizations. */
9117 if (XFASTINT (w->hscroll) != hscroll)
9119 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
9120 w->hscroll = make_number (hscroll);
9121 hscrolled_p = 1;
9126 window = w->next;
9129 /* Value is non-zero if hscroll of any leaf window has been changed. */
9130 return hscrolled_p;
9134 /* Set hscroll so that cursor is visible and not inside horizontal
9135 scroll margins for all windows in the tree rooted at WINDOW. See
9136 also hscroll_window_tree above. Value is non-zero if any window's
9137 hscroll has been changed. If it has, desired matrices on the frame
9138 of WINDOW are cleared. */
9140 static int
9141 hscroll_windows (window)
9142 Lisp_Object window;
9144 int hscrolled_p;
9146 if (automatic_hscrolling_p)
9148 hscrolled_p = hscroll_window_tree (window);
9149 if (hscrolled_p)
9150 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
9152 else
9153 hscrolled_p = 0;
9154 return hscrolled_p;
9159 /************************************************************************
9160 Redisplay
9161 ************************************************************************/
9163 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
9164 to a non-zero value. This is sometimes handy to have in a debugger
9165 session. */
9167 #if GLYPH_DEBUG
9169 /* First and last unchanged row for try_window_id. */
9171 int debug_first_unchanged_at_end_vpos;
9172 int debug_last_unchanged_at_beg_vpos;
9174 /* Delta vpos and y. */
9176 int debug_dvpos, debug_dy;
9178 /* Delta in characters and bytes for try_window_id. */
9180 int debug_delta, debug_delta_bytes;
9182 /* Values of window_end_pos and window_end_vpos at the end of
9183 try_window_id. */
9185 EMACS_INT debug_end_pos, debug_end_vpos;
9187 /* Append a string to W->desired_matrix->method. FMT is a printf
9188 format string. A1...A9 are a supplement for a variable-length
9189 argument list. If trace_redisplay_p is non-zero also printf the
9190 resulting string to stderr. */
9192 static void
9193 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
9194 struct window *w;
9195 char *fmt;
9196 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
9198 char buffer[512];
9199 char *method = w->desired_matrix->method;
9200 int len = strlen (method);
9201 int size = sizeof w->desired_matrix->method;
9202 int remaining = size - len - 1;
9204 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
9205 if (len && remaining)
9207 method[len] = '|';
9208 --remaining, ++len;
9211 strncpy (method + len, buffer, remaining);
9213 if (trace_redisplay_p)
9214 fprintf (stderr, "%p (%s): %s\n",
9216 ((BUFFERP (w->buffer)
9217 && STRINGP (XBUFFER (w->buffer)->name))
9218 ? (char *) SDATA (XBUFFER (w->buffer)->name)
9219 : "no buffer"),
9220 buffer);
9223 #endif /* GLYPH_DEBUG */
9226 /* Value is non-zero if all changes in window W, which displays
9227 current_buffer, are in the text between START and END. START is a
9228 buffer position, END is given as a distance from Z. Used in
9229 redisplay_internal for display optimization. */
9231 static INLINE int
9232 text_outside_line_unchanged_p (w, start, end)
9233 struct window *w;
9234 int start, end;
9236 int unchanged_p = 1;
9238 /* If text or overlays have changed, see where. */
9239 if (XFASTINT (w->last_modified) < MODIFF
9240 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9242 /* Gap in the line? */
9243 if (GPT < start || Z - GPT < end)
9244 unchanged_p = 0;
9246 /* Changes start in front of the line, or end after it? */
9247 if (unchanged_p
9248 && (BEG_UNCHANGED < start - 1
9249 || END_UNCHANGED < end))
9250 unchanged_p = 0;
9252 /* If selective display, can't optimize if changes start at the
9253 beginning of the line. */
9254 if (unchanged_p
9255 && INTEGERP (current_buffer->selective_display)
9256 && XINT (current_buffer->selective_display) > 0
9257 && (BEG_UNCHANGED < start || GPT <= start))
9258 unchanged_p = 0;
9260 /* If there are overlays at the start or end of the line, these
9261 may have overlay strings with newlines in them. A change at
9262 START, for instance, may actually concern the display of such
9263 overlay strings as well, and they are displayed on different
9264 lines. So, quickly rule out this case. (For the future, it
9265 might be desirable to implement something more telling than
9266 just BEG/END_UNCHANGED.) */
9267 if (unchanged_p)
9269 if (BEG + BEG_UNCHANGED == start
9270 && overlay_touches_p (start))
9271 unchanged_p = 0;
9272 if (END_UNCHANGED == end
9273 && overlay_touches_p (Z - end))
9274 unchanged_p = 0;
9278 return unchanged_p;
9282 /* Do a frame update, taking possible shortcuts into account. This is
9283 the main external entry point for redisplay.
9285 If the last redisplay displayed an echo area message and that message
9286 is no longer requested, we clear the echo area or bring back the
9287 mini-buffer if that is in use. */
9289 void
9290 redisplay ()
9292 redisplay_internal (0);
9296 /* Return 1 if point moved out of or into a composition. Otherwise
9297 return 0. PREV_BUF and PREV_PT are the last point buffer and
9298 position. BUF and PT are the current point buffer and position. */
9301 check_point_in_composition (prev_buf, prev_pt, buf, pt)
9302 struct buffer *prev_buf, *buf;
9303 int prev_pt, pt;
9305 int start, end;
9306 Lisp_Object prop;
9307 Lisp_Object buffer;
9309 XSETBUFFER (buffer, buf);
9310 /* Check a composition at the last point if point moved within the
9311 same buffer. */
9312 if (prev_buf == buf)
9314 if (prev_pt == pt)
9315 /* Point didn't move. */
9316 return 0;
9318 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
9319 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
9320 && COMPOSITION_VALID_P (start, end, prop)
9321 && start < prev_pt && end > prev_pt)
9322 /* The last point was within the composition. Return 1 iff
9323 point moved out of the composition. */
9324 return (pt <= start || pt >= end);
9327 /* Check a composition at the current point. */
9328 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
9329 && find_composition (pt, -1, &start, &end, &prop, buffer)
9330 && COMPOSITION_VALID_P (start, end, prop)
9331 && start < pt && end > pt);
9335 /* Reconsider the setting of B->clip_changed which is displayed
9336 in window W. */
9338 static INLINE void
9339 reconsider_clip_changes (w, b)
9340 struct window *w;
9341 struct buffer *b;
9343 if (b->clip_changed
9344 && !NILP (w->window_end_valid)
9345 && w->current_matrix->buffer == b
9346 && w->current_matrix->zv == BUF_ZV (b)
9347 && w->current_matrix->begv == BUF_BEGV (b))
9348 b->clip_changed = 0;
9350 /* If display wasn't paused, and W is not a tool bar window, see if
9351 point has been moved into or out of a composition. In that case,
9352 we set b->clip_changed to 1 to force updating the screen. If
9353 b->clip_changed has already been set to 1, we can skip this
9354 check. */
9355 if (!b->clip_changed
9356 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
9358 int pt;
9360 if (w == XWINDOW (selected_window))
9361 pt = BUF_PT (current_buffer);
9362 else
9363 pt = marker_position (w->pointm);
9365 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
9366 || pt != XINT (w->last_point))
9367 && check_point_in_composition (w->current_matrix->buffer,
9368 XINT (w->last_point),
9369 XBUFFER (w->buffer), pt))
9370 b->clip_changed = 1;
9375 /* Select FRAME to forward the values of frame-local variables into C
9376 variables so that the redisplay routines can access those values
9377 directly. */
9379 static void
9380 select_frame_for_redisplay (frame)
9381 Lisp_Object frame;
9383 Lisp_Object tail, sym, val;
9384 Lisp_Object old = selected_frame;
9386 selected_frame = frame;
9388 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
9389 if (CONSP (XCAR (tail))
9390 && (sym = XCAR (XCAR (tail)),
9391 SYMBOLP (sym))
9392 && (sym = indirect_variable (sym),
9393 val = SYMBOL_VALUE (sym),
9394 (BUFFER_LOCAL_VALUEP (val)
9395 || SOME_BUFFER_LOCAL_VALUEP (val)))
9396 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9397 Fsymbol_value (sym);
9399 for (tail = XFRAME (old)->param_alist; CONSP (tail); tail = XCDR (tail))
9400 if (CONSP (XCAR (tail))
9401 && (sym = XCAR (XCAR (tail)),
9402 SYMBOLP (sym))
9403 && (sym = indirect_variable (sym),
9404 val = SYMBOL_VALUE (sym),
9405 (BUFFER_LOCAL_VALUEP (val)
9406 || SOME_BUFFER_LOCAL_VALUEP (val)))
9407 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9408 Fsymbol_value (sym);
9412 #define STOP_POLLING \
9413 do { if (! polling_stopped_here) stop_polling (); \
9414 polling_stopped_here = 1; } while (0)
9416 #define RESUME_POLLING \
9417 do { if (polling_stopped_here) start_polling (); \
9418 polling_stopped_here = 0; } while (0)
9421 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
9422 response to any user action; therefore, we should preserve the echo
9423 area. (Actually, our caller does that job.) Perhaps in the future
9424 avoid recentering windows if it is not necessary; currently that
9425 causes some problems. */
9427 static void
9428 redisplay_internal (preserve_echo_area)
9429 int preserve_echo_area;
9431 struct window *w = XWINDOW (selected_window);
9432 struct frame *f = XFRAME (w->frame);
9433 int pause;
9434 int must_finish = 0;
9435 struct text_pos tlbufpos, tlendpos;
9436 int number_of_visible_frames;
9437 int count;
9438 struct frame *sf = SELECTED_FRAME ();
9439 int polling_stopped_here = 0;
9441 /* Non-zero means redisplay has to consider all windows on all
9442 frames. Zero means, only selected_window is considered. */
9443 int consider_all_windows_p;
9445 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
9447 /* No redisplay if running in batch mode or frame is not yet fully
9448 initialized, or redisplay is explicitly turned off by setting
9449 Vinhibit_redisplay. */
9450 if (noninteractive
9451 || !NILP (Vinhibit_redisplay)
9452 || !f->glyphs_initialized_p)
9453 return;
9455 /* The flag redisplay_performed_directly_p is set by
9456 direct_output_for_insert when it already did the whole screen
9457 update necessary. */
9458 if (redisplay_performed_directly_p)
9460 redisplay_performed_directly_p = 0;
9461 if (!hscroll_windows (selected_window))
9462 return;
9465 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
9466 if (popup_activated ())
9467 return;
9468 #endif
9470 /* I don't think this happens but let's be paranoid. */
9471 if (redisplaying_p)
9472 return;
9474 /* Record a function that resets redisplaying_p to its old value
9475 when we leave this function. */
9476 count = SPECPDL_INDEX ();
9477 record_unwind_protect (unwind_redisplay,
9478 Fcons (make_number (redisplaying_p), selected_frame));
9479 ++redisplaying_p;
9480 specbind (Qinhibit_free_realized_faces, Qnil);
9482 retry:
9483 pause = 0;
9484 reconsider_clip_changes (w, current_buffer);
9486 /* If new fonts have been loaded that make a glyph matrix adjustment
9487 necessary, do it. */
9488 if (fonts_changed_p)
9490 adjust_glyphs (NULL);
9491 ++windows_or_buffers_changed;
9492 fonts_changed_p = 0;
9495 /* If face_change_count is non-zero, init_iterator will free all
9496 realized faces, which includes the faces referenced from current
9497 matrices. So, we can't reuse current matrices in this case. */
9498 if (face_change_count)
9499 ++windows_or_buffers_changed;
9501 if (! FRAME_WINDOW_P (sf)
9502 && previous_terminal_frame != sf)
9504 /* Since frames on an ASCII terminal share the same display
9505 area, displaying a different frame means redisplay the whole
9506 thing. */
9507 windows_or_buffers_changed++;
9508 SET_FRAME_GARBAGED (sf);
9509 XSETFRAME (Vterminal_frame, sf);
9511 previous_terminal_frame = sf;
9513 /* Set the visible flags for all frames. Do this before checking
9514 for resized or garbaged frames; they want to know if their frames
9515 are visible. See the comment in frame.h for
9516 FRAME_SAMPLE_VISIBILITY. */
9518 Lisp_Object tail, frame;
9520 number_of_visible_frames = 0;
9522 FOR_EACH_FRAME (tail, frame)
9524 struct frame *f = XFRAME (frame);
9526 FRAME_SAMPLE_VISIBILITY (f);
9527 if (FRAME_VISIBLE_P (f))
9528 ++number_of_visible_frames;
9529 clear_desired_matrices (f);
9533 /* Notice any pending interrupt request to change frame size. */
9534 do_pending_window_change (1);
9536 /* Clear frames marked as garbaged. */
9537 if (frame_garbaged)
9538 clear_garbaged_frames ();
9540 /* Build menubar and tool-bar items. */
9541 prepare_menu_bars ();
9543 if (windows_or_buffers_changed)
9544 update_mode_lines++;
9546 /* Detect case that we need to write or remove a star in the mode line. */
9547 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
9549 w->update_mode_line = Qt;
9550 if (buffer_shared > 1)
9551 update_mode_lines++;
9554 /* If %c is in the mode line, update it if needed. */
9555 if (!NILP (w->column_number_displayed)
9556 /* This alternative quickly identifies a common case
9557 where no change is needed. */
9558 && !(PT == XFASTINT (w->last_point)
9559 && XFASTINT (w->last_modified) >= MODIFF
9560 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
9561 && (XFASTINT (w->column_number_displayed)
9562 != (int) current_column ())) /* iftc */
9563 w->update_mode_line = Qt;
9565 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
9567 /* The variable buffer_shared is set in redisplay_window and
9568 indicates that we redisplay a buffer in different windows. See
9569 there. */
9570 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
9571 || cursor_type_changed);
9573 /* If specs for an arrow have changed, do thorough redisplay
9574 to ensure we remove any arrow that should no longer exist. */
9575 if (! EQ (COERCE_MARKER (Voverlay_arrow_position), last_arrow_position)
9576 || ! EQ (Voverlay_arrow_string, last_arrow_string))
9577 consider_all_windows_p = windows_or_buffers_changed = 1;
9579 /* Normally the message* functions will have already displayed and
9580 updated the echo area, but the frame may have been trashed, or
9581 the update may have been preempted, so display the echo area
9582 again here. Checking message_cleared_p captures the case that
9583 the echo area should be cleared. */
9584 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
9585 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
9586 || (message_cleared_p
9587 && minibuf_level == 0
9588 /* If the mini-window is currently selected, this means the
9589 echo-area doesn't show through. */
9590 && !MINI_WINDOW_P (XWINDOW (selected_window))))
9592 int window_height_changed_p = echo_area_display (0);
9593 must_finish = 1;
9595 /* If we don't display the current message, don't clear the
9596 message_cleared_p flag, because, if we did, we wouldn't clear
9597 the echo area in the next redisplay which doesn't preserve
9598 the echo area. */
9599 if (!display_last_displayed_message_p)
9600 message_cleared_p = 0;
9602 if (fonts_changed_p)
9603 goto retry;
9604 else if (window_height_changed_p)
9606 consider_all_windows_p = 1;
9607 ++update_mode_lines;
9608 ++windows_or_buffers_changed;
9610 /* If window configuration was changed, frames may have been
9611 marked garbaged. Clear them or we will experience
9612 surprises wrt scrolling. */
9613 if (frame_garbaged)
9614 clear_garbaged_frames ();
9617 else if (EQ (selected_window, minibuf_window)
9618 && (current_buffer->clip_changed
9619 || XFASTINT (w->last_modified) < MODIFF
9620 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9621 && resize_mini_window (w, 0))
9623 /* Resized active mini-window to fit the size of what it is
9624 showing if its contents might have changed. */
9625 must_finish = 1;
9626 consider_all_windows_p = 1;
9627 ++windows_or_buffers_changed;
9628 ++update_mode_lines;
9630 /* If window configuration was changed, frames may have been
9631 marked garbaged. Clear them or we will experience
9632 surprises wrt scrolling. */
9633 if (frame_garbaged)
9634 clear_garbaged_frames ();
9638 /* If showing the region, and mark has changed, we must redisplay
9639 the whole window. The assignment to this_line_start_pos prevents
9640 the optimization directly below this if-statement. */
9641 if (((!NILP (Vtransient_mark_mode)
9642 && !NILP (XBUFFER (w->buffer)->mark_active))
9643 != !NILP (w->region_showing))
9644 || (!NILP (w->region_showing)
9645 && !EQ (w->region_showing,
9646 Fmarker_position (XBUFFER (w->buffer)->mark))))
9647 CHARPOS (this_line_start_pos) = 0;
9649 /* Optimize the case that only the line containing the cursor in the
9650 selected window has changed. Variables starting with this_ are
9651 set in display_line and record information about the line
9652 containing the cursor. */
9653 tlbufpos = this_line_start_pos;
9654 tlendpos = this_line_end_pos;
9655 if (!consider_all_windows_p
9656 && CHARPOS (tlbufpos) > 0
9657 && NILP (w->update_mode_line)
9658 && !current_buffer->clip_changed
9659 && !current_buffer->prevent_redisplay_optimizations_p
9660 && FRAME_VISIBLE_P (XFRAME (w->frame))
9661 && !FRAME_OBSCURED_P (XFRAME (w->frame))
9662 /* Make sure recorded data applies to current buffer, etc. */
9663 && this_line_buffer == current_buffer
9664 && current_buffer == XBUFFER (w->buffer)
9665 && NILP (w->force_start)
9666 && NILP (w->optional_new_start)
9667 /* Point must be on the line that we have info recorded about. */
9668 && PT >= CHARPOS (tlbufpos)
9669 && PT <= Z - CHARPOS (tlendpos)
9670 /* All text outside that line, including its final newline,
9671 must be unchanged */
9672 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
9673 CHARPOS (tlendpos)))
9675 if (CHARPOS (tlbufpos) > BEGV
9676 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
9677 && (CHARPOS (tlbufpos) == ZV
9678 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
9679 /* Former continuation line has disappeared by becoming empty */
9680 goto cancel;
9681 else if (XFASTINT (w->last_modified) < MODIFF
9682 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
9683 || MINI_WINDOW_P (w))
9685 /* We have to handle the case of continuation around a
9686 wide-column character (See the comment in indent.c around
9687 line 885).
9689 For instance, in the following case:
9691 -------- Insert --------
9692 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
9693 J_I_ ==> J_I_ `^^' are cursors.
9694 ^^ ^^
9695 -------- --------
9697 As we have to redraw the line above, we should goto cancel. */
9699 struct it it;
9700 int line_height_before = this_line_pixel_height;
9702 /* Note that start_display will handle the case that the
9703 line starting at tlbufpos is a continuation lines. */
9704 start_display (&it, w, tlbufpos);
9706 /* Implementation note: It this still necessary? */
9707 if (it.current_x != this_line_start_x)
9708 goto cancel;
9710 TRACE ((stderr, "trying display optimization 1\n"));
9711 w->cursor.vpos = -1;
9712 overlay_arrow_seen = 0;
9713 it.vpos = this_line_vpos;
9714 it.current_y = this_line_y;
9715 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
9716 display_line (&it);
9718 /* If line contains point, is not continued,
9719 and ends at same distance from eob as before, we win */
9720 if (w->cursor.vpos >= 0
9721 /* Line is not continued, otherwise this_line_start_pos
9722 would have been set to 0 in display_line. */
9723 && CHARPOS (this_line_start_pos)
9724 /* Line ends as before. */
9725 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
9726 /* Line has same height as before. Otherwise other lines
9727 would have to be shifted up or down. */
9728 && this_line_pixel_height == line_height_before)
9730 /* If this is not the window's last line, we must adjust
9731 the charstarts of the lines below. */
9732 if (it.current_y < it.last_visible_y)
9734 struct glyph_row *row
9735 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
9736 int delta, delta_bytes;
9738 if (Z - CHARPOS (tlendpos) == ZV)
9740 /* This line ends at end of (accessible part of)
9741 buffer. There is no newline to count. */
9742 delta = (Z
9743 - CHARPOS (tlendpos)
9744 - MATRIX_ROW_START_CHARPOS (row));
9745 delta_bytes = (Z_BYTE
9746 - BYTEPOS (tlendpos)
9747 - MATRIX_ROW_START_BYTEPOS (row));
9749 else
9751 /* This line ends in a newline. Must take
9752 account of the newline and the rest of the
9753 text that follows. */
9754 delta = (Z
9755 - CHARPOS (tlendpos)
9756 - MATRIX_ROW_START_CHARPOS (row));
9757 delta_bytes = (Z_BYTE
9758 - BYTEPOS (tlendpos)
9759 - MATRIX_ROW_START_BYTEPOS (row));
9762 increment_matrix_positions (w->current_matrix,
9763 this_line_vpos + 1,
9764 w->current_matrix->nrows,
9765 delta, delta_bytes);
9768 /* If this row displays text now but previously didn't,
9769 or vice versa, w->window_end_vpos may have to be
9770 adjusted. */
9771 if ((it.glyph_row - 1)->displays_text_p)
9773 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
9774 XSETINT (w->window_end_vpos, this_line_vpos);
9776 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
9777 && this_line_vpos > 0)
9778 XSETINT (w->window_end_vpos, this_line_vpos - 1);
9779 w->window_end_valid = Qnil;
9781 /* Update hint: No need to try to scroll in update_window. */
9782 w->desired_matrix->no_scrolling_p = 1;
9784 #if GLYPH_DEBUG
9785 *w->desired_matrix->method = 0;
9786 debug_method_add (w, "optimization 1");
9787 #endif
9788 #ifdef HAVE_WINDOW_SYSTEM
9789 update_window_fringes (w, 0);
9790 #endif
9791 goto update;
9793 else
9794 goto cancel;
9796 else if (/* Cursor position hasn't changed. */
9797 PT == XFASTINT (w->last_point)
9798 /* Make sure the cursor was last displayed
9799 in this window. Otherwise we have to reposition it. */
9800 && 0 <= w->cursor.vpos
9801 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
9803 if (!must_finish)
9805 do_pending_window_change (1);
9807 /* We used to always goto end_of_redisplay here, but this
9808 isn't enough if we have a blinking cursor. */
9809 if (w->cursor_off_p == w->last_cursor_off_p)
9810 goto end_of_redisplay;
9812 goto update;
9814 /* If highlighting the region, or if the cursor is in the echo area,
9815 then we can't just move the cursor. */
9816 else if (! (!NILP (Vtransient_mark_mode)
9817 && !NILP (current_buffer->mark_active))
9818 && (EQ (selected_window, current_buffer->last_selected_window)
9819 || highlight_nonselected_windows)
9820 && NILP (w->region_showing)
9821 && NILP (Vshow_trailing_whitespace)
9822 && !cursor_in_echo_area)
9824 struct it it;
9825 struct glyph_row *row;
9827 /* Skip from tlbufpos to PT and see where it is. Note that
9828 PT may be in invisible text. If so, we will end at the
9829 next visible position. */
9830 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
9831 NULL, DEFAULT_FACE_ID);
9832 it.current_x = this_line_start_x;
9833 it.current_y = this_line_y;
9834 it.vpos = this_line_vpos;
9836 /* The call to move_it_to stops in front of PT, but
9837 moves over before-strings. */
9838 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
9840 if (it.vpos == this_line_vpos
9841 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
9842 row->enabled_p))
9844 xassert (this_line_vpos == it.vpos);
9845 xassert (this_line_y == it.current_y);
9846 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
9847 #if GLYPH_DEBUG
9848 *w->desired_matrix->method = 0;
9849 debug_method_add (w, "optimization 3");
9850 #endif
9851 goto update;
9853 else
9854 goto cancel;
9857 cancel:
9858 /* Text changed drastically or point moved off of line. */
9859 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
9862 CHARPOS (this_line_start_pos) = 0;
9863 consider_all_windows_p |= buffer_shared > 1;
9864 ++clear_face_cache_count;
9867 /* Build desired matrices, and update the display. If
9868 consider_all_windows_p is non-zero, do it for all windows on all
9869 frames. Otherwise do it for selected_window, only. */
9871 if (consider_all_windows_p)
9873 Lisp_Object tail, frame;
9874 int i, n = 0, size = 50;
9875 struct frame **updated
9876 = (struct frame **) alloca (size * sizeof *updated);
9878 /* Clear the face cache eventually. */
9879 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
9881 clear_face_cache (0);
9882 clear_face_cache_count = 0;
9885 /* Recompute # windows showing selected buffer. This will be
9886 incremented each time such a window is displayed. */
9887 buffer_shared = 0;
9889 FOR_EACH_FRAME (tail, frame)
9891 struct frame *f = XFRAME (frame);
9893 if (FRAME_WINDOW_P (f) || f == sf)
9895 if (! EQ (frame, selected_frame))
9896 /* Select the frame, for the sake of frame-local
9897 variables. */
9898 select_frame_for_redisplay (frame);
9900 #ifdef HAVE_WINDOW_SYSTEM
9901 if (clear_face_cache_count % 50 == 0
9902 && FRAME_WINDOW_P (f))
9903 clear_image_cache (f, 0);
9904 #endif /* HAVE_WINDOW_SYSTEM */
9906 /* Mark all the scroll bars to be removed; we'll redeem
9907 the ones we want when we redisplay their windows. */
9908 if (condemn_scroll_bars_hook)
9909 condemn_scroll_bars_hook (f);
9911 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
9912 redisplay_windows (FRAME_ROOT_WINDOW (f));
9914 /* Any scroll bars which redisplay_windows should have
9915 nuked should now go away. */
9916 if (judge_scroll_bars_hook)
9917 judge_scroll_bars_hook (f);
9919 /* If fonts changed, display again. */
9920 /* ??? rms: I suspect it is a mistake to jump all the way
9921 back to retry here. It should just retry this frame. */
9922 if (fonts_changed_p)
9923 goto retry;
9925 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
9927 /* See if we have to hscroll. */
9928 if (hscroll_windows (f->root_window))
9929 goto retry;
9931 /* Prevent various kinds of signals during display
9932 update. stdio is not robust about handling
9933 signals, which can cause an apparent I/O
9934 error. */
9935 if (interrupt_input)
9936 unrequest_sigio ();
9937 STOP_POLLING;
9939 /* Update the display. */
9940 set_window_update_flags (XWINDOW (f->root_window), 1);
9941 pause |= update_frame (f, 0, 0);
9942 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
9943 if (pause)
9944 break;
9945 #endif
9947 if (n == size)
9949 int nbytes = size * sizeof *updated;
9950 struct frame **p = (struct frame **) alloca (2 * nbytes);
9951 bcopy (updated, p, nbytes);
9952 size *= 2;
9955 updated[n++] = f;
9960 if (!pause)
9962 /* Do the mark_window_display_accurate after all windows have
9963 been redisplayed because this call resets flags in buffers
9964 which are needed for proper redisplay. */
9965 for (i = 0; i < n; ++i)
9967 struct frame *f = updated[i];
9968 mark_window_display_accurate (f->root_window, 1);
9969 if (frame_up_to_date_hook)
9970 frame_up_to_date_hook (f);
9974 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
9976 Lisp_Object mini_window;
9977 struct frame *mini_frame;
9979 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
9980 /* Use list_of_error, not Qerror, so that
9981 we catch only errors and don't run the debugger. */
9982 internal_condition_case_1 (redisplay_window_1, selected_window,
9983 list_of_error,
9984 redisplay_window_error);
9986 /* Compare desired and current matrices, perform output. */
9988 update:
9989 /* If fonts changed, display again. */
9990 if (fonts_changed_p)
9991 goto retry;
9993 /* Prevent various kinds of signals during display update.
9994 stdio is not robust about handling signals,
9995 which can cause an apparent I/O error. */
9996 if (interrupt_input)
9997 unrequest_sigio ();
9998 STOP_POLLING;
10000 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10002 if (hscroll_windows (selected_window))
10003 goto retry;
10005 XWINDOW (selected_window)->must_be_updated_p = 1;
10006 pause = update_frame (sf, 0, 0);
10009 /* We may have called echo_area_display at the top of this
10010 function. If the echo area is on another frame, that may
10011 have put text on a frame other than the selected one, so the
10012 above call to update_frame would not have caught it. Catch
10013 it here. */
10014 mini_window = FRAME_MINIBUF_WINDOW (sf);
10015 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10017 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
10019 XWINDOW (mini_window)->must_be_updated_p = 1;
10020 pause |= update_frame (mini_frame, 0, 0);
10021 if (!pause && hscroll_windows (mini_window))
10022 goto retry;
10026 /* If display was paused because of pending input, make sure we do a
10027 thorough update the next time. */
10028 if (pause)
10030 /* Prevent the optimization at the beginning of
10031 redisplay_internal that tries a single-line update of the
10032 line containing the cursor in the selected window. */
10033 CHARPOS (this_line_start_pos) = 0;
10035 /* Let the overlay arrow be updated the next time. */
10036 if (!NILP (last_arrow_position))
10038 last_arrow_position = Qt;
10039 last_arrow_string = Qt;
10042 /* If we pause after scrolling, some rows in the current
10043 matrices of some windows are not valid. */
10044 if (!WINDOW_FULL_WIDTH_P (w)
10045 && !FRAME_WINDOW_P (XFRAME (w->frame)))
10046 update_mode_lines = 1;
10048 else
10050 if (!consider_all_windows_p)
10052 /* This has already been done above if
10053 consider_all_windows_p is set. */
10054 mark_window_display_accurate_1 (w, 1);
10056 last_arrow_position = COERCE_MARKER (Voverlay_arrow_position);
10057 last_arrow_string = Voverlay_arrow_string;
10059 if (frame_up_to_date_hook != 0)
10060 frame_up_to_date_hook (sf);
10063 update_mode_lines = 0;
10064 windows_or_buffers_changed = 0;
10065 cursor_type_changed = 0;
10068 /* Start SIGIO interrupts coming again. Having them off during the
10069 code above makes it less likely one will discard output, but not
10070 impossible, since there might be stuff in the system buffer here.
10071 But it is much hairier to try to do anything about that. */
10072 if (interrupt_input)
10073 request_sigio ();
10074 RESUME_POLLING;
10076 /* If a frame has become visible which was not before, redisplay
10077 again, so that we display it. Expose events for such a frame
10078 (which it gets when becoming visible) don't call the parts of
10079 redisplay constructing glyphs, so simply exposing a frame won't
10080 display anything in this case. So, we have to display these
10081 frames here explicitly. */
10082 if (!pause)
10084 Lisp_Object tail, frame;
10085 int new_count = 0;
10087 FOR_EACH_FRAME (tail, frame)
10089 int this_is_visible = 0;
10091 if (XFRAME (frame)->visible)
10092 this_is_visible = 1;
10093 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
10094 if (XFRAME (frame)->visible)
10095 this_is_visible = 1;
10097 if (this_is_visible)
10098 new_count++;
10101 if (new_count != number_of_visible_frames)
10102 windows_or_buffers_changed++;
10105 /* Change frame size now if a change is pending. */
10106 do_pending_window_change (1);
10108 /* If we just did a pending size change, or have additional
10109 visible frames, redisplay again. */
10110 if (windows_or_buffers_changed && !pause)
10111 goto retry;
10113 end_of_redisplay:
10114 unbind_to (count, Qnil);
10115 RESUME_POLLING;
10119 /* Redisplay, but leave alone any recent echo area message unless
10120 another message has been requested in its place.
10122 This is useful in situations where you need to redisplay but no
10123 user action has occurred, making it inappropriate for the message
10124 area to be cleared. See tracking_off and
10125 wait_reading_process_input for examples of these situations.
10127 FROM_WHERE is an integer saying from where this function was
10128 called. This is useful for debugging. */
10130 void
10131 redisplay_preserve_echo_area (from_where)
10132 int from_where;
10134 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
10136 if (!NILP (echo_area_buffer[1]))
10138 /* We have a previously displayed message, but no current
10139 message. Redisplay the previous message. */
10140 display_last_displayed_message_p = 1;
10141 redisplay_internal (1);
10142 display_last_displayed_message_p = 0;
10144 else
10145 redisplay_internal (1);
10149 /* Function registered with record_unwind_protect in
10150 redisplay_internal. Reset redisplaying_p to the value it had
10151 before redisplay_internal was called, and clear
10152 prevent_freeing_realized_faces_p. It also selects the previously
10153 selected frame. */
10155 static Lisp_Object
10156 unwind_redisplay (val)
10157 Lisp_Object val;
10159 Lisp_Object old_redisplaying_p, old_frame;
10161 old_redisplaying_p = XCAR (val);
10162 redisplaying_p = XFASTINT (old_redisplaying_p);
10163 old_frame = XCDR (val);
10164 if (! EQ (old_frame, selected_frame))
10165 select_frame_for_redisplay (old_frame);
10166 return Qnil;
10170 /* Mark the display of window W as accurate or inaccurate. If
10171 ACCURATE_P is non-zero mark display of W as accurate. If
10172 ACCURATE_P is zero, arrange for W to be redisplayed the next time
10173 redisplay_internal is called. */
10175 static void
10176 mark_window_display_accurate_1 (w, accurate_p)
10177 struct window *w;
10178 int accurate_p;
10180 if (BUFFERP (w->buffer))
10182 struct buffer *b = XBUFFER (w->buffer);
10184 w->last_modified
10185 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
10186 w->last_overlay_modified
10187 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
10188 w->last_had_star
10189 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
10191 if (accurate_p)
10193 b->clip_changed = 0;
10194 b->prevent_redisplay_optimizations_p = 0;
10196 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
10197 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
10198 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
10199 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
10201 w->current_matrix->buffer = b;
10202 w->current_matrix->begv = BUF_BEGV (b);
10203 w->current_matrix->zv = BUF_ZV (b);
10205 w->last_cursor = w->cursor;
10206 w->last_cursor_off_p = w->cursor_off_p;
10208 if (w == XWINDOW (selected_window))
10209 w->last_point = make_number (BUF_PT (b));
10210 else
10211 w->last_point = make_number (XMARKER (w->pointm)->charpos);
10215 if (accurate_p)
10217 w->window_end_valid = w->buffer;
10218 #if 0 /* This is incorrect with variable-height lines. */
10219 xassert (XINT (w->window_end_vpos)
10220 < (WINDOW_TOTAL_LINES (w)
10221 - (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
10222 #endif
10223 w->update_mode_line = Qnil;
10228 /* Mark the display of windows in the window tree rooted at WINDOW as
10229 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
10230 windows as accurate. If ACCURATE_P is zero, arrange for windows to
10231 be redisplayed the next time redisplay_internal is called. */
10233 void
10234 mark_window_display_accurate (window, accurate_p)
10235 Lisp_Object window;
10236 int accurate_p;
10238 struct window *w;
10240 for (; !NILP (window); window = w->next)
10242 w = XWINDOW (window);
10243 mark_window_display_accurate_1 (w, accurate_p);
10245 if (!NILP (w->vchild))
10246 mark_window_display_accurate (w->vchild, accurate_p);
10247 if (!NILP (w->hchild))
10248 mark_window_display_accurate (w->hchild, accurate_p);
10251 if (accurate_p)
10253 last_arrow_position = COERCE_MARKER (Voverlay_arrow_position);
10254 last_arrow_string = Voverlay_arrow_string;
10256 else
10258 /* Force a thorough redisplay the next time by setting
10259 last_arrow_position and last_arrow_string to t, which is
10260 unequal to any useful value of Voverlay_arrow_... */
10261 last_arrow_position = Qt;
10262 last_arrow_string = Qt;
10267 /* Return value in display table DP (Lisp_Char_Table *) for character
10268 C. Since a display table doesn't have any parent, we don't have to
10269 follow parent. Do not call this function directly but use the
10270 macro DISP_CHAR_VECTOR. */
10272 Lisp_Object
10273 disp_char_vector (dp, c)
10274 struct Lisp_Char_Table *dp;
10275 int c;
10277 int code[4], i;
10278 Lisp_Object val;
10280 if (SINGLE_BYTE_CHAR_P (c))
10281 return (dp->contents[c]);
10283 SPLIT_CHAR (c, code[0], code[1], code[2]);
10284 if (code[1] < 32)
10285 code[1] = -1;
10286 else if (code[2] < 32)
10287 code[2] = -1;
10289 /* Here, the possible range of code[0] (== charset ID) is
10290 128..max_charset. Since the top level char table contains data
10291 for multibyte characters after 256th element, we must increment
10292 code[0] by 128 to get a correct index. */
10293 code[0] += 128;
10294 code[3] = -1; /* anchor */
10296 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
10298 val = dp->contents[code[i]];
10299 if (!SUB_CHAR_TABLE_P (val))
10300 return (NILP (val) ? dp->defalt : val);
10303 /* Here, val is a sub char table. We return the default value of
10304 it. */
10305 return (dp->defalt);
10310 /***********************************************************************
10311 Window Redisplay
10312 ***********************************************************************/
10314 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
10316 static void
10317 redisplay_windows (window)
10318 Lisp_Object window;
10320 while (!NILP (window))
10322 struct window *w = XWINDOW (window);
10324 if (!NILP (w->hchild))
10325 redisplay_windows (w->hchild);
10326 else if (!NILP (w->vchild))
10327 redisplay_windows (w->vchild);
10328 else
10330 displayed_buffer = XBUFFER (w->buffer);
10331 /* Use list_of_error, not Qerror, so that
10332 we catch only errors and don't run the debugger. */
10333 internal_condition_case_1 (redisplay_window_0, window,
10334 list_of_error,
10335 redisplay_window_error);
10338 window = w->next;
10342 static Lisp_Object
10343 redisplay_window_error ()
10345 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
10346 return Qnil;
10349 static Lisp_Object
10350 redisplay_window_0 (window)
10351 Lisp_Object window;
10353 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10354 redisplay_window (window, 0);
10355 return Qnil;
10358 static Lisp_Object
10359 redisplay_window_1 (window)
10360 Lisp_Object window;
10362 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10363 redisplay_window (window, 1);
10364 return Qnil;
10368 /* Increment GLYPH until it reaches END or CONDITION fails while
10369 adding (GLYPH)->pixel_width to X. */
10371 #define SKIP_GLYPHS(glyph, end, x, condition) \
10372 do \
10374 (x) += (glyph)->pixel_width; \
10375 ++(glyph); \
10377 while ((glyph) < (end) && (condition))
10380 /* Set cursor position of W. PT is assumed to be displayed in ROW.
10381 DELTA is the number of bytes by which positions recorded in ROW
10382 differ from current buffer positions. */
10384 void
10385 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
10386 struct window *w;
10387 struct glyph_row *row;
10388 struct glyph_matrix *matrix;
10389 int delta, delta_bytes, dy, dvpos;
10391 struct glyph *glyph = row->glyphs[TEXT_AREA];
10392 struct glyph *end = glyph + row->used[TEXT_AREA];
10393 /* The first glyph that starts a sequence of glyphs from string. */
10394 struct glyph *string_start;
10395 /* The X coordinate of string_start. */
10396 int string_start_x;
10397 /* The last known character position. */
10398 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
10399 /* The last known character position before string_start. */
10400 int string_before_pos;
10401 int x = row->x;
10402 int pt_old = PT - delta;
10404 /* Skip over glyphs not having an object at the start of the row.
10405 These are special glyphs like truncation marks on terminal
10406 frames. */
10407 if (row->displays_text_p)
10408 while (glyph < end
10409 && INTEGERP (glyph->object)
10410 && glyph->charpos < 0)
10412 x += glyph->pixel_width;
10413 ++glyph;
10416 string_start = NULL;
10417 while (glyph < end
10418 && !INTEGERP (glyph->object)
10419 && (!BUFFERP (glyph->object)
10420 || (last_pos = glyph->charpos) < pt_old))
10422 if (! STRINGP (glyph->object))
10424 string_start = NULL;
10425 x += glyph->pixel_width;
10426 ++glyph;
10428 else
10430 string_before_pos = last_pos;
10431 string_start = glyph;
10432 string_start_x = x;
10433 /* Skip all glyphs from string. */
10434 SKIP_GLYPHS (glyph, end, x, STRINGP (glyph->object));
10438 if (string_start
10439 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
10441 /* We may have skipped over point because the previous glyphs
10442 are from string. As there's no easy way to know the
10443 character position of the current glyph, find the correct
10444 glyph on point by scanning from string_start again. */
10445 Lisp_Object limit;
10446 Lisp_Object string;
10447 int pos;
10449 limit = make_number (pt_old + 1);
10450 end = glyph;
10451 glyph = string_start;
10452 x = string_start_x;
10453 string = glyph->object;
10454 pos = string_buffer_position (w, string, string_before_pos);
10455 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
10456 because we always put cursor after overlay strings. */
10457 while (pos == 0 && glyph < end)
10459 string = glyph->object;
10460 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10461 if (glyph < end)
10462 pos = string_buffer_position (w, glyph->object, string_before_pos);
10465 while (glyph < end)
10467 pos = XINT (Fnext_single_char_property_change
10468 (make_number (pos), Qdisplay, Qnil, limit));
10469 if (pos > pt_old)
10470 break;
10471 /* Skip glyphs from the same string. */
10472 string = glyph->object;
10473 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10474 /* Skip glyphs from an overlay. */
10475 while (glyph < end
10476 && ! string_buffer_position (w, glyph->object, pos))
10478 string = glyph->object;
10479 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10484 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
10485 w->cursor.x = x;
10486 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
10487 w->cursor.y = row->y + dy;
10489 if (w == XWINDOW (selected_window))
10491 if (!row->continued_p
10492 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
10493 && row->x == 0)
10495 this_line_buffer = XBUFFER (w->buffer);
10497 CHARPOS (this_line_start_pos)
10498 = MATRIX_ROW_START_CHARPOS (row) + delta;
10499 BYTEPOS (this_line_start_pos)
10500 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
10502 CHARPOS (this_line_end_pos)
10503 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
10504 BYTEPOS (this_line_end_pos)
10505 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
10507 this_line_y = w->cursor.y;
10508 this_line_pixel_height = row->height;
10509 this_line_vpos = w->cursor.vpos;
10510 this_line_start_x = row->x;
10512 else
10513 CHARPOS (this_line_start_pos) = 0;
10518 /* Run window scroll functions, if any, for WINDOW with new window
10519 start STARTP. Sets the window start of WINDOW to that position.
10521 We assume that the window's buffer is really current. */
10523 static INLINE struct text_pos
10524 run_window_scroll_functions (window, startp)
10525 Lisp_Object window;
10526 struct text_pos startp;
10528 struct window *w = XWINDOW (window);
10529 SET_MARKER_FROM_TEXT_POS (w->start, startp);
10531 if (current_buffer != XBUFFER (w->buffer))
10532 abort ();
10534 if (!NILP (Vwindow_scroll_functions))
10536 run_hook_with_args_2 (Qwindow_scroll_functions, window,
10537 make_number (CHARPOS (startp)));
10538 SET_TEXT_POS_FROM_MARKER (startp, w->start);
10539 /* In case the hook functions switch buffers. */
10540 if (current_buffer != XBUFFER (w->buffer))
10541 set_buffer_internal_1 (XBUFFER (w->buffer));
10544 return startp;
10548 /* Make sure the line containing the cursor is fully visible.
10549 A value of 1 means there is nothing to be done.
10550 (Either the line is fully visible, or it cannot be made so,
10551 or we cannot tell.)
10552 A value of 0 means the caller should do scrolling
10553 as if point had gone off the screen. */
10555 static int
10556 make_cursor_line_fully_visible (w)
10557 struct window *w;
10559 struct glyph_matrix *matrix;
10560 struct glyph_row *row;
10561 int window_height;
10563 /* It's not always possible to find the cursor, e.g, when a window
10564 is full of overlay strings. Don't do anything in that case. */
10565 if (w->cursor.vpos < 0)
10566 return 1;
10568 matrix = w->desired_matrix;
10569 row = MATRIX_ROW (matrix, w->cursor.vpos);
10571 /* If the cursor row is not partially visible, there's nothing to do. */
10572 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
10573 return 1;
10575 /* If the row the cursor is in is taller than the window's height,
10576 it's not clear what to do, so do nothing. */
10577 window_height = window_box_height (w);
10578 if (row->height >= window_height)
10579 return 1;
10581 return 0;
10583 #if 0
10584 /* This code used to try to scroll the window just enough to make
10585 the line visible. It returned 0 to say that the caller should
10586 allocate larger glyph matrices. */
10588 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
10590 int dy = row->height - row->visible_height;
10591 w->vscroll = 0;
10592 w->cursor.y += dy;
10593 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
10595 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
10597 int dy = - (row->height - row->visible_height);
10598 w->vscroll = dy;
10599 w->cursor.y += dy;
10600 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
10603 /* When we change the cursor y-position of the selected window,
10604 change this_line_y as well so that the display optimization for
10605 the cursor line of the selected window in redisplay_internal uses
10606 the correct y-position. */
10607 if (w == XWINDOW (selected_window))
10608 this_line_y = w->cursor.y;
10610 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
10611 redisplay with larger matrices. */
10612 if (matrix->nrows < required_matrix_height (w))
10614 fonts_changed_p = 1;
10615 return 0;
10618 return 1;
10619 #endif /* 0 */
10623 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
10624 non-zero means only WINDOW is redisplayed in redisplay_internal.
10625 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
10626 in redisplay_window to bring a partially visible line into view in
10627 the case that only the cursor has moved.
10629 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
10630 last screen line's vertical height extends past the end of the screen.
10632 Value is
10634 1 if scrolling succeeded
10636 0 if scrolling didn't find point.
10638 -1 if new fonts have been loaded so that we must interrupt
10639 redisplay, adjust glyph matrices, and try again. */
10641 enum
10643 SCROLLING_SUCCESS,
10644 SCROLLING_FAILED,
10645 SCROLLING_NEED_LARGER_MATRICES
10648 static int
10649 try_scrolling (window, just_this_one_p, scroll_conservatively,
10650 scroll_step, temp_scroll_step, last_line_misfit)
10651 Lisp_Object window;
10652 int just_this_one_p;
10653 EMACS_INT scroll_conservatively, scroll_step;
10654 int temp_scroll_step;
10655 int last_line_misfit;
10657 struct window *w = XWINDOW (window);
10658 struct frame *f = XFRAME (w->frame);
10659 struct text_pos scroll_margin_pos;
10660 struct text_pos pos;
10661 struct text_pos startp;
10662 struct it it;
10663 Lisp_Object window_end;
10664 int this_scroll_margin;
10665 int dy = 0;
10666 int scroll_max;
10667 int rc;
10668 int amount_to_scroll = 0;
10669 Lisp_Object aggressive;
10670 int height;
10671 int end_scroll_margin;
10673 #if GLYPH_DEBUG
10674 debug_method_add (w, "try_scrolling");
10675 #endif
10677 SET_TEXT_POS_FROM_MARKER (startp, w->start);
10679 /* Compute scroll margin height in pixels. We scroll when point is
10680 within this distance from the top or bottom of the window. */
10681 if (scroll_margin > 0)
10683 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
10684 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
10686 else
10687 this_scroll_margin = 0;
10689 /* Compute how much we should try to scroll maximally to bring point
10690 into view. */
10691 if (scroll_step || scroll_conservatively || temp_scroll_step)
10692 scroll_max = max (scroll_step,
10693 max (scroll_conservatively, temp_scroll_step));
10694 else if (NUMBERP (current_buffer->scroll_down_aggressively)
10695 || NUMBERP (current_buffer->scroll_up_aggressively))
10696 /* We're trying to scroll because of aggressive scrolling
10697 but no scroll_step is set. Choose an arbitrary one. Maybe
10698 there should be a variable for this. */
10699 scroll_max = 10;
10700 else
10701 scroll_max = 0;
10702 scroll_max *= FRAME_LINE_HEIGHT (f);
10704 /* Decide whether we have to scroll down. Start at the window end
10705 and move this_scroll_margin up to find the position of the scroll
10706 margin. */
10707 window_end = Fwindow_end (window, Qt);
10709 too_near_end:
10711 CHARPOS (scroll_margin_pos) = XINT (window_end);
10712 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
10714 end_scroll_margin = this_scroll_margin + !!last_line_misfit;
10715 if (end_scroll_margin)
10717 start_display (&it, w, scroll_margin_pos);
10718 move_it_vertically (&it, - end_scroll_margin);
10719 scroll_margin_pos = it.current.pos;
10722 if (PT >= CHARPOS (scroll_margin_pos))
10724 int y0;
10726 /* Point is in the scroll margin at the bottom of the window, or
10727 below. Compute a new window start that makes point visible. */
10729 /* Compute the distance from the scroll margin to PT.
10730 Give up if the distance is greater than scroll_max. */
10731 start_display (&it, w, scroll_margin_pos);
10732 y0 = it.current_y;
10733 move_it_to (&it, PT, 0, it.last_visible_y, -1,
10734 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
10736 /* To make point visible, we have to move the window start
10737 down so that the line the cursor is in is visible, which
10738 means we have to add in the height of the cursor line. */
10739 dy = line_bottom_y (&it) - y0;
10741 if (dy > scroll_max)
10742 return SCROLLING_FAILED;
10744 /* Move the window start down. If scrolling conservatively,
10745 move it just enough down to make point visible. If
10746 scroll_step is set, move it down by scroll_step. */
10747 start_display (&it, w, startp);
10749 if (scroll_conservatively)
10750 /* Set AMOUNT_TO_SCROLL to at least one line,
10751 and at most scroll_conservatively lines. */
10752 amount_to_scroll
10753 = min (max (dy, FRAME_LINE_HEIGHT (f)),
10754 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
10755 else if (scroll_step || temp_scroll_step)
10756 amount_to_scroll = scroll_max;
10757 else
10759 aggressive = current_buffer->scroll_up_aggressively;
10760 height = WINDOW_BOX_TEXT_HEIGHT (w);
10761 if (NUMBERP (aggressive))
10762 amount_to_scroll = XFLOATINT (aggressive) * height;
10765 if (amount_to_scroll <= 0)
10766 return SCROLLING_FAILED;
10768 /* If moving by amount_to_scroll leaves STARTP unchanged,
10769 move it down one screen line. */
10771 move_it_vertically (&it, amount_to_scroll);
10772 if (CHARPOS (it.current.pos) == CHARPOS (startp))
10773 move_it_by_lines (&it, 1, 1);
10774 startp = it.current.pos;
10776 else
10778 /* See if point is inside the scroll margin at the top of the
10779 window. */
10780 scroll_margin_pos = startp;
10781 if (this_scroll_margin)
10783 start_display (&it, w, startp);
10784 move_it_vertically (&it, this_scroll_margin);
10785 scroll_margin_pos = it.current.pos;
10788 if (PT < CHARPOS (scroll_margin_pos))
10790 /* Point is in the scroll margin at the top of the window or
10791 above what is displayed in the window. */
10792 int y0;
10794 /* Compute the vertical distance from PT to the scroll
10795 margin position. Give up if distance is greater than
10796 scroll_max. */
10797 SET_TEXT_POS (pos, PT, PT_BYTE);
10798 start_display (&it, w, pos);
10799 y0 = it.current_y;
10800 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
10801 it.last_visible_y, -1,
10802 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
10803 dy = it.current_y - y0;
10804 if (dy > scroll_max)
10805 return SCROLLING_FAILED;
10807 /* Compute new window start. */
10808 start_display (&it, w, startp);
10810 if (scroll_conservatively)
10811 amount_to_scroll =
10812 max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
10813 else if (scroll_step || temp_scroll_step)
10814 amount_to_scroll = scroll_max;
10815 else
10817 aggressive = current_buffer->scroll_down_aggressively;
10818 height = WINDOW_BOX_TEXT_HEIGHT (w);
10819 if (NUMBERP (aggressive))
10820 amount_to_scroll = XFLOATINT (aggressive) * height;
10823 if (amount_to_scroll <= 0)
10824 return SCROLLING_FAILED;
10826 move_it_vertically (&it, - amount_to_scroll);
10827 startp = it.current.pos;
10831 /* Run window scroll functions. */
10832 startp = run_window_scroll_functions (window, startp);
10834 /* Display the window. Give up if new fonts are loaded, or if point
10835 doesn't appear. */
10836 if (!try_window (window, startp))
10837 rc = SCROLLING_NEED_LARGER_MATRICES;
10838 else if (w->cursor.vpos < 0)
10840 clear_glyph_matrix (w->desired_matrix);
10841 rc = SCROLLING_FAILED;
10843 else
10845 /* Maybe forget recorded base line for line number display. */
10846 if (!just_this_one_p
10847 || current_buffer->clip_changed
10848 || BEG_UNCHANGED < CHARPOS (startp))
10849 w->base_line_number = Qnil;
10851 /* If cursor ends up on a partially visible line,
10852 treat that as being off the bottom of the screen. */
10853 if (! make_cursor_line_fully_visible (w))
10855 clear_glyph_matrix (w->desired_matrix);
10856 last_line_misfit = 1;
10857 goto too_near_end;
10859 rc = SCROLLING_SUCCESS;
10862 return rc;
10866 /* Compute a suitable window start for window W if display of W starts
10867 on a continuation line. Value is non-zero if a new window start
10868 was computed.
10870 The new window start will be computed, based on W's width, starting
10871 from the start of the continued line. It is the start of the
10872 screen line with the minimum distance from the old start W->start. */
10874 static int
10875 compute_window_start_on_continuation_line (w)
10876 struct window *w;
10878 struct text_pos pos, start_pos;
10879 int window_start_changed_p = 0;
10881 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
10883 /* If window start is on a continuation line... Window start may be
10884 < BEGV in case there's invisible text at the start of the
10885 buffer (M-x rmail, for example). */
10886 if (CHARPOS (start_pos) > BEGV
10887 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
10889 struct it it;
10890 struct glyph_row *row;
10892 /* Handle the case that the window start is out of range. */
10893 if (CHARPOS (start_pos) < BEGV)
10894 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
10895 else if (CHARPOS (start_pos) > ZV)
10896 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
10898 /* Find the start of the continued line. This should be fast
10899 because scan_buffer is fast (newline cache). */
10900 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
10901 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
10902 row, DEFAULT_FACE_ID);
10903 reseat_at_previous_visible_line_start (&it);
10905 /* If the line start is "too far" away from the window start,
10906 say it takes too much time to compute a new window start. */
10907 if (CHARPOS (start_pos) - IT_CHARPOS (it)
10908 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
10910 int min_distance, distance;
10912 /* Move forward by display lines to find the new window
10913 start. If window width was enlarged, the new start can
10914 be expected to be > the old start. If window width was
10915 decreased, the new window start will be < the old start.
10916 So, we're looking for the display line start with the
10917 minimum distance from the old window start. */
10918 pos = it.current.pos;
10919 min_distance = INFINITY;
10920 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
10921 distance < min_distance)
10923 min_distance = distance;
10924 pos = it.current.pos;
10925 move_it_by_lines (&it, 1, 0);
10928 /* Set the window start there. */
10929 SET_MARKER_FROM_TEXT_POS (w->start, pos);
10930 window_start_changed_p = 1;
10934 return window_start_changed_p;
10938 /* Try cursor movement in case text has not changed in window WINDOW,
10939 with window start STARTP. Value is
10941 CURSOR_MOVEMENT_SUCCESS if successful
10943 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
10945 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
10946 display. *SCROLL_STEP is set to 1, under certain circumstances, if
10947 we want to scroll as if scroll-step were set to 1. See the code.
10949 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
10950 which case we have to abort this redisplay, and adjust matrices
10951 first. */
10953 enum
10955 CURSOR_MOVEMENT_SUCCESS,
10956 CURSOR_MOVEMENT_CANNOT_BE_USED,
10957 CURSOR_MOVEMENT_MUST_SCROLL,
10958 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
10961 static int
10962 try_cursor_movement (window, startp, scroll_step)
10963 Lisp_Object window;
10964 struct text_pos startp;
10965 int *scroll_step;
10967 struct window *w = XWINDOW (window);
10968 struct frame *f = XFRAME (w->frame);
10969 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
10971 #if GLYPH_DEBUG
10972 if (inhibit_try_cursor_movement)
10973 return rc;
10974 #endif
10976 /* Handle case where text has not changed, only point, and it has
10977 not moved off the frame. */
10978 if (/* Point may be in this window. */
10979 PT >= CHARPOS (startp)
10980 /* Selective display hasn't changed. */
10981 && !current_buffer->clip_changed
10982 /* Function force-mode-line-update is used to force a thorough
10983 redisplay. It sets either windows_or_buffers_changed or
10984 update_mode_lines. So don't take a shortcut here for these
10985 cases. */
10986 && !update_mode_lines
10987 && !windows_or_buffers_changed
10988 && !cursor_type_changed
10989 /* Can't use this case if highlighting a region. When a
10990 region exists, cursor movement has to do more than just
10991 set the cursor. */
10992 && !(!NILP (Vtransient_mark_mode)
10993 && !NILP (current_buffer->mark_active))
10994 && NILP (w->region_showing)
10995 && NILP (Vshow_trailing_whitespace)
10996 /* Right after splitting windows, last_point may be nil. */
10997 && INTEGERP (w->last_point)
10998 /* This code is not used for mini-buffer for the sake of the case
10999 of redisplaying to replace an echo area message; since in
11000 that case the mini-buffer contents per se are usually
11001 unchanged. This code is of no real use in the mini-buffer
11002 since the handling of this_line_start_pos, etc., in redisplay
11003 handles the same cases. */
11004 && !EQ (window, minibuf_window)
11005 /* When splitting windows or for new windows, it happens that
11006 redisplay is called with a nil window_end_vpos or one being
11007 larger than the window. This should really be fixed in
11008 window.c. I don't have this on my list, now, so we do
11009 approximately the same as the old redisplay code. --gerd. */
11010 && INTEGERP (w->window_end_vpos)
11011 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
11012 && (FRAME_WINDOW_P (f)
11013 || !MARKERP (Voverlay_arrow_position)
11014 || current_buffer != XMARKER (Voverlay_arrow_position)->buffer))
11016 int this_scroll_margin;
11017 struct glyph_row *row = NULL;
11019 #if GLYPH_DEBUG
11020 debug_method_add (w, "cursor movement");
11021 #endif
11023 /* Scroll if point within this distance from the top or bottom
11024 of the window. This is a pixel value. */
11025 this_scroll_margin = max (0, scroll_margin);
11026 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
11027 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
11029 /* Start with the row the cursor was displayed during the last
11030 not paused redisplay. Give up if that row is not valid. */
11031 if (w->last_cursor.vpos < 0
11032 || w->last_cursor.vpos >= w->current_matrix->nrows)
11033 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11034 else
11036 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
11037 if (row->mode_line_p)
11038 ++row;
11039 if (!row->enabled_p)
11040 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11043 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
11045 int scroll_p = 0;
11046 int last_y = window_text_bottom_y (w) - this_scroll_margin;
11048 if (PT > XFASTINT (w->last_point))
11050 /* Point has moved forward. */
11051 while (MATRIX_ROW_END_CHARPOS (row) < PT
11052 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
11054 xassert (row->enabled_p);
11055 ++row;
11058 /* The end position of a row equals the start position
11059 of the next row. If PT is there, we would rather
11060 display it in the next line. */
11061 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11062 && MATRIX_ROW_END_CHARPOS (row) == PT
11063 && !cursor_row_p (w, row))
11064 ++row;
11066 /* If within the scroll margin, scroll. Note that
11067 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
11068 the next line would be drawn, and that
11069 this_scroll_margin can be zero. */
11070 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
11071 || PT > MATRIX_ROW_END_CHARPOS (row)
11072 /* Line is completely visible last line in window
11073 and PT is to be set in the next line. */
11074 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
11075 && PT == MATRIX_ROW_END_CHARPOS (row)
11076 && !row->ends_at_zv_p
11077 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
11078 scroll_p = 1;
11080 else if (PT < XFASTINT (w->last_point))
11082 /* Cursor has to be moved backward. Note that PT >=
11083 CHARPOS (startp) because of the outer
11084 if-statement. */
11085 while (!row->mode_line_p
11086 && (MATRIX_ROW_START_CHARPOS (row) > PT
11087 || (MATRIX_ROW_START_CHARPOS (row) == PT
11088 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)))
11089 && (row->y > this_scroll_margin
11090 || CHARPOS (startp) == BEGV))
11092 xassert (row->enabled_p);
11093 --row;
11096 /* Consider the following case: Window starts at BEGV,
11097 there is invisible, intangible text at BEGV, so that
11098 display starts at some point START > BEGV. It can
11099 happen that we are called with PT somewhere between
11100 BEGV and START. Try to handle that case. */
11101 if (row < w->current_matrix->rows
11102 || row->mode_line_p)
11104 row = w->current_matrix->rows;
11105 if (row->mode_line_p)
11106 ++row;
11109 /* Due to newlines in overlay strings, we may have to
11110 skip forward over overlay strings. */
11111 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11112 && MATRIX_ROW_END_CHARPOS (row) == PT
11113 && !cursor_row_p (w, row))
11114 ++row;
11116 /* If within the scroll margin, scroll. */
11117 if (row->y < this_scroll_margin
11118 && CHARPOS (startp) != BEGV)
11119 scroll_p = 1;
11122 if (PT < MATRIX_ROW_START_CHARPOS (row)
11123 || PT > MATRIX_ROW_END_CHARPOS (row))
11125 /* if PT is not in the glyph row, give up. */
11126 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11128 else if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
11130 if (PT == MATRIX_ROW_END_CHARPOS (row)
11131 && !row->ends_at_zv_p
11132 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
11133 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11134 else if (row->height > window_box_height (w))
11136 /* If we end up in a partially visible line, let's
11137 make it fully visible, except when it's taller
11138 than the window, in which case we can't do much
11139 about it. */
11140 *scroll_step = 1;
11141 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11143 else
11145 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11146 if (!make_cursor_line_fully_visible (w))
11147 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11148 else
11149 rc = CURSOR_MOVEMENT_SUCCESS;
11152 else if (scroll_p)
11153 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11154 else
11156 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11157 rc = CURSOR_MOVEMENT_SUCCESS;
11162 return rc;
11165 void
11166 set_vertical_scroll_bar (w)
11167 struct window *w;
11169 int start, end, whole;
11171 /* Calculate the start and end positions for the current window.
11172 At some point, it would be nice to choose between scrollbars
11173 which reflect the whole buffer size, with special markers
11174 indicating narrowing, and scrollbars which reflect only the
11175 visible region.
11177 Note that mini-buffers sometimes aren't displaying any text. */
11178 if (!MINI_WINDOW_P (w)
11179 || (w == XWINDOW (minibuf_window)
11180 && NILP (echo_area_buffer[0])))
11182 struct buffer *buf = XBUFFER (w->buffer);
11183 whole = BUF_ZV (buf) - BUF_BEGV (buf);
11184 start = marker_position (w->start) - BUF_BEGV (buf);
11185 /* I don't think this is guaranteed to be right. For the
11186 moment, we'll pretend it is. */
11187 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
11189 if (end < start)
11190 end = start;
11191 if (whole < (end - start))
11192 whole = end - start;
11194 else
11195 start = end = whole = 0;
11197 /* Indicate what this scroll bar ought to be displaying now. */
11198 set_vertical_scroll_bar_hook (w, end - start, whole, start);
11202 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
11203 selected_window is redisplayed.
11205 We can return without actually redisplaying the window if
11206 fonts_changed_p is nonzero. In that case, redisplay_internal will
11207 retry. */
11209 static void
11210 redisplay_window (window, just_this_one_p)
11211 Lisp_Object window;
11212 int just_this_one_p;
11214 struct window *w = XWINDOW (window);
11215 struct frame *f = XFRAME (w->frame);
11216 struct buffer *buffer = XBUFFER (w->buffer);
11217 struct buffer *old = current_buffer;
11218 struct text_pos lpoint, opoint, startp;
11219 int update_mode_line;
11220 int tem;
11221 struct it it;
11222 /* Record it now because it's overwritten. */
11223 int current_matrix_up_to_date_p = 0;
11224 int used_current_matrix_p = 0;
11225 /* This is less strict than current_matrix_up_to_date_p.
11226 It indictes that the buffer contents and narrowing are unchanged. */
11227 int buffer_unchanged_p = 0;
11228 int temp_scroll_step = 0;
11229 int count = SPECPDL_INDEX ();
11230 int rc;
11231 int centering_position;
11232 int last_line_misfit = 0;
11234 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11235 opoint = lpoint;
11237 /* W must be a leaf window here. */
11238 xassert (!NILP (w->buffer));
11239 #if GLYPH_DEBUG
11240 *w->desired_matrix->method = 0;
11241 #endif
11243 specbind (Qinhibit_point_motion_hooks, Qt);
11245 reconsider_clip_changes (w, buffer);
11247 /* Has the mode line to be updated? */
11248 update_mode_line = (!NILP (w->update_mode_line)
11249 || update_mode_lines
11250 || buffer->clip_changed
11251 || buffer->prevent_redisplay_optimizations_p);
11253 if (MINI_WINDOW_P (w))
11255 if (w == XWINDOW (echo_area_window)
11256 && !NILP (echo_area_buffer[0]))
11258 if (update_mode_line)
11259 /* We may have to update a tty frame's menu bar or a
11260 tool-bar. Example `M-x C-h C-h C-g'. */
11261 goto finish_menu_bars;
11262 else
11263 /* We've already displayed the echo area glyphs in this window. */
11264 goto finish_scroll_bars;
11266 else if ((w != XWINDOW (minibuf_window)
11267 || minibuf_level == 0)
11268 /* When buffer is nonempty, redisplay window normally. */
11269 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
11270 /* Quail displays non-mini buffers in minibuffer window.
11271 In that case, redisplay the window normally. */
11272 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
11274 /* W is a mini-buffer window, but it's not active, so clear
11275 it. */
11276 int yb = window_text_bottom_y (w);
11277 struct glyph_row *row;
11278 int y;
11280 for (y = 0, row = w->desired_matrix->rows;
11281 y < yb;
11282 y += row->height, ++row)
11283 blank_row (w, row, y);
11284 goto finish_scroll_bars;
11287 clear_glyph_matrix (w->desired_matrix);
11290 /* Otherwise set up data on this window; select its buffer and point
11291 value. */
11292 /* Really select the buffer, for the sake of buffer-local
11293 variables. */
11294 set_buffer_internal_1 (XBUFFER (w->buffer));
11295 SET_TEXT_POS (opoint, PT, PT_BYTE);
11297 current_matrix_up_to_date_p
11298 = (!NILP (w->window_end_valid)
11299 && !current_buffer->clip_changed
11300 && !current_buffer->prevent_redisplay_optimizations_p
11301 && XFASTINT (w->last_modified) >= MODIFF
11302 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11304 buffer_unchanged_p
11305 = (!NILP (w->window_end_valid)
11306 && !current_buffer->clip_changed
11307 && XFASTINT (w->last_modified) >= MODIFF
11308 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11310 /* When windows_or_buffers_changed is non-zero, we can't rely on
11311 the window end being valid, so set it to nil there. */
11312 if (windows_or_buffers_changed)
11314 /* If window starts on a continuation line, maybe adjust the
11315 window start in case the window's width changed. */
11316 if (XMARKER (w->start)->buffer == current_buffer)
11317 compute_window_start_on_continuation_line (w);
11319 w->window_end_valid = Qnil;
11322 /* Some sanity checks. */
11323 CHECK_WINDOW_END (w);
11324 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
11325 abort ();
11326 if (BYTEPOS (opoint) < CHARPOS (opoint))
11327 abort ();
11329 /* If %c is in mode line, update it if needed. */
11330 if (!NILP (w->column_number_displayed)
11331 /* This alternative quickly identifies a common case
11332 where no change is needed. */
11333 && !(PT == XFASTINT (w->last_point)
11334 && XFASTINT (w->last_modified) >= MODIFF
11335 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
11336 && (XFASTINT (w->column_number_displayed)
11337 != (int) current_column ())) /* iftc */
11338 update_mode_line = 1;
11340 /* Count number of windows showing the selected buffer. An indirect
11341 buffer counts as its base buffer. */
11342 if (!just_this_one_p)
11344 struct buffer *current_base, *window_base;
11345 current_base = current_buffer;
11346 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
11347 if (current_base->base_buffer)
11348 current_base = current_base->base_buffer;
11349 if (window_base->base_buffer)
11350 window_base = window_base->base_buffer;
11351 if (current_base == window_base)
11352 buffer_shared++;
11355 /* Point refers normally to the selected window. For any other
11356 window, set up appropriate value. */
11357 if (!EQ (window, selected_window))
11359 int new_pt = XMARKER (w->pointm)->charpos;
11360 int new_pt_byte = marker_byte_position (w->pointm);
11361 if (new_pt < BEGV)
11363 new_pt = BEGV;
11364 new_pt_byte = BEGV_BYTE;
11365 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
11367 else if (new_pt > (ZV - 1))
11369 new_pt = ZV;
11370 new_pt_byte = ZV_BYTE;
11371 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
11374 /* We don't use SET_PT so that the point-motion hooks don't run. */
11375 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
11378 /* If any of the character widths specified in the display table
11379 have changed, invalidate the width run cache. It's true that
11380 this may be a bit late to catch such changes, but the rest of
11381 redisplay goes (non-fatally) haywire when the display table is
11382 changed, so why should we worry about doing any better? */
11383 if (current_buffer->width_run_cache)
11385 struct Lisp_Char_Table *disptab = buffer_display_table ();
11387 if (! disptab_matches_widthtab (disptab,
11388 XVECTOR (current_buffer->width_table)))
11390 invalidate_region_cache (current_buffer,
11391 current_buffer->width_run_cache,
11392 BEG, Z);
11393 recompute_width_table (current_buffer, disptab);
11397 /* If window-start is screwed up, choose a new one. */
11398 if (XMARKER (w->start)->buffer != current_buffer)
11399 goto recenter;
11401 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11403 /* If someone specified a new starting point but did not insist,
11404 check whether it can be used. */
11405 if (!NILP (w->optional_new_start)
11406 && CHARPOS (startp) >= BEGV
11407 && CHARPOS (startp) <= ZV)
11409 w->optional_new_start = Qnil;
11410 start_display (&it, w, startp);
11411 move_it_to (&it, PT, 0, it.last_visible_y, -1,
11412 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11413 if (IT_CHARPOS (it) == PT)
11414 w->force_start = Qt;
11415 /* IT may overshoot PT if text at PT is invisible. */
11416 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
11417 w->force_start = Qt;
11422 /* Handle case where place to start displaying has been specified,
11423 unless the specified location is outside the accessible range. */
11424 if (!NILP (w->force_start)
11425 || w->frozen_window_start_p)
11427 /* We set this later on if we have to adjust point. */
11428 int new_vpos = -1;
11430 w->force_start = Qnil;
11431 w->vscroll = 0;
11432 w->window_end_valid = Qnil;
11434 /* Forget any recorded base line for line number display. */
11435 if (!buffer_unchanged_p)
11436 w->base_line_number = Qnil;
11438 /* Redisplay the mode line. Select the buffer properly for that.
11439 Also, run the hook window-scroll-functions
11440 because we have scrolled. */
11441 /* Note, we do this after clearing force_start because
11442 if there's an error, it is better to forget about force_start
11443 than to get into an infinite loop calling the hook functions
11444 and having them get more errors. */
11445 if (!update_mode_line
11446 || ! NILP (Vwindow_scroll_functions))
11448 update_mode_line = 1;
11449 w->update_mode_line = Qt;
11450 startp = run_window_scroll_functions (window, startp);
11453 w->last_modified = make_number (0);
11454 w->last_overlay_modified = make_number (0);
11455 if (CHARPOS (startp) < BEGV)
11456 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
11457 else if (CHARPOS (startp) > ZV)
11458 SET_TEXT_POS (startp, ZV, ZV_BYTE);
11460 /* Redisplay, then check if cursor has been set during the
11461 redisplay. Give up if new fonts were loaded. */
11462 if (!try_window (window, startp))
11464 w->force_start = Qt;
11465 clear_glyph_matrix (w->desired_matrix);
11466 goto need_larger_matrices;
11469 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
11471 /* If point does not appear, try to move point so it does
11472 appear. The desired matrix has been built above, so we
11473 can use it here. */
11474 new_vpos = window_box_height (w) / 2;
11477 if (!make_cursor_line_fully_visible (w))
11479 /* Point does appear, but on a line partly visible at end of window.
11480 Move it back to a fully-visible line. */
11481 new_vpos = window_box_height (w);
11484 /* If we need to move point for either of the above reasons,
11485 now actually do it. */
11486 if (new_vpos >= 0)
11488 struct glyph_row *row;
11490 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
11491 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
11492 ++row;
11494 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
11495 MATRIX_ROW_START_BYTEPOS (row));
11497 if (w != XWINDOW (selected_window))
11498 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
11499 else if (current_buffer == old)
11500 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11502 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
11504 /* If we are highlighting the region, then we just changed
11505 the region, so redisplay to show it. */
11506 if (!NILP (Vtransient_mark_mode)
11507 && !NILP (current_buffer->mark_active))
11509 clear_glyph_matrix (w->desired_matrix);
11510 if (!try_window (window, startp))
11511 goto need_larger_matrices;
11515 #if GLYPH_DEBUG
11516 debug_method_add (w, "forced window start");
11517 #endif
11518 goto done;
11521 /* Handle case where text has not changed, only point, and it has
11522 not moved off the frame, and we are not retrying after hscroll.
11523 (current_matrix_up_to_date_p is nonzero when retrying.) */
11524 if (current_matrix_up_to_date_p
11525 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
11526 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
11528 switch (rc)
11530 case CURSOR_MOVEMENT_SUCCESS:
11531 used_current_matrix_p = 1;
11532 goto done;
11534 #if 0 /* try_cursor_movement never returns this value. */
11535 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES:
11536 goto need_larger_matrices;
11537 #endif
11539 case CURSOR_MOVEMENT_MUST_SCROLL:
11540 goto try_to_scroll;
11542 default:
11543 abort ();
11546 /* If current starting point was originally the beginning of a line
11547 but no longer is, find a new starting point. */
11548 else if (!NILP (w->start_at_line_beg)
11549 && !(CHARPOS (startp) <= BEGV
11550 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
11552 #if GLYPH_DEBUG
11553 debug_method_add (w, "recenter 1");
11554 #endif
11555 goto recenter;
11558 /* Try scrolling with try_window_id. Value is > 0 if update has
11559 been done, it is -1 if we know that the same window start will
11560 not work. It is 0 if unsuccessful for some other reason. */
11561 else if ((tem = try_window_id (w)) != 0)
11563 #if GLYPH_DEBUG
11564 debug_method_add (w, "try_window_id %d", tem);
11565 #endif
11567 if (fonts_changed_p)
11568 goto need_larger_matrices;
11569 if (tem > 0)
11570 goto done;
11572 /* Otherwise try_window_id has returned -1 which means that we
11573 don't want the alternative below this comment to execute. */
11575 else if (CHARPOS (startp) >= BEGV
11576 && CHARPOS (startp) <= ZV
11577 && PT >= CHARPOS (startp)
11578 && (CHARPOS (startp) < ZV
11579 /* Avoid starting at end of buffer. */
11580 || CHARPOS (startp) == BEGV
11581 || (XFASTINT (w->last_modified) >= MODIFF
11582 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
11584 #if GLYPH_DEBUG
11585 debug_method_add (w, "same window start");
11586 #endif
11588 /* Try to redisplay starting at same place as before.
11589 If point has not moved off frame, accept the results. */
11590 if (!current_matrix_up_to_date_p
11591 /* Don't use try_window_reusing_current_matrix in this case
11592 because a window scroll function can have changed the
11593 buffer. */
11594 || !NILP (Vwindow_scroll_functions)
11595 || MINI_WINDOW_P (w)
11596 || !(used_current_matrix_p =
11597 try_window_reusing_current_matrix (w)))
11599 IF_DEBUG (debug_method_add (w, "1"));
11600 try_window (window, startp);
11603 if (fonts_changed_p)
11604 goto need_larger_matrices;
11606 if (w->cursor.vpos >= 0)
11608 if (!just_this_one_p
11609 || current_buffer->clip_changed
11610 || BEG_UNCHANGED < CHARPOS (startp))
11611 /* Forget any recorded base line for line number display. */
11612 w->base_line_number = Qnil;
11614 if (!make_cursor_line_fully_visible (w))
11616 clear_glyph_matrix (w->desired_matrix);
11617 last_line_misfit = 1;
11619 /* Drop through and scroll. */
11620 else
11621 goto done;
11623 else
11624 clear_glyph_matrix (w->desired_matrix);
11627 try_to_scroll:
11629 w->last_modified = make_number (0);
11630 w->last_overlay_modified = make_number (0);
11632 /* Redisplay the mode line. Select the buffer properly for that. */
11633 if (!update_mode_line)
11635 update_mode_line = 1;
11636 w->update_mode_line = Qt;
11639 /* Try to scroll by specified few lines. */
11640 if ((scroll_conservatively
11641 || scroll_step
11642 || temp_scroll_step
11643 || NUMBERP (current_buffer->scroll_up_aggressively)
11644 || NUMBERP (current_buffer->scroll_down_aggressively))
11645 && !current_buffer->clip_changed
11646 && CHARPOS (startp) >= BEGV
11647 && CHARPOS (startp) <= ZV)
11649 /* The function returns -1 if new fonts were loaded, 1 if
11650 successful, 0 if not successful. */
11651 int rc = try_scrolling (window, just_this_one_p,
11652 scroll_conservatively,
11653 scroll_step,
11654 temp_scroll_step, last_line_misfit);
11655 switch (rc)
11657 case SCROLLING_SUCCESS:
11658 goto done;
11660 case SCROLLING_NEED_LARGER_MATRICES:
11661 goto need_larger_matrices;
11663 case SCROLLING_FAILED:
11664 break;
11666 default:
11667 abort ();
11671 /* Finally, just choose place to start which centers point */
11673 recenter:
11674 centering_position = window_box_height (w) / 2;
11676 point_at_top:
11677 /* Jump here with centering_position already set to 0. */
11679 #if GLYPH_DEBUG
11680 debug_method_add (w, "recenter");
11681 #endif
11683 /* w->vscroll = 0; */
11685 /* Forget any previously recorded base line for line number display. */
11686 if (!buffer_unchanged_p)
11687 w->base_line_number = Qnil;
11689 /* Move backward half the height of the window. */
11690 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
11691 it.current_y = it.last_visible_y;
11692 move_it_vertically_backward (&it, centering_position);
11693 xassert (IT_CHARPOS (it) >= BEGV);
11695 /* The function move_it_vertically_backward may move over more
11696 than the specified y-distance. If it->w is small, e.g. a
11697 mini-buffer window, we may end up in front of the window's
11698 display area. Start displaying at the start of the line
11699 containing PT in this case. */
11700 if (it.current_y <= 0)
11702 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
11703 move_it_vertically (&it, 0);
11704 xassert (IT_CHARPOS (it) <= PT);
11705 it.current_y = 0;
11708 it.current_x = it.hpos = 0;
11710 /* Set startp here explicitly in case that helps avoid an infinite loop
11711 in case the window-scroll-functions functions get errors. */
11712 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
11714 /* Run scroll hooks. */
11715 startp = run_window_scroll_functions (window, it.current.pos);
11717 /* Redisplay the window. */
11718 if (!current_matrix_up_to_date_p
11719 || windows_or_buffers_changed
11720 || cursor_type_changed
11721 /* Don't use try_window_reusing_current_matrix in this case
11722 because it can have changed the buffer. */
11723 || !NILP (Vwindow_scroll_functions)
11724 || !just_this_one_p
11725 || MINI_WINDOW_P (w)
11726 || !(used_current_matrix_p =
11727 try_window_reusing_current_matrix (w)))
11728 try_window (window, startp);
11730 /* If new fonts have been loaded (due to fontsets), give up. We
11731 have to start a new redisplay since we need to re-adjust glyph
11732 matrices. */
11733 if (fonts_changed_p)
11734 goto need_larger_matrices;
11736 /* If cursor did not appear assume that the middle of the window is
11737 in the first line of the window. Do it again with the next line.
11738 (Imagine a window of height 100, displaying two lines of height
11739 60. Moving back 50 from it->last_visible_y will end in the first
11740 line.) */
11741 if (w->cursor.vpos < 0)
11743 if (!NILP (w->window_end_valid)
11744 && PT >= Z - XFASTINT (w->window_end_pos))
11746 clear_glyph_matrix (w->desired_matrix);
11747 move_it_by_lines (&it, 1, 0);
11748 try_window (window, it.current.pos);
11750 else if (PT < IT_CHARPOS (it))
11752 clear_glyph_matrix (w->desired_matrix);
11753 move_it_by_lines (&it, -1, 0);
11754 try_window (window, it.current.pos);
11756 else
11758 /* Not much we can do about it. */
11762 /* Consider the following case: Window starts at BEGV, there is
11763 invisible, intangible text at BEGV, so that display starts at
11764 some point START > BEGV. It can happen that we are called with
11765 PT somewhere between BEGV and START. Try to handle that case. */
11766 if (w->cursor.vpos < 0)
11768 struct glyph_row *row = w->current_matrix->rows;
11769 if (row->mode_line_p)
11770 ++row;
11771 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11774 if (!make_cursor_line_fully_visible (w))
11776 /* If vscroll is enabled, disable it and try again. */
11777 if (w->vscroll)
11779 w->vscroll = 0;
11780 clear_glyph_matrix (w->desired_matrix);
11781 goto recenter;
11784 /* If centering point failed to make the whole line visible,
11785 put point at the top instead. That has to make the whole line
11786 visible, if it can be done. */
11787 centering_position = 0;
11788 goto point_at_top;
11791 done:
11793 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11794 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
11795 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
11796 ? Qt : Qnil);
11798 /* Display the mode line, if we must. */
11799 if ((update_mode_line
11800 /* If window not full width, must redo its mode line
11801 if (a) the window to its side is being redone and
11802 (b) we do a frame-based redisplay. This is a consequence
11803 of how inverted lines are drawn in frame-based redisplay. */
11804 || (!just_this_one_p
11805 && !FRAME_WINDOW_P (f)
11806 && !WINDOW_FULL_WIDTH_P (w))
11807 /* Line number to display. */
11808 || INTEGERP (w->base_line_pos)
11809 /* Column number is displayed and different from the one displayed. */
11810 || (!NILP (w->column_number_displayed)
11811 && (XFASTINT (w->column_number_displayed)
11812 != (int) current_column ()))) /* iftc */
11813 /* This means that the window has a mode line. */
11814 && (WINDOW_WANTS_MODELINE_P (w)
11815 || WINDOW_WANTS_HEADER_LINE_P (w)))
11817 display_mode_lines (w);
11819 /* If mode line height has changed, arrange for a thorough
11820 immediate redisplay using the correct mode line height. */
11821 if (WINDOW_WANTS_MODELINE_P (w)
11822 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
11824 fonts_changed_p = 1;
11825 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
11826 = DESIRED_MODE_LINE_HEIGHT (w);
11829 /* If top line height has changed, arrange for a thorough
11830 immediate redisplay using the correct mode line height. */
11831 if (WINDOW_WANTS_HEADER_LINE_P (w)
11832 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
11834 fonts_changed_p = 1;
11835 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
11836 = DESIRED_HEADER_LINE_HEIGHT (w);
11839 if (fonts_changed_p)
11840 goto need_larger_matrices;
11843 if (!line_number_displayed
11844 && !BUFFERP (w->base_line_pos))
11846 w->base_line_pos = Qnil;
11847 w->base_line_number = Qnil;
11850 finish_menu_bars:
11852 /* When we reach a frame's selected window, redo the frame's menu bar. */
11853 if (update_mode_line
11854 && EQ (FRAME_SELECTED_WINDOW (f), window))
11856 int redisplay_menu_p = 0;
11857 int redisplay_tool_bar_p = 0;
11859 if (FRAME_WINDOW_P (f))
11861 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
11862 || defined (USE_GTK)
11863 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
11864 #else
11865 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
11866 #endif
11868 else
11869 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
11871 if (redisplay_menu_p)
11872 display_menu_bar (w);
11874 #ifdef HAVE_WINDOW_SYSTEM
11875 #ifdef USE_GTK
11876 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
11877 #else
11878 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
11879 && (FRAME_TOOL_BAR_LINES (f) > 0
11880 || auto_resize_tool_bars_p);
11882 #endif
11884 if (redisplay_tool_bar_p)
11885 redisplay_tool_bar (f);
11886 #endif
11889 #ifdef HAVE_WINDOW_SYSTEM
11890 if (update_window_fringes (w, 0)
11891 && !just_this_one_p
11892 && (used_current_matrix_p || overlay_arrow_seen)
11893 && !w->pseudo_window_p)
11895 update_begin (f);
11896 BLOCK_INPUT;
11897 draw_window_fringes (w);
11898 UNBLOCK_INPUT;
11899 update_end (f);
11901 #endif /* HAVE_WINDOW_SYSTEM */
11903 /* We go to this label, with fonts_changed_p nonzero,
11904 if it is necessary to try again using larger glyph matrices.
11905 We have to redeem the scroll bar even in this case,
11906 because the loop in redisplay_internal expects that. */
11907 need_larger_matrices:
11909 finish_scroll_bars:
11911 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
11913 /* Set the thumb's position and size. */
11914 set_vertical_scroll_bar (w);
11916 /* Note that we actually used the scroll bar attached to this
11917 window, so it shouldn't be deleted at the end of redisplay. */
11918 redeem_scroll_bar_hook (w);
11921 /* Restore current_buffer and value of point in it. */
11922 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
11923 set_buffer_internal_1 (old);
11924 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
11926 unbind_to (count, Qnil);
11930 /* Build the complete desired matrix of WINDOW with a window start
11931 buffer position POS. Value is non-zero if successful. It is zero
11932 if fonts were loaded during redisplay which makes re-adjusting
11933 glyph matrices necessary. */
11936 try_window (window, pos)
11937 Lisp_Object window;
11938 struct text_pos pos;
11940 struct window *w = XWINDOW (window);
11941 struct it it;
11942 struct glyph_row *last_text_row = NULL;
11944 /* Make POS the new window start. */
11945 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
11947 /* Mark cursor position as unknown. No overlay arrow seen. */
11948 w->cursor.vpos = -1;
11949 overlay_arrow_seen = 0;
11951 /* Initialize iterator and info to start at POS. */
11952 start_display (&it, w, pos);
11954 /* Display all lines of W. */
11955 while (it.current_y < it.last_visible_y)
11957 if (display_line (&it))
11958 last_text_row = it.glyph_row - 1;
11959 if (fonts_changed_p)
11960 return 0;
11963 /* If bottom moved off end of frame, change mode line percentage. */
11964 if (XFASTINT (w->window_end_pos) <= 0
11965 && Z != IT_CHARPOS (it))
11966 w->update_mode_line = Qt;
11968 /* Set window_end_pos to the offset of the last character displayed
11969 on the window from the end of current_buffer. Set
11970 window_end_vpos to its row number. */
11971 if (last_text_row)
11973 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
11974 w->window_end_bytepos
11975 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
11976 w->window_end_pos
11977 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
11978 w->window_end_vpos
11979 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
11980 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
11981 ->displays_text_p);
11983 else
11985 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
11986 w->window_end_pos = make_number (Z - ZV);
11987 w->window_end_vpos = make_number (0);
11990 /* But that is not valid info until redisplay finishes. */
11991 w->window_end_valid = Qnil;
11992 return 1;
11997 /************************************************************************
11998 Window redisplay reusing current matrix when buffer has not changed
11999 ************************************************************************/
12001 /* Try redisplay of window W showing an unchanged buffer with a
12002 different window start than the last time it was displayed by
12003 reusing its current matrix. Value is non-zero if successful.
12004 W->start is the new window start. */
12006 static int
12007 try_window_reusing_current_matrix (w)
12008 struct window *w;
12010 struct frame *f = XFRAME (w->frame);
12011 struct glyph_row *row, *bottom_row;
12012 struct it it;
12013 struct run run;
12014 struct text_pos start, new_start;
12015 int nrows_scrolled, i;
12016 struct glyph_row *last_text_row;
12017 struct glyph_row *last_reused_text_row;
12018 struct glyph_row *start_row;
12019 int start_vpos, min_y, max_y;
12021 #if GLYPH_DEBUG
12022 if (inhibit_try_window_reusing)
12023 return 0;
12024 #endif
12026 if (/* This function doesn't handle terminal frames. */
12027 !FRAME_WINDOW_P (f)
12028 /* Don't try to reuse the display if windows have been split
12029 or such. */
12030 || windows_or_buffers_changed
12031 || cursor_type_changed)
12032 return 0;
12034 /* Can't do this if region may have changed. */
12035 if ((!NILP (Vtransient_mark_mode)
12036 && !NILP (current_buffer->mark_active))
12037 || !NILP (w->region_showing)
12038 || !NILP (Vshow_trailing_whitespace))
12039 return 0;
12041 /* If top-line visibility has changed, give up. */
12042 if (WINDOW_WANTS_HEADER_LINE_P (w)
12043 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
12044 return 0;
12046 /* Give up if old or new display is scrolled vertically. We could
12047 make this function handle this, but right now it doesn't. */
12048 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12049 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row))
12050 return 0;
12052 /* The variable new_start now holds the new window start. The old
12053 start `start' can be determined from the current matrix. */
12054 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
12055 start = start_row->start.pos;
12056 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
12058 /* Clear the desired matrix for the display below. */
12059 clear_glyph_matrix (w->desired_matrix);
12061 if (CHARPOS (new_start) <= CHARPOS (start))
12063 int first_row_y;
12065 /* Don't use this method if the display starts with an ellipsis
12066 displayed for invisible text. It's not easy to handle that case
12067 below, and it's certainly not worth the effort since this is
12068 not a frequent case. */
12069 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
12070 return 0;
12072 IF_DEBUG (debug_method_add (w, "twu1"));
12074 /* Display up to a row that can be reused. The variable
12075 last_text_row is set to the last row displayed that displays
12076 text. Note that it.vpos == 0 if or if not there is a
12077 header-line; it's not the same as the MATRIX_ROW_VPOS! */
12078 start_display (&it, w, new_start);
12079 first_row_y = it.current_y;
12080 w->cursor.vpos = -1;
12081 last_text_row = last_reused_text_row = NULL;
12083 while (it.current_y < it.last_visible_y
12084 && IT_CHARPOS (it) < CHARPOS (start)
12085 && !fonts_changed_p)
12086 if (display_line (&it))
12087 last_text_row = it.glyph_row - 1;
12089 /* A value of current_y < last_visible_y means that we stopped
12090 at the previous window start, which in turn means that we
12091 have at least one reusable row. */
12092 if (it.current_y < it.last_visible_y)
12094 /* IT.vpos always starts from 0; it counts text lines. */
12095 nrows_scrolled = it.vpos;
12097 /* Find PT if not already found in the lines displayed. */
12098 if (w->cursor.vpos < 0)
12100 int dy = it.current_y - first_row_y;
12102 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12103 row = row_containing_pos (w, PT, row, NULL, dy);
12104 if (row)
12105 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
12106 dy, nrows_scrolled);
12107 else
12109 clear_glyph_matrix (w->desired_matrix);
12110 return 0;
12114 /* Scroll the display. Do it before the current matrix is
12115 changed. The problem here is that update has not yet
12116 run, i.e. part of the current matrix is not up to date.
12117 scroll_run_hook will clear the cursor, and use the
12118 current matrix to get the height of the row the cursor is
12119 in. */
12120 run.current_y = first_row_y;
12121 run.desired_y = it.current_y;
12122 run.height = it.last_visible_y - it.current_y;
12124 if (run.height > 0 && run.current_y != run.desired_y)
12126 update_begin (f);
12127 rif->update_window_begin_hook (w);
12128 rif->clear_window_mouse_face (w);
12129 rif->scroll_run_hook (w, &run);
12130 rif->update_window_end_hook (w, 0, 0);
12131 update_end (f);
12134 /* Shift current matrix down by nrows_scrolled lines. */
12135 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12136 rotate_matrix (w->current_matrix,
12137 start_vpos,
12138 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12139 nrows_scrolled);
12141 /* Disable lines that must be updated. */
12142 for (i = 0; i < it.vpos; ++i)
12143 (start_row + i)->enabled_p = 0;
12145 /* Re-compute Y positions. */
12146 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12147 max_y = it.last_visible_y;
12148 for (row = start_row + nrows_scrolled;
12149 row < bottom_row;
12150 ++row)
12152 row->y = it.current_y;
12153 row->visible_height = row->height;
12155 if (row->y < min_y)
12156 row->visible_height -= min_y - row->y;
12157 if (row->y + row->height > max_y)
12158 row->visible_height -= row->y + row->height - max_y;
12159 row->redraw_fringe_bitmaps_p = 1;
12161 it.current_y += row->height;
12163 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12164 last_reused_text_row = row;
12165 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
12166 break;
12169 /* Disable lines in the current matrix which are now
12170 below the window. */
12171 for (++row; row < bottom_row; ++row)
12172 row->enabled_p = 0;
12175 /* Update window_end_pos etc.; last_reused_text_row is the last
12176 reused row from the current matrix containing text, if any.
12177 The value of last_text_row is the last displayed line
12178 containing text. */
12179 if (last_reused_text_row)
12181 w->window_end_bytepos
12182 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
12183 w->window_end_pos
12184 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
12185 w->window_end_vpos
12186 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
12187 w->current_matrix));
12189 else if (last_text_row)
12191 w->window_end_bytepos
12192 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12193 w->window_end_pos
12194 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12195 w->window_end_vpos
12196 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12198 else
12200 /* This window must be completely empty. */
12201 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12202 w->window_end_pos = make_number (Z - ZV);
12203 w->window_end_vpos = make_number (0);
12205 w->window_end_valid = Qnil;
12207 /* Update hint: don't try scrolling again in update_window. */
12208 w->desired_matrix->no_scrolling_p = 1;
12210 #if GLYPH_DEBUG
12211 debug_method_add (w, "try_window_reusing_current_matrix 1");
12212 #endif
12213 return 1;
12215 else if (CHARPOS (new_start) > CHARPOS (start))
12217 struct glyph_row *pt_row, *row;
12218 struct glyph_row *first_reusable_row;
12219 struct glyph_row *first_row_to_display;
12220 int dy;
12221 int yb = window_text_bottom_y (w);
12223 /* Find the row starting at new_start, if there is one. Don't
12224 reuse a partially visible line at the end. */
12225 first_reusable_row = start_row;
12226 while (first_reusable_row->enabled_p
12227 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
12228 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12229 < CHARPOS (new_start)))
12230 ++first_reusable_row;
12232 /* Give up if there is no row to reuse. */
12233 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
12234 || !first_reusable_row->enabled_p
12235 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12236 != CHARPOS (new_start)))
12237 return 0;
12239 /* We can reuse fully visible rows beginning with
12240 first_reusable_row to the end of the window. Set
12241 first_row_to_display to the first row that cannot be reused.
12242 Set pt_row to the row containing point, if there is any. */
12243 pt_row = NULL;
12244 for (first_row_to_display = first_reusable_row;
12245 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
12246 ++first_row_to_display)
12248 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
12249 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
12250 pt_row = first_row_to_display;
12253 /* Start displaying at the start of first_row_to_display. */
12254 xassert (first_row_to_display->y < yb);
12255 init_to_row_start (&it, w, first_row_to_display);
12257 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
12258 - start_vpos);
12259 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
12260 - nrows_scrolled);
12261 it.current_y = (first_row_to_display->y - first_reusable_row->y
12262 + WINDOW_HEADER_LINE_HEIGHT (w));
12264 /* Display lines beginning with first_row_to_display in the
12265 desired matrix. Set last_text_row to the last row displayed
12266 that displays text. */
12267 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
12268 if (pt_row == NULL)
12269 w->cursor.vpos = -1;
12270 last_text_row = NULL;
12271 while (it.current_y < it.last_visible_y && !fonts_changed_p)
12272 if (display_line (&it))
12273 last_text_row = it.glyph_row - 1;
12275 /* Give up If point isn't in a row displayed or reused. */
12276 if (w->cursor.vpos < 0)
12278 clear_glyph_matrix (w->desired_matrix);
12279 return 0;
12282 /* If point is in a reused row, adjust y and vpos of the cursor
12283 position. */
12284 if (pt_row)
12286 w->cursor.vpos -= MATRIX_ROW_VPOS (first_reusable_row,
12287 w->current_matrix);
12288 w->cursor.y -= first_reusable_row->y;
12291 /* Scroll the display. */
12292 run.current_y = first_reusable_row->y;
12293 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
12294 run.height = it.last_visible_y - run.current_y;
12295 dy = run.current_y - run.desired_y;
12297 if (run.height)
12299 update_begin (f);
12300 rif->update_window_begin_hook (w);
12301 rif->clear_window_mouse_face (w);
12302 rif->scroll_run_hook (w, &run);
12303 rif->update_window_end_hook (w, 0, 0);
12304 update_end (f);
12307 /* Adjust Y positions of reused rows. */
12308 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12309 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12310 max_y = it.last_visible_y;
12311 for (row = first_reusable_row; row < first_row_to_display; ++row)
12313 row->y -= dy;
12314 row->visible_height = row->height;
12315 if (row->y < min_y)
12316 row->visible_height -= min_y - row->y;
12317 if (row->y + row->height > max_y)
12318 row->visible_height -= row->y + row->height - max_y;
12319 row->redraw_fringe_bitmaps_p = 1;
12322 /* Scroll the current matrix. */
12323 xassert (nrows_scrolled > 0);
12324 rotate_matrix (w->current_matrix,
12325 start_vpos,
12326 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12327 -nrows_scrolled);
12329 /* Disable rows not reused. */
12330 for (row -= nrows_scrolled; row < bottom_row; ++row)
12331 row->enabled_p = 0;
12333 /* Adjust window end. A null value of last_text_row means that
12334 the window end is in reused rows which in turn means that
12335 only its vpos can have changed. */
12336 if (last_text_row)
12338 w->window_end_bytepos
12339 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12340 w->window_end_pos
12341 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12342 w->window_end_vpos
12343 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12345 else
12347 w->window_end_vpos
12348 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
12351 w->window_end_valid = Qnil;
12352 w->desired_matrix->no_scrolling_p = 1;
12354 #if GLYPH_DEBUG
12355 debug_method_add (w, "try_window_reusing_current_matrix 2");
12356 #endif
12357 return 1;
12360 return 0;
12365 /************************************************************************
12366 Window redisplay reusing current matrix when buffer has changed
12367 ************************************************************************/
12369 static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *));
12370 static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *,
12371 int *, int *));
12372 static struct glyph_row *
12373 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
12374 struct glyph_row *));
12377 /* Return the last row in MATRIX displaying text. If row START is
12378 non-null, start searching with that row. IT gives the dimensions
12379 of the display. Value is null if matrix is empty; otherwise it is
12380 a pointer to the row found. */
12382 static struct glyph_row *
12383 find_last_row_displaying_text (matrix, it, start)
12384 struct glyph_matrix *matrix;
12385 struct it *it;
12386 struct glyph_row *start;
12388 struct glyph_row *row, *row_found;
12390 /* Set row_found to the last row in IT->w's current matrix
12391 displaying text. The loop looks funny but think of partially
12392 visible lines. */
12393 row_found = NULL;
12394 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
12395 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12397 xassert (row->enabled_p);
12398 row_found = row;
12399 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
12400 break;
12401 ++row;
12404 return row_found;
12408 /* Return the last row in the current matrix of W that is not affected
12409 by changes at the start of current_buffer that occurred since W's
12410 current matrix was built. Value is null if no such row exists.
12412 BEG_UNCHANGED us the number of characters unchanged at the start of
12413 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
12414 first changed character in current_buffer. Characters at positions <
12415 BEG + BEG_UNCHANGED are at the same buffer positions as they were
12416 when the current matrix was built. */
12418 static struct glyph_row *
12419 find_last_unchanged_at_beg_row (w)
12420 struct window *w;
12422 int first_changed_pos = BEG + BEG_UNCHANGED;
12423 struct glyph_row *row;
12424 struct glyph_row *row_found = NULL;
12425 int yb = window_text_bottom_y (w);
12427 /* Find the last row displaying unchanged text. */
12428 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12429 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12430 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
12432 if (/* If row ends before first_changed_pos, it is unchanged,
12433 except in some case. */
12434 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
12435 /* When row ends in ZV and we write at ZV it is not
12436 unchanged. */
12437 && !row->ends_at_zv_p
12438 /* When first_changed_pos is the end of a continued line,
12439 row is not unchanged because it may be no longer
12440 continued. */
12441 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
12442 && (row->continued_p
12443 || row->exact_window_width_line_p)))
12444 row_found = row;
12446 /* Stop if last visible row. */
12447 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
12448 break;
12450 ++row;
12453 return row_found;
12457 /* Find the first glyph row in the current matrix of W that is not
12458 affected by changes at the end of current_buffer since the
12459 time W's current matrix was built.
12461 Return in *DELTA the number of chars by which buffer positions in
12462 unchanged text at the end of current_buffer must be adjusted.
12464 Return in *DELTA_BYTES the corresponding number of bytes.
12466 Value is null if no such row exists, i.e. all rows are affected by
12467 changes. */
12469 static struct glyph_row *
12470 find_first_unchanged_at_end_row (w, delta, delta_bytes)
12471 struct window *w;
12472 int *delta, *delta_bytes;
12474 struct glyph_row *row;
12475 struct glyph_row *row_found = NULL;
12477 *delta = *delta_bytes = 0;
12479 /* Display must not have been paused, otherwise the current matrix
12480 is not up to date. */
12481 if (NILP (w->window_end_valid))
12482 abort ();
12484 /* A value of window_end_pos >= END_UNCHANGED means that the window
12485 end is in the range of changed text. If so, there is no
12486 unchanged row at the end of W's current matrix. */
12487 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
12488 return NULL;
12490 /* Set row to the last row in W's current matrix displaying text. */
12491 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
12493 /* If matrix is entirely empty, no unchanged row exists. */
12494 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12496 /* The value of row is the last glyph row in the matrix having a
12497 meaningful buffer position in it. The end position of row
12498 corresponds to window_end_pos. This allows us to translate
12499 buffer positions in the current matrix to current buffer
12500 positions for characters not in changed text. */
12501 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
12502 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
12503 int last_unchanged_pos, last_unchanged_pos_old;
12504 struct glyph_row *first_text_row
12505 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12507 *delta = Z - Z_old;
12508 *delta_bytes = Z_BYTE - Z_BYTE_old;
12510 /* Set last_unchanged_pos to the buffer position of the last
12511 character in the buffer that has not been changed. Z is the
12512 index + 1 of the last character in current_buffer, i.e. by
12513 subtracting END_UNCHANGED we get the index of the last
12514 unchanged character, and we have to add BEG to get its buffer
12515 position. */
12516 last_unchanged_pos = Z - END_UNCHANGED + BEG;
12517 last_unchanged_pos_old = last_unchanged_pos - *delta;
12519 /* Search backward from ROW for a row displaying a line that
12520 starts at a minimum position >= last_unchanged_pos_old. */
12521 for (; row > first_text_row; --row)
12523 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
12524 abort ();
12526 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
12527 row_found = row;
12531 if (row_found && !MATRIX_ROW_DISPLAYS_TEXT_P (row_found))
12532 abort ();
12534 return row_found;
12538 /* Make sure that glyph rows in the current matrix of window W
12539 reference the same glyph memory as corresponding rows in the
12540 frame's frame matrix. This function is called after scrolling W's
12541 current matrix on a terminal frame in try_window_id and
12542 try_window_reusing_current_matrix. */
12544 static void
12545 sync_frame_with_window_matrix_rows (w)
12546 struct window *w;
12548 struct frame *f = XFRAME (w->frame);
12549 struct glyph_row *window_row, *window_row_end, *frame_row;
12551 /* Preconditions: W must be a leaf window and full-width. Its frame
12552 must have a frame matrix. */
12553 xassert (NILP (w->hchild) && NILP (w->vchild));
12554 xassert (WINDOW_FULL_WIDTH_P (w));
12555 xassert (!FRAME_WINDOW_P (f));
12557 /* If W is a full-width window, glyph pointers in W's current matrix
12558 have, by definition, to be the same as glyph pointers in the
12559 corresponding frame matrix. Note that frame matrices have no
12560 marginal areas (see build_frame_matrix). */
12561 window_row = w->current_matrix->rows;
12562 window_row_end = window_row + w->current_matrix->nrows;
12563 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
12564 while (window_row < window_row_end)
12566 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
12567 struct glyph *end = window_row->glyphs[LAST_AREA];
12569 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
12570 frame_row->glyphs[TEXT_AREA] = start;
12571 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
12572 frame_row->glyphs[LAST_AREA] = end;
12574 /* Disable frame rows whose corresponding window rows have
12575 been disabled in try_window_id. */
12576 if (!window_row->enabled_p)
12577 frame_row->enabled_p = 0;
12579 ++window_row, ++frame_row;
12584 /* Find the glyph row in window W containing CHARPOS. Consider all
12585 rows between START and END (not inclusive). END null means search
12586 all rows to the end of the display area of W. Value is the row
12587 containing CHARPOS or null. */
12589 struct glyph_row *
12590 row_containing_pos (w, charpos, start, end, dy)
12591 struct window *w;
12592 int charpos;
12593 struct glyph_row *start, *end;
12594 int dy;
12596 struct glyph_row *row = start;
12597 int last_y;
12599 /* If we happen to start on a header-line, skip that. */
12600 if (row->mode_line_p)
12601 ++row;
12603 if ((end && row >= end) || !row->enabled_p)
12604 return NULL;
12606 last_y = window_text_bottom_y (w) - dy;
12608 while (1)
12610 /* Give up if we have gone too far. */
12611 if (end && row >= end)
12612 return NULL;
12613 /* This formerly returned if they were equal.
12614 I think that both quantities are of a "last plus one" type;
12615 if so, when they are equal, the row is within the screen. -- rms. */
12616 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
12617 return NULL;
12619 /* If it is in this row, return this row. */
12620 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
12621 || (MATRIX_ROW_END_CHARPOS (row) == charpos
12622 /* The end position of a row equals the start
12623 position of the next row. If CHARPOS is there, we
12624 would rather display it in the next line, except
12625 when this line ends in ZV. */
12626 && !row->ends_at_zv_p
12627 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
12628 && charpos >= MATRIX_ROW_START_CHARPOS (row))
12629 return row;
12630 ++row;
12635 /* Try to redisplay window W by reusing its existing display. W's
12636 current matrix must be up to date when this function is called,
12637 i.e. window_end_valid must not be nil.
12639 Value is
12641 1 if display has been updated
12642 0 if otherwise unsuccessful
12643 -1 if redisplay with same window start is known not to succeed
12645 The following steps are performed:
12647 1. Find the last row in the current matrix of W that is not
12648 affected by changes at the start of current_buffer. If no such row
12649 is found, give up.
12651 2. Find the first row in W's current matrix that is not affected by
12652 changes at the end of current_buffer. Maybe there is no such row.
12654 3. Display lines beginning with the row + 1 found in step 1 to the
12655 row found in step 2 or, if step 2 didn't find a row, to the end of
12656 the window.
12658 4. If cursor is not known to appear on the window, give up.
12660 5. If display stopped at the row found in step 2, scroll the
12661 display and current matrix as needed.
12663 6. Maybe display some lines at the end of W, if we must. This can
12664 happen under various circumstances, like a partially visible line
12665 becoming fully visible, or because newly displayed lines are displayed
12666 in smaller font sizes.
12668 7. Update W's window end information. */
12670 static int
12671 try_window_id (w)
12672 struct window *w;
12674 struct frame *f = XFRAME (w->frame);
12675 struct glyph_matrix *current_matrix = w->current_matrix;
12676 struct glyph_matrix *desired_matrix = w->desired_matrix;
12677 struct glyph_row *last_unchanged_at_beg_row;
12678 struct glyph_row *first_unchanged_at_end_row;
12679 struct glyph_row *row;
12680 struct glyph_row *bottom_row;
12681 int bottom_vpos;
12682 struct it it;
12683 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
12684 struct text_pos start_pos;
12685 struct run run;
12686 int first_unchanged_at_end_vpos = 0;
12687 struct glyph_row *last_text_row, *last_text_row_at_end;
12688 struct text_pos start;
12689 int first_changed_charpos, last_changed_charpos;
12691 #if GLYPH_DEBUG
12692 if (inhibit_try_window_id)
12693 return 0;
12694 #endif
12696 /* This is handy for debugging. */
12697 #if 0
12698 #define GIVE_UP(X) \
12699 do { \
12700 fprintf (stderr, "try_window_id give up %d\n", (X)); \
12701 return 0; \
12702 } while (0)
12703 #else
12704 #define GIVE_UP(X) return 0
12705 #endif
12707 SET_TEXT_POS_FROM_MARKER (start, w->start);
12709 /* Don't use this for mini-windows because these can show
12710 messages and mini-buffers, and we don't handle that here. */
12711 if (MINI_WINDOW_P (w))
12712 GIVE_UP (1);
12714 /* This flag is used to prevent redisplay optimizations. */
12715 if (windows_or_buffers_changed || cursor_type_changed)
12716 GIVE_UP (2);
12718 /* Verify that narrowing has not changed.
12719 Also verify that we were not told to prevent redisplay optimizations.
12720 It would be nice to further
12721 reduce the number of cases where this prevents try_window_id. */
12722 if (current_buffer->clip_changed
12723 || current_buffer->prevent_redisplay_optimizations_p)
12724 GIVE_UP (3);
12726 /* Window must either use window-based redisplay or be full width. */
12727 if (!FRAME_WINDOW_P (f)
12728 && (!line_ins_del_ok
12729 || !WINDOW_FULL_WIDTH_P (w)))
12730 GIVE_UP (4);
12732 /* Give up if point is not known NOT to appear in W. */
12733 if (PT < CHARPOS (start))
12734 GIVE_UP (5);
12736 /* Another way to prevent redisplay optimizations. */
12737 if (XFASTINT (w->last_modified) == 0)
12738 GIVE_UP (6);
12740 /* Verify that window is not hscrolled. */
12741 if (XFASTINT (w->hscroll) != 0)
12742 GIVE_UP (7);
12744 /* Verify that display wasn't paused. */
12745 if (NILP (w->window_end_valid))
12746 GIVE_UP (8);
12748 /* Can't use this if highlighting a region because a cursor movement
12749 will do more than just set the cursor. */
12750 if (!NILP (Vtransient_mark_mode)
12751 && !NILP (current_buffer->mark_active))
12752 GIVE_UP (9);
12754 /* Likewise if highlighting trailing whitespace. */
12755 if (!NILP (Vshow_trailing_whitespace))
12756 GIVE_UP (11);
12758 /* Likewise if showing a region. */
12759 if (!NILP (w->region_showing))
12760 GIVE_UP (10);
12762 /* Can use this if overlay arrow position and or string have changed. */
12763 if (!EQ (last_arrow_position, COERCE_MARKER (Voverlay_arrow_position))
12764 || !EQ (last_arrow_string, Voverlay_arrow_string))
12765 GIVE_UP (12);
12768 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
12769 only if buffer has really changed. The reason is that the gap is
12770 initially at Z for freshly visited files. The code below would
12771 set end_unchanged to 0 in that case. */
12772 if (MODIFF > SAVE_MODIFF
12773 /* This seems to happen sometimes after saving a buffer. */
12774 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
12776 if (GPT - BEG < BEG_UNCHANGED)
12777 BEG_UNCHANGED = GPT - BEG;
12778 if (Z - GPT < END_UNCHANGED)
12779 END_UNCHANGED = Z - GPT;
12782 /* The position of the first and last character that has been changed. */
12783 first_changed_charpos = BEG + BEG_UNCHANGED;
12784 last_changed_charpos = Z - END_UNCHANGED;
12786 /* If window starts after a line end, and the last change is in
12787 front of that newline, then changes don't affect the display.
12788 This case happens with stealth-fontification. Note that although
12789 the display is unchanged, glyph positions in the matrix have to
12790 be adjusted, of course. */
12791 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
12792 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12793 && ((last_changed_charpos < CHARPOS (start)
12794 && CHARPOS (start) == BEGV)
12795 || (last_changed_charpos < CHARPOS (start) - 1
12796 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
12798 int Z_old, delta, Z_BYTE_old, delta_bytes;
12799 struct glyph_row *r0;
12801 /* Compute how many chars/bytes have been added to or removed
12802 from the buffer. */
12803 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
12804 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
12805 delta = Z - Z_old;
12806 delta_bytes = Z_BYTE - Z_BYTE_old;
12808 /* Give up if PT is not in the window. Note that it already has
12809 been checked at the start of try_window_id that PT is not in
12810 front of the window start. */
12811 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
12812 GIVE_UP (13);
12814 /* If window start is unchanged, we can reuse the whole matrix
12815 as is, after adjusting glyph positions. No need to compute
12816 the window end again, since its offset from Z hasn't changed. */
12817 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
12818 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
12819 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
12820 /* PT must not be in a partially visible line. */
12821 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
12822 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
12824 /* Adjust positions in the glyph matrix. */
12825 if (delta || delta_bytes)
12827 struct glyph_row *r1
12828 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
12829 increment_matrix_positions (w->current_matrix,
12830 MATRIX_ROW_VPOS (r0, current_matrix),
12831 MATRIX_ROW_VPOS (r1, current_matrix),
12832 delta, delta_bytes);
12835 /* Set the cursor. */
12836 row = row_containing_pos (w, PT, r0, NULL, 0);
12837 if (row)
12838 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
12839 else
12840 abort ();
12841 return 1;
12845 /* Handle the case that changes are all below what is displayed in
12846 the window, and that PT is in the window. This shortcut cannot
12847 be taken if ZV is visible in the window, and text has been added
12848 there that is visible in the window. */
12849 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
12850 /* ZV is not visible in the window, or there are no
12851 changes at ZV, actually. */
12852 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
12853 || first_changed_charpos == last_changed_charpos))
12855 struct glyph_row *r0;
12857 /* Give up if PT is not in the window. Note that it already has
12858 been checked at the start of try_window_id that PT is not in
12859 front of the window start. */
12860 if (PT >= MATRIX_ROW_END_CHARPOS (row))
12861 GIVE_UP (14);
12863 /* If window start is unchanged, we can reuse the whole matrix
12864 as is, without changing glyph positions since no text has
12865 been added/removed in front of the window end. */
12866 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
12867 if (TEXT_POS_EQUAL_P (start, r0->start.pos)
12868 /* PT must not be in a partially visible line. */
12869 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
12870 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
12872 /* We have to compute the window end anew since text
12873 can have been added/removed after it. */
12874 w->window_end_pos
12875 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
12876 w->window_end_bytepos
12877 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
12879 /* Set the cursor. */
12880 row = row_containing_pos (w, PT, r0, NULL, 0);
12881 if (row)
12882 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
12883 else
12884 abort ();
12885 return 2;
12889 /* Give up if window start is in the changed area.
12891 The condition used to read
12893 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
12895 but why that was tested escapes me at the moment. */
12896 if (CHARPOS (start) >= first_changed_charpos
12897 && CHARPOS (start) <= last_changed_charpos)
12898 GIVE_UP (15);
12900 /* Check that window start agrees with the start of the first glyph
12901 row in its current matrix. Check this after we know the window
12902 start is not in changed text, otherwise positions would not be
12903 comparable. */
12904 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
12905 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
12906 GIVE_UP (16);
12908 /* Give up if the window ends in strings. Overlay strings
12909 at the end are difficult to handle, so don't try. */
12910 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
12911 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
12912 GIVE_UP (20);
12914 /* Compute the position at which we have to start displaying new
12915 lines. Some of the lines at the top of the window might be
12916 reusable because they are not displaying changed text. Find the
12917 last row in W's current matrix not affected by changes at the
12918 start of current_buffer. Value is null if changes start in the
12919 first line of window. */
12920 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
12921 if (last_unchanged_at_beg_row)
12923 /* Avoid starting to display in the moddle of a character, a TAB
12924 for instance. This is easier than to set up the iterator
12925 exactly, and it's not a frequent case, so the additional
12926 effort wouldn't really pay off. */
12927 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
12928 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
12929 && last_unchanged_at_beg_row > w->current_matrix->rows)
12930 --last_unchanged_at_beg_row;
12932 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
12933 GIVE_UP (17);
12935 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
12936 GIVE_UP (18);
12937 start_pos = it.current.pos;
12939 /* Start displaying new lines in the desired matrix at the same
12940 vpos we would use in the current matrix, i.e. below
12941 last_unchanged_at_beg_row. */
12942 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
12943 current_matrix);
12944 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
12945 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
12947 xassert (it.hpos == 0 && it.current_x == 0);
12949 else
12951 /* There are no reusable lines at the start of the window.
12952 Start displaying in the first text line. */
12953 start_display (&it, w, start);
12954 it.vpos = it.first_vpos;
12955 start_pos = it.current.pos;
12958 /* Find the first row that is not affected by changes at the end of
12959 the buffer. Value will be null if there is no unchanged row, in
12960 which case we must redisplay to the end of the window. delta
12961 will be set to the value by which buffer positions beginning with
12962 first_unchanged_at_end_row have to be adjusted due to text
12963 changes. */
12964 first_unchanged_at_end_row
12965 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
12966 IF_DEBUG (debug_delta = delta);
12967 IF_DEBUG (debug_delta_bytes = delta_bytes);
12969 /* Set stop_pos to the buffer position up to which we will have to
12970 display new lines. If first_unchanged_at_end_row != NULL, this
12971 is the buffer position of the start of the line displayed in that
12972 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
12973 that we don't stop at a buffer position. */
12974 stop_pos = 0;
12975 if (first_unchanged_at_end_row)
12977 xassert (last_unchanged_at_beg_row == NULL
12978 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
12980 /* If this is a continuation line, move forward to the next one
12981 that isn't. Changes in lines above affect this line.
12982 Caution: this may move first_unchanged_at_end_row to a row
12983 not displaying text. */
12984 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
12985 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
12986 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
12987 < it.last_visible_y))
12988 ++first_unchanged_at_end_row;
12990 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
12991 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
12992 >= it.last_visible_y))
12993 first_unchanged_at_end_row = NULL;
12994 else
12996 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
12997 + delta);
12998 first_unchanged_at_end_vpos
12999 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
13000 xassert (stop_pos >= Z - END_UNCHANGED);
13003 else if (last_unchanged_at_beg_row == NULL)
13004 GIVE_UP (19);
13007 #if GLYPH_DEBUG
13009 /* Either there is no unchanged row at the end, or the one we have
13010 now displays text. This is a necessary condition for the window
13011 end pos calculation at the end of this function. */
13012 xassert (first_unchanged_at_end_row == NULL
13013 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
13015 debug_last_unchanged_at_beg_vpos
13016 = (last_unchanged_at_beg_row
13017 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
13018 : -1);
13019 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
13021 #endif /* GLYPH_DEBUG != 0 */
13024 /* Display new lines. Set last_text_row to the last new line
13025 displayed which has text on it, i.e. might end up as being the
13026 line where the window_end_vpos is. */
13027 w->cursor.vpos = -1;
13028 last_text_row = NULL;
13029 overlay_arrow_seen = 0;
13030 while (it.current_y < it.last_visible_y
13031 && !fonts_changed_p
13032 && (first_unchanged_at_end_row == NULL
13033 || IT_CHARPOS (it) < stop_pos))
13035 if (display_line (&it))
13036 last_text_row = it.glyph_row - 1;
13039 if (fonts_changed_p)
13040 return -1;
13043 /* Compute differences in buffer positions, y-positions etc. for
13044 lines reused at the bottom of the window. Compute what we can
13045 scroll. */
13046 if (first_unchanged_at_end_row
13047 /* No lines reused because we displayed everything up to the
13048 bottom of the window. */
13049 && it.current_y < it.last_visible_y)
13051 dvpos = (it.vpos
13052 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
13053 current_matrix));
13054 dy = it.current_y - first_unchanged_at_end_row->y;
13055 run.current_y = first_unchanged_at_end_row->y;
13056 run.desired_y = run.current_y + dy;
13057 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
13059 else
13061 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
13062 first_unchanged_at_end_row = NULL;
13064 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
13067 /* Find the cursor if not already found. We have to decide whether
13068 PT will appear on this window (it sometimes doesn't, but this is
13069 not a very frequent case.) This decision has to be made before
13070 the current matrix is altered. A value of cursor.vpos < 0 means
13071 that PT is either in one of the lines beginning at
13072 first_unchanged_at_end_row or below the window. Don't care for
13073 lines that might be displayed later at the window end; as
13074 mentioned, this is not a frequent case. */
13075 if (w->cursor.vpos < 0)
13077 /* Cursor in unchanged rows at the top? */
13078 if (PT < CHARPOS (start_pos)
13079 && last_unchanged_at_beg_row)
13081 row = row_containing_pos (w, PT,
13082 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
13083 last_unchanged_at_beg_row + 1, 0);
13084 if (row)
13085 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13088 /* Start from first_unchanged_at_end_row looking for PT. */
13089 else if (first_unchanged_at_end_row)
13091 row = row_containing_pos (w, PT - delta,
13092 first_unchanged_at_end_row, NULL, 0);
13093 if (row)
13094 set_cursor_from_row (w, row, w->current_matrix, delta,
13095 delta_bytes, dy, dvpos);
13098 /* Give up if cursor was not found. */
13099 if (w->cursor.vpos < 0)
13101 clear_glyph_matrix (w->desired_matrix);
13102 return -1;
13106 /* Don't let the cursor end in the scroll margins. */
13108 int this_scroll_margin, cursor_height;
13110 this_scroll_margin = max (0, scroll_margin);
13111 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13112 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
13113 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
13115 if ((w->cursor.y < this_scroll_margin
13116 && CHARPOS (start) > BEGV)
13117 /* Don't take scroll margin into account at the bottom because
13118 old redisplay didn't do it either. */
13119 || w->cursor.y + cursor_height > it.last_visible_y)
13121 w->cursor.vpos = -1;
13122 clear_glyph_matrix (w->desired_matrix);
13123 return -1;
13127 /* Scroll the display. Do it before changing the current matrix so
13128 that xterm.c doesn't get confused about where the cursor glyph is
13129 found. */
13130 if (dy && run.height)
13132 update_begin (f);
13134 if (FRAME_WINDOW_P (f))
13136 rif->update_window_begin_hook (w);
13137 rif->clear_window_mouse_face (w);
13138 rif->scroll_run_hook (w, &run);
13139 rif->update_window_end_hook (w, 0, 0);
13141 else
13143 /* Terminal frame. In this case, dvpos gives the number of
13144 lines to scroll by; dvpos < 0 means scroll up. */
13145 int first_unchanged_at_end_vpos
13146 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
13147 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
13148 int end = (WINDOW_TOP_EDGE_LINE (w)
13149 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
13150 + window_internal_height (w));
13152 /* Perform the operation on the screen. */
13153 if (dvpos > 0)
13155 /* Scroll last_unchanged_at_beg_row to the end of the
13156 window down dvpos lines. */
13157 set_terminal_window (end);
13159 /* On dumb terminals delete dvpos lines at the end
13160 before inserting dvpos empty lines. */
13161 if (!scroll_region_ok)
13162 ins_del_lines (end - dvpos, -dvpos);
13164 /* Insert dvpos empty lines in front of
13165 last_unchanged_at_beg_row. */
13166 ins_del_lines (from, dvpos);
13168 else if (dvpos < 0)
13170 /* Scroll up last_unchanged_at_beg_vpos to the end of
13171 the window to last_unchanged_at_beg_vpos - |dvpos|. */
13172 set_terminal_window (end);
13174 /* Delete dvpos lines in front of
13175 last_unchanged_at_beg_vpos. ins_del_lines will set
13176 the cursor to the given vpos and emit |dvpos| delete
13177 line sequences. */
13178 ins_del_lines (from + dvpos, dvpos);
13180 /* On a dumb terminal insert dvpos empty lines at the
13181 end. */
13182 if (!scroll_region_ok)
13183 ins_del_lines (end + dvpos, -dvpos);
13186 set_terminal_window (0);
13189 update_end (f);
13192 /* Shift reused rows of the current matrix to the right position.
13193 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
13194 text. */
13195 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13196 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
13197 if (dvpos < 0)
13199 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
13200 bottom_vpos, dvpos);
13201 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
13202 bottom_vpos, 0);
13204 else if (dvpos > 0)
13206 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
13207 bottom_vpos, dvpos);
13208 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
13209 first_unchanged_at_end_vpos + dvpos, 0);
13212 /* For frame-based redisplay, make sure that current frame and window
13213 matrix are in sync with respect to glyph memory. */
13214 if (!FRAME_WINDOW_P (f))
13215 sync_frame_with_window_matrix_rows (w);
13217 /* Adjust buffer positions in reused rows. */
13218 if (delta)
13219 increment_matrix_positions (current_matrix,
13220 first_unchanged_at_end_vpos + dvpos,
13221 bottom_vpos, delta, delta_bytes);
13223 /* Adjust Y positions. */
13224 if (dy)
13225 shift_glyph_matrix (w, current_matrix,
13226 first_unchanged_at_end_vpos + dvpos,
13227 bottom_vpos, dy);
13229 if (first_unchanged_at_end_row)
13230 first_unchanged_at_end_row += dvpos;
13232 /* If scrolling up, there may be some lines to display at the end of
13233 the window. */
13234 last_text_row_at_end = NULL;
13235 if (dy < 0)
13237 /* Scrolling up can leave for example a partially visible line
13238 at the end of the window to be redisplayed. */
13239 /* Set last_row to the glyph row in the current matrix where the
13240 window end line is found. It has been moved up or down in
13241 the matrix by dvpos. */
13242 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
13243 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
13245 /* If last_row is the window end line, it should display text. */
13246 xassert (last_row->displays_text_p);
13248 /* If window end line was partially visible before, begin
13249 displaying at that line. Otherwise begin displaying with the
13250 line following it. */
13251 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
13253 init_to_row_start (&it, w, last_row);
13254 it.vpos = last_vpos;
13255 it.current_y = last_row->y;
13257 else
13259 init_to_row_end (&it, w, last_row);
13260 it.vpos = 1 + last_vpos;
13261 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
13262 ++last_row;
13265 /* We may start in a continuation line. If so, we have to
13266 get the right continuation_lines_width and current_x. */
13267 it.continuation_lines_width = last_row->continuation_lines_width;
13268 it.hpos = it.current_x = 0;
13270 /* Display the rest of the lines at the window end. */
13271 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13272 while (it.current_y < it.last_visible_y
13273 && !fonts_changed_p)
13275 /* Is it always sure that the display agrees with lines in
13276 the current matrix? I don't think so, so we mark rows
13277 displayed invalid in the current matrix by setting their
13278 enabled_p flag to zero. */
13279 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
13280 if (display_line (&it))
13281 last_text_row_at_end = it.glyph_row - 1;
13285 /* Update window_end_pos and window_end_vpos. */
13286 if (first_unchanged_at_end_row
13287 && first_unchanged_at_end_row->y < it.last_visible_y
13288 && !last_text_row_at_end)
13290 /* Window end line if one of the preserved rows from the current
13291 matrix. Set row to the last row displaying text in current
13292 matrix starting at first_unchanged_at_end_row, after
13293 scrolling. */
13294 xassert (first_unchanged_at_end_row->displays_text_p);
13295 row = find_last_row_displaying_text (w->current_matrix, &it,
13296 first_unchanged_at_end_row);
13297 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
13299 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13300 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13301 w->window_end_vpos
13302 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
13303 xassert (w->window_end_bytepos >= 0);
13304 IF_DEBUG (debug_method_add (w, "A"));
13306 else if (last_text_row_at_end)
13308 w->window_end_pos
13309 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
13310 w->window_end_bytepos
13311 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
13312 w->window_end_vpos
13313 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
13314 xassert (w->window_end_bytepos >= 0);
13315 IF_DEBUG (debug_method_add (w, "B"));
13317 else if (last_text_row)
13319 /* We have displayed either to the end of the window or at the
13320 end of the window, i.e. the last row with text is to be found
13321 in the desired matrix. */
13322 w->window_end_pos
13323 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13324 w->window_end_bytepos
13325 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13326 w->window_end_vpos
13327 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
13328 xassert (w->window_end_bytepos >= 0);
13330 else if (first_unchanged_at_end_row == NULL
13331 && last_text_row == NULL
13332 && last_text_row_at_end == NULL)
13334 /* Displayed to end of window, but no line containing text was
13335 displayed. Lines were deleted at the end of the window. */
13336 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
13337 int vpos = XFASTINT (w->window_end_vpos);
13338 struct glyph_row *current_row = current_matrix->rows + vpos;
13339 struct glyph_row *desired_row = desired_matrix->rows + vpos;
13341 for (row = NULL;
13342 row == NULL && vpos >= first_vpos;
13343 --vpos, --current_row, --desired_row)
13345 if (desired_row->enabled_p)
13347 if (desired_row->displays_text_p)
13348 row = desired_row;
13350 else if (current_row->displays_text_p)
13351 row = current_row;
13354 xassert (row != NULL);
13355 w->window_end_vpos = make_number (vpos + 1);
13356 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13357 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13358 xassert (w->window_end_bytepos >= 0);
13359 IF_DEBUG (debug_method_add (w, "C"));
13361 else
13362 abort ();
13364 #if 0 /* This leads to problems, for instance when the cursor is
13365 at ZV, and the cursor line displays no text. */
13366 /* Disable rows below what's displayed in the window. This makes
13367 debugging easier. */
13368 enable_glyph_matrix_rows (current_matrix,
13369 XFASTINT (w->window_end_vpos) + 1,
13370 bottom_vpos, 0);
13371 #endif
13373 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
13374 debug_end_vpos = XFASTINT (w->window_end_vpos));
13376 /* Record that display has not been completed. */
13377 w->window_end_valid = Qnil;
13378 w->desired_matrix->no_scrolling_p = 1;
13379 return 3;
13381 #undef GIVE_UP
13386 /***********************************************************************
13387 More debugging support
13388 ***********************************************************************/
13390 #if GLYPH_DEBUG
13392 void dump_glyph_row P_ ((struct glyph_row *, int, int));
13393 void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
13394 void dump_glyph P_ ((struct glyph_row *, struct glyph *, int));
13397 /* Dump the contents of glyph matrix MATRIX on stderr.
13399 GLYPHS 0 means don't show glyph contents.
13400 GLYPHS 1 means show glyphs in short form
13401 GLYPHS > 1 means show glyphs in long form. */
13403 void
13404 dump_glyph_matrix (matrix, glyphs)
13405 struct glyph_matrix *matrix;
13406 int glyphs;
13408 int i;
13409 for (i = 0; i < matrix->nrows; ++i)
13410 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
13414 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
13415 the glyph row and area where the glyph comes from. */
13417 void
13418 dump_glyph (row, glyph, area)
13419 struct glyph_row *row;
13420 struct glyph *glyph;
13421 int area;
13423 if (glyph->type == CHAR_GLYPH)
13425 fprintf (stderr,
13426 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13427 glyph - row->glyphs[TEXT_AREA],
13428 'C',
13429 glyph->charpos,
13430 (BUFFERP (glyph->object)
13431 ? 'B'
13432 : (STRINGP (glyph->object)
13433 ? 'S'
13434 : '-')),
13435 glyph->pixel_width,
13436 glyph->u.ch,
13437 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
13438 ? glyph->u.ch
13439 : '.'),
13440 glyph->face_id,
13441 glyph->left_box_line_p,
13442 glyph->right_box_line_p);
13444 else if (glyph->type == STRETCH_GLYPH)
13446 fprintf (stderr,
13447 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13448 glyph - row->glyphs[TEXT_AREA],
13449 'S',
13450 glyph->charpos,
13451 (BUFFERP (glyph->object)
13452 ? 'B'
13453 : (STRINGP (glyph->object)
13454 ? 'S'
13455 : '-')),
13456 glyph->pixel_width,
13458 '.',
13459 glyph->face_id,
13460 glyph->left_box_line_p,
13461 glyph->right_box_line_p);
13463 else if (glyph->type == IMAGE_GLYPH)
13465 fprintf (stderr,
13466 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13467 glyph - row->glyphs[TEXT_AREA],
13468 'I',
13469 glyph->charpos,
13470 (BUFFERP (glyph->object)
13471 ? 'B'
13472 : (STRINGP (glyph->object)
13473 ? 'S'
13474 : '-')),
13475 glyph->pixel_width,
13476 glyph->u.img_id,
13477 '.',
13478 glyph->face_id,
13479 glyph->left_box_line_p,
13480 glyph->right_box_line_p);
13485 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
13486 GLYPHS 0 means don't show glyph contents.
13487 GLYPHS 1 means show glyphs in short form
13488 GLYPHS > 1 means show glyphs in long form. */
13490 void
13491 dump_glyph_row (row, vpos, glyphs)
13492 struct glyph_row *row;
13493 int vpos, glyphs;
13495 if (glyphs != 1)
13497 fprintf (stderr, "Row Start End Used oEI><O\\CTZFesm X Y W H V A P\n");
13498 fprintf (stderr, "=======================================================================\n");
13500 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d%1.1d\
13501 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
13502 vpos,
13503 MATRIX_ROW_START_CHARPOS (row),
13504 MATRIX_ROW_END_CHARPOS (row),
13505 row->used[TEXT_AREA],
13506 row->contains_overlapping_glyphs_p,
13507 row->enabled_p,
13508 row->truncated_on_left_p,
13509 row->truncated_on_right_p,
13510 row->overlay_arrow_p,
13511 row->continued_p,
13512 MATRIX_ROW_CONTINUATION_LINE_P (row),
13513 row->displays_text_p,
13514 row->ends_at_zv_p,
13515 row->fill_line_p,
13516 row->ends_in_middle_of_char_p,
13517 row->starts_in_middle_of_char_p,
13518 row->mouse_face_p,
13519 row->x,
13520 row->y,
13521 row->pixel_width,
13522 row->height,
13523 row->visible_height,
13524 row->ascent,
13525 row->phys_ascent);
13526 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
13527 row->end.overlay_string_index,
13528 row->continuation_lines_width);
13529 fprintf (stderr, "%9d %5d\n",
13530 CHARPOS (row->start.string_pos),
13531 CHARPOS (row->end.string_pos));
13532 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
13533 row->end.dpvec_index);
13536 if (glyphs > 1)
13538 int area;
13540 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
13542 struct glyph *glyph = row->glyphs[area];
13543 struct glyph *glyph_end = glyph + row->used[area];
13545 /* Glyph for a line end in text. */
13546 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
13547 ++glyph_end;
13549 if (glyph < glyph_end)
13550 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
13552 for (; glyph < glyph_end; ++glyph)
13553 dump_glyph (row, glyph, area);
13556 else if (glyphs == 1)
13558 int area;
13560 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
13562 char *s = (char *) alloca (row->used[area] + 1);
13563 int i;
13565 for (i = 0; i < row->used[area]; ++i)
13567 struct glyph *glyph = row->glyphs[area] + i;
13568 if (glyph->type == CHAR_GLYPH
13569 && glyph->u.ch < 0x80
13570 && glyph->u.ch >= ' ')
13571 s[i] = glyph->u.ch;
13572 else
13573 s[i] = '.';
13576 s[i] = '\0';
13577 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
13583 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
13584 Sdump_glyph_matrix, 0, 1, "p",
13585 doc: /* Dump the current matrix of the selected window to stderr.
13586 Shows contents of glyph row structures. With non-nil
13587 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
13588 glyphs in short form, otherwise show glyphs in long form. */)
13589 (glyphs)
13590 Lisp_Object glyphs;
13592 struct window *w = XWINDOW (selected_window);
13593 struct buffer *buffer = XBUFFER (w->buffer);
13595 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
13596 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
13597 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
13598 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
13599 fprintf (stderr, "=============================================\n");
13600 dump_glyph_matrix (w->current_matrix,
13601 NILP (glyphs) ? 0 : XINT (glyphs));
13602 return Qnil;
13606 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
13607 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
13610 struct frame *f = XFRAME (selected_frame);
13611 dump_glyph_matrix (f->current_matrix, 1);
13612 return Qnil;
13616 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
13617 doc: /* Dump glyph row ROW to stderr.
13618 GLYPH 0 means don't dump glyphs.
13619 GLYPH 1 means dump glyphs in short form.
13620 GLYPH > 1 or omitted means dump glyphs in long form. */)
13621 (row, glyphs)
13622 Lisp_Object row, glyphs;
13624 struct glyph_matrix *matrix;
13625 int vpos;
13627 CHECK_NUMBER (row);
13628 matrix = XWINDOW (selected_window)->current_matrix;
13629 vpos = XINT (row);
13630 if (vpos >= 0 && vpos < matrix->nrows)
13631 dump_glyph_row (MATRIX_ROW (matrix, vpos),
13632 vpos,
13633 INTEGERP (glyphs) ? XINT (glyphs) : 2);
13634 return Qnil;
13638 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
13639 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
13640 GLYPH 0 means don't dump glyphs.
13641 GLYPH 1 means dump glyphs in short form.
13642 GLYPH > 1 or omitted means dump glyphs in long form. */)
13643 (row, glyphs)
13644 Lisp_Object row, glyphs;
13646 struct frame *sf = SELECTED_FRAME ();
13647 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
13648 int vpos;
13650 CHECK_NUMBER (row);
13651 vpos = XINT (row);
13652 if (vpos >= 0 && vpos < m->nrows)
13653 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
13654 INTEGERP (glyphs) ? XINT (glyphs) : 2);
13655 return Qnil;
13659 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
13660 doc: /* Toggle tracing of redisplay.
13661 With ARG, turn tracing on if and only if ARG is positive. */)
13662 (arg)
13663 Lisp_Object arg;
13665 if (NILP (arg))
13666 trace_redisplay_p = !trace_redisplay_p;
13667 else
13669 arg = Fprefix_numeric_value (arg);
13670 trace_redisplay_p = XINT (arg) > 0;
13673 return Qnil;
13677 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
13678 doc: /* Like `format', but print result to stderr.
13679 usage: (trace-to-stderr STRING &rest OBJECTS) */)
13680 (nargs, args)
13681 int nargs;
13682 Lisp_Object *args;
13684 Lisp_Object s = Fformat (nargs, args);
13685 fprintf (stderr, "%s", SDATA (s));
13686 return Qnil;
13689 #endif /* GLYPH_DEBUG */
13693 /***********************************************************************
13694 Building Desired Matrix Rows
13695 ***********************************************************************/
13697 /* Return a temporary glyph row holding the glyphs of an overlay
13698 arrow. Only used for non-window-redisplay windows. */
13700 static struct glyph_row *
13701 get_overlay_arrow_glyph_row (w)
13702 struct window *w;
13704 struct frame *f = XFRAME (WINDOW_FRAME (w));
13705 struct buffer *buffer = XBUFFER (w->buffer);
13706 struct buffer *old = current_buffer;
13707 const unsigned char *arrow_string = SDATA (Voverlay_arrow_string);
13708 int arrow_len = SCHARS (Voverlay_arrow_string);
13709 const unsigned char *arrow_end = arrow_string + arrow_len;
13710 const unsigned char *p;
13711 struct it it;
13712 int multibyte_p;
13713 int n_glyphs_before;
13715 set_buffer_temp (buffer);
13716 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
13717 it.glyph_row->used[TEXT_AREA] = 0;
13718 SET_TEXT_POS (it.position, 0, 0);
13720 multibyte_p = !NILP (buffer->enable_multibyte_characters);
13721 p = arrow_string;
13722 while (p < arrow_end)
13724 Lisp_Object face, ilisp;
13726 /* Get the next character. */
13727 if (multibyte_p)
13728 it.c = string_char_and_length (p, arrow_len, &it.len);
13729 else
13730 it.c = *p, it.len = 1;
13731 p += it.len;
13733 /* Get its face. */
13734 ilisp = make_number (p - arrow_string);
13735 face = Fget_text_property (ilisp, Qface, Voverlay_arrow_string);
13736 it.face_id = compute_char_face (f, it.c, face);
13738 /* Compute its width, get its glyphs. */
13739 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
13740 SET_TEXT_POS (it.position, -1, -1);
13741 PRODUCE_GLYPHS (&it);
13743 /* If this character doesn't fit any more in the line, we have
13744 to remove some glyphs. */
13745 if (it.current_x > it.last_visible_x)
13747 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
13748 break;
13752 set_buffer_temp (old);
13753 return it.glyph_row;
13757 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
13758 glyphs are only inserted for terminal frames since we can't really
13759 win with truncation glyphs when partially visible glyphs are
13760 involved. Which glyphs to insert is determined by
13761 produce_special_glyphs. */
13763 static void
13764 insert_left_trunc_glyphs (it)
13765 struct it *it;
13767 struct it truncate_it;
13768 struct glyph *from, *end, *to, *toend;
13770 xassert (!FRAME_WINDOW_P (it->f));
13772 /* Get the truncation glyphs. */
13773 truncate_it = *it;
13774 truncate_it.current_x = 0;
13775 truncate_it.face_id = DEFAULT_FACE_ID;
13776 truncate_it.glyph_row = &scratch_glyph_row;
13777 truncate_it.glyph_row->used[TEXT_AREA] = 0;
13778 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
13779 truncate_it.object = make_number (0);
13780 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
13782 /* Overwrite glyphs from IT with truncation glyphs. */
13783 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
13784 end = from + truncate_it.glyph_row->used[TEXT_AREA];
13785 to = it->glyph_row->glyphs[TEXT_AREA];
13786 toend = to + it->glyph_row->used[TEXT_AREA];
13788 while (from < end)
13789 *to++ = *from++;
13791 /* There may be padding glyphs left over. Overwrite them too. */
13792 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
13794 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
13795 while (from < end)
13796 *to++ = *from++;
13799 if (to > toend)
13800 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
13804 /* Compute the pixel height and width of IT->glyph_row.
13806 Most of the time, ascent and height of a display line will be equal
13807 to the max_ascent and max_height values of the display iterator
13808 structure. This is not the case if
13810 1. We hit ZV without displaying anything. In this case, max_ascent
13811 and max_height will be zero.
13813 2. We have some glyphs that don't contribute to the line height.
13814 (The glyph row flag contributes_to_line_height_p is for future
13815 pixmap extensions).
13817 The first case is easily covered by using default values because in
13818 these cases, the line height does not really matter, except that it
13819 must not be zero. */
13821 static void
13822 compute_line_metrics (it)
13823 struct it *it;
13825 struct glyph_row *row = it->glyph_row;
13826 int area, i;
13828 if (FRAME_WINDOW_P (it->f))
13830 int i, min_y, max_y;
13832 /* The line may consist of one space only, that was added to
13833 place the cursor on it. If so, the row's height hasn't been
13834 computed yet. */
13835 if (row->height == 0)
13837 if (it->max_ascent + it->max_descent == 0)
13838 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
13839 row->ascent = it->max_ascent;
13840 row->height = it->max_ascent + it->max_descent;
13841 row->phys_ascent = it->max_phys_ascent;
13842 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
13845 /* Compute the width of this line. */
13846 row->pixel_width = row->x;
13847 for (i = 0; i < row->used[TEXT_AREA]; ++i)
13848 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
13850 xassert (row->pixel_width >= 0);
13851 xassert (row->ascent >= 0 && row->height > 0);
13853 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
13854 || MATRIX_ROW_OVERLAPS_PRED_P (row));
13856 /* If first line's physical ascent is larger than its logical
13857 ascent, use the physical ascent, and make the row taller.
13858 This makes accented characters fully visible. */
13859 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
13860 && row->phys_ascent > row->ascent)
13862 row->height += row->phys_ascent - row->ascent;
13863 row->ascent = row->phys_ascent;
13866 /* Compute how much of the line is visible. */
13867 row->visible_height = row->height;
13869 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
13870 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
13872 if (row->y < min_y)
13873 row->visible_height -= min_y - row->y;
13874 if (row->y + row->height > max_y)
13875 row->visible_height -= row->y + row->height - max_y;
13877 else
13879 row->pixel_width = row->used[TEXT_AREA];
13880 if (row->continued_p)
13881 row->pixel_width -= it->continuation_pixel_width;
13882 else if (row->truncated_on_right_p)
13883 row->pixel_width -= it->truncation_pixel_width;
13884 row->ascent = row->phys_ascent = 0;
13885 row->height = row->phys_height = row->visible_height = 1;
13888 /* Compute a hash code for this row. */
13889 row->hash = 0;
13890 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
13891 for (i = 0; i < row->used[area]; ++i)
13892 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
13893 + row->glyphs[area][i].u.val
13894 + row->glyphs[area][i].face_id
13895 + row->glyphs[area][i].padding_p
13896 + (row->glyphs[area][i].type << 2));
13898 it->max_ascent = it->max_descent = 0;
13899 it->max_phys_ascent = it->max_phys_descent = 0;
13903 /* Append one space to the glyph row of iterator IT if doing a
13904 window-based redisplay. DEFAULT_FACE_P non-zero means let the
13905 space have the default face, otherwise let it have the same face as
13906 IT->face_id. Value is non-zero if a space was added.
13908 This function is called to make sure that there is always one glyph
13909 at the end of a glyph row that the cursor can be set on under
13910 window-systems. (If there weren't such a glyph we would not know
13911 how wide and tall a box cursor should be displayed).
13913 At the same time this space let's a nicely handle clearing to the
13914 end of the line if the row ends in italic text. */
13916 static int
13917 append_space (it, default_face_p)
13918 struct it *it;
13919 int default_face_p;
13921 if (FRAME_WINDOW_P (it->f))
13923 int n = it->glyph_row->used[TEXT_AREA];
13925 if (it->glyph_row->glyphs[TEXT_AREA] + n
13926 < it->glyph_row->glyphs[1 + TEXT_AREA])
13928 /* Save some values that must not be changed.
13929 Must save IT->c and IT->len because otherwise
13930 ITERATOR_AT_END_P wouldn't work anymore after
13931 append_space has been called. */
13932 enum display_element_type saved_what = it->what;
13933 int saved_c = it->c, saved_len = it->len;
13934 int saved_x = it->current_x;
13935 int saved_face_id = it->face_id;
13936 struct text_pos saved_pos;
13937 Lisp_Object saved_object;
13938 struct face *face;
13940 saved_object = it->object;
13941 saved_pos = it->position;
13943 it->what = IT_CHARACTER;
13944 bzero (&it->position, sizeof it->position);
13945 it->object = make_number (0);
13946 it->c = ' ';
13947 it->len = 1;
13949 if (default_face_p)
13950 it->face_id = DEFAULT_FACE_ID;
13951 else if (it->face_before_selective_p)
13952 it->face_id = it->saved_face_id;
13953 face = FACE_FROM_ID (it->f, it->face_id);
13954 it->face_id = FACE_FOR_CHAR (it->f, face, 0);
13956 PRODUCE_GLYPHS (it);
13958 it->current_x = saved_x;
13959 it->object = saved_object;
13960 it->position = saved_pos;
13961 it->what = saved_what;
13962 it->face_id = saved_face_id;
13963 it->len = saved_len;
13964 it->c = saved_c;
13965 return 1;
13969 return 0;
13973 /* Extend the face of the last glyph in the text area of IT->glyph_row
13974 to the end of the display line. Called from display_line.
13975 If the glyph row is empty, add a space glyph to it so that we
13976 know the face to draw. Set the glyph row flag fill_line_p. */
13978 static void
13979 extend_face_to_end_of_line (it)
13980 struct it *it;
13982 struct face *face;
13983 struct frame *f = it->f;
13985 /* If line is already filled, do nothing. */
13986 if (it->current_x >= it->last_visible_x)
13987 return;
13989 /* Face extension extends the background and box of IT->face_id
13990 to the end of the line. If the background equals the background
13991 of the frame, we don't have to do anything. */
13992 if (it->face_before_selective_p)
13993 face = FACE_FROM_ID (it->f, it->saved_face_id);
13994 else
13995 face = FACE_FROM_ID (f, it->face_id);
13997 if (FRAME_WINDOW_P (f)
13998 && face->box == FACE_NO_BOX
13999 && face->background == FRAME_BACKGROUND_PIXEL (f)
14000 && !face->stipple)
14001 return;
14003 /* Set the glyph row flag indicating that the face of the last glyph
14004 in the text area has to be drawn to the end of the text area. */
14005 it->glyph_row->fill_line_p = 1;
14007 /* If current character of IT is not ASCII, make sure we have the
14008 ASCII face. This will be automatically undone the next time
14009 get_next_display_element returns a multibyte character. Note
14010 that the character will always be single byte in unibyte text. */
14011 if (!SINGLE_BYTE_CHAR_P (it->c))
14013 it->face_id = FACE_FOR_CHAR (f, face, 0);
14016 if (FRAME_WINDOW_P (f))
14018 /* If the row is empty, add a space with the current face of IT,
14019 so that we know which face to draw. */
14020 if (it->glyph_row->used[TEXT_AREA] == 0)
14022 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
14023 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
14024 it->glyph_row->used[TEXT_AREA] = 1;
14027 else
14029 /* Save some values that must not be changed. */
14030 int saved_x = it->current_x;
14031 struct text_pos saved_pos;
14032 Lisp_Object saved_object;
14033 enum display_element_type saved_what = it->what;
14034 int saved_face_id = it->face_id;
14036 saved_object = it->object;
14037 saved_pos = it->position;
14039 it->what = IT_CHARACTER;
14040 bzero (&it->position, sizeof it->position);
14041 it->object = make_number (0);
14042 it->c = ' ';
14043 it->len = 1;
14044 it->face_id = face->id;
14046 PRODUCE_GLYPHS (it);
14048 while (it->current_x <= it->last_visible_x)
14049 PRODUCE_GLYPHS (it);
14051 /* Don't count these blanks really. It would let us insert a left
14052 truncation glyph below and make us set the cursor on them, maybe. */
14053 it->current_x = saved_x;
14054 it->object = saved_object;
14055 it->position = saved_pos;
14056 it->what = saved_what;
14057 it->face_id = saved_face_id;
14062 /* Value is non-zero if text starting at CHARPOS in current_buffer is
14063 trailing whitespace. */
14065 static int
14066 trailing_whitespace_p (charpos)
14067 int charpos;
14069 int bytepos = CHAR_TO_BYTE (charpos);
14070 int c = 0;
14072 while (bytepos < ZV_BYTE
14073 && (c = FETCH_CHAR (bytepos),
14074 c == ' ' || c == '\t'))
14075 ++bytepos;
14077 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
14079 if (bytepos != PT_BYTE)
14080 return 1;
14082 return 0;
14086 /* Highlight trailing whitespace, if any, in ROW. */
14088 void
14089 highlight_trailing_whitespace (f, row)
14090 struct frame *f;
14091 struct glyph_row *row;
14093 int used = row->used[TEXT_AREA];
14095 if (used)
14097 struct glyph *start = row->glyphs[TEXT_AREA];
14098 struct glyph *glyph = start + used - 1;
14100 /* Skip over glyphs inserted to display the cursor at the
14101 end of a line, for extending the face of the last glyph
14102 to the end of the line on terminals, and for truncation
14103 and continuation glyphs. */
14104 while (glyph >= start
14105 && glyph->type == CHAR_GLYPH
14106 && INTEGERP (glyph->object))
14107 --glyph;
14109 /* If last glyph is a space or stretch, and it's trailing
14110 whitespace, set the face of all trailing whitespace glyphs in
14111 IT->glyph_row to `trailing-whitespace'. */
14112 if (glyph >= start
14113 && BUFFERP (glyph->object)
14114 && (glyph->type == STRETCH_GLYPH
14115 || (glyph->type == CHAR_GLYPH
14116 && glyph->u.ch == ' '))
14117 && trailing_whitespace_p (glyph->charpos))
14119 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
14121 while (glyph >= start
14122 && BUFFERP (glyph->object)
14123 && (glyph->type == STRETCH_GLYPH
14124 || (glyph->type == CHAR_GLYPH
14125 && glyph->u.ch == ' ')))
14126 (glyph--)->face_id = face_id;
14132 /* Value is non-zero if glyph row ROW in window W should be
14133 used to hold the cursor. */
14135 static int
14136 cursor_row_p (w, row)
14137 struct window *w;
14138 struct glyph_row *row;
14140 int cursor_row_p = 1;
14142 if (PT == MATRIX_ROW_END_CHARPOS (row))
14144 /* If the row ends with a newline from a string, we don't want
14145 the cursor there (if the row is continued it doesn't end in a
14146 newline). */
14147 if (CHARPOS (row->end.string_pos) >= 0
14148 || MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
14149 cursor_row_p = row->continued_p;
14151 /* If the row ends at ZV, display the cursor at the end of that
14152 row instead of at the start of the row below. */
14153 else if (row->ends_at_zv_p)
14154 cursor_row_p = 1;
14155 else
14156 cursor_row_p = 0;
14159 return cursor_row_p;
14163 /* Construct the glyph row IT->glyph_row in the desired matrix of
14164 IT->w from text at the current position of IT. See dispextern.h
14165 for an overview of struct it. Value is non-zero if
14166 IT->glyph_row displays text, as opposed to a line displaying ZV
14167 only. */
14169 static int
14170 display_line (it)
14171 struct it *it;
14173 struct glyph_row *row = it->glyph_row;
14175 /* We always start displaying at hpos zero even if hscrolled. */
14176 xassert (it->hpos == 0 && it->current_x == 0);
14178 /* We must not display in a row that's not a text row. */
14179 xassert (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
14180 < it->w->desired_matrix->nrows);
14182 /* Is IT->w showing the region? */
14183 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
14185 /* Clear the result glyph row and enable it. */
14186 prepare_desired_row (row);
14188 row->y = it->current_y;
14189 row->start = it->start;
14190 row->continuation_lines_width = it->continuation_lines_width;
14191 row->displays_text_p = 1;
14192 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
14193 it->starts_in_middle_of_char_p = 0;
14195 /* Arrange the overlays nicely for our purposes. Usually, we call
14196 display_line on only one line at a time, in which case this
14197 can't really hurt too much, or we call it on lines which appear
14198 one after another in the buffer, in which case all calls to
14199 recenter_overlay_lists but the first will be pretty cheap. */
14200 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
14202 /* Move over display elements that are not visible because we are
14203 hscrolled. This may stop at an x-position < IT->first_visible_x
14204 if the first glyph is partially visible or if we hit a line end. */
14205 if (it->current_x < it->first_visible_x)
14206 move_it_in_display_line_to (it, ZV, it->first_visible_x,
14207 MOVE_TO_POS | MOVE_TO_X);
14209 /* Get the initial row height. This is either the height of the
14210 text hscrolled, if there is any, or zero. */
14211 row->ascent = it->max_ascent;
14212 row->height = it->max_ascent + it->max_descent;
14213 row->phys_ascent = it->max_phys_ascent;
14214 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14216 /* Loop generating characters. The loop is left with IT on the next
14217 character to display. */
14218 while (1)
14220 int n_glyphs_before, hpos_before, x_before;
14221 int x, i, nglyphs;
14222 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
14224 /* Retrieve the next thing to display. Value is zero if end of
14225 buffer reached. */
14226 if (!get_next_display_element (it))
14228 /* Maybe add a space at the end of this line that is used to
14229 display the cursor there under X. Set the charpos of the
14230 first glyph of blank lines not corresponding to any text
14231 to -1. */
14232 #ifdef HAVE_WINDOW_SYSTEM
14233 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14234 row->exact_window_width_line_p = 1;
14235 else
14236 #endif /* HAVE_WINDOW_SYSTEM */
14237 if ((append_space (it, 1) && row->used[TEXT_AREA] == 1)
14238 || row->used[TEXT_AREA] == 0)
14240 row->glyphs[TEXT_AREA]->charpos = -1;
14241 row->displays_text_p = 0;
14243 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
14244 && (!MINI_WINDOW_P (it->w)
14245 || (minibuf_level && EQ (it->window, minibuf_window))))
14246 row->indicate_empty_line_p = 1;
14249 it->continuation_lines_width = 0;
14250 row->ends_at_zv_p = 1;
14251 break;
14254 /* Now, get the metrics of what we want to display. This also
14255 generates glyphs in `row' (which is IT->glyph_row). */
14256 n_glyphs_before = row->used[TEXT_AREA];
14257 x = it->current_x;
14259 /* Remember the line height so far in case the next element doesn't
14260 fit on the line. */
14261 if (!it->truncate_lines_p)
14263 ascent = it->max_ascent;
14264 descent = it->max_descent;
14265 phys_ascent = it->max_phys_ascent;
14266 phys_descent = it->max_phys_descent;
14269 PRODUCE_GLYPHS (it);
14271 /* If this display element was in marginal areas, continue with
14272 the next one. */
14273 if (it->area != TEXT_AREA)
14275 row->ascent = max (row->ascent, it->max_ascent);
14276 row->height = max (row->height, it->max_ascent + it->max_descent);
14277 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14278 row->phys_height = max (row->phys_height,
14279 it->max_phys_ascent + it->max_phys_descent);
14280 set_iterator_to_next (it, 1);
14281 continue;
14284 /* Does the display element fit on the line? If we truncate
14285 lines, we should draw past the right edge of the window. If
14286 we don't truncate, we want to stop so that we can display the
14287 continuation glyph before the right margin. If lines are
14288 continued, there are two possible strategies for characters
14289 resulting in more than 1 glyph (e.g. tabs): Display as many
14290 glyphs as possible in this line and leave the rest for the
14291 continuation line, or display the whole element in the next
14292 line. Original redisplay did the former, so we do it also. */
14293 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
14294 hpos_before = it->hpos;
14295 x_before = x;
14297 if (/* Not a newline. */
14298 nglyphs > 0
14299 /* Glyphs produced fit entirely in the line. */
14300 && it->current_x < it->last_visible_x)
14302 it->hpos += nglyphs;
14303 row->ascent = max (row->ascent, it->max_ascent);
14304 row->height = max (row->height, it->max_ascent + it->max_descent);
14305 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14306 row->phys_height = max (row->phys_height,
14307 it->max_phys_ascent + it->max_phys_descent);
14308 if (it->current_x - it->pixel_width < it->first_visible_x)
14309 row->x = x - it->first_visible_x;
14311 else
14313 int new_x;
14314 struct glyph *glyph;
14316 for (i = 0; i < nglyphs; ++i, x = new_x)
14318 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
14319 new_x = x + glyph->pixel_width;
14321 if (/* Lines are continued. */
14322 !it->truncate_lines_p
14323 && (/* Glyph doesn't fit on the line. */
14324 new_x > it->last_visible_x
14325 /* Or it fits exactly on a window system frame. */
14326 || (new_x == it->last_visible_x
14327 && FRAME_WINDOW_P (it->f))))
14329 /* End of a continued line. */
14331 if (it->hpos == 0
14332 || (new_x == it->last_visible_x
14333 && FRAME_WINDOW_P (it->f)))
14335 /* Current glyph is the only one on the line or
14336 fits exactly on the line. We must continue
14337 the line because we can't draw the cursor
14338 after the glyph. */
14339 row->continued_p = 1;
14340 it->current_x = new_x;
14341 it->continuation_lines_width += new_x;
14342 ++it->hpos;
14343 if (i == nglyphs - 1)
14345 set_iterator_to_next (it, 1);
14346 #ifdef HAVE_WINDOW_SYSTEM
14347 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14349 if (!get_next_display_element (it))
14351 row->exact_window_width_line_p = 1;
14352 it->continuation_lines_width = 0;
14353 row->continued_p = 0;
14354 row->ends_at_zv_p = 1;
14356 else if (ITERATOR_AT_END_OF_LINE_P (it))
14358 row->continued_p = 0;
14359 row->exact_window_width_line_p = 1;
14362 #endif /* HAVE_WINDOW_SYSTEM */
14365 else if (CHAR_GLYPH_PADDING_P (*glyph)
14366 && !FRAME_WINDOW_P (it->f))
14368 /* A padding glyph that doesn't fit on this line.
14369 This means the whole character doesn't fit
14370 on the line. */
14371 row->used[TEXT_AREA] = n_glyphs_before;
14373 /* Fill the rest of the row with continuation
14374 glyphs like in 20.x. */
14375 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
14376 < row->glyphs[1 + TEXT_AREA])
14377 produce_special_glyphs (it, IT_CONTINUATION);
14379 row->continued_p = 1;
14380 it->current_x = x_before;
14381 it->continuation_lines_width += x_before;
14383 /* Restore the height to what it was before the
14384 element not fitting on the line. */
14385 it->max_ascent = ascent;
14386 it->max_descent = descent;
14387 it->max_phys_ascent = phys_ascent;
14388 it->max_phys_descent = phys_descent;
14390 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
14392 /* A TAB that extends past the right edge of the
14393 window. This produces a single glyph on
14394 window system frames. We leave the glyph in
14395 this row and let it fill the row, but don't
14396 consume the TAB. */
14397 it->continuation_lines_width += it->last_visible_x;
14398 row->ends_in_middle_of_char_p = 1;
14399 row->continued_p = 1;
14400 glyph->pixel_width = it->last_visible_x - x;
14401 it->starts_in_middle_of_char_p = 1;
14403 else
14405 /* Something other than a TAB that draws past
14406 the right edge of the window. Restore
14407 positions to values before the element. */
14408 row->used[TEXT_AREA] = n_glyphs_before + i;
14410 /* Display continuation glyphs. */
14411 if (!FRAME_WINDOW_P (it->f))
14412 produce_special_glyphs (it, IT_CONTINUATION);
14413 row->continued_p = 1;
14415 it->continuation_lines_width += x;
14417 if (nglyphs > 1 && i > 0)
14419 row->ends_in_middle_of_char_p = 1;
14420 it->starts_in_middle_of_char_p = 1;
14423 /* Restore the height to what it was before the
14424 element not fitting on the line. */
14425 it->max_ascent = ascent;
14426 it->max_descent = descent;
14427 it->max_phys_ascent = phys_ascent;
14428 it->max_phys_descent = phys_descent;
14431 break;
14433 else if (new_x > it->first_visible_x)
14435 /* Increment number of glyphs actually displayed. */
14436 ++it->hpos;
14438 if (x < it->first_visible_x)
14439 /* Glyph is partially visible, i.e. row starts at
14440 negative X position. */
14441 row->x = x - it->first_visible_x;
14443 else
14445 /* Glyph is completely off the left margin of the
14446 window. This should not happen because of the
14447 move_it_in_display_line at the start of this
14448 function, unless the text display area of the
14449 window is empty. */
14450 xassert (it->first_visible_x <= it->last_visible_x);
14454 row->ascent = max (row->ascent, it->max_ascent);
14455 row->height = max (row->height, it->max_ascent + it->max_descent);
14456 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14457 row->phys_height = max (row->phys_height,
14458 it->max_phys_ascent + it->max_phys_descent);
14460 /* End of this display line if row is continued. */
14461 if (row->continued_p || row->ends_at_zv_p)
14462 break;
14465 at_end_of_line:
14466 /* Is this a line end? If yes, we're also done, after making
14467 sure that a non-default face is extended up to the right
14468 margin of the window. */
14469 if (ITERATOR_AT_END_OF_LINE_P (it))
14471 int used_before = row->used[TEXT_AREA];
14473 row->ends_in_newline_from_string_p = STRINGP (it->object);
14475 #ifdef HAVE_WINDOW_SYSTEM
14476 /* Add a space at the end of the line that is used to
14477 display the cursor there. */
14478 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14479 append_space (it, 0);
14480 #endif /* HAVE_WINDOW_SYSTEM */
14482 /* Extend the face to the end of the line. */
14483 extend_face_to_end_of_line (it);
14485 /* Make sure we have the position. */
14486 if (used_before == 0)
14487 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
14489 /* Consume the line end. This skips over invisible lines. */
14490 set_iterator_to_next (it, 1);
14491 it->continuation_lines_width = 0;
14492 break;
14495 /* Proceed with next display element. Note that this skips
14496 over lines invisible because of selective display. */
14497 set_iterator_to_next (it, 1);
14499 /* If we truncate lines, we are done when the last displayed
14500 glyphs reach past the right margin of the window. */
14501 if (it->truncate_lines_p
14502 && (FRAME_WINDOW_P (it->f)
14503 ? (it->current_x >= it->last_visible_x)
14504 : (it->current_x > it->last_visible_x)))
14506 /* Maybe add truncation glyphs. */
14507 if (!FRAME_WINDOW_P (it->f))
14509 int i, n;
14511 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
14512 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
14513 break;
14515 for (n = row->used[TEXT_AREA]; i < n; ++i)
14517 row->used[TEXT_AREA] = i;
14518 produce_special_glyphs (it, IT_TRUNCATION);
14521 #ifdef HAVE_WINDOW_SYSTEM
14522 else
14524 /* Don't truncate if we can overflow newline into fringe. */
14525 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14527 if (!get_next_display_element (it))
14529 #ifdef HAVE_WINDOW_SYSTEM
14530 it->continuation_lines_width = 0;
14531 row->ends_at_zv_p = 1;
14532 row->exact_window_width_line_p = 1;
14533 break;
14534 #endif /* HAVE_WINDOW_SYSTEM */
14536 if (ITERATOR_AT_END_OF_LINE_P (it))
14538 row->exact_window_width_line_p = 1;
14539 goto at_end_of_line;
14543 #endif /* HAVE_WINDOW_SYSTEM */
14545 row->truncated_on_right_p = 1;
14546 it->continuation_lines_width = 0;
14547 reseat_at_next_visible_line_start (it, 0);
14548 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
14549 it->hpos = hpos_before;
14550 it->current_x = x_before;
14551 break;
14555 /* If line is not empty and hscrolled, maybe insert truncation glyphs
14556 at the left window margin. */
14557 if (it->first_visible_x
14558 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
14560 if (!FRAME_WINDOW_P (it->f))
14561 insert_left_trunc_glyphs (it);
14562 row->truncated_on_left_p = 1;
14565 /* If the start of this line is the overlay arrow-position, then
14566 mark this glyph row as the one containing the overlay arrow.
14567 This is clearly a mess with variable size fonts. It would be
14568 better to let it be displayed like cursors under X. */
14569 if (MARKERP (Voverlay_arrow_position)
14570 && current_buffer == XMARKER (Voverlay_arrow_position)->buffer
14571 && (MATRIX_ROW_START_CHARPOS (row)
14572 == marker_position (Voverlay_arrow_position))
14573 && STRINGP (Voverlay_arrow_string)
14574 && ! overlay_arrow_seen)
14576 /* Overlay arrow in window redisplay is a fringe bitmap. */
14577 if (!FRAME_WINDOW_P (it->f))
14579 struct glyph_row *arrow_row = get_overlay_arrow_glyph_row (it->w);
14580 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
14581 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
14582 struct glyph *p = row->glyphs[TEXT_AREA];
14583 struct glyph *p2, *end;
14585 /* Copy the arrow glyphs. */
14586 while (glyph < arrow_end)
14587 *p++ = *glyph++;
14589 /* Throw away padding glyphs. */
14590 p2 = p;
14591 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
14592 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
14593 ++p2;
14594 if (p2 > p)
14596 while (p2 < end)
14597 *p++ = *p2++;
14598 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
14602 overlay_arrow_seen = 1;
14603 row->overlay_arrow_p = 1;
14606 /* Compute pixel dimensions of this line. */
14607 compute_line_metrics (it);
14609 /* Remember the position at which this line ends. */
14610 row->end = it->current;
14612 /* Save fringe bitmaps in this row. */
14613 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
14614 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
14615 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
14616 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
14618 it->left_user_fringe_bitmap = 0;
14619 it->left_user_fringe_face_id = 0;
14620 it->right_user_fringe_bitmap = 0;
14621 it->right_user_fringe_face_id = 0;
14623 /* Maybe set the cursor. */
14624 if (it->w->cursor.vpos < 0
14625 && PT >= MATRIX_ROW_START_CHARPOS (row)
14626 && PT <= MATRIX_ROW_END_CHARPOS (row)
14627 && cursor_row_p (it->w, row))
14628 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
14630 /* Highlight trailing whitespace. */
14631 if (!NILP (Vshow_trailing_whitespace))
14632 highlight_trailing_whitespace (it->f, it->glyph_row);
14634 /* Prepare for the next line. This line starts horizontally at (X
14635 HPOS) = (0 0). Vertical positions are incremented. As a
14636 convenience for the caller, IT->glyph_row is set to the next
14637 row to be used. */
14638 it->current_x = it->hpos = 0;
14639 it->current_y += row->height;
14640 ++it->vpos;
14641 ++it->glyph_row;
14642 it->start = it->current;
14643 return row->displays_text_p;
14648 /***********************************************************************
14649 Menu Bar
14650 ***********************************************************************/
14652 /* Redisplay the menu bar in the frame for window W.
14654 The menu bar of X frames that don't have X toolkit support is
14655 displayed in a special window W->frame->menu_bar_window.
14657 The menu bar of terminal frames is treated specially as far as
14658 glyph matrices are concerned. Menu bar lines are not part of
14659 windows, so the update is done directly on the frame matrix rows
14660 for the menu bar. */
14662 static void
14663 display_menu_bar (w)
14664 struct window *w;
14666 struct frame *f = XFRAME (WINDOW_FRAME (w));
14667 struct it it;
14668 Lisp_Object items;
14669 int i;
14671 /* Don't do all this for graphical frames. */
14672 #ifdef HAVE_NTGUI
14673 if (!NILP (Vwindow_system))
14674 return;
14675 #endif
14676 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
14677 if (FRAME_X_P (f))
14678 return;
14679 #endif
14680 #ifdef MAC_OS
14681 if (FRAME_MAC_P (f))
14682 return;
14683 #endif
14685 #ifdef USE_X_TOOLKIT
14686 xassert (!FRAME_WINDOW_P (f));
14687 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
14688 it.first_visible_x = 0;
14689 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
14690 #else /* not USE_X_TOOLKIT */
14691 if (FRAME_WINDOW_P (f))
14693 /* Menu bar lines are displayed in the desired matrix of the
14694 dummy window menu_bar_window. */
14695 struct window *menu_w;
14696 xassert (WINDOWP (f->menu_bar_window));
14697 menu_w = XWINDOW (f->menu_bar_window);
14698 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
14699 MENU_FACE_ID);
14700 it.first_visible_x = 0;
14701 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
14703 else
14705 /* This is a TTY frame, i.e. character hpos/vpos are used as
14706 pixel x/y. */
14707 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
14708 MENU_FACE_ID);
14709 it.first_visible_x = 0;
14710 it.last_visible_x = FRAME_COLS (f);
14712 #endif /* not USE_X_TOOLKIT */
14714 if (! mode_line_inverse_video)
14715 /* Force the menu-bar to be displayed in the default face. */
14716 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
14718 /* Clear all rows of the menu bar. */
14719 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
14721 struct glyph_row *row = it.glyph_row + i;
14722 clear_glyph_row (row);
14723 row->enabled_p = 1;
14724 row->full_width_p = 1;
14727 /* Display all items of the menu bar. */
14728 items = FRAME_MENU_BAR_ITEMS (it.f);
14729 for (i = 0; i < XVECTOR (items)->size; i += 4)
14731 Lisp_Object string;
14733 /* Stop at nil string. */
14734 string = AREF (items, i + 1);
14735 if (NILP (string))
14736 break;
14738 /* Remember where item was displayed. */
14739 AREF (items, i + 3) = make_number (it.hpos);
14741 /* Display the item, pad with one space. */
14742 if (it.current_x < it.last_visible_x)
14743 display_string (NULL, string, Qnil, 0, 0, &it,
14744 SCHARS (string) + 1, 0, 0, -1);
14747 /* Fill out the line with spaces. */
14748 if (it.current_x < it.last_visible_x)
14749 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
14751 /* Compute the total height of the lines. */
14752 compute_line_metrics (&it);
14757 /***********************************************************************
14758 Mode Line
14759 ***********************************************************************/
14761 /* Redisplay mode lines in the window tree whose root is WINDOW. If
14762 FORCE is non-zero, redisplay mode lines unconditionally.
14763 Otherwise, redisplay only mode lines that are garbaged. Value is
14764 the number of windows whose mode lines were redisplayed. */
14766 static int
14767 redisplay_mode_lines (window, force)
14768 Lisp_Object window;
14769 int force;
14771 int nwindows = 0;
14773 while (!NILP (window))
14775 struct window *w = XWINDOW (window);
14777 if (WINDOWP (w->hchild))
14778 nwindows += redisplay_mode_lines (w->hchild, force);
14779 else if (WINDOWP (w->vchild))
14780 nwindows += redisplay_mode_lines (w->vchild, force);
14781 else if (force
14782 || FRAME_GARBAGED_P (XFRAME (w->frame))
14783 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
14785 struct text_pos lpoint;
14786 struct buffer *old = current_buffer;
14788 /* Set the window's buffer for the mode line display. */
14789 SET_TEXT_POS (lpoint, PT, PT_BYTE);
14790 set_buffer_internal_1 (XBUFFER (w->buffer));
14792 /* Point refers normally to the selected window. For any
14793 other window, set up appropriate value. */
14794 if (!EQ (window, selected_window))
14796 struct text_pos pt;
14798 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
14799 if (CHARPOS (pt) < BEGV)
14800 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
14801 else if (CHARPOS (pt) > (ZV - 1))
14802 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
14803 else
14804 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
14807 /* Display mode lines. */
14808 clear_glyph_matrix (w->desired_matrix);
14809 if (display_mode_lines (w))
14811 ++nwindows;
14812 w->must_be_updated_p = 1;
14815 /* Restore old settings. */
14816 set_buffer_internal_1 (old);
14817 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
14820 window = w->next;
14823 return nwindows;
14827 /* Display the mode and/or top line of window W. Value is the number
14828 of mode lines displayed. */
14830 static int
14831 display_mode_lines (w)
14832 struct window *w;
14834 Lisp_Object old_selected_window, old_selected_frame;
14835 int n = 0;
14837 old_selected_frame = selected_frame;
14838 selected_frame = w->frame;
14839 old_selected_window = selected_window;
14840 XSETWINDOW (selected_window, w);
14842 /* These will be set while the mode line specs are processed. */
14843 line_number_displayed = 0;
14844 w->column_number_displayed = Qnil;
14846 if (WINDOW_WANTS_MODELINE_P (w))
14848 struct window *sel_w = XWINDOW (old_selected_window);
14850 /* Select mode line face based on the real selected window. */
14851 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
14852 current_buffer->mode_line_format);
14853 ++n;
14856 if (WINDOW_WANTS_HEADER_LINE_P (w))
14858 display_mode_line (w, HEADER_LINE_FACE_ID,
14859 current_buffer->header_line_format);
14860 ++n;
14863 selected_frame = old_selected_frame;
14864 selected_window = old_selected_window;
14865 return n;
14869 /* Display mode or top line of window W. FACE_ID specifies which line
14870 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
14871 FORMAT is the mode line format to display. Value is the pixel
14872 height of the mode line displayed. */
14874 static int
14875 display_mode_line (w, face_id, format)
14876 struct window *w;
14877 enum face_id face_id;
14878 Lisp_Object format;
14880 struct it it;
14881 struct face *face;
14883 init_iterator (&it, w, -1, -1, NULL, face_id);
14884 prepare_desired_row (it.glyph_row);
14886 if (! mode_line_inverse_video)
14887 /* Force the mode-line to be displayed in the default face. */
14888 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
14890 /* Temporarily make frame's keyboard the current kboard so that
14891 kboard-local variables in the mode_line_format will get the right
14892 values. */
14893 push_frame_kboard (it.f);
14894 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
14895 pop_frame_kboard ();
14897 /* Fill up with spaces. */
14898 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
14900 compute_line_metrics (&it);
14901 it.glyph_row->full_width_p = 1;
14902 it.glyph_row->mode_line_p = 1;
14903 it.glyph_row->continued_p = 0;
14904 it.glyph_row->truncated_on_left_p = 0;
14905 it.glyph_row->truncated_on_right_p = 0;
14907 /* Make a 3D mode-line have a shadow at its right end. */
14908 face = FACE_FROM_ID (it.f, face_id);
14909 extend_face_to_end_of_line (&it);
14910 if (face->box != FACE_NO_BOX)
14912 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
14913 + it.glyph_row->used[TEXT_AREA] - 1);
14914 last->right_box_line_p = 1;
14917 return it.glyph_row->height;
14920 /* Alist that caches the results of :propertize.
14921 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
14922 Lisp_Object mode_line_proptrans_alist;
14924 /* List of strings making up the mode-line. */
14925 Lisp_Object mode_line_string_list;
14927 /* Base face property when building propertized mode line string. */
14928 static Lisp_Object mode_line_string_face;
14929 static Lisp_Object mode_line_string_face_prop;
14932 /* Contribute ELT to the mode line for window IT->w. How it
14933 translates into text depends on its data type.
14935 IT describes the display environment in which we display, as usual.
14937 DEPTH is the depth in recursion. It is used to prevent
14938 infinite recursion here.
14940 FIELD_WIDTH is the number of characters the display of ELT should
14941 occupy in the mode line, and PRECISION is the maximum number of
14942 characters to display from ELT's representation. See
14943 display_string for details.
14945 Returns the hpos of the end of the text generated by ELT.
14947 PROPS is a property list to add to any string we encounter.
14949 If RISKY is nonzero, remove (disregard) any properties in any string
14950 we encounter, and ignore :eval and :propertize.
14952 If the global variable `frame_title_ptr' is non-NULL, then the output
14953 is passed to `store_frame_title' instead of `display_string'. */
14955 static int
14956 display_mode_element (it, depth, field_width, precision, elt, props, risky)
14957 struct it *it;
14958 int depth;
14959 int field_width, precision;
14960 Lisp_Object elt, props;
14961 int risky;
14963 int n = 0, field, prec;
14964 int literal = 0;
14966 tail_recurse:
14967 if (depth > 100)
14968 elt = build_string ("*too-deep*");
14970 depth++;
14972 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
14974 case Lisp_String:
14976 /* A string: output it and check for %-constructs within it. */
14977 unsigned char c;
14978 const unsigned char *this, *lisp_string;
14980 if (!NILP (props) || risky)
14982 Lisp_Object oprops, aelt;
14983 oprops = Ftext_properties_at (make_number (0), elt);
14985 if (NILP (Fequal (props, oprops)) || risky)
14987 /* If the starting string has properties,
14988 merge the specified ones onto the existing ones. */
14989 if (! NILP (oprops) && !risky)
14991 Lisp_Object tem;
14993 oprops = Fcopy_sequence (oprops);
14994 tem = props;
14995 while (CONSP (tem))
14997 oprops = Fplist_put (oprops, XCAR (tem),
14998 XCAR (XCDR (tem)));
14999 tem = XCDR (XCDR (tem));
15001 props = oprops;
15004 aelt = Fassoc (elt, mode_line_proptrans_alist);
15005 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
15007 mode_line_proptrans_alist
15008 = Fcons (aelt, Fdelq (aelt, mode_line_proptrans_alist));
15009 elt = XCAR (aelt);
15011 else
15013 Lisp_Object tem;
15015 elt = Fcopy_sequence (elt);
15016 Fset_text_properties (make_number (0), Flength (elt),
15017 props, elt);
15018 /* Add this item to mode_line_proptrans_alist. */
15019 mode_line_proptrans_alist
15020 = Fcons (Fcons (elt, props),
15021 mode_line_proptrans_alist);
15022 /* Truncate mode_line_proptrans_alist
15023 to at most 50 elements. */
15024 tem = Fnthcdr (make_number (50),
15025 mode_line_proptrans_alist);
15026 if (! NILP (tem))
15027 XSETCDR (tem, Qnil);
15032 this = SDATA (elt);
15033 lisp_string = this;
15035 if (literal)
15037 prec = precision - n;
15038 if (frame_title_ptr)
15039 n += store_frame_title (SDATA (elt), -1, prec);
15040 else if (!NILP (mode_line_string_list))
15041 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
15042 else
15043 n += display_string (NULL, elt, Qnil, 0, 0, it,
15044 0, prec, 0, STRING_MULTIBYTE (elt));
15046 break;
15049 while ((precision <= 0 || n < precision)
15050 && *this
15051 && (frame_title_ptr
15052 || !NILP (mode_line_string_list)
15053 || it->current_x < it->last_visible_x))
15055 const unsigned char *last = this;
15057 /* Advance to end of string or next format specifier. */
15058 while ((c = *this++) != '\0' && c != '%')
15061 if (this - 1 != last)
15063 /* Output to end of string or up to '%'. Field width
15064 is length of string. Don't output more than
15065 PRECISION allows us. */
15066 --this;
15068 prec = chars_in_text (last, this - last);
15069 if (precision > 0 && prec > precision - n)
15070 prec = precision - n;
15072 if (frame_title_ptr)
15073 n += store_frame_title (last, 0, prec);
15074 else if (!NILP (mode_line_string_list))
15076 int bytepos = last - lisp_string;
15077 int charpos = string_byte_to_char (elt, bytepos);
15078 n += store_mode_line_string (NULL,
15079 Fsubstring (elt, make_number (charpos),
15080 make_number (charpos + prec)),
15081 0, 0, 0, Qnil);
15083 else
15085 int bytepos = last - lisp_string;
15086 int charpos = string_byte_to_char (elt, bytepos);
15087 n += display_string (NULL, elt, Qnil, 0, charpos,
15088 it, 0, prec, 0,
15089 STRING_MULTIBYTE (elt));
15092 else /* c == '%' */
15094 const unsigned char *percent_position = this;
15096 /* Get the specified minimum width. Zero means
15097 don't pad. */
15098 field = 0;
15099 while ((c = *this++) >= '0' && c <= '9')
15100 field = field * 10 + c - '0';
15102 /* Don't pad beyond the total padding allowed. */
15103 if (field_width - n > 0 && field > field_width - n)
15104 field = field_width - n;
15106 /* Note that either PRECISION <= 0 or N < PRECISION. */
15107 prec = precision - n;
15109 if (c == 'M')
15110 n += display_mode_element (it, depth, field, prec,
15111 Vglobal_mode_string, props,
15112 risky);
15113 else if (c != 0)
15115 int multibyte;
15116 int bytepos, charpos;
15117 unsigned char *spec;
15119 bytepos = percent_position - lisp_string;
15120 charpos = (STRING_MULTIBYTE (elt)
15121 ? string_byte_to_char (elt, bytepos)
15122 : bytepos);
15124 spec
15125 = decode_mode_spec (it->w, c, field, prec, &multibyte);
15127 if (frame_title_ptr)
15128 n += store_frame_title (spec, field, prec);
15129 else if (!NILP (mode_line_string_list))
15131 int len = strlen (spec);
15132 Lisp_Object tem = make_string (spec, len);
15133 props = Ftext_properties_at (make_number (charpos), elt);
15134 /* Should only keep face property in props */
15135 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
15137 else
15139 int nglyphs_before, nwritten;
15141 nglyphs_before = it->glyph_row->used[TEXT_AREA];
15142 nwritten = display_string (spec, Qnil, elt,
15143 charpos, 0, it,
15144 field, prec, 0,
15145 multibyte);
15147 /* Assign to the glyphs written above the
15148 string where the `%x' came from, position
15149 of the `%'. */
15150 if (nwritten > 0)
15152 struct glyph *glyph
15153 = (it->glyph_row->glyphs[TEXT_AREA]
15154 + nglyphs_before);
15155 int i;
15157 for (i = 0; i < nwritten; ++i)
15159 glyph[i].object = elt;
15160 glyph[i].charpos = charpos;
15163 n += nwritten;
15167 else /* c == 0 */
15168 break;
15172 break;
15174 case Lisp_Symbol:
15175 /* A symbol: process the value of the symbol recursively
15176 as if it appeared here directly. Avoid error if symbol void.
15177 Special case: if value of symbol is a string, output the string
15178 literally. */
15180 register Lisp_Object tem;
15182 /* If the variable is not marked as risky to set
15183 then its contents are risky to use. */
15184 if (NILP (Fget (elt, Qrisky_local_variable)))
15185 risky = 1;
15187 tem = Fboundp (elt);
15188 if (!NILP (tem))
15190 tem = Fsymbol_value (elt);
15191 /* If value is a string, output that string literally:
15192 don't check for % within it. */
15193 if (STRINGP (tem))
15194 literal = 1;
15196 if (!EQ (tem, elt))
15198 /* Give up right away for nil or t. */
15199 elt = tem;
15200 goto tail_recurse;
15204 break;
15206 case Lisp_Cons:
15208 register Lisp_Object car, tem;
15210 /* A cons cell: five distinct cases.
15211 If first element is :eval or :propertize, do something special.
15212 If first element is a string or a cons, process all the elements
15213 and effectively concatenate them.
15214 If first element is a negative number, truncate displaying cdr to
15215 at most that many characters. If positive, pad (with spaces)
15216 to at least that many characters.
15217 If first element is a symbol, process the cadr or caddr recursively
15218 according to whether the symbol's value is non-nil or nil. */
15219 car = XCAR (elt);
15220 if (EQ (car, QCeval))
15222 /* An element of the form (:eval FORM) means evaluate FORM
15223 and use the result as mode line elements. */
15225 if (risky)
15226 break;
15228 if (CONSP (XCDR (elt)))
15230 Lisp_Object spec;
15231 spec = safe_eval (XCAR (XCDR (elt)));
15232 n += display_mode_element (it, depth, field_width - n,
15233 precision - n, spec, props,
15234 risky);
15237 else if (EQ (car, QCpropertize))
15239 /* An element of the form (:propertize ELT PROPS...)
15240 means display ELT but applying properties PROPS. */
15242 if (risky)
15243 break;
15245 if (CONSP (XCDR (elt)))
15246 n += display_mode_element (it, depth, field_width - n,
15247 precision - n, XCAR (XCDR (elt)),
15248 XCDR (XCDR (elt)), risky);
15250 else if (SYMBOLP (car))
15252 tem = Fboundp (car);
15253 elt = XCDR (elt);
15254 if (!CONSP (elt))
15255 goto invalid;
15256 /* elt is now the cdr, and we know it is a cons cell.
15257 Use its car if CAR has a non-nil value. */
15258 if (!NILP (tem))
15260 tem = Fsymbol_value (car);
15261 if (!NILP (tem))
15263 elt = XCAR (elt);
15264 goto tail_recurse;
15267 /* Symbol's value is nil (or symbol is unbound)
15268 Get the cddr of the original list
15269 and if possible find the caddr and use that. */
15270 elt = XCDR (elt);
15271 if (NILP (elt))
15272 break;
15273 else if (!CONSP (elt))
15274 goto invalid;
15275 elt = XCAR (elt);
15276 goto tail_recurse;
15278 else if (INTEGERP (car))
15280 register int lim = XINT (car);
15281 elt = XCDR (elt);
15282 if (lim < 0)
15284 /* Negative int means reduce maximum width. */
15285 if (precision <= 0)
15286 precision = -lim;
15287 else
15288 precision = min (precision, -lim);
15290 else if (lim > 0)
15292 /* Padding specified. Don't let it be more than
15293 current maximum. */
15294 if (precision > 0)
15295 lim = min (precision, lim);
15297 /* If that's more padding than already wanted, queue it.
15298 But don't reduce padding already specified even if
15299 that is beyond the current truncation point. */
15300 field_width = max (lim, field_width);
15302 goto tail_recurse;
15304 else if (STRINGP (car) || CONSP (car))
15306 register int limit = 50;
15307 /* Limit is to protect against circular lists. */
15308 while (CONSP (elt)
15309 && --limit > 0
15310 && (precision <= 0 || n < precision))
15312 n += display_mode_element (it, depth, field_width - n,
15313 precision - n, XCAR (elt),
15314 props, risky);
15315 elt = XCDR (elt);
15319 break;
15321 default:
15322 invalid:
15323 elt = build_string ("*invalid*");
15324 goto tail_recurse;
15327 /* Pad to FIELD_WIDTH. */
15328 if (field_width > 0 && n < field_width)
15330 if (frame_title_ptr)
15331 n += store_frame_title ("", field_width - n, 0);
15332 else if (!NILP (mode_line_string_list))
15333 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
15334 else
15335 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
15336 0, 0, 0);
15339 return n;
15342 /* Store a mode-line string element in mode_line_string_list.
15344 If STRING is non-null, display that C string. Otherwise, the Lisp
15345 string LISP_STRING is displayed.
15347 FIELD_WIDTH is the minimum number of output glyphs to produce.
15348 If STRING has fewer characters than FIELD_WIDTH, pad to the right
15349 with spaces. FIELD_WIDTH <= 0 means don't pad.
15351 PRECISION is the maximum number of characters to output from
15352 STRING. PRECISION <= 0 means don't truncate the string.
15354 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
15355 properties to the string.
15357 PROPS are the properties to add to the string.
15358 The mode_line_string_face face property is always added to the string.
15361 static int store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
15362 char *string;
15363 Lisp_Object lisp_string;
15364 int copy_string;
15365 int field_width;
15366 int precision;
15367 Lisp_Object props;
15369 int len;
15370 int n = 0;
15372 if (string != NULL)
15374 len = strlen (string);
15375 if (precision > 0 && len > precision)
15376 len = precision;
15377 lisp_string = make_string (string, len);
15378 if (NILP (props))
15379 props = mode_line_string_face_prop;
15380 else if (!NILP (mode_line_string_face))
15382 Lisp_Object face = Fplist_get (props, Qface);
15383 props = Fcopy_sequence (props);
15384 if (NILP (face))
15385 face = mode_line_string_face;
15386 else
15387 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15388 props = Fplist_put (props, Qface, face);
15390 Fadd_text_properties (make_number (0), make_number (len),
15391 props, lisp_string);
15393 else
15395 len = XFASTINT (Flength (lisp_string));
15396 if (precision > 0 && len > precision)
15398 len = precision;
15399 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
15400 precision = -1;
15402 if (!NILP (mode_line_string_face))
15404 Lisp_Object face;
15405 if (NILP (props))
15406 props = Ftext_properties_at (make_number (0), lisp_string);
15407 face = Fplist_get (props, Qface);
15408 if (NILP (face))
15409 face = mode_line_string_face;
15410 else
15411 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15412 props = Fcons (Qface, Fcons (face, Qnil));
15413 if (copy_string)
15414 lisp_string = Fcopy_sequence (lisp_string);
15416 if (!NILP (props))
15417 Fadd_text_properties (make_number (0), make_number (len),
15418 props, lisp_string);
15421 if (len > 0)
15423 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15424 n += len;
15427 if (field_width > len)
15429 field_width -= len;
15430 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
15431 if (!NILP (props))
15432 Fadd_text_properties (make_number (0), make_number (field_width),
15433 props, lisp_string);
15434 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15435 n += field_width;
15438 return n;
15442 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
15443 0, 3, 0,
15444 doc: /* Return the mode-line of selected window as a string.
15445 First optional arg FORMAT specifies a different format string (see
15446 `mode-line-format' for details) to use. If FORMAT is t, return
15447 the buffer's header-line. Second optional arg WINDOW specifies a
15448 different window to use as the context for the formatting.
15449 If third optional arg NO-PROPS is non-nil, string is not propertized. */)
15450 (format, window, no_props)
15451 Lisp_Object format, window, no_props;
15453 struct it it;
15454 int len;
15455 struct window *w;
15456 struct buffer *old_buffer = NULL;
15457 enum face_id face_id = DEFAULT_FACE_ID;
15459 if (NILP (window))
15460 window = selected_window;
15461 CHECK_WINDOW (window);
15462 w = XWINDOW (window);
15463 CHECK_BUFFER (w->buffer);
15465 if (XBUFFER (w->buffer) != current_buffer)
15467 old_buffer = current_buffer;
15468 set_buffer_internal_1 (XBUFFER (w->buffer));
15471 if (NILP (format) || EQ (format, Qt))
15473 face_id = NILP (format)
15474 ? CURRENT_MODE_LINE_FACE_ID (w) :
15475 HEADER_LINE_FACE_ID;
15476 format = NILP (format)
15477 ? current_buffer->mode_line_format
15478 : current_buffer->header_line_format;
15481 init_iterator (&it, w, -1, -1, NULL, face_id);
15483 if (NILP (no_props))
15485 mode_line_string_face =
15486 (face_id == MODE_LINE_FACE_ID ? Qmode_line :
15487 face_id == MODE_LINE_INACTIVE_FACE_ID ? Qmode_line_inactive :
15488 face_id == HEADER_LINE_FACE_ID ? Qheader_line : Qnil);
15490 mode_line_string_face_prop =
15491 NILP (mode_line_string_face) ? Qnil :
15492 Fcons (Qface, Fcons (mode_line_string_face, Qnil));
15494 /* We need a dummy last element in mode_line_string_list to
15495 indicate we are building the propertized mode-line string.
15496 Using mode_line_string_face_prop here GC protects it. */
15497 mode_line_string_list =
15498 Fcons (mode_line_string_face_prop, Qnil);
15499 frame_title_ptr = NULL;
15501 else
15503 mode_line_string_face_prop = Qnil;
15504 mode_line_string_list = Qnil;
15505 frame_title_ptr = frame_title_buf;
15508 push_frame_kboard (it.f);
15509 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
15510 pop_frame_kboard ();
15512 if (old_buffer)
15513 set_buffer_internal_1 (old_buffer);
15515 if (NILP (no_props))
15517 Lisp_Object str;
15518 mode_line_string_list = Fnreverse (mode_line_string_list);
15519 str = Fmapconcat (intern ("identity"), XCDR (mode_line_string_list),
15520 make_string ("", 0));
15521 mode_line_string_face_prop = Qnil;
15522 mode_line_string_list = Qnil;
15523 return str;
15526 len = frame_title_ptr - frame_title_buf;
15527 if (len > 0 && frame_title_ptr[-1] == '-')
15529 /* Mode lines typically ends with numerous dashes; reduce to two dashes. */
15530 while (frame_title_ptr > frame_title_buf && *--frame_title_ptr == '-')
15532 frame_title_ptr += 3; /* restore last non-dash + two dashes */
15533 if (len > frame_title_ptr - frame_title_buf)
15534 len = frame_title_ptr - frame_title_buf;
15537 frame_title_ptr = NULL;
15538 return make_string (frame_title_buf, len);
15541 /* Write a null-terminated, right justified decimal representation of
15542 the positive integer D to BUF using a minimal field width WIDTH. */
15544 static void
15545 pint2str (buf, width, d)
15546 register char *buf;
15547 register int width;
15548 register int d;
15550 register char *p = buf;
15552 if (d <= 0)
15553 *p++ = '0';
15554 else
15556 while (d > 0)
15558 *p++ = d % 10 + '0';
15559 d /= 10;
15563 for (width -= (int) (p - buf); width > 0; --width)
15564 *p++ = ' ';
15565 *p-- = '\0';
15566 while (p > buf)
15568 d = *buf;
15569 *buf++ = *p;
15570 *p-- = d;
15574 /* Write a null-terminated, right justified decimal and "human
15575 readable" representation of the nonnegative integer D to BUF using
15576 a minimal field width WIDTH. D should be smaller than 999.5e24. */
15578 static const char power_letter[] =
15580 0, /* not used */
15581 'k', /* kilo */
15582 'M', /* mega */
15583 'G', /* giga */
15584 'T', /* tera */
15585 'P', /* peta */
15586 'E', /* exa */
15587 'Z', /* zetta */
15588 'Y' /* yotta */
15591 static void
15592 pint2hrstr (buf, width, d)
15593 char *buf;
15594 int width;
15595 int d;
15597 /* We aim to represent the nonnegative integer D as
15598 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
15599 int quotient = d;
15600 int remainder = 0;
15601 /* -1 means: do not use TENTHS. */
15602 int tenths = -1;
15603 int exponent = 0;
15605 /* Length of QUOTIENT.TENTHS as a string. */
15606 int length;
15608 char * psuffix;
15609 char * p;
15611 if (1000 <= quotient)
15613 /* Scale to the appropriate EXPONENT. */
15616 remainder = quotient % 1000;
15617 quotient /= 1000;
15618 exponent++;
15620 while (1000 <= quotient);
15622 /* Round to nearest and decide whether to use TENTHS or not. */
15623 if (quotient <= 9)
15625 tenths = remainder / 100;
15626 if (50 <= remainder % 100)
15627 if (tenths < 9)
15628 tenths++;
15629 else
15631 quotient++;
15632 if (quotient == 10)
15633 tenths = -1;
15634 else
15635 tenths = 0;
15638 else
15639 if (500 <= remainder)
15640 if (quotient < 999)
15641 quotient++;
15642 else
15644 quotient = 1;
15645 exponent++;
15646 tenths = 0;
15650 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
15651 if (tenths == -1 && quotient <= 99)
15652 if (quotient <= 9)
15653 length = 1;
15654 else
15655 length = 2;
15656 else
15657 length = 3;
15658 p = psuffix = buf + max (width, length);
15660 /* Print EXPONENT. */
15661 if (exponent)
15662 *psuffix++ = power_letter[exponent];
15663 *psuffix = '\0';
15665 /* Print TENTHS. */
15666 if (tenths >= 0)
15668 *--p = '0' + tenths;
15669 *--p = '.';
15672 /* Print QUOTIENT. */
15675 int digit = quotient % 10;
15676 *--p = '0' + digit;
15678 while ((quotient /= 10) != 0);
15680 /* Print leading spaces. */
15681 while (buf < p)
15682 *--p = ' ';
15685 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
15686 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
15687 type of CODING_SYSTEM. Return updated pointer into BUF. */
15689 static unsigned char invalid_eol_type[] = "(*invalid*)";
15691 static char *
15692 decode_mode_spec_coding (coding_system, buf, eol_flag)
15693 Lisp_Object coding_system;
15694 register char *buf;
15695 int eol_flag;
15697 Lisp_Object val;
15698 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
15699 const unsigned char *eol_str;
15700 int eol_str_len;
15701 /* The EOL conversion we are using. */
15702 Lisp_Object eoltype;
15704 val = Fget (coding_system, Qcoding_system);
15705 eoltype = Qnil;
15707 if (!VECTORP (val)) /* Not yet decided. */
15709 if (multibyte)
15710 *buf++ = '-';
15711 if (eol_flag)
15712 eoltype = eol_mnemonic_undecided;
15713 /* Don't mention EOL conversion if it isn't decided. */
15715 else
15717 Lisp_Object eolvalue;
15719 eolvalue = Fget (coding_system, Qeol_type);
15721 if (multibyte)
15722 *buf++ = XFASTINT (AREF (val, 1));
15724 if (eol_flag)
15726 /* The EOL conversion that is normal on this system. */
15728 if (NILP (eolvalue)) /* Not yet decided. */
15729 eoltype = eol_mnemonic_undecided;
15730 else if (VECTORP (eolvalue)) /* Not yet decided. */
15731 eoltype = eol_mnemonic_undecided;
15732 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
15733 eoltype = (XFASTINT (eolvalue) == 0
15734 ? eol_mnemonic_unix
15735 : (XFASTINT (eolvalue) == 1
15736 ? eol_mnemonic_dos : eol_mnemonic_mac));
15740 if (eol_flag)
15742 /* Mention the EOL conversion if it is not the usual one. */
15743 if (STRINGP (eoltype))
15745 eol_str = SDATA (eoltype);
15746 eol_str_len = SBYTES (eoltype);
15748 else if (INTEGERP (eoltype)
15749 && CHAR_VALID_P (XINT (eoltype), 0))
15751 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
15752 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
15753 eol_str = tmp;
15755 else
15757 eol_str = invalid_eol_type;
15758 eol_str_len = sizeof (invalid_eol_type) - 1;
15760 bcopy (eol_str, buf, eol_str_len);
15761 buf += eol_str_len;
15764 return buf;
15767 /* Return a string for the output of a mode line %-spec for window W,
15768 generated by character C. PRECISION >= 0 means don't return a
15769 string longer than that value. FIELD_WIDTH > 0 means pad the
15770 string returned with spaces to that value. Return 1 in *MULTIBYTE
15771 if the result is multibyte text. */
15773 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
15775 static char *
15776 decode_mode_spec (w, c, field_width, precision, multibyte)
15777 struct window *w;
15778 register int c;
15779 int field_width, precision;
15780 int *multibyte;
15782 Lisp_Object obj;
15783 struct frame *f = XFRAME (WINDOW_FRAME (w));
15784 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
15785 struct buffer *b = XBUFFER (w->buffer);
15787 obj = Qnil;
15788 *multibyte = 0;
15790 switch (c)
15792 case '*':
15793 if (!NILP (b->read_only))
15794 return "%";
15795 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
15796 return "*";
15797 return "-";
15799 case '+':
15800 /* This differs from %* only for a modified read-only buffer. */
15801 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
15802 return "*";
15803 if (!NILP (b->read_only))
15804 return "%";
15805 return "-";
15807 case '&':
15808 /* This differs from %* in ignoring read-only-ness. */
15809 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
15810 return "*";
15811 return "-";
15813 case '%':
15814 return "%";
15816 case '[':
15818 int i;
15819 char *p;
15821 if (command_loop_level > 5)
15822 return "[[[... ";
15823 p = decode_mode_spec_buf;
15824 for (i = 0; i < command_loop_level; i++)
15825 *p++ = '[';
15826 *p = 0;
15827 return decode_mode_spec_buf;
15830 case ']':
15832 int i;
15833 char *p;
15835 if (command_loop_level > 5)
15836 return " ...]]]";
15837 p = decode_mode_spec_buf;
15838 for (i = 0; i < command_loop_level; i++)
15839 *p++ = ']';
15840 *p = 0;
15841 return decode_mode_spec_buf;
15844 case '-':
15846 register int i;
15848 /* Let lots_of_dashes be a string of infinite length. */
15849 if (!NILP (mode_line_string_list))
15850 return "--";
15851 if (field_width <= 0
15852 || field_width > sizeof (lots_of_dashes))
15854 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
15855 decode_mode_spec_buf[i] = '-';
15856 decode_mode_spec_buf[i] = '\0';
15857 return decode_mode_spec_buf;
15859 else
15860 return lots_of_dashes;
15863 case 'b':
15864 obj = b->name;
15865 break;
15867 case 'c':
15869 int col = (int) current_column (); /* iftc */
15870 w->column_number_displayed = make_number (col);
15871 pint2str (decode_mode_spec_buf, field_width, col);
15872 return decode_mode_spec_buf;
15875 case 'F':
15876 /* %F displays the frame name. */
15877 if (!NILP (f->title))
15878 return (char *) SDATA (f->title);
15879 if (f->explicit_name || ! FRAME_WINDOW_P (f))
15880 return (char *) SDATA (f->name);
15881 return "Emacs";
15883 case 'f':
15884 obj = b->filename;
15885 break;
15887 case 'i':
15889 int size = ZV - BEGV;
15890 pint2str (decode_mode_spec_buf, field_width, size);
15891 return decode_mode_spec_buf;
15894 case 'I':
15896 int size = ZV - BEGV;
15897 pint2hrstr (decode_mode_spec_buf, field_width, size);
15898 return decode_mode_spec_buf;
15901 case 'l':
15903 int startpos = XMARKER (w->start)->charpos;
15904 int startpos_byte = marker_byte_position (w->start);
15905 int line, linepos, linepos_byte, topline;
15906 int nlines, junk;
15907 int height = WINDOW_TOTAL_LINES (w);
15909 /* If we decided that this buffer isn't suitable for line numbers,
15910 don't forget that too fast. */
15911 if (EQ (w->base_line_pos, w->buffer))
15912 goto no_value;
15913 /* But do forget it, if the window shows a different buffer now. */
15914 else if (BUFFERP (w->base_line_pos))
15915 w->base_line_pos = Qnil;
15917 /* If the buffer is very big, don't waste time. */
15918 if (INTEGERP (Vline_number_display_limit)
15919 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
15921 w->base_line_pos = Qnil;
15922 w->base_line_number = Qnil;
15923 goto no_value;
15926 if (!NILP (w->base_line_number)
15927 && !NILP (w->base_line_pos)
15928 && XFASTINT (w->base_line_pos) <= startpos)
15930 line = XFASTINT (w->base_line_number);
15931 linepos = XFASTINT (w->base_line_pos);
15932 linepos_byte = buf_charpos_to_bytepos (b, linepos);
15934 else
15936 line = 1;
15937 linepos = BUF_BEGV (b);
15938 linepos_byte = BUF_BEGV_BYTE (b);
15941 /* Count lines from base line to window start position. */
15942 nlines = display_count_lines (linepos, linepos_byte,
15943 startpos_byte,
15944 startpos, &junk);
15946 topline = nlines + line;
15948 /* Determine a new base line, if the old one is too close
15949 or too far away, or if we did not have one.
15950 "Too close" means it's plausible a scroll-down would
15951 go back past it. */
15952 if (startpos == BUF_BEGV (b))
15954 w->base_line_number = make_number (topline);
15955 w->base_line_pos = make_number (BUF_BEGV (b));
15957 else if (nlines < height + 25 || nlines > height * 3 + 50
15958 || linepos == BUF_BEGV (b))
15960 int limit = BUF_BEGV (b);
15961 int limit_byte = BUF_BEGV_BYTE (b);
15962 int position;
15963 int distance = (height * 2 + 30) * line_number_display_limit_width;
15965 if (startpos - distance > limit)
15967 limit = startpos - distance;
15968 limit_byte = CHAR_TO_BYTE (limit);
15971 nlines = display_count_lines (startpos, startpos_byte,
15972 limit_byte,
15973 - (height * 2 + 30),
15974 &position);
15975 /* If we couldn't find the lines we wanted within
15976 line_number_display_limit_width chars per line,
15977 give up on line numbers for this window. */
15978 if (position == limit_byte && limit == startpos - distance)
15980 w->base_line_pos = w->buffer;
15981 w->base_line_number = Qnil;
15982 goto no_value;
15985 w->base_line_number = make_number (topline - nlines);
15986 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
15989 /* Now count lines from the start pos to point. */
15990 nlines = display_count_lines (startpos, startpos_byte,
15991 PT_BYTE, PT, &junk);
15993 /* Record that we did display the line number. */
15994 line_number_displayed = 1;
15996 /* Make the string to show. */
15997 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
15998 return decode_mode_spec_buf;
15999 no_value:
16001 char* p = decode_mode_spec_buf;
16002 int pad = field_width - 2;
16003 while (pad-- > 0)
16004 *p++ = ' ';
16005 *p++ = '?';
16006 *p++ = '?';
16007 *p = '\0';
16008 return decode_mode_spec_buf;
16011 break;
16013 case 'm':
16014 obj = b->mode_name;
16015 break;
16017 case 'n':
16018 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
16019 return " Narrow";
16020 break;
16022 case 'p':
16024 int pos = marker_position (w->start);
16025 int total = BUF_ZV (b) - BUF_BEGV (b);
16027 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
16029 if (pos <= BUF_BEGV (b))
16030 return "All";
16031 else
16032 return "Bottom";
16034 else if (pos <= BUF_BEGV (b))
16035 return "Top";
16036 else
16038 if (total > 1000000)
16039 /* Do it differently for a large value, to avoid overflow. */
16040 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16041 else
16042 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
16043 /* We can't normally display a 3-digit number,
16044 so get us a 2-digit number that is close. */
16045 if (total == 100)
16046 total = 99;
16047 sprintf (decode_mode_spec_buf, "%2d%%", total);
16048 return decode_mode_spec_buf;
16052 /* Display percentage of size above the bottom of the screen. */
16053 case 'P':
16055 int toppos = marker_position (w->start);
16056 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
16057 int total = BUF_ZV (b) - BUF_BEGV (b);
16059 if (botpos >= BUF_ZV (b))
16061 if (toppos <= BUF_BEGV (b))
16062 return "All";
16063 else
16064 return "Bottom";
16066 else
16068 if (total > 1000000)
16069 /* Do it differently for a large value, to avoid overflow. */
16070 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16071 else
16072 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
16073 /* We can't normally display a 3-digit number,
16074 so get us a 2-digit number that is close. */
16075 if (total == 100)
16076 total = 99;
16077 if (toppos <= BUF_BEGV (b))
16078 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
16079 else
16080 sprintf (decode_mode_spec_buf, "%2d%%", total);
16081 return decode_mode_spec_buf;
16085 case 's':
16086 /* status of process */
16087 obj = Fget_buffer_process (w->buffer);
16088 if (NILP (obj))
16089 return "no process";
16090 #ifdef subprocesses
16091 obj = Fsymbol_name (Fprocess_status (obj));
16092 #endif
16093 break;
16095 case 't': /* indicate TEXT or BINARY */
16096 #ifdef MODE_LINE_BINARY_TEXT
16097 return MODE_LINE_BINARY_TEXT (b);
16098 #else
16099 return "T";
16100 #endif
16102 case 'z':
16103 /* coding-system (not including end-of-line format) */
16104 case 'Z':
16105 /* coding-system (including end-of-line type) */
16107 int eol_flag = (c == 'Z');
16108 char *p = decode_mode_spec_buf;
16110 if (! FRAME_WINDOW_P (f))
16112 /* No need to mention EOL here--the terminal never needs
16113 to do EOL conversion. */
16114 p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
16115 p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
16117 p = decode_mode_spec_coding (b->buffer_file_coding_system,
16118 p, eol_flag);
16120 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
16121 #ifdef subprocesses
16122 obj = Fget_buffer_process (Fcurrent_buffer ());
16123 if (PROCESSP (obj))
16125 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
16126 p, eol_flag);
16127 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
16128 p, eol_flag);
16130 #endif /* subprocesses */
16131 #endif /* 0 */
16132 *p = 0;
16133 return decode_mode_spec_buf;
16137 if (STRINGP (obj))
16139 *multibyte = STRING_MULTIBYTE (obj);
16140 return (char *) SDATA (obj);
16142 else
16143 return "";
16147 /* Count up to COUNT lines starting from START / START_BYTE.
16148 But don't go beyond LIMIT_BYTE.
16149 Return the number of lines thus found (always nonnegative).
16151 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
16153 static int
16154 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
16155 int start, start_byte, limit_byte, count;
16156 int *byte_pos_ptr;
16158 register unsigned char *cursor;
16159 unsigned char *base;
16161 register int ceiling;
16162 register unsigned char *ceiling_addr;
16163 int orig_count = count;
16165 /* If we are not in selective display mode,
16166 check only for newlines. */
16167 int selective_display = (!NILP (current_buffer->selective_display)
16168 && !INTEGERP (current_buffer->selective_display));
16170 if (count > 0)
16172 while (start_byte < limit_byte)
16174 ceiling = BUFFER_CEILING_OF (start_byte);
16175 ceiling = min (limit_byte - 1, ceiling);
16176 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
16177 base = (cursor = BYTE_POS_ADDR (start_byte));
16178 while (1)
16180 if (selective_display)
16181 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
16183 else
16184 while (*cursor != '\n' && ++cursor != ceiling_addr)
16187 if (cursor != ceiling_addr)
16189 if (--count == 0)
16191 start_byte += cursor - base + 1;
16192 *byte_pos_ptr = start_byte;
16193 return orig_count;
16195 else
16196 if (++cursor == ceiling_addr)
16197 break;
16199 else
16200 break;
16202 start_byte += cursor - base;
16205 else
16207 while (start_byte > limit_byte)
16209 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
16210 ceiling = max (limit_byte, ceiling);
16211 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
16212 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
16213 while (1)
16215 if (selective_display)
16216 while (--cursor != ceiling_addr
16217 && *cursor != '\n' && *cursor != 015)
16219 else
16220 while (--cursor != ceiling_addr && *cursor != '\n')
16223 if (cursor != ceiling_addr)
16225 if (++count == 0)
16227 start_byte += cursor - base + 1;
16228 *byte_pos_ptr = start_byte;
16229 /* When scanning backwards, we should
16230 not count the newline posterior to which we stop. */
16231 return - orig_count - 1;
16234 else
16235 break;
16237 /* Here we add 1 to compensate for the last decrement
16238 of CURSOR, which took it past the valid range. */
16239 start_byte += cursor - base + 1;
16243 *byte_pos_ptr = limit_byte;
16245 if (count < 0)
16246 return - orig_count + count;
16247 return orig_count - count;
16253 /***********************************************************************
16254 Displaying strings
16255 ***********************************************************************/
16257 /* Display a NUL-terminated string, starting with index START.
16259 If STRING is non-null, display that C string. Otherwise, the Lisp
16260 string LISP_STRING is displayed.
16262 If FACE_STRING is not nil, FACE_STRING_POS is a position in
16263 FACE_STRING. Display STRING or LISP_STRING with the face at
16264 FACE_STRING_POS in FACE_STRING:
16266 Display the string in the environment given by IT, but use the
16267 standard display table, temporarily.
16269 FIELD_WIDTH is the minimum number of output glyphs to produce.
16270 If STRING has fewer characters than FIELD_WIDTH, pad to the right
16271 with spaces. If STRING has more characters, more than FIELD_WIDTH
16272 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
16274 PRECISION is the maximum number of characters to output from
16275 STRING. PRECISION < 0 means don't truncate the string.
16277 This is roughly equivalent to printf format specifiers:
16279 FIELD_WIDTH PRECISION PRINTF
16280 ----------------------------------------
16281 -1 -1 %s
16282 -1 10 %.10s
16283 10 -1 %10s
16284 20 10 %20.10s
16286 MULTIBYTE zero means do not display multibyte chars, > 0 means do
16287 display them, and < 0 means obey the current buffer's value of
16288 enable_multibyte_characters.
16290 Value is the number of glyphs produced. */
16292 static int
16293 display_string (string, lisp_string, face_string, face_string_pos,
16294 start, it, field_width, precision, max_x, multibyte)
16295 unsigned char *string;
16296 Lisp_Object lisp_string;
16297 Lisp_Object face_string;
16298 int face_string_pos;
16299 int start;
16300 struct it *it;
16301 int field_width, precision, max_x;
16302 int multibyte;
16304 int hpos_at_start = it->hpos;
16305 int saved_face_id = it->face_id;
16306 struct glyph_row *row = it->glyph_row;
16308 /* Initialize the iterator IT for iteration over STRING beginning
16309 with index START. */
16310 reseat_to_string (it, string, lisp_string, start,
16311 precision, field_width, multibyte);
16313 /* If displaying STRING, set up the face of the iterator
16314 from LISP_STRING, if that's given. */
16315 if (STRINGP (face_string))
16317 int endptr;
16318 struct face *face;
16320 it->face_id
16321 = face_at_string_position (it->w, face_string, face_string_pos,
16322 0, it->region_beg_charpos,
16323 it->region_end_charpos,
16324 &endptr, it->base_face_id, 0);
16325 face = FACE_FROM_ID (it->f, it->face_id);
16326 it->face_box_p = face->box != FACE_NO_BOX;
16329 /* Set max_x to the maximum allowed X position. Don't let it go
16330 beyond the right edge of the window. */
16331 if (max_x <= 0)
16332 max_x = it->last_visible_x;
16333 else
16334 max_x = min (max_x, it->last_visible_x);
16336 /* Skip over display elements that are not visible. because IT->w is
16337 hscrolled. */
16338 if (it->current_x < it->first_visible_x)
16339 move_it_in_display_line_to (it, 100000, it->first_visible_x,
16340 MOVE_TO_POS | MOVE_TO_X);
16342 row->ascent = it->max_ascent;
16343 row->height = it->max_ascent + it->max_descent;
16344 row->phys_ascent = it->max_phys_ascent;
16345 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
16347 /* This condition is for the case that we are called with current_x
16348 past last_visible_x. */
16349 while (it->current_x < max_x)
16351 int x_before, x, n_glyphs_before, i, nglyphs;
16353 /* Get the next display element. */
16354 if (!get_next_display_element (it))
16355 break;
16357 /* Produce glyphs. */
16358 x_before = it->current_x;
16359 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
16360 PRODUCE_GLYPHS (it);
16362 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
16363 i = 0;
16364 x = x_before;
16365 while (i < nglyphs)
16367 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
16369 if (!it->truncate_lines_p
16370 && x + glyph->pixel_width > max_x)
16372 /* End of continued line or max_x reached. */
16373 if (CHAR_GLYPH_PADDING_P (*glyph))
16375 /* A wide character is unbreakable. */
16376 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
16377 it->current_x = x_before;
16379 else
16381 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
16382 it->current_x = x;
16384 break;
16386 else if (x + glyph->pixel_width > it->first_visible_x)
16388 /* Glyph is at least partially visible. */
16389 ++it->hpos;
16390 if (x < it->first_visible_x)
16391 it->glyph_row->x = x - it->first_visible_x;
16393 else
16395 /* Glyph is off the left margin of the display area.
16396 Should not happen. */
16397 abort ();
16400 row->ascent = max (row->ascent, it->max_ascent);
16401 row->height = max (row->height, it->max_ascent + it->max_descent);
16402 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16403 row->phys_height = max (row->phys_height,
16404 it->max_phys_ascent + it->max_phys_descent);
16405 x += glyph->pixel_width;
16406 ++i;
16409 /* Stop if max_x reached. */
16410 if (i < nglyphs)
16411 break;
16413 /* Stop at line ends. */
16414 if (ITERATOR_AT_END_OF_LINE_P (it))
16416 it->continuation_lines_width = 0;
16417 break;
16420 set_iterator_to_next (it, 1);
16422 /* Stop if truncating at the right edge. */
16423 if (it->truncate_lines_p
16424 && it->current_x >= it->last_visible_x)
16426 /* Add truncation mark, but don't do it if the line is
16427 truncated at a padding space. */
16428 if (IT_CHARPOS (*it) < it->string_nchars)
16430 if (!FRAME_WINDOW_P (it->f))
16432 int i, n;
16434 if (it->current_x > it->last_visible_x)
16436 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
16437 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
16438 break;
16439 for (n = row->used[TEXT_AREA]; i < n; ++i)
16441 row->used[TEXT_AREA] = i;
16442 produce_special_glyphs (it, IT_TRUNCATION);
16445 produce_special_glyphs (it, IT_TRUNCATION);
16447 it->glyph_row->truncated_on_right_p = 1;
16449 break;
16453 /* Maybe insert a truncation at the left. */
16454 if (it->first_visible_x
16455 && IT_CHARPOS (*it) > 0)
16457 if (!FRAME_WINDOW_P (it->f))
16458 insert_left_trunc_glyphs (it);
16459 it->glyph_row->truncated_on_left_p = 1;
16462 it->face_id = saved_face_id;
16464 /* Value is number of columns displayed. */
16465 return it->hpos - hpos_at_start;
16470 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
16471 appears as an element of LIST or as the car of an element of LIST.
16472 If PROPVAL is a list, compare each element against LIST in that
16473 way, and return 1/2 if any element of PROPVAL is found in LIST.
16474 Otherwise return 0. This function cannot quit.
16475 The return value is 2 if the text is invisible but with an ellipsis
16476 and 1 if it's invisible and without an ellipsis. */
16479 invisible_p (propval, list)
16480 register Lisp_Object propval;
16481 Lisp_Object list;
16483 register Lisp_Object tail, proptail;
16485 for (tail = list; CONSP (tail); tail = XCDR (tail))
16487 register Lisp_Object tem;
16488 tem = XCAR (tail);
16489 if (EQ (propval, tem))
16490 return 1;
16491 if (CONSP (tem) && EQ (propval, XCAR (tem)))
16492 return NILP (XCDR (tem)) ? 1 : 2;
16495 if (CONSP (propval))
16497 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
16499 Lisp_Object propelt;
16500 propelt = XCAR (proptail);
16501 for (tail = list; CONSP (tail); tail = XCDR (tail))
16503 register Lisp_Object tem;
16504 tem = XCAR (tail);
16505 if (EQ (propelt, tem))
16506 return 1;
16507 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
16508 return NILP (XCDR (tem)) ? 1 : 2;
16513 return 0;
16517 /***********************************************************************
16518 Glyph Display
16519 ***********************************************************************/
16521 #ifdef HAVE_WINDOW_SYSTEM
16523 #if GLYPH_DEBUG
16525 void
16526 dump_glyph_string (s)
16527 struct glyph_string *s;
16529 fprintf (stderr, "glyph string\n");
16530 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
16531 s->x, s->y, s->width, s->height);
16532 fprintf (stderr, " ybase = %d\n", s->ybase);
16533 fprintf (stderr, " hl = %d\n", s->hl);
16534 fprintf (stderr, " left overhang = %d, right = %d\n",
16535 s->left_overhang, s->right_overhang);
16536 fprintf (stderr, " nchars = %d\n", s->nchars);
16537 fprintf (stderr, " extends to end of line = %d\n",
16538 s->extends_to_end_of_line_p);
16539 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
16540 fprintf (stderr, " bg width = %d\n", s->background_width);
16543 #endif /* GLYPH_DEBUG */
16545 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
16546 of XChar2b structures for S; it can't be allocated in
16547 init_glyph_string because it must be allocated via `alloca'. W
16548 is the window on which S is drawn. ROW and AREA are the glyph row
16549 and area within the row from which S is constructed. START is the
16550 index of the first glyph structure covered by S. HL is a
16551 face-override for drawing S. */
16553 #ifdef HAVE_NTGUI
16554 #define OPTIONAL_HDC(hdc) hdc,
16555 #define DECLARE_HDC(hdc) HDC hdc;
16556 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
16557 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
16558 #endif
16560 #ifndef OPTIONAL_HDC
16561 #define OPTIONAL_HDC(hdc)
16562 #define DECLARE_HDC(hdc)
16563 #define ALLOCATE_HDC(hdc, f)
16564 #define RELEASE_HDC(hdc, f)
16565 #endif
16567 static void
16568 init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
16569 struct glyph_string *s;
16570 DECLARE_HDC (hdc)
16571 XChar2b *char2b;
16572 struct window *w;
16573 struct glyph_row *row;
16574 enum glyph_row_area area;
16575 int start;
16576 enum draw_glyphs_face hl;
16578 bzero (s, sizeof *s);
16579 s->w = w;
16580 s->f = XFRAME (w->frame);
16581 #ifdef HAVE_NTGUI
16582 s->hdc = hdc;
16583 #endif
16584 s->display = FRAME_X_DISPLAY (s->f);
16585 s->window = FRAME_X_WINDOW (s->f);
16586 s->char2b = char2b;
16587 s->hl = hl;
16588 s->row = row;
16589 s->area = area;
16590 s->first_glyph = row->glyphs[area] + start;
16591 s->height = row->height;
16592 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
16594 /* Display the internal border below the tool-bar window. */
16595 if (s->w == XWINDOW (s->f->tool_bar_window))
16596 s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
16598 s->ybase = s->y + row->ascent;
16602 /* Append the list of glyph strings with head H and tail T to the list
16603 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
16605 static INLINE void
16606 append_glyph_string_lists (head, tail, h, t)
16607 struct glyph_string **head, **tail;
16608 struct glyph_string *h, *t;
16610 if (h)
16612 if (*head)
16613 (*tail)->next = h;
16614 else
16615 *head = h;
16616 h->prev = *tail;
16617 *tail = t;
16622 /* Prepend the list of glyph strings with head H and tail T to the
16623 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
16624 result. */
16626 static INLINE void
16627 prepend_glyph_string_lists (head, tail, h, t)
16628 struct glyph_string **head, **tail;
16629 struct glyph_string *h, *t;
16631 if (h)
16633 if (*head)
16634 (*head)->prev = t;
16635 else
16636 *tail = t;
16637 t->next = *head;
16638 *head = h;
16643 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
16644 Set *HEAD and *TAIL to the resulting list. */
16646 static INLINE void
16647 append_glyph_string (head, tail, s)
16648 struct glyph_string **head, **tail;
16649 struct glyph_string *s;
16651 s->next = s->prev = NULL;
16652 append_glyph_string_lists (head, tail, s, s);
16656 /* Get face and two-byte form of character glyph GLYPH on frame F.
16657 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
16658 a pointer to a realized face that is ready for display. */
16660 static INLINE struct face *
16661 get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
16662 struct frame *f;
16663 struct glyph *glyph;
16664 XChar2b *char2b;
16665 int *two_byte_p;
16667 struct face *face;
16669 xassert (glyph->type == CHAR_GLYPH);
16670 face = FACE_FROM_ID (f, glyph->face_id);
16672 if (two_byte_p)
16673 *two_byte_p = 0;
16675 if (!glyph->multibyte_p)
16677 /* Unibyte case. We don't have to encode, but we have to make
16678 sure to use a face suitable for unibyte. */
16679 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
16681 else if (glyph->u.ch < 128
16682 && glyph->face_id < BASIC_FACE_ID_SENTINEL)
16684 /* Case of ASCII in a face known to fit ASCII. */
16685 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
16687 else
16689 int c1, c2, charset;
16691 /* Split characters into bytes. If c2 is -1 afterwards, C is
16692 really a one-byte character so that byte1 is zero. */
16693 SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
16694 if (c2 > 0)
16695 STORE_XCHAR2B (char2b, c1, c2);
16696 else
16697 STORE_XCHAR2B (char2b, 0, c1);
16699 /* Maybe encode the character in *CHAR2B. */
16700 if (charset != CHARSET_ASCII)
16702 struct font_info *font_info
16703 = FONT_INFO_FROM_ID (f, face->font_info_id);
16704 if (font_info)
16705 glyph->font_type
16706 = rif->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
16710 /* Make sure X resources of the face are allocated. */
16711 xassert (face != NULL);
16712 PREPARE_FACE_FOR_DISPLAY (f, face);
16713 return face;
16717 /* Fill glyph string S with composition components specified by S->cmp.
16719 FACES is an array of faces for all components of this composition.
16720 S->gidx is the index of the first component for S.
16721 OVERLAPS_P non-zero means S should draw the foreground only, and
16722 use its physical height for clipping.
16724 Value is the index of a component not in S. */
16726 static int
16727 fill_composite_glyph_string (s, faces, overlaps_p)
16728 struct glyph_string *s;
16729 struct face **faces;
16730 int overlaps_p;
16732 int i;
16734 xassert (s);
16736 s->for_overlaps_p = overlaps_p;
16738 s->face = faces[s->gidx];
16739 s->font = s->face->font;
16740 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
16742 /* For all glyphs of this composition, starting at the offset
16743 S->gidx, until we reach the end of the definition or encounter a
16744 glyph that requires the different face, add it to S. */
16745 ++s->nchars;
16746 for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
16747 ++s->nchars;
16749 /* All glyph strings for the same composition has the same width,
16750 i.e. the width set for the first component of the composition. */
16752 s->width = s->first_glyph->pixel_width;
16754 /* If the specified font could not be loaded, use the frame's
16755 default font, but record the fact that we couldn't load it in
16756 the glyph string so that we can draw rectangles for the
16757 characters of the glyph string. */
16758 if (s->font == NULL)
16760 s->font_not_found_p = 1;
16761 s->font = FRAME_FONT (s->f);
16764 /* Adjust base line for subscript/superscript text. */
16765 s->ybase += s->first_glyph->voffset;
16767 xassert (s->face && s->face->gc);
16769 /* This glyph string must always be drawn with 16-bit functions. */
16770 s->two_byte_p = 1;
16772 return s->gidx + s->nchars;
16776 /* Fill glyph string S from a sequence of character glyphs.
16778 FACE_ID is the face id of the string. START is the index of the
16779 first glyph to consider, END is the index of the last + 1.
16780 OVERLAPS_P non-zero means S should draw the foreground only, and
16781 use its physical height for clipping.
16783 Value is the index of the first glyph not in S. */
16785 static int
16786 fill_glyph_string (s, face_id, start, end, overlaps_p)
16787 struct glyph_string *s;
16788 int face_id;
16789 int start, end, overlaps_p;
16791 struct glyph *glyph, *last;
16792 int voffset;
16793 int glyph_not_available_p;
16795 xassert (s->f == XFRAME (s->w->frame));
16796 xassert (s->nchars == 0);
16797 xassert (start >= 0 && end > start);
16799 s->for_overlaps_p = overlaps_p,
16800 glyph = s->row->glyphs[s->area] + start;
16801 last = s->row->glyphs[s->area] + end;
16802 voffset = glyph->voffset;
16804 glyph_not_available_p = glyph->glyph_not_available_p;
16806 while (glyph < last
16807 && glyph->type == CHAR_GLYPH
16808 && glyph->voffset == voffset
16809 /* Same face id implies same font, nowadays. */
16810 && glyph->face_id == face_id
16811 && glyph->glyph_not_available_p == glyph_not_available_p)
16813 int two_byte_p;
16815 s->face = get_glyph_face_and_encoding (s->f, glyph,
16816 s->char2b + s->nchars,
16817 &two_byte_p);
16818 s->two_byte_p = two_byte_p;
16819 ++s->nchars;
16820 xassert (s->nchars <= end - start);
16821 s->width += glyph->pixel_width;
16822 ++glyph;
16825 s->font = s->face->font;
16826 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
16828 /* If the specified font could not be loaded, use the frame's font,
16829 but record the fact that we couldn't load it in
16830 S->font_not_found_p so that we can draw rectangles for the
16831 characters of the glyph string. */
16832 if (s->font == NULL || glyph_not_available_p)
16834 s->font_not_found_p = 1;
16835 s->font = FRAME_FONT (s->f);
16838 /* Adjust base line for subscript/superscript text. */
16839 s->ybase += voffset;
16841 xassert (s->face && s->face->gc);
16842 return glyph - s->row->glyphs[s->area];
16846 /* Fill glyph string S from image glyph S->first_glyph. */
16848 static void
16849 fill_image_glyph_string (s)
16850 struct glyph_string *s;
16852 xassert (s->first_glyph->type == IMAGE_GLYPH);
16853 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
16854 xassert (s->img);
16855 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
16856 s->font = s->face->font;
16857 s->width = s->first_glyph->pixel_width;
16859 /* Adjust base line for subscript/superscript text. */
16860 s->ybase += s->first_glyph->voffset;
16864 /* Fill glyph string S from a sequence of stretch glyphs.
16866 ROW is the glyph row in which the glyphs are found, AREA is the
16867 area within the row. START is the index of the first glyph to
16868 consider, END is the index of the last + 1.
16870 Value is the index of the first glyph not in S. */
16872 static int
16873 fill_stretch_glyph_string (s, row, area, start, end)
16874 struct glyph_string *s;
16875 struct glyph_row *row;
16876 enum glyph_row_area area;
16877 int start, end;
16879 struct glyph *glyph, *last;
16880 int voffset, face_id;
16882 xassert (s->first_glyph->type == STRETCH_GLYPH);
16884 glyph = s->row->glyphs[s->area] + start;
16885 last = s->row->glyphs[s->area] + end;
16886 face_id = glyph->face_id;
16887 s->face = FACE_FROM_ID (s->f, face_id);
16888 s->font = s->face->font;
16889 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
16890 s->width = glyph->pixel_width;
16891 voffset = glyph->voffset;
16893 for (++glyph;
16894 (glyph < last
16895 && glyph->type == STRETCH_GLYPH
16896 && glyph->voffset == voffset
16897 && glyph->face_id == face_id);
16898 ++glyph)
16899 s->width += glyph->pixel_width;
16901 /* Adjust base line for subscript/superscript text. */
16902 s->ybase += voffset;
16904 /* The case that face->gc == 0 is handled when drawing the glyph
16905 string by calling PREPARE_FACE_FOR_DISPLAY. */
16906 xassert (s->face);
16907 return glyph - s->row->glyphs[s->area];
16911 /* EXPORT for RIF:
16912 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
16913 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
16914 assumed to be zero. */
16916 void
16917 x_get_glyph_overhangs (glyph, f, left, right)
16918 struct glyph *glyph;
16919 struct frame *f;
16920 int *left, *right;
16922 *left = *right = 0;
16924 if (glyph->type == CHAR_GLYPH)
16926 XFontStruct *font;
16927 struct face *face;
16928 struct font_info *font_info;
16929 XChar2b char2b;
16930 XCharStruct *pcm;
16932 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
16933 font = face->font;
16934 font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
16935 if (font /* ++KFS: Should this be font_info ? */
16936 && (pcm = rif->per_char_metric (font, &char2b, glyph->font_type)))
16938 if (pcm->rbearing > pcm->width)
16939 *right = pcm->rbearing - pcm->width;
16940 if (pcm->lbearing < 0)
16941 *left = -pcm->lbearing;
16947 /* Return the index of the first glyph preceding glyph string S that
16948 is overwritten by S because of S's left overhang. Value is -1
16949 if no glyphs are overwritten. */
16951 static int
16952 left_overwritten (s)
16953 struct glyph_string *s;
16955 int k;
16957 if (s->left_overhang)
16959 int x = 0, i;
16960 struct glyph *glyphs = s->row->glyphs[s->area];
16961 int first = s->first_glyph - glyphs;
16963 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
16964 x -= glyphs[i].pixel_width;
16966 k = i + 1;
16968 else
16969 k = -1;
16971 return k;
16975 /* Return the index of the first glyph preceding glyph string S that
16976 is overwriting S because of its right overhang. Value is -1 if no
16977 glyph in front of S overwrites S. */
16979 static int
16980 left_overwriting (s)
16981 struct glyph_string *s;
16983 int i, k, x;
16984 struct glyph *glyphs = s->row->glyphs[s->area];
16985 int first = s->first_glyph - glyphs;
16987 k = -1;
16988 x = 0;
16989 for (i = first - 1; i >= 0; --i)
16991 int left, right;
16992 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
16993 if (x + right > 0)
16994 k = i;
16995 x -= glyphs[i].pixel_width;
16998 return k;
17002 /* Return the index of the last glyph following glyph string S that is
17003 not overwritten by S because of S's right overhang. Value is -1 if
17004 no such glyph is found. */
17006 static int
17007 right_overwritten (s)
17008 struct glyph_string *s;
17010 int k = -1;
17012 if (s->right_overhang)
17014 int x = 0, i;
17015 struct glyph *glyphs = s->row->glyphs[s->area];
17016 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17017 int end = s->row->used[s->area];
17019 for (i = first; i < end && s->right_overhang > x; ++i)
17020 x += glyphs[i].pixel_width;
17022 k = i;
17025 return k;
17029 /* Return the index of the last glyph following glyph string S that
17030 overwrites S because of its left overhang. Value is negative
17031 if no such glyph is found. */
17033 static int
17034 right_overwriting (s)
17035 struct glyph_string *s;
17037 int i, k, x;
17038 int end = s->row->used[s->area];
17039 struct glyph *glyphs = s->row->glyphs[s->area];
17040 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17042 k = -1;
17043 x = 0;
17044 for (i = first; i < end; ++i)
17046 int left, right;
17047 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
17048 if (x - left < 0)
17049 k = i;
17050 x += glyphs[i].pixel_width;
17053 return k;
17057 /* Get face and two-byte form of character C in face FACE_ID on frame
17058 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
17059 means we want to display multibyte text. DISPLAY_P non-zero means
17060 make sure that X resources for the face returned are allocated.
17061 Value is a pointer to a realized face that is ready for display if
17062 DISPLAY_P is non-zero. */
17064 static INLINE struct face *
17065 get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
17066 struct frame *f;
17067 int c, face_id;
17068 XChar2b *char2b;
17069 int multibyte_p, display_p;
17071 struct face *face = FACE_FROM_ID (f, face_id);
17073 if (!multibyte_p)
17075 /* Unibyte case. We don't have to encode, but we have to make
17076 sure to use a face suitable for unibyte. */
17077 STORE_XCHAR2B (char2b, 0, c);
17078 face_id = FACE_FOR_CHAR (f, face, c);
17079 face = FACE_FROM_ID (f, face_id);
17081 else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL)
17083 /* Case of ASCII in a face known to fit ASCII. */
17084 STORE_XCHAR2B (char2b, 0, c);
17086 else
17088 int c1, c2, charset;
17090 /* Split characters into bytes. If c2 is -1 afterwards, C is
17091 really a one-byte character so that byte1 is zero. */
17092 SPLIT_CHAR (c, charset, c1, c2);
17093 if (c2 > 0)
17094 STORE_XCHAR2B (char2b, c1, c2);
17095 else
17096 STORE_XCHAR2B (char2b, 0, c1);
17098 /* Maybe encode the character in *CHAR2B. */
17099 if (face->font != NULL)
17101 struct font_info *font_info
17102 = FONT_INFO_FROM_ID (f, face->font_info_id);
17103 if (font_info)
17104 rif->encode_char (c, char2b, font_info, 0);
17108 /* Make sure X resources of the face are allocated. */
17109 #ifdef HAVE_X_WINDOWS
17110 if (display_p)
17111 #endif
17113 xassert (face != NULL);
17114 PREPARE_FACE_FOR_DISPLAY (f, face);
17117 return face;
17121 /* Set background width of glyph string S. START is the index of the
17122 first glyph following S. LAST_X is the right-most x-position + 1
17123 in the drawing area. */
17125 static INLINE void
17126 set_glyph_string_background_width (s, start, last_x)
17127 struct glyph_string *s;
17128 int start;
17129 int last_x;
17131 /* If the face of this glyph string has to be drawn to the end of
17132 the drawing area, set S->extends_to_end_of_line_p. */
17133 struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID);
17135 if (start == s->row->used[s->area]
17136 && s->area == TEXT_AREA
17137 && ((s->hl == DRAW_NORMAL_TEXT
17138 && (s->row->fill_line_p
17139 || s->face->background != default_face->background
17140 || s->face->stipple != default_face->stipple
17141 || s->row->mouse_face_p))
17142 || s->hl == DRAW_MOUSE_FACE
17143 || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN)
17144 && s->row->fill_line_p)))
17145 s->extends_to_end_of_line_p = 1;
17147 /* If S extends its face to the end of the line, set its
17148 background_width to the distance to the right edge of the drawing
17149 area. */
17150 if (s->extends_to_end_of_line_p)
17151 s->background_width = last_x - s->x + 1;
17152 else
17153 s->background_width = s->width;
17157 /* Compute overhangs and x-positions for glyph string S and its
17158 predecessors, or successors. X is the starting x-position for S.
17159 BACKWARD_P non-zero means process predecessors. */
17161 static void
17162 compute_overhangs_and_x (s, x, backward_p)
17163 struct glyph_string *s;
17164 int x;
17165 int backward_p;
17167 if (backward_p)
17169 while (s)
17171 if (rif->compute_glyph_string_overhangs)
17172 rif->compute_glyph_string_overhangs (s);
17173 x -= s->width;
17174 s->x = x;
17175 s = s->prev;
17178 else
17180 while (s)
17182 if (rif->compute_glyph_string_overhangs)
17183 rif->compute_glyph_string_overhangs (s);
17184 s->x = x;
17185 x += s->width;
17186 s = s->next;
17193 /* The following macros are only called from draw_glyphs below.
17194 They reference the following parameters of that function directly:
17195 `w', `row', `area', and `overlap_p'
17196 as well as the following local variables:
17197 `s', `f', and `hdc' (in W32) */
17199 #ifdef HAVE_NTGUI
17200 /* On W32, silently add local `hdc' variable to argument list of
17201 init_glyph_string. */
17202 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17203 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
17204 #else
17205 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17206 init_glyph_string (s, char2b, w, row, area, start, hl)
17207 #endif
17209 /* Add a glyph string for a stretch glyph to the list of strings
17210 between HEAD and TAIL. START is the index of the stretch glyph in
17211 row area AREA of glyph row ROW. END is the index of the last glyph
17212 in that glyph row area. X is the current output position assigned
17213 to the new glyph string constructed. HL overrides that face of the
17214 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17215 is the right-most x-position of the drawing area. */
17217 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
17218 and below -- keep them on one line. */
17219 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17220 do \
17222 s = (struct glyph_string *) alloca (sizeof *s); \
17223 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17224 START = fill_stretch_glyph_string (s, row, area, START, END); \
17225 append_glyph_string (&HEAD, &TAIL, s); \
17226 s->x = (X); \
17228 while (0)
17231 /* Add a glyph string for an image glyph to the list of strings
17232 between HEAD and TAIL. START is the index of the image glyph in
17233 row area AREA of glyph row ROW. END is the index of the last glyph
17234 in that glyph row area. X is the current output position assigned
17235 to the new glyph string constructed. HL overrides that face of the
17236 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17237 is the right-most x-position of the drawing area. */
17239 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17240 do \
17242 s = (struct glyph_string *) alloca (sizeof *s); \
17243 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17244 fill_image_glyph_string (s); \
17245 append_glyph_string (&HEAD, &TAIL, s); \
17246 ++START; \
17247 s->x = (X); \
17249 while (0)
17252 /* Add a glyph string for a sequence of character glyphs to the list
17253 of strings between HEAD and TAIL. START is the index of the first
17254 glyph in row area AREA of glyph row ROW that is part of the new
17255 glyph string. END is the index of the last glyph in that glyph row
17256 area. X is the current output position assigned to the new glyph
17257 string constructed. HL overrides that face of the glyph; e.g. it
17258 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
17259 right-most x-position of the drawing area. */
17261 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17262 do \
17264 int c, face_id; \
17265 XChar2b *char2b; \
17267 c = (row)->glyphs[area][START].u.ch; \
17268 face_id = (row)->glyphs[area][START].face_id; \
17270 s = (struct glyph_string *) alloca (sizeof *s); \
17271 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
17272 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
17273 append_glyph_string (&HEAD, &TAIL, s); \
17274 s->x = (X); \
17275 START = fill_glyph_string (s, face_id, START, END, overlaps_p); \
17277 while (0)
17280 /* Add a glyph string for a composite sequence to the list of strings
17281 between HEAD and TAIL. START is the index of the first glyph in
17282 row area AREA of glyph row ROW that is part of the new glyph
17283 string. END is the index of the last glyph in that glyph row area.
17284 X is the current output position assigned to the new glyph string
17285 constructed. HL overrides that face of the glyph; e.g. it is
17286 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
17287 x-position of the drawing area. */
17289 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17290 do { \
17291 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
17292 int face_id = (row)->glyphs[area][START].face_id; \
17293 struct face *base_face = FACE_FROM_ID (f, face_id); \
17294 struct composition *cmp = composition_table[cmp_id]; \
17295 int glyph_len = cmp->glyph_len; \
17296 XChar2b *char2b; \
17297 struct face **faces; \
17298 struct glyph_string *first_s = NULL; \
17299 int n; \
17301 base_face = base_face->ascii_face; \
17302 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
17303 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
17304 /* At first, fill in `char2b' and `faces'. */ \
17305 for (n = 0; n < glyph_len; n++) \
17307 int c = COMPOSITION_GLYPH (cmp, n); \
17308 int this_face_id = FACE_FOR_CHAR (f, base_face, c); \
17309 faces[n] = FACE_FROM_ID (f, this_face_id); \
17310 get_char_face_and_encoding (f, c, this_face_id, \
17311 char2b + n, 1, 1); \
17314 /* Make glyph_strings for each glyph sequence that is drawable by \
17315 the same face, and append them to HEAD/TAIL. */ \
17316 for (n = 0; n < cmp->glyph_len;) \
17318 s = (struct glyph_string *) alloca (sizeof *s); \
17319 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \
17320 append_glyph_string (&(HEAD), &(TAIL), s); \
17321 s->cmp = cmp; \
17322 s->gidx = n; \
17323 s->x = (X); \
17325 if (n == 0) \
17326 first_s = s; \
17328 n = fill_composite_glyph_string (s, faces, overlaps_p); \
17331 ++START; \
17332 s = first_s; \
17333 } while (0)
17336 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
17337 of AREA of glyph row ROW on window W between indices START and END.
17338 HL overrides the face for drawing glyph strings, e.g. it is
17339 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
17340 x-positions of the drawing area.
17342 This is an ugly monster macro construct because we must use alloca
17343 to allocate glyph strings (because draw_glyphs can be called
17344 asynchronously). */
17346 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17347 do \
17349 HEAD = TAIL = NULL; \
17350 while (START < END) \
17352 struct glyph *first_glyph = (row)->glyphs[area] + START; \
17353 switch (first_glyph->type) \
17355 case CHAR_GLYPH: \
17356 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
17357 HL, X, LAST_X); \
17358 break; \
17360 case COMPOSITE_GLYPH: \
17361 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
17362 HL, X, LAST_X); \
17363 break; \
17365 case STRETCH_GLYPH: \
17366 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
17367 HL, X, LAST_X); \
17368 break; \
17370 case IMAGE_GLYPH: \
17371 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
17372 HL, X, LAST_X); \
17373 break; \
17375 default: \
17376 abort (); \
17379 set_glyph_string_background_width (s, START, LAST_X); \
17380 (X) += s->width; \
17383 while (0)
17386 /* Draw glyphs between START and END in AREA of ROW on window W,
17387 starting at x-position X. X is relative to AREA in W. HL is a
17388 face-override with the following meaning:
17390 DRAW_NORMAL_TEXT draw normally
17391 DRAW_CURSOR draw in cursor face
17392 DRAW_MOUSE_FACE draw in mouse face.
17393 DRAW_INVERSE_VIDEO draw in mode line face
17394 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
17395 DRAW_IMAGE_RAISED draw an image with a raised relief around it
17397 If OVERLAPS_P is non-zero, draw only the foreground of characters
17398 and clip to the physical height of ROW.
17400 Value is the x-position reached, relative to AREA of W. */
17402 static int
17403 draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
17404 struct window *w;
17405 int x;
17406 struct glyph_row *row;
17407 enum glyph_row_area area;
17408 int start, end;
17409 enum draw_glyphs_face hl;
17410 int overlaps_p;
17412 struct glyph_string *head, *tail;
17413 struct glyph_string *s;
17414 int last_x, area_width;
17415 int x_reached;
17416 int i, j;
17417 struct frame *f = XFRAME (WINDOW_FRAME (w));
17418 DECLARE_HDC (hdc);
17420 ALLOCATE_HDC (hdc, f);
17422 /* Let's rather be paranoid than getting a SEGV. */
17423 end = min (end, row->used[area]);
17424 start = max (0, start);
17425 start = min (end, start);
17427 /* Translate X to frame coordinates. Set last_x to the right
17428 end of the drawing area. */
17429 if (row->full_width_p)
17431 /* X is relative to the left edge of W, without scroll bars
17432 or fringes. */
17433 x += WINDOW_LEFT_EDGE_X (w);
17434 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
17436 else
17438 int area_left = window_box_left (w, area);
17439 x += area_left;
17440 area_width = window_box_width (w, area);
17441 last_x = area_left + area_width;
17444 /* Build a doubly-linked list of glyph_string structures between
17445 head and tail from what we have to draw. Note that the macro
17446 BUILD_GLYPH_STRINGS will modify its start parameter. That's
17447 the reason we use a separate variable `i'. */
17448 i = start;
17449 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
17450 if (tail)
17451 x_reached = tail->x + tail->background_width;
17452 else
17453 x_reached = x;
17455 /* If there are any glyphs with lbearing < 0 or rbearing > width in
17456 the row, redraw some glyphs in front or following the glyph
17457 strings built above. */
17458 if (head && !overlaps_p && row->contains_overlapping_glyphs_p)
17460 int dummy_x = 0;
17461 struct glyph_string *h, *t;
17463 /* Compute overhangs for all glyph strings. */
17464 if (rif->compute_glyph_string_overhangs)
17465 for (s = head; s; s = s->next)
17466 rif->compute_glyph_string_overhangs (s);
17468 /* Prepend glyph strings for glyphs in front of the first glyph
17469 string that are overwritten because of the first glyph
17470 string's left overhang. The background of all strings
17471 prepended must be drawn because the first glyph string
17472 draws over it. */
17473 i = left_overwritten (head);
17474 if (i >= 0)
17476 j = i;
17477 BUILD_GLYPH_STRINGS (j, start, h, t,
17478 DRAW_NORMAL_TEXT, dummy_x, last_x);
17479 start = i;
17480 compute_overhangs_and_x (t, head->x, 1);
17481 prepend_glyph_string_lists (&head, &tail, h, t);
17484 /* Prepend glyph strings for glyphs in front of the first glyph
17485 string that overwrite that glyph string because of their
17486 right overhang. For these strings, only the foreground must
17487 be drawn, because it draws over the glyph string at `head'.
17488 The background must not be drawn because this would overwrite
17489 right overhangs of preceding glyphs for which no glyph
17490 strings exist. */
17491 i = left_overwriting (head);
17492 if (i >= 0)
17494 BUILD_GLYPH_STRINGS (i, start, h, t,
17495 DRAW_NORMAL_TEXT, dummy_x, last_x);
17496 for (s = h; s; s = s->next)
17497 s->background_filled_p = 1;
17498 compute_overhangs_and_x (t, head->x, 1);
17499 prepend_glyph_string_lists (&head, &tail, h, t);
17502 /* Append glyphs strings for glyphs following the last glyph
17503 string tail that are overwritten by tail. The background of
17504 these strings has to be drawn because tail's foreground draws
17505 over it. */
17506 i = right_overwritten (tail);
17507 if (i >= 0)
17509 BUILD_GLYPH_STRINGS (end, i, h, t,
17510 DRAW_NORMAL_TEXT, x, last_x);
17511 compute_overhangs_and_x (h, tail->x + tail->width, 0);
17512 append_glyph_string_lists (&head, &tail, h, t);
17515 /* Append glyph strings for glyphs following the last glyph
17516 string tail that overwrite tail. The foreground of such
17517 glyphs has to be drawn because it writes into the background
17518 of tail. The background must not be drawn because it could
17519 paint over the foreground of following glyphs. */
17520 i = right_overwriting (tail);
17521 if (i >= 0)
17523 BUILD_GLYPH_STRINGS (end, i, h, t,
17524 DRAW_NORMAL_TEXT, x, last_x);
17525 for (s = h; s; s = s->next)
17526 s->background_filled_p = 1;
17527 compute_overhangs_and_x (h, tail->x + tail->width, 0);
17528 append_glyph_string_lists (&head, &tail, h, t);
17532 /* Draw all strings. */
17533 for (s = head; s; s = s->next)
17534 rif->draw_glyph_string (s);
17536 if (area == TEXT_AREA
17537 && !row->full_width_p
17538 /* When drawing overlapping rows, only the glyph strings'
17539 foreground is drawn, which doesn't erase a cursor
17540 completely. */
17541 && !overlaps_p)
17543 int x0 = head ? head->x : x;
17544 int x1 = tail ? tail->x + tail->background_width : x;
17546 int text_left = window_box_left (w, TEXT_AREA);
17547 x0 -= text_left;
17548 x1 -= text_left;
17550 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
17551 row->y, MATRIX_ROW_BOTTOM_Y (row));
17554 /* Value is the x-position up to which drawn, relative to AREA of W.
17555 This doesn't include parts drawn because of overhangs. */
17556 if (row->full_width_p)
17557 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
17558 else
17559 x_reached -= window_box_left (w, area);
17561 RELEASE_HDC (hdc, f);
17563 return x_reached;
17567 /* Store one glyph for IT->char_to_display in IT->glyph_row.
17568 Called from x_produce_glyphs when IT->glyph_row is non-null. */
17570 static INLINE void
17571 append_glyph (it)
17572 struct it *it;
17574 struct glyph *glyph;
17575 enum glyph_row_area area = it->area;
17577 xassert (it->glyph_row);
17578 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
17580 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
17581 if (glyph < it->glyph_row->glyphs[area + 1])
17583 glyph->charpos = CHARPOS (it->position);
17584 glyph->object = it->object;
17585 glyph->pixel_width = it->pixel_width;
17586 glyph->ascent = it->ascent;
17587 glyph->descent = it->descent;
17588 glyph->voffset = it->voffset;
17589 glyph->type = CHAR_GLYPH;
17590 glyph->multibyte_p = it->multibyte_p;
17591 glyph->left_box_line_p = it->start_of_box_run_p;
17592 glyph->right_box_line_p = it->end_of_box_run_p;
17593 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
17594 || it->phys_descent > it->descent);
17595 glyph->padding_p = 0;
17596 glyph->glyph_not_available_p = it->glyph_not_available_p;
17597 glyph->face_id = it->face_id;
17598 glyph->u.ch = it->char_to_display;
17599 glyph->font_type = FONT_TYPE_UNKNOWN;
17600 ++it->glyph_row->used[area];
17604 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
17605 Called from x_produce_glyphs when IT->glyph_row is non-null. */
17607 static INLINE void
17608 append_composite_glyph (it)
17609 struct it *it;
17611 struct glyph *glyph;
17612 enum glyph_row_area area = it->area;
17614 xassert (it->glyph_row);
17616 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
17617 if (glyph < it->glyph_row->glyphs[area + 1])
17619 glyph->charpos = CHARPOS (it->position);
17620 glyph->object = it->object;
17621 glyph->pixel_width = it->pixel_width;
17622 glyph->ascent = it->ascent;
17623 glyph->descent = it->descent;
17624 glyph->voffset = it->voffset;
17625 glyph->type = COMPOSITE_GLYPH;
17626 glyph->multibyte_p = it->multibyte_p;
17627 glyph->left_box_line_p = it->start_of_box_run_p;
17628 glyph->right_box_line_p = it->end_of_box_run_p;
17629 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
17630 || it->phys_descent > it->descent);
17631 glyph->padding_p = 0;
17632 glyph->glyph_not_available_p = 0;
17633 glyph->face_id = it->face_id;
17634 glyph->u.cmp_id = it->cmp_id;
17635 glyph->font_type = FONT_TYPE_UNKNOWN;
17636 ++it->glyph_row->used[area];
17641 /* Change IT->ascent and IT->height according to the setting of
17642 IT->voffset. */
17644 static INLINE void
17645 take_vertical_position_into_account (it)
17646 struct it *it;
17648 if (it->voffset)
17650 if (it->voffset < 0)
17651 /* Increase the ascent so that we can display the text higher
17652 in the line. */
17653 it->ascent += abs (it->voffset);
17654 else
17655 /* Increase the descent so that we can display the text lower
17656 in the line. */
17657 it->descent += it->voffset;
17662 /* Produce glyphs/get display metrics for the image IT is loaded with.
17663 See the description of struct display_iterator in dispextern.h for
17664 an overview of struct display_iterator. */
17666 static void
17667 produce_image_glyph (it)
17668 struct it *it;
17670 struct image *img;
17671 struct face *face;
17672 int face_ascent, glyph_ascent;
17674 xassert (it->what == IT_IMAGE);
17676 face = FACE_FROM_ID (it->f, it->face_id);
17677 img = IMAGE_FROM_ID (it->f, it->image_id);
17678 xassert (img);
17680 /* Make sure X resources of the face and image are loaded. */
17681 PREPARE_FACE_FOR_DISPLAY (it->f, face);
17682 prepare_image_for_display (it->f, img);
17684 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face);
17685 it->descent = it->phys_descent = img->height + 2 * img->vmargin - it->ascent;
17686 it->pixel_width = img->width + 2 * img->hmargin;
17688 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
17689 face_ascent = face->font ? FONT_BASE (face->font) : FRAME_BASELINE_OFFSET (it->f);
17690 if (face_ascent > it->ascent)
17691 it->ascent = it->phys_ascent = face_ascent;
17693 it->nglyphs = 1;
17695 if (face->box != FACE_NO_BOX)
17697 if (face->box_line_width > 0)
17699 it->ascent += face->box_line_width;
17700 it->descent += face->box_line_width;
17703 if (it->start_of_box_run_p)
17704 it->pixel_width += abs (face->box_line_width);
17705 if (it->end_of_box_run_p)
17706 it->pixel_width += abs (face->box_line_width);
17709 take_vertical_position_into_account (it);
17711 if (it->glyph_row)
17713 struct glyph *glyph;
17714 enum glyph_row_area area = it->area;
17716 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
17717 if (glyph < it->glyph_row->glyphs[area + 1])
17719 glyph->charpos = CHARPOS (it->position);
17720 glyph->object = it->object;
17721 glyph->pixel_width = it->pixel_width;
17722 glyph->ascent = glyph_ascent;
17723 glyph->descent = it->descent;
17724 glyph->voffset = it->voffset;
17725 glyph->type = IMAGE_GLYPH;
17726 glyph->multibyte_p = it->multibyte_p;
17727 glyph->left_box_line_p = it->start_of_box_run_p;
17728 glyph->right_box_line_p = it->end_of_box_run_p;
17729 glyph->overlaps_vertically_p = 0;
17730 glyph->padding_p = 0;
17731 glyph->glyph_not_available_p = 0;
17732 glyph->face_id = it->face_id;
17733 glyph->u.img_id = img->id;
17734 glyph->font_type = FONT_TYPE_UNKNOWN;
17735 ++it->glyph_row->used[area];
17741 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
17742 of the glyph, WIDTH and HEIGHT are the width and height of the
17743 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
17745 static void
17746 append_stretch_glyph (it, object, width, height, ascent)
17747 struct it *it;
17748 Lisp_Object object;
17749 int width, height;
17750 int ascent;
17752 struct glyph *glyph;
17753 enum glyph_row_area area = it->area;
17755 xassert (ascent >= 0 && ascent <= height);
17757 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
17758 if (glyph < it->glyph_row->glyphs[area + 1])
17760 glyph->charpos = CHARPOS (it->position);
17761 glyph->object = object;
17762 glyph->pixel_width = width;
17763 glyph->ascent = ascent;
17764 glyph->descent = height - ascent;
17765 glyph->voffset = it->voffset;
17766 glyph->type = STRETCH_GLYPH;
17767 glyph->multibyte_p = it->multibyte_p;
17768 glyph->left_box_line_p = it->start_of_box_run_p;
17769 glyph->right_box_line_p = it->end_of_box_run_p;
17770 glyph->overlaps_vertically_p = 0;
17771 glyph->padding_p = 0;
17772 glyph->glyph_not_available_p = 0;
17773 glyph->face_id = it->face_id;
17774 glyph->u.stretch.ascent = ascent;
17775 glyph->u.stretch.height = height;
17776 glyph->font_type = FONT_TYPE_UNKNOWN;
17777 ++it->glyph_row->used[area];
17782 /* Calculate a width or height in pixels from a specification using
17783 the following elements:
17785 SPEC ::=
17786 NUM - a (fractional) multiple of the default font width/height
17787 (NUM) - specifies exactly NUM pixels
17788 UNIT - a fixed number of pixels, see below.
17789 ELEMENT - size of a display element in pixels, see below.
17790 (NUM . SPEC) - equals NUM * SPEC
17791 (+ SPEC SPEC ...) - add pixel values
17792 (- SPEC SPEC ...) - subtract pixel values
17793 (- SPEC) - negate pixel value
17795 NUM ::=
17796 INT or FLOAT - a number constant
17797 SYMBOL - use symbol's (buffer local) variable binding.
17799 UNIT ::=
17800 in - pixels per inch *)
17801 mm - pixels per 1/1000 meter *)
17802 cm - pixels per 1/100 meter *)
17803 width - width of current font in pixels.
17804 height - height of current font in pixels.
17806 *) using the ratio(s) defined in display-pixels-per-inch.
17808 ELEMENT ::=
17810 left-fringe - left fringe width in pixels
17811 (left-fringe . nil) - left fringe width if inside margins, else 0
17812 (left-fringe . t) - left fringe width if outside margins, else 0
17814 right-fringe - right fringe width in pixels
17815 (right-fringe . nil) - right fringe width if inside margins, else 0
17816 (right-fringe . t) - right fringe width if outside margins, else 0
17818 left-margin - left margin width in pixels
17819 right-margin - right margin width in pixels
17821 scroll-bar - scroll-bar area width in pixels
17822 (scroll-bar . left) - scroll-bar width if on left, else 0
17823 (scroll-bar . right) - scroll-bar width if on right, else 0
17825 Examples:
17827 Pixels corresponding to 5 inches:
17828 (5 . in)
17830 Total width of non-text areas on left side of window:
17831 (+ left-fringe left-margin (scroll-bar . left))
17833 Total width of fringes if inside display margins:
17834 (+ (left-fringe) (right-fringe))
17836 Width of left margin minus width of 1 character in the default font:
17837 (- left-margin 1)
17839 Width of left margin minus width of 2 characters in the current font:
17840 (- left-margin (2 . width))
17842 Width of left fringe plus left margin minus one pixel:
17843 (- (+ left-fringe left-margin) (1))
17844 (+ left-fringe left-margin (- (1)))
17845 (+ left-fringe left-margin (-1))
17849 #define NUMVAL(X) \
17850 ((INTEGERP (X) || FLOATP (X)) \
17851 ? XFLOATINT (X) \
17852 : - 1)
17854 static int
17855 calc_pixel_width_or_height (res, it, prop, font, width_p)
17856 double *res;
17857 struct it *it;
17858 Lisp_Object prop;
17859 XFontStruct *font;
17860 int width_p;
17862 double pixels;
17864 #define OK_PIXELS(val) ((*res = (val)), 1)
17866 if (SYMBOLP (prop))
17868 if (SCHARS (SYMBOL_NAME (prop)) == 2)
17870 char *unit = SDATA (SYMBOL_NAME (prop));
17872 if (unit[0] == 'i' && unit[1] == 'n')
17873 pixels = 1.0;
17874 else if (unit[0] == 'm' && unit[1] == 'm')
17875 pixels = 25.4;
17876 else if (unit[0] == 'c' && unit[1] == 'm')
17877 pixels = 2.54;
17878 else
17879 pixels = 0;
17880 if (pixels > 0)
17882 double ppi;
17883 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
17884 || (CONSP (Vdisplay_pixels_per_inch)
17885 && (ppi = (width_p
17886 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
17887 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
17888 ppi > 0)))
17889 return OK_PIXELS (ppi / pixels);
17891 return 0;
17895 if (EQ (prop, Qheight))
17896 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
17897 if (EQ (prop, Qwidth))
17898 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
17899 if (EQ (prop, Qleft_fringe))
17900 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
17901 if (EQ (prop, Qright_fringe))
17902 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
17903 if (EQ (prop, Qleft_margin))
17904 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
17905 if (EQ (prop, Qright_margin))
17906 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
17907 if (EQ (prop, Qscroll_bar))
17908 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
17910 prop = Fbuffer_local_value (prop, it->w->buffer);
17913 if (INTEGERP (prop) || FLOATP (prop))
17915 int base_unit = (width_p
17916 ? FRAME_COLUMN_WIDTH (it->f)
17917 : FRAME_LINE_HEIGHT (it->f));
17918 return OK_PIXELS (XFLOATINT (prop) * base_unit);
17921 if (CONSP (prop))
17923 Lisp_Object car = XCAR (prop);
17924 Lisp_Object cdr = XCDR (prop);
17926 if (SYMBOLP (car))
17928 if (EQ (car, Qplus) || EQ (car, Qminus))
17930 int first = 1;
17931 double px;
17933 pixels = 0;
17934 while (CONSP (cdr))
17936 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr), font, width_p))
17937 return 0;
17938 if (first)
17939 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
17940 else
17941 pixels += px;
17942 cdr = XCDR (cdr);
17944 if (EQ (car, Qminus))
17945 pixels = -pixels;
17946 return OK_PIXELS (pixels);
17949 if (EQ (car, Qleft_fringe))
17950 return OK_PIXELS ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17951 == !NILP (cdr))
17952 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
17953 : 0);
17954 if (EQ (car, Qright_fringe))
17955 return OK_PIXELS ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17956 == !NILP (cdr))
17957 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
17958 : 0);
17959 if (EQ (car, Qscroll_bar))
17960 return OK_PIXELS ((WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
17961 == EQ (cdr, Qleft))
17962 ? WINDOW_SCROLL_BAR_AREA_WIDTH (it->w)
17963 : 0);
17965 car = Fbuffer_local_value (car, it->w->buffer);
17968 if (INTEGERP (car) || FLOATP (car))
17970 double fact;
17971 pixels = XFLOATINT (car);
17972 if (NILP (cdr))
17973 return OK_PIXELS (pixels);
17974 if (calc_pixel_width_or_height (&fact, it, cdr, font, width_p))
17975 return OK_PIXELS (pixels * fact);
17976 return 0;
17979 return 0;
17982 return 0;
17985 /* Produce a stretch glyph for iterator IT. IT->object is the value
17986 of the glyph property displayed. The value must be a list
17987 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
17988 being recognized:
17990 1. `:width WIDTH' specifies that the space should be WIDTH *
17991 canonical char width wide. WIDTH may be an integer or floating
17992 point number.
17994 2. `:relative-width FACTOR' specifies that the width of the stretch
17995 should be computed from the width of the first character having the
17996 `glyph' property, and should be FACTOR times that width.
17998 3. `:align-to HPOS' specifies that the space should be wide enough
17999 to reach HPOS, a value in canonical character units.
18001 Exactly one of the above pairs must be present.
18003 4. `:height HEIGHT' specifies that the height of the stretch produced
18004 should be HEIGHT, measured in canonical character units.
18006 5. `:relative-height FACTOR' specifies that the height of the
18007 stretch should be FACTOR times the height of the characters having
18008 the glyph property.
18010 Either none or exactly one of 4 or 5 must be present.
18012 6. `:ascent ASCENT' specifies that ASCENT percent of the height
18013 of the stretch should be used for the ascent of the stretch.
18014 ASCENT must be in the range 0 <= ASCENT <= 100. */
18016 static void
18017 produce_stretch_glyph (it)
18018 struct it *it;
18020 /* (space :width WIDTH :height HEIGHT ...) */
18021 Lisp_Object prop, plist;
18022 int width = 0, height = 0;
18023 int zero_width_ok_p = 0, zero_height_ok_p = 0;
18024 int ascent = 0;
18025 double tem;
18026 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18027 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
18029 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18031 /* List should start with `space'. */
18032 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
18033 plist = XCDR (it->object);
18035 /* Compute the width of the stretch. */
18036 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
18037 && calc_pixel_width_or_height (&tem, it, prop, font, 1))
18039 /* Absolute width `:width WIDTH' specified and valid. */
18040 zero_width_ok_p = 1;
18041 width = (int)tem;
18043 else if (prop = Fplist_get (plist, QCrelative_width),
18044 NUMVAL (prop) > 0)
18046 /* Relative width `:relative-width FACTOR' specified and valid.
18047 Compute the width of the characters having the `glyph'
18048 property. */
18049 struct it it2;
18050 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
18052 it2 = *it;
18053 if (it->multibyte_p)
18055 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
18056 - IT_BYTEPOS (*it));
18057 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
18059 else
18060 it2.c = *p, it2.len = 1;
18062 it2.glyph_row = NULL;
18063 it2.what = IT_CHARACTER;
18064 x_produce_glyphs (&it2);
18065 width = NUMVAL (prop) * it2.pixel_width;
18067 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
18068 && calc_pixel_width_or_height (&tem, it, prop, font, 1))
18070 width = max (0, (int)tem - it->current_x);
18071 zero_width_ok_p = 1;
18073 else
18074 /* Nothing specified -> width defaults to canonical char width. */
18075 width = FRAME_COLUMN_WIDTH (it->f);
18077 if (width <= 0 && (width < 0 || !zero_width_ok_p))
18078 width = 1;
18080 /* Compute height. */
18081 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
18082 && calc_pixel_width_or_height (&tem, it, prop, font, 0))
18084 height = (int)tem;
18085 zero_height_ok_p = 1;
18087 else if (prop = Fplist_get (plist, QCrelative_height),
18088 NUMVAL (prop) > 0)
18089 height = FONT_HEIGHT (font) * NUMVAL (prop);
18090 else
18091 height = FONT_HEIGHT (font);
18093 if (height <= 0 && (height < 0 || !zero_height_ok_p))
18094 height = 1;
18096 /* Compute percentage of height used for ascent. If
18097 `:ascent ASCENT' is present and valid, use that. Otherwise,
18098 derive the ascent from the font in use. */
18099 if (prop = Fplist_get (plist, QCascent),
18100 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
18101 ascent = height * NUMVAL (prop) / 100.0;
18102 else if (!NILP (prop)
18103 && calc_pixel_width_or_height (&tem, it, prop, font, 0))
18104 ascent = min (max (0, (int)tem), height);
18105 else
18106 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
18108 if (width > 0 && height > 0 && it->glyph_row)
18110 Lisp_Object object = it->stack[it->sp - 1].string;
18111 if (!STRINGP (object))
18112 object = it->w->buffer;
18113 append_stretch_glyph (it, object, width, height, ascent);
18116 it->pixel_width = width;
18117 it->ascent = it->phys_ascent = ascent;
18118 it->descent = it->phys_descent = height - it->ascent;
18119 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
18121 if (width > 0 && height > 0 && face->box != FACE_NO_BOX)
18123 if (face->box_line_width > 0)
18125 it->ascent += face->box_line_width;
18126 it->descent += face->box_line_width;
18129 if (it->start_of_box_run_p)
18130 it->pixel_width += abs (face->box_line_width);
18131 if (it->end_of_box_run_p)
18132 it->pixel_width += abs (face->box_line_width);
18135 take_vertical_position_into_account (it);
18138 /* RIF:
18139 Produce glyphs/get display metrics for the display element IT is
18140 loaded with. See the description of struct display_iterator in
18141 dispextern.h for an overview of struct display_iterator. */
18143 void
18144 x_produce_glyphs (it)
18145 struct it *it;
18147 it->glyph_not_available_p = 0;
18149 if (it->what == IT_CHARACTER)
18151 XChar2b char2b;
18152 XFontStruct *font;
18153 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18154 XCharStruct *pcm;
18155 int font_not_found_p;
18156 struct font_info *font_info;
18157 int boff; /* baseline offset */
18158 /* We may change it->multibyte_p upon unibyte<->multibyte
18159 conversion. So, save the current value now and restore it
18160 later.
18162 Note: It seems that we don't have to record multibyte_p in
18163 struct glyph because the character code itself tells if or
18164 not the character is multibyte. Thus, in the future, we must
18165 consider eliminating the field `multibyte_p' in the struct
18166 glyph. */
18167 int saved_multibyte_p = it->multibyte_p;
18169 /* Maybe translate single-byte characters to multibyte, or the
18170 other way. */
18171 it->char_to_display = it->c;
18172 if (!ASCII_BYTE_P (it->c))
18174 if (unibyte_display_via_language_environment
18175 && SINGLE_BYTE_CHAR_P (it->c)
18176 && (it->c >= 0240
18177 || !NILP (Vnonascii_translation_table)))
18179 it->char_to_display = unibyte_char_to_multibyte (it->c);
18180 it->multibyte_p = 1;
18181 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18182 face = FACE_FROM_ID (it->f, it->face_id);
18184 else if (!SINGLE_BYTE_CHAR_P (it->c)
18185 && !it->multibyte_p)
18187 it->multibyte_p = 1;
18188 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18189 face = FACE_FROM_ID (it->f, it->face_id);
18193 /* Get font to use. Encode IT->char_to_display. */
18194 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
18195 &char2b, it->multibyte_p, 0);
18196 font = face->font;
18198 /* When no suitable font found, use the default font. */
18199 font_not_found_p = font == NULL;
18200 if (font_not_found_p)
18202 font = FRAME_FONT (it->f);
18203 boff = FRAME_BASELINE_OFFSET (it->f);
18204 font_info = NULL;
18206 else
18208 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18209 boff = font_info->baseline_offset;
18210 if (font_info->vertical_centering)
18211 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18214 if (it->char_to_display >= ' '
18215 && (!it->multibyte_p || it->char_to_display < 128))
18217 /* Either unibyte or ASCII. */
18218 int stretched_p;
18220 it->nglyphs = 1;
18222 pcm = rif->per_char_metric (font, &char2b,
18223 FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
18224 it->ascent = FONT_BASE (font) + boff;
18225 it->descent = FONT_DESCENT (font) - boff;
18227 if (pcm)
18229 it->phys_ascent = pcm->ascent + boff;
18230 it->phys_descent = pcm->descent - boff;
18231 it->pixel_width = pcm->width;
18233 else
18235 it->glyph_not_available_p = 1;
18236 it->phys_ascent = FONT_BASE (font) + boff;
18237 it->phys_descent = FONT_DESCENT (font) - boff;
18238 it->pixel_width = FONT_WIDTH (font);
18241 /* If this is a space inside a region of text with
18242 `space-width' property, change its width. */
18243 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
18244 if (stretched_p)
18245 it->pixel_width *= XFLOATINT (it->space_width);
18247 /* If face has a box, add the box thickness to the character
18248 height. If character has a box line to the left and/or
18249 right, add the box line width to the character's width. */
18250 if (face->box != FACE_NO_BOX)
18252 int thick = face->box_line_width;
18254 if (thick > 0)
18256 it->ascent += thick;
18257 it->descent += thick;
18259 else
18260 thick = -thick;
18262 if (it->start_of_box_run_p)
18263 it->pixel_width += thick;
18264 if (it->end_of_box_run_p)
18265 it->pixel_width += thick;
18268 /* If face has an overline, add the height of the overline
18269 (1 pixel) and a 1 pixel margin to the character height. */
18270 if (face->overline_p)
18271 it->ascent += 2;
18273 take_vertical_position_into_account (it);
18275 /* If we have to actually produce glyphs, do it. */
18276 if (it->glyph_row)
18278 if (stretched_p)
18280 /* Translate a space with a `space-width' property
18281 into a stretch glyph. */
18282 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
18283 / FONT_HEIGHT (font));
18284 append_stretch_glyph (it, it->object, it->pixel_width,
18285 it->ascent + it->descent, ascent);
18287 else
18288 append_glyph (it);
18290 /* If characters with lbearing or rbearing are displayed
18291 in this line, record that fact in a flag of the
18292 glyph row. This is used to optimize X output code. */
18293 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
18294 it->glyph_row->contains_overlapping_glyphs_p = 1;
18297 else if (it->char_to_display == '\n')
18299 /* A newline has no width but we need the height of the line. */
18300 it->pixel_width = 0;
18301 it->nglyphs = 0;
18302 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
18303 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
18305 if (face->box != FACE_NO_BOX
18306 && face->box_line_width > 0)
18308 it->ascent += face->box_line_width;
18309 it->descent += face->box_line_width;
18312 else if (it->char_to_display == '\t')
18314 int tab_width = it->tab_width * FRAME_COLUMN_WIDTH (it->f);
18315 int x = it->current_x + it->continuation_lines_width;
18316 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
18318 /* If the distance from the current position to the next tab
18319 stop is less than a canonical character width, use the
18320 tab stop after that. */
18321 if (next_tab_x - x < FRAME_COLUMN_WIDTH (it->f))
18322 next_tab_x += tab_width;
18324 it->pixel_width = next_tab_x - x;
18325 it->nglyphs = 1;
18326 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
18327 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
18329 if (it->glyph_row)
18331 append_stretch_glyph (it, it->object, it->pixel_width,
18332 it->ascent + it->descent, it->ascent);
18335 else
18337 /* A multi-byte character. Assume that the display width of the
18338 character is the width of the character multiplied by the
18339 width of the font. */
18341 /* If we found a font, this font should give us the right
18342 metrics. If we didn't find a font, use the frame's
18343 default font and calculate the width of the character
18344 from the charset width; this is what old redisplay code
18345 did. */
18347 pcm = rif->per_char_metric (font, &char2b,
18348 FONT_TYPE_FOR_MULTIBYTE (font, it->c));
18350 if (font_not_found_p || !pcm)
18352 int charset = CHAR_CHARSET (it->char_to_display);
18354 it->glyph_not_available_p = 1;
18355 it->pixel_width = (FRAME_COLUMN_WIDTH (it->f)
18356 * CHARSET_WIDTH (charset));
18357 it->phys_ascent = FONT_BASE (font) + boff;
18358 it->phys_descent = FONT_DESCENT (font) - boff;
18360 else
18362 it->pixel_width = pcm->width;
18363 it->phys_ascent = pcm->ascent + boff;
18364 it->phys_descent = pcm->descent - boff;
18365 if (it->glyph_row
18366 && (pcm->lbearing < 0
18367 || pcm->rbearing > pcm->width))
18368 it->glyph_row->contains_overlapping_glyphs_p = 1;
18370 it->nglyphs = 1;
18371 it->ascent = FONT_BASE (font) + boff;
18372 it->descent = FONT_DESCENT (font) - boff;
18373 if (face->box != FACE_NO_BOX)
18375 int thick = face->box_line_width;
18377 if (thick > 0)
18379 it->ascent += thick;
18380 it->descent += thick;
18382 else
18383 thick = - thick;
18385 if (it->start_of_box_run_p)
18386 it->pixel_width += thick;
18387 if (it->end_of_box_run_p)
18388 it->pixel_width += thick;
18391 /* If face has an overline, add the height of the overline
18392 (1 pixel) and a 1 pixel margin to the character height. */
18393 if (face->overline_p)
18394 it->ascent += 2;
18396 take_vertical_position_into_account (it);
18398 if (it->glyph_row)
18399 append_glyph (it);
18401 it->multibyte_p = saved_multibyte_p;
18403 else if (it->what == IT_COMPOSITION)
18405 /* Note: A composition is represented as one glyph in the
18406 glyph matrix. There are no padding glyphs. */
18407 XChar2b char2b;
18408 XFontStruct *font;
18409 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18410 XCharStruct *pcm;
18411 int font_not_found_p;
18412 struct font_info *font_info;
18413 int boff; /* baseline offset */
18414 struct composition *cmp = composition_table[it->cmp_id];
18416 /* Maybe translate single-byte characters to multibyte. */
18417 it->char_to_display = it->c;
18418 if (unibyte_display_via_language_environment
18419 && SINGLE_BYTE_CHAR_P (it->c)
18420 && (it->c >= 0240
18421 || (it->c >= 0200
18422 && !NILP (Vnonascii_translation_table))))
18424 it->char_to_display = unibyte_char_to_multibyte (it->c);
18427 /* Get face and font to use. Encode IT->char_to_display. */
18428 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18429 face = FACE_FROM_ID (it->f, it->face_id);
18430 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
18431 &char2b, it->multibyte_p, 0);
18432 font = face->font;
18434 /* When no suitable font found, use the default font. */
18435 font_not_found_p = font == NULL;
18436 if (font_not_found_p)
18438 font = FRAME_FONT (it->f);
18439 boff = FRAME_BASELINE_OFFSET (it->f);
18440 font_info = NULL;
18442 else
18444 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18445 boff = font_info->baseline_offset;
18446 if (font_info->vertical_centering)
18447 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18450 /* There are no padding glyphs, so there is only one glyph to
18451 produce for the composition. Important is that pixel_width,
18452 ascent and descent are the values of what is drawn by
18453 draw_glyphs (i.e. the values of the overall glyphs composed). */
18454 it->nglyphs = 1;
18456 /* If we have not yet calculated pixel size data of glyphs of
18457 the composition for the current face font, calculate them
18458 now. Theoretically, we have to check all fonts for the
18459 glyphs, but that requires much time and memory space. So,
18460 here we check only the font of the first glyph. This leads
18461 to incorrect display very rarely, and C-l (recenter) can
18462 correct the display anyway. */
18463 if (cmp->font != (void *) font)
18465 /* Ascent and descent of the font of the first character of
18466 this composition (adjusted by baseline offset). Ascent
18467 and descent of overall glyphs should not be less than
18468 them respectively. */
18469 int font_ascent = FONT_BASE (font) + boff;
18470 int font_descent = FONT_DESCENT (font) - boff;
18471 /* Bounding box of the overall glyphs. */
18472 int leftmost, rightmost, lowest, highest;
18473 int i, width, ascent, descent;
18475 cmp->font = (void *) font;
18477 /* Initialize the bounding box. */
18478 if (font_info
18479 && (pcm = rif->per_char_metric (font, &char2b,
18480 FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
18482 width = pcm->width;
18483 ascent = pcm->ascent;
18484 descent = pcm->descent;
18486 else
18488 width = FONT_WIDTH (font);
18489 ascent = FONT_BASE (font);
18490 descent = FONT_DESCENT (font);
18493 rightmost = width;
18494 lowest = - descent + boff;
18495 highest = ascent + boff;
18496 leftmost = 0;
18498 if (font_info
18499 && font_info->default_ascent
18500 && CHAR_TABLE_P (Vuse_default_ascent)
18501 && !NILP (Faref (Vuse_default_ascent,
18502 make_number (it->char_to_display))))
18503 highest = font_info->default_ascent + boff;
18505 /* Draw the first glyph at the normal position. It may be
18506 shifted to right later if some other glyphs are drawn at
18507 the left. */
18508 cmp->offsets[0] = 0;
18509 cmp->offsets[1] = boff;
18511 /* Set cmp->offsets for the remaining glyphs. */
18512 for (i = 1; i < cmp->glyph_len; i++)
18514 int left, right, btm, top;
18515 int ch = COMPOSITION_GLYPH (cmp, i);
18516 int face_id = FACE_FOR_CHAR (it->f, face, ch);
18518 face = FACE_FROM_ID (it->f, face_id);
18519 get_char_face_and_encoding (it->f, ch, face->id,
18520 &char2b, it->multibyte_p, 0);
18521 font = face->font;
18522 if (font == NULL)
18524 font = FRAME_FONT (it->f);
18525 boff = FRAME_BASELINE_OFFSET (it->f);
18526 font_info = NULL;
18528 else
18530 font_info
18531 = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18532 boff = font_info->baseline_offset;
18533 if (font_info->vertical_centering)
18534 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18537 if (font_info
18538 && (pcm = rif->per_char_metric (font, &char2b,
18539 FONT_TYPE_FOR_MULTIBYTE (font, ch))))
18541 width = pcm->width;
18542 ascent = pcm->ascent;
18543 descent = pcm->descent;
18545 else
18547 width = FONT_WIDTH (font);
18548 ascent = 1;
18549 descent = 0;
18552 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
18554 /* Relative composition with or without
18555 alternate chars. */
18556 left = (leftmost + rightmost - width) / 2;
18557 btm = - descent + boff;
18558 if (font_info && font_info->relative_compose
18559 && (! CHAR_TABLE_P (Vignore_relative_composition)
18560 || NILP (Faref (Vignore_relative_composition,
18561 make_number (ch)))))
18564 if (- descent >= font_info->relative_compose)
18565 /* One extra pixel between two glyphs. */
18566 btm = highest + 1;
18567 else if (ascent <= 0)
18568 /* One extra pixel between two glyphs. */
18569 btm = lowest - 1 - ascent - descent;
18572 else
18574 /* A composition rule is specified by an integer
18575 value that encodes global and new reference
18576 points (GREF and NREF). GREF and NREF are
18577 specified by numbers as below:
18579 0---1---2 -- ascent
18583 9--10--11 -- center
18585 ---3---4---5--- baseline
18587 6---7---8 -- descent
18589 int rule = COMPOSITION_RULE (cmp, i);
18590 int gref, nref, grefx, grefy, nrefx, nrefy;
18592 COMPOSITION_DECODE_RULE (rule, gref, nref);
18593 grefx = gref % 3, nrefx = nref % 3;
18594 grefy = gref / 3, nrefy = nref / 3;
18596 left = (leftmost
18597 + grefx * (rightmost - leftmost) / 2
18598 - nrefx * width / 2);
18599 btm = ((grefy == 0 ? highest
18600 : grefy == 1 ? 0
18601 : grefy == 2 ? lowest
18602 : (highest + lowest) / 2)
18603 - (nrefy == 0 ? ascent + descent
18604 : nrefy == 1 ? descent - boff
18605 : nrefy == 2 ? 0
18606 : (ascent + descent) / 2));
18609 cmp->offsets[i * 2] = left;
18610 cmp->offsets[i * 2 + 1] = btm + descent;
18612 /* Update the bounding box of the overall glyphs. */
18613 right = left + width;
18614 top = btm + descent + ascent;
18615 if (left < leftmost)
18616 leftmost = left;
18617 if (right > rightmost)
18618 rightmost = right;
18619 if (top > highest)
18620 highest = top;
18621 if (btm < lowest)
18622 lowest = btm;
18625 /* If there are glyphs whose x-offsets are negative,
18626 shift all glyphs to the right and make all x-offsets
18627 non-negative. */
18628 if (leftmost < 0)
18630 for (i = 0; i < cmp->glyph_len; i++)
18631 cmp->offsets[i * 2] -= leftmost;
18632 rightmost -= leftmost;
18635 cmp->pixel_width = rightmost;
18636 cmp->ascent = highest;
18637 cmp->descent = - lowest;
18638 if (cmp->ascent < font_ascent)
18639 cmp->ascent = font_ascent;
18640 if (cmp->descent < font_descent)
18641 cmp->descent = font_descent;
18644 it->pixel_width = cmp->pixel_width;
18645 it->ascent = it->phys_ascent = cmp->ascent;
18646 it->descent = it->phys_descent = cmp->descent;
18648 if (face->box != FACE_NO_BOX)
18650 int thick = face->box_line_width;
18652 if (thick > 0)
18654 it->ascent += thick;
18655 it->descent += thick;
18657 else
18658 thick = - thick;
18660 if (it->start_of_box_run_p)
18661 it->pixel_width += thick;
18662 if (it->end_of_box_run_p)
18663 it->pixel_width += thick;
18666 /* If face has an overline, add the height of the overline
18667 (1 pixel) and a 1 pixel margin to the character height. */
18668 if (face->overline_p)
18669 it->ascent += 2;
18671 take_vertical_position_into_account (it);
18673 if (it->glyph_row)
18674 append_composite_glyph (it);
18676 else if (it->what == IT_IMAGE)
18677 produce_image_glyph (it);
18678 else if (it->what == IT_STRETCH)
18679 produce_stretch_glyph (it);
18681 /* Accumulate dimensions. Note: can't assume that it->descent > 0
18682 because this isn't true for images with `:ascent 100'. */
18683 xassert (it->ascent >= 0 && it->descent >= 0);
18684 if (it->area == TEXT_AREA)
18685 it->current_x += it->pixel_width;
18687 it->descent += it->extra_line_spacing;
18689 it->max_ascent = max (it->max_ascent, it->ascent);
18690 it->max_descent = max (it->max_descent, it->descent);
18691 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
18692 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
18695 /* EXPORT for RIF:
18696 Output LEN glyphs starting at START at the nominal cursor position.
18697 Advance the nominal cursor over the text. The global variable
18698 updated_window contains the window being updated, updated_row is
18699 the glyph row being updated, and updated_area is the area of that
18700 row being updated. */
18702 void
18703 x_write_glyphs (start, len)
18704 struct glyph *start;
18705 int len;
18707 int x, hpos;
18709 xassert (updated_window && updated_row);
18710 BLOCK_INPUT;
18712 /* Write glyphs. */
18714 hpos = start - updated_row->glyphs[updated_area];
18715 x = draw_glyphs (updated_window, output_cursor.x,
18716 updated_row, updated_area,
18717 hpos, hpos + len,
18718 DRAW_NORMAL_TEXT, 0);
18720 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
18721 if (updated_area == TEXT_AREA
18722 && updated_window->phys_cursor_on_p
18723 && updated_window->phys_cursor.vpos == output_cursor.vpos
18724 && updated_window->phys_cursor.hpos >= hpos
18725 && updated_window->phys_cursor.hpos < hpos + len)
18726 updated_window->phys_cursor_on_p = 0;
18728 UNBLOCK_INPUT;
18730 /* Advance the output cursor. */
18731 output_cursor.hpos += len;
18732 output_cursor.x = x;
18736 /* EXPORT for RIF:
18737 Insert LEN glyphs from START at the nominal cursor position. */
18739 void
18740 x_insert_glyphs (start, len)
18741 struct glyph *start;
18742 int len;
18744 struct frame *f;
18745 struct window *w;
18746 int line_height, shift_by_width, shifted_region_width;
18747 struct glyph_row *row;
18748 struct glyph *glyph;
18749 int frame_x, frame_y, hpos;
18751 xassert (updated_window && updated_row);
18752 BLOCK_INPUT;
18753 w = updated_window;
18754 f = XFRAME (WINDOW_FRAME (w));
18756 /* Get the height of the line we are in. */
18757 row = updated_row;
18758 line_height = row->height;
18760 /* Get the width of the glyphs to insert. */
18761 shift_by_width = 0;
18762 for (glyph = start; glyph < start + len; ++glyph)
18763 shift_by_width += glyph->pixel_width;
18765 /* Get the width of the region to shift right. */
18766 shifted_region_width = (window_box_width (w, updated_area)
18767 - output_cursor.x
18768 - shift_by_width);
18770 /* Shift right. */
18771 frame_x = window_box_left (w, updated_area) + output_cursor.x;
18772 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
18774 rif->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
18775 line_height, shift_by_width);
18777 /* Write the glyphs. */
18778 hpos = start - row->glyphs[updated_area];
18779 draw_glyphs (w, output_cursor.x, row, updated_area,
18780 hpos, hpos + len,
18781 DRAW_NORMAL_TEXT, 0);
18783 /* Advance the output cursor. */
18784 output_cursor.hpos += len;
18785 output_cursor.x += shift_by_width;
18786 UNBLOCK_INPUT;
18790 /* EXPORT for RIF:
18791 Erase the current text line from the nominal cursor position
18792 (inclusive) to pixel column TO_X (exclusive). The idea is that
18793 everything from TO_X onward is already erased.
18795 TO_X is a pixel position relative to updated_area of
18796 updated_window. TO_X == -1 means clear to the end of this area. */
18798 void
18799 x_clear_end_of_line (to_x)
18800 int to_x;
18802 struct frame *f;
18803 struct window *w = updated_window;
18804 int max_x, min_y, max_y;
18805 int from_x, from_y, to_y;
18807 xassert (updated_window && updated_row);
18808 f = XFRAME (w->frame);
18810 if (updated_row->full_width_p)
18811 max_x = WINDOW_TOTAL_WIDTH (w);
18812 else
18813 max_x = window_box_width (w, updated_area);
18814 max_y = window_text_bottom_y (w);
18816 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
18817 of window. For TO_X > 0, truncate to end of drawing area. */
18818 if (to_x == 0)
18819 return;
18820 else if (to_x < 0)
18821 to_x = max_x;
18822 else
18823 to_x = min (to_x, max_x);
18825 to_y = min (max_y, output_cursor.y + updated_row->height);
18827 /* Notice if the cursor will be cleared by this operation. */
18828 if (!updated_row->full_width_p)
18829 notice_overwritten_cursor (w, updated_area,
18830 output_cursor.x, -1,
18831 updated_row->y,
18832 MATRIX_ROW_BOTTOM_Y (updated_row));
18834 from_x = output_cursor.x;
18836 /* Translate to frame coordinates. */
18837 if (updated_row->full_width_p)
18839 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
18840 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
18842 else
18844 int area_left = window_box_left (w, updated_area);
18845 from_x += area_left;
18846 to_x += area_left;
18849 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
18850 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
18851 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
18853 /* Prevent inadvertently clearing to end of the X window. */
18854 if (to_x > from_x && to_y > from_y)
18856 BLOCK_INPUT;
18857 rif->clear_frame_area (f, from_x, from_y,
18858 to_x - from_x, to_y - from_y);
18859 UNBLOCK_INPUT;
18863 #endif /* HAVE_WINDOW_SYSTEM */
18867 /***********************************************************************
18868 Cursor types
18869 ***********************************************************************/
18871 /* Value is the internal representation of the specified cursor type
18872 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
18873 of the bar cursor. */
18875 static enum text_cursor_kinds
18876 get_specified_cursor_type (arg, width)
18877 Lisp_Object arg;
18878 int *width;
18880 enum text_cursor_kinds type;
18882 if (NILP (arg))
18883 return NO_CURSOR;
18885 if (EQ (arg, Qbox))
18886 return FILLED_BOX_CURSOR;
18888 if (EQ (arg, Qhollow))
18889 return HOLLOW_BOX_CURSOR;
18891 if (EQ (arg, Qbar))
18893 *width = 2;
18894 return BAR_CURSOR;
18897 if (CONSP (arg)
18898 && EQ (XCAR (arg), Qbar)
18899 && INTEGERP (XCDR (arg))
18900 && XINT (XCDR (arg)) >= 0)
18902 *width = XINT (XCDR (arg));
18903 return BAR_CURSOR;
18906 if (EQ (arg, Qhbar))
18908 *width = 2;
18909 return HBAR_CURSOR;
18912 if (CONSP (arg)
18913 && EQ (XCAR (arg), Qhbar)
18914 && INTEGERP (XCDR (arg))
18915 && XINT (XCDR (arg)) >= 0)
18917 *width = XINT (XCDR (arg));
18918 return HBAR_CURSOR;
18921 /* Treat anything unknown as "hollow box cursor".
18922 It was bad to signal an error; people have trouble fixing
18923 .Xdefaults with Emacs, when it has something bad in it. */
18924 type = HOLLOW_BOX_CURSOR;
18926 return type;
18929 /* Set the default cursor types for specified frame. */
18930 void
18931 set_frame_cursor_types (f, arg)
18932 struct frame *f;
18933 Lisp_Object arg;
18935 int width;
18936 Lisp_Object tem;
18938 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
18939 FRAME_CURSOR_WIDTH (f) = width;
18941 /* By default, set up the blink-off state depending on the on-state. */
18943 tem = Fassoc (arg, Vblink_cursor_alist);
18944 if (!NILP (tem))
18946 FRAME_BLINK_OFF_CURSOR (f)
18947 = get_specified_cursor_type (XCDR (tem), &width);
18948 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
18950 else
18951 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
18955 /* Return the cursor we want to be displayed in window W. Return
18956 width of bar/hbar cursor through WIDTH arg. Return with
18957 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
18958 (i.e. if the `system caret' should track this cursor).
18960 In a mini-buffer window, we want the cursor only to appear if we
18961 are reading input from this window. For the selected window, we
18962 want the cursor type given by the frame parameter or buffer local
18963 setting of cursor-type. If explicitly marked off, draw no cursor.
18964 In all other cases, we want a hollow box cursor. */
18966 static enum text_cursor_kinds
18967 get_window_cursor_type (w, glyph, width, active_cursor)
18968 struct window *w;
18969 struct glyph *glyph;
18970 int *width;
18971 int *active_cursor;
18973 struct frame *f = XFRAME (w->frame);
18974 struct buffer *b = XBUFFER (w->buffer);
18975 int cursor_type = DEFAULT_CURSOR;
18976 Lisp_Object alt_cursor;
18977 int non_selected = 0;
18979 *active_cursor = 1;
18981 /* Echo area */
18982 if (cursor_in_echo_area
18983 && FRAME_HAS_MINIBUF_P (f)
18984 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
18986 if (w == XWINDOW (echo_area_window))
18988 *width = FRAME_CURSOR_WIDTH (f);
18989 return FRAME_DESIRED_CURSOR (f);
18992 *active_cursor = 0;
18993 non_selected = 1;
18996 /* Nonselected window or nonselected frame. */
18997 else if (w != XWINDOW (f->selected_window)
18998 #ifdef HAVE_WINDOW_SYSTEM
18999 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
19000 #endif
19003 *active_cursor = 0;
19005 if (MINI_WINDOW_P (w) && minibuf_level == 0)
19006 return NO_CURSOR;
19008 non_selected = 1;
19011 /* Never display a cursor in a window in which cursor-type is nil. */
19012 if (NILP (b->cursor_type))
19013 return NO_CURSOR;
19015 /* Use cursor-in-non-selected-windows for non-selected window or frame. */
19016 if (non_selected)
19018 alt_cursor = Fbuffer_local_value (Qcursor_in_non_selected_windows, w->buffer);
19019 return get_specified_cursor_type (alt_cursor, width);
19022 /* Get the normal cursor type for this window. */
19023 if (EQ (b->cursor_type, Qt))
19025 cursor_type = FRAME_DESIRED_CURSOR (f);
19026 *width = FRAME_CURSOR_WIDTH (f);
19028 else
19029 cursor_type = get_specified_cursor_type (b->cursor_type, width);
19031 /* Use normal cursor if not blinked off. */
19032 if (!w->cursor_off_p && glyph != NULL)
19034 if (glyph->type == IMAGE_GLYPH) {
19035 if (cursor_type == FILLED_BOX_CURSOR)
19036 cursor_type = HOLLOW_BOX_CURSOR;
19038 return cursor_type;
19041 /* Cursor is blinked off, so determine how to "toggle" it. */
19043 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
19044 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
19045 return get_specified_cursor_type (XCDR (alt_cursor), width);
19047 /* Then see if frame has specified a specific blink off cursor type. */
19048 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
19050 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
19051 return FRAME_BLINK_OFF_CURSOR (f);
19054 #if 0
19055 /* Some people liked having a permanently visible blinking cursor,
19056 while others had very strong opinions against it. So it was
19057 decided to remove it. KFS 2003-09-03 */
19059 /* Finally perform built-in cursor blinking:
19060 filled box <-> hollow box
19061 wide [h]bar <-> narrow [h]bar
19062 narrow [h]bar <-> no cursor
19063 other type <-> no cursor */
19065 if (cursor_type == FILLED_BOX_CURSOR)
19066 return HOLLOW_BOX_CURSOR;
19068 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
19070 *width = 1;
19071 return cursor_type;
19073 #endif
19075 return NO_CURSOR;
19079 #ifdef HAVE_WINDOW_SYSTEM
19081 /* Notice when the text cursor of window W has been completely
19082 overwritten by a drawing operation that outputs glyphs in AREA
19083 starting at X0 and ending at X1 in the line starting at Y0 and
19084 ending at Y1. X coordinates are area-relative. X1 < 0 means all
19085 the rest of the line after X0 has been written. Y coordinates
19086 are window-relative. */
19088 static void
19089 notice_overwritten_cursor (w, area, x0, x1, y0, y1)
19090 struct window *w;
19091 enum glyph_row_area area;
19092 int x0, y0, x1, y1;
19094 int cx0, cx1, cy0, cy1;
19095 struct glyph_row *row;
19097 if (!w->phys_cursor_on_p)
19098 return;
19099 if (area != TEXT_AREA)
19100 return;
19102 row = w->current_matrix->rows + w->phys_cursor.vpos;
19103 if (!row->displays_text_p)
19104 return;
19106 if (row->cursor_in_fringe_p)
19108 row->cursor_in_fringe_p = 0;
19109 draw_fringe_bitmap (w, row, 0);
19110 w->phys_cursor_on_p = 0;
19111 return;
19114 cx0 = w->phys_cursor.x;
19115 cx1 = cx0 + w->phys_cursor_width;
19116 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
19117 return;
19119 /* The cursor image will be completely removed from the
19120 screen if the output area intersects the cursor area in
19121 y-direction. When we draw in [y0 y1[, and some part of
19122 the cursor is at y < y0, that part must have been drawn
19123 before. When scrolling, the cursor is erased before
19124 actually scrolling, so we don't come here. When not
19125 scrolling, the rows above the old cursor row must have
19126 changed, and in this case these rows must have written
19127 over the cursor image.
19129 Likewise if part of the cursor is below y1, with the
19130 exception of the cursor being in the first blank row at
19131 the buffer and window end because update_text_area
19132 doesn't draw that row. (Except when it does, but
19133 that's handled in update_text_area.) */
19135 cy0 = w->phys_cursor.y;
19136 cy1 = cy0 + w->phys_cursor_height;
19137 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
19138 return;
19140 w->phys_cursor_on_p = 0;
19143 #endif /* HAVE_WINDOW_SYSTEM */
19146 /************************************************************************
19147 Mouse Face
19148 ************************************************************************/
19150 #ifdef HAVE_WINDOW_SYSTEM
19152 /* EXPORT for RIF:
19153 Fix the display of area AREA of overlapping row ROW in window W. */
19155 void
19156 x_fix_overlapping_area (w, row, area)
19157 struct window *w;
19158 struct glyph_row *row;
19159 enum glyph_row_area area;
19161 int i, x;
19163 BLOCK_INPUT;
19165 x = 0;
19166 for (i = 0; i < row->used[area];)
19168 if (row->glyphs[area][i].overlaps_vertically_p)
19170 int start = i, start_x = x;
19174 x += row->glyphs[area][i].pixel_width;
19175 ++i;
19177 while (i < row->used[area]
19178 && row->glyphs[area][i].overlaps_vertically_p);
19180 draw_glyphs (w, start_x, row, area,
19181 start, i,
19182 DRAW_NORMAL_TEXT, 1);
19184 else
19186 x += row->glyphs[area][i].pixel_width;
19187 ++i;
19191 UNBLOCK_INPUT;
19195 /* EXPORT:
19196 Draw the cursor glyph of window W in glyph row ROW. See the
19197 comment of draw_glyphs for the meaning of HL. */
19199 void
19200 draw_phys_cursor_glyph (w, row, hl)
19201 struct window *w;
19202 struct glyph_row *row;
19203 enum draw_glyphs_face hl;
19205 /* If cursor hpos is out of bounds, don't draw garbage. This can
19206 happen in mini-buffer windows when switching between echo area
19207 glyphs and mini-buffer. */
19208 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
19210 int on_p = w->phys_cursor_on_p;
19211 int x1;
19212 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
19213 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
19214 hl, 0);
19215 w->phys_cursor_on_p = on_p;
19217 if (hl == DRAW_CURSOR)
19218 w->phys_cursor_width = x1 - w->phys_cursor.x;
19219 /* When we erase the cursor, and ROW is overlapped by other
19220 rows, make sure that these overlapping parts of other rows
19221 are redrawn. */
19222 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
19224 if (row > w->current_matrix->rows
19225 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
19226 x_fix_overlapping_area (w, row - 1, TEXT_AREA);
19228 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
19229 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
19230 x_fix_overlapping_area (w, row + 1, TEXT_AREA);
19236 /* EXPORT:
19237 Erase the image of a cursor of window W from the screen. */
19239 void
19240 erase_phys_cursor (w)
19241 struct window *w;
19243 struct frame *f = XFRAME (w->frame);
19244 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
19245 int hpos = w->phys_cursor.hpos;
19246 int vpos = w->phys_cursor.vpos;
19247 int mouse_face_here_p = 0;
19248 struct glyph_matrix *active_glyphs = w->current_matrix;
19249 struct glyph_row *cursor_row;
19250 struct glyph *cursor_glyph;
19251 enum draw_glyphs_face hl;
19253 /* No cursor displayed or row invalidated => nothing to do on the
19254 screen. */
19255 if (w->phys_cursor_type == NO_CURSOR)
19256 goto mark_cursor_off;
19258 /* VPOS >= active_glyphs->nrows means that window has been resized.
19259 Don't bother to erase the cursor. */
19260 if (vpos >= active_glyphs->nrows)
19261 goto mark_cursor_off;
19263 /* If row containing cursor is marked invalid, there is nothing we
19264 can do. */
19265 cursor_row = MATRIX_ROW (active_glyphs, vpos);
19266 if (!cursor_row->enabled_p)
19267 goto mark_cursor_off;
19269 /* If row is completely invisible, don't attempt to delete a cursor which
19270 isn't there. This can happen if cursor is at top of a window, and
19271 we switch to a buffer with a header line in that window. */
19272 if (cursor_row->visible_height <= 0)
19273 goto mark_cursor_off;
19275 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
19276 if (cursor_row->cursor_in_fringe_p)
19278 cursor_row->cursor_in_fringe_p = 0;
19279 draw_fringe_bitmap (w, cursor_row, 0);
19280 goto mark_cursor_off;
19283 /* This can happen when the new row is shorter than the old one.
19284 In this case, either draw_glyphs or clear_end_of_line
19285 should have cleared the cursor. Note that we wouldn't be
19286 able to erase the cursor in this case because we don't have a
19287 cursor glyph at hand. */
19288 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
19289 goto mark_cursor_off;
19291 /* If the cursor is in the mouse face area, redisplay that when
19292 we clear the cursor. */
19293 if (! NILP (dpyinfo->mouse_face_window)
19294 && w == XWINDOW (dpyinfo->mouse_face_window)
19295 && (vpos > dpyinfo->mouse_face_beg_row
19296 || (vpos == dpyinfo->mouse_face_beg_row
19297 && hpos >= dpyinfo->mouse_face_beg_col))
19298 && (vpos < dpyinfo->mouse_face_end_row
19299 || (vpos == dpyinfo->mouse_face_end_row
19300 && hpos < dpyinfo->mouse_face_end_col))
19301 /* Don't redraw the cursor's spot in mouse face if it is at the
19302 end of a line (on a newline). The cursor appears there, but
19303 mouse highlighting does not. */
19304 && cursor_row->used[TEXT_AREA] > hpos)
19305 mouse_face_here_p = 1;
19307 /* Maybe clear the display under the cursor. */
19308 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
19310 int x, y;
19311 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
19313 cursor_glyph = get_phys_cursor_glyph (w);
19314 if (cursor_glyph == NULL)
19315 goto mark_cursor_off;
19317 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
19318 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
19320 rif->clear_frame_area (f, x, y,
19321 cursor_glyph->pixel_width, cursor_row->visible_height);
19324 /* Erase the cursor by redrawing the character underneath it. */
19325 if (mouse_face_here_p)
19326 hl = DRAW_MOUSE_FACE;
19327 else
19328 hl = DRAW_NORMAL_TEXT;
19329 draw_phys_cursor_glyph (w, cursor_row, hl);
19331 mark_cursor_off:
19332 w->phys_cursor_on_p = 0;
19333 w->phys_cursor_type = NO_CURSOR;
19337 /* EXPORT:
19338 Display or clear cursor of window W. If ON is zero, clear the
19339 cursor. If it is non-zero, display the cursor. If ON is nonzero,
19340 where to put the cursor is specified by HPOS, VPOS, X and Y. */
19342 void
19343 display_and_set_cursor (w, on, hpos, vpos, x, y)
19344 struct window *w;
19345 int on, hpos, vpos, x, y;
19347 struct frame *f = XFRAME (w->frame);
19348 int new_cursor_type;
19349 int new_cursor_width;
19350 int active_cursor;
19351 struct glyph_matrix *current_glyphs;
19352 struct glyph_row *glyph_row;
19353 struct glyph *glyph;
19355 /* This is pointless on invisible frames, and dangerous on garbaged
19356 windows and frames; in the latter case, the frame or window may
19357 be in the midst of changing its size, and x and y may be off the
19358 window. */
19359 if (! FRAME_VISIBLE_P (f)
19360 || FRAME_GARBAGED_P (f)
19361 || vpos >= w->current_matrix->nrows
19362 || hpos >= w->current_matrix->matrix_w)
19363 return;
19365 /* If cursor is off and we want it off, return quickly. */
19366 if (!on && !w->phys_cursor_on_p)
19367 return;
19369 current_glyphs = w->current_matrix;
19370 glyph_row = MATRIX_ROW (current_glyphs, vpos);
19371 glyph = (glyph_row->cursor_in_fringe_p ? NULL
19372 : glyph_row->glyphs[TEXT_AREA] + hpos);
19374 /* If cursor row is not enabled, we don't really know where to
19375 display the cursor. */
19376 if (!glyph_row->enabled_p)
19378 w->phys_cursor_on_p = 0;
19379 return;
19382 xassert (interrupt_input_blocked);
19384 /* Set new_cursor_type to the cursor we want to be displayed. */
19385 new_cursor_type = get_window_cursor_type (w, glyph,
19386 &new_cursor_width, &active_cursor);
19388 /* If cursor is currently being shown and we don't want it to be or
19389 it is in the wrong place, or the cursor type is not what we want,
19390 erase it. */
19391 if (w->phys_cursor_on_p
19392 && (!on
19393 || w->phys_cursor.x != x
19394 || w->phys_cursor.y != y
19395 || new_cursor_type != w->phys_cursor_type
19396 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
19397 && new_cursor_width != w->phys_cursor_width)))
19398 erase_phys_cursor (w);
19400 /* Don't check phys_cursor_on_p here because that flag is only set
19401 to zero in some cases where we know that the cursor has been
19402 completely erased, to avoid the extra work of erasing the cursor
19403 twice. In other words, phys_cursor_on_p can be 1 and the cursor
19404 still not be visible, or it has only been partly erased. */
19405 if (on)
19407 w->phys_cursor_ascent = glyph_row->ascent;
19408 w->phys_cursor_height = glyph_row->height;
19410 /* Set phys_cursor_.* before x_draw_.* is called because some
19411 of them may need the information. */
19412 w->phys_cursor.x = x;
19413 w->phys_cursor.y = glyph_row->y;
19414 w->phys_cursor.hpos = hpos;
19415 w->phys_cursor.vpos = vpos;
19418 rif->draw_window_cursor (w, glyph_row, x, y,
19419 new_cursor_type, new_cursor_width,
19420 on, active_cursor);
19424 /* Switch the display of W's cursor on or off, according to the value
19425 of ON. */
19427 static void
19428 update_window_cursor (w, on)
19429 struct window *w;
19430 int on;
19432 /* Don't update cursor in windows whose frame is in the process
19433 of being deleted. */
19434 if (w->current_matrix)
19436 BLOCK_INPUT;
19437 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
19438 w->phys_cursor.x, w->phys_cursor.y);
19439 UNBLOCK_INPUT;
19444 /* Call update_window_cursor with parameter ON_P on all leaf windows
19445 in the window tree rooted at W. */
19447 static void
19448 update_cursor_in_window_tree (w, on_p)
19449 struct window *w;
19450 int on_p;
19452 while (w)
19454 if (!NILP (w->hchild))
19455 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
19456 else if (!NILP (w->vchild))
19457 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
19458 else
19459 update_window_cursor (w, on_p);
19461 w = NILP (w->next) ? 0 : XWINDOW (w->next);
19466 /* EXPORT:
19467 Display the cursor on window W, or clear it, according to ON_P.
19468 Don't change the cursor's position. */
19470 void
19471 x_update_cursor (f, on_p)
19472 struct frame *f;
19473 int on_p;
19475 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
19479 /* EXPORT:
19480 Clear the cursor of window W to background color, and mark the
19481 cursor as not shown. This is used when the text where the cursor
19482 is is about to be rewritten. */
19484 void
19485 x_clear_cursor (w)
19486 struct window *w;
19488 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
19489 update_window_cursor (w, 0);
19493 /* EXPORT:
19494 Display the active region described by mouse_face_* according to DRAW. */
19496 void
19497 show_mouse_face (dpyinfo, draw)
19498 Display_Info *dpyinfo;
19499 enum draw_glyphs_face draw;
19501 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
19502 struct frame *f = XFRAME (WINDOW_FRAME (w));
19504 if (/* If window is in the process of being destroyed, don't bother
19505 to do anything. */
19506 w->current_matrix != NULL
19507 /* Don't update mouse highlight if hidden */
19508 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
19509 /* Recognize when we are called to operate on rows that don't exist
19510 anymore. This can happen when a window is split. */
19511 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
19513 int phys_cursor_on_p = w->phys_cursor_on_p;
19514 struct glyph_row *row, *first, *last;
19516 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
19517 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
19519 for (row = first; row <= last && row->enabled_p; ++row)
19521 int start_hpos, end_hpos, start_x;
19523 /* For all but the first row, the highlight starts at column 0. */
19524 if (row == first)
19526 start_hpos = dpyinfo->mouse_face_beg_col;
19527 start_x = dpyinfo->mouse_face_beg_x;
19529 else
19531 start_hpos = 0;
19532 start_x = 0;
19535 if (row == last)
19536 end_hpos = dpyinfo->mouse_face_end_col;
19537 else
19538 end_hpos = row->used[TEXT_AREA];
19540 if (end_hpos > start_hpos)
19542 draw_glyphs (w, start_x, row, TEXT_AREA,
19543 start_hpos, end_hpos,
19544 draw, 0);
19546 row->mouse_face_p
19547 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
19551 /* When we've written over the cursor, arrange for it to
19552 be displayed again. */
19553 if (phys_cursor_on_p && !w->phys_cursor_on_p)
19555 BLOCK_INPUT;
19556 display_and_set_cursor (w, 1,
19557 w->phys_cursor.hpos, w->phys_cursor.vpos,
19558 w->phys_cursor.x, w->phys_cursor.y);
19559 UNBLOCK_INPUT;
19563 /* Change the mouse cursor. */
19564 if (draw == DRAW_NORMAL_TEXT)
19565 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
19566 else if (draw == DRAW_MOUSE_FACE)
19567 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
19568 else
19569 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
19572 /* EXPORT:
19573 Clear out the mouse-highlighted active region.
19574 Redraw it un-highlighted first. Value is non-zero if mouse
19575 face was actually drawn unhighlighted. */
19578 clear_mouse_face (dpyinfo)
19579 Display_Info *dpyinfo;
19581 int cleared = 0;
19583 if (!NILP (dpyinfo->mouse_face_window))
19585 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
19586 cleared = 1;
19589 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
19590 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
19591 dpyinfo->mouse_face_window = Qnil;
19592 dpyinfo->mouse_face_overlay = Qnil;
19593 return cleared;
19597 /* EXPORT:
19598 Non-zero if physical cursor of window W is within mouse face. */
19601 cursor_in_mouse_face_p (w)
19602 struct window *w;
19604 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
19605 int in_mouse_face = 0;
19607 if (WINDOWP (dpyinfo->mouse_face_window)
19608 && XWINDOW (dpyinfo->mouse_face_window) == w)
19610 int hpos = w->phys_cursor.hpos;
19611 int vpos = w->phys_cursor.vpos;
19613 if (vpos >= dpyinfo->mouse_face_beg_row
19614 && vpos <= dpyinfo->mouse_face_end_row
19615 && (vpos > dpyinfo->mouse_face_beg_row
19616 || hpos >= dpyinfo->mouse_face_beg_col)
19617 && (vpos < dpyinfo->mouse_face_end_row
19618 || hpos < dpyinfo->mouse_face_end_col
19619 || dpyinfo->mouse_face_past_end))
19620 in_mouse_face = 1;
19623 return in_mouse_face;
19629 /* Find the glyph matrix position of buffer position CHARPOS in window
19630 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
19631 current glyphs must be up to date. If CHARPOS is above window
19632 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
19633 of last line in W. In the row containing CHARPOS, stop before glyphs
19634 having STOP as object. */
19636 #if 1 /* This is a version of fast_find_position that's more correct
19637 in the presence of hscrolling, for example. I didn't install
19638 it right away because the problem fixed is minor, it failed
19639 in 20.x as well, and I think it's too risky to install
19640 so near the release of 21.1. 2001-09-25 gerd. */
19642 static int
19643 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
19644 struct window *w;
19645 int charpos;
19646 int *hpos, *vpos, *x, *y;
19647 Lisp_Object stop;
19649 struct glyph_row *row, *first;
19650 struct glyph *glyph, *end;
19651 int past_end = 0;
19653 first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
19654 row = row_containing_pos (w, charpos, first, NULL, 0);
19655 if (row == NULL)
19657 if (charpos < MATRIX_ROW_START_CHARPOS (first))
19659 *x = *y = *hpos = *vpos = 0;
19660 return 1;
19662 else
19664 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
19665 past_end = 1;
19669 *x = row->x;
19670 *y = row->y;
19671 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
19673 glyph = row->glyphs[TEXT_AREA];
19674 end = glyph + row->used[TEXT_AREA];
19676 /* Skip over glyphs not having an object at the start of the row.
19677 These are special glyphs like truncation marks on terminal
19678 frames. */
19679 if (row->displays_text_p)
19680 while (glyph < end
19681 && INTEGERP (glyph->object)
19682 && !EQ (stop, glyph->object)
19683 && glyph->charpos < 0)
19685 *x += glyph->pixel_width;
19686 ++glyph;
19689 while (glyph < end
19690 && !INTEGERP (glyph->object)
19691 && !EQ (stop, glyph->object)
19692 && (!BUFFERP (glyph->object)
19693 || glyph->charpos < charpos))
19695 *x += glyph->pixel_width;
19696 ++glyph;
19699 *hpos = glyph - row->glyphs[TEXT_AREA];
19700 return !past_end;
19703 #else /* not 1 */
19705 static int
19706 fast_find_position (w, pos, hpos, vpos, x, y, stop)
19707 struct window *w;
19708 int pos;
19709 int *hpos, *vpos, *x, *y;
19710 Lisp_Object stop;
19712 int i;
19713 int lastcol;
19714 int maybe_next_line_p = 0;
19715 int line_start_position;
19716 int yb = window_text_bottom_y (w);
19717 struct glyph_row *row, *best_row;
19718 int row_vpos, best_row_vpos;
19719 int current_x;
19721 row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
19722 row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
19724 while (row->y < yb)
19726 if (row->used[TEXT_AREA])
19727 line_start_position = row->glyphs[TEXT_AREA]->charpos;
19728 else
19729 line_start_position = 0;
19731 if (line_start_position > pos)
19732 break;
19733 /* If the position sought is the end of the buffer,
19734 don't include the blank lines at the bottom of the window. */
19735 else if (line_start_position == pos
19736 && pos == BUF_ZV (XBUFFER (w->buffer)))
19738 maybe_next_line_p = 1;
19739 break;
19741 else if (line_start_position > 0)
19743 best_row = row;
19744 best_row_vpos = row_vpos;
19747 if (row->y + row->height >= yb)
19748 break;
19750 ++row;
19751 ++row_vpos;
19754 /* Find the right column within BEST_ROW. */
19755 lastcol = 0;
19756 current_x = best_row->x;
19757 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
19759 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
19760 int charpos = glyph->charpos;
19762 if (BUFFERP (glyph->object))
19764 if (charpos == pos)
19766 *hpos = i;
19767 *vpos = best_row_vpos;
19768 *x = current_x;
19769 *y = best_row->y;
19770 return 1;
19772 else if (charpos > pos)
19773 break;
19775 else if (EQ (glyph->object, stop))
19776 break;
19778 if (charpos > 0)
19779 lastcol = i;
19780 current_x += glyph->pixel_width;
19783 /* If we're looking for the end of the buffer,
19784 and we didn't find it in the line we scanned,
19785 use the start of the following line. */
19786 if (maybe_next_line_p)
19788 ++best_row;
19789 ++best_row_vpos;
19790 lastcol = 0;
19791 current_x = best_row->x;
19794 *vpos = best_row_vpos;
19795 *hpos = lastcol + 1;
19796 *x = current_x;
19797 *y = best_row->y;
19798 return 0;
19801 #endif /* not 1 */
19804 /* Find the position of the glyph for position POS in OBJECT in
19805 window W's current matrix, and return in *X, *Y the pixel
19806 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
19808 RIGHT_P non-zero means return the position of the right edge of the
19809 glyph, RIGHT_P zero means return the left edge position.
19811 If no glyph for POS exists in the matrix, return the position of
19812 the glyph with the next smaller position that is in the matrix, if
19813 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
19814 exists in the matrix, return the position of the glyph with the
19815 next larger position in OBJECT.
19817 Value is non-zero if a glyph was found. */
19819 static int
19820 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
19821 struct window *w;
19822 int pos;
19823 Lisp_Object object;
19824 int *hpos, *vpos, *x, *y;
19825 int right_p;
19827 int yb = window_text_bottom_y (w);
19828 struct glyph_row *r;
19829 struct glyph *best_glyph = NULL;
19830 struct glyph_row *best_row = NULL;
19831 int best_x = 0;
19833 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
19834 r->enabled_p && r->y < yb;
19835 ++r)
19837 struct glyph *g = r->glyphs[TEXT_AREA];
19838 struct glyph *e = g + r->used[TEXT_AREA];
19839 int gx;
19841 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
19842 if (EQ (g->object, object))
19844 if (g->charpos == pos)
19846 best_glyph = g;
19847 best_x = gx;
19848 best_row = r;
19849 goto found;
19851 else if (best_glyph == NULL
19852 || ((abs (g->charpos - pos)
19853 < abs (best_glyph->charpos - pos))
19854 && (right_p
19855 ? g->charpos < pos
19856 : g->charpos > pos)))
19858 best_glyph = g;
19859 best_x = gx;
19860 best_row = r;
19865 found:
19867 if (best_glyph)
19869 *x = best_x;
19870 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
19872 if (right_p)
19874 *x += best_glyph->pixel_width;
19875 ++*hpos;
19878 *y = best_row->y;
19879 *vpos = best_row - w->current_matrix->rows;
19882 return best_glyph != NULL;
19886 /* See if position X, Y is within a hot-spot of an image. */
19888 static int
19889 on_hot_spot_p (hot_spot, x, y)
19890 Lisp_Object hot_spot;
19891 int x, y;
19893 if (!CONSP (hot_spot))
19894 return 0;
19896 if (EQ (XCAR (hot_spot), Qrect))
19898 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
19899 Lisp_Object rect = XCDR (hot_spot);
19900 Lisp_Object tem;
19901 if (!CONSP (rect))
19902 return 0;
19903 if (!CONSP (XCAR (rect)))
19904 return 0;
19905 if (!CONSP (XCDR (rect)))
19906 return 0;
19907 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
19908 return 0;
19909 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
19910 return 0;
19911 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
19912 return 0;
19913 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
19914 return 0;
19915 return 1;
19917 else if (EQ (XCAR (hot_spot), Qcircle))
19919 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
19920 Lisp_Object circ = XCDR (hot_spot);
19921 Lisp_Object lr, lx0, ly0;
19922 if (CONSP (circ)
19923 && CONSP (XCAR (circ))
19924 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
19925 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
19926 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
19928 double r = XFLOATINT (lr);
19929 double dx = XINT (lx0) - x;
19930 double dy = XINT (ly0) - y;
19931 return (dx * dx + dy * dy <= r * r);
19934 else if (EQ (XCAR (hot_spot), Qpoly))
19936 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
19937 if (VECTORP (XCDR (hot_spot)))
19939 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
19940 Lisp_Object *poly = v->contents;
19941 int n = v->size;
19942 int i;
19943 int inside = 0;
19944 Lisp_Object lx, ly;
19945 int x0, y0;
19947 /* Need an even number of coordinates, and at least 3 edges. */
19948 if (n < 6 || n & 1)
19949 return 0;
19951 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
19952 If count is odd, we are inside polygon. Pixels on edges
19953 may or may not be included depending on actual geometry of the
19954 polygon. */
19955 if ((lx = poly[n-2], !INTEGERP (lx))
19956 || (ly = poly[n-1], !INTEGERP (lx)))
19957 return 0;
19958 x0 = XINT (lx), y0 = XINT (ly);
19959 for (i = 0; i < n; i += 2)
19961 int x1 = x0, y1 = y0;
19962 if ((lx = poly[i], !INTEGERP (lx))
19963 || (ly = poly[i+1], !INTEGERP (ly)))
19964 return 0;
19965 x0 = XINT (lx), y0 = XINT (ly);
19967 /* Does this segment cross the X line? */
19968 if (x0 >= x)
19970 if (x1 >= x)
19971 continue;
19973 else if (x1 < x)
19974 continue;
19975 if (y > y0 && y > y1)
19976 continue;
19977 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
19978 inside = !inside;
19980 return inside;
19983 else
19984 return 0;
19987 Lisp_Object
19988 find_hot_spot (map, x, y)
19989 Lisp_Object map;
19990 int x, y;
19992 while (CONSP (map))
19994 if (CONSP (XCAR (map))
19995 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
19996 return XCAR (map);
19997 map = XCDR (map);
20000 return Qnil;
20003 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
20004 3, 3, 0,
20005 doc: /* Lookup in image map MAP coordinates X and Y.
20006 An image map is an alist where each element has the format (AREA ID PLIST).
20007 An AREA is specified as either a rectangle, a circle, or a polygon:
20008 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
20009 pixel coordinates of the upper left and bottom right corners.
20010 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
20011 and the radius of the circle; r may be a float or integer.
20012 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
20013 vector describes one corner in the polygon.
20014 Returns the alist element for the first matching AREA in MAP. */)
20015 (map, x, y)
20016 Lisp_Object map;
20017 Lisp_Object x, y;
20019 int ix, iy;
20020 if (NILP (map))
20021 return Qnil;
20023 CHECK_NUMBER (x);
20024 CHECK_NUMBER (y);
20026 return find_hot_spot (map, XINT (x), XINT (y));
20030 /* Display frame CURSOR, optionally using shape defined by POINTER. */
20031 static void
20032 define_frame_cursor1 (f, cursor, pointer)
20033 struct frame *f;
20034 Cursor cursor;
20035 Lisp_Object pointer;
20037 if (!NILP (pointer))
20039 if (EQ (pointer, Qarrow))
20040 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20041 else if (EQ (pointer, Qhand))
20042 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
20043 else if (EQ (pointer, Qtext))
20044 cursor = FRAME_X_OUTPUT (f)->text_cursor;
20045 else if (EQ (pointer, intern ("hdrag")))
20046 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
20047 #ifdef HAVE_X_WINDOWS
20048 else if (EQ (pointer, intern ("vdrag")))
20049 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
20050 #endif
20051 else if (EQ (pointer, intern ("hourglass")))
20052 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
20053 else if (EQ (pointer, Qmodeline))
20054 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
20055 else
20056 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20059 #ifndef HAVE_CARBON
20060 if (cursor != No_Cursor)
20061 #else
20062 if (bcmp (&cursor, &No_Cursor, sizeof (Cursor)))
20063 #endif
20064 rif->define_frame_cursor (f, cursor);
20067 /* Take proper action when mouse has moved to the mode or header line
20068 or marginal area AREA of window W, x-position X and y-position Y.
20069 X is relative to the start of the text display area of W, so the
20070 width of bitmap areas and scroll bars must be subtracted to get a
20071 position relative to the start of the mode line. */
20073 static void
20074 note_mode_line_or_margin_highlight (w, x, y, area)
20075 struct window *w;
20076 int x, y;
20077 enum window_part area;
20079 struct frame *f = XFRAME (w->frame);
20080 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20081 Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20082 Lisp_Object pointer = Qnil;
20083 int charpos, dx, dy, width, height;
20084 Lisp_Object string, object = Qnil;
20085 Lisp_Object pos, help, image;
20087 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
20088 string = mode_line_string (w, area, &x, &y, &charpos,
20089 &object, &dx, &dy, &width, &height);
20090 else
20092 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
20093 string = marginal_area_string (w, area, &x, &y, &charpos,
20094 &object, &dx, &dy, &width, &height);
20097 help = Qnil;
20099 if (IMAGEP (object))
20101 Lisp_Object image_map, hotspot;
20102 if ((image_map = Fplist_get (XCDR (object), QCmap),
20103 !NILP (image_map))
20104 && (hotspot = find_hot_spot (image_map, dx, dy),
20105 CONSP (hotspot))
20106 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
20108 Lisp_Object area_id, plist;
20110 area_id = XCAR (hotspot);
20111 /* Could check AREA_ID to see if we enter/leave this hot-spot.
20112 If so, we could look for mouse-enter, mouse-leave
20113 properties in PLIST (and do something...). */
20114 if ((plist = XCDR (hotspot), CONSP (plist)))
20116 pointer = Fplist_get (plist, Qpointer);
20117 if (NILP (pointer))
20118 pointer = Qhand;
20119 help = Fplist_get (plist, Qhelp_echo);
20120 if (!NILP (help))
20122 help_echo_string = help;
20123 /* Is this correct? ++kfs */
20124 XSETWINDOW (help_echo_window, w);
20125 help_echo_object = w->buffer;
20126 help_echo_pos = charpos;
20129 if (NILP (pointer))
20130 pointer = Fplist_get (XCDR (object), QCpointer);
20134 if (STRINGP (string))
20136 pos = make_number (charpos);
20137 /* If we're on a string with `help-echo' text property, arrange
20138 for the help to be displayed. This is done by setting the
20139 global variable help_echo_string to the help string. */
20140 help = Fget_text_property (pos, Qhelp_echo, string);
20141 if (!NILP (help))
20143 help_echo_string = help;
20144 XSETWINDOW (help_echo_window, w);
20145 help_echo_object = string;
20146 help_echo_pos = charpos;
20149 if (NILP (pointer))
20150 pointer = Fget_text_property (pos, Qpointer, string);
20152 /* Change the mouse pointer according to what is under X/Y. */
20153 if (NILP (pointer) && area == ON_MODE_LINE)
20155 Lisp_Object map;
20156 map = Fget_text_property (pos, Qlocal_map, string);
20157 if (!KEYMAPP (map))
20158 map = Fget_text_property (pos, Qkeymap, string);
20159 if (!KEYMAPP (map))
20160 cursor = dpyinfo->vertical_scroll_bar_cursor;
20164 define_frame_cursor1 (f, cursor, pointer);
20168 /* EXPORT:
20169 Take proper action when the mouse has moved to position X, Y on
20170 frame F as regards highlighting characters that have mouse-face
20171 properties. Also de-highlighting chars where the mouse was before.
20172 X and Y can be negative or out of range. */
20174 void
20175 note_mouse_highlight (f, x, y)
20176 struct frame *f;
20177 int x, y;
20179 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20180 enum window_part part;
20181 Lisp_Object window;
20182 struct window *w;
20183 Cursor cursor = No_Cursor;
20184 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
20185 struct buffer *b;
20187 /* When a menu is active, don't highlight because this looks odd. */
20188 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
20189 if (popup_activated ())
20190 return;
20191 #endif
20193 if (NILP (Vmouse_highlight)
20194 || !f->glyphs_initialized_p)
20195 return;
20197 dpyinfo->mouse_face_mouse_x = x;
20198 dpyinfo->mouse_face_mouse_y = y;
20199 dpyinfo->mouse_face_mouse_frame = f;
20201 if (dpyinfo->mouse_face_defer)
20202 return;
20204 if (gc_in_progress)
20206 dpyinfo->mouse_face_deferred_gc = 1;
20207 return;
20210 /* Which window is that in? */
20211 window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
20213 /* If we were displaying active text in another window, clear that. */
20214 if (! EQ (window, dpyinfo->mouse_face_window))
20215 clear_mouse_face (dpyinfo);
20217 /* Not on a window -> return. */
20218 if (!WINDOWP (window))
20219 return;
20221 /* Reset help_echo_string. It will get recomputed below. */
20222 help_echo_string = Qnil;
20224 /* Convert to window-relative pixel coordinates. */
20225 w = XWINDOW (window);
20226 frame_to_window_pixel_xy (w, &x, &y);
20228 /* Handle tool-bar window differently since it doesn't display a
20229 buffer. */
20230 if (EQ (window, f->tool_bar_window))
20232 note_tool_bar_highlight (f, x, y);
20233 return;
20236 /* Mouse is on the mode, header line or margin? */
20237 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
20238 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
20240 note_mode_line_or_margin_highlight (w, x, y, part);
20241 return;
20244 if (part == ON_VERTICAL_BORDER)
20245 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
20246 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE)
20247 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20248 else
20249 cursor = FRAME_X_OUTPUT (f)->text_cursor;
20251 /* Are we in a window whose display is up to date?
20252 And verify the buffer's text has not changed. */
20253 b = XBUFFER (w->buffer);
20254 if (part == ON_TEXT
20255 && EQ (w->window_end_valid, w->buffer)
20256 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
20257 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
20259 int hpos, vpos, pos, i, dx, dy, area;
20260 struct glyph *glyph;
20261 Lisp_Object object;
20262 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
20263 Lisp_Object *overlay_vec = NULL;
20264 int len, noverlays;
20265 struct buffer *obuf;
20266 int obegv, ozv, same_region;
20268 /* Find the glyph under X/Y. */
20269 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
20271 /* Look for :pointer property on image. */
20272 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
20274 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
20275 if (img != NULL && IMAGEP (img->spec))
20277 Lisp_Object image_map, hotspot;
20278 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
20279 !NILP (image_map))
20280 && (hotspot = find_hot_spot (image_map, dx, dy),
20281 CONSP (hotspot))
20282 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
20284 Lisp_Object area_id, plist;
20286 area_id = XCAR (hotspot);
20287 /* Could check AREA_ID to see if we enter/leave this hot-spot.
20288 If so, we could look for mouse-enter, mouse-leave
20289 properties in PLIST (and do something...). */
20290 if ((plist = XCDR (hotspot), CONSP (plist)))
20292 pointer = Fplist_get (plist, Qpointer);
20293 if (NILP (pointer))
20294 pointer = Qhand;
20295 help_echo_string = Fplist_get (plist, Qhelp_echo);
20296 if (!NILP (help_echo_string))
20298 help_echo_window = window;
20299 help_echo_object = glyph->object;
20300 help_echo_pos = glyph->charpos;
20304 if (NILP (pointer))
20305 pointer = Fplist_get (XCDR (img->spec), QCpointer);
20309 /* Clear mouse face if X/Y not over text. */
20310 if (glyph == NULL
20311 || area != TEXT_AREA
20312 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
20314 if (clear_mouse_face (dpyinfo))
20315 cursor = No_Cursor;
20316 if (NILP (pointer))
20318 if (area != TEXT_AREA)
20319 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20320 else
20321 pointer = Vvoid_text_area_pointer;
20323 goto set_cursor;
20326 pos = glyph->charpos;
20327 object = glyph->object;
20328 if (!STRINGP (object) && !BUFFERP (object))
20329 goto set_cursor;
20331 /* If we get an out-of-range value, return now; avoid an error. */
20332 if (BUFFERP (object) && pos > BUF_Z (b))
20333 goto set_cursor;
20335 /* Make the window's buffer temporarily current for
20336 overlays_at and compute_char_face. */
20337 obuf = current_buffer;
20338 current_buffer = b;
20339 obegv = BEGV;
20340 ozv = ZV;
20341 BEGV = BEG;
20342 ZV = Z;
20344 /* Is this char mouse-active or does it have help-echo? */
20345 position = make_number (pos);
20347 if (BUFFERP (object))
20349 /* Put all the overlays we want in a vector in overlay_vec.
20350 Store the length in len. If there are more than 10, make
20351 enough space for all, and try again. */
20352 len = 10;
20353 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
20354 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL, 0);
20355 if (noverlays > len)
20357 len = noverlays;
20358 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
20359 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL,0);
20362 /* Sort overlays into increasing priority order. */
20363 noverlays = sort_overlays (overlay_vec, noverlays, w);
20365 else
20366 noverlays = 0;
20368 same_region = (EQ (window, dpyinfo->mouse_face_window)
20369 && vpos >= dpyinfo->mouse_face_beg_row
20370 && vpos <= dpyinfo->mouse_face_end_row
20371 && (vpos > dpyinfo->mouse_face_beg_row
20372 || hpos >= dpyinfo->mouse_face_beg_col)
20373 && (vpos < dpyinfo->mouse_face_end_row
20374 || hpos < dpyinfo->mouse_face_end_col
20375 || dpyinfo->mouse_face_past_end));
20377 if (same_region)
20378 cursor = No_Cursor;
20380 /* Check mouse-face highlighting. */
20381 if (! same_region
20382 /* If there exists an overlay with mouse-face overlapping
20383 the one we are currently highlighting, we have to
20384 check if we enter the overlapping overlay, and then
20385 highlight only that. */
20386 || (OVERLAYP (dpyinfo->mouse_face_overlay)
20387 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
20389 /* Find the highest priority overlay that has a mouse-face
20390 property. */
20391 overlay = Qnil;
20392 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
20394 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
20395 if (!NILP (mouse_face))
20396 overlay = overlay_vec[i];
20399 /* If we're actually highlighting the same overlay as
20400 before, there's no need to do that again. */
20401 if (!NILP (overlay)
20402 && EQ (overlay, dpyinfo->mouse_face_overlay))
20403 goto check_help_echo;
20405 dpyinfo->mouse_face_overlay = overlay;
20407 /* Clear the display of the old active region, if any. */
20408 if (clear_mouse_face (dpyinfo))
20409 cursor = No_Cursor;
20411 /* If no overlay applies, get a text property. */
20412 if (NILP (overlay))
20413 mouse_face = Fget_text_property (position, Qmouse_face, object);
20415 /* Handle the overlay case. */
20416 if (!NILP (overlay))
20418 /* Find the range of text around this char that
20419 should be active. */
20420 Lisp_Object before, after;
20421 int ignore;
20423 before = Foverlay_start (overlay);
20424 after = Foverlay_end (overlay);
20425 /* Record this as the current active region. */
20426 fast_find_position (w, XFASTINT (before),
20427 &dpyinfo->mouse_face_beg_col,
20428 &dpyinfo->mouse_face_beg_row,
20429 &dpyinfo->mouse_face_beg_x,
20430 &dpyinfo->mouse_face_beg_y, Qnil);
20432 dpyinfo->mouse_face_past_end
20433 = !fast_find_position (w, XFASTINT (after),
20434 &dpyinfo->mouse_face_end_col,
20435 &dpyinfo->mouse_face_end_row,
20436 &dpyinfo->mouse_face_end_x,
20437 &dpyinfo->mouse_face_end_y, Qnil);
20438 dpyinfo->mouse_face_window = window;
20440 dpyinfo->mouse_face_face_id
20441 = face_at_buffer_position (w, pos, 0, 0,
20442 &ignore, pos + 1,
20443 !dpyinfo->mouse_face_hidden);
20445 /* Display it as active. */
20446 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
20447 cursor = No_Cursor;
20449 /* Handle the text property case. */
20450 else if (!NILP (mouse_face) && BUFFERP (object))
20452 /* Find the range of text around this char that
20453 should be active. */
20454 Lisp_Object before, after, beginning, end;
20455 int ignore;
20457 beginning = Fmarker_position (w->start);
20458 end = make_number (BUF_Z (XBUFFER (object))
20459 - XFASTINT (w->window_end_pos));
20460 before
20461 = Fprevious_single_property_change (make_number (pos + 1),
20462 Qmouse_face,
20463 object, beginning);
20464 after
20465 = Fnext_single_property_change (position, Qmouse_face,
20466 object, end);
20468 /* Record this as the current active region. */
20469 fast_find_position (w, XFASTINT (before),
20470 &dpyinfo->mouse_face_beg_col,
20471 &dpyinfo->mouse_face_beg_row,
20472 &dpyinfo->mouse_face_beg_x,
20473 &dpyinfo->mouse_face_beg_y, Qnil);
20474 dpyinfo->mouse_face_past_end
20475 = !fast_find_position (w, XFASTINT (after),
20476 &dpyinfo->mouse_face_end_col,
20477 &dpyinfo->mouse_face_end_row,
20478 &dpyinfo->mouse_face_end_x,
20479 &dpyinfo->mouse_face_end_y, Qnil);
20480 dpyinfo->mouse_face_window = window;
20482 if (BUFFERP (object))
20483 dpyinfo->mouse_face_face_id
20484 = face_at_buffer_position (w, pos, 0, 0,
20485 &ignore, pos + 1,
20486 !dpyinfo->mouse_face_hidden);
20488 /* Display it as active. */
20489 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
20490 cursor = No_Cursor;
20492 else if (!NILP (mouse_face) && STRINGP (object))
20494 Lisp_Object b, e;
20495 int ignore;
20497 b = Fprevious_single_property_change (make_number (pos + 1),
20498 Qmouse_face,
20499 object, Qnil);
20500 e = Fnext_single_property_change (position, Qmouse_face,
20501 object, Qnil);
20502 if (NILP (b))
20503 b = make_number (0);
20504 if (NILP (e))
20505 e = make_number (SCHARS (object) - 1);
20506 fast_find_string_pos (w, XINT (b), object,
20507 &dpyinfo->mouse_face_beg_col,
20508 &dpyinfo->mouse_face_beg_row,
20509 &dpyinfo->mouse_face_beg_x,
20510 &dpyinfo->mouse_face_beg_y, 0);
20511 fast_find_string_pos (w, XINT (e), object,
20512 &dpyinfo->mouse_face_end_col,
20513 &dpyinfo->mouse_face_end_row,
20514 &dpyinfo->mouse_face_end_x,
20515 &dpyinfo->mouse_face_end_y, 1);
20516 dpyinfo->mouse_face_past_end = 0;
20517 dpyinfo->mouse_face_window = window;
20518 dpyinfo->mouse_face_face_id
20519 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
20520 glyph->face_id, 1);
20521 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
20522 cursor = No_Cursor;
20524 else if (STRINGP (object) && NILP (mouse_face))
20526 /* A string which doesn't have mouse-face, but
20527 the text ``under'' it might have. */
20528 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
20529 int start = MATRIX_ROW_START_CHARPOS (r);
20531 pos = string_buffer_position (w, object, start);
20532 if (pos > 0)
20533 mouse_face = get_char_property_and_overlay (make_number (pos),
20534 Qmouse_face,
20535 w->buffer,
20536 &overlay);
20537 if (!NILP (mouse_face) && !NILP (overlay))
20539 Lisp_Object before = Foverlay_start (overlay);
20540 Lisp_Object after = Foverlay_end (overlay);
20541 int ignore;
20543 /* Note that we might not be able to find position
20544 BEFORE in the glyph matrix if the overlay is
20545 entirely covered by a `display' property. In
20546 this case, we overshoot. So let's stop in
20547 the glyph matrix before glyphs for OBJECT. */
20548 fast_find_position (w, XFASTINT (before),
20549 &dpyinfo->mouse_face_beg_col,
20550 &dpyinfo->mouse_face_beg_row,
20551 &dpyinfo->mouse_face_beg_x,
20552 &dpyinfo->mouse_face_beg_y,
20553 object);
20555 dpyinfo->mouse_face_past_end
20556 = !fast_find_position (w, XFASTINT (after),
20557 &dpyinfo->mouse_face_end_col,
20558 &dpyinfo->mouse_face_end_row,
20559 &dpyinfo->mouse_face_end_x,
20560 &dpyinfo->mouse_face_end_y,
20561 Qnil);
20562 dpyinfo->mouse_face_window = window;
20563 dpyinfo->mouse_face_face_id
20564 = face_at_buffer_position (w, pos, 0, 0,
20565 &ignore, pos + 1,
20566 !dpyinfo->mouse_face_hidden);
20568 /* Display it as active. */
20569 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
20570 cursor = No_Cursor;
20575 check_help_echo:
20577 /* Look for a `help-echo' property. */
20578 if (NILP (help_echo_string)) {
20579 Lisp_Object help, overlay;
20581 /* Check overlays first. */
20582 help = overlay = Qnil;
20583 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
20585 overlay = overlay_vec[i];
20586 help = Foverlay_get (overlay, Qhelp_echo);
20589 if (!NILP (help))
20591 help_echo_string = help;
20592 help_echo_window = window;
20593 help_echo_object = overlay;
20594 help_echo_pos = pos;
20596 else
20598 Lisp_Object object = glyph->object;
20599 int charpos = glyph->charpos;
20601 /* Try text properties. */
20602 if (STRINGP (object)
20603 && charpos >= 0
20604 && charpos < SCHARS (object))
20606 help = Fget_text_property (make_number (charpos),
20607 Qhelp_echo, object);
20608 if (NILP (help))
20610 /* If the string itself doesn't specify a help-echo,
20611 see if the buffer text ``under'' it does. */
20612 struct glyph_row *r
20613 = MATRIX_ROW (w->current_matrix, vpos);
20614 int start = MATRIX_ROW_START_CHARPOS (r);
20615 int pos = string_buffer_position (w, object, start);
20616 if (pos > 0)
20618 help = Fget_char_property (make_number (pos),
20619 Qhelp_echo, w->buffer);
20620 if (!NILP (help))
20622 charpos = pos;
20623 object = w->buffer;
20628 else if (BUFFERP (object)
20629 && charpos >= BEGV
20630 && charpos < ZV)
20631 help = Fget_text_property (make_number (charpos), Qhelp_echo,
20632 object);
20634 if (!NILP (help))
20636 help_echo_string = help;
20637 help_echo_window = window;
20638 help_echo_object = object;
20639 help_echo_pos = charpos;
20644 /* Look for a `pointer' property. */
20645 if (NILP (pointer))
20647 /* Check overlays first. */
20648 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
20649 pointer = Foverlay_get (overlay_vec[i], Qpointer);
20651 if (NILP (pointer))
20653 Lisp_Object object = glyph->object;
20654 int charpos = glyph->charpos;
20656 /* Try text properties. */
20657 if (STRINGP (object)
20658 && charpos >= 0
20659 && charpos < SCHARS (object))
20661 pointer = Fget_text_property (make_number (charpos),
20662 Qpointer, object);
20663 if (NILP (pointer))
20665 /* If the string itself doesn't specify a pointer,
20666 see if the buffer text ``under'' it does. */
20667 struct glyph_row *r
20668 = MATRIX_ROW (w->current_matrix, vpos);
20669 int start = MATRIX_ROW_START_CHARPOS (r);
20670 int pos = string_buffer_position (w, object, start);
20671 if (pos > 0)
20672 pointer = Fget_char_property (make_number (pos),
20673 Qpointer, w->buffer);
20676 else if (BUFFERP (object)
20677 && charpos >= BEGV
20678 && charpos < ZV)
20679 pointer = Fget_text_property (make_number (charpos),
20680 Qpointer, object);
20684 BEGV = obegv;
20685 ZV = ozv;
20686 current_buffer = obuf;
20689 set_cursor:
20691 define_frame_cursor1 (f, cursor, pointer);
20695 /* EXPORT for RIF:
20696 Clear any mouse-face on window W. This function is part of the
20697 redisplay interface, and is called from try_window_id and similar
20698 functions to ensure the mouse-highlight is off. */
20700 void
20701 x_clear_window_mouse_face (w)
20702 struct window *w;
20704 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
20705 Lisp_Object window;
20707 BLOCK_INPUT;
20708 XSETWINDOW (window, w);
20709 if (EQ (window, dpyinfo->mouse_face_window))
20710 clear_mouse_face (dpyinfo);
20711 UNBLOCK_INPUT;
20715 /* EXPORT:
20716 Just discard the mouse face information for frame F, if any.
20717 This is used when the size of F is changed. */
20719 void
20720 cancel_mouse_face (f)
20721 struct frame *f;
20723 Lisp_Object window;
20724 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20726 window = dpyinfo->mouse_face_window;
20727 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
20729 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
20730 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
20731 dpyinfo->mouse_face_window = Qnil;
20736 #endif /* HAVE_WINDOW_SYSTEM */
20739 /***********************************************************************
20740 Exposure Events
20741 ***********************************************************************/
20743 #ifdef HAVE_WINDOW_SYSTEM
20745 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
20746 which intersects rectangle R. R is in window-relative coordinates. */
20748 static void
20749 expose_area (w, row, r, area)
20750 struct window *w;
20751 struct glyph_row *row;
20752 XRectangle *r;
20753 enum glyph_row_area area;
20755 struct glyph *first = row->glyphs[area];
20756 struct glyph *end = row->glyphs[area] + row->used[area];
20757 struct glyph *last;
20758 int first_x, start_x, x;
20760 if (area == TEXT_AREA && row->fill_line_p)
20761 /* If row extends face to end of line write the whole line. */
20762 draw_glyphs (w, 0, row, area,
20763 0, row->used[area],
20764 DRAW_NORMAL_TEXT, 0);
20765 else
20767 /* Set START_X to the window-relative start position for drawing glyphs of
20768 AREA. The first glyph of the text area can be partially visible.
20769 The first glyphs of other areas cannot. */
20770 start_x = window_box_left_offset (w, area);
20771 x = start_x;
20772 if (area == TEXT_AREA)
20773 x += row->x;
20775 /* Find the first glyph that must be redrawn. */
20776 while (first < end
20777 && x + first->pixel_width < r->x)
20779 x += first->pixel_width;
20780 ++first;
20783 /* Find the last one. */
20784 last = first;
20785 first_x = x;
20786 while (last < end
20787 && x < r->x + r->width)
20789 x += last->pixel_width;
20790 ++last;
20793 /* Repaint. */
20794 if (last > first)
20795 draw_glyphs (w, first_x - start_x, row, area,
20796 first - row->glyphs[area], last - row->glyphs[area],
20797 DRAW_NORMAL_TEXT, 0);
20802 /* Redraw the parts of the glyph row ROW on window W intersecting
20803 rectangle R. R is in window-relative coordinates. Value is
20804 non-zero if mouse-face was overwritten. */
20806 static int
20807 expose_line (w, row, r)
20808 struct window *w;
20809 struct glyph_row *row;
20810 XRectangle *r;
20812 xassert (row->enabled_p);
20814 if (row->mode_line_p || w->pseudo_window_p)
20815 draw_glyphs (w, 0, row, TEXT_AREA,
20816 0, row->used[TEXT_AREA],
20817 DRAW_NORMAL_TEXT, 0);
20818 else
20820 if (row->used[LEFT_MARGIN_AREA])
20821 expose_area (w, row, r, LEFT_MARGIN_AREA);
20822 if (row->used[TEXT_AREA])
20823 expose_area (w, row, r, TEXT_AREA);
20824 if (row->used[RIGHT_MARGIN_AREA])
20825 expose_area (w, row, r, RIGHT_MARGIN_AREA);
20826 draw_row_fringe_bitmaps (w, row);
20829 return row->mouse_face_p;
20833 /* Redraw those parts of glyphs rows during expose event handling that
20834 overlap other rows. Redrawing of an exposed line writes over parts
20835 of lines overlapping that exposed line; this function fixes that.
20837 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
20838 row in W's current matrix that is exposed and overlaps other rows.
20839 LAST_OVERLAPPING_ROW is the last such row. */
20841 static void
20842 expose_overlaps (w, first_overlapping_row, last_overlapping_row)
20843 struct window *w;
20844 struct glyph_row *first_overlapping_row;
20845 struct glyph_row *last_overlapping_row;
20847 struct glyph_row *row;
20849 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
20850 if (row->overlapping_p)
20852 xassert (row->enabled_p && !row->mode_line_p);
20854 if (row->used[LEFT_MARGIN_AREA])
20855 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
20857 if (row->used[TEXT_AREA])
20858 x_fix_overlapping_area (w, row, TEXT_AREA);
20860 if (row->used[RIGHT_MARGIN_AREA])
20861 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
20866 /* Return non-zero if W's cursor intersects rectangle R. */
20868 static int
20869 phys_cursor_in_rect_p (w, r)
20870 struct window *w;
20871 XRectangle *r;
20873 XRectangle cr, result;
20874 struct glyph *cursor_glyph;
20876 cursor_glyph = get_phys_cursor_glyph (w);
20877 if (cursor_glyph)
20879 /* r is relative to W's box, but w->phys_cursor.x is relative
20880 to left edge of W's TEXT area. Adjust it. */
20881 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
20882 cr.y = w->phys_cursor.y;
20883 cr.width = cursor_glyph->pixel_width;
20884 cr.height = w->phys_cursor_height;
20885 /* ++KFS: W32 version used W32-specific IntersectRect here, but
20886 I assume the effect is the same -- and this is portable. */
20887 return x_intersect_rectangles (&cr, r, &result);
20889 else
20890 return 0;
20894 /* EXPORT:
20895 Draw a vertical window border to the right of window W if W doesn't
20896 have vertical scroll bars. */
20898 void
20899 x_draw_vertical_border (w)
20900 struct window *w;
20902 /* We could do better, if we knew what type of scroll-bar the adjacent
20903 windows (on either side) have... But we don't :-(
20904 However, I think this works ok. ++KFS 2003-04-25 */
20906 /* Redraw borders between horizontally adjacent windows. Don't
20907 do it for frames with vertical scroll bars because either the
20908 right scroll bar of a window, or the left scroll bar of its
20909 neighbor will suffice as a border. */
20910 if (!WINDOW_RIGHTMOST_P (w)
20911 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
20913 int x0, x1, y0, y1;
20915 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
20916 y1 -= 1;
20918 rif->draw_vertical_window_border (w, x1, y0, y1);
20920 else if (!WINDOW_LEFTMOST_P (w)
20921 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
20923 int x0, x1, y0, y1;
20925 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
20926 y1 -= 1;
20928 rif->draw_vertical_window_border (w, x0, y0, y1);
20933 /* Redraw the part of window W intersection rectangle FR. Pixel
20934 coordinates in FR are frame-relative. Call this function with
20935 input blocked. Value is non-zero if the exposure overwrites
20936 mouse-face. */
20938 static int
20939 expose_window (w, fr)
20940 struct window *w;
20941 XRectangle *fr;
20943 struct frame *f = XFRAME (w->frame);
20944 XRectangle wr, r;
20945 int mouse_face_overwritten_p = 0;
20947 /* If window is not yet fully initialized, do nothing. This can
20948 happen when toolkit scroll bars are used and a window is split.
20949 Reconfiguring the scroll bar will generate an expose for a newly
20950 created window. */
20951 if (w->current_matrix == NULL)
20952 return 0;
20954 /* When we're currently updating the window, display and current
20955 matrix usually don't agree. Arrange for a thorough display
20956 later. */
20957 if (w == updated_window)
20959 SET_FRAME_GARBAGED (f);
20960 return 0;
20963 /* Frame-relative pixel rectangle of W. */
20964 wr.x = WINDOW_LEFT_EDGE_X (w);
20965 wr.y = WINDOW_TOP_EDGE_Y (w);
20966 wr.width = WINDOW_TOTAL_WIDTH (w);
20967 wr.height = WINDOW_TOTAL_HEIGHT (w);
20969 if (x_intersect_rectangles (fr, &wr, &r))
20971 int yb = window_text_bottom_y (w);
20972 struct glyph_row *row;
20973 int cursor_cleared_p;
20974 struct glyph_row *first_overlapping_row, *last_overlapping_row;
20976 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
20977 r.x, r.y, r.width, r.height));
20979 /* Convert to window coordinates. */
20980 r.x -= WINDOW_LEFT_EDGE_X (w);
20981 r.y -= WINDOW_TOP_EDGE_Y (w);
20983 /* Turn off the cursor. */
20984 if (!w->pseudo_window_p
20985 && phys_cursor_in_rect_p (w, &r))
20987 x_clear_cursor (w);
20988 cursor_cleared_p = 1;
20990 else
20991 cursor_cleared_p = 0;
20993 /* Update lines intersecting rectangle R. */
20994 first_overlapping_row = last_overlapping_row = NULL;
20995 for (row = w->current_matrix->rows;
20996 row->enabled_p;
20997 ++row)
20999 int y0 = row->y;
21000 int y1 = MATRIX_ROW_BOTTOM_Y (row);
21002 if ((y0 >= r.y && y0 < r.y + r.height)
21003 || (y1 > r.y && y1 < r.y + r.height)
21004 || (r.y >= y0 && r.y < y1)
21005 || (r.y + r.height > y0 && r.y + r.height < y1))
21007 if (row->overlapping_p)
21009 if (first_overlapping_row == NULL)
21010 first_overlapping_row = row;
21011 last_overlapping_row = row;
21014 if (expose_line (w, row, &r))
21015 mouse_face_overwritten_p = 1;
21018 if (y1 >= yb)
21019 break;
21022 /* Display the mode line if there is one. */
21023 if (WINDOW_WANTS_MODELINE_P (w)
21024 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
21025 row->enabled_p)
21026 && row->y < r.y + r.height)
21028 if (expose_line (w, row, &r))
21029 mouse_face_overwritten_p = 1;
21032 if (!w->pseudo_window_p)
21034 /* Fix the display of overlapping rows. */
21035 if (first_overlapping_row)
21036 expose_overlaps (w, first_overlapping_row, last_overlapping_row);
21038 /* Draw border between windows. */
21039 x_draw_vertical_border (w);
21041 /* Turn the cursor on again. */
21042 if (cursor_cleared_p)
21043 update_window_cursor (w, 1);
21047 #ifdef HAVE_CARBON
21048 /* Display scroll bar for this window. */
21049 if (!NILP (w->vertical_scroll_bar))
21051 /* ++KFS:
21052 If this doesn't work here (maybe some header files are missing),
21053 make a function in macterm.c and call it to do the job! */
21054 ControlHandle ch
21055 = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (w->vertical_scroll_bar));
21057 Draw1Control (ch);
21059 #endif
21061 return mouse_face_overwritten_p;
21066 /* Redraw (parts) of all windows in the window tree rooted at W that
21067 intersect R. R contains frame pixel coordinates. Value is
21068 non-zero if the exposure overwrites mouse-face. */
21070 static int
21071 expose_window_tree (w, r)
21072 struct window *w;
21073 XRectangle *r;
21075 struct frame *f = XFRAME (w->frame);
21076 int mouse_face_overwritten_p = 0;
21078 while (w && !FRAME_GARBAGED_P (f))
21080 if (!NILP (w->hchild))
21081 mouse_face_overwritten_p
21082 |= expose_window_tree (XWINDOW (w->hchild), r);
21083 else if (!NILP (w->vchild))
21084 mouse_face_overwritten_p
21085 |= expose_window_tree (XWINDOW (w->vchild), r);
21086 else
21087 mouse_face_overwritten_p |= expose_window (w, r);
21089 w = NILP (w->next) ? NULL : XWINDOW (w->next);
21092 return mouse_face_overwritten_p;
21096 /* EXPORT:
21097 Redisplay an exposed area of frame F. X and Y are the upper-left
21098 corner of the exposed rectangle. W and H are width and height of
21099 the exposed area. All are pixel values. W or H zero means redraw
21100 the entire frame. */
21102 void
21103 expose_frame (f, x, y, w, h)
21104 struct frame *f;
21105 int x, y, w, h;
21107 XRectangle r;
21108 int mouse_face_overwritten_p = 0;
21110 TRACE ((stderr, "expose_frame "));
21112 /* No need to redraw if frame will be redrawn soon. */
21113 if (FRAME_GARBAGED_P (f))
21115 TRACE ((stderr, " garbaged\n"));
21116 return;
21119 #ifdef HAVE_CARBON
21120 /* MAC_TODO: this is a kludge, but if scroll bars are not activated
21121 or deactivated here, for unknown reasons, activated scroll bars
21122 are shown in deactivated frames in some instances. */
21123 if (f == FRAME_MAC_DISPLAY_INFO (f)->x_focus_frame)
21124 activate_scroll_bars (f);
21125 else
21126 deactivate_scroll_bars (f);
21127 #endif
21129 /* If basic faces haven't been realized yet, there is no point in
21130 trying to redraw anything. This can happen when we get an expose
21131 event while Emacs is starting, e.g. by moving another window. */
21132 if (FRAME_FACE_CACHE (f) == NULL
21133 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
21135 TRACE ((stderr, " no faces\n"));
21136 return;
21139 if (w == 0 || h == 0)
21141 r.x = r.y = 0;
21142 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
21143 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
21145 else
21147 r.x = x;
21148 r.y = y;
21149 r.width = w;
21150 r.height = h;
21153 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
21154 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
21156 if (WINDOWP (f->tool_bar_window))
21157 mouse_face_overwritten_p
21158 |= expose_window (XWINDOW (f->tool_bar_window), &r);
21160 #ifdef HAVE_X_WINDOWS
21161 #ifndef MSDOS
21162 #ifndef USE_X_TOOLKIT
21163 if (WINDOWP (f->menu_bar_window))
21164 mouse_face_overwritten_p
21165 |= expose_window (XWINDOW (f->menu_bar_window), &r);
21166 #endif /* not USE_X_TOOLKIT */
21167 #endif
21168 #endif
21170 /* Some window managers support a focus-follows-mouse style with
21171 delayed raising of frames. Imagine a partially obscured frame,
21172 and moving the mouse into partially obscured mouse-face on that
21173 frame. The visible part of the mouse-face will be highlighted,
21174 then the WM raises the obscured frame. With at least one WM, KDE
21175 2.1, Emacs is not getting any event for the raising of the frame
21176 (even tried with SubstructureRedirectMask), only Expose events.
21177 These expose events will draw text normally, i.e. not
21178 highlighted. Which means we must redo the highlight here.
21179 Subsume it under ``we love X''. --gerd 2001-08-15 */
21180 /* Included in Windows version because Windows most likely does not
21181 do the right thing if any third party tool offers
21182 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
21183 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
21185 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21186 if (f == dpyinfo->mouse_face_mouse_frame)
21188 int x = dpyinfo->mouse_face_mouse_x;
21189 int y = dpyinfo->mouse_face_mouse_y;
21190 clear_mouse_face (dpyinfo);
21191 note_mouse_highlight (f, x, y);
21197 /* EXPORT:
21198 Determine the intersection of two rectangles R1 and R2. Return
21199 the intersection in *RESULT. Value is non-zero if RESULT is not
21200 empty. */
21203 x_intersect_rectangles (r1, r2, result)
21204 XRectangle *r1, *r2, *result;
21206 XRectangle *left, *right;
21207 XRectangle *upper, *lower;
21208 int intersection_p = 0;
21210 /* Rearrange so that R1 is the left-most rectangle. */
21211 if (r1->x < r2->x)
21212 left = r1, right = r2;
21213 else
21214 left = r2, right = r1;
21216 /* X0 of the intersection is right.x0, if this is inside R1,
21217 otherwise there is no intersection. */
21218 if (right->x <= left->x + left->width)
21220 result->x = right->x;
21222 /* The right end of the intersection is the minimum of the
21223 the right ends of left and right. */
21224 result->width = (min (left->x + left->width, right->x + right->width)
21225 - result->x);
21227 /* Same game for Y. */
21228 if (r1->y < r2->y)
21229 upper = r1, lower = r2;
21230 else
21231 upper = r2, lower = r1;
21233 /* The upper end of the intersection is lower.y0, if this is inside
21234 of upper. Otherwise, there is no intersection. */
21235 if (lower->y <= upper->y + upper->height)
21237 result->y = lower->y;
21239 /* The lower end of the intersection is the minimum of the lower
21240 ends of upper and lower. */
21241 result->height = (min (lower->y + lower->height,
21242 upper->y + upper->height)
21243 - result->y);
21244 intersection_p = 1;
21248 return intersection_p;
21251 #endif /* HAVE_WINDOW_SYSTEM */
21254 /***********************************************************************
21255 Initialization
21256 ***********************************************************************/
21258 void
21259 syms_of_xdisp ()
21261 Vwith_echo_area_save_vector = Qnil;
21262 staticpro (&Vwith_echo_area_save_vector);
21264 Vmessage_stack = Qnil;
21265 staticpro (&Vmessage_stack);
21267 Qinhibit_redisplay = intern ("inhibit-redisplay");
21268 staticpro (&Qinhibit_redisplay);
21270 message_dolog_marker1 = Fmake_marker ();
21271 staticpro (&message_dolog_marker1);
21272 message_dolog_marker2 = Fmake_marker ();
21273 staticpro (&message_dolog_marker2);
21274 message_dolog_marker3 = Fmake_marker ();
21275 staticpro (&message_dolog_marker3);
21277 #if GLYPH_DEBUG
21278 defsubr (&Sdump_frame_glyph_matrix);
21279 defsubr (&Sdump_glyph_matrix);
21280 defsubr (&Sdump_glyph_row);
21281 defsubr (&Sdump_tool_bar_row);
21282 defsubr (&Strace_redisplay);
21283 defsubr (&Strace_to_stderr);
21284 #endif
21285 #ifdef HAVE_WINDOW_SYSTEM
21286 defsubr (&Stool_bar_lines_needed);
21287 defsubr (&Slookup_image_map);
21288 #endif
21289 defsubr (&Sformat_mode_line);
21291 staticpro (&Qmenu_bar_update_hook);
21292 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
21294 staticpro (&Qoverriding_terminal_local_map);
21295 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
21297 staticpro (&Qoverriding_local_map);
21298 Qoverriding_local_map = intern ("overriding-local-map");
21300 staticpro (&Qwindow_scroll_functions);
21301 Qwindow_scroll_functions = intern ("window-scroll-functions");
21303 staticpro (&Qredisplay_end_trigger_functions);
21304 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
21306 staticpro (&Qinhibit_point_motion_hooks);
21307 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
21309 QCdata = intern (":data");
21310 staticpro (&QCdata);
21311 Qdisplay = intern ("display");
21312 staticpro (&Qdisplay);
21313 Qspace_width = intern ("space-width");
21314 staticpro (&Qspace_width);
21315 Qraise = intern ("raise");
21316 staticpro (&Qraise);
21317 Qspace = intern ("space");
21318 staticpro (&Qspace);
21319 Qmargin = intern ("margin");
21320 staticpro (&Qmargin);
21321 Qpointer = intern ("pointer");
21322 staticpro (&Qpointer);
21323 Qleft_margin = intern ("left-margin");
21324 staticpro (&Qleft_margin);
21325 Qright_margin = intern ("right-margin");
21326 staticpro (&Qright_margin);
21327 QCalign_to = intern (":align-to");
21328 staticpro (&QCalign_to);
21329 QCrelative_width = intern (":relative-width");
21330 staticpro (&QCrelative_width);
21331 QCrelative_height = intern (":relative-height");
21332 staticpro (&QCrelative_height);
21333 QCeval = intern (":eval");
21334 staticpro (&QCeval);
21335 QCpropertize = intern (":propertize");
21336 staticpro (&QCpropertize);
21337 QCfile = intern (":file");
21338 staticpro (&QCfile);
21339 Qfontified = intern ("fontified");
21340 staticpro (&Qfontified);
21341 Qfontification_functions = intern ("fontification-functions");
21342 staticpro (&Qfontification_functions);
21343 Qtrailing_whitespace = intern ("trailing-whitespace");
21344 staticpro (&Qtrailing_whitespace);
21345 Qimage = intern ("image");
21346 staticpro (&Qimage);
21347 QCmap = intern (":map");
21348 staticpro (&QCmap);
21349 QCpointer = intern (":pointer");
21350 staticpro (&QCpointer);
21351 Qrect = intern ("rect");
21352 staticpro (&Qrect);
21353 Qcircle = intern ("circle");
21354 staticpro (&Qcircle);
21355 Qpoly = intern ("poly");
21356 staticpro (&Qpoly);
21357 Qmessage_truncate_lines = intern ("message-truncate-lines");
21358 staticpro (&Qmessage_truncate_lines);
21359 Qcursor_in_non_selected_windows = intern ("cursor-in-non-selected-windows");
21360 staticpro (&Qcursor_in_non_selected_windows);
21361 Qgrow_only = intern ("grow-only");
21362 staticpro (&Qgrow_only);
21363 Qinhibit_menubar_update = intern ("inhibit-menubar-update");
21364 staticpro (&Qinhibit_menubar_update);
21365 Qinhibit_eval_during_redisplay = intern ("inhibit-eval-during-redisplay");
21366 staticpro (&Qinhibit_eval_during_redisplay);
21367 Qposition = intern ("position");
21368 staticpro (&Qposition);
21369 Qbuffer_position = intern ("buffer-position");
21370 staticpro (&Qbuffer_position);
21371 Qobject = intern ("object");
21372 staticpro (&Qobject);
21373 Qbar = intern ("bar");
21374 staticpro (&Qbar);
21375 Qhbar = intern ("hbar");
21376 staticpro (&Qhbar);
21377 Qbox = intern ("box");
21378 staticpro (&Qbox);
21379 Qhollow = intern ("hollow");
21380 staticpro (&Qhollow);
21381 Qhand = intern ("hand");
21382 staticpro (&Qhand);
21383 Qarrow = intern ("arrow");
21384 staticpro (&Qarrow);
21385 Qtext = intern ("text");
21386 staticpro (&Qtext);
21387 Qrisky_local_variable = intern ("risky-local-variable");
21388 staticpro (&Qrisky_local_variable);
21389 Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
21390 staticpro (&Qinhibit_free_realized_faces);
21392 list_of_error = Fcons (intern ("error"), Qnil);
21393 staticpro (&list_of_error);
21395 last_arrow_position = Qnil;
21396 last_arrow_string = Qnil;
21397 staticpro (&last_arrow_position);
21398 staticpro (&last_arrow_string);
21400 echo_buffer[0] = echo_buffer[1] = Qnil;
21401 staticpro (&echo_buffer[0]);
21402 staticpro (&echo_buffer[1]);
21404 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
21405 staticpro (&echo_area_buffer[0]);
21406 staticpro (&echo_area_buffer[1]);
21408 Vmessages_buffer_name = build_string ("*Messages*");
21409 staticpro (&Vmessages_buffer_name);
21411 mode_line_proptrans_alist = Qnil;
21412 staticpro (&mode_line_proptrans_alist);
21414 mode_line_string_list = Qnil;
21415 staticpro (&mode_line_string_list);
21417 help_echo_string = Qnil;
21418 staticpro (&help_echo_string);
21419 help_echo_object = Qnil;
21420 staticpro (&help_echo_object);
21421 help_echo_window = Qnil;
21422 staticpro (&help_echo_window);
21423 previous_help_echo_string = Qnil;
21424 staticpro (&previous_help_echo_string);
21425 help_echo_pos = -1;
21427 #ifdef HAVE_WINDOW_SYSTEM
21428 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
21429 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
21430 For example, if a block cursor is over a tab, it will be drawn as
21431 wide as that tab on the display. */);
21432 x_stretch_cursor_p = 0;
21433 #endif
21435 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
21436 doc: /* *Non-nil means highlight trailing whitespace.
21437 The face used for trailing whitespace is `trailing-whitespace'. */);
21438 Vshow_trailing_whitespace = Qnil;
21440 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
21441 doc: /* *The pointer shape to show in void text areas.
21442 Nil means to show the text pointer. Other options are `arrow', `text',
21443 `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
21444 Vvoid_text_area_pointer = Qarrow;
21446 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
21447 doc: /* Non-nil means don't actually do any redisplay.
21448 This is used for internal purposes. */);
21449 Vinhibit_redisplay = Qnil;
21451 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
21452 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
21453 Vglobal_mode_string = Qnil;
21455 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
21456 doc: /* Marker for where to display an arrow on top of the buffer text.
21457 This must be the beginning of a line in order to work.
21458 See also `overlay-arrow-string'. */);
21459 Voverlay_arrow_position = Qnil;
21461 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
21462 doc: /* String to display as an arrow. See also `overlay-arrow-position'. */);
21463 Voverlay_arrow_string = Qnil;
21465 DEFVAR_INT ("scroll-step", &scroll_step,
21466 doc: /* *The number of lines to try scrolling a window by when point moves out.
21467 If that fails to bring point back on frame, point is centered instead.
21468 If this is zero, point is always centered after it moves off frame.
21469 If you want scrolling to always be a line at a time, you should set
21470 `scroll-conservatively' to a large value rather than set this to 1. */);
21472 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
21473 doc: /* *Scroll up to this many lines, to bring point back on screen.
21474 A value of zero means to scroll the text to center point vertically
21475 in the window. */);
21476 scroll_conservatively = 0;
21478 DEFVAR_INT ("scroll-margin", &scroll_margin,
21479 doc: /* *Number of lines of margin at the top and bottom of a window.
21480 Recenter the window whenever point gets within this many lines
21481 of the top or bottom of the window. */);
21482 scroll_margin = 0;
21484 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch,
21485 doc: /* Pixels per inch on current display.
21486 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
21487 Vdisplay_pixels_per_inch = make_float (72.0);
21489 #if GLYPH_DEBUG
21490 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
21491 #endif
21493 DEFVAR_BOOL ("truncate-partial-width-windows",
21494 &truncate_partial_width_windows,
21495 doc: /* *Non-nil means truncate lines in all windows less than full frame wide. */);
21496 truncate_partial_width_windows = 1;
21498 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
21499 doc: /* nil means display the mode-line/header-line/menu-bar in the default face.
21500 Any other value means to use the appropriate face, `mode-line',
21501 `header-line', or `menu' respectively. */);
21502 mode_line_inverse_video = 1;
21504 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
21505 doc: /* *Maximum buffer size for which line number should be displayed.
21506 If the buffer is bigger than this, the line number does not appear
21507 in the mode line. A value of nil means no limit. */);
21508 Vline_number_display_limit = Qnil;
21510 DEFVAR_INT ("line-number-display-limit-width",
21511 &line_number_display_limit_width,
21512 doc: /* *Maximum line width (in characters) for line number display.
21513 If the average length of the lines near point is bigger than this, then the
21514 line number may be omitted from the mode line. */);
21515 line_number_display_limit_width = 200;
21517 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
21518 doc: /* *Non-nil means highlight region even in nonselected windows. */);
21519 highlight_nonselected_windows = 0;
21521 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
21522 doc: /* Non-nil if more than one frame is visible on this display.
21523 Minibuffer-only frames don't count, but iconified frames do.
21524 This variable is not guaranteed to be accurate except while processing
21525 `frame-title-format' and `icon-title-format'. */);
21527 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
21528 doc: /* Template for displaying the title bar of visible frames.
21529 \(Assuming the window manager supports this feature.)
21530 This variable has the same structure as `mode-line-format' (which see),
21531 and is used only on frames for which no explicit name has been set
21532 \(see `modify-frame-parameters'). */);
21534 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
21535 doc: /* Template for displaying the title bar of an iconified frame.
21536 \(Assuming the window manager supports this feature.)
21537 This variable has the same structure as `mode-line-format' (which see),
21538 and is used only on frames for which no explicit name has been set
21539 \(see `modify-frame-parameters'). */);
21540 Vicon_title_format
21541 = Vframe_title_format
21542 = Fcons (intern ("multiple-frames"),
21543 Fcons (build_string ("%b"),
21544 Fcons (Fcons (empty_string,
21545 Fcons (intern ("invocation-name"),
21546 Fcons (build_string ("@"),
21547 Fcons (intern ("system-name"),
21548 Qnil)))),
21549 Qnil)));
21551 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
21552 doc: /* Maximum number of lines to keep in the message log buffer.
21553 If nil, disable message logging. If t, log messages but don't truncate
21554 the buffer when it becomes large. */);
21555 Vmessage_log_max = make_number (50);
21557 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
21558 doc: /* Functions called before redisplay, if window sizes have changed.
21559 The value should be a list of functions that take one argument.
21560 Just before redisplay, for each frame, if any of its windows have changed
21561 size since the last redisplay, or have been split or deleted,
21562 all the functions in the list are called, with the frame as argument. */);
21563 Vwindow_size_change_functions = Qnil;
21565 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
21566 doc: /* List of Functions to call before redisplaying a window with scrolling.
21567 Each function is called with two arguments, the window
21568 and its new display-start position. Note that the value of `window-end'
21569 is not valid when these functions are called. */);
21570 Vwindow_scroll_functions = Qnil;
21572 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window,
21573 doc: /* *Non-nil means autoselect window with mouse pointer. */);
21574 mouse_autoselect_window = 0;
21576 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
21577 doc: /* *Non-nil means automatically resize tool-bars.
21578 This increases a tool-bar's height if not all tool-bar items are visible.
21579 It decreases a tool-bar's height when it would display blank lines
21580 otherwise. */);
21581 auto_resize_tool_bars_p = 1;
21583 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
21584 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
21585 auto_raise_tool_bar_buttons_p = 1;
21587 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
21588 doc: /* *Margin around tool-bar buttons in pixels.
21589 If an integer, use that for both horizontal and vertical margins.
21590 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
21591 HORZ specifying the horizontal margin, and VERT specifying the
21592 vertical margin. */);
21593 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
21595 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
21596 doc: /* *Relief thickness of tool-bar buttons. */);
21597 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
21599 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
21600 doc: /* List of functions to call to fontify regions of text.
21601 Each function is called with one argument POS. Functions must
21602 fontify a region starting at POS in the current buffer, and give
21603 fontified regions the property `fontified'. */);
21604 Vfontification_functions = Qnil;
21605 Fmake_variable_buffer_local (Qfontification_functions);
21607 DEFVAR_BOOL ("unibyte-display-via-language-environment",
21608 &unibyte_display_via_language_environment,
21609 doc: /* *Non-nil means display unibyte text according to language environment.
21610 Specifically this means that unibyte non-ASCII characters
21611 are displayed by converting them to the equivalent multibyte characters
21612 according to the current language environment. As a result, they are
21613 displayed according to the current fontset. */);
21614 unibyte_display_via_language_environment = 0;
21616 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
21617 doc: /* *Maximum height for resizing mini-windows.
21618 If a float, it specifies a fraction of the mini-window frame's height.
21619 If an integer, it specifies a number of lines. */);
21620 Vmax_mini_window_height = make_float (0.25);
21622 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
21623 doc: /* *How to resize mini-windows.
21624 A value of nil means don't automatically resize mini-windows.
21625 A value of t means resize them to fit the text displayed in them.
21626 A value of `grow-only', the default, means let mini-windows grow
21627 only, until their display becomes empty, at which point the windows
21628 go back to their normal size. */);
21629 Vresize_mini_windows = Qgrow_only;
21631 DEFVAR_LISP ("cursor-in-non-selected-windows",
21632 &Vcursor_in_non_selected_windows,
21633 doc: /* *Cursor type to display in non-selected windows.
21634 t means to use hollow box cursor. See `cursor-type' for other values. */);
21635 Vcursor_in_non_selected_windows = Qt;
21637 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
21638 doc: /* Alist specifying how to blink the cursor off.
21639 Each element has the form (ON-STATE . OFF-STATE). Whenever the
21640 `cursor-type' frame-parameter or variable equals ON-STATE,
21641 comparing using `equal', Emacs uses OFF-STATE to specify
21642 how to blink it off. */);
21643 Vblink_cursor_alist = Qnil;
21645 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
21646 doc: /* *Non-nil means scroll the display automatically to make point visible. */);
21647 automatic_hscrolling_p = 1;
21649 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
21650 doc: /* *How many columns away from the window edge point is allowed to get
21651 before automatic hscrolling will horizontally scroll the window. */);
21652 hscroll_margin = 5;
21654 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
21655 doc: /* *How many columns to scroll the window when point gets too close to the edge.
21656 When point is less than `automatic-hscroll-margin' columns from the window
21657 edge, automatic hscrolling will scroll the window by the amount of columns
21658 determined by this variable. If its value is a positive integer, scroll that
21659 many columns. If it's a positive floating-point number, it specifies the
21660 fraction of the window's width to scroll. If it's nil or zero, point will be
21661 centered horizontally after the scroll. Any other value, including negative
21662 numbers, are treated as if the value were zero.
21664 Automatic hscrolling always moves point outside the scroll margin, so if
21665 point was more than scroll step columns inside the margin, the window will
21666 scroll more than the value given by the scroll step.
21668 Note that the lower bound for automatic hscrolling specified by `scroll-left'
21669 and `scroll-right' overrides this variable's effect. */);
21670 Vhscroll_step = make_number (0);
21672 DEFVAR_LISP ("image-types", &Vimage_types,
21673 doc: /* List of supported image types.
21674 Each element of the list is a symbol for a supported image type. */);
21675 Vimage_types = Qnil;
21677 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
21678 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
21679 Bind this around calls to `message' to let it take effect. */);
21680 message_truncate_lines = 0;
21682 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
21683 doc: /* Normal hook run for clicks on menu bar, before displaying a submenu.
21684 Can be used to update submenus whose contents should vary. */);
21685 Vmenu_bar_update_hook = Qnil;
21687 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
21688 doc: /* Non-nil means don't update menu bars. Internal use only. */);
21689 inhibit_menubar_update = 0;
21691 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
21692 doc: /* Non-nil means don't eval Lisp during redisplay. */);
21693 inhibit_eval_during_redisplay = 0;
21695 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
21696 doc: /* Non-nil means don't free realized faces. Internal use only. */);
21697 inhibit_free_realized_faces = 0;
21699 #if GLYPH_DEBUG
21700 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
21701 doc: /* Inhibit try_window_id display optimization. */);
21702 inhibit_try_window_id = 0;
21704 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
21705 doc: /* Inhibit try_window_reusing display optimization. */);
21706 inhibit_try_window_reusing = 0;
21708 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
21709 doc: /* Inhibit try_cursor_movement display optimization. */);
21710 inhibit_try_cursor_movement = 0;
21711 #endif /* GLYPH_DEBUG */
21715 /* Initialize this module when Emacs starts. */
21717 void
21718 init_xdisp ()
21720 Lisp_Object root_window;
21721 struct window *mini_w;
21723 current_header_line_height = current_mode_line_height = -1;
21725 CHARPOS (this_line_start_pos) = 0;
21727 mini_w = XWINDOW (minibuf_window);
21728 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
21730 if (!noninteractive)
21732 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
21733 int i;
21735 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
21736 set_window_height (root_window,
21737 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
21739 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
21740 set_window_height (minibuf_window, 1, 0);
21742 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
21743 mini_w->total_cols = make_number (FRAME_COLS (f));
21745 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
21746 scratch_glyph_row.glyphs[TEXT_AREA + 1]
21747 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
21749 /* The default ellipsis glyphs `...'. */
21750 for (i = 0; i < 3; ++i)
21751 default_invis_vector[i] = make_number ('.');
21755 /* Allocate the buffer for frame titles.
21756 Also used for `format-mode-line'. */
21757 int size = 100;
21758 frame_title_buf = (char *) xmalloc (size);
21759 frame_title_buf_end = frame_title_buf + size;
21760 frame_title_ptr = NULL;
21763 help_echo_showing_p = 0;
21767 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
21768 (do not change this comment) */