(doc-view-mode-map): Use remapping.
[emacs.git] / src / xdisp.c
blob43e5a953e509ec9f573e847d381bb021130e7656
1 /* Display generation from window structure and buffer text.
2 Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995,
3 1997, 1998, 1999, 2000, 2001, 2002, 2003,
4 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
6 This file is part of GNU Emacs.
8 GNU Emacs is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs; see the file COPYING. If not, write to
20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
23 /* New redisplay written by Gerd Moellmann <gerd@gnu.org>.
25 Redisplay.
27 Emacs separates the task of updating the display from code
28 modifying global state, e.g. buffer text. This way functions
29 operating on buffers don't also have to be concerned with updating
30 the display.
32 Updating the display is triggered by the Lisp interpreter when it
33 decides it's time to do it. This is done either automatically for
34 you as part of the interpreter's command loop or as the result of
35 calling Lisp functions like `sit-for'. The C function `redisplay'
36 in xdisp.c is the only entry into the inner redisplay code. (Or,
37 let's say almost---see the description of direct update
38 operations, below.)
40 The following diagram shows how redisplay code is invoked. As you
41 can see, Lisp calls redisplay and vice versa. Under window systems
42 like X, some portions of the redisplay code are also called
43 asynchronously during mouse movement or expose events. It is very
44 important that these code parts do NOT use the C library (malloc,
45 free) because many C libraries under Unix are not reentrant. They
46 may also NOT call functions of the Lisp interpreter which could
47 change the interpreter's state. If you don't follow these rules,
48 you will encounter bugs which are very hard to explain.
50 (Direct functions, see below)
51 direct_output_for_insert,
52 direct_forward_char (dispnew.c)
53 +---------------------------------+
54 | |
55 | V
56 +--------------+ redisplay +----------------+
57 | Lisp machine |---------------->| Redisplay code |<--+
58 +--------------+ (xdisp.c) +----------------+ |
59 ^ | |
60 +----------------------------------+ |
61 Don't use this path when called |
62 asynchronously! |
64 expose_window (asynchronous) |
66 X expose events -----+
68 What does redisplay do? Obviously, it has to figure out somehow what
69 has been changed since the last time the display has been updated,
70 and to make these changes visible. Preferably it would do that in
71 a moderately intelligent way, i.e. fast.
73 Changes in buffer text can be deduced from window and buffer
74 structures, and from some global variables like `beg_unchanged' and
75 `end_unchanged'. The contents of the display are additionally
76 recorded in a `glyph matrix', a two-dimensional matrix of glyph
77 structures. Each row in such a matrix corresponds to a line on the
78 display, and each glyph in a row corresponds to a column displaying
79 a character, an image, or what else. This matrix is called the
80 `current glyph matrix' or `current matrix' in redisplay
81 terminology.
83 For buffer parts that have been changed since the last update, a
84 second glyph matrix is constructed, the so called `desired glyph
85 matrix' or short `desired matrix'. Current and desired matrix are
86 then compared to find a cheap way to update the display, e.g. by
87 reusing part of the display by scrolling lines.
90 Direct operations.
92 You will find a lot of redisplay optimizations when you start
93 looking at the innards of redisplay. The overall goal of all these
94 optimizations is to make redisplay fast because it is done
95 frequently.
97 Two optimizations are not found in xdisp.c. These are the direct
98 operations mentioned above. As the name suggests they follow a
99 different principle than the rest of redisplay. Instead of
100 building a desired matrix and then comparing it with the current
101 display, they perform their actions directly on the display and on
102 the current matrix.
104 One direct operation updates the display after one character has
105 been entered. The other one moves the cursor by one position
106 forward or backward. You find these functions under the names
107 `direct_output_for_insert' and `direct_output_forward_char' in
108 dispnew.c.
111 Desired matrices.
113 Desired matrices are always built per Emacs window. The function
114 `display_line' is the central function to look at if you are
115 interested. It constructs one row in a desired matrix given an
116 iterator structure containing both a buffer position and a
117 description of the environment in which the text is to be
118 displayed. But this is too early, read on.
120 Characters and pixmaps displayed for a range of buffer text depend
121 on various settings of buffers and windows, on overlays and text
122 properties, on display tables, on selective display. The good news
123 is that all this hairy stuff is hidden behind a small set of
124 interface functions taking an iterator structure (struct it)
125 argument.
127 Iteration over things to be displayed is then simple. It is
128 started by initializing an iterator with a call to init_iterator.
129 Calls to get_next_display_element fill the iterator structure with
130 relevant information about the next thing to display. Calls to
131 set_iterator_to_next move the iterator to the next thing.
133 Besides this, an iterator also contains information about the
134 display environment in which glyphs for display elements are to be
135 produced. It has fields for the width and height of the display,
136 the information whether long lines are truncated or continued, a
137 current X and Y position, and lots of other stuff you can better
138 see in dispextern.h.
140 Glyphs in a desired matrix are normally constructed in a loop
141 calling get_next_display_element and then produce_glyphs. The call
142 to produce_glyphs will fill the iterator structure with pixel
143 information about the element being displayed and at the same time
144 produce glyphs for it. If the display element fits on the line
145 being displayed, set_iterator_to_next is called next, otherwise the
146 glyphs produced are discarded.
149 Frame matrices.
151 That just couldn't be all, could it? What about terminal types not
152 supporting operations on sub-windows of the screen? To update the
153 display on such a terminal, window-based glyph matrices are not
154 well suited. To be able to reuse part of the display (scrolling
155 lines up and down), we must instead have a view of the whole
156 screen. This is what `frame matrices' are for. They are a trick.
158 Frames on terminals like above have a glyph pool. Windows on such
159 a frame sub-allocate their glyph memory from their frame's glyph
160 pool. The frame itself is given its own glyph matrices. By
161 coincidence---or maybe something else---rows in window glyph
162 matrices are slices of corresponding rows in frame matrices. Thus
163 writing to window matrices implicitly updates a frame matrix which
164 provides us with the view of the whole screen that we originally
165 wanted to have without having to move many bytes around. To be
166 honest, there is a little bit more done, but not much more. If you
167 plan to extend that code, take a look at dispnew.c. The function
168 build_frame_matrix is a good starting point. */
170 #include <config.h>
171 #include <stdio.h>
173 #include "lisp.h"
174 #include "keyboard.h"
175 #include "frame.h"
176 #include "window.h"
177 #include "termchar.h"
178 #include "dispextern.h"
179 #include "buffer.h"
180 #include "charset.h"
181 #include "indent.h"
182 #include "commands.h"
183 #include "keymap.h"
184 #include "macros.h"
185 #include "disptab.h"
186 #include "termhooks.h"
187 #include "intervals.h"
188 #include "coding.h"
189 #include "process.h"
190 #include "region-cache.h"
191 #include "fontset.h"
192 #include "blockinput.h"
194 #ifdef HAVE_X_WINDOWS
195 #include "xterm.h"
196 #endif
197 #ifdef WINDOWSNT
198 #include "w32term.h"
199 #endif
200 #ifdef MAC_OS
201 #include "macterm.h"
202 #endif
204 #ifndef FRAME_X_OUTPUT
205 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
206 #endif
208 #define INFINITY 10000000
210 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
211 || defined (USE_GTK)
212 extern void set_frame_menubar P_ ((struct frame *f, int, int));
213 extern int pending_menu_activation;
214 #endif
216 extern int interrupt_input;
217 extern int command_loop_level;
219 extern Lisp_Object do_mouse_tracking;
221 extern int minibuffer_auto_raise;
222 extern Lisp_Object Vminibuffer_list;
224 extern Lisp_Object Qface;
225 extern Lisp_Object Qmode_line, Qmode_line_inactive, Qheader_line;
227 extern Lisp_Object Voverriding_local_map;
228 extern Lisp_Object Voverriding_local_map_menu_flag;
229 extern Lisp_Object Qmenu_item;
230 extern Lisp_Object Qwhen;
231 extern Lisp_Object Qhelp_echo;
233 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
234 Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
235 Lisp_Object Qredisplay_end_trigger_functions, Vredisplay_end_trigger_functions;
236 Lisp_Object Qinhibit_point_motion_hooks;
237 Lisp_Object QCeval, QCfile, QCdata, QCpropertize;
238 Lisp_Object Qfontified;
239 Lisp_Object Qgrow_only;
240 Lisp_Object Qinhibit_eval_during_redisplay;
241 Lisp_Object Qbuffer_position, Qposition, Qobject;
243 /* Cursor shapes */
244 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
246 /* Pointer shapes */
247 Lisp_Object Qarrow, Qhand, Qtext;
249 Lisp_Object Qrisky_local_variable;
251 /* Holds the list (error). */
252 Lisp_Object list_of_error;
254 /* Functions called to fontify regions of text. */
256 Lisp_Object Vfontification_functions;
257 Lisp_Object Qfontification_functions;
259 /* Non-nil means automatically select any window when the mouse
260 cursor moves into it. */
261 Lisp_Object Vmouse_autoselect_window;
263 /* Non-zero means draw tool bar buttons raised when the mouse moves
264 over them. */
266 int auto_raise_tool_bar_buttons_p;
268 /* Non-zero means to reposition window if cursor line is only partially visible. */
270 int make_cursor_line_fully_visible_p;
272 /* Margin below tool bar in pixels. 0 or nil means no margin.
273 If value is `internal-border-width' or `border-width',
274 the corresponding frame parameter is used. */
276 Lisp_Object Vtool_bar_border;
278 /* Margin around tool bar buttons in pixels. */
280 Lisp_Object Vtool_bar_button_margin;
282 /* Thickness of shadow to draw around tool bar buttons. */
284 EMACS_INT tool_bar_button_relief;
286 /* Non-nil means automatically resize tool-bars so that all tool-bar
287 items are visible, and no blank lines remain.
289 If value is `grow-only', only make tool-bar bigger. */
291 Lisp_Object Vauto_resize_tool_bars;
293 /* Non-zero means draw block and hollow cursor as wide as the glyph
294 under it. For example, if a block cursor is over a tab, it will be
295 drawn as wide as that tab on the display. */
297 int x_stretch_cursor_p;
299 /* Non-nil means don't actually do any redisplay. */
301 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
303 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
305 int inhibit_eval_during_redisplay;
307 /* Names of text properties relevant for redisplay. */
309 Lisp_Object Qdisplay;
310 extern Lisp_Object Qface, Qinvisible, Qwidth;
312 /* Symbols used in text property values. */
314 Lisp_Object Vdisplay_pixels_per_inch;
315 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
316 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
317 Lisp_Object Qslice;
318 Lisp_Object Qcenter;
319 Lisp_Object Qmargin, Qpointer;
320 Lisp_Object Qline_height;
321 extern Lisp_Object Qheight;
322 extern Lisp_Object QCwidth, QCheight, QCascent;
323 extern Lisp_Object Qscroll_bar;
324 extern Lisp_Object Qcursor;
326 /* Non-nil means highlight trailing whitespace. */
328 Lisp_Object Vshow_trailing_whitespace;
330 /* Non-nil means escape non-break space and hyphens. */
332 Lisp_Object Vnobreak_char_display;
334 #ifdef HAVE_WINDOW_SYSTEM
335 extern Lisp_Object Voverflow_newline_into_fringe;
337 /* Test if overflow newline into fringe. Called with iterator IT
338 at or past right window margin, and with IT->current_x set. */
340 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) \
341 (!NILP (Voverflow_newline_into_fringe) \
342 && FRAME_WINDOW_P (it->f) \
343 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
344 && it->current_x == it->last_visible_x)
346 #endif /* HAVE_WINDOW_SYSTEM */
348 /* Non-nil means show the text cursor in void text areas
349 i.e. in blank areas after eol and eob. This used to be
350 the default in 21.3. */
352 Lisp_Object Vvoid_text_area_pointer;
354 /* Name of the face used to highlight trailing whitespace. */
356 Lisp_Object Qtrailing_whitespace;
358 /* Name and number of the face used to highlight escape glyphs. */
360 Lisp_Object Qescape_glyph;
362 /* Name and number of the face used to highlight non-breaking spaces. */
364 Lisp_Object Qnobreak_space;
366 /* The symbol `image' which is the car of the lists used to represent
367 images in Lisp. */
369 Lisp_Object Qimage;
371 /* The image map types. */
372 Lisp_Object QCmap, QCpointer;
373 Lisp_Object Qrect, Qcircle, Qpoly;
375 /* Non-zero means print newline to stdout before next mini-buffer
376 message. */
378 int noninteractive_need_newline;
380 /* Non-zero means print newline to message log before next message. */
382 static int message_log_need_newline;
384 /* Three markers that message_dolog uses.
385 It could allocate them itself, but that causes trouble
386 in handling memory-full errors. */
387 static Lisp_Object message_dolog_marker1;
388 static Lisp_Object message_dolog_marker2;
389 static Lisp_Object message_dolog_marker3;
391 /* The buffer position of the first character appearing entirely or
392 partially on the line of the selected window which contains the
393 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
394 redisplay optimization in redisplay_internal. */
396 static struct text_pos this_line_start_pos;
398 /* Number of characters past the end of the line above, including the
399 terminating newline. */
401 static struct text_pos this_line_end_pos;
403 /* The vertical positions and the height of this line. */
405 static int this_line_vpos;
406 static int this_line_y;
407 static int this_line_pixel_height;
409 /* X position at which this display line starts. Usually zero;
410 negative if first character is partially visible. */
412 static int this_line_start_x;
414 /* Buffer that this_line_.* variables are referring to. */
416 static struct buffer *this_line_buffer;
418 /* Nonzero means truncate lines in all windows less wide than the
419 frame. */
421 int truncate_partial_width_windows;
423 /* A flag to control how to display unibyte 8-bit character. */
425 int unibyte_display_via_language_environment;
427 /* Nonzero means we have more than one non-mini-buffer-only frame.
428 Not guaranteed to be accurate except while parsing
429 frame-title-format. */
431 int multiple_frames;
433 Lisp_Object Vglobal_mode_string;
436 /* List of variables (symbols) which hold markers for overlay arrows.
437 The symbols on this list are examined during redisplay to determine
438 where to display overlay arrows. */
440 Lisp_Object Voverlay_arrow_variable_list;
442 /* Marker for where to display an arrow on top of the buffer text. */
444 Lisp_Object Voverlay_arrow_position;
446 /* String to display for the arrow. Only used on terminal frames. */
448 Lisp_Object Voverlay_arrow_string;
450 /* Values of those variables at last redisplay are stored as
451 properties on `overlay-arrow-position' symbol. However, if
452 Voverlay_arrow_position is a marker, last-arrow-position is its
453 numerical position. */
455 Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
457 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
458 properties on a symbol in overlay-arrow-variable-list. */
460 Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
462 /* Like mode-line-format, but for the title bar on a visible frame. */
464 Lisp_Object Vframe_title_format;
466 /* Like mode-line-format, but for the title bar on an iconified frame. */
468 Lisp_Object Vicon_title_format;
470 /* List of functions to call when a window's size changes. These
471 functions get one arg, a frame on which one or more windows' sizes
472 have changed. */
474 static Lisp_Object Vwindow_size_change_functions;
476 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
478 /* Nonzero if an overlay arrow has been displayed in this window. */
480 static int overlay_arrow_seen;
482 /* Nonzero means highlight the region even in nonselected windows. */
484 int highlight_nonselected_windows;
486 /* If cursor motion alone moves point off frame, try scrolling this
487 many lines up or down if that will bring it back. */
489 static EMACS_INT scroll_step;
491 /* Nonzero means scroll just far enough to bring point back on the
492 screen, when appropriate. */
494 static EMACS_INT scroll_conservatively;
496 /* Recenter the window whenever point gets within this many lines of
497 the top or bottom of the window. This value is translated into a
498 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
499 that there is really a fixed pixel height scroll margin. */
501 EMACS_INT scroll_margin;
503 /* Number of windows showing the buffer of the selected window (or
504 another buffer with the same base buffer). keyboard.c refers to
505 this. */
507 int buffer_shared;
509 /* Vector containing glyphs for an ellipsis `...'. */
511 static Lisp_Object default_invis_vector[3];
513 /* Zero means display the mode-line/header-line/menu-bar in the default face
514 (this slightly odd definition is for compatibility with previous versions
515 of emacs), non-zero means display them using their respective faces.
517 This variable is deprecated. */
519 int mode_line_inverse_video;
521 /* Prompt to display in front of the mini-buffer contents. */
523 Lisp_Object minibuf_prompt;
525 /* Width of current mini-buffer prompt. Only set after display_line
526 of the line that contains the prompt. */
528 int minibuf_prompt_width;
530 /* This is the window where the echo area message was displayed. It
531 is always a mini-buffer window, but it may not be the same window
532 currently active as a mini-buffer. */
534 Lisp_Object echo_area_window;
536 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
537 pushes the current message and the value of
538 message_enable_multibyte on the stack, the function restore_message
539 pops the stack and displays MESSAGE again. */
541 Lisp_Object Vmessage_stack;
543 /* Nonzero means multibyte characters were enabled when the echo area
544 message was specified. */
546 int message_enable_multibyte;
548 /* Nonzero if we should redraw the mode lines on the next redisplay. */
550 int update_mode_lines;
552 /* Nonzero if window sizes or contents have changed since last
553 redisplay that finished. */
555 int windows_or_buffers_changed;
557 /* Nonzero means a frame's cursor type has been changed. */
559 int cursor_type_changed;
561 /* Nonzero after display_mode_line if %l was used and it displayed a
562 line number. */
564 int line_number_displayed;
566 /* Maximum buffer size for which to display line numbers. */
568 Lisp_Object Vline_number_display_limit;
570 /* Line width to consider when repositioning for line number display. */
572 static EMACS_INT line_number_display_limit_width;
574 /* Number of lines to keep in the message log buffer. t means
575 infinite. nil means don't log at all. */
577 Lisp_Object Vmessage_log_max;
579 /* The name of the *Messages* buffer, a string. */
581 static Lisp_Object Vmessages_buffer_name;
583 /* Current, index 0, and last displayed echo area message. Either
584 buffers from echo_buffers, or nil to indicate no message. */
586 Lisp_Object echo_area_buffer[2];
588 /* The buffers referenced from echo_area_buffer. */
590 static Lisp_Object echo_buffer[2];
592 /* A vector saved used in with_area_buffer to reduce consing. */
594 static Lisp_Object Vwith_echo_area_save_vector;
596 /* Non-zero means display_echo_area should display the last echo area
597 message again. Set by redisplay_preserve_echo_area. */
599 static int display_last_displayed_message_p;
601 /* Nonzero if echo area is being used by print; zero if being used by
602 message. */
604 int message_buf_print;
606 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
608 Lisp_Object Qinhibit_menubar_update;
609 int inhibit_menubar_update;
611 /* When evaluating expressions from menu bar items (enable conditions,
612 for instance), this is the frame they are being processed for. */
614 Lisp_Object Vmenu_updating_frame;
616 /* Maximum height for resizing mini-windows. Either a float
617 specifying a fraction of the available height, or an integer
618 specifying a number of lines. */
620 Lisp_Object Vmax_mini_window_height;
622 /* Non-zero means messages should be displayed with truncated
623 lines instead of being continued. */
625 int message_truncate_lines;
626 Lisp_Object Qmessage_truncate_lines;
628 /* Set to 1 in clear_message to make redisplay_internal aware
629 of an emptied echo area. */
631 static int message_cleared_p;
633 /* How to blink the default frame cursor off. */
634 Lisp_Object Vblink_cursor_alist;
636 /* A scratch glyph row with contents used for generating truncation
637 glyphs. Also used in direct_output_for_insert. */
639 #define MAX_SCRATCH_GLYPHS 100
640 struct glyph_row scratch_glyph_row;
641 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
643 /* Ascent and height of the last line processed by move_it_to. */
645 static int last_max_ascent, last_height;
647 /* Non-zero if there's a help-echo in the echo area. */
649 int help_echo_showing_p;
651 /* If >= 0, computed, exact values of mode-line and header-line height
652 to use in the macros CURRENT_MODE_LINE_HEIGHT and
653 CURRENT_HEADER_LINE_HEIGHT. */
655 int current_mode_line_height, current_header_line_height;
657 /* The maximum distance to look ahead for text properties. Values
658 that are too small let us call compute_char_face and similar
659 functions too often which is expensive. Values that are too large
660 let us call compute_char_face and alike too often because we
661 might not be interested in text properties that far away. */
663 #define TEXT_PROP_DISTANCE_LIMIT 100
665 #if GLYPH_DEBUG
667 /* Variables to turn off display optimizations from Lisp. */
669 int inhibit_try_window_id, inhibit_try_window_reusing;
670 int inhibit_try_cursor_movement;
672 /* Non-zero means print traces of redisplay if compiled with
673 GLYPH_DEBUG != 0. */
675 int trace_redisplay_p;
677 #endif /* GLYPH_DEBUG */
679 #ifdef DEBUG_TRACE_MOVE
680 /* Non-zero means trace with TRACE_MOVE to stderr. */
681 int trace_move;
683 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
684 #else
685 #define TRACE_MOVE(x) (void) 0
686 #endif
688 /* Non-zero means automatically scroll windows horizontally to make
689 point visible. */
691 int automatic_hscrolling_p;
693 /* How close to the margin can point get before the window is scrolled
694 horizontally. */
695 EMACS_INT hscroll_margin;
697 /* How much to scroll horizontally when point is inside the above margin. */
698 Lisp_Object Vhscroll_step;
700 /* The variable `resize-mini-windows'. If nil, don't resize
701 mini-windows. If t, always resize them to fit the text they
702 display. If `grow-only', let mini-windows grow only until they
703 become empty. */
705 Lisp_Object Vresize_mini_windows;
707 /* Buffer being redisplayed -- for redisplay_window_error. */
709 struct buffer *displayed_buffer;
711 /* Space between overline and text. */
713 EMACS_INT overline_margin;
715 /* Value returned from text property handlers (see below). */
717 enum prop_handled
719 HANDLED_NORMALLY,
720 HANDLED_RECOMPUTE_PROPS,
721 HANDLED_OVERLAY_STRING_CONSUMED,
722 HANDLED_RETURN
725 /* A description of text properties that redisplay is interested
726 in. */
728 struct props
730 /* The name of the property. */
731 Lisp_Object *name;
733 /* A unique index for the property. */
734 enum prop_idx idx;
736 /* A handler function called to set up iterator IT from the property
737 at IT's current position. Value is used to steer handle_stop. */
738 enum prop_handled (*handler) P_ ((struct it *it));
741 static enum prop_handled handle_face_prop P_ ((struct it *));
742 static enum prop_handled handle_invisible_prop P_ ((struct it *));
743 static enum prop_handled handle_display_prop P_ ((struct it *));
744 static enum prop_handled handle_composition_prop P_ ((struct it *));
745 static enum prop_handled handle_overlay_change P_ ((struct it *));
746 static enum prop_handled handle_fontified_prop P_ ((struct it *));
748 /* Properties handled by iterators. */
750 static struct props it_props[] =
752 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
753 /* Handle `face' before `display' because some sub-properties of
754 `display' need to know the face. */
755 {&Qface, FACE_PROP_IDX, handle_face_prop},
756 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
757 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
758 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
759 {NULL, 0, NULL}
762 /* Value is the position described by X. If X is a marker, value is
763 the marker_position of X. Otherwise, value is X. */
765 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
767 /* Enumeration returned by some move_it_.* functions internally. */
769 enum move_it_result
771 /* Not used. Undefined value. */
772 MOVE_UNDEFINED,
774 /* Move ended at the requested buffer position or ZV. */
775 MOVE_POS_MATCH_OR_ZV,
777 /* Move ended at the requested X pixel position. */
778 MOVE_X_REACHED,
780 /* Move within a line ended at the end of a line that must be
781 continued. */
782 MOVE_LINE_CONTINUED,
784 /* Move within a line ended at the end of a line that would
785 be displayed truncated. */
786 MOVE_LINE_TRUNCATED,
788 /* Move within a line ended at a line end. */
789 MOVE_NEWLINE_OR_CR
792 /* This counter is used to clear the face cache every once in a while
793 in redisplay_internal. It is incremented for each redisplay.
794 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
795 cleared. */
797 #define CLEAR_FACE_CACHE_COUNT 500
798 static int clear_face_cache_count;
800 /* Similarly for the image cache. */
802 #ifdef HAVE_WINDOW_SYSTEM
803 #define CLEAR_IMAGE_CACHE_COUNT 101
804 static int clear_image_cache_count;
805 #endif
807 /* Non-zero while redisplay_internal is in progress. */
809 int redisplaying_p;
811 /* Non-zero means don't free realized faces. Bound while freeing
812 realized faces is dangerous because glyph matrices might still
813 reference them. */
815 int inhibit_free_realized_faces;
816 Lisp_Object Qinhibit_free_realized_faces;
818 /* If a string, XTread_socket generates an event to display that string.
819 (The display is done in read_char.) */
821 Lisp_Object help_echo_string;
822 Lisp_Object help_echo_window;
823 Lisp_Object help_echo_object;
824 int help_echo_pos;
826 /* Temporary variable for XTread_socket. */
828 Lisp_Object previous_help_echo_string;
830 /* Null glyph slice */
832 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
835 /* Function prototypes. */
837 static void setup_for_ellipsis P_ ((struct it *, int));
838 static void mark_window_display_accurate_1 P_ ((struct window *, int));
839 static int single_display_spec_string_p P_ ((Lisp_Object, Lisp_Object));
840 static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
841 static int cursor_row_p P_ ((struct window *, struct glyph_row *));
842 static int redisplay_mode_lines P_ ((Lisp_Object, int));
843 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
845 #if 0
846 static int invisible_text_between_p P_ ((struct it *, int, int));
847 #endif
849 static void pint2str P_ ((char *, int, int));
850 static void pint2hrstr P_ ((char *, int, int));
851 static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
852 struct text_pos));
853 static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
854 static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
855 static void store_mode_line_noprop_char P_ ((char));
856 static int store_mode_line_noprop P_ ((const unsigned char *, int, int));
857 static void x_consider_frame_title P_ ((Lisp_Object));
858 static void handle_stop P_ ((struct it *));
859 static int tool_bar_lines_needed P_ ((struct frame *, int *));
860 static int single_display_spec_intangible_p P_ ((Lisp_Object));
861 static void ensure_echo_area_buffers P_ ((void));
862 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
863 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
864 static int with_echo_area_buffer P_ ((struct window *, int,
865 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
866 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
867 static void clear_garbaged_frames P_ ((void));
868 static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
869 static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
870 static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
871 static int display_echo_area P_ ((struct window *));
872 static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
873 static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
874 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
875 static int string_char_and_length P_ ((const unsigned char *, int, int *));
876 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
877 struct text_pos));
878 static int compute_window_start_on_continuation_line P_ ((struct window *));
879 static Lisp_Object safe_eval_handler P_ ((Lisp_Object));
880 static void insert_left_trunc_glyphs P_ ((struct it *));
881 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *,
882 Lisp_Object));
883 static void extend_face_to_end_of_line P_ ((struct it *));
884 static int append_space_for_newline P_ ((struct it *, int));
885 static int cursor_row_fully_visible_p P_ ((struct window *, int, int));
886 static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
887 static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
888 static int trailing_whitespace_p P_ ((int));
889 static int message_log_check_duplicate P_ ((int, int, int, int));
890 static void push_it P_ ((struct it *));
891 static void pop_it P_ ((struct it *));
892 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
893 static void select_frame_for_redisplay P_ ((Lisp_Object));
894 static void redisplay_internal P_ ((int));
895 static int echo_area_display P_ ((int));
896 static void redisplay_windows P_ ((Lisp_Object));
897 static void redisplay_window P_ ((Lisp_Object, int));
898 static Lisp_Object redisplay_window_error ();
899 static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
900 static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
901 static int update_menu_bar P_ ((struct frame *, int, int));
902 static int try_window_reusing_current_matrix P_ ((struct window *));
903 static int try_window_id P_ ((struct window *));
904 static int display_line P_ ((struct it *));
905 static int display_mode_lines P_ ((struct window *));
906 static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
907 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
908 static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
909 static char *decode_mode_spec P_ ((struct window *, int, int, int, int *));
910 static void display_menu_bar P_ ((struct window *));
911 static int display_count_lines P_ ((int, int, int, int, int *));
912 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
913 int, int, struct it *, int, int, int, int));
914 static void compute_line_metrics P_ ((struct it *));
915 static void run_redisplay_end_trigger_hook P_ ((struct it *));
916 static int get_overlay_strings P_ ((struct it *, int));
917 static int get_overlay_strings_1 P_ ((struct it *, int, int));
918 static void next_overlay_string P_ ((struct it *));
919 static void reseat P_ ((struct it *, struct text_pos, int));
920 static void reseat_1 P_ ((struct it *, struct text_pos, int));
921 static void back_to_previous_visible_line_start P_ ((struct it *));
922 void reseat_at_previous_visible_line_start P_ ((struct it *));
923 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
924 static int next_element_from_ellipsis P_ ((struct it *));
925 static int next_element_from_display_vector P_ ((struct it *));
926 static int next_element_from_string P_ ((struct it *));
927 static int next_element_from_c_string P_ ((struct it *));
928 static int next_element_from_buffer P_ ((struct it *));
929 static int next_element_from_composition P_ ((struct it *));
930 static int next_element_from_image P_ ((struct it *));
931 static int next_element_from_stretch P_ ((struct it *));
932 static void load_overlay_strings P_ ((struct it *, int));
933 static int init_from_display_pos P_ ((struct it *, struct window *,
934 struct display_pos *));
935 static void reseat_to_string P_ ((struct it *, unsigned char *,
936 Lisp_Object, int, int, int, int));
937 static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
938 int, int, int));
939 void move_it_vertically_backward P_ ((struct it *, int));
940 static void init_to_row_start P_ ((struct it *, struct window *,
941 struct glyph_row *));
942 static int init_to_row_end P_ ((struct it *, struct window *,
943 struct glyph_row *));
944 static void back_to_previous_line_start P_ ((struct it *));
945 static int forward_to_next_line_start P_ ((struct it *, int *));
946 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
947 Lisp_Object, int));
948 static struct text_pos string_pos P_ ((int, Lisp_Object));
949 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
950 static int number_of_chars P_ ((unsigned char *, int));
951 static void compute_stop_pos P_ ((struct it *));
952 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
953 Lisp_Object));
954 static int face_before_or_after_it_pos P_ ((struct it *, int));
955 static int next_overlay_change P_ ((int));
956 static int handle_single_display_spec P_ ((struct it *, Lisp_Object,
957 Lisp_Object, struct text_pos *,
958 int));
959 static int underlying_face_id P_ ((struct it *));
960 static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
961 struct window *));
963 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
964 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
966 #ifdef HAVE_WINDOW_SYSTEM
968 static void update_tool_bar P_ ((struct frame *, int));
969 static void build_desired_tool_bar_string P_ ((struct frame *f));
970 static int redisplay_tool_bar P_ ((struct frame *));
971 static void display_tool_bar_line P_ ((struct it *, int));
972 static void notice_overwritten_cursor P_ ((struct window *,
973 enum glyph_row_area,
974 int, int, int, int));
978 #endif /* HAVE_WINDOW_SYSTEM */
981 /***********************************************************************
982 Window display dimensions
983 ***********************************************************************/
985 /* Return the bottom boundary y-position for text lines in window W.
986 This is the first y position at which a line cannot start.
987 It is relative to the top of the window.
989 This is the height of W minus the height of a mode line, if any. */
991 INLINE int
992 window_text_bottom_y (w)
993 struct window *w;
995 int height = WINDOW_TOTAL_HEIGHT (w);
997 if (WINDOW_WANTS_MODELINE_P (w))
998 height -= CURRENT_MODE_LINE_HEIGHT (w);
999 return height;
1002 /* Return the pixel width of display area AREA of window W. AREA < 0
1003 means return the total width of W, not including fringes to
1004 the left and right of the window. */
1006 INLINE int
1007 window_box_width (w, area)
1008 struct window *w;
1009 int area;
1011 int cols = XFASTINT (w->total_cols);
1012 int pixels = 0;
1014 if (!w->pseudo_window_p)
1016 cols -= WINDOW_SCROLL_BAR_COLS (w);
1018 if (area == TEXT_AREA)
1020 if (INTEGERP (w->left_margin_cols))
1021 cols -= XFASTINT (w->left_margin_cols);
1022 if (INTEGERP (w->right_margin_cols))
1023 cols -= XFASTINT (w->right_margin_cols);
1024 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
1026 else if (area == LEFT_MARGIN_AREA)
1028 cols = (INTEGERP (w->left_margin_cols)
1029 ? XFASTINT (w->left_margin_cols) : 0);
1030 pixels = 0;
1032 else if (area == RIGHT_MARGIN_AREA)
1034 cols = (INTEGERP (w->right_margin_cols)
1035 ? XFASTINT (w->right_margin_cols) : 0);
1036 pixels = 0;
1040 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1044 /* Return the pixel height of the display area of window W, not
1045 including mode lines of W, if any. */
1047 INLINE int
1048 window_box_height (w)
1049 struct window *w;
1051 struct frame *f = XFRAME (w->frame);
1052 int height = WINDOW_TOTAL_HEIGHT (w);
1054 xassert (height >= 0);
1056 /* Note: the code below that determines the mode-line/header-line
1057 height is essentially the same as that contained in the macro
1058 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1059 the appropriate glyph row has its `mode_line_p' flag set,
1060 and if it doesn't, uses estimate_mode_line_height instead. */
1062 if (WINDOW_WANTS_MODELINE_P (w))
1064 struct glyph_row *ml_row
1065 = (w->current_matrix && w->current_matrix->rows
1066 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1067 : 0);
1068 if (ml_row && ml_row->mode_line_p)
1069 height -= ml_row->height;
1070 else
1071 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1074 if (WINDOW_WANTS_HEADER_LINE_P (w))
1076 struct glyph_row *hl_row
1077 = (w->current_matrix && w->current_matrix->rows
1078 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1079 : 0);
1080 if (hl_row && hl_row->mode_line_p)
1081 height -= hl_row->height;
1082 else
1083 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1086 /* With a very small font and a mode-line that's taller than
1087 default, we might end up with a negative height. */
1088 return max (0, height);
1091 /* Return the window-relative coordinate of the left edge of display
1092 area AREA of window W. AREA < 0 means return the left edge of the
1093 whole window, to the right of the left fringe of W. */
1095 INLINE int
1096 window_box_left_offset (w, area)
1097 struct window *w;
1098 int area;
1100 int x;
1102 if (w->pseudo_window_p)
1103 return 0;
1105 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1107 if (area == TEXT_AREA)
1108 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1109 + window_box_width (w, LEFT_MARGIN_AREA));
1110 else if (area == RIGHT_MARGIN_AREA)
1111 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1112 + window_box_width (w, LEFT_MARGIN_AREA)
1113 + window_box_width (w, TEXT_AREA)
1114 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1116 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1117 else if (area == LEFT_MARGIN_AREA
1118 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1119 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1121 return x;
1125 /* Return the window-relative coordinate of the right edge of display
1126 area AREA of window W. AREA < 0 means return the left edge of the
1127 whole window, to the left of the right fringe of W. */
1129 INLINE int
1130 window_box_right_offset (w, area)
1131 struct window *w;
1132 int area;
1134 return window_box_left_offset (w, area) + window_box_width (w, area);
1137 /* Return the frame-relative coordinate of the left edge of display
1138 area AREA of window W. AREA < 0 means return the left edge of the
1139 whole window, to the right of the left fringe of W. */
1141 INLINE int
1142 window_box_left (w, area)
1143 struct window *w;
1144 int area;
1146 struct frame *f = XFRAME (w->frame);
1147 int x;
1149 if (w->pseudo_window_p)
1150 return FRAME_INTERNAL_BORDER_WIDTH (f);
1152 x = (WINDOW_LEFT_EDGE_X (w)
1153 + window_box_left_offset (w, area));
1155 return x;
1159 /* Return the frame-relative coordinate of the right edge of display
1160 area AREA of window W. AREA < 0 means return the left edge of the
1161 whole window, to the left of the right fringe of W. */
1163 INLINE int
1164 window_box_right (w, area)
1165 struct window *w;
1166 int area;
1168 return window_box_left (w, area) + window_box_width (w, area);
1171 /* Get the bounding box of the display area AREA of window W, without
1172 mode lines, in frame-relative coordinates. AREA < 0 means the
1173 whole window, not including the left and right fringes of
1174 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1175 coordinates of the upper-left corner of the box. Return in
1176 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1178 INLINE void
1179 window_box (w, area, box_x, box_y, box_width, box_height)
1180 struct window *w;
1181 int area;
1182 int *box_x, *box_y, *box_width, *box_height;
1184 if (box_width)
1185 *box_width = window_box_width (w, area);
1186 if (box_height)
1187 *box_height = window_box_height (w);
1188 if (box_x)
1189 *box_x = window_box_left (w, area);
1190 if (box_y)
1192 *box_y = WINDOW_TOP_EDGE_Y (w);
1193 if (WINDOW_WANTS_HEADER_LINE_P (w))
1194 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1199 /* Get the bounding box of the display area AREA of window W, without
1200 mode lines. AREA < 0 means the whole window, not including the
1201 left and right fringe of the window. Return in *TOP_LEFT_X
1202 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1203 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1204 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1205 box. */
1207 INLINE void
1208 window_box_edges (w, area, top_left_x, top_left_y,
1209 bottom_right_x, bottom_right_y)
1210 struct window *w;
1211 int area;
1212 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
1214 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1215 bottom_right_y);
1216 *bottom_right_x += *top_left_x;
1217 *bottom_right_y += *top_left_y;
1222 /***********************************************************************
1223 Utilities
1224 ***********************************************************************/
1226 /* Return the bottom y-position of the line the iterator IT is in.
1227 This can modify IT's settings. */
1230 line_bottom_y (it)
1231 struct it *it;
1233 int line_height = it->max_ascent + it->max_descent;
1234 int line_top_y = it->current_y;
1236 if (line_height == 0)
1238 if (last_height)
1239 line_height = last_height;
1240 else if (IT_CHARPOS (*it) < ZV)
1242 move_it_by_lines (it, 1, 1);
1243 line_height = (it->max_ascent || it->max_descent
1244 ? it->max_ascent + it->max_descent
1245 : last_height);
1247 else
1249 struct glyph_row *row = it->glyph_row;
1251 /* Use the default character height. */
1252 it->glyph_row = NULL;
1253 it->what = IT_CHARACTER;
1254 it->c = ' ';
1255 it->len = 1;
1256 PRODUCE_GLYPHS (it);
1257 line_height = it->ascent + it->descent;
1258 it->glyph_row = row;
1262 return line_top_y + line_height;
1266 /* Return 1 if position CHARPOS is visible in window W.
1267 CHARPOS < 0 means return info about WINDOW_END position.
1268 If visible, set *X and *Y to pixel coordinates of top left corner.
1269 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1270 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1273 pos_visible_p (w, charpos, x, y, rtop, rbot, rowh, vpos)
1274 struct window *w;
1275 int charpos, *x, *y, *rtop, *rbot, *rowh, *vpos;
1277 struct it it;
1278 struct text_pos top;
1279 int visible_p = 0;
1280 struct buffer *old_buffer = NULL;
1282 if (noninteractive)
1283 return visible_p;
1285 if (XBUFFER (w->buffer) != current_buffer)
1287 old_buffer = current_buffer;
1288 set_buffer_internal_1 (XBUFFER (w->buffer));
1291 SET_TEXT_POS_FROM_MARKER (top, w->start);
1293 /* Compute exact mode line heights. */
1294 if (WINDOW_WANTS_MODELINE_P (w))
1295 current_mode_line_height
1296 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1297 current_buffer->mode_line_format);
1299 if (WINDOW_WANTS_HEADER_LINE_P (w))
1300 current_header_line_height
1301 = display_mode_line (w, HEADER_LINE_FACE_ID,
1302 current_buffer->header_line_format);
1304 start_display (&it, w, top);
1305 move_it_to (&it, charpos, -1, it.last_visible_y-1, -1,
1306 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
1308 /* Note that we may overshoot because of invisible text. */
1309 if (charpos >= 0 && IT_CHARPOS (it) >= charpos)
1311 int top_x = it.current_x;
1312 int top_y = it.current_y;
1313 int bottom_y = (last_height = 0, line_bottom_y (&it));
1314 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1316 if (top_y < window_top_y)
1317 visible_p = bottom_y > window_top_y;
1318 else if (top_y < it.last_visible_y)
1319 visible_p = 1;
1320 if (visible_p)
1322 *x = top_x;
1323 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1324 *rtop = max (0, window_top_y - top_y);
1325 *rbot = max (0, bottom_y - it.last_visible_y);
1326 *rowh = max (0, (min (bottom_y, it.last_visible_y)
1327 - max (top_y, window_top_y)));
1328 *vpos = it.vpos;
1331 else
1333 struct it it2;
1335 it2 = it;
1336 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1337 move_it_by_lines (&it, 1, 0);
1338 if (charpos < IT_CHARPOS (it)
1339 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1341 visible_p = 1;
1342 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1343 *x = it2.current_x;
1344 *y = it2.current_y + it2.max_ascent - it2.ascent;
1345 *rtop = max (0, -it2.current_y);
1346 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1347 - it.last_visible_y));
1348 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
1349 it.last_visible_y)
1350 - max (it2.current_y,
1351 WINDOW_HEADER_LINE_HEIGHT (w))));
1352 *vpos = it2.vpos;
1356 if (old_buffer)
1357 set_buffer_internal_1 (old_buffer);
1359 current_header_line_height = current_mode_line_height = -1;
1361 if (visible_p && XFASTINT (w->hscroll) > 0)
1362 *x -= XFASTINT (w->hscroll) * WINDOW_FRAME_COLUMN_WIDTH (w);
1364 #if 0
1365 /* Debugging code. */
1366 if (visible_p)
1367 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1368 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
1369 else
1370 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
1371 #endif
1373 return visible_p;
1377 /* Return the next character from STR which is MAXLEN bytes long.
1378 Return in *LEN the length of the character. This is like
1379 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1380 we find one, we return a `?', but with the length of the invalid
1381 character. */
1383 static INLINE int
1384 string_char_and_length (str, maxlen, len)
1385 const unsigned char *str;
1386 int maxlen, *len;
1388 int c;
1390 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
1391 if (!CHAR_VALID_P (c, 1))
1392 /* We may not change the length here because other places in Emacs
1393 don't use this function, i.e. they silently accept invalid
1394 characters. */
1395 c = '?';
1397 return c;
1402 /* Given a position POS containing a valid character and byte position
1403 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1405 static struct text_pos
1406 string_pos_nchars_ahead (pos, string, nchars)
1407 struct text_pos pos;
1408 Lisp_Object string;
1409 int nchars;
1411 xassert (STRINGP (string) && nchars >= 0);
1413 if (STRING_MULTIBYTE (string))
1415 int rest = SBYTES (string) - BYTEPOS (pos);
1416 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1417 int len;
1419 while (nchars--)
1421 string_char_and_length (p, rest, &len);
1422 p += len, rest -= len;
1423 xassert (rest >= 0);
1424 CHARPOS (pos) += 1;
1425 BYTEPOS (pos) += len;
1428 else
1429 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1431 return pos;
1435 /* Value is the text position, i.e. character and byte position,
1436 for character position CHARPOS in STRING. */
1438 static INLINE struct text_pos
1439 string_pos (charpos, string)
1440 int charpos;
1441 Lisp_Object string;
1443 struct text_pos pos;
1444 xassert (STRINGP (string));
1445 xassert (charpos >= 0);
1446 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1447 return pos;
1451 /* Value is a text position, i.e. character and byte position, for
1452 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1453 means recognize multibyte characters. */
1455 static struct text_pos
1456 c_string_pos (charpos, s, multibyte_p)
1457 int charpos;
1458 unsigned char *s;
1459 int multibyte_p;
1461 struct text_pos pos;
1463 xassert (s != NULL);
1464 xassert (charpos >= 0);
1466 if (multibyte_p)
1468 int rest = strlen (s), len;
1470 SET_TEXT_POS (pos, 0, 0);
1471 while (charpos--)
1473 string_char_and_length (s, rest, &len);
1474 s += len, rest -= len;
1475 xassert (rest >= 0);
1476 CHARPOS (pos) += 1;
1477 BYTEPOS (pos) += len;
1480 else
1481 SET_TEXT_POS (pos, charpos, charpos);
1483 return pos;
1487 /* Value is the number of characters in C string S. MULTIBYTE_P
1488 non-zero means recognize multibyte characters. */
1490 static int
1491 number_of_chars (s, multibyte_p)
1492 unsigned char *s;
1493 int multibyte_p;
1495 int nchars;
1497 if (multibyte_p)
1499 int rest = strlen (s), len;
1500 unsigned char *p = (unsigned char *) s;
1502 for (nchars = 0; rest > 0; ++nchars)
1504 string_char_and_length (p, rest, &len);
1505 rest -= len, p += len;
1508 else
1509 nchars = strlen (s);
1511 return nchars;
1515 /* Compute byte position NEWPOS->bytepos corresponding to
1516 NEWPOS->charpos. POS is a known position in string STRING.
1517 NEWPOS->charpos must be >= POS.charpos. */
1519 static void
1520 compute_string_pos (newpos, pos, string)
1521 struct text_pos *newpos, pos;
1522 Lisp_Object string;
1524 xassert (STRINGP (string));
1525 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1527 if (STRING_MULTIBYTE (string))
1528 *newpos = string_pos_nchars_ahead (pos, string,
1529 CHARPOS (*newpos) - CHARPOS (pos));
1530 else
1531 BYTEPOS (*newpos) = CHARPOS (*newpos);
1534 /* EXPORT:
1535 Return an estimation of the pixel height of mode or top lines on
1536 frame F. FACE_ID specifies what line's height to estimate. */
1539 estimate_mode_line_height (f, face_id)
1540 struct frame *f;
1541 enum face_id face_id;
1543 #ifdef HAVE_WINDOW_SYSTEM
1544 if (FRAME_WINDOW_P (f))
1546 int height = FONT_HEIGHT (FRAME_FONT (f));
1548 /* This function is called so early when Emacs starts that the face
1549 cache and mode line face are not yet initialized. */
1550 if (FRAME_FACE_CACHE (f))
1552 struct face *face = FACE_FROM_ID (f, face_id);
1553 if (face)
1555 if (face->font)
1556 height = FONT_HEIGHT (face->font);
1557 if (face->box_line_width > 0)
1558 height += 2 * face->box_line_width;
1562 return height;
1564 #endif
1566 return 1;
1569 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1570 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1571 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1572 not force the value into range. */
1574 void
1575 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
1576 FRAME_PTR f;
1577 register int pix_x, pix_y;
1578 int *x, *y;
1579 NativeRectangle *bounds;
1580 int noclip;
1583 #ifdef HAVE_WINDOW_SYSTEM
1584 if (FRAME_WINDOW_P (f))
1586 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1587 even for negative values. */
1588 if (pix_x < 0)
1589 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1590 if (pix_y < 0)
1591 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1593 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1594 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1596 if (bounds)
1597 STORE_NATIVE_RECT (*bounds,
1598 FRAME_COL_TO_PIXEL_X (f, pix_x),
1599 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1600 FRAME_COLUMN_WIDTH (f) - 1,
1601 FRAME_LINE_HEIGHT (f) - 1);
1603 if (!noclip)
1605 if (pix_x < 0)
1606 pix_x = 0;
1607 else if (pix_x > FRAME_TOTAL_COLS (f))
1608 pix_x = FRAME_TOTAL_COLS (f);
1610 if (pix_y < 0)
1611 pix_y = 0;
1612 else if (pix_y > FRAME_LINES (f))
1613 pix_y = FRAME_LINES (f);
1616 #endif
1618 *x = pix_x;
1619 *y = pix_y;
1623 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1624 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1625 can't tell the positions because W's display is not up to date,
1626 return 0. */
1629 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
1630 struct window *w;
1631 int hpos, vpos;
1632 int *frame_x, *frame_y;
1634 #ifdef HAVE_WINDOW_SYSTEM
1635 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1637 int success_p;
1639 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1640 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1642 if (display_completed)
1644 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1645 struct glyph *glyph = row->glyphs[TEXT_AREA];
1646 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1648 hpos = row->x;
1649 vpos = row->y;
1650 while (glyph < end)
1652 hpos += glyph->pixel_width;
1653 ++glyph;
1656 /* If first glyph is partially visible, its first visible position is still 0. */
1657 if (hpos < 0)
1658 hpos = 0;
1660 success_p = 1;
1662 else
1664 hpos = vpos = 0;
1665 success_p = 0;
1668 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1669 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1670 return success_p;
1672 #endif
1674 *frame_x = hpos;
1675 *frame_y = vpos;
1676 return 1;
1680 #ifdef HAVE_WINDOW_SYSTEM
1682 /* Find the glyph under window-relative coordinates X/Y in window W.
1683 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1684 strings. Return in *HPOS and *VPOS the row and column number of
1685 the glyph found. Return in *AREA the glyph area containing X.
1686 Value is a pointer to the glyph found or null if X/Y is not on
1687 text, or we can't tell because W's current matrix is not up to
1688 date. */
1690 static struct glyph *
1691 x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
1692 struct window *w;
1693 int x, y;
1694 int *hpos, *vpos, *dx, *dy, *area;
1696 struct glyph *glyph, *end;
1697 struct glyph_row *row = NULL;
1698 int x0, i;
1700 /* Find row containing Y. Give up if some row is not enabled. */
1701 for (i = 0; i < w->current_matrix->nrows; ++i)
1703 row = MATRIX_ROW (w->current_matrix, i);
1704 if (!row->enabled_p)
1705 return NULL;
1706 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1707 break;
1710 *vpos = i;
1711 *hpos = 0;
1713 /* Give up if Y is not in the window. */
1714 if (i == w->current_matrix->nrows)
1715 return NULL;
1717 /* Get the glyph area containing X. */
1718 if (w->pseudo_window_p)
1720 *area = TEXT_AREA;
1721 x0 = 0;
1723 else
1725 if (x < window_box_left_offset (w, TEXT_AREA))
1727 *area = LEFT_MARGIN_AREA;
1728 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1730 else if (x < window_box_right_offset (w, TEXT_AREA))
1732 *area = TEXT_AREA;
1733 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1735 else
1737 *area = RIGHT_MARGIN_AREA;
1738 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1742 /* Find glyph containing X. */
1743 glyph = row->glyphs[*area];
1744 end = glyph + row->used[*area];
1745 x -= x0;
1746 while (glyph < end && x >= glyph->pixel_width)
1748 x -= glyph->pixel_width;
1749 ++glyph;
1752 if (glyph == end)
1753 return NULL;
1755 if (dx)
1757 *dx = x;
1758 *dy = y - (row->y + row->ascent - glyph->ascent);
1761 *hpos = glyph - row->glyphs[*area];
1762 return glyph;
1766 /* EXPORT:
1767 Convert frame-relative x/y to coordinates relative to window W.
1768 Takes pseudo-windows into account. */
1770 void
1771 frame_to_window_pixel_xy (w, x, y)
1772 struct window *w;
1773 int *x, *y;
1775 if (w->pseudo_window_p)
1777 /* A pseudo-window is always full-width, and starts at the
1778 left edge of the frame, plus a frame border. */
1779 struct frame *f = XFRAME (w->frame);
1780 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1781 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1783 else
1785 *x -= WINDOW_LEFT_EDGE_X (w);
1786 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1790 /* EXPORT:
1791 Return in RECTS[] at most N clipping rectangles for glyph string S.
1792 Return the number of stored rectangles. */
1795 get_glyph_string_clip_rects (s, rects, n)
1796 struct glyph_string *s;
1797 NativeRectangle *rects;
1798 int n;
1800 XRectangle r;
1802 if (n <= 0)
1803 return 0;
1805 if (s->row->full_width_p)
1807 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1808 r.x = WINDOW_LEFT_EDGE_X (s->w);
1809 r.width = WINDOW_TOTAL_WIDTH (s->w);
1811 /* Unless displaying a mode or menu bar line, which are always
1812 fully visible, clip to the visible part of the row. */
1813 if (s->w->pseudo_window_p)
1814 r.height = s->row->visible_height;
1815 else
1816 r.height = s->height;
1818 else
1820 /* This is a text line that may be partially visible. */
1821 r.x = window_box_left (s->w, s->area);
1822 r.width = window_box_width (s->w, s->area);
1823 r.height = s->row->visible_height;
1826 if (s->clip_head)
1827 if (r.x < s->clip_head->x)
1829 if (r.width >= s->clip_head->x - r.x)
1830 r.width -= s->clip_head->x - r.x;
1831 else
1832 r.width = 0;
1833 r.x = s->clip_head->x;
1835 if (s->clip_tail)
1836 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
1838 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
1839 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
1840 else
1841 r.width = 0;
1844 /* If S draws overlapping rows, it's sufficient to use the top and
1845 bottom of the window for clipping because this glyph string
1846 intentionally draws over other lines. */
1847 if (s->for_overlaps)
1849 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1850 r.height = window_text_bottom_y (s->w) - r.y;
1852 /* Alas, the above simple strategy does not work for the
1853 environments with anti-aliased text: if the same text is
1854 drawn onto the same place multiple times, it gets thicker.
1855 If the overlap we are processing is for the erased cursor, we
1856 take the intersection with the rectagle of the cursor. */
1857 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
1859 XRectangle rc, r_save = r;
1861 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
1862 rc.y = s->w->phys_cursor.y;
1863 rc.width = s->w->phys_cursor_width;
1864 rc.height = s->w->phys_cursor_height;
1866 x_intersect_rectangles (&r_save, &rc, &r);
1869 else
1871 /* Don't use S->y for clipping because it doesn't take partially
1872 visible lines into account. For example, it can be negative for
1873 partially visible lines at the top of a window. */
1874 if (!s->row->full_width_p
1875 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1876 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1877 else
1878 r.y = max (0, s->row->y);
1880 /* If drawing a tool-bar window, draw it over the internal border
1881 at the top of the window. */
1882 if (WINDOWP (s->f->tool_bar_window)
1883 && s->w == XWINDOW (s->f->tool_bar_window))
1884 r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
1887 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1889 /* If drawing the cursor, don't let glyph draw outside its
1890 advertised boundaries. Cleartype does this under some circumstances. */
1891 if (s->hl == DRAW_CURSOR)
1893 struct glyph *glyph = s->first_glyph;
1894 int height, max_y;
1896 if (s->x > r.x)
1898 r.width -= s->x - r.x;
1899 r.x = s->x;
1901 r.width = min (r.width, glyph->pixel_width);
1903 /* If r.y is below window bottom, ensure that we still see a cursor. */
1904 height = min (glyph->ascent + glyph->descent,
1905 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
1906 max_y = window_text_bottom_y (s->w) - height;
1907 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
1908 if (s->ybase - glyph->ascent > max_y)
1910 r.y = max_y;
1911 r.height = height;
1913 else
1915 /* Don't draw cursor glyph taller than our actual glyph. */
1916 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
1917 if (height < r.height)
1919 max_y = r.y + r.height;
1920 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
1921 r.height = min (max_y - r.y, height);
1926 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
1927 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
1929 #ifdef CONVERT_FROM_XRECT
1930 CONVERT_FROM_XRECT (r, *rects);
1931 #else
1932 *rects = r;
1933 #endif
1934 return 1;
1936 else
1938 /* If we are processing overlapping and allowed to return
1939 multiple clipping rectangles, we exclude the row of the glyph
1940 string from the clipping rectangle. This is to avoid drawing
1941 the same text on the environment with anti-aliasing. */
1942 #ifdef CONVERT_FROM_XRECT
1943 XRectangle rs[2];
1944 #else
1945 XRectangle *rs = rects;
1946 #endif
1947 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
1949 if (s->for_overlaps & OVERLAPS_PRED)
1951 rs[i] = r;
1952 if (r.y + r.height > row_y)
1954 if (r.y < row_y)
1955 rs[i].height = row_y - r.y;
1956 else
1957 rs[i].height = 0;
1959 i++;
1961 if (s->for_overlaps & OVERLAPS_SUCC)
1963 rs[i] = r;
1964 if (r.y < row_y + s->row->visible_height)
1966 if (r.y + r.height > row_y + s->row->visible_height)
1968 rs[i].y = row_y + s->row->visible_height;
1969 rs[i].height = r.y + r.height - rs[i].y;
1971 else
1972 rs[i].height = 0;
1974 i++;
1977 n = i;
1978 #ifdef CONVERT_FROM_XRECT
1979 for (i = 0; i < n; i++)
1980 CONVERT_FROM_XRECT (rs[i], rects[i]);
1981 #endif
1982 return n;
1986 /* EXPORT:
1987 Return in *NR the clipping rectangle for glyph string S. */
1989 void
1990 get_glyph_string_clip_rect (s, nr)
1991 struct glyph_string *s;
1992 NativeRectangle *nr;
1994 get_glyph_string_clip_rects (s, nr, 1);
1998 /* EXPORT:
1999 Return the position and height of the phys cursor in window W.
2000 Set w->phys_cursor_width to width of phys cursor.
2003 void
2004 get_phys_cursor_geometry (w, row, glyph, xp, yp, heightp)
2005 struct window *w;
2006 struct glyph_row *row;
2007 struct glyph *glyph;
2008 int *xp, *yp, *heightp;
2010 struct frame *f = XFRAME (WINDOW_FRAME (w));
2011 int x, y, wd, h, h0, y0;
2013 /* Compute the width of the rectangle to draw. If on a stretch
2014 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2015 rectangle as wide as the glyph, but use a canonical character
2016 width instead. */
2017 wd = glyph->pixel_width - 1;
2018 #ifdef HAVE_NTGUI
2019 wd++; /* Why? */
2020 #endif
2022 x = w->phys_cursor.x;
2023 if (x < 0)
2025 wd += x;
2026 x = 0;
2029 if (glyph->type == STRETCH_GLYPH
2030 && !x_stretch_cursor_p)
2031 wd = min (FRAME_COLUMN_WIDTH (f), wd);
2032 w->phys_cursor_width = wd;
2034 y = w->phys_cursor.y + row->ascent - glyph->ascent;
2036 /* If y is below window bottom, ensure that we still see a cursor. */
2037 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
2039 h = max (h0, glyph->ascent + glyph->descent);
2040 h0 = min (h0, glyph->ascent + glyph->descent);
2042 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
2043 if (y < y0)
2045 h = max (h - (y0 - y) + 1, h0);
2046 y = y0 - 1;
2048 else
2050 y0 = window_text_bottom_y (w) - h0;
2051 if (y > y0)
2053 h += y - y0;
2054 y = y0;
2058 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
2059 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
2060 *heightp = h;
2064 * Remember which glyph the mouse is over.
2067 void
2068 remember_mouse_glyph (f, gx, gy, rect)
2069 struct frame *f;
2070 int gx, gy;
2071 NativeRectangle *rect;
2073 Lisp_Object window;
2074 struct window *w;
2075 struct glyph_row *r, *gr, *end_row;
2076 enum window_part part;
2077 enum glyph_row_area area;
2078 int x, y, width, height;
2080 /* Try to determine frame pixel position and size of the glyph under
2081 frame pixel coordinates X/Y on frame F. */
2083 if (!f->glyphs_initialized_p
2084 || (window = window_from_coordinates (f, gx, gy, &part, &x, &y, 0),
2085 NILP (window)))
2087 width = FRAME_SMALLEST_CHAR_WIDTH (f);
2088 height = FRAME_SMALLEST_FONT_HEIGHT (f);
2089 goto virtual_glyph;
2092 w = XWINDOW (window);
2093 width = WINDOW_FRAME_COLUMN_WIDTH (w);
2094 height = WINDOW_FRAME_LINE_HEIGHT (w);
2096 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
2097 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
2099 if (w->pseudo_window_p)
2101 area = TEXT_AREA;
2102 part = ON_MODE_LINE; /* Don't adjust margin. */
2103 goto text_glyph;
2106 switch (part)
2108 case ON_LEFT_MARGIN:
2109 area = LEFT_MARGIN_AREA;
2110 goto text_glyph;
2112 case ON_RIGHT_MARGIN:
2113 area = RIGHT_MARGIN_AREA;
2114 goto text_glyph;
2116 case ON_HEADER_LINE:
2117 case ON_MODE_LINE:
2118 gr = (part == ON_HEADER_LINE
2119 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
2120 : MATRIX_MODE_LINE_ROW (w->current_matrix));
2121 gy = gr->y;
2122 area = TEXT_AREA;
2123 goto text_glyph_row_found;
2125 case ON_TEXT:
2126 area = TEXT_AREA;
2128 text_glyph:
2129 gr = 0; gy = 0;
2130 for (; r <= end_row && r->enabled_p; ++r)
2131 if (r->y + r->height > y)
2133 gr = r; gy = r->y;
2134 break;
2137 text_glyph_row_found:
2138 if (gr && gy <= y)
2140 struct glyph *g = gr->glyphs[area];
2141 struct glyph *end = g + gr->used[area];
2143 height = gr->height;
2144 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2145 if (gx + g->pixel_width > x)
2146 break;
2148 if (g < end)
2150 if (g->type == IMAGE_GLYPH)
2152 /* Don't remember when mouse is over image, as
2153 image may have hot-spots. */
2154 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2155 return;
2157 width = g->pixel_width;
2159 else
2161 /* Use nominal char spacing at end of line. */
2162 x -= gx;
2163 gx += (x / width) * width;
2166 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2167 gx += window_box_left_offset (w, area);
2169 else
2171 /* Use nominal line height at end of window. */
2172 gx = (x / width) * width;
2173 y -= gy;
2174 gy += (y / height) * height;
2176 break;
2178 case ON_LEFT_FRINGE:
2179 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2180 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2181 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2182 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2183 goto row_glyph;
2185 case ON_RIGHT_FRINGE:
2186 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2187 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2188 : window_box_right_offset (w, TEXT_AREA));
2189 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2190 goto row_glyph;
2192 case ON_SCROLL_BAR:
2193 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2195 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2196 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2197 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2198 : 0)));
2199 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2201 row_glyph:
2202 gr = 0, gy = 0;
2203 for (; r <= end_row && r->enabled_p; ++r)
2204 if (r->y + r->height > y)
2206 gr = r; gy = r->y;
2207 break;
2210 if (gr && gy <= y)
2211 height = gr->height;
2212 else
2214 /* Use nominal line height at end of window. */
2215 y -= gy;
2216 gy += (y / height) * height;
2218 break;
2220 default:
2222 virtual_glyph:
2223 /* If there is no glyph under the mouse, then we divide the screen
2224 into a grid of the smallest glyph in the frame, and use that
2225 as our "glyph". */
2227 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2228 round down even for negative values. */
2229 if (gx < 0)
2230 gx -= width - 1;
2231 if (gy < 0)
2232 gy -= height - 1;
2234 gx = (gx / width) * width;
2235 gy = (gy / height) * height;
2237 goto store_rect;
2240 gx += WINDOW_LEFT_EDGE_X (w);
2241 gy += WINDOW_TOP_EDGE_Y (w);
2243 store_rect:
2244 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2246 /* Visible feedback for debugging. */
2247 #if 0
2248 #if HAVE_X_WINDOWS
2249 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2250 f->output_data.x->normal_gc,
2251 gx, gy, width, height);
2252 #endif
2253 #endif
2257 #endif /* HAVE_WINDOW_SYSTEM */
2260 /***********************************************************************
2261 Lisp form evaluation
2262 ***********************************************************************/
2264 /* Error handler for safe_eval and safe_call. */
2266 static Lisp_Object
2267 safe_eval_handler (arg)
2268 Lisp_Object arg;
2270 add_to_log ("Error during redisplay: %s", arg, Qnil);
2271 return Qnil;
2275 /* Evaluate SEXPR and return the result, or nil if something went
2276 wrong. Prevent redisplay during the evaluation. */
2278 Lisp_Object
2279 safe_eval (sexpr)
2280 Lisp_Object sexpr;
2282 Lisp_Object val;
2284 if (inhibit_eval_during_redisplay)
2285 val = Qnil;
2286 else
2288 int count = SPECPDL_INDEX ();
2289 struct gcpro gcpro1;
2291 GCPRO1 (sexpr);
2292 specbind (Qinhibit_redisplay, Qt);
2293 /* Use Qt to ensure debugger does not run,
2294 so there is no possibility of wanting to redisplay. */
2295 val = internal_condition_case_1 (Feval, sexpr, Qt,
2296 safe_eval_handler);
2297 UNGCPRO;
2298 val = unbind_to (count, val);
2301 return val;
2305 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
2306 Return the result, or nil if something went wrong. Prevent
2307 redisplay during the evaluation. */
2309 Lisp_Object
2310 safe_call (nargs, args)
2311 int nargs;
2312 Lisp_Object *args;
2314 Lisp_Object val;
2316 if (inhibit_eval_during_redisplay)
2317 val = Qnil;
2318 else
2320 int count = SPECPDL_INDEX ();
2321 struct gcpro gcpro1;
2323 GCPRO1 (args[0]);
2324 gcpro1.nvars = nargs;
2325 specbind (Qinhibit_redisplay, Qt);
2326 /* Use Qt to ensure debugger does not run,
2327 so there is no possibility of wanting to redisplay. */
2328 val = internal_condition_case_2 (Ffuncall, nargs, args, Qt,
2329 safe_eval_handler);
2330 UNGCPRO;
2331 val = unbind_to (count, val);
2334 return val;
2338 /* Call function FN with one argument ARG.
2339 Return the result, or nil if something went wrong. */
2341 Lisp_Object
2342 safe_call1 (fn, arg)
2343 Lisp_Object fn, arg;
2345 Lisp_Object args[2];
2346 args[0] = fn;
2347 args[1] = arg;
2348 return safe_call (2, args);
2353 /***********************************************************************
2354 Debugging
2355 ***********************************************************************/
2357 #if 0
2359 /* Define CHECK_IT to perform sanity checks on iterators.
2360 This is for debugging. It is too slow to do unconditionally. */
2362 static void
2363 check_it (it)
2364 struct it *it;
2366 if (it->method == GET_FROM_STRING)
2368 xassert (STRINGP (it->string));
2369 xassert (IT_STRING_CHARPOS (*it) >= 0);
2371 else
2373 xassert (IT_STRING_CHARPOS (*it) < 0);
2374 if (it->method == GET_FROM_BUFFER)
2376 /* Check that character and byte positions agree. */
2377 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2381 if (it->dpvec)
2382 xassert (it->current.dpvec_index >= 0);
2383 else
2384 xassert (it->current.dpvec_index < 0);
2387 #define CHECK_IT(IT) check_it ((IT))
2389 #else /* not 0 */
2391 #define CHECK_IT(IT) (void) 0
2393 #endif /* not 0 */
2396 #if GLYPH_DEBUG
2398 /* Check that the window end of window W is what we expect it
2399 to be---the last row in the current matrix displaying text. */
2401 static void
2402 check_window_end (w)
2403 struct window *w;
2405 if (!MINI_WINDOW_P (w)
2406 && !NILP (w->window_end_valid))
2408 struct glyph_row *row;
2409 xassert ((row = MATRIX_ROW (w->current_matrix,
2410 XFASTINT (w->window_end_vpos)),
2411 !row->enabled_p
2412 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2413 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2417 #define CHECK_WINDOW_END(W) check_window_end ((W))
2419 #else /* not GLYPH_DEBUG */
2421 #define CHECK_WINDOW_END(W) (void) 0
2423 #endif /* not GLYPH_DEBUG */
2427 /***********************************************************************
2428 Iterator initialization
2429 ***********************************************************************/
2431 /* Initialize IT for displaying current_buffer in window W, starting
2432 at character position CHARPOS. CHARPOS < 0 means that no buffer
2433 position is specified which is useful when the iterator is assigned
2434 a position later. BYTEPOS is the byte position corresponding to
2435 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2437 If ROW is not null, calls to produce_glyphs with IT as parameter
2438 will produce glyphs in that row.
2440 BASE_FACE_ID is the id of a base face to use. It must be one of
2441 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2442 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2443 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2445 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2446 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2447 will be initialized to use the corresponding mode line glyph row of
2448 the desired matrix of W. */
2450 void
2451 init_iterator (it, w, charpos, bytepos, row, base_face_id)
2452 struct it *it;
2453 struct window *w;
2454 int charpos, bytepos;
2455 struct glyph_row *row;
2456 enum face_id base_face_id;
2458 int highlight_region_p;
2460 /* Some precondition checks. */
2461 xassert (w != NULL && it != NULL);
2462 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2463 && charpos <= ZV));
2465 /* If face attributes have been changed since the last redisplay,
2466 free realized faces now because they depend on face definitions
2467 that might have changed. Don't free faces while there might be
2468 desired matrices pending which reference these faces. */
2469 if (face_change_count && !inhibit_free_realized_faces)
2471 face_change_count = 0;
2472 free_all_realized_faces (Qnil);
2475 /* Use one of the mode line rows of W's desired matrix if
2476 appropriate. */
2477 if (row == NULL)
2479 if (base_face_id == MODE_LINE_FACE_ID
2480 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2481 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2482 else if (base_face_id == HEADER_LINE_FACE_ID)
2483 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2486 /* Clear IT. */
2487 bzero (it, sizeof *it);
2488 it->current.overlay_string_index = -1;
2489 it->current.dpvec_index = -1;
2490 it->base_face_id = base_face_id;
2491 it->string = Qnil;
2492 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2494 /* The window in which we iterate over current_buffer: */
2495 XSETWINDOW (it->window, w);
2496 it->w = w;
2497 it->f = XFRAME (w->frame);
2499 /* Extra space between lines (on window systems only). */
2500 if (base_face_id == DEFAULT_FACE_ID
2501 && FRAME_WINDOW_P (it->f))
2503 if (NATNUMP (current_buffer->extra_line_spacing))
2504 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
2505 else if (FLOATP (current_buffer->extra_line_spacing))
2506 it->extra_line_spacing = (XFLOAT_DATA (current_buffer->extra_line_spacing)
2507 * FRAME_LINE_HEIGHT (it->f));
2508 else if (it->f->extra_line_spacing > 0)
2509 it->extra_line_spacing = it->f->extra_line_spacing;
2510 it->max_extra_line_spacing = 0;
2513 /* If realized faces have been removed, e.g. because of face
2514 attribute changes of named faces, recompute them. When running
2515 in batch mode, the face cache of the initial frame is null. If
2516 we happen to get called, make a dummy face cache. */
2517 if (FRAME_FACE_CACHE (it->f) == NULL)
2518 init_frame_faces (it->f);
2519 if (FRAME_FACE_CACHE (it->f)->used == 0)
2520 recompute_basic_faces (it->f);
2522 /* Current value of the `slice', `space-width', and 'height' properties. */
2523 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2524 it->space_width = Qnil;
2525 it->font_height = Qnil;
2526 it->override_ascent = -1;
2528 /* Are control characters displayed as `^C'? */
2529 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
2531 /* -1 means everything between a CR and the following line end
2532 is invisible. >0 means lines indented more than this value are
2533 invisible. */
2534 it->selective = (INTEGERP (current_buffer->selective_display)
2535 ? XFASTINT (current_buffer->selective_display)
2536 : (!NILP (current_buffer->selective_display)
2537 ? -1 : 0));
2538 it->selective_display_ellipsis_p
2539 = !NILP (current_buffer->selective_display_ellipses);
2541 /* Display table to use. */
2542 it->dp = window_display_table (w);
2544 /* Are multibyte characters enabled in current_buffer? */
2545 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2547 /* Non-zero if we should highlight the region. */
2548 highlight_region_p
2549 = (!NILP (Vtransient_mark_mode)
2550 && !NILP (current_buffer->mark_active)
2551 && XMARKER (current_buffer->mark)->buffer != 0);
2553 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2554 start and end of a visible region in window IT->w. Set both to
2555 -1 to indicate no region. */
2556 if (highlight_region_p
2557 /* Maybe highlight only in selected window. */
2558 && (/* Either show region everywhere. */
2559 highlight_nonselected_windows
2560 /* Or show region in the selected window. */
2561 || w == XWINDOW (selected_window)
2562 /* Or show the region if we are in the mini-buffer and W is
2563 the window the mini-buffer refers to. */
2564 || (MINI_WINDOW_P (XWINDOW (selected_window))
2565 && WINDOWP (minibuf_selected_window)
2566 && w == XWINDOW (minibuf_selected_window))))
2568 int charpos = marker_position (current_buffer->mark);
2569 it->region_beg_charpos = min (PT, charpos);
2570 it->region_end_charpos = max (PT, charpos);
2572 else
2573 it->region_beg_charpos = it->region_end_charpos = -1;
2575 /* Get the position at which the redisplay_end_trigger hook should
2576 be run, if it is to be run at all. */
2577 if (MARKERP (w->redisplay_end_trigger)
2578 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2579 it->redisplay_end_trigger_charpos
2580 = marker_position (w->redisplay_end_trigger);
2581 else if (INTEGERP (w->redisplay_end_trigger))
2582 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2584 /* Correct bogus values of tab_width. */
2585 it->tab_width = XINT (current_buffer->tab_width);
2586 if (it->tab_width <= 0 || it->tab_width > 1000)
2587 it->tab_width = 8;
2589 /* Are lines in the display truncated? */
2590 it->truncate_lines_p
2591 = (base_face_id != DEFAULT_FACE_ID
2592 || XINT (it->w->hscroll)
2593 || (truncate_partial_width_windows
2594 && !WINDOW_FULL_WIDTH_P (it->w))
2595 || !NILP (current_buffer->truncate_lines));
2597 /* Get dimensions of truncation and continuation glyphs. These are
2598 displayed as fringe bitmaps under X, so we don't need them for such
2599 frames. */
2600 if (!FRAME_WINDOW_P (it->f))
2602 if (it->truncate_lines_p)
2604 /* We will need the truncation glyph. */
2605 xassert (it->glyph_row == NULL);
2606 produce_special_glyphs (it, IT_TRUNCATION);
2607 it->truncation_pixel_width = it->pixel_width;
2609 else
2611 /* We will need the continuation glyph. */
2612 xassert (it->glyph_row == NULL);
2613 produce_special_glyphs (it, IT_CONTINUATION);
2614 it->continuation_pixel_width = it->pixel_width;
2617 /* Reset these values to zero because the produce_special_glyphs
2618 above has changed them. */
2619 it->pixel_width = it->ascent = it->descent = 0;
2620 it->phys_ascent = it->phys_descent = 0;
2623 /* Set this after getting the dimensions of truncation and
2624 continuation glyphs, so that we don't produce glyphs when calling
2625 produce_special_glyphs, above. */
2626 it->glyph_row = row;
2627 it->area = TEXT_AREA;
2629 /* Get the dimensions of the display area. The display area
2630 consists of the visible window area plus a horizontally scrolled
2631 part to the left of the window. All x-values are relative to the
2632 start of this total display area. */
2633 if (base_face_id != DEFAULT_FACE_ID)
2635 /* Mode lines, menu bar in terminal frames. */
2636 it->first_visible_x = 0;
2637 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2639 else
2641 it->first_visible_x
2642 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2643 it->last_visible_x = (it->first_visible_x
2644 + window_box_width (w, TEXT_AREA));
2646 /* If we truncate lines, leave room for the truncator glyph(s) at
2647 the right margin. Otherwise, leave room for the continuation
2648 glyph(s). Truncation and continuation glyphs are not inserted
2649 for window-based redisplay. */
2650 if (!FRAME_WINDOW_P (it->f))
2652 if (it->truncate_lines_p)
2653 it->last_visible_x -= it->truncation_pixel_width;
2654 else
2655 it->last_visible_x -= it->continuation_pixel_width;
2658 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2659 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2662 /* Leave room for a border glyph. */
2663 if (!FRAME_WINDOW_P (it->f)
2664 && !WINDOW_RIGHTMOST_P (it->w))
2665 it->last_visible_x -= 1;
2667 it->last_visible_y = window_text_bottom_y (w);
2669 /* For mode lines and alike, arrange for the first glyph having a
2670 left box line if the face specifies a box. */
2671 if (base_face_id != DEFAULT_FACE_ID)
2673 struct face *face;
2675 it->face_id = base_face_id;
2677 /* If we have a boxed mode line, make the first character appear
2678 with a left box line. */
2679 face = FACE_FROM_ID (it->f, base_face_id);
2680 if (face->box != FACE_NO_BOX)
2681 it->start_of_box_run_p = 1;
2684 /* If a buffer position was specified, set the iterator there,
2685 getting overlays and face properties from that position. */
2686 if (charpos >= BUF_BEG (current_buffer))
2688 it->end_charpos = ZV;
2689 it->face_id = -1;
2690 IT_CHARPOS (*it) = charpos;
2692 /* Compute byte position if not specified. */
2693 if (bytepos < charpos)
2694 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2695 else
2696 IT_BYTEPOS (*it) = bytepos;
2698 it->start = it->current;
2700 /* Compute faces etc. */
2701 reseat (it, it->current.pos, 1);
2704 CHECK_IT (it);
2708 /* Initialize IT for the display of window W with window start POS. */
2710 void
2711 start_display (it, w, pos)
2712 struct it *it;
2713 struct window *w;
2714 struct text_pos pos;
2716 struct glyph_row *row;
2717 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2719 row = w->desired_matrix->rows + first_vpos;
2720 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2721 it->first_vpos = first_vpos;
2723 /* Don't reseat to previous visible line start if current start
2724 position is in a string or image. */
2725 if (it->method == GET_FROM_BUFFER && !it->truncate_lines_p)
2727 int start_at_line_beg_p;
2728 int first_y = it->current_y;
2730 /* If window start is not at a line start, skip forward to POS to
2731 get the correct continuation lines width. */
2732 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2733 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2734 if (!start_at_line_beg_p)
2736 int new_x;
2738 reseat_at_previous_visible_line_start (it);
2739 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2741 new_x = it->current_x + it->pixel_width;
2743 /* If lines are continued, this line may end in the middle
2744 of a multi-glyph character (e.g. a control character
2745 displayed as \003, or in the middle of an overlay
2746 string). In this case move_it_to above will not have
2747 taken us to the start of the continuation line but to the
2748 end of the continued line. */
2749 if (it->current_x > 0
2750 && !it->truncate_lines_p /* Lines are continued. */
2751 && (/* And glyph doesn't fit on the line. */
2752 new_x > it->last_visible_x
2753 /* Or it fits exactly and we're on a window
2754 system frame. */
2755 || (new_x == it->last_visible_x
2756 && FRAME_WINDOW_P (it->f))))
2758 if (it->current.dpvec_index >= 0
2759 || it->current.overlay_string_index >= 0)
2761 set_iterator_to_next (it, 1);
2762 move_it_in_display_line_to (it, -1, -1, 0);
2765 it->continuation_lines_width += it->current_x;
2768 /* We're starting a new display line, not affected by the
2769 height of the continued line, so clear the appropriate
2770 fields in the iterator structure. */
2771 it->max_ascent = it->max_descent = 0;
2772 it->max_phys_ascent = it->max_phys_descent = 0;
2774 it->current_y = first_y;
2775 it->vpos = 0;
2776 it->current_x = it->hpos = 0;
2780 #if 0 /* Don't assert the following because start_display is sometimes
2781 called intentionally with a window start that is not at a
2782 line start. Please leave this code in as a comment. */
2784 /* Window start should be on a line start, now. */
2785 xassert (it->continuation_lines_width
2786 || IT_CHARPOS (it) == BEGV
2787 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
2788 #endif /* 0 */
2792 /* Return 1 if POS is a position in ellipses displayed for invisible
2793 text. W is the window we display, for text property lookup. */
2795 static int
2796 in_ellipses_for_invisible_text_p (pos, w)
2797 struct display_pos *pos;
2798 struct window *w;
2800 Lisp_Object prop, window;
2801 int ellipses_p = 0;
2802 int charpos = CHARPOS (pos->pos);
2804 /* If POS specifies a position in a display vector, this might
2805 be for an ellipsis displayed for invisible text. We won't
2806 get the iterator set up for delivering that ellipsis unless
2807 we make sure that it gets aware of the invisible text. */
2808 if (pos->dpvec_index >= 0
2809 && pos->overlay_string_index < 0
2810 && CHARPOS (pos->string_pos) < 0
2811 && charpos > BEGV
2812 && (XSETWINDOW (window, w),
2813 prop = Fget_char_property (make_number (charpos),
2814 Qinvisible, window),
2815 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2817 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2818 window);
2819 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2822 return ellipses_p;
2826 /* Initialize IT for stepping through current_buffer in window W,
2827 starting at position POS that includes overlay string and display
2828 vector/ control character translation position information. Value
2829 is zero if there are overlay strings with newlines at POS. */
2831 static int
2832 init_from_display_pos (it, w, pos)
2833 struct it *it;
2834 struct window *w;
2835 struct display_pos *pos;
2837 int charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2838 int i, overlay_strings_with_newlines = 0;
2840 /* If POS specifies a position in a display vector, this might
2841 be for an ellipsis displayed for invisible text. We won't
2842 get the iterator set up for delivering that ellipsis unless
2843 we make sure that it gets aware of the invisible text. */
2844 if (in_ellipses_for_invisible_text_p (pos, w))
2846 --charpos;
2847 bytepos = 0;
2850 /* Keep in mind: the call to reseat in init_iterator skips invisible
2851 text, so we might end up at a position different from POS. This
2852 is only a problem when POS is a row start after a newline and an
2853 overlay starts there with an after-string, and the overlay has an
2854 invisible property. Since we don't skip invisible text in
2855 display_line and elsewhere immediately after consuming the
2856 newline before the row start, such a POS will not be in a string,
2857 but the call to init_iterator below will move us to the
2858 after-string. */
2859 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2861 /* This only scans the current chunk -- it should scan all chunks.
2862 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
2863 to 16 in 22.1 to make this a lesser problem. */
2864 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
2866 const char *s = SDATA (it->overlay_strings[i]);
2867 const char *e = s + SBYTES (it->overlay_strings[i]);
2869 while (s < e && *s != '\n')
2870 ++s;
2872 if (s < e)
2874 overlay_strings_with_newlines = 1;
2875 break;
2879 /* If position is within an overlay string, set up IT to the right
2880 overlay string. */
2881 if (pos->overlay_string_index >= 0)
2883 int relative_index;
2885 /* If the first overlay string happens to have a `display'
2886 property for an image, the iterator will be set up for that
2887 image, and we have to undo that setup first before we can
2888 correct the overlay string index. */
2889 if (it->method == GET_FROM_IMAGE)
2890 pop_it (it);
2892 /* We already have the first chunk of overlay strings in
2893 IT->overlay_strings. Load more until the one for
2894 pos->overlay_string_index is in IT->overlay_strings. */
2895 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
2897 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
2898 it->current.overlay_string_index = 0;
2899 while (n--)
2901 load_overlay_strings (it, 0);
2902 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
2906 it->current.overlay_string_index = pos->overlay_string_index;
2907 relative_index = (it->current.overlay_string_index
2908 % OVERLAY_STRING_CHUNK_SIZE);
2909 it->string = it->overlay_strings[relative_index];
2910 xassert (STRINGP (it->string));
2911 it->current.string_pos = pos->string_pos;
2912 it->method = GET_FROM_STRING;
2915 #if 0 /* This is bogus because POS not having an overlay string
2916 position does not mean it's after the string. Example: A
2917 line starting with a before-string and initialization of IT
2918 to the previous row's end position. */
2919 else if (it->current.overlay_string_index >= 0)
2921 /* If POS says we're already after an overlay string ending at
2922 POS, make sure to pop the iterator because it will be in
2923 front of that overlay string. When POS is ZV, we've thereby
2924 also ``processed'' overlay strings at ZV. */
2925 while (it->sp)
2926 pop_it (it);
2927 xassert (it->current.overlay_string_index == -1);
2928 xassert (it->method == GET_FROM_BUFFER);
2929 if (CHARPOS (pos->pos) == ZV)
2930 it->overlay_strings_at_end_processed_p = 1;
2932 #endif /* 0 */
2934 if (CHARPOS (pos->string_pos) >= 0)
2936 /* Recorded position is not in an overlay string, but in another
2937 string. This can only be a string from a `display' property.
2938 IT should already be filled with that string. */
2939 it->current.string_pos = pos->string_pos;
2940 xassert (STRINGP (it->string));
2943 /* Restore position in display vector translations, control
2944 character translations or ellipses. */
2945 if (pos->dpvec_index >= 0)
2947 if (it->dpvec == NULL)
2948 get_next_display_element (it);
2949 xassert (it->dpvec && it->current.dpvec_index == 0);
2950 it->current.dpvec_index = pos->dpvec_index;
2953 CHECK_IT (it);
2954 return !overlay_strings_with_newlines;
2958 /* Initialize IT for stepping through current_buffer in window W
2959 starting at ROW->start. */
2961 static void
2962 init_to_row_start (it, w, row)
2963 struct it *it;
2964 struct window *w;
2965 struct glyph_row *row;
2967 init_from_display_pos (it, w, &row->start);
2968 it->start = row->start;
2969 it->continuation_lines_width = row->continuation_lines_width;
2970 CHECK_IT (it);
2974 /* Initialize IT for stepping through current_buffer in window W
2975 starting in the line following ROW, i.e. starting at ROW->end.
2976 Value is zero if there are overlay strings with newlines at ROW's
2977 end position. */
2979 static int
2980 init_to_row_end (it, w, row)
2981 struct it *it;
2982 struct window *w;
2983 struct glyph_row *row;
2985 int success = 0;
2987 if (init_from_display_pos (it, w, &row->end))
2989 if (row->continued_p)
2990 it->continuation_lines_width
2991 = row->continuation_lines_width + row->pixel_width;
2992 CHECK_IT (it);
2993 success = 1;
2996 return success;
3002 /***********************************************************************
3003 Text properties
3004 ***********************************************************************/
3006 /* Called when IT reaches IT->stop_charpos. Handle text property and
3007 overlay changes. Set IT->stop_charpos to the next position where
3008 to stop. */
3010 static void
3011 handle_stop (it)
3012 struct it *it;
3014 enum prop_handled handled;
3015 int handle_overlay_change_p;
3016 struct props *p;
3018 it->dpvec = NULL;
3019 it->current.dpvec_index = -1;
3020 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
3021 it->ignore_overlay_strings_at_pos_p = 0;
3023 /* Use face of preceding text for ellipsis (if invisible) */
3024 if (it->selective_display_ellipsis_p)
3025 it->saved_face_id = it->face_id;
3029 handled = HANDLED_NORMALLY;
3031 /* Call text property handlers. */
3032 for (p = it_props; p->handler; ++p)
3034 handled = p->handler (it);
3036 if (handled == HANDLED_RECOMPUTE_PROPS)
3037 break;
3038 else if (handled == HANDLED_RETURN)
3040 /* We still want to show before and after strings from
3041 overlays even if the actual buffer text is replaced. */
3042 if (!handle_overlay_change_p || it->sp > 1)
3043 return;
3044 if (!get_overlay_strings_1 (it, 0, 0))
3045 return;
3046 it->ignore_overlay_strings_at_pos_p = 1;
3047 it->string_from_display_prop_p = 0;
3048 handle_overlay_change_p = 0;
3049 handled = HANDLED_RECOMPUTE_PROPS;
3050 break;
3052 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
3053 handle_overlay_change_p = 0;
3056 if (handled != HANDLED_RECOMPUTE_PROPS)
3058 /* Don't check for overlay strings below when set to deliver
3059 characters from a display vector. */
3060 if (it->method == GET_FROM_DISPLAY_VECTOR)
3061 handle_overlay_change_p = 0;
3063 /* Handle overlay changes. */
3064 if (handle_overlay_change_p)
3065 handled = handle_overlay_change (it);
3067 /* Determine where to stop next. */
3068 if (handled == HANDLED_NORMALLY)
3069 compute_stop_pos (it);
3072 while (handled == HANDLED_RECOMPUTE_PROPS);
3076 /* Compute IT->stop_charpos from text property and overlay change
3077 information for IT's current position. */
3079 static void
3080 compute_stop_pos (it)
3081 struct it *it;
3083 register INTERVAL iv, next_iv;
3084 Lisp_Object object, limit, position;
3086 /* If nowhere else, stop at the end. */
3087 it->stop_charpos = it->end_charpos;
3089 if (STRINGP (it->string))
3091 /* Strings are usually short, so don't limit the search for
3092 properties. */
3093 object = it->string;
3094 limit = Qnil;
3095 position = make_number (IT_STRING_CHARPOS (*it));
3097 else
3099 int charpos;
3101 /* If next overlay change is in front of the current stop pos
3102 (which is IT->end_charpos), stop there. Note: value of
3103 next_overlay_change is point-max if no overlay change
3104 follows. */
3105 charpos = next_overlay_change (IT_CHARPOS (*it));
3106 if (charpos < it->stop_charpos)
3107 it->stop_charpos = charpos;
3109 /* If showing the region, we have to stop at the region
3110 start or end because the face might change there. */
3111 if (it->region_beg_charpos > 0)
3113 if (IT_CHARPOS (*it) < it->region_beg_charpos)
3114 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
3115 else if (IT_CHARPOS (*it) < it->region_end_charpos)
3116 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
3119 /* Set up variables for computing the stop position from text
3120 property changes. */
3121 XSETBUFFER (object, current_buffer);
3122 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3123 position = make_number (IT_CHARPOS (*it));
3127 /* Get the interval containing IT's position. Value is a null
3128 interval if there isn't such an interval. */
3129 iv = validate_interval_range (object, &position, &position, 0);
3130 if (!NULL_INTERVAL_P (iv))
3132 Lisp_Object values_here[LAST_PROP_IDX];
3133 struct props *p;
3135 /* Get properties here. */
3136 for (p = it_props; p->handler; ++p)
3137 values_here[p->idx] = textget (iv->plist, *p->name);
3139 /* Look for an interval following iv that has different
3140 properties. */
3141 for (next_iv = next_interval (iv);
3142 (!NULL_INTERVAL_P (next_iv)
3143 && (NILP (limit)
3144 || XFASTINT (limit) > next_iv->position));
3145 next_iv = next_interval (next_iv))
3147 for (p = it_props; p->handler; ++p)
3149 Lisp_Object new_value;
3151 new_value = textget (next_iv->plist, *p->name);
3152 if (!EQ (values_here[p->idx], new_value))
3153 break;
3156 if (p->handler)
3157 break;
3160 if (!NULL_INTERVAL_P (next_iv))
3162 if (INTEGERP (limit)
3163 && next_iv->position >= XFASTINT (limit))
3164 /* No text property change up to limit. */
3165 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3166 else
3167 /* Text properties change in next_iv. */
3168 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3172 xassert (STRINGP (it->string)
3173 || (it->stop_charpos >= BEGV
3174 && it->stop_charpos >= IT_CHARPOS (*it)));
3178 /* Return the position of the next overlay change after POS in
3179 current_buffer. Value is point-max if no overlay change
3180 follows. This is like `next-overlay-change' but doesn't use
3181 xmalloc. */
3183 static int
3184 next_overlay_change (pos)
3185 int pos;
3187 int noverlays;
3188 int endpos;
3189 Lisp_Object *overlays;
3190 int i;
3192 /* Get all overlays at the given position. */
3193 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
3195 /* If any of these overlays ends before endpos,
3196 use its ending point instead. */
3197 for (i = 0; i < noverlays; ++i)
3199 Lisp_Object oend;
3200 int oendpos;
3202 oend = OVERLAY_END (overlays[i]);
3203 oendpos = OVERLAY_POSITION (oend);
3204 endpos = min (endpos, oendpos);
3207 return endpos;
3212 /***********************************************************************
3213 Fontification
3214 ***********************************************************************/
3216 /* Handle changes in the `fontified' property of the current buffer by
3217 calling hook functions from Qfontification_functions to fontify
3218 regions of text. */
3220 static enum prop_handled
3221 handle_fontified_prop (it)
3222 struct it *it;
3224 Lisp_Object prop, pos;
3225 enum prop_handled handled = HANDLED_NORMALLY;
3227 if (!NILP (Vmemory_full))
3228 return handled;
3230 /* Get the value of the `fontified' property at IT's current buffer
3231 position. (The `fontified' property doesn't have a special
3232 meaning in strings.) If the value is nil, call functions from
3233 Qfontification_functions. */
3234 if (!STRINGP (it->string)
3235 && it->s == NULL
3236 && !NILP (Vfontification_functions)
3237 && !NILP (Vrun_hooks)
3238 && (pos = make_number (IT_CHARPOS (*it)),
3239 prop = Fget_char_property (pos, Qfontified, Qnil),
3240 /* Ignore the special cased nil value always present at EOB since
3241 no amount of fontifying will be able to change it. */
3242 NILP (prop) && IT_CHARPOS (*it) < Z))
3244 int count = SPECPDL_INDEX ();
3245 Lisp_Object val;
3247 val = Vfontification_functions;
3248 specbind (Qfontification_functions, Qnil);
3250 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3251 safe_call1 (val, pos);
3252 else
3254 Lisp_Object globals, fn;
3255 struct gcpro gcpro1, gcpro2;
3257 globals = Qnil;
3258 GCPRO2 (val, globals);
3260 for (; CONSP (val); val = XCDR (val))
3262 fn = XCAR (val);
3264 if (EQ (fn, Qt))
3266 /* A value of t indicates this hook has a local
3267 binding; it means to run the global binding too.
3268 In a global value, t should not occur. If it
3269 does, we must ignore it to avoid an endless
3270 loop. */
3271 for (globals = Fdefault_value (Qfontification_functions);
3272 CONSP (globals);
3273 globals = XCDR (globals))
3275 fn = XCAR (globals);
3276 if (!EQ (fn, Qt))
3277 safe_call1 (fn, pos);
3280 else
3281 safe_call1 (fn, pos);
3284 UNGCPRO;
3287 unbind_to (count, Qnil);
3289 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3290 something. This avoids an endless loop if they failed to
3291 fontify the text for which reason ever. */
3292 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3293 handled = HANDLED_RECOMPUTE_PROPS;
3296 return handled;
3301 /***********************************************************************
3302 Faces
3303 ***********************************************************************/
3305 /* Set up iterator IT from face properties at its current position.
3306 Called from handle_stop. */
3308 static enum prop_handled
3309 handle_face_prop (it)
3310 struct it *it;
3312 int new_face_id, next_stop;
3314 if (!STRINGP (it->string))
3316 new_face_id
3317 = face_at_buffer_position (it->w,
3318 IT_CHARPOS (*it),
3319 it->region_beg_charpos,
3320 it->region_end_charpos,
3321 &next_stop,
3322 (IT_CHARPOS (*it)
3323 + TEXT_PROP_DISTANCE_LIMIT),
3326 /* Is this a start of a run of characters with box face?
3327 Caveat: this can be called for a freshly initialized
3328 iterator; face_id is -1 in this case. We know that the new
3329 face will not change until limit, i.e. if the new face has a
3330 box, all characters up to limit will have one. But, as
3331 usual, we don't know whether limit is really the end. */
3332 if (new_face_id != it->face_id)
3334 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3336 /* If new face has a box but old face has not, this is
3337 the start of a run of characters with box, i.e. it has
3338 a shadow on the left side. The value of face_id of the
3339 iterator will be -1 if this is the initial call that gets
3340 the face. In this case, we have to look in front of IT's
3341 position and see whether there is a face != new_face_id. */
3342 it->start_of_box_run_p
3343 = (new_face->box != FACE_NO_BOX
3344 && (it->face_id >= 0
3345 || IT_CHARPOS (*it) == BEG
3346 || new_face_id != face_before_it_pos (it)));
3347 it->face_box_p = new_face->box != FACE_NO_BOX;
3350 else
3352 int base_face_id, bufpos;
3354 if (it->current.overlay_string_index >= 0)
3355 bufpos = IT_CHARPOS (*it);
3356 else
3357 bufpos = 0;
3359 /* For strings from a buffer, i.e. overlay strings or strings
3360 from a `display' property, use the face at IT's current
3361 buffer position as the base face to merge with, so that
3362 overlay strings appear in the same face as surrounding
3363 text, unless they specify their own faces. */
3364 base_face_id = underlying_face_id (it);
3366 new_face_id = face_at_string_position (it->w,
3367 it->string,
3368 IT_STRING_CHARPOS (*it),
3369 bufpos,
3370 it->region_beg_charpos,
3371 it->region_end_charpos,
3372 &next_stop,
3373 base_face_id, 0);
3375 #if 0 /* This shouldn't be neccessary. Let's check it. */
3376 /* If IT is used to display a mode line we would really like to
3377 use the mode line face instead of the frame's default face. */
3378 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
3379 && new_face_id == DEFAULT_FACE_ID)
3380 new_face_id = CURRENT_MODE_LINE_FACE_ID (it->w);
3381 #endif
3383 /* Is this a start of a run of characters with box? Caveat:
3384 this can be called for a freshly allocated iterator; face_id
3385 is -1 is this case. We know that the new face will not
3386 change until the next check pos, i.e. if the new face has a
3387 box, all characters up to that position will have a
3388 box. But, as usual, we don't know whether that position
3389 is really the end. */
3390 if (new_face_id != it->face_id)
3392 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3393 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3395 /* If new face has a box but old face hasn't, this is the
3396 start of a run of characters with box, i.e. it has a
3397 shadow on the left side. */
3398 it->start_of_box_run_p
3399 = new_face->box && (old_face == NULL || !old_face->box);
3400 it->face_box_p = new_face->box != FACE_NO_BOX;
3404 it->face_id = new_face_id;
3405 return HANDLED_NORMALLY;
3409 /* Return the ID of the face ``underlying'' IT's current position,
3410 which is in a string. If the iterator is associated with a
3411 buffer, return the face at IT's current buffer position.
3412 Otherwise, use the iterator's base_face_id. */
3414 static int
3415 underlying_face_id (it)
3416 struct it *it;
3418 int face_id = it->base_face_id, i;
3420 xassert (STRINGP (it->string));
3422 for (i = it->sp - 1; i >= 0; --i)
3423 if (NILP (it->stack[i].string))
3424 face_id = it->stack[i].face_id;
3426 return face_id;
3430 /* Compute the face one character before or after the current position
3431 of IT. BEFORE_P non-zero means get the face in front of IT's
3432 position. Value is the id of the face. */
3434 static int
3435 face_before_or_after_it_pos (it, before_p)
3436 struct it *it;
3437 int before_p;
3439 int face_id, limit;
3440 int next_check_charpos;
3441 struct text_pos pos;
3443 xassert (it->s == NULL);
3445 if (STRINGP (it->string))
3447 int bufpos, base_face_id;
3449 /* No face change past the end of the string (for the case
3450 we are padding with spaces). No face change before the
3451 string start. */
3452 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
3453 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
3454 return it->face_id;
3456 /* Set pos to the position before or after IT's current position. */
3457 if (before_p)
3458 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
3459 else
3460 /* For composition, we must check the character after the
3461 composition. */
3462 pos = (it->what == IT_COMPOSITION
3463 ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string)
3464 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
3466 if (it->current.overlay_string_index >= 0)
3467 bufpos = IT_CHARPOS (*it);
3468 else
3469 bufpos = 0;
3471 base_face_id = underlying_face_id (it);
3473 /* Get the face for ASCII, or unibyte. */
3474 face_id = face_at_string_position (it->w,
3475 it->string,
3476 CHARPOS (pos),
3477 bufpos,
3478 it->region_beg_charpos,
3479 it->region_end_charpos,
3480 &next_check_charpos,
3481 base_face_id, 0);
3483 /* Correct the face for charsets different from ASCII. Do it
3484 for the multibyte case only. The face returned above is
3485 suitable for unibyte text if IT->string is unibyte. */
3486 if (STRING_MULTIBYTE (it->string))
3488 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
3489 int rest = SBYTES (it->string) - BYTEPOS (pos);
3490 int c, len;
3491 struct face *face = FACE_FROM_ID (it->f, face_id);
3493 c = string_char_and_length (p, rest, &len);
3494 face_id = FACE_FOR_CHAR (it->f, face, c);
3497 else
3499 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3500 || (IT_CHARPOS (*it) <= BEGV && before_p))
3501 return it->face_id;
3503 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3504 pos = it->current.pos;
3506 if (before_p)
3507 DEC_TEXT_POS (pos, it->multibyte_p);
3508 else
3510 if (it->what == IT_COMPOSITION)
3511 /* For composition, we must check the position after the
3512 composition. */
3513 pos.charpos += it->cmp_len, pos.bytepos += it->len;
3514 else
3515 INC_TEXT_POS (pos, it->multibyte_p);
3518 /* Determine face for CHARSET_ASCII, or unibyte. */
3519 face_id = face_at_buffer_position (it->w,
3520 CHARPOS (pos),
3521 it->region_beg_charpos,
3522 it->region_end_charpos,
3523 &next_check_charpos,
3524 limit, 0);
3526 /* Correct the face for charsets different from ASCII. Do it
3527 for the multibyte case only. The face returned above is
3528 suitable for unibyte text if current_buffer is unibyte. */
3529 if (it->multibyte_p)
3531 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3532 struct face *face = FACE_FROM_ID (it->f, face_id);
3533 face_id = FACE_FOR_CHAR (it->f, face, c);
3537 return face_id;
3542 /***********************************************************************
3543 Invisible text
3544 ***********************************************************************/
3546 /* Set up iterator IT from invisible properties at its current
3547 position. Called from handle_stop. */
3549 static enum prop_handled
3550 handle_invisible_prop (it)
3551 struct it *it;
3553 enum prop_handled handled = HANDLED_NORMALLY;
3555 if (STRINGP (it->string))
3557 extern Lisp_Object Qinvisible;
3558 Lisp_Object prop, end_charpos, limit, charpos;
3560 /* Get the value of the invisible text property at the
3561 current position. Value will be nil if there is no such
3562 property. */
3563 charpos = make_number (IT_STRING_CHARPOS (*it));
3564 prop = Fget_text_property (charpos, Qinvisible, it->string);
3566 if (!NILP (prop)
3567 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3569 handled = HANDLED_RECOMPUTE_PROPS;
3571 /* Get the position at which the next change of the
3572 invisible text property can be found in IT->string.
3573 Value will be nil if the property value is the same for
3574 all the rest of IT->string. */
3575 XSETINT (limit, SCHARS (it->string));
3576 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3577 it->string, limit);
3579 /* Text at current position is invisible. The next
3580 change in the property is at position end_charpos.
3581 Move IT's current position to that position. */
3582 if (INTEGERP (end_charpos)
3583 && XFASTINT (end_charpos) < XFASTINT (limit))
3585 struct text_pos old;
3586 old = it->current.string_pos;
3587 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3588 compute_string_pos (&it->current.string_pos, old, it->string);
3590 else
3592 /* The rest of the string is invisible. If this is an
3593 overlay string, proceed with the next overlay string
3594 or whatever comes and return a character from there. */
3595 if (it->current.overlay_string_index >= 0)
3597 next_overlay_string (it);
3598 /* Don't check for overlay strings when we just
3599 finished processing them. */
3600 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3602 else
3604 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3605 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3610 else
3612 int invis_p;
3613 EMACS_INT newpos, next_stop, start_charpos;
3614 Lisp_Object pos, prop, overlay;
3616 /* First of all, is there invisible text at this position? */
3617 start_charpos = IT_CHARPOS (*it);
3618 pos = make_number (IT_CHARPOS (*it));
3619 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3620 &overlay);
3621 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3623 /* If we are on invisible text, skip over it. */
3624 if (invis_p && IT_CHARPOS (*it) < it->end_charpos)
3626 /* Record whether we have to display an ellipsis for the
3627 invisible text. */
3628 int display_ellipsis_p = invis_p == 2;
3630 handled = HANDLED_RECOMPUTE_PROPS;
3632 /* Loop skipping over invisible text. The loop is left at
3633 ZV or with IT on the first char being visible again. */
3636 /* Try to skip some invisible text. Return value is the
3637 position reached which can be equal to IT's position
3638 if there is nothing invisible here. This skips both
3639 over invisible text properties and overlays with
3640 invisible property. */
3641 newpos = skip_invisible (IT_CHARPOS (*it),
3642 &next_stop, ZV, it->window);
3644 /* If we skipped nothing at all we weren't at invisible
3645 text in the first place. If everything to the end of
3646 the buffer was skipped, end the loop. */
3647 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
3648 invis_p = 0;
3649 else
3651 /* We skipped some characters but not necessarily
3652 all there are. Check if we ended up on visible
3653 text. Fget_char_property returns the property of
3654 the char before the given position, i.e. if we
3655 get invis_p = 0, this means that the char at
3656 newpos is visible. */
3657 pos = make_number (newpos);
3658 prop = Fget_char_property (pos, Qinvisible, it->window);
3659 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3662 /* If we ended up on invisible text, proceed to
3663 skip starting with next_stop. */
3664 if (invis_p)
3665 IT_CHARPOS (*it) = next_stop;
3667 /* If there are adjacent invisible texts, don't lose the
3668 second one's ellipsis. */
3669 if (invis_p == 2)
3670 display_ellipsis_p = 1;
3672 while (invis_p);
3674 /* The position newpos is now either ZV or on visible text. */
3675 IT_CHARPOS (*it) = newpos;
3676 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3678 /* If there are before-strings at the start of invisible
3679 text, and the text is invisible because of a text
3680 property, arrange to show before-strings because 20.x did
3681 it that way. (If the text is invisible because of an
3682 overlay property instead of a text property, this is
3683 already handled in the overlay code.) */
3684 if (NILP (overlay)
3685 && get_overlay_strings (it, start_charpos))
3687 handled = HANDLED_RECOMPUTE_PROPS;
3688 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3690 else if (display_ellipsis_p)
3692 /* Make sure that the glyphs of the ellipsis will get
3693 correct `charpos' values. If we would not update
3694 it->position here, the glyphs would belong to the
3695 last visible character _before_ the invisible
3696 text, which confuses `set_cursor_from_row'.
3698 We use the last invisible position instead of the
3699 first because this way the cursor is always drawn on
3700 the first "." of the ellipsis, whenever PT is inside
3701 the invisible text. Otherwise the cursor would be
3702 placed _after_ the ellipsis when the point is after the
3703 first invisible character. */
3704 if (!STRINGP (it->object))
3706 it->position.charpos = IT_CHARPOS (*it) - 1;
3707 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
3709 setup_for_ellipsis (it, 0);
3710 /* Let the ellipsis display before
3711 considering any properties of the following char.
3712 Fixes jasonr@gnu.org 01 Oct 07 bug. */
3713 handled = HANDLED_RETURN;
3718 return handled;
3722 /* Make iterator IT return `...' next.
3723 Replaces LEN characters from buffer. */
3725 static void
3726 setup_for_ellipsis (it, len)
3727 struct it *it;
3728 int len;
3730 /* Use the display table definition for `...'. Invalid glyphs
3731 will be handled by the method returning elements from dpvec. */
3732 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3734 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3735 it->dpvec = v->contents;
3736 it->dpend = v->contents + v->size;
3738 else
3740 /* Default `...'. */
3741 it->dpvec = default_invis_vector;
3742 it->dpend = default_invis_vector + 3;
3745 it->dpvec_char_len = len;
3746 it->current.dpvec_index = 0;
3747 it->dpvec_face_id = -1;
3749 /* Remember the current face id in case glyphs specify faces.
3750 IT's face is restored in set_iterator_to_next.
3751 saved_face_id was set to preceding char's face in handle_stop. */
3752 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
3753 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
3755 it->method = GET_FROM_DISPLAY_VECTOR;
3756 it->ellipsis_p = 1;
3761 /***********************************************************************
3762 'display' property
3763 ***********************************************************************/
3765 /* Set up iterator IT from `display' property at its current position.
3766 Called from handle_stop.
3767 We return HANDLED_RETURN if some part of the display property
3768 overrides the display of the buffer text itself.
3769 Otherwise we return HANDLED_NORMALLY. */
3771 static enum prop_handled
3772 handle_display_prop (it)
3773 struct it *it;
3775 Lisp_Object prop, object;
3776 struct text_pos *position;
3777 /* Nonzero if some property replaces the display of the text itself. */
3778 int display_replaced_p = 0;
3780 if (STRINGP (it->string))
3782 object = it->string;
3783 position = &it->current.string_pos;
3785 else
3787 XSETWINDOW (object, it->w);
3788 position = &it->current.pos;
3791 /* Reset those iterator values set from display property values. */
3792 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
3793 it->space_width = Qnil;
3794 it->font_height = Qnil;
3795 it->voffset = 0;
3797 /* We don't support recursive `display' properties, i.e. string
3798 values that have a string `display' property, that have a string
3799 `display' property etc. */
3800 if (!it->string_from_display_prop_p)
3801 it->area = TEXT_AREA;
3803 prop = Fget_char_property (make_number (position->charpos),
3804 Qdisplay, object);
3805 if (NILP (prop))
3806 return HANDLED_NORMALLY;
3808 if (!STRINGP (it->string))
3809 object = it->w->buffer;
3811 if (CONSP (prop)
3812 /* Simple properties. */
3813 && !EQ (XCAR (prop), Qimage)
3814 && !EQ (XCAR (prop), Qspace)
3815 && !EQ (XCAR (prop), Qwhen)
3816 && !EQ (XCAR (prop), Qslice)
3817 && !EQ (XCAR (prop), Qspace_width)
3818 && !EQ (XCAR (prop), Qheight)
3819 && !EQ (XCAR (prop), Qraise)
3820 /* Marginal area specifications. */
3821 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
3822 && !EQ (XCAR (prop), Qleft_fringe)
3823 && !EQ (XCAR (prop), Qright_fringe)
3824 && !NILP (XCAR (prop)))
3826 for (; CONSP (prop); prop = XCDR (prop))
3828 if (handle_single_display_spec (it, XCAR (prop), object,
3829 position, display_replaced_p))
3831 display_replaced_p = 1;
3832 /* If some text in a string is replaced, `position' no
3833 longer points to the position of `object'. */
3834 if (STRINGP (object))
3835 break;
3839 else if (VECTORP (prop))
3841 int i;
3842 for (i = 0; i < ASIZE (prop); ++i)
3843 if (handle_single_display_spec (it, AREF (prop, i), object,
3844 position, display_replaced_p))
3846 display_replaced_p = 1;
3847 /* If some text in a string is replaced, `position' no
3848 longer points to the position of `object'. */
3849 if (STRINGP (object))
3850 break;
3853 else
3855 int ret = handle_single_display_spec (it, prop, object, position, 0);
3856 if (ret < 0) /* Replaced by "", i.e. nothing. */
3857 return HANDLED_RECOMPUTE_PROPS;
3858 if (ret)
3859 display_replaced_p = 1;
3862 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
3866 /* Value is the position of the end of the `display' property starting
3867 at START_POS in OBJECT. */
3869 static struct text_pos
3870 display_prop_end (it, object, start_pos)
3871 struct it *it;
3872 Lisp_Object object;
3873 struct text_pos start_pos;
3875 Lisp_Object end;
3876 struct text_pos end_pos;
3878 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
3879 Qdisplay, object, Qnil);
3880 CHARPOS (end_pos) = XFASTINT (end);
3881 if (STRINGP (object))
3882 compute_string_pos (&end_pos, start_pos, it->string);
3883 else
3884 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
3886 return end_pos;
3890 /* Set up IT from a single `display' specification PROP. OBJECT
3891 is the object in which the `display' property was found. *POSITION
3892 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3893 means that we previously saw a display specification which already
3894 replaced text display with something else, for example an image;
3895 we ignore such properties after the first one has been processed.
3897 If PROP is a `space' or `image' specification, and in some other
3898 cases too, set *POSITION to the position where the `display'
3899 property ends.
3901 Value is non-zero if something was found which replaces the display
3902 of buffer or string text. Specifically, the value is -1 if that
3903 "something" is "nothing". */
3905 static int
3906 handle_single_display_spec (it, spec, object, position,
3907 display_replaced_before_p)
3908 struct it *it;
3909 Lisp_Object spec;
3910 Lisp_Object object;
3911 struct text_pos *position;
3912 int display_replaced_before_p;
3914 Lisp_Object form;
3915 Lisp_Object location, value;
3916 struct text_pos start_pos, save_pos;
3917 int valid_p;
3919 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
3920 If the result is non-nil, use VALUE instead of SPEC. */
3921 form = Qt;
3922 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
3924 spec = XCDR (spec);
3925 if (!CONSP (spec))
3926 return 0;
3927 form = XCAR (spec);
3928 spec = XCDR (spec);
3931 if (!NILP (form) && !EQ (form, Qt))
3933 int count = SPECPDL_INDEX ();
3934 struct gcpro gcpro1;
3936 /* Bind `object' to the object having the `display' property, a
3937 buffer or string. Bind `position' to the position in the
3938 object where the property was found, and `buffer-position'
3939 to the current position in the buffer. */
3940 specbind (Qobject, object);
3941 specbind (Qposition, make_number (CHARPOS (*position)));
3942 specbind (Qbuffer_position,
3943 make_number (STRINGP (object)
3944 ? IT_CHARPOS (*it) : CHARPOS (*position)));
3945 GCPRO1 (form);
3946 form = safe_eval (form);
3947 UNGCPRO;
3948 unbind_to (count, Qnil);
3951 if (NILP (form))
3952 return 0;
3954 /* Handle `(height HEIGHT)' specifications. */
3955 if (CONSP (spec)
3956 && EQ (XCAR (spec), Qheight)
3957 && CONSP (XCDR (spec)))
3959 if (!FRAME_WINDOW_P (it->f))
3960 return 0;
3962 it->font_height = XCAR (XCDR (spec));
3963 if (!NILP (it->font_height))
3965 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3966 int new_height = -1;
3968 if (CONSP (it->font_height)
3969 && (EQ (XCAR (it->font_height), Qplus)
3970 || EQ (XCAR (it->font_height), Qminus))
3971 && CONSP (XCDR (it->font_height))
3972 && INTEGERP (XCAR (XCDR (it->font_height))))
3974 /* `(+ N)' or `(- N)' where N is an integer. */
3975 int steps = XINT (XCAR (XCDR (it->font_height)));
3976 if (EQ (XCAR (it->font_height), Qplus))
3977 steps = - steps;
3978 it->face_id = smaller_face (it->f, it->face_id, steps);
3980 else if (FUNCTIONP (it->font_height))
3982 /* Call function with current height as argument.
3983 Value is the new height. */
3984 Lisp_Object height;
3985 height = safe_call1 (it->font_height,
3986 face->lface[LFACE_HEIGHT_INDEX]);
3987 if (NUMBERP (height))
3988 new_height = XFLOATINT (height);
3990 else if (NUMBERP (it->font_height))
3992 /* Value is a multiple of the canonical char height. */
3993 struct face *face;
3995 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
3996 new_height = (XFLOATINT (it->font_height)
3997 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
3999 else
4001 /* Evaluate IT->font_height with `height' bound to the
4002 current specified height to get the new height. */
4003 int count = SPECPDL_INDEX ();
4005 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
4006 value = safe_eval (it->font_height);
4007 unbind_to (count, Qnil);
4009 if (NUMBERP (value))
4010 new_height = XFLOATINT (value);
4013 if (new_height > 0)
4014 it->face_id = face_with_height (it->f, it->face_id, new_height);
4017 return 0;
4020 /* Handle `(space_width WIDTH)'. */
4021 if (CONSP (spec)
4022 && EQ (XCAR (spec), Qspace_width)
4023 && CONSP (XCDR (spec)))
4025 if (!FRAME_WINDOW_P (it->f))
4026 return 0;
4028 value = XCAR (XCDR (spec));
4029 if (NUMBERP (value) && XFLOATINT (value) > 0)
4030 it->space_width = value;
4032 return 0;
4035 /* Handle `(slice X Y WIDTH HEIGHT)'. */
4036 if (CONSP (spec)
4037 && EQ (XCAR (spec), Qslice))
4039 Lisp_Object tem;
4041 if (!FRAME_WINDOW_P (it->f))
4042 return 0;
4044 if (tem = XCDR (spec), CONSP (tem))
4046 it->slice.x = XCAR (tem);
4047 if (tem = XCDR (tem), CONSP (tem))
4049 it->slice.y = XCAR (tem);
4050 if (tem = XCDR (tem), CONSP (tem))
4052 it->slice.width = XCAR (tem);
4053 if (tem = XCDR (tem), CONSP (tem))
4054 it->slice.height = XCAR (tem);
4059 return 0;
4062 /* Handle `(raise FACTOR)'. */
4063 if (CONSP (spec)
4064 && EQ (XCAR (spec), Qraise)
4065 && CONSP (XCDR (spec)))
4067 if (!FRAME_WINDOW_P (it->f))
4068 return 0;
4070 #ifdef HAVE_WINDOW_SYSTEM
4071 value = XCAR (XCDR (spec));
4072 if (NUMBERP (value))
4074 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4075 it->voffset = - (XFLOATINT (value)
4076 * (FONT_HEIGHT (face->font)));
4078 #endif /* HAVE_WINDOW_SYSTEM */
4080 return 0;
4083 /* Don't handle the other kinds of display specifications
4084 inside a string that we got from a `display' property. */
4085 if (it->string_from_display_prop_p)
4086 return 0;
4088 /* Characters having this form of property are not displayed, so
4089 we have to find the end of the property. */
4090 start_pos = *position;
4091 *position = display_prop_end (it, object, start_pos);
4092 value = Qnil;
4094 /* Stop the scan at that end position--we assume that all
4095 text properties change there. */
4096 it->stop_charpos = position->charpos;
4098 /* Handle `(left-fringe BITMAP [FACE])'
4099 and `(right-fringe BITMAP [FACE])'. */
4100 if (CONSP (spec)
4101 && (EQ (XCAR (spec), Qleft_fringe)
4102 || EQ (XCAR (spec), Qright_fringe))
4103 && CONSP (XCDR (spec)))
4105 int face_id = DEFAULT_FACE_ID;
4106 int fringe_bitmap;
4108 if (!FRAME_WINDOW_P (it->f))
4109 /* If we return here, POSITION has been advanced
4110 across the text with this property. */
4111 return 0;
4113 #ifdef HAVE_WINDOW_SYSTEM
4114 value = XCAR (XCDR (spec));
4115 if (!SYMBOLP (value)
4116 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
4117 /* If we return here, POSITION has been advanced
4118 across the text with this property. */
4119 return 0;
4121 if (CONSP (XCDR (XCDR (spec))))
4123 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
4124 int face_id2 = lookup_derived_face (it->f, face_name,
4125 'A', FRINGE_FACE_ID, 0);
4126 if (face_id2 >= 0)
4127 face_id = face_id2;
4130 /* Save current settings of IT so that we can restore them
4131 when we are finished with the glyph property value. */
4133 save_pos = it->position;
4134 it->position = *position;
4135 push_it (it);
4136 it->position = save_pos;
4138 it->area = TEXT_AREA;
4139 it->what = IT_IMAGE;
4140 it->image_id = -1; /* no image */
4141 it->position = start_pos;
4142 it->object = NILP (object) ? it->w->buffer : object;
4143 it->method = GET_FROM_IMAGE;
4144 it->face_id = face_id;
4146 /* Say that we haven't consumed the characters with
4147 `display' property yet. The call to pop_it in
4148 set_iterator_to_next will clean this up. */
4149 *position = start_pos;
4151 if (EQ (XCAR (spec), Qleft_fringe))
4153 it->left_user_fringe_bitmap = fringe_bitmap;
4154 it->left_user_fringe_face_id = face_id;
4156 else
4158 it->right_user_fringe_bitmap = fringe_bitmap;
4159 it->right_user_fringe_face_id = face_id;
4161 #endif /* HAVE_WINDOW_SYSTEM */
4162 return 1;
4165 /* Prepare to handle `((margin left-margin) ...)',
4166 `((margin right-margin) ...)' and `((margin nil) ...)'
4167 prefixes for display specifications. */
4168 location = Qunbound;
4169 if (CONSP (spec) && CONSP (XCAR (spec)))
4171 Lisp_Object tem;
4173 value = XCDR (spec);
4174 if (CONSP (value))
4175 value = XCAR (value);
4177 tem = XCAR (spec);
4178 if (EQ (XCAR (tem), Qmargin)
4179 && (tem = XCDR (tem),
4180 tem = CONSP (tem) ? XCAR (tem) : Qnil,
4181 (NILP (tem)
4182 || EQ (tem, Qleft_margin)
4183 || EQ (tem, Qright_margin))))
4184 location = tem;
4187 if (EQ (location, Qunbound))
4189 location = Qnil;
4190 value = spec;
4193 /* After this point, VALUE is the property after any
4194 margin prefix has been stripped. It must be a string,
4195 an image specification, or `(space ...)'.
4197 LOCATION specifies where to display: `left-margin',
4198 `right-margin' or nil. */
4200 valid_p = (STRINGP (value)
4201 #ifdef HAVE_WINDOW_SYSTEM
4202 || (FRAME_WINDOW_P (it->f) && valid_image_p (value))
4203 #endif /* not HAVE_WINDOW_SYSTEM */
4204 || (CONSP (value) && EQ (XCAR (value), Qspace)));
4206 if (valid_p && !display_replaced_before_p)
4208 /* Save current settings of IT so that we can restore them
4209 when we are finished with the glyph property value. */
4210 save_pos = it->position;
4211 it->position = *position;
4212 push_it (it);
4213 it->position = save_pos;
4215 if (NILP (location))
4216 it->area = TEXT_AREA;
4217 else if (EQ (location, Qleft_margin))
4218 it->area = LEFT_MARGIN_AREA;
4219 else
4220 it->area = RIGHT_MARGIN_AREA;
4222 if (STRINGP (value))
4224 if (SCHARS (value) == 0)
4226 pop_it (it);
4227 return -1; /* Replaced by "", i.e. nothing. */
4229 it->string = value;
4230 it->multibyte_p = STRING_MULTIBYTE (it->string);
4231 it->current.overlay_string_index = -1;
4232 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4233 it->end_charpos = it->string_nchars = SCHARS (it->string);
4234 it->method = GET_FROM_STRING;
4235 it->stop_charpos = 0;
4236 it->string_from_display_prop_p = 1;
4237 /* Say that we haven't consumed the characters with
4238 `display' property yet. The call to pop_it in
4239 set_iterator_to_next will clean this up. */
4240 if (BUFFERP (object))
4241 it->current.pos = start_pos;
4243 else if (CONSP (value) && EQ (XCAR (value), Qspace))
4245 it->method = GET_FROM_STRETCH;
4246 it->object = value;
4247 it->position = start_pos;
4248 if (BUFFERP (object))
4249 it->current.pos = start_pos;
4251 #ifdef HAVE_WINDOW_SYSTEM
4252 else
4254 it->what = IT_IMAGE;
4255 it->image_id = lookup_image (it->f, value);
4256 it->position = start_pos;
4257 it->object = NILP (object) ? it->w->buffer : object;
4258 it->method = GET_FROM_IMAGE;
4260 /* Say that we haven't consumed the characters with
4261 `display' property yet. The call to pop_it in
4262 set_iterator_to_next will clean this up. */
4263 if (BUFFERP (object))
4264 it->current.pos = start_pos;
4266 #endif /* HAVE_WINDOW_SYSTEM */
4268 return 1;
4271 /* Invalid property or property not supported. Restore
4272 POSITION to what it was before. */
4273 *position = start_pos;
4274 return 0;
4278 /* Check if SPEC is a display sub-property value whose text should be
4279 treated as intangible. */
4281 static int
4282 single_display_spec_intangible_p (prop)
4283 Lisp_Object prop;
4285 /* Skip over `when FORM'. */
4286 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
4288 prop = XCDR (prop);
4289 if (!CONSP (prop))
4290 return 0;
4291 prop = XCDR (prop);
4294 if (STRINGP (prop))
4295 return 1;
4297 if (!CONSP (prop))
4298 return 0;
4300 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
4301 we don't need to treat text as intangible. */
4302 if (EQ (XCAR (prop), Qmargin))
4304 prop = XCDR (prop);
4305 if (!CONSP (prop))
4306 return 0;
4308 prop = XCDR (prop);
4309 if (!CONSP (prop)
4310 || EQ (XCAR (prop), Qleft_margin)
4311 || EQ (XCAR (prop), Qright_margin))
4312 return 0;
4315 return (CONSP (prop)
4316 && (EQ (XCAR (prop), Qimage)
4317 || EQ (XCAR (prop), Qspace)));
4321 /* Check if PROP is a display property value whose text should be
4322 treated as intangible. */
4325 display_prop_intangible_p (prop)
4326 Lisp_Object prop;
4328 if (CONSP (prop)
4329 && CONSP (XCAR (prop))
4330 && !EQ (Qmargin, XCAR (XCAR (prop))))
4332 /* A list of sub-properties. */
4333 while (CONSP (prop))
4335 if (single_display_spec_intangible_p (XCAR (prop)))
4336 return 1;
4337 prop = XCDR (prop);
4340 else if (VECTORP (prop))
4342 /* A vector of sub-properties. */
4343 int i;
4344 for (i = 0; i < ASIZE (prop); ++i)
4345 if (single_display_spec_intangible_p (AREF (prop, i)))
4346 return 1;
4348 else
4349 return single_display_spec_intangible_p (prop);
4351 return 0;
4355 /* Return 1 if PROP is a display sub-property value containing STRING. */
4357 static int
4358 single_display_spec_string_p (prop, string)
4359 Lisp_Object prop, string;
4361 if (EQ (string, prop))
4362 return 1;
4364 /* Skip over `when FORM'. */
4365 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
4367 prop = XCDR (prop);
4368 if (!CONSP (prop))
4369 return 0;
4370 prop = XCDR (prop);
4373 if (CONSP (prop))
4374 /* Skip over `margin LOCATION'. */
4375 if (EQ (XCAR (prop), Qmargin))
4377 prop = XCDR (prop);
4378 if (!CONSP (prop))
4379 return 0;
4381 prop = XCDR (prop);
4382 if (!CONSP (prop))
4383 return 0;
4386 return CONSP (prop) && EQ (XCAR (prop), string);
4390 /* Return 1 if STRING appears in the `display' property PROP. */
4392 static int
4393 display_prop_string_p (prop, string)
4394 Lisp_Object prop, string;
4396 if (CONSP (prop)
4397 && CONSP (XCAR (prop))
4398 && !EQ (Qmargin, XCAR (XCAR (prop))))
4400 /* A list of sub-properties. */
4401 while (CONSP (prop))
4403 if (single_display_spec_string_p (XCAR (prop), string))
4404 return 1;
4405 prop = XCDR (prop);
4408 else if (VECTORP (prop))
4410 /* A vector of sub-properties. */
4411 int i;
4412 for (i = 0; i < ASIZE (prop); ++i)
4413 if (single_display_spec_string_p (AREF (prop, i), string))
4414 return 1;
4416 else
4417 return single_display_spec_string_p (prop, string);
4419 return 0;
4423 /* Determine from which buffer position in W's buffer STRING comes
4424 from. AROUND_CHARPOS is an approximate position where it could
4425 be from. Value is the buffer position or 0 if it couldn't be
4426 determined.
4428 W's buffer must be current.
4430 This function is necessary because we don't record buffer positions
4431 in glyphs generated from strings (to keep struct glyph small).
4432 This function may only use code that doesn't eval because it is
4433 called asynchronously from note_mouse_highlight. */
4436 string_buffer_position (w, string, around_charpos)
4437 struct window *w;
4438 Lisp_Object string;
4439 int around_charpos;
4441 Lisp_Object limit, prop, pos;
4442 const int MAX_DISTANCE = 1000;
4443 int found = 0;
4445 pos = make_number (around_charpos);
4446 limit = make_number (min (XINT (pos) + MAX_DISTANCE, ZV));
4447 while (!found && !EQ (pos, limit))
4449 prop = Fget_char_property (pos, Qdisplay, Qnil);
4450 if (!NILP (prop) && display_prop_string_p (prop, string))
4451 found = 1;
4452 else
4453 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil, limit);
4456 if (!found)
4458 pos = make_number (around_charpos);
4459 limit = make_number (max (XINT (pos) - MAX_DISTANCE, BEGV));
4460 while (!found && !EQ (pos, limit))
4462 prop = Fget_char_property (pos, Qdisplay, Qnil);
4463 if (!NILP (prop) && display_prop_string_p (prop, string))
4464 found = 1;
4465 else
4466 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
4467 limit);
4471 return found ? XINT (pos) : 0;
4476 /***********************************************************************
4477 `composition' property
4478 ***********************************************************************/
4480 /* Set up iterator IT from `composition' property at its current
4481 position. Called from handle_stop. */
4483 static enum prop_handled
4484 handle_composition_prop (it)
4485 struct it *it;
4487 Lisp_Object prop, string;
4488 int pos, pos_byte, end;
4489 enum prop_handled handled = HANDLED_NORMALLY;
4491 if (STRINGP (it->string))
4493 pos = IT_STRING_CHARPOS (*it);
4494 pos_byte = IT_STRING_BYTEPOS (*it);
4495 string = it->string;
4497 else
4499 pos = IT_CHARPOS (*it);
4500 pos_byte = IT_BYTEPOS (*it);
4501 string = Qnil;
4504 /* If there's a valid composition and point is not inside of the
4505 composition (in the case that the composition is from the current
4506 buffer), draw a glyph composed from the composition components. */
4507 if (find_composition (pos, -1, &pos, &end, &prop, string)
4508 && COMPOSITION_VALID_P (pos, end, prop)
4509 && (STRINGP (it->string) || (PT <= pos || PT >= end)))
4511 int id = get_composition_id (pos, pos_byte, end - pos, prop, string);
4513 if (id >= 0)
4515 struct composition *cmp = composition_table[id];
4517 if (cmp->glyph_len == 0)
4519 /* No glyph. */
4520 if (STRINGP (it->string))
4522 IT_STRING_CHARPOS (*it) = end;
4523 IT_STRING_BYTEPOS (*it) = string_char_to_byte (it->string,
4524 end);
4526 else
4528 IT_CHARPOS (*it) = end;
4529 IT_BYTEPOS (*it) = CHAR_TO_BYTE (end);
4531 return HANDLED_RECOMPUTE_PROPS;
4534 it->stop_charpos = end;
4535 push_it (it);
4537 it->method = GET_FROM_COMPOSITION;
4538 it->cmp_id = id;
4539 it->cmp_len = COMPOSITION_LENGTH (prop);
4540 /* For a terminal, draw only the first character of the
4541 components. */
4542 it->c = COMPOSITION_GLYPH (composition_table[id], 0);
4543 it->len = (STRINGP (it->string)
4544 ? string_char_to_byte (it->string, end)
4545 : CHAR_TO_BYTE (end)) - pos_byte;
4546 handled = HANDLED_RETURN;
4550 return handled;
4555 /***********************************************************************
4556 Overlay strings
4557 ***********************************************************************/
4559 /* The following structure is used to record overlay strings for
4560 later sorting in load_overlay_strings. */
4562 struct overlay_entry
4564 Lisp_Object overlay;
4565 Lisp_Object string;
4566 int priority;
4567 int after_string_p;
4571 /* Set up iterator IT from overlay strings at its current position.
4572 Called from handle_stop. */
4574 static enum prop_handled
4575 handle_overlay_change (it)
4576 struct it *it;
4578 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
4579 return HANDLED_RECOMPUTE_PROPS;
4580 else
4581 return HANDLED_NORMALLY;
4585 /* Set up the next overlay string for delivery by IT, if there is an
4586 overlay string to deliver. Called by set_iterator_to_next when the
4587 end of the current overlay string is reached. If there are more
4588 overlay strings to display, IT->string and
4589 IT->current.overlay_string_index are set appropriately here.
4590 Otherwise IT->string is set to nil. */
4592 static void
4593 next_overlay_string (it)
4594 struct it *it;
4596 ++it->current.overlay_string_index;
4597 if (it->current.overlay_string_index == it->n_overlay_strings)
4599 /* No more overlay strings. Restore IT's settings to what
4600 they were before overlay strings were processed, and
4601 continue to deliver from current_buffer. */
4602 int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
4604 pop_it (it);
4605 xassert (it->sp > 0
4606 || it->method == GET_FROM_COMPOSITION
4607 || (NILP (it->string)
4608 && it->method == GET_FROM_BUFFER
4609 && it->stop_charpos >= BEGV
4610 && it->stop_charpos <= it->end_charpos));
4611 it->current.overlay_string_index = -1;
4612 it->n_overlay_strings = 0;
4614 /* If we're at the end of the buffer, record that we have
4615 processed the overlay strings there already, so that
4616 next_element_from_buffer doesn't try it again. */
4617 if (IT_CHARPOS (*it) >= it->end_charpos)
4618 it->overlay_strings_at_end_processed_p = 1;
4620 /* If we have to display `...' for invisible text, set
4621 the iterator up for that. */
4622 if (display_ellipsis_p)
4623 setup_for_ellipsis (it, 0);
4625 else
4627 /* There are more overlay strings to process. If
4628 IT->current.overlay_string_index has advanced to a position
4629 where we must load IT->overlay_strings with more strings, do
4630 it. */
4631 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
4633 if (it->current.overlay_string_index && i == 0)
4634 load_overlay_strings (it, 0);
4636 /* Initialize IT to deliver display elements from the overlay
4637 string. */
4638 it->string = it->overlay_strings[i];
4639 it->multibyte_p = STRING_MULTIBYTE (it->string);
4640 SET_TEXT_POS (it->current.string_pos, 0, 0);
4641 it->method = GET_FROM_STRING;
4642 it->stop_charpos = 0;
4645 CHECK_IT (it);
4649 /* Compare two overlay_entry structures E1 and E2. Used as a
4650 comparison function for qsort in load_overlay_strings. Overlay
4651 strings for the same position are sorted so that
4653 1. All after-strings come in front of before-strings, except
4654 when they come from the same overlay.
4656 2. Within after-strings, strings are sorted so that overlay strings
4657 from overlays with higher priorities come first.
4659 2. Within before-strings, strings are sorted so that overlay
4660 strings from overlays with higher priorities come last.
4662 Value is analogous to strcmp. */
4665 static int
4666 compare_overlay_entries (e1, e2)
4667 void *e1, *e2;
4669 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4670 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4671 int result;
4673 if (entry1->after_string_p != entry2->after_string_p)
4675 /* Let after-strings appear in front of before-strings if
4676 they come from different overlays. */
4677 if (EQ (entry1->overlay, entry2->overlay))
4678 result = entry1->after_string_p ? 1 : -1;
4679 else
4680 result = entry1->after_string_p ? -1 : 1;
4682 else if (entry1->after_string_p)
4683 /* After-strings sorted in order of decreasing priority. */
4684 result = entry2->priority - entry1->priority;
4685 else
4686 /* Before-strings sorted in order of increasing priority. */
4687 result = entry1->priority - entry2->priority;
4689 return result;
4693 /* Load the vector IT->overlay_strings with overlay strings from IT's
4694 current buffer position, or from CHARPOS if that is > 0. Set
4695 IT->n_overlays to the total number of overlay strings found.
4697 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4698 a time. On entry into load_overlay_strings,
4699 IT->current.overlay_string_index gives the number of overlay
4700 strings that have already been loaded by previous calls to this
4701 function.
4703 IT->add_overlay_start contains an additional overlay start
4704 position to consider for taking overlay strings from, if non-zero.
4705 This position comes into play when the overlay has an `invisible'
4706 property, and both before and after-strings. When we've skipped to
4707 the end of the overlay, because of its `invisible' property, we
4708 nevertheless want its before-string to appear.
4709 IT->add_overlay_start will contain the overlay start position
4710 in this case.
4712 Overlay strings are sorted so that after-string strings come in
4713 front of before-string strings. Within before and after-strings,
4714 strings are sorted by overlay priority. See also function
4715 compare_overlay_entries. */
4717 static void
4718 load_overlay_strings (it, charpos)
4719 struct it *it;
4720 int charpos;
4722 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
4723 Lisp_Object overlay, window, str, invisible;
4724 struct Lisp_Overlay *ov;
4725 int start, end;
4726 int size = 20;
4727 int n = 0, i, j, invis_p;
4728 struct overlay_entry *entries
4729 = (struct overlay_entry *) alloca (size * sizeof *entries);
4731 if (charpos <= 0)
4732 charpos = IT_CHARPOS (*it);
4734 /* Append the overlay string STRING of overlay OVERLAY to vector
4735 `entries' which has size `size' and currently contains `n'
4736 elements. AFTER_P non-zero means STRING is an after-string of
4737 OVERLAY. */
4738 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4739 do \
4741 Lisp_Object priority; \
4743 if (n == size) \
4745 int new_size = 2 * size; \
4746 struct overlay_entry *old = entries; \
4747 entries = \
4748 (struct overlay_entry *) alloca (new_size \
4749 * sizeof *entries); \
4750 bcopy (old, entries, size * sizeof *entries); \
4751 size = new_size; \
4754 entries[n].string = (STRING); \
4755 entries[n].overlay = (OVERLAY); \
4756 priority = Foverlay_get ((OVERLAY), Qpriority); \
4757 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4758 entries[n].after_string_p = (AFTER_P); \
4759 ++n; \
4761 while (0)
4763 /* Process overlay before the overlay center. */
4764 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4766 XSETMISC (overlay, ov);
4767 xassert (OVERLAYP (overlay));
4768 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4769 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4771 if (end < charpos)
4772 break;
4774 /* Skip this overlay if it doesn't start or end at IT's current
4775 position. */
4776 if (end != charpos && start != charpos)
4777 continue;
4779 /* Skip this overlay if it doesn't apply to IT->w. */
4780 window = Foverlay_get (overlay, Qwindow);
4781 if (WINDOWP (window) && XWINDOW (window) != it->w)
4782 continue;
4784 /* If the text ``under'' the overlay is invisible, both before-
4785 and after-strings from this overlay are visible; start and
4786 end position are indistinguishable. */
4787 invisible = Foverlay_get (overlay, Qinvisible);
4788 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4790 /* If overlay has a non-empty before-string, record it. */
4791 if ((start == charpos || (end == charpos && invis_p))
4792 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4793 && SCHARS (str))
4794 RECORD_OVERLAY_STRING (overlay, str, 0);
4796 /* If overlay has a non-empty after-string, record it. */
4797 if ((end == charpos || (start == charpos && invis_p))
4798 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4799 && SCHARS (str))
4800 RECORD_OVERLAY_STRING (overlay, str, 1);
4803 /* Process overlays after the overlay center. */
4804 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
4806 XSETMISC (overlay, ov);
4807 xassert (OVERLAYP (overlay));
4808 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4809 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4811 if (start > charpos)
4812 break;
4814 /* Skip this overlay if it doesn't start or end at IT's current
4815 position. */
4816 if (end != charpos && start != charpos)
4817 continue;
4819 /* Skip this overlay if it doesn't apply to IT->w. */
4820 window = Foverlay_get (overlay, Qwindow);
4821 if (WINDOWP (window) && XWINDOW (window) != it->w)
4822 continue;
4824 /* If the text ``under'' the overlay is invisible, it has a zero
4825 dimension, and both before- and after-strings apply. */
4826 invisible = Foverlay_get (overlay, Qinvisible);
4827 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4829 /* If overlay has a non-empty before-string, record it. */
4830 if ((start == charpos || (end == charpos && invis_p))
4831 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4832 && SCHARS (str))
4833 RECORD_OVERLAY_STRING (overlay, str, 0);
4835 /* If overlay has a non-empty after-string, record it. */
4836 if ((end == charpos || (start == charpos && invis_p))
4837 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4838 && SCHARS (str))
4839 RECORD_OVERLAY_STRING (overlay, str, 1);
4842 #undef RECORD_OVERLAY_STRING
4844 /* Sort entries. */
4845 if (n > 1)
4846 qsort (entries, n, sizeof *entries, compare_overlay_entries);
4848 /* Record the total number of strings to process. */
4849 it->n_overlay_strings = n;
4851 /* IT->current.overlay_string_index is the number of overlay strings
4852 that have already been consumed by IT. Copy some of the
4853 remaining overlay strings to IT->overlay_strings. */
4854 i = 0;
4855 j = it->current.overlay_string_index;
4856 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
4857 it->overlay_strings[i++] = entries[j++].string;
4859 CHECK_IT (it);
4863 /* Get the first chunk of overlay strings at IT's current buffer
4864 position, or at CHARPOS if that is > 0. Value is non-zero if at
4865 least one overlay string was found. */
4867 static int
4868 get_overlay_strings_1 (it, charpos, compute_stop_p)
4869 struct it *it;
4870 int charpos;
4872 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4873 process. This fills IT->overlay_strings with strings, and sets
4874 IT->n_overlay_strings to the total number of strings to process.
4875 IT->pos.overlay_string_index has to be set temporarily to zero
4876 because load_overlay_strings needs this; it must be set to -1
4877 when no overlay strings are found because a zero value would
4878 indicate a position in the first overlay string. */
4879 it->current.overlay_string_index = 0;
4880 load_overlay_strings (it, charpos);
4882 /* If we found overlay strings, set up IT to deliver display
4883 elements from the first one. Otherwise set up IT to deliver
4884 from current_buffer. */
4885 if (it->n_overlay_strings)
4887 /* Make sure we know settings in current_buffer, so that we can
4888 restore meaningful values when we're done with the overlay
4889 strings. */
4890 if (compute_stop_p)
4891 compute_stop_pos (it);
4892 xassert (it->face_id >= 0);
4894 /* Save IT's settings. They are restored after all overlay
4895 strings have been processed. */
4896 xassert (!compute_stop_p || it->sp == 0);
4897 push_it (it);
4899 /* Set up IT to deliver display elements from the first overlay
4900 string. */
4901 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4902 it->string = it->overlay_strings[0];
4903 it->stop_charpos = 0;
4904 xassert (STRINGP (it->string));
4905 it->end_charpos = SCHARS (it->string);
4906 it->multibyte_p = STRING_MULTIBYTE (it->string);
4907 it->method = GET_FROM_STRING;
4908 return 1;
4911 it->current.overlay_string_index = -1;
4912 return 0;
4915 static int
4916 get_overlay_strings (it, charpos)
4917 struct it *it;
4918 int charpos;
4920 it->string = Qnil;
4921 it->method = GET_FROM_BUFFER;
4923 (void) get_overlay_strings_1 (it, charpos, 1);
4925 CHECK_IT (it);
4927 /* Value is non-zero if we found at least one overlay string. */
4928 return STRINGP (it->string);
4933 /***********************************************************************
4934 Saving and restoring state
4935 ***********************************************************************/
4937 /* Save current settings of IT on IT->stack. Called, for example,
4938 before setting up IT for an overlay string, to be able to restore
4939 IT's settings to what they were after the overlay string has been
4940 processed. */
4942 static void
4943 push_it (it)
4944 struct it *it;
4946 struct iterator_stack_entry *p;
4948 xassert (it->sp < IT_STACK_SIZE);
4949 p = it->stack + it->sp;
4951 p->stop_charpos = it->stop_charpos;
4952 xassert (it->face_id >= 0);
4953 p->face_id = it->face_id;
4954 p->string = it->string;
4955 p->method = it->method;
4956 switch (p->method)
4958 case GET_FROM_IMAGE:
4959 p->u.image.object = it->object;
4960 p->u.image.image_id = it->image_id;
4961 p->u.image.slice = it->slice;
4962 break;
4963 case GET_FROM_COMPOSITION:
4964 p->u.comp.object = it->object;
4965 p->u.comp.c = it->c;
4966 p->u.comp.len = it->len;
4967 p->u.comp.cmp_id = it->cmp_id;
4968 p->u.comp.cmp_len = it->cmp_len;
4969 break;
4970 case GET_FROM_STRETCH:
4971 p->u.stretch.object = it->object;
4972 break;
4974 p->position = it->position;
4975 p->current = it->current;
4976 p->end_charpos = it->end_charpos;
4977 p->string_nchars = it->string_nchars;
4978 p->area = it->area;
4979 p->multibyte_p = it->multibyte_p;
4980 p->space_width = it->space_width;
4981 p->font_height = it->font_height;
4982 p->voffset = it->voffset;
4983 p->string_from_display_prop_p = it->string_from_display_prop_p;
4984 p->display_ellipsis_p = 0;
4985 ++it->sp;
4989 /* Restore IT's settings from IT->stack. Called, for example, when no
4990 more overlay strings must be processed, and we return to delivering
4991 display elements from a buffer, or when the end of a string from a
4992 `display' property is reached and we return to delivering display
4993 elements from an overlay string, or from a buffer. */
4995 static void
4996 pop_it (it)
4997 struct it *it;
4999 struct iterator_stack_entry *p;
5001 xassert (it->sp > 0);
5002 --it->sp;
5003 p = it->stack + it->sp;
5004 it->stop_charpos = p->stop_charpos;
5005 it->face_id = p->face_id;
5006 it->current = p->current;
5007 it->position = p->position;
5008 it->string = p->string;
5009 if (NILP (it->string))
5010 SET_TEXT_POS (it->current.string_pos, -1, -1);
5011 it->method = p->method;
5012 switch (it->method)
5014 case GET_FROM_IMAGE:
5015 it->image_id = p->u.image.image_id;
5016 it->object = p->u.image.object;
5017 it->slice = p->u.image.slice;
5018 break;
5019 case GET_FROM_COMPOSITION:
5020 it->object = p->u.comp.object;
5021 it->c = p->u.comp.c;
5022 it->len = p->u.comp.len;
5023 it->cmp_id = p->u.comp.cmp_id;
5024 it->cmp_len = p->u.comp.cmp_len;
5025 break;
5026 case GET_FROM_STRETCH:
5027 it->object = p->u.comp.object;
5028 break;
5029 case GET_FROM_BUFFER:
5030 it->object = it->w->buffer;
5031 break;
5032 case GET_FROM_STRING:
5033 it->object = it->string;
5034 break;
5036 it->end_charpos = p->end_charpos;
5037 it->string_nchars = p->string_nchars;
5038 it->area = p->area;
5039 it->multibyte_p = p->multibyte_p;
5040 it->space_width = p->space_width;
5041 it->font_height = p->font_height;
5042 it->voffset = p->voffset;
5043 it->string_from_display_prop_p = p->string_from_display_prop_p;
5048 /***********************************************************************
5049 Moving over lines
5050 ***********************************************************************/
5052 /* Set IT's current position to the previous line start. */
5054 static void
5055 back_to_previous_line_start (it)
5056 struct it *it;
5058 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
5059 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
5063 /* Move IT to the next line start.
5065 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
5066 we skipped over part of the text (as opposed to moving the iterator
5067 continuously over the text). Otherwise, don't change the value
5068 of *SKIPPED_P.
5070 Newlines may come from buffer text, overlay strings, or strings
5071 displayed via the `display' property. That's the reason we can't
5072 simply use find_next_newline_no_quit.
5074 Note that this function may not skip over invisible text that is so
5075 because of text properties and immediately follows a newline. If
5076 it would, function reseat_at_next_visible_line_start, when called
5077 from set_iterator_to_next, would effectively make invisible
5078 characters following a newline part of the wrong glyph row, which
5079 leads to wrong cursor motion. */
5081 static int
5082 forward_to_next_line_start (it, skipped_p)
5083 struct it *it;
5084 int *skipped_p;
5086 int old_selective, newline_found_p, n;
5087 const int MAX_NEWLINE_DISTANCE = 500;
5089 /* If already on a newline, just consume it to avoid unintended
5090 skipping over invisible text below. */
5091 if (it->what == IT_CHARACTER
5092 && it->c == '\n'
5093 && CHARPOS (it->position) == IT_CHARPOS (*it))
5095 set_iterator_to_next (it, 0);
5096 it->c = 0;
5097 return 1;
5100 /* Don't handle selective display in the following. It's (a)
5101 unnecessary because it's done by the caller, and (b) leads to an
5102 infinite recursion because next_element_from_ellipsis indirectly
5103 calls this function. */
5104 old_selective = it->selective;
5105 it->selective = 0;
5107 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
5108 from buffer text. */
5109 for (n = newline_found_p = 0;
5110 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
5111 n += STRINGP (it->string) ? 0 : 1)
5113 if (!get_next_display_element (it))
5114 return 0;
5115 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
5116 set_iterator_to_next (it, 0);
5119 /* If we didn't find a newline near enough, see if we can use a
5120 short-cut. */
5121 if (!newline_found_p)
5123 int start = IT_CHARPOS (*it);
5124 int limit = find_next_newline_no_quit (start, 1);
5125 Lisp_Object pos;
5127 xassert (!STRINGP (it->string));
5129 /* If there isn't any `display' property in sight, and no
5130 overlays, we can just use the position of the newline in
5131 buffer text. */
5132 if (it->stop_charpos >= limit
5133 || ((pos = Fnext_single_property_change (make_number (start),
5134 Qdisplay,
5135 Qnil, make_number (limit)),
5136 NILP (pos))
5137 && next_overlay_change (start) == ZV))
5139 IT_CHARPOS (*it) = limit;
5140 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
5141 *skipped_p = newline_found_p = 1;
5143 else
5145 while (get_next_display_element (it)
5146 && !newline_found_p)
5148 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
5149 set_iterator_to_next (it, 0);
5154 it->selective = old_selective;
5155 return newline_found_p;
5159 /* Set IT's current position to the previous visible line start. Skip
5160 invisible text that is so either due to text properties or due to
5161 selective display. Caution: this does not change IT->current_x and
5162 IT->hpos. */
5164 static void
5165 back_to_previous_visible_line_start (it)
5166 struct it *it;
5168 while (IT_CHARPOS (*it) > BEGV)
5170 back_to_previous_line_start (it);
5172 if (IT_CHARPOS (*it) <= BEGV)
5173 break;
5175 /* If selective > 0, then lines indented more than that values
5176 are invisible. */
5177 if (it->selective > 0
5178 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5179 (double) it->selective)) /* iftc */
5180 continue;
5182 /* Check the newline before point for invisibility. */
5184 Lisp_Object prop;
5185 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
5186 Qinvisible, it->window);
5187 if (TEXT_PROP_MEANS_INVISIBLE (prop))
5188 continue;
5191 if (IT_CHARPOS (*it) <= BEGV)
5192 break;
5195 struct it it2;
5196 int pos;
5197 int beg, end;
5198 Lisp_Object val, overlay;
5200 /* If newline is part of a composition, continue from start of composition */
5201 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
5202 && beg < IT_CHARPOS (*it))
5203 goto replaced;
5205 /* If newline is replaced by a display property, find start of overlay
5206 or interval and continue search from that point. */
5207 it2 = *it;
5208 pos = --IT_CHARPOS (it2);
5209 --IT_BYTEPOS (it2);
5210 it2.sp = 0;
5211 if (handle_display_prop (&it2) == HANDLED_RETURN
5212 && !NILP (val = get_char_property_and_overlay
5213 (make_number (pos), Qdisplay, Qnil, &overlay))
5214 && (OVERLAYP (overlay)
5215 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
5216 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
5217 goto replaced;
5219 /* Newline is not replaced by anything -- so we are done. */
5220 break;
5222 replaced:
5223 if (beg < BEGV)
5224 beg = BEGV;
5225 IT_CHARPOS (*it) = beg;
5226 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
5230 it->continuation_lines_width = 0;
5232 xassert (IT_CHARPOS (*it) >= BEGV);
5233 xassert (IT_CHARPOS (*it) == BEGV
5234 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5235 CHECK_IT (it);
5239 /* Reseat iterator IT at the previous visible line start. Skip
5240 invisible text that is so either due to text properties or due to
5241 selective display. At the end, update IT's overlay information,
5242 face information etc. */
5244 void
5245 reseat_at_previous_visible_line_start (it)
5246 struct it *it;
5248 back_to_previous_visible_line_start (it);
5249 reseat (it, it->current.pos, 1);
5250 CHECK_IT (it);
5254 /* Reseat iterator IT on the next visible line start in the current
5255 buffer. ON_NEWLINE_P non-zero means position IT on the newline
5256 preceding the line start. Skip over invisible text that is so
5257 because of selective display. Compute faces, overlays etc at the
5258 new position. Note that this function does not skip over text that
5259 is invisible because of text properties. */
5261 static void
5262 reseat_at_next_visible_line_start (it, on_newline_p)
5263 struct it *it;
5264 int on_newline_p;
5266 int newline_found_p, skipped_p = 0;
5268 newline_found_p = forward_to_next_line_start (it, &skipped_p);
5270 /* Skip over lines that are invisible because they are indented
5271 more than the value of IT->selective. */
5272 if (it->selective > 0)
5273 while (IT_CHARPOS (*it) < ZV
5274 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5275 (double) it->selective)) /* iftc */
5277 xassert (IT_BYTEPOS (*it) == BEGV
5278 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5279 newline_found_p = forward_to_next_line_start (it, &skipped_p);
5282 /* Position on the newline if that's what's requested. */
5283 if (on_newline_p && newline_found_p)
5285 if (STRINGP (it->string))
5287 if (IT_STRING_CHARPOS (*it) > 0)
5289 --IT_STRING_CHARPOS (*it);
5290 --IT_STRING_BYTEPOS (*it);
5293 else if (IT_CHARPOS (*it) > BEGV)
5295 --IT_CHARPOS (*it);
5296 --IT_BYTEPOS (*it);
5297 reseat (it, it->current.pos, 0);
5300 else if (skipped_p)
5301 reseat (it, it->current.pos, 0);
5303 CHECK_IT (it);
5308 /***********************************************************************
5309 Changing an iterator's position
5310 ***********************************************************************/
5312 /* Change IT's current position to POS in current_buffer. If FORCE_P
5313 is non-zero, always check for text properties at the new position.
5314 Otherwise, text properties are only looked up if POS >=
5315 IT->check_charpos of a property. */
5317 static void
5318 reseat (it, pos, force_p)
5319 struct it *it;
5320 struct text_pos pos;
5321 int force_p;
5323 int original_pos = IT_CHARPOS (*it);
5325 reseat_1 (it, pos, 0);
5327 /* Determine where to check text properties. Avoid doing it
5328 where possible because text property lookup is very expensive. */
5329 if (force_p
5330 || CHARPOS (pos) > it->stop_charpos
5331 || CHARPOS (pos) < original_pos)
5332 handle_stop (it);
5334 CHECK_IT (it);
5338 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
5339 IT->stop_pos to POS, also. */
5341 static void
5342 reseat_1 (it, pos, set_stop_p)
5343 struct it *it;
5344 struct text_pos pos;
5345 int set_stop_p;
5347 /* Don't call this function when scanning a C string. */
5348 xassert (it->s == NULL);
5350 /* POS must be a reasonable value. */
5351 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
5353 it->current.pos = it->position = pos;
5354 it->end_charpos = ZV;
5355 it->dpvec = NULL;
5356 it->current.dpvec_index = -1;
5357 it->current.overlay_string_index = -1;
5358 IT_STRING_CHARPOS (*it) = -1;
5359 IT_STRING_BYTEPOS (*it) = -1;
5360 it->string = Qnil;
5361 it->method = GET_FROM_BUFFER;
5362 it->object = it->w->buffer;
5363 it->area = TEXT_AREA;
5364 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
5365 it->sp = 0;
5366 it->string_from_display_prop_p = 0;
5367 it->face_before_selective_p = 0;
5369 if (set_stop_p)
5370 it->stop_charpos = CHARPOS (pos);
5374 /* Set up IT for displaying a string, starting at CHARPOS in window W.
5375 If S is non-null, it is a C string to iterate over. Otherwise,
5376 STRING gives a Lisp string to iterate over.
5378 If PRECISION > 0, don't return more then PRECISION number of
5379 characters from the string.
5381 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
5382 characters have been returned. FIELD_WIDTH < 0 means an infinite
5383 field width.
5385 MULTIBYTE = 0 means disable processing of multibyte characters,
5386 MULTIBYTE > 0 means enable it,
5387 MULTIBYTE < 0 means use IT->multibyte_p.
5389 IT must be initialized via a prior call to init_iterator before
5390 calling this function. */
5392 static void
5393 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
5394 struct it *it;
5395 unsigned char *s;
5396 Lisp_Object string;
5397 int charpos;
5398 int precision, field_width, multibyte;
5400 /* No region in strings. */
5401 it->region_beg_charpos = it->region_end_charpos = -1;
5403 /* No text property checks performed by default, but see below. */
5404 it->stop_charpos = -1;
5406 /* Set iterator position and end position. */
5407 bzero (&it->current, sizeof it->current);
5408 it->current.overlay_string_index = -1;
5409 it->current.dpvec_index = -1;
5410 xassert (charpos >= 0);
5412 /* If STRING is specified, use its multibyteness, otherwise use the
5413 setting of MULTIBYTE, if specified. */
5414 if (multibyte >= 0)
5415 it->multibyte_p = multibyte > 0;
5417 if (s == NULL)
5419 xassert (STRINGP (string));
5420 it->string = string;
5421 it->s = NULL;
5422 it->end_charpos = it->string_nchars = SCHARS (string);
5423 it->method = GET_FROM_STRING;
5424 it->current.string_pos = string_pos (charpos, string);
5426 else
5428 it->s = s;
5429 it->string = Qnil;
5431 /* Note that we use IT->current.pos, not it->current.string_pos,
5432 for displaying C strings. */
5433 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
5434 if (it->multibyte_p)
5436 it->current.pos = c_string_pos (charpos, s, 1);
5437 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
5439 else
5441 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
5442 it->end_charpos = it->string_nchars = strlen (s);
5445 it->method = GET_FROM_C_STRING;
5448 /* PRECISION > 0 means don't return more than PRECISION characters
5449 from the string. */
5450 if (precision > 0 && it->end_charpos - charpos > precision)
5451 it->end_charpos = it->string_nchars = charpos + precision;
5453 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
5454 characters have been returned. FIELD_WIDTH == 0 means don't pad,
5455 FIELD_WIDTH < 0 means infinite field width. This is useful for
5456 padding with `-' at the end of a mode line. */
5457 if (field_width < 0)
5458 field_width = INFINITY;
5459 if (field_width > it->end_charpos - charpos)
5460 it->end_charpos = charpos + field_width;
5462 /* Use the standard display table for displaying strings. */
5463 if (DISP_TABLE_P (Vstandard_display_table))
5464 it->dp = XCHAR_TABLE (Vstandard_display_table);
5466 it->stop_charpos = charpos;
5467 CHECK_IT (it);
5472 /***********************************************************************
5473 Iteration
5474 ***********************************************************************/
5476 /* Map enum it_method value to corresponding next_element_from_* function. */
5478 static int (* get_next_element[NUM_IT_METHODS]) P_ ((struct it *it)) =
5480 next_element_from_buffer,
5481 next_element_from_display_vector,
5482 next_element_from_composition,
5483 next_element_from_string,
5484 next_element_from_c_string,
5485 next_element_from_image,
5486 next_element_from_stretch
5490 /* Load IT's display element fields with information about the next
5491 display element from the current position of IT. Value is zero if
5492 end of buffer (or C string) is reached. */
5494 static struct frame *last_escape_glyph_frame = NULL;
5495 static unsigned last_escape_glyph_face_id = (1 << FACE_ID_BITS);
5496 static int last_escape_glyph_merged_face_id = 0;
5499 get_next_display_element (it)
5500 struct it *it;
5502 /* Non-zero means that we found a display element. Zero means that
5503 we hit the end of what we iterate over. Performance note: the
5504 function pointer `method' used here turns out to be faster than
5505 using a sequence of if-statements. */
5506 int success_p;
5508 get_next:
5509 success_p = (*get_next_element[it->method]) (it);
5511 if (it->what == IT_CHARACTER)
5513 /* Map via display table or translate control characters.
5514 IT->c, IT->len etc. have been set to the next character by
5515 the function call above. If we have a display table, and it
5516 contains an entry for IT->c, translate it. Don't do this if
5517 IT->c itself comes from a display table, otherwise we could
5518 end up in an infinite recursion. (An alternative could be to
5519 count the recursion depth of this function and signal an
5520 error when a certain maximum depth is reached.) Is it worth
5521 it? */
5522 if (success_p && it->dpvec == NULL)
5524 Lisp_Object dv;
5526 if (it->dp
5527 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
5528 VECTORP (dv)))
5530 struct Lisp_Vector *v = XVECTOR (dv);
5532 /* Return the first character from the display table
5533 entry, if not empty. If empty, don't display the
5534 current character. */
5535 if (v->size)
5537 it->dpvec_char_len = it->len;
5538 it->dpvec = v->contents;
5539 it->dpend = v->contents + v->size;
5540 it->current.dpvec_index = 0;
5541 it->dpvec_face_id = -1;
5542 it->saved_face_id = it->face_id;
5543 it->method = GET_FROM_DISPLAY_VECTOR;
5544 it->ellipsis_p = 0;
5546 else
5548 set_iterator_to_next (it, 0);
5550 goto get_next;
5553 /* Translate control characters into `\003' or `^C' form.
5554 Control characters coming from a display table entry are
5555 currently not translated because we use IT->dpvec to hold
5556 the translation. This could easily be changed but I
5557 don't believe that it is worth doing.
5559 If it->multibyte_p is nonzero, eight-bit characters and
5560 non-printable multibyte characters are also translated to
5561 octal form.
5563 If it->multibyte_p is zero, eight-bit characters that
5564 don't have corresponding multibyte char code are also
5565 translated to octal form. */
5566 else if ((it->c < ' '
5567 && (it->area != TEXT_AREA
5568 /* In mode line, treat \n like other crl chars. */
5569 || (it->c != '\t'
5570 && it->glyph_row && it->glyph_row->mode_line_p)
5571 || (it->c != '\n' && it->c != '\t')))
5572 || (it->multibyte_p
5573 ? ((it->c >= 127
5574 && it->len == 1)
5575 || !CHAR_PRINTABLE_P (it->c)
5576 || (!NILP (Vnobreak_char_display)
5577 && (it->c == 0x8a0 || it->c == 0x8ad
5578 || it->c == 0x920 || it->c == 0x92d
5579 || it->c == 0xe20 || it->c == 0xe2d
5580 || it->c == 0xf20 || it->c == 0xf2d)))
5581 : (it->c >= 127
5582 && (!unibyte_display_via_language_environment
5583 || it->c == unibyte_char_to_multibyte (it->c)))))
5585 /* IT->c is a control character which must be displayed
5586 either as '\003' or as `^C' where the '\\' and '^'
5587 can be defined in the display table. Fill
5588 IT->ctl_chars with glyphs for what we have to
5589 display. Then, set IT->dpvec to these glyphs. */
5590 GLYPH g;
5591 int ctl_len;
5592 int face_id, lface_id = 0 ;
5593 GLYPH escape_glyph;
5595 /* Handle control characters with ^. */
5597 if (it->c < 128 && it->ctl_arrow_p)
5599 g = '^'; /* default glyph for Control */
5600 /* Set IT->ctl_chars[0] to the glyph for `^'. */
5601 if (it->dp
5602 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
5603 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
5605 g = XINT (DISP_CTRL_GLYPH (it->dp));
5606 lface_id = FAST_GLYPH_FACE (g);
5608 if (lface_id)
5610 g = FAST_GLYPH_CHAR (g);
5611 face_id = merge_faces (it->f, Qt, lface_id,
5612 it->face_id);
5614 else if (it->f == last_escape_glyph_frame
5615 && it->face_id == last_escape_glyph_face_id)
5617 face_id = last_escape_glyph_merged_face_id;
5619 else
5621 /* Merge the escape-glyph face into the current face. */
5622 face_id = merge_faces (it->f, Qescape_glyph, 0,
5623 it->face_id);
5624 last_escape_glyph_frame = it->f;
5625 last_escape_glyph_face_id = it->face_id;
5626 last_escape_glyph_merged_face_id = face_id;
5629 XSETINT (it->ctl_chars[0], g);
5630 g = it->c ^ 0100;
5631 XSETINT (it->ctl_chars[1], g);
5632 ctl_len = 2;
5633 goto display_control;
5636 /* Handle non-break space in the mode where it only gets
5637 highlighting. */
5639 if (EQ (Vnobreak_char_display, Qt)
5640 && (it->c == 0x8a0 || it->c == 0x920
5641 || it->c == 0xe20 || it->c == 0xf20))
5643 /* Merge the no-break-space face into the current face. */
5644 face_id = merge_faces (it->f, Qnobreak_space, 0,
5645 it->face_id);
5647 g = it->c = ' ';
5648 XSETINT (it->ctl_chars[0], g);
5649 ctl_len = 1;
5650 goto display_control;
5653 /* Handle sequences that start with the "escape glyph". */
5655 /* the default escape glyph is \. */
5656 escape_glyph = '\\';
5658 if (it->dp
5659 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
5660 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
5662 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
5663 lface_id = FAST_GLYPH_FACE (escape_glyph);
5665 if (lface_id)
5667 /* The display table specified a face.
5668 Merge it into face_id and also into escape_glyph. */
5669 escape_glyph = FAST_GLYPH_CHAR (escape_glyph);
5670 face_id = merge_faces (it->f, Qt, lface_id,
5671 it->face_id);
5673 else if (it->f == last_escape_glyph_frame
5674 && it->face_id == last_escape_glyph_face_id)
5676 face_id = last_escape_glyph_merged_face_id;
5678 else
5680 /* Merge the escape-glyph face into the current face. */
5681 face_id = merge_faces (it->f, Qescape_glyph, 0,
5682 it->face_id);
5683 last_escape_glyph_frame = it->f;
5684 last_escape_glyph_face_id = it->face_id;
5685 last_escape_glyph_merged_face_id = face_id;
5688 /* Handle soft hyphens in the mode where they only get
5689 highlighting. */
5691 if (EQ (Vnobreak_char_display, Qt)
5692 && (it->c == 0x8ad || it->c == 0x92d
5693 || it->c == 0xe2d || it->c == 0xf2d))
5695 g = it->c = '-';
5696 XSETINT (it->ctl_chars[0], g);
5697 ctl_len = 1;
5698 goto display_control;
5701 /* Handle non-break space and soft hyphen
5702 with the escape glyph. */
5704 if (it->c == 0x8a0 || it->c == 0x8ad
5705 || it->c == 0x920 || it->c == 0x92d
5706 || it->c == 0xe20 || it->c == 0xe2d
5707 || it->c == 0xf20 || it->c == 0xf2d)
5709 XSETINT (it->ctl_chars[0], escape_glyph);
5710 g = it->c = ((it->c & 0xf) == 0 ? ' ' : '-');
5711 XSETINT (it->ctl_chars[1], g);
5712 ctl_len = 2;
5713 goto display_control;
5717 unsigned char str[MAX_MULTIBYTE_LENGTH];
5718 int len;
5719 int i;
5721 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
5722 if (SINGLE_BYTE_CHAR_P (it->c))
5723 str[0] = it->c, len = 1;
5724 else
5726 len = CHAR_STRING_NO_SIGNAL (it->c, str);
5727 if (len < 0)
5729 /* It's an invalid character, which shouldn't
5730 happen actually, but due to bugs it may
5731 happen. Let's print the char as is, there's
5732 not much meaningful we can do with it. */
5733 str[0] = it->c;
5734 str[1] = it->c >> 8;
5735 str[2] = it->c >> 16;
5736 str[3] = it->c >> 24;
5737 len = 4;
5741 for (i = 0; i < len; i++)
5743 XSETINT (it->ctl_chars[i * 4], escape_glyph);
5744 /* Insert three more glyphs into IT->ctl_chars for
5745 the octal display of the character. */
5746 g = ((str[i] >> 6) & 7) + '0';
5747 XSETINT (it->ctl_chars[i * 4 + 1], g);
5748 g = ((str[i] >> 3) & 7) + '0';
5749 XSETINT (it->ctl_chars[i * 4 + 2], g);
5750 g = (str[i] & 7) + '0';
5751 XSETINT (it->ctl_chars[i * 4 + 3], g);
5753 ctl_len = len * 4;
5756 display_control:
5757 /* Set up IT->dpvec and return first character from it. */
5758 it->dpvec_char_len = it->len;
5759 it->dpvec = it->ctl_chars;
5760 it->dpend = it->dpvec + ctl_len;
5761 it->current.dpvec_index = 0;
5762 it->dpvec_face_id = face_id;
5763 it->saved_face_id = it->face_id;
5764 it->method = GET_FROM_DISPLAY_VECTOR;
5765 it->ellipsis_p = 0;
5766 goto get_next;
5770 /* Adjust face id for a multibyte character. There are no
5771 multibyte character in unibyte text. */
5772 if (it->multibyte_p
5773 && success_p
5774 && FRAME_WINDOW_P (it->f))
5776 struct face *face = FACE_FROM_ID (it->f, it->face_id);
5777 it->face_id = FACE_FOR_CHAR (it->f, face, it->c);
5781 /* Is this character the last one of a run of characters with
5782 box? If yes, set IT->end_of_box_run_p to 1. */
5783 if (it->face_box_p
5784 && it->s == NULL)
5786 int face_id;
5787 struct face *face;
5789 it->end_of_box_run_p
5790 = ((face_id = face_after_it_pos (it),
5791 face_id != it->face_id)
5792 && (face = FACE_FROM_ID (it->f, face_id),
5793 face->box == FACE_NO_BOX));
5796 /* Value is 0 if end of buffer or string reached. */
5797 return success_p;
5801 /* Move IT to the next display element.
5803 RESEAT_P non-zero means if called on a newline in buffer text,
5804 skip to the next visible line start.
5806 Functions get_next_display_element and set_iterator_to_next are
5807 separate because I find this arrangement easier to handle than a
5808 get_next_display_element function that also increments IT's
5809 position. The way it is we can first look at an iterator's current
5810 display element, decide whether it fits on a line, and if it does,
5811 increment the iterator position. The other way around we probably
5812 would either need a flag indicating whether the iterator has to be
5813 incremented the next time, or we would have to implement a
5814 decrement position function which would not be easy to write. */
5816 void
5817 set_iterator_to_next (it, reseat_p)
5818 struct it *it;
5819 int reseat_p;
5821 /* Reset flags indicating start and end of a sequence of characters
5822 with box. Reset them at the start of this function because
5823 moving the iterator to a new position might set them. */
5824 it->start_of_box_run_p = it->end_of_box_run_p = 0;
5826 switch (it->method)
5828 case GET_FROM_BUFFER:
5829 /* The current display element of IT is a character from
5830 current_buffer. Advance in the buffer, and maybe skip over
5831 invisible lines that are so because of selective display. */
5832 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
5833 reseat_at_next_visible_line_start (it, 0);
5834 else
5836 xassert (it->len != 0);
5837 IT_BYTEPOS (*it) += it->len;
5838 IT_CHARPOS (*it) += 1;
5839 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
5841 break;
5843 case GET_FROM_COMPOSITION:
5844 xassert (it->cmp_id >= 0 && it->cmp_id < n_compositions);
5845 xassert (it->sp > 0);
5846 pop_it (it);
5847 if (it->method == GET_FROM_STRING)
5849 IT_STRING_BYTEPOS (*it) += it->len;
5850 IT_STRING_CHARPOS (*it) += it->cmp_len;
5851 goto consider_string_end;
5853 else if (it->method == GET_FROM_BUFFER)
5855 IT_BYTEPOS (*it) += it->len;
5856 IT_CHARPOS (*it) += it->cmp_len;
5858 break;
5860 case GET_FROM_C_STRING:
5861 /* Current display element of IT is from a C string. */
5862 IT_BYTEPOS (*it) += it->len;
5863 IT_CHARPOS (*it) += 1;
5864 break;
5866 case GET_FROM_DISPLAY_VECTOR:
5867 /* Current display element of IT is from a display table entry.
5868 Advance in the display table definition. Reset it to null if
5869 end reached, and continue with characters from buffers/
5870 strings. */
5871 ++it->current.dpvec_index;
5873 /* Restore face of the iterator to what they were before the
5874 display vector entry (these entries may contain faces). */
5875 it->face_id = it->saved_face_id;
5877 if (it->dpvec + it->current.dpvec_index == it->dpend)
5879 int recheck_faces = it->ellipsis_p;
5881 if (it->s)
5882 it->method = GET_FROM_C_STRING;
5883 else if (STRINGP (it->string))
5884 it->method = GET_FROM_STRING;
5885 else
5887 it->method = GET_FROM_BUFFER;
5888 it->object = it->w->buffer;
5891 it->dpvec = NULL;
5892 it->current.dpvec_index = -1;
5894 /* Skip over characters which were displayed via IT->dpvec. */
5895 if (it->dpvec_char_len < 0)
5896 reseat_at_next_visible_line_start (it, 1);
5897 else if (it->dpvec_char_len > 0)
5899 if (it->method == GET_FROM_STRING
5900 && it->n_overlay_strings > 0)
5901 it->ignore_overlay_strings_at_pos_p = 1;
5902 it->len = it->dpvec_char_len;
5903 set_iterator_to_next (it, reseat_p);
5906 /* Maybe recheck faces after display vector */
5907 if (recheck_faces)
5908 it->stop_charpos = IT_CHARPOS (*it);
5910 break;
5912 case GET_FROM_STRING:
5913 /* Current display element is a character from a Lisp string. */
5914 xassert (it->s == NULL && STRINGP (it->string));
5915 IT_STRING_BYTEPOS (*it) += it->len;
5916 IT_STRING_CHARPOS (*it) += 1;
5918 consider_string_end:
5920 if (it->current.overlay_string_index >= 0)
5922 /* IT->string is an overlay string. Advance to the
5923 next, if there is one. */
5924 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5925 next_overlay_string (it);
5927 else
5929 /* IT->string is not an overlay string. If we reached
5930 its end, and there is something on IT->stack, proceed
5931 with what is on the stack. This can be either another
5932 string, this time an overlay string, or a buffer. */
5933 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
5934 && it->sp > 0)
5936 pop_it (it);
5937 if (it->method == GET_FROM_STRING)
5938 goto consider_string_end;
5941 break;
5943 case GET_FROM_IMAGE:
5944 case GET_FROM_STRETCH:
5945 /* The position etc with which we have to proceed are on
5946 the stack. The position may be at the end of a string,
5947 if the `display' property takes up the whole string. */
5948 xassert (it->sp > 0);
5949 pop_it (it);
5950 if (it->method == GET_FROM_STRING)
5951 goto consider_string_end;
5952 break;
5954 default:
5955 /* There are no other methods defined, so this should be a bug. */
5956 abort ();
5959 xassert (it->method != GET_FROM_STRING
5960 || (STRINGP (it->string)
5961 && IT_STRING_CHARPOS (*it) >= 0));
5964 /* Load IT's display element fields with information about the next
5965 display element which comes from a display table entry or from the
5966 result of translating a control character to one of the forms `^C'
5967 or `\003'.
5969 IT->dpvec holds the glyphs to return as characters.
5970 IT->saved_face_id holds the face id before the display vector--
5971 it is restored into IT->face_idin set_iterator_to_next. */
5973 static int
5974 next_element_from_display_vector (it)
5975 struct it *it;
5977 /* Precondition. */
5978 xassert (it->dpvec && it->current.dpvec_index >= 0);
5980 it->face_id = it->saved_face_id;
5982 if (INTEGERP (*it->dpvec)
5983 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
5985 GLYPH g;
5987 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
5988 it->c = FAST_GLYPH_CHAR (g);
5989 it->len = CHAR_BYTES (it->c);
5991 /* The entry may contain a face id to use. Such a face id is
5992 the id of a Lisp face, not a realized face. A face id of
5993 zero means no face is specified. */
5994 if (it->dpvec_face_id >= 0)
5995 it->face_id = it->dpvec_face_id;
5996 else
5998 int lface_id = FAST_GLYPH_FACE (g);
5999 if (lface_id > 0)
6000 it->face_id = merge_faces (it->f, Qt, lface_id,
6001 it->saved_face_id);
6004 else
6005 /* Display table entry is invalid. Return a space. */
6006 it->c = ' ', it->len = 1;
6008 /* Don't change position and object of the iterator here. They are
6009 still the values of the character that had this display table
6010 entry or was translated, and that's what we want. */
6011 it->what = IT_CHARACTER;
6012 return 1;
6016 /* Load IT with the next display element from Lisp string IT->string.
6017 IT->current.string_pos is the current position within the string.
6018 If IT->current.overlay_string_index >= 0, the Lisp string is an
6019 overlay string. */
6021 static int
6022 next_element_from_string (it)
6023 struct it *it;
6025 struct text_pos position;
6027 xassert (STRINGP (it->string));
6028 xassert (IT_STRING_CHARPOS (*it) >= 0);
6029 position = it->current.string_pos;
6031 /* Time to check for invisible text? */
6032 if (IT_STRING_CHARPOS (*it) < it->end_charpos
6033 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
6035 handle_stop (it);
6037 /* Since a handler may have changed IT->method, we must
6038 recurse here. */
6039 return get_next_display_element (it);
6042 if (it->current.overlay_string_index >= 0)
6044 /* Get the next character from an overlay string. In overlay
6045 strings, There is no field width or padding with spaces to
6046 do. */
6047 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
6049 it->what = IT_EOB;
6050 return 0;
6052 else if (STRING_MULTIBYTE (it->string))
6054 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
6055 const unsigned char *s = (SDATA (it->string)
6056 + IT_STRING_BYTEPOS (*it));
6057 it->c = string_char_and_length (s, remaining, &it->len);
6059 else
6061 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
6062 it->len = 1;
6065 else
6067 /* Get the next character from a Lisp string that is not an
6068 overlay string. Such strings come from the mode line, for
6069 example. We may have to pad with spaces, or truncate the
6070 string. See also next_element_from_c_string. */
6071 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
6073 it->what = IT_EOB;
6074 return 0;
6076 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
6078 /* Pad with spaces. */
6079 it->c = ' ', it->len = 1;
6080 CHARPOS (position) = BYTEPOS (position) = -1;
6082 else if (STRING_MULTIBYTE (it->string))
6084 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
6085 const unsigned char *s = (SDATA (it->string)
6086 + IT_STRING_BYTEPOS (*it));
6087 it->c = string_char_and_length (s, maxlen, &it->len);
6089 else
6091 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
6092 it->len = 1;
6096 /* Record what we have and where it came from. */
6097 it->what = IT_CHARACTER;
6098 it->object = it->string;
6099 it->position = position;
6100 return 1;
6104 /* Load IT with next display element from C string IT->s.
6105 IT->string_nchars is the maximum number of characters to return
6106 from the string. IT->end_charpos may be greater than
6107 IT->string_nchars when this function is called, in which case we
6108 may have to return padding spaces. Value is zero if end of string
6109 reached, including padding spaces. */
6111 static int
6112 next_element_from_c_string (it)
6113 struct it *it;
6115 int success_p = 1;
6117 xassert (it->s);
6118 it->what = IT_CHARACTER;
6119 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
6120 it->object = Qnil;
6122 /* IT's position can be greater IT->string_nchars in case a field
6123 width or precision has been specified when the iterator was
6124 initialized. */
6125 if (IT_CHARPOS (*it) >= it->end_charpos)
6127 /* End of the game. */
6128 it->what = IT_EOB;
6129 success_p = 0;
6131 else if (IT_CHARPOS (*it) >= it->string_nchars)
6133 /* Pad with spaces. */
6134 it->c = ' ', it->len = 1;
6135 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
6137 else if (it->multibyte_p)
6139 /* Implementation note: The calls to strlen apparently aren't a
6140 performance problem because there is no noticeable performance
6141 difference between Emacs running in unibyte or multibyte mode. */
6142 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
6143 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
6144 maxlen, &it->len);
6146 else
6147 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
6149 return success_p;
6153 /* Set up IT to return characters from an ellipsis, if appropriate.
6154 The definition of the ellipsis glyphs may come from a display table
6155 entry. This function Fills IT with the first glyph from the
6156 ellipsis if an ellipsis is to be displayed. */
6158 static int
6159 next_element_from_ellipsis (it)
6160 struct it *it;
6162 if (it->selective_display_ellipsis_p)
6163 setup_for_ellipsis (it, it->len);
6164 else
6166 /* The face at the current position may be different from the
6167 face we find after the invisible text. Remember what it
6168 was in IT->saved_face_id, and signal that it's there by
6169 setting face_before_selective_p. */
6170 it->saved_face_id = it->face_id;
6171 it->method = GET_FROM_BUFFER;
6172 it->object = it->w->buffer;
6173 reseat_at_next_visible_line_start (it, 1);
6174 it->face_before_selective_p = 1;
6177 return get_next_display_element (it);
6181 /* Deliver an image display element. The iterator IT is already
6182 filled with image information (done in handle_display_prop). Value
6183 is always 1. */
6186 static int
6187 next_element_from_image (it)
6188 struct it *it;
6190 it->what = IT_IMAGE;
6191 return 1;
6195 /* Fill iterator IT with next display element from a stretch glyph
6196 property. IT->object is the value of the text property. Value is
6197 always 1. */
6199 static int
6200 next_element_from_stretch (it)
6201 struct it *it;
6203 it->what = IT_STRETCH;
6204 return 1;
6208 /* Load IT with the next display element from current_buffer. Value
6209 is zero if end of buffer reached. IT->stop_charpos is the next
6210 position at which to stop and check for text properties or buffer
6211 end. */
6213 static int
6214 next_element_from_buffer (it)
6215 struct it *it;
6217 int success_p = 1;
6219 /* Check this assumption, otherwise, we would never enter the
6220 if-statement, below. */
6221 xassert (IT_CHARPOS (*it) >= BEGV
6222 && IT_CHARPOS (*it) <= it->stop_charpos);
6224 if (IT_CHARPOS (*it) >= it->stop_charpos)
6226 if (IT_CHARPOS (*it) >= it->end_charpos)
6228 int overlay_strings_follow_p;
6230 /* End of the game, except when overlay strings follow that
6231 haven't been returned yet. */
6232 if (it->overlay_strings_at_end_processed_p)
6233 overlay_strings_follow_p = 0;
6234 else
6236 it->overlay_strings_at_end_processed_p = 1;
6237 overlay_strings_follow_p = get_overlay_strings (it, 0);
6240 if (overlay_strings_follow_p)
6241 success_p = get_next_display_element (it);
6242 else
6244 it->what = IT_EOB;
6245 it->position = it->current.pos;
6246 success_p = 0;
6249 else
6251 handle_stop (it);
6252 return get_next_display_element (it);
6255 else
6257 /* No face changes, overlays etc. in sight, so just return a
6258 character from current_buffer. */
6259 unsigned char *p;
6261 /* Maybe run the redisplay end trigger hook. Performance note:
6262 This doesn't seem to cost measurable time. */
6263 if (it->redisplay_end_trigger_charpos
6264 && it->glyph_row
6265 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
6266 run_redisplay_end_trigger_hook (it);
6268 /* Get the next character, maybe multibyte. */
6269 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
6270 if (it->multibyte_p && !ASCII_BYTE_P (*p))
6272 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
6273 - IT_BYTEPOS (*it));
6274 it->c = string_char_and_length (p, maxlen, &it->len);
6276 else
6277 it->c = *p, it->len = 1;
6279 /* Record what we have and where it came from. */
6280 it->what = IT_CHARACTER;
6281 it->object = it->w->buffer;
6282 it->position = it->current.pos;
6284 /* Normally we return the character found above, except when we
6285 really want to return an ellipsis for selective display. */
6286 if (it->selective)
6288 if (it->c == '\n')
6290 /* A value of selective > 0 means hide lines indented more
6291 than that number of columns. */
6292 if (it->selective > 0
6293 && IT_CHARPOS (*it) + 1 < ZV
6294 && indented_beyond_p (IT_CHARPOS (*it) + 1,
6295 IT_BYTEPOS (*it) + 1,
6296 (double) it->selective)) /* iftc */
6298 success_p = next_element_from_ellipsis (it);
6299 it->dpvec_char_len = -1;
6302 else if (it->c == '\r' && it->selective == -1)
6304 /* A value of selective == -1 means that everything from the
6305 CR to the end of the line is invisible, with maybe an
6306 ellipsis displayed for it. */
6307 success_p = next_element_from_ellipsis (it);
6308 it->dpvec_char_len = -1;
6313 /* Value is zero if end of buffer reached. */
6314 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
6315 return success_p;
6319 /* Run the redisplay end trigger hook for IT. */
6321 static void
6322 run_redisplay_end_trigger_hook (it)
6323 struct it *it;
6325 Lisp_Object args[3];
6327 /* IT->glyph_row should be non-null, i.e. we should be actually
6328 displaying something, or otherwise we should not run the hook. */
6329 xassert (it->glyph_row);
6331 /* Set up hook arguments. */
6332 args[0] = Qredisplay_end_trigger_functions;
6333 args[1] = it->window;
6334 XSETINT (args[2], it->redisplay_end_trigger_charpos);
6335 it->redisplay_end_trigger_charpos = 0;
6337 /* Since we are *trying* to run these functions, don't try to run
6338 them again, even if they get an error. */
6339 it->w->redisplay_end_trigger = Qnil;
6340 Frun_hook_with_args (3, args);
6342 /* Notice if it changed the face of the character we are on. */
6343 handle_face_prop (it);
6347 /* Deliver a composition display element. The iterator IT is already
6348 filled with composition information (done in
6349 handle_composition_prop). Value is always 1. */
6351 static int
6352 next_element_from_composition (it)
6353 struct it *it;
6355 it->what = IT_COMPOSITION;
6356 it->position = (STRINGP (it->string)
6357 ? it->current.string_pos
6358 : it->current.pos);
6359 if (STRINGP (it->string))
6360 it->object = it->string;
6361 else
6362 it->object = it->w->buffer;
6363 return 1;
6368 /***********************************************************************
6369 Moving an iterator without producing glyphs
6370 ***********************************************************************/
6372 /* Check if iterator is at a position corresponding to a valid buffer
6373 position after some move_it_ call. */
6375 #define IT_POS_VALID_AFTER_MOVE_P(it) \
6376 ((it)->method == GET_FROM_STRING \
6377 ? IT_STRING_CHARPOS (*it) == 0 \
6378 : 1)
6381 /* Move iterator IT to a specified buffer or X position within one
6382 line on the display without producing glyphs.
6384 OP should be a bit mask including some or all of these bits:
6385 MOVE_TO_X: Stop on reaching x-position TO_X.
6386 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
6387 Regardless of OP's value, stop in reaching the end of the display line.
6389 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
6390 This means, in particular, that TO_X includes window's horizontal
6391 scroll amount.
6393 The return value has several possible values that
6394 say what condition caused the scan to stop:
6396 MOVE_POS_MATCH_OR_ZV
6397 - when TO_POS or ZV was reached.
6399 MOVE_X_REACHED
6400 -when TO_X was reached before TO_POS or ZV were reached.
6402 MOVE_LINE_CONTINUED
6403 - when we reached the end of the display area and the line must
6404 be continued.
6406 MOVE_LINE_TRUNCATED
6407 - when we reached the end of the display area and the line is
6408 truncated.
6410 MOVE_NEWLINE_OR_CR
6411 - when we stopped at a line end, i.e. a newline or a CR and selective
6412 display is on. */
6414 static enum move_it_result
6415 move_it_in_display_line_to (it, to_charpos, to_x, op)
6416 struct it *it;
6417 int to_charpos, to_x, op;
6419 enum move_it_result result = MOVE_UNDEFINED;
6420 struct glyph_row *saved_glyph_row;
6422 /* Don't produce glyphs in produce_glyphs. */
6423 saved_glyph_row = it->glyph_row;
6424 it->glyph_row = NULL;
6426 #define BUFFER_POS_REACHED_P() \
6427 ((op & MOVE_TO_POS) != 0 \
6428 && BUFFERP (it->object) \
6429 && IT_CHARPOS (*it) >= to_charpos \
6430 && (it->method == GET_FROM_BUFFER \
6431 || (it->method == GET_FROM_DISPLAY_VECTOR \
6432 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
6435 while (1)
6437 int x, i, ascent = 0, descent = 0;
6439 /* Stop if we move beyond TO_CHARPOS (after an image or stretch glyph). */
6440 if ((op & MOVE_TO_POS) != 0
6441 && BUFFERP (it->object)
6442 && it->method == GET_FROM_BUFFER
6443 && IT_CHARPOS (*it) > to_charpos)
6445 result = MOVE_POS_MATCH_OR_ZV;
6446 break;
6449 /* Stop when ZV reached.
6450 We used to stop here when TO_CHARPOS reached as well, but that is
6451 too soon if this glyph does not fit on this line. So we handle it
6452 explicitly below. */
6453 if (!get_next_display_element (it)
6454 || (it->truncate_lines_p
6455 && BUFFER_POS_REACHED_P ()))
6457 result = MOVE_POS_MATCH_OR_ZV;
6458 break;
6461 /* The call to produce_glyphs will get the metrics of the
6462 display element IT is loaded with. We record in x the
6463 x-position before this display element in case it does not
6464 fit on the line. */
6465 x = it->current_x;
6467 /* Remember the line height so far in case the next element doesn't
6468 fit on the line. */
6469 if (!it->truncate_lines_p)
6471 ascent = it->max_ascent;
6472 descent = it->max_descent;
6475 PRODUCE_GLYPHS (it);
6477 if (it->area != TEXT_AREA)
6479 set_iterator_to_next (it, 1);
6480 continue;
6483 /* The number of glyphs we get back in IT->nglyphs will normally
6484 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
6485 character on a terminal frame, or (iii) a line end. For the
6486 second case, IT->nglyphs - 1 padding glyphs will be present
6487 (on X frames, there is only one glyph produced for a
6488 composite character.
6490 The behavior implemented below means, for continuation lines,
6491 that as many spaces of a TAB as fit on the current line are
6492 displayed there. For terminal frames, as many glyphs of a
6493 multi-glyph character are displayed in the current line, too.
6494 This is what the old redisplay code did, and we keep it that
6495 way. Under X, the whole shape of a complex character must
6496 fit on the line or it will be completely displayed in the
6497 next line.
6499 Note that both for tabs and padding glyphs, all glyphs have
6500 the same width. */
6501 if (it->nglyphs)
6503 /* More than one glyph or glyph doesn't fit on line. All
6504 glyphs have the same width. */
6505 int single_glyph_width = it->pixel_width / it->nglyphs;
6506 int new_x;
6507 int x_before_this_char = x;
6508 int hpos_before_this_char = it->hpos;
6510 for (i = 0; i < it->nglyphs; ++i, x = new_x)
6512 new_x = x + single_glyph_width;
6514 /* We want to leave anything reaching TO_X to the caller. */
6515 if ((op & MOVE_TO_X) && new_x > to_x)
6517 if (BUFFER_POS_REACHED_P ())
6518 goto buffer_pos_reached;
6519 it->current_x = x;
6520 result = MOVE_X_REACHED;
6521 break;
6523 else if (/* Lines are continued. */
6524 !it->truncate_lines_p
6525 && (/* And glyph doesn't fit on the line. */
6526 new_x > it->last_visible_x
6527 /* Or it fits exactly and we're on a window
6528 system frame. */
6529 || (new_x == it->last_visible_x
6530 && FRAME_WINDOW_P (it->f))))
6532 if (/* IT->hpos == 0 means the very first glyph
6533 doesn't fit on the line, e.g. a wide image. */
6534 it->hpos == 0
6535 || (new_x == it->last_visible_x
6536 && FRAME_WINDOW_P (it->f)))
6538 ++it->hpos;
6539 it->current_x = new_x;
6541 /* The character's last glyph just barely fits
6542 in this row. */
6543 if (i == it->nglyphs - 1)
6545 /* If this is the destination position,
6546 return a position *before* it in this row,
6547 now that we know it fits in this row. */
6548 if (BUFFER_POS_REACHED_P ())
6550 it->hpos = hpos_before_this_char;
6551 it->current_x = x_before_this_char;
6552 result = MOVE_POS_MATCH_OR_ZV;
6553 break;
6556 set_iterator_to_next (it, 1);
6557 #ifdef HAVE_WINDOW_SYSTEM
6558 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
6560 if (!get_next_display_element (it))
6562 result = MOVE_POS_MATCH_OR_ZV;
6563 break;
6565 if (BUFFER_POS_REACHED_P ())
6567 if (ITERATOR_AT_END_OF_LINE_P (it))
6568 result = MOVE_POS_MATCH_OR_ZV;
6569 else
6570 result = MOVE_LINE_CONTINUED;
6571 break;
6573 if (ITERATOR_AT_END_OF_LINE_P (it))
6575 result = MOVE_NEWLINE_OR_CR;
6576 break;
6579 #endif /* HAVE_WINDOW_SYSTEM */
6582 else
6584 it->current_x = x;
6585 it->max_ascent = ascent;
6586 it->max_descent = descent;
6589 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
6590 IT_CHARPOS (*it)));
6591 result = MOVE_LINE_CONTINUED;
6592 break;
6594 else if (BUFFER_POS_REACHED_P ())
6595 goto buffer_pos_reached;
6596 else if (new_x > it->first_visible_x)
6598 /* Glyph is visible. Increment number of glyphs that
6599 would be displayed. */
6600 ++it->hpos;
6602 else
6604 /* Glyph is completely off the left margin of the display
6605 area. Nothing to do. */
6609 if (result != MOVE_UNDEFINED)
6610 break;
6612 else if (BUFFER_POS_REACHED_P ())
6614 buffer_pos_reached:
6615 it->current_x = x;
6616 it->max_ascent = ascent;
6617 it->max_descent = descent;
6618 result = MOVE_POS_MATCH_OR_ZV;
6619 break;
6621 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
6623 /* Stop when TO_X specified and reached. This check is
6624 necessary here because of lines consisting of a line end,
6625 only. The line end will not produce any glyphs and we
6626 would never get MOVE_X_REACHED. */
6627 xassert (it->nglyphs == 0);
6628 result = MOVE_X_REACHED;
6629 break;
6632 /* Is this a line end? If yes, we're done. */
6633 if (ITERATOR_AT_END_OF_LINE_P (it))
6635 result = MOVE_NEWLINE_OR_CR;
6636 break;
6639 /* The current display element has been consumed. Advance
6640 to the next. */
6641 set_iterator_to_next (it, 1);
6643 /* Stop if lines are truncated and IT's current x-position is
6644 past the right edge of the window now. */
6645 if (it->truncate_lines_p
6646 && it->current_x >= it->last_visible_x)
6648 #ifdef HAVE_WINDOW_SYSTEM
6649 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
6651 if (!get_next_display_element (it)
6652 || BUFFER_POS_REACHED_P ())
6654 result = MOVE_POS_MATCH_OR_ZV;
6655 break;
6657 if (ITERATOR_AT_END_OF_LINE_P (it))
6659 result = MOVE_NEWLINE_OR_CR;
6660 break;
6663 #endif /* HAVE_WINDOW_SYSTEM */
6664 result = MOVE_LINE_TRUNCATED;
6665 break;
6669 #undef BUFFER_POS_REACHED_P
6671 /* Restore the iterator settings altered at the beginning of this
6672 function. */
6673 it->glyph_row = saved_glyph_row;
6674 return result;
6678 /* Move IT forward until it satisfies one or more of the criteria in
6679 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
6681 OP is a bit-mask that specifies where to stop, and in particular,
6682 which of those four position arguments makes a difference. See the
6683 description of enum move_operation_enum.
6685 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
6686 screen line, this function will set IT to the next position >
6687 TO_CHARPOS. */
6689 void
6690 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
6691 struct it *it;
6692 int to_charpos, to_x, to_y, to_vpos;
6693 int op;
6695 enum move_it_result skip, skip2 = MOVE_X_REACHED;
6696 int line_height;
6697 int reached = 0;
6699 for (;;)
6701 if (op & MOVE_TO_VPOS)
6703 /* If no TO_CHARPOS and no TO_X specified, stop at the
6704 start of the line TO_VPOS. */
6705 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
6707 if (it->vpos == to_vpos)
6709 reached = 1;
6710 break;
6712 else
6713 skip = move_it_in_display_line_to (it, -1, -1, 0);
6715 else
6717 /* TO_VPOS >= 0 means stop at TO_X in the line at
6718 TO_VPOS, or at TO_POS, whichever comes first. */
6719 if (it->vpos == to_vpos)
6721 reached = 2;
6722 break;
6725 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
6727 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
6729 reached = 3;
6730 break;
6732 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
6734 /* We have reached TO_X but not in the line we want. */
6735 skip = move_it_in_display_line_to (it, to_charpos,
6736 -1, MOVE_TO_POS);
6737 if (skip == MOVE_POS_MATCH_OR_ZV)
6739 reached = 4;
6740 break;
6745 else if (op & MOVE_TO_Y)
6747 struct it it_backup;
6749 /* TO_Y specified means stop at TO_X in the line containing
6750 TO_Y---or at TO_CHARPOS if this is reached first. The
6751 problem is that we can't really tell whether the line
6752 contains TO_Y before we have completely scanned it, and
6753 this may skip past TO_X. What we do is to first scan to
6754 TO_X.
6756 If TO_X is not specified, use a TO_X of zero. The reason
6757 is to make the outcome of this function more predictable.
6758 If we didn't use TO_X == 0, we would stop at the end of
6759 the line which is probably not what a caller would expect
6760 to happen. */
6761 skip = move_it_in_display_line_to (it, to_charpos,
6762 ((op & MOVE_TO_X)
6763 ? to_x : 0),
6764 (MOVE_TO_X
6765 | (op & MOVE_TO_POS)));
6767 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
6768 if (skip == MOVE_POS_MATCH_OR_ZV)
6770 reached = 5;
6771 break;
6774 /* If TO_X was reached, we would like to know whether TO_Y
6775 is in the line. This can only be said if we know the
6776 total line height which requires us to scan the rest of
6777 the line. */
6778 if (skip == MOVE_X_REACHED)
6780 it_backup = *it;
6781 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
6782 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
6783 op & MOVE_TO_POS);
6784 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
6787 /* Now, decide whether TO_Y is in this line. */
6788 line_height = it->max_ascent + it->max_descent;
6789 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
6791 if (to_y >= it->current_y
6792 && to_y < it->current_y + line_height)
6794 if (skip == MOVE_X_REACHED)
6795 /* If TO_Y is in this line and TO_X was reached above,
6796 we scanned too far. We have to restore IT's settings
6797 to the ones before skipping. */
6798 *it = it_backup;
6799 reached = 6;
6801 else if (skip == MOVE_X_REACHED)
6803 skip = skip2;
6804 if (skip == MOVE_POS_MATCH_OR_ZV)
6805 reached = 7;
6808 if (reached)
6809 break;
6811 else if (BUFFERP (it->object)
6812 && it->method == GET_FROM_BUFFER
6813 && IT_CHARPOS (*it) >= to_charpos)
6814 skip = MOVE_POS_MATCH_OR_ZV;
6815 else
6816 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
6818 switch (skip)
6820 case MOVE_POS_MATCH_OR_ZV:
6821 reached = 8;
6822 goto out;
6824 case MOVE_NEWLINE_OR_CR:
6825 set_iterator_to_next (it, 1);
6826 it->continuation_lines_width = 0;
6827 break;
6829 case MOVE_LINE_TRUNCATED:
6830 it->continuation_lines_width = 0;
6831 reseat_at_next_visible_line_start (it, 0);
6832 if ((op & MOVE_TO_POS) != 0
6833 && IT_CHARPOS (*it) > to_charpos)
6835 reached = 9;
6836 goto out;
6838 break;
6840 case MOVE_LINE_CONTINUED:
6841 /* For continued lines ending in a tab, some of the glyphs
6842 associated with the tab are displayed on the current
6843 line. Since it->current_x does not include these glyphs,
6844 we use it->last_visible_x instead. */
6845 it->continuation_lines_width +=
6846 (it->c == '\t') ? it->last_visible_x : it->current_x;
6847 break;
6849 default:
6850 abort ();
6853 /* Reset/increment for the next run. */
6854 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
6855 it->current_x = it->hpos = 0;
6856 it->current_y += it->max_ascent + it->max_descent;
6857 ++it->vpos;
6858 last_height = it->max_ascent + it->max_descent;
6859 last_max_ascent = it->max_ascent;
6860 it->max_ascent = it->max_descent = 0;
6863 out:
6865 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
6869 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
6871 If DY > 0, move IT backward at least that many pixels. DY = 0
6872 means move IT backward to the preceding line start or BEGV. This
6873 function may move over more than DY pixels if IT->current_y - DY
6874 ends up in the middle of a line; in this case IT->current_y will be
6875 set to the top of the line moved to. */
6877 void
6878 move_it_vertically_backward (it, dy)
6879 struct it *it;
6880 int dy;
6882 int nlines, h;
6883 struct it it2, it3;
6884 int start_pos;
6886 move_further_back:
6887 xassert (dy >= 0);
6889 start_pos = IT_CHARPOS (*it);
6891 /* Estimate how many newlines we must move back. */
6892 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
6894 /* Set the iterator's position that many lines back. */
6895 while (nlines-- && IT_CHARPOS (*it) > BEGV)
6896 back_to_previous_visible_line_start (it);
6898 /* Reseat the iterator here. When moving backward, we don't want
6899 reseat to skip forward over invisible text, set up the iterator
6900 to deliver from overlay strings at the new position etc. So,
6901 use reseat_1 here. */
6902 reseat_1 (it, it->current.pos, 1);
6904 /* We are now surely at a line start. */
6905 it->current_x = it->hpos = 0;
6906 it->continuation_lines_width = 0;
6908 /* Move forward and see what y-distance we moved. First move to the
6909 start of the next line so that we get its height. We need this
6910 height to be able to tell whether we reached the specified
6911 y-distance. */
6912 it2 = *it;
6913 it2.max_ascent = it2.max_descent = 0;
6916 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
6917 MOVE_TO_POS | MOVE_TO_VPOS);
6919 while (!IT_POS_VALID_AFTER_MOVE_P (&it2));
6920 xassert (IT_CHARPOS (*it) >= BEGV);
6921 it3 = it2;
6923 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
6924 xassert (IT_CHARPOS (*it) >= BEGV);
6925 /* H is the actual vertical distance from the position in *IT
6926 and the starting position. */
6927 h = it2.current_y - it->current_y;
6928 /* NLINES is the distance in number of lines. */
6929 nlines = it2.vpos - it->vpos;
6931 /* Correct IT's y and vpos position
6932 so that they are relative to the starting point. */
6933 it->vpos -= nlines;
6934 it->current_y -= h;
6936 if (dy == 0)
6938 /* DY == 0 means move to the start of the screen line. The
6939 value of nlines is > 0 if continuation lines were involved. */
6940 if (nlines > 0)
6941 move_it_by_lines (it, nlines, 1);
6942 #if 0
6943 /* I think this assert is bogus if buffer contains
6944 invisible text or images. KFS. */
6945 xassert (IT_CHARPOS (*it) <= start_pos);
6946 #endif
6948 else
6950 /* The y-position we try to reach, relative to *IT.
6951 Note that H has been subtracted in front of the if-statement. */
6952 int target_y = it->current_y + h - dy;
6953 int y0 = it3.current_y;
6954 int y1 = line_bottom_y (&it3);
6955 int line_height = y1 - y0;
6957 /* If we did not reach target_y, try to move further backward if
6958 we can. If we moved too far backward, try to move forward. */
6959 if (target_y < it->current_y
6960 /* This is heuristic. In a window that's 3 lines high, with
6961 a line height of 13 pixels each, recentering with point
6962 on the bottom line will try to move -39/2 = 19 pixels
6963 backward. Try to avoid moving into the first line. */
6964 && (it->current_y - target_y
6965 > min (window_box_height (it->w), line_height * 2 / 3))
6966 && IT_CHARPOS (*it) > BEGV)
6968 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
6969 target_y - it->current_y));
6970 dy = it->current_y - target_y;
6971 goto move_further_back;
6973 else if (target_y >= it->current_y + line_height
6974 && IT_CHARPOS (*it) < ZV)
6976 /* Should move forward by at least one line, maybe more.
6978 Note: Calling move_it_by_lines can be expensive on
6979 terminal frames, where compute_motion is used (via
6980 vmotion) to do the job, when there are very long lines
6981 and truncate-lines is nil. That's the reason for
6982 treating terminal frames specially here. */
6984 if (!FRAME_WINDOW_P (it->f))
6985 move_it_vertically (it, target_y - (it->current_y + line_height));
6986 else
6990 move_it_by_lines (it, 1, 1);
6992 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
6995 #if 0
6996 /* I think this assert is bogus if buffer contains
6997 invisible text or images. KFS. */
6998 xassert (IT_CHARPOS (*it) >= BEGV);
6999 #endif
7005 /* Move IT by a specified amount of pixel lines DY. DY negative means
7006 move backwards. DY = 0 means move to start of screen line. At the
7007 end, IT will be on the start of a screen line. */
7009 void
7010 move_it_vertically (it, dy)
7011 struct it *it;
7012 int dy;
7014 if (dy <= 0)
7015 move_it_vertically_backward (it, -dy);
7016 else
7018 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
7019 move_it_to (it, ZV, -1, it->current_y + dy, -1,
7020 MOVE_TO_POS | MOVE_TO_Y);
7021 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
7023 /* If buffer ends in ZV without a newline, move to the start of
7024 the line to satisfy the post-condition. */
7025 if (IT_CHARPOS (*it) == ZV
7026 && ZV > BEGV
7027 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
7028 move_it_by_lines (it, 0, 0);
7033 /* Move iterator IT past the end of the text line it is in. */
7035 void
7036 move_it_past_eol (it)
7037 struct it *it;
7039 enum move_it_result rc;
7041 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
7042 if (rc == MOVE_NEWLINE_OR_CR)
7043 set_iterator_to_next (it, 0);
7047 #if 0 /* Currently not used. */
7049 /* Return non-zero if some text between buffer positions START_CHARPOS
7050 and END_CHARPOS is invisible. IT->window is the window for text
7051 property lookup. */
7053 static int
7054 invisible_text_between_p (it, start_charpos, end_charpos)
7055 struct it *it;
7056 int start_charpos, end_charpos;
7058 Lisp_Object prop, limit;
7059 int invisible_found_p;
7061 xassert (it != NULL && start_charpos <= end_charpos);
7063 /* Is text at START invisible? */
7064 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
7065 it->window);
7066 if (TEXT_PROP_MEANS_INVISIBLE (prop))
7067 invisible_found_p = 1;
7068 else
7070 limit = Fnext_single_char_property_change (make_number (start_charpos),
7071 Qinvisible, Qnil,
7072 make_number (end_charpos));
7073 invisible_found_p = XFASTINT (limit) < end_charpos;
7076 return invisible_found_p;
7079 #endif /* 0 */
7082 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
7083 negative means move up. DVPOS == 0 means move to the start of the
7084 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
7085 NEED_Y_P is zero, IT->current_y will be left unchanged.
7087 Further optimization ideas: If we would know that IT->f doesn't use
7088 a face with proportional font, we could be faster for
7089 truncate-lines nil. */
7091 void
7092 move_it_by_lines (it, dvpos, need_y_p)
7093 struct it *it;
7094 int dvpos, need_y_p;
7096 struct position pos;
7098 /* The commented-out optimization uses vmotion on terminals. This
7099 gives bad results, because elements like it->what, on which
7100 callers such as pos_visible_p rely, aren't updated. */
7101 /* if (!FRAME_WINDOW_P (it->f))
7103 struct text_pos textpos;
7105 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
7106 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
7107 reseat (it, textpos, 1);
7108 it->vpos += pos.vpos;
7109 it->current_y += pos.vpos;
7111 else */
7113 if (dvpos == 0)
7115 /* DVPOS == 0 means move to the start of the screen line. */
7116 move_it_vertically_backward (it, 0);
7117 xassert (it->current_x == 0 && it->hpos == 0);
7118 /* Let next call to line_bottom_y calculate real line height */
7119 last_height = 0;
7121 else if (dvpos > 0)
7123 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
7124 if (!IT_POS_VALID_AFTER_MOVE_P (it))
7125 move_it_to (it, IT_CHARPOS (*it) + 1, -1, -1, -1, MOVE_TO_POS);
7127 else
7129 struct it it2;
7130 int start_charpos, i;
7132 /* Start at the beginning of the screen line containing IT's
7133 position. This may actually move vertically backwards,
7134 in case of overlays, so adjust dvpos accordingly. */
7135 dvpos += it->vpos;
7136 move_it_vertically_backward (it, 0);
7137 dvpos -= it->vpos;
7139 /* Go back -DVPOS visible lines and reseat the iterator there. */
7140 start_charpos = IT_CHARPOS (*it);
7141 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > BEGV; --i)
7142 back_to_previous_visible_line_start (it);
7143 reseat (it, it->current.pos, 1);
7145 /* Move further back if we end up in a string or an image. */
7146 while (!IT_POS_VALID_AFTER_MOVE_P (it))
7148 /* First try to move to start of display line. */
7149 dvpos += it->vpos;
7150 move_it_vertically_backward (it, 0);
7151 dvpos -= it->vpos;
7152 if (IT_POS_VALID_AFTER_MOVE_P (it))
7153 break;
7154 /* If start of line is still in string or image,
7155 move further back. */
7156 back_to_previous_visible_line_start (it);
7157 reseat (it, it->current.pos, 1);
7158 dvpos--;
7161 it->current_x = it->hpos = 0;
7163 /* Above call may have moved too far if continuation lines
7164 are involved. Scan forward and see if it did. */
7165 it2 = *it;
7166 it2.vpos = it2.current_y = 0;
7167 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
7168 it->vpos -= it2.vpos;
7169 it->current_y -= it2.current_y;
7170 it->current_x = it->hpos = 0;
7172 /* If we moved too far back, move IT some lines forward. */
7173 if (it2.vpos > -dvpos)
7175 int delta = it2.vpos + dvpos;
7176 it2 = *it;
7177 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
7178 /* Move back again if we got too far ahead. */
7179 if (IT_CHARPOS (*it) >= start_charpos)
7180 *it = it2;
7185 /* Return 1 if IT points into the middle of a display vector. */
7188 in_display_vector_p (it)
7189 struct it *it;
7191 return (it->method == GET_FROM_DISPLAY_VECTOR
7192 && it->current.dpvec_index > 0
7193 && it->dpvec + it->current.dpvec_index != it->dpend);
7197 /***********************************************************************
7198 Messages
7199 ***********************************************************************/
7202 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
7203 to *Messages*. */
7205 void
7206 add_to_log (format, arg1, arg2)
7207 char *format;
7208 Lisp_Object arg1, arg2;
7210 Lisp_Object args[3];
7211 Lisp_Object msg, fmt;
7212 char *buffer;
7213 int len;
7214 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
7215 USE_SAFE_ALLOCA;
7217 /* Do nothing if called asynchronously. Inserting text into
7218 a buffer may call after-change-functions and alike and
7219 that would means running Lisp asynchronously. */
7220 if (handling_signal)
7221 return;
7223 fmt = msg = Qnil;
7224 GCPRO4 (fmt, msg, arg1, arg2);
7226 args[0] = fmt = build_string (format);
7227 args[1] = arg1;
7228 args[2] = arg2;
7229 msg = Fformat (3, args);
7231 len = SBYTES (msg) + 1;
7232 SAFE_ALLOCA (buffer, char *, len);
7233 bcopy (SDATA (msg), buffer, len);
7235 message_dolog (buffer, len - 1, 1, 0);
7236 SAFE_FREE ();
7238 UNGCPRO;
7242 /* Output a newline in the *Messages* buffer if "needs" one. */
7244 void
7245 message_log_maybe_newline ()
7247 if (message_log_need_newline)
7248 message_dolog ("", 0, 1, 0);
7252 /* Add a string M of length NBYTES to the message log, optionally
7253 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
7254 nonzero, means interpret the contents of M as multibyte. This
7255 function calls low-level routines in order to bypass text property
7256 hooks, etc. which might not be safe to run.
7258 This may GC (insert may run before/after change hooks),
7259 so the buffer M must NOT point to a Lisp string. */
7261 void
7262 message_dolog (m, nbytes, nlflag, multibyte)
7263 const char *m;
7264 int nbytes, nlflag, multibyte;
7266 if (!NILP (Vmemory_full))
7267 return;
7269 if (!NILP (Vmessage_log_max))
7271 struct buffer *oldbuf;
7272 Lisp_Object oldpoint, oldbegv, oldzv;
7273 int old_windows_or_buffers_changed = windows_or_buffers_changed;
7274 int point_at_end = 0;
7275 int zv_at_end = 0;
7276 Lisp_Object old_deactivate_mark, tem;
7277 struct gcpro gcpro1;
7279 old_deactivate_mark = Vdeactivate_mark;
7280 oldbuf = current_buffer;
7281 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
7282 current_buffer->undo_list = Qt;
7284 oldpoint = message_dolog_marker1;
7285 set_marker_restricted (oldpoint, make_number (PT), Qnil);
7286 oldbegv = message_dolog_marker2;
7287 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
7288 oldzv = message_dolog_marker3;
7289 set_marker_restricted (oldzv, make_number (ZV), Qnil);
7290 GCPRO1 (old_deactivate_mark);
7292 if (PT == Z)
7293 point_at_end = 1;
7294 if (ZV == Z)
7295 zv_at_end = 1;
7297 BEGV = BEG;
7298 BEGV_BYTE = BEG_BYTE;
7299 ZV = Z;
7300 ZV_BYTE = Z_BYTE;
7301 TEMP_SET_PT_BOTH (Z, Z_BYTE);
7303 /* Insert the string--maybe converting multibyte to single byte
7304 or vice versa, so that all the text fits the buffer. */
7305 if (multibyte
7306 && NILP (current_buffer->enable_multibyte_characters))
7308 int i, c, char_bytes;
7309 unsigned char work[1];
7311 /* Convert a multibyte string to single-byte
7312 for the *Message* buffer. */
7313 for (i = 0; i < nbytes; i += char_bytes)
7315 c = string_char_and_length (m + i, nbytes - i, &char_bytes);
7316 work[0] = (SINGLE_BYTE_CHAR_P (c)
7318 : multibyte_char_to_unibyte (c, Qnil));
7319 insert_1_both (work, 1, 1, 1, 0, 0);
7322 else if (! multibyte
7323 && ! NILP (current_buffer->enable_multibyte_characters))
7325 int i, c, char_bytes;
7326 unsigned char *msg = (unsigned char *) m;
7327 unsigned char str[MAX_MULTIBYTE_LENGTH];
7328 /* Convert a single-byte string to multibyte
7329 for the *Message* buffer. */
7330 for (i = 0; i < nbytes; i++)
7332 c = unibyte_char_to_multibyte (msg[i]);
7333 char_bytes = CHAR_STRING (c, str);
7334 insert_1_both (str, 1, char_bytes, 1, 0, 0);
7337 else if (nbytes)
7338 insert_1 (m, nbytes, 1, 0, 0);
7340 if (nlflag)
7342 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
7343 insert_1 ("\n", 1, 1, 0, 0);
7345 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
7346 this_bol = PT;
7347 this_bol_byte = PT_BYTE;
7349 /* See if this line duplicates the previous one.
7350 If so, combine duplicates. */
7351 if (this_bol > BEG)
7353 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
7354 prev_bol = PT;
7355 prev_bol_byte = PT_BYTE;
7357 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
7358 this_bol, this_bol_byte);
7359 if (dup)
7361 del_range_both (prev_bol, prev_bol_byte,
7362 this_bol, this_bol_byte, 0);
7363 if (dup > 1)
7365 char dupstr[40];
7366 int duplen;
7368 /* If you change this format, don't forget to also
7369 change message_log_check_duplicate. */
7370 sprintf (dupstr, " [%d times]", dup);
7371 duplen = strlen (dupstr);
7372 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
7373 insert_1 (dupstr, duplen, 1, 0, 1);
7378 /* If we have more than the desired maximum number of lines
7379 in the *Messages* buffer now, delete the oldest ones.
7380 This is safe because we don't have undo in this buffer. */
7382 if (NATNUMP (Vmessage_log_max))
7384 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
7385 -XFASTINT (Vmessage_log_max) - 1, 0);
7386 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
7389 BEGV = XMARKER (oldbegv)->charpos;
7390 BEGV_BYTE = marker_byte_position (oldbegv);
7392 if (zv_at_end)
7394 ZV = Z;
7395 ZV_BYTE = Z_BYTE;
7397 else
7399 ZV = XMARKER (oldzv)->charpos;
7400 ZV_BYTE = marker_byte_position (oldzv);
7403 if (point_at_end)
7404 TEMP_SET_PT_BOTH (Z, Z_BYTE);
7405 else
7406 /* We can't do Fgoto_char (oldpoint) because it will run some
7407 Lisp code. */
7408 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
7409 XMARKER (oldpoint)->bytepos);
7411 UNGCPRO;
7412 unchain_marker (XMARKER (oldpoint));
7413 unchain_marker (XMARKER (oldbegv));
7414 unchain_marker (XMARKER (oldzv));
7416 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
7417 set_buffer_internal (oldbuf);
7418 if (NILP (tem))
7419 windows_or_buffers_changed = old_windows_or_buffers_changed;
7420 message_log_need_newline = !nlflag;
7421 Vdeactivate_mark = old_deactivate_mark;
7426 /* We are at the end of the buffer after just having inserted a newline.
7427 (Note: We depend on the fact we won't be crossing the gap.)
7428 Check to see if the most recent message looks a lot like the previous one.
7429 Return 0 if different, 1 if the new one should just replace it, or a
7430 value N > 1 if we should also append " [N times]". */
7432 static int
7433 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
7434 int prev_bol, this_bol;
7435 int prev_bol_byte, this_bol_byte;
7437 int i;
7438 int len = Z_BYTE - 1 - this_bol_byte;
7439 int seen_dots = 0;
7440 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
7441 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
7443 for (i = 0; i < len; i++)
7445 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
7446 seen_dots = 1;
7447 if (p1[i] != p2[i])
7448 return seen_dots;
7450 p1 += len;
7451 if (*p1 == '\n')
7452 return 2;
7453 if (*p1++ == ' ' && *p1++ == '[')
7455 int n = 0;
7456 while (*p1 >= '0' && *p1 <= '9')
7457 n = n * 10 + *p1++ - '0';
7458 if (strncmp (p1, " times]\n", 8) == 0)
7459 return n+1;
7461 return 0;
7465 /* Display an echo area message M with a specified length of NBYTES
7466 bytes. The string may include null characters. If M is 0, clear
7467 out any existing message, and let the mini-buffer text show
7468 through.
7470 This may GC, so the buffer M must NOT point to a Lisp string. */
7472 void
7473 message2 (m, nbytes, multibyte)
7474 const char *m;
7475 int nbytes;
7476 int multibyte;
7478 /* First flush out any partial line written with print. */
7479 message_log_maybe_newline ();
7480 if (m)
7481 message_dolog (m, nbytes, 1, multibyte);
7482 message2_nolog (m, nbytes, multibyte);
7486 /* The non-logging counterpart of message2. */
7488 void
7489 message2_nolog (m, nbytes, multibyte)
7490 const char *m;
7491 int nbytes, multibyte;
7493 struct frame *sf = SELECTED_FRAME ();
7494 message_enable_multibyte = multibyte;
7496 if (noninteractive)
7498 if (noninteractive_need_newline)
7499 putc ('\n', stderr);
7500 noninteractive_need_newline = 0;
7501 if (m)
7502 fwrite (m, nbytes, 1, stderr);
7503 if (cursor_in_echo_area == 0)
7504 fprintf (stderr, "\n");
7505 fflush (stderr);
7507 /* A null message buffer means that the frame hasn't really been
7508 initialized yet. Error messages get reported properly by
7509 cmd_error, so this must be just an informative message; toss it. */
7510 else if (INTERACTIVE
7511 && sf->glyphs_initialized_p
7512 && FRAME_MESSAGE_BUF (sf))
7514 Lisp_Object mini_window;
7515 struct frame *f;
7517 /* Get the frame containing the mini-buffer
7518 that the selected frame is using. */
7519 mini_window = FRAME_MINIBUF_WINDOW (sf);
7520 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
7522 FRAME_SAMPLE_VISIBILITY (f);
7523 if (FRAME_VISIBLE_P (sf)
7524 && ! FRAME_VISIBLE_P (f))
7525 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
7527 if (m)
7529 set_message (m, Qnil, nbytes, multibyte);
7530 if (minibuffer_auto_raise)
7531 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
7533 else
7534 clear_message (1, 1);
7536 do_pending_window_change (0);
7537 echo_area_display (1);
7538 do_pending_window_change (0);
7539 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
7540 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
7545 /* Display an echo area message M with a specified length of NBYTES
7546 bytes. The string may include null characters. If M is not a
7547 string, clear out any existing message, and let the mini-buffer
7548 text show through.
7550 This function cancels echoing. */
7552 void
7553 message3 (m, nbytes, multibyte)
7554 Lisp_Object m;
7555 int nbytes;
7556 int multibyte;
7558 struct gcpro gcpro1;
7560 GCPRO1 (m);
7561 clear_message (1,1);
7562 cancel_echoing ();
7564 /* First flush out any partial line written with print. */
7565 message_log_maybe_newline ();
7566 if (STRINGP (m))
7568 char *buffer;
7569 USE_SAFE_ALLOCA;
7571 SAFE_ALLOCA (buffer, char *, nbytes);
7572 bcopy (SDATA (m), buffer, nbytes);
7573 message_dolog (buffer, nbytes, 1, multibyte);
7574 SAFE_FREE ();
7576 message3_nolog (m, nbytes, multibyte);
7578 UNGCPRO;
7582 /* The non-logging version of message3.
7583 This does not cancel echoing, because it is used for echoing.
7584 Perhaps we need to make a separate function for echoing
7585 and make this cancel echoing. */
7587 void
7588 message3_nolog (m, nbytes, multibyte)
7589 Lisp_Object m;
7590 int nbytes, multibyte;
7592 struct frame *sf = SELECTED_FRAME ();
7593 message_enable_multibyte = multibyte;
7595 if (noninteractive)
7597 if (noninteractive_need_newline)
7598 putc ('\n', stderr);
7599 noninteractive_need_newline = 0;
7600 if (STRINGP (m))
7601 fwrite (SDATA (m), nbytes, 1, stderr);
7602 if (cursor_in_echo_area == 0)
7603 fprintf (stderr, "\n");
7604 fflush (stderr);
7606 /* A null message buffer means that the frame hasn't really been
7607 initialized yet. Error messages get reported properly by
7608 cmd_error, so this must be just an informative message; toss it. */
7609 else if (INTERACTIVE
7610 && sf->glyphs_initialized_p
7611 && FRAME_MESSAGE_BUF (sf))
7613 Lisp_Object mini_window;
7614 Lisp_Object frame;
7615 struct frame *f;
7617 /* Get the frame containing the mini-buffer
7618 that the selected frame is using. */
7619 mini_window = FRAME_MINIBUF_WINDOW (sf);
7620 frame = XWINDOW (mini_window)->frame;
7621 f = XFRAME (frame);
7623 FRAME_SAMPLE_VISIBILITY (f);
7624 if (FRAME_VISIBLE_P (sf)
7625 && !FRAME_VISIBLE_P (f))
7626 Fmake_frame_visible (frame);
7628 if (STRINGP (m) && SCHARS (m) > 0)
7630 set_message (NULL, m, nbytes, multibyte);
7631 if (minibuffer_auto_raise)
7632 Fraise_frame (frame);
7633 /* Assume we are not echoing.
7634 (If we are, echo_now will override this.) */
7635 echo_message_buffer = Qnil;
7637 else
7638 clear_message (1, 1);
7640 do_pending_window_change (0);
7641 echo_area_display (1);
7642 do_pending_window_change (0);
7643 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
7644 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
7649 /* Display a null-terminated echo area message M. If M is 0, clear
7650 out any existing message, and let the mini-buffer text show through.
7652 The buffer M must continue to exist until after the echo area gets
7653 cleared or some other message gets displayed there. Do not pass
7654 text that is stored in a Lisp string. Do not pass text in a buffer
7655 that was alloca'd. */
7657 void
7658 message1 (m)
7659 char *m;
7661 message2 (m, (m ? strlen (m) : 0), 0);
7665 /* The non-logging counterpart of message1. */
7667 void
7668 message1_nolog (m)
7669 char *m;
7671 message2_nolog (m, (m ? strlen (m) : 0), 0);
7674 /* Display a message M which contains a single %s
7675 which gets replaced with STRING. */
7677 void
7678 message_with_string (m, string, log)
7679 char *m;
7680 Lisp_Object string;
7681 int log;
7683 CHECK_STRING (string);
7685 if (noninteractive)
7687 if (m)
7689 if (noninteractive_need_newline)
7690 putc ('\n', stderr);
7691 noninteractive_need_newline = 0;
7692 fprintf (stderr, m, SDATA (string));
7693 if (cursor_in_echo_area == 0)
7694 fprintf (stderr, "\n");
7695 fflush (stderr);
7698 else if (INTERACTIVE)
7700 /* The frame whose minibuffer we're going to display the message on.
7701 It may be larger than the selected frame, so we need
7702 to use its buffer, not the selected frame's buffer. */
7703 Lisp_Object mini_window;
7704 struct frame *f, *sf = SELECTED_FRAME ();
7706 /* Get the frame containing the minibuffer
7707 that the selected frame is using. */
7708 mini_window = FRAME_MINIBUF_WINDOW (sf);
7709 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
7711 /* A null message buffer means that the frame hasn't really been
7712 initialized yet. Error messages get reported properly by
7713 cmd_error, so this must be just an informative message; toss it. */
7714 if (FRAME_MESSAGE_BUF (f))
7716 Lisp_Object args[2], message;
7717 struct gcpro gcpro1, gcpro2;
7719 args[0] = build_string (m);
7720 args[1] = message = string;
7721 GCPRO2 (args[0], message);
7722 gcpro1.nvars = 2;
7724 message = Fformat (2, args);
7726 if (log)
7727 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
7728 else
7729 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
7731 UNGCPRO;
7733 /* Print should start at the beginning of the message
7734 buffer next time. */
7735 message_buf_print = 0;
7741 /* Dump an informative message to the minibuf. If M is 0, clear out
7742 any existing message, and let the mini-buffer text show through. */
7744 /* VARARGS 1 */
7745 void
7746 message (m, a1, a2, a3)
7747 char *m;
7748 EMACS_INT a1, a2, a3;
7750 if (noninteractive)
7752 if (m)
7754 if (noninteractive_need_newline)
7755 putc ('\n', stderr);
7756 noninteractive_need_newline = 0;
7757 fprintf (stderr, m, a1, a2, a3);
7758 if (cursor_in_echo_area == 0)
7759 fprintf (stderr, "\n");
7760 fflush (stderr);
7763 else if (INTERACTIVE)
7765 /* The frame whose mini-buffer we're going to display the message
7766 on. It may be larger than the selected frame, so we need to
7767 use its buffer, not the selected frame's buffer. */
7768 Lisp_Object mini_window;
7769 struct frame *f, *sf = SELECTED_FRAME ();
7771 /* Get the frame containing the mini-buffer
7772 that the selected frame is using. */
7773 mini_window = FRAME_MINIBUF_WINDOW (sf);
7774 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
7776 /* A null message buffer means that the frame hasn't really been
7777 initialized yet. Error messages get reported properly by
7778 cmd_error, so this must be just an informative message; toss
7779 it. */
7780 if (FRAME_MESSAGE_BUF (f))
7782 if (m)
7784 int len;
7785 #ifdef NO_ARG_ARRAY
7786 char *a[3];
7787 a[0] = (char *) a1;
7788 a[1] = (char *) a2;
7789 a[2] = (char *) a3;
7791 len = doprnt (FRAME_MESSAGE_BUF (f),
7792 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
7793 #else
7794 len = doprnt (FRAME_MESSAGE_BUF (f),
7795 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
7796 (char **) &a1);
7797 #endif /* NO_ARG_ARRAY */
7799 message2 (FRAME_MESSAGE_BUF (f), len, 0);
7801 else
7802 message1 (0);
7804 /* Print should start at the beginning of the message
7805 buffer next time. */
7806 message_buf_print = 0;
7812 /* The non-logging version of message. */
7814 void
7815 message_nolog (m, a1, a2, a3)
7816 char *m;
7817 EMACS_INT a1, a2, a3;
7819 Lisp_Object old_log_max;
7820 old_log_max = Vmessage_log_max;
7821 Vmessage_log_max = Qnil;
7822 message (m, a1, a2, a3);
7823 Vmessage_log_max = old_log_max;
7827 /* Display the current message in the current mini-buffer. This is
7828 only called from error handlers in process.c, and is not time
7829 critical. */
7831 void
7832 update_echo_area ()
7834 if (!NILP (echo_area_buffer[0]))
7836 Lisp_Object string;
7837 string = Fcurrent_message ();
7838 message3 (string, SBYTES (string),
7839 !NILP (current_buffer->enable_multibyte_characters));
7844 /* Make sure echo area buffers in `echo_buffers' are live.
7845 If they aren't, make new ones. */
7847 static void
7848 ensure_echo_area_buffers ()
7850 int i;
7852 for (i = 0; i < 2; ++i)
7853 if (!BUFFERP (echo_buffer[i])
7854 || NILP (XBUFFER (echo_buffer[i])->name))
7856 char name[30];
7857 Lisp_Object old_buffer;
7858 int j;
7860 old_buffer = echo_buffer[i];
7861 sprintf (name, " *Echo Area %d*", i);
7862 echo_buffer[i] = Fget_buffer_create (build_string (name));
7863 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
7865 for (j = 0; j < 2; ++j)
7866 if (EQ (old_buffer, echo_area_buffer[j]))
7867 echo_area_buffer[j] = echo_buffer[i];
7872 /* Call FN with args A1..A4 with either the current or last displayed
7873 echo_area_buffer as current buffer.
7875 WHICH zero means use the current message buffer
7876 echo_area_buffer[0]. If that is nil, choose a suitable buffer
7877 from echo_buffer[] and clear it.
7879 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
7880 suitable buffer from echo_buffer[] and clear it.
7882 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
7883 that the current message becomes the last displayed one, make
7884 choose a suitable buffer for echo_area_buffer[0], and clear it.
7886 Value is what FN returns. */
7888 static int
7889 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
7890 struct window *w;
7891 int which;
7892 int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
7893 EMACS_INT a1;
7894 Lisp_Object a2;
7895 EMACS_INT a3, a4;
7897 Lisp_Object buffer;
7898 int this_one, the_other, clear_buffer_p, rc;
7899 int count = SPECPDL_INDEX ();
7901 /* If buffers aren't live, make new ones. */
7902 ensure_echo_area_buffers ();
7904 clear_buffer_p = 0;
7906 if (which == 0)
7907 this_one = 0, the_other = 1;
7908 else if (which > 0)
7909 this_one = 1, the_other = 0;
7910 else
7912 this_one = 0, the_other = 1;
7913 clear_buffer_p = 1;
7915 /* We need a fresh one in case the current echo buffer equals
7916 the one containing the last displayed echo area message. */
7917 if (!NILP (echo_area_buffer[this_one])
7918 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
7919 echo_area_buffer[this_one] = Qnil;
7922 /* Choose a suitable buffer from echo_buffer[] is we don't
7923 have one. */
7924 if (NILP (echo_area_buffer[this_one]))
7926 echo_area_buffer[this_one]
7927 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
7928 ? echo_buffer[the_other]
7929 : echo_buffer[this_one]);
7930 clear_buffer_p = 1;
7933 buffer = echo_area_buffer[this_one];
7935 /* Don't get confused by reusing the buffer used for echoing
7936 for a different purpose. */
7937 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
7938 cancel_echoing ();
7940 record_unwind_protect (unwind_with_echo_area_buffer,
7941 with_echo_area_buffer_unwind_data (w));
7943 /* Make the echo area buffer current. Note that for display
7944 purposes, it is not necessary that the displayed window's buffer
7945 == current_buffer, except for text property lookup. So, let's
7946 only set that buffer temporarily here without doing a full
7947 Fset_window_buffer. We must also change w->pointm, though,
7948 because otherwise an assertions in unshow_buffer fails, and Emacs
7949 aborts. */
7950 set_buffer_internal_1 (XBUFFER (buffer));
7951 if (w)
7953 w->buffer = buffer;
7954 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
7957 current_buffer->undo_list = Qt;
7958 current_buffer->read_only = Qnil;
7959 specbind (Qinhibit_read_only, Qt);
7960 specbind (Qinhibit_modification_hooks, Qt);
7962 if (clear_buffer_p && Z > BEG)
7963 del_range (BEG, Z);
7965 xassert (BEGV >= BEG);
7966 xassert (ZV <= Z && ZV >= BEGV);
7968 rc = fn (a1, a2, a3, a4);
7970 xassert (BEGV >= BEG);
7971 xassert (ZV <= Z && ZV >= BEGV);
7973 unbind_to (count, Qnil);
7974 return rc;
7978 /* Save state that should be preserved around the call to the function
7979 FN called in with_echo_area_buffer. */
7981 static Lisp_Object
7982 with_echo_area_buffer_unwind_data (w)
7983 struct window *w;
7985 int i = 0;
7986 Lisp_Object vector;
7988 /* Reduce consing by keeping one vector in
7989 Vwith_echo_area_save_vector. */
7990 vector = Vwith_echo_area_save_vector;
7991 Vwith_echo_area_save_vector = Qnil;
7993 if (NILP (vector))
7994 vector = Fmake_vector (make_number (7), Qnil);
7996 XSETBUFFER (AREF (vector, i), current_buffer); ++i;
7997 AREF (vector, i) = Vdeactivate_mark, ++i;
7998 AREF (vector, i) = make_number (windows_or_buffers_changed), ++i;
8000 if (w)
8002 XSETWINDOW (AREF (vector, i), w); ++i;
8003 AREF (vector, i) = w->buffer; ++i;
8004 AREF (vector, i) = make_number (XMARKER (w->pointm)->charpos); ++i;
8005 AREF (vector, i) = make_number (XMARKER (w->pointm)->bytepos); ++i;
8007 else
8009 int end = i + 4;
8010 for (; i < end; ++i)
8011 AREF (vector, i) = Qnil;
8014 xassert (i == ASIZE (vector));
8015 return vector;
8019 /* Restore global state from VECTOR which was created by
8020 with_echo_area_buffer_unwind_data. */
8022 static Lisp_Object
8023 unwind_with_echo_area_buffer (vector)
8024 Lisp_Object vector;
8026 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
8027 Vdeactivate_mark = AREF (vector, 1);
8028 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
8030 if (WINDOWP (AREF (vector, 3)))
8032 struct window *w;
8033 Lisp_Object buffer, charpos, bytepos;
8035 w = XWINDOW (AREF (vector, 3));
8036 buffer = AREF (vector, 4);
8037 charpos = AREF (vector, 5);
8038 bytepos = AREF (vector, 6);
8040 w->buffer = buffer;
8041 set_marker_both (w->pointm, buffer,
8042 XFASTINT (charpos), XFASTINT (bytepos));
8045 Vwith_echo_area_save_vector = vector;
8046 return Qnil;
8050 /* Set up the echo area for use by print functions. MULTIBYTE_P
8051 non-zero means we will print multibyte. */
8053 void
8054 setup_echo_area_for_printing (multibyte_p)
8055 int multibyte_p;
8057 /* If we can't find an echo area any more, exit. */
8058 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
8059 Fkill_emacs (Qnil);
8061 ensure_echo_area_buffers ();
8063 if (!message_buf_print)
8065 /* A message has been output since the last time we printed.
8066 Choose a fresh echo area buffer. */
8067 if (EQ (echo_area_buffer[1], echo_buffer[0]))
8068 echo_area_buffer[0] = echo_buffer[1];
8069 else
8070 echo_area_buffer[0] = echo_buffer[0];
8072 /* Switch to that buffer and clear it. */
8073 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
8074 current_buffer->truncate_lines = Qnil;
8076 if (Z > BEG)
8078 int count = SPECPDL_INDEX ();
8079 specbind (Qinhibit_read_only, Qt);
8080 /* Note that undo recording is always disabled. */
8081 del_range (BEG, Z);
8082 unbind_to (count, Qnil);
8084 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
8086 /* Set up the buffer for the multibyteness we need. */
8087 if (multibyte_p
8088 != !NILP (current_buffer->enable_multibyte_characters))
8089 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
8091 /* Raise the frame containing the echo area. */
8092 if (minibuffer_auto_raise)
8094 struct frame *sf = SELECTED_FRAME ();
8095 Lisp_Object mini_window;
8096 mini_window = FRAME_MINIBUF_WINDOW (sf);
8097 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
8100 message_log_maybe_newline ();
8101 message_buf_print = 1;
8103 else
8105 if (NILP (echo_area_buffer[0]))
8107 if (EQ (echo_area_buffer[1], echo_buffer[0]))
8108 echo_area_buffer[0] = echo_buffer[1];
8109 else
8110 echo_area_buffer[0] = echo_buffer[0];
8113 if (current_buffer != XBUFFER (echo_area_buffer[0]))
8115 /* Someone switched buffers between print requests. */
8116 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
8117 current_buffer->truncate_lines = Qnil;
8123 /* Display an echo area message in window W. Value is non-zero if W's
8124 height is changed. If display_last_displayed_message_p is
8125 non-zero, display the message that was last displayed, otherwise
8126 display the current message. */
8128 static int
8129 display_echo_area (w)
8130 struct window *w;
8132 int i, no_message_p, window_height_changed_p, count;
8134 /* Temporarily disable garbage collections while displaying the echo
8135 area. This is done because a GC can print a message itself.
8136 That message would modify the echo area buffer's contents while a
8137 redisplay of the buffer is going on, and seriously confuse
8138 redisplay. */
8139 count = inhibit_garbage_collection ();
8141 /* If there is no message, we must call display_echo_area_1
8142 nevertheless because it resizes the window. But we will have to
8143 reset the echo_area_buffer in question to nil at the end because
8144 with_echo_area_buffer will sets it to an empty buffer. */
8145 i = display_last_displayed_message_p ? 1 : 0;
8146 no_message_p = NILP (echo_area_buffer[i]);
8148 window_height_changed_p
8149 = with_echo_area_buffer (w, display_last_displayed_message_p,
8150 display_echo_area_1,
8151 (EMACS_INT) w, Qnil, 0, 0);
8153 if (no_message_p)
8154 echo_area_buffer[i] = Qnil;
8156 unbind_to (count, Qnil);
8157 return window_height_changed_p;
8161 /* Helper for display_echo_area. Display the current buffer which
8162 contains the current echo area message in window W, a mini-window,
8163 a pointer to which is passed in A1. A2..A4 are currently not used.
8164 Change the height of W so that all of the message is displayed.
8165 Value is non-zero if height of W was changed. */
8167 static int
8168 display_echo_area_1 (a1, a2, a3, a4)
8169 EMACS_INT a1;
8170 Lisp_Object a2;
8171 EMACS_INT a3, a4;
8173 struct window *w = (struct window *) a1;
8174 Lisp_Object window;
8175 struct text_pos start;
8176 int window_height_changed_p = 0;
8178 /* Do this before displaying, so that we have a large enough glyph
8179 matrix for the display. If we can't get enough space for the
8180 whole text, display the last N lines. That works by setting w->start. */
8181 window_height_changed_p = resize_mini_window (w, 0);
8183 /* Use the starting position chosen by resize_mini_window. */
8184 SET_TEXT_POS_FROM_MARKER (start, w->start);
8186 /* Display. */
8187 clear_glyph_matrix (w->desired_matrix);
8188 XSETWINDOW (window, w);
8189 try_window (window, start, 0);
8191 return window_height_changed_p;
8195 /* Resize the echo area window to exactly the size needed for the
8196 currently displayed message, if there is one. If a mini-buffer
8197 is active, don't shrink it. */
8199 void
8200 resize_echo_area_exactly ()
8202 if (BUFFERP (echo_area_buffer[0])
8203 && WINDOWP (echo_area_window))
8205 struct window *w = XWINDOW (echo_area_window);
8206 int resized_p;
8207 Lisp_Object resize_exactly;
8209 if (minibuf_level == 0)
8210 resize_exactly = Qt;
8211 else
8212 resize_exactly = Qnil;
8214 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
8215 (EMACS_INT) w, resize_exactly, 0, 0);
8216 if (resized_p)
8218 ++windows_or_buffers_changed;
8219 ++update_mode_lines;
8220 redisplay_internal (0);
8226 /* Callback function for with_echo_area_buffer, when used from
8227 resize_echo_area_exactly. A1 contains a pointer to the window to
8228 resize, EXACTLY non-nil means resize the mini-window exactly to the
8229 size of the text displayed. A3 and A4 are not used. Value is what
8230 resize_mini_window returns. */
8232 static int
8233 resize_mini_window_1 (a1, exactly, a3, a4)
8234 EMACS_INT a1;
8235 Lisp_Object exactly;
8236 EMACS_INT a3, a4;
8238 return resize_mini_window ((struct window *) a1, !NILP (exactly));
8242 /* Resize mini-window W to fit the size of its contents. EXACT:P
8243 means size the window exactly to the size needed. Otherwise, it's
8244 only enlarged until W's buffer is empty.
8246 Set W->start to the right place to begin display. If the whole
8247 contents fit, start at the beginning. Otherwise, start so as
8248 to make the end of the contents appear. This is particularly
8249 important for y-or-n-p, but seems desirable generally.
8251 Value is non-zero if the window height has been changed. */
8254 resize_mini_window (w, exact_p)
8255 struct window *w;
8256 int exact_p;
8258 struct frame *f = XFRAME (w->frame);
8259 int window_height_changed_p = 0;
8261 xassert (MINI_WINDOW_P (w));
8263 /* By default, start display at the beginning. */
8264 set_marker_both (w->start, w->buffer,
8265 BUF_BEGV (XBUFFER (w->buffer)),
8266 BUF_BEGV_BYTE (XBUFFER (w->buffer)));
8268 /* Don't resize windows while redisplaying a window; it would
8269 confuse redisplay functions when the size of the window they are
8270 displaying changes from under them. Such a resizing can happen,
8271 for instance, when which-func prints a long message while
8272 we are running fontification-functions. We're running these
8273 functions with safe_call which binds inhibit-redisplay to t. */
8274 if (!NILP (Vinhibit_redisplay))
8275 return 0;
8277 /* Nil means don't try to resize. */
8278 if (NILP (Vresize_mini_windows)
8279 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
8280 return 0;
8282 if (!FRAME_MINIBUF_ONLY_P (f))
8284 struct it it;
8285 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
8286 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
8287 int height, max_height;
8288 int unit = FRAME_LINE_HEIGHT (f);
8289 struct text_pos start;
8290 struct buffer *old_current_buffer = NULL;
8292 if (current_buffer != XBUFFER (w->buffer))
8294 old_current_buffer = current_buffer;
8295 set_buffer_internal (XBUFFER (w->buffer));
8298 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
8300 /* Compute the max. number of lines specified by the user. */
8301 if (FLOATP (Vmax_mini_window_height))
8302 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
8303 else if (INTEGERP (Vmax_mini_window_height))
8304 max_height = XINT (Vmax_mini_window_height);
8305 else
8306 max_height = total_height / 4;
8308 /* Correct that max. height if it's bogus. */
8309 max_height = max (1, max_height);
8310 max_height = min (total_height, max_height);
8312 /* Find out the height of the text in the window. */
8313 if (it.truncate_lines_p)
8314 height = 1;
8315 else
8317 last_height = 0;
8318 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
8319 if (it.max_ascent == 0 && it.max_descent == 0)
8320 height = it.current_y + last_height;
8321 else
8322 height = it.current_y + it.max_ascent + it.max_descent;
8323 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
8324 height = (height + unit - 1) / unit;
8327 /* Compute a suitable window start. */
8328 if (height > max_height)
8330 height = max_height;
8331 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
8332 move_it_vertically_backward (&it, (height - 1) * unit);
8333 start = it.current.pos;
8335 else
8336 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
8337 SET_MARKER_FROM_TEXT_POS (w->start, start);
8339 if (EQ (Vresize_mini_windows, Qgrow_only))
8341 /* Let it grow only, until we display an empty message, in which
8342 case the window shrinks again. */
8343 if (height > WINDOW_TOTAL_LINES (w))
8345 int old_height = WINDOW_TOTAL_LINES (w);
8346 freeze_window_starts (f, 1);
8347 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
8348 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8350 else if (height < WINDOW_TOTAL_LINES (w)
8351 && (exact_p || BEGV == ZV))
8353 int old_height = WINDOW_TOTAL_LINES (w);
8354 freeze_window_starts (f, 0);
8355 shrink_mini_window (w);
8356 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8359 else
8361 /* Always resize to exact size needed. */
8362 if (height > WINDOW_TOTAL_LINES (w))
8364 int old_height = WINDOW_TOTAL_LINES (w);
8365 freeze_window_starts (f, 1);
8366 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
8367 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8369 else if (height < WINDOW_TOTAL_LINES (w))
8371 int old_height = WINDOW_TOTAL_LINES (w);
8372 freeze_window_starts (f, 0);
8373 shrink_mini_window (w);
8375 if (height)
8377 freeze_window_starts (f, 1);
8378 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
8381 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8385 if (old_current_buffer)
8386 set_buffer_internal (old_current_buffer);
8389 return window_height_changed_p;
8393 /* Value is the current message, a string, or nil if there is no
8394 current message. */
8396 Lisp_Object
8397 current_message ()
8399 Lisp_Object msg;
8401 if (NILP (echo_area_buffer[0]))
8402 msg = Qnil;
8403 else
8405 with_echo_area_buffer (0, 0, current_message_1,
8406 (EMACS_INT) &msg, Qnil, 0, 0);
8407 if (NILP (msg))
8408 echo_area_buffer[0] = Qnil;
8411 return msg;
8415 static int
8416 current_message_1 (a1, a2, a3, a4)
8417 EMACS_INT a1;
8418 Lisp_Object a2;
8419 EMACS_INT a3, a4;
8421 Lisp_Object *msg = (Lisp_Object *) a1;
8423 if (Z > BEG)
8424 *msg = make_buffer_string (BEG, Z, 1);
8425 else
8426 *msg = Qnil;
8427 return 0;
8431 /* Push the current message on Vmessage_stack for later restauration
8432 by restore_message. Value is non-zero if the current message isn't
8433 empty. This is a relatively infrequent operation, so it's not
8434 worth optimizing. */
8437 push_message ()
8439 Lisp_Object msg;
8440 msg = current_message ();
8441 Vmessage_stack = Fcons (msg, Vmessage_stack);
8442 return STRINGP (msg);
8446 /* Restore message display from the top of Vmessage_stack. */
8448 void
8449 restore_message ()
8451 Lisp_Object msg;
8453 xassert (CONSP (Vmessage_stack));
8454 msg = XCAR (Vmessage_stack);
8455 if (STRINGP (msg))
8456 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
8457 else
8458 message3_nolog (msg, 0, 0);
8462 /* Handler for record_unwind_protect calling pop_message. */
8464 Lisp_Object
8465 pop_message_unwind (dummy)
8466 Lisp_Object dummy;
8468 pop_message ();
8469 return Qnil;
8472 /* Pop the top-most entry off Vmessage_stack. */
8474 void
8475 pop_message ()
8477 xassert (CONSP (Vmessage_stack));
8478 Vmessage_stack = XCDR (Vmessage_stack);
8482 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
8483 exits. If the stack is not empty, we have a missing pop_message
8484 somewhere. */
8486 void
8487 check_message_stack ()
8489 if (!NILP (Vmessage_stack))
8490 abort ();
8494 /* Truncate to NCHARS what will be displayed in the echo area the next
8495 time we display it---but don't redisplay it now. */
8497 void
8498 truncate_echo_area (nchars)
8499 int nchars;
8501 if (nchars == 0)
8502 echo_area_buffer[0] = Qnil;
8503 /* A null message buffer means that the frame hasn't really been
8504 initialized yet. Error messages get reported properly by
8505 cmd_error, so this must be just an informative message; toss it. */
8506 else if (!noninteractive
8507 && INTERACTIVE
8508 && !NILP (echo_area_buffer[0]))
8510 struct frame *sf = SELECTED_FRAME ();
8511 if (FRAME_MESSAGE_BUF (sf))
8512 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
8517 /* Helper function for truncate_echo_area. Truncate the current
8518 message to at most NCHARS characters. */
8520 static int
8521 truncate_message_1 (nchars, a2, a3, a4)
8522 EMACS_INT nchars;
8523 Lisp_Object a2;
8524 EMACS_INT a3, a4;
8526 if (BEG + nchars < Z)
8527 del_range (BEG + nchars, Z);
8528 if (Z == BEG)
8529 echo_area_buffer[0] = Qnil;
8530 return 0;
8534 /* Set the current message to a substring of S or STRING.
8536 If STRING is a Lisp string, set the message to the first NBYTES
8537 bytes from STRING. NBYTES zero means use the whole string. If
8538 STRING is multibyte, the message will be displayed multibyte.
8540 If S is not null, set the message to the first LEN bytes of S. LEN
8541 zero means use the whole string. MULTIBYTE_P non-zero means S is
8542 multibyte. Display the message multibyte in that case.
8544 Doesn't GC, as with_echo_area_buffer binds Qinhibit_modification_hooks
8545 to t before calling set_message_1 (which calls insert).
8548 void
8549 set_message (s, string, nbytes, multibyte_p)
8550 const char *s;
8551 Lisp_Object string;
8552 int nbytes, multibyte_p;
8554 message_enable_multibyte
8555 = ((s && multibyte_p)
8556 || (STRINGP (string) && STRING_MULTIBYTE (string)));
8558 with_echo_area_buffer (0, -1, set_message_1,
8559 (EMACS_INT) s, string, nbytes, multibyte_p);
8560 message_buf_print = 0;
8561 help_echo_showing_p = 0;
8565 /* Helper function for set_message. Arguments have the same meaning
8566 as there, with A1 corresponding to S and A2 corresponding to STRING
8567 This function is called with the echo area buffer being
8568 current. */
8570 static int
8571 set_message_1 (a1, a2, nbytes, multibyte_p)
8572 EMACS_INT a1;
8573 Lisp_Object a2;
8574 EMACS_INT nbytes, multibyte_p;
8576 const char *s = (const char *) a1;
8577 Lisp_Object string = a2;
8579 /* Change multibyteness of the echo buffer appropriately. */
8580 if (message_enable_multibyte
8581 != !NILP (current_buffer->enable_multibyte_characters))
8582 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
8584 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
8586 /* Insert new message at BEG. */
8587 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
8589 if (STRINGP (string))
8591 int nchars;
8593 if (nbytes == 0)
8594 nbytes = SBYTES (string);
8595 nchars = string_byte_to_char (string, nbytes);
8597 /* This function takes care of single/multibyte conversion. We
8598 just have to ensure that the echo area buffer has the right
8599 setting of enable_multibyte_characters. */
8600 insert_from_string (string, 0, 0, nchars, nbytes, 1);
8602 else if (s)
8604 if (nbytes == 0)
8605 nbytes = strlen (s);
8607 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
8609 /* Convert from multi-byte to single-byte. */
8610 int i, c, n;
8611 unsigned char work[1];
8613 /* Convert a multibyte string to single-byte. */
8614 for (i = 0; i < nbytes; i += n)
8616 c = string_char_and_length (s + i, nbytes - i, &n);
8617 work[0] = (SINGLE_BYTE_CHAR_P (c)
8619 : multibyte_char_to_unibyte (c, Qnil));
8620 insert_1_both (work, 1, 1, 1, 0, 0);
8623 else if (!multibyte_p
8624 && !NILP (current_buffer->enable_multibyte_characters))
8626 /* Convert from single-byte to multi-byte. */
8627 int i, c, n;
8628 const unsigned char *msg = (const unsigned char *) s;
8629 unsigned char str[MAX_MULTIBYTE_LENGTH];
8631 /* Convert a single-byte string to multibyte. */
8632 for (i = 0; i < nbytes; i++)
8634 c = unibyte_char_to_multibyte (msg[i]);
8635 n = CHAR_STRING (c, str);
8636 insert_1_both (str, 1, n, 1, 0, 0);
8639 else
8640 insert_1 (s, nbytes, 1, 0, 0);
8643 return 0;
8647 /* Clear messages. CURRENT_P non-zero means clear the current
8648 message. LAST_DISPLAYED_P non-zero means clear the message
8649 last displayed. */
8651 void
8652 clear_message (current_p, last_displayed_p)
8653 int current_p, last_displayed_p;
8655 if (current_p)
8657 echo_area_buffer[0] = Qnil;
8658 message_cleared_p = 1;
8661 if (last_displayed_p)
8662 echo_area_buffer[1] = Qnil;
8664 message_buf_print = 0;
8667 /* Clear garbaged frames.
8669 This function is used where the old redisplay called
8670 redraw_garbaged_frames which in turn called redraw_frame which in
8671 turn called clear_frame. The call to clear_frame was a source of
8672 flickering. I believe a clear_frame is not necessary. It should
8673 suffice in the new redisplay to invalidate all current matrices,
8674 and ensure a complete redisplay of all windows. */
8676 static void
8677 clear_garbaged_frames ()
8679 if (frame_garbaged)
8681 Lisp_Object tail, frame;
8682 int changed_count = 0;
8684 FOR_EACH_FRAME (tail, frame)
8686 struct frame *f = XFRAME (frame);
8688 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
8690 if (f->resized_p)
8692 Fredraw_frame (frame);
8693 f->force_flush_display_p = 1;
8695 clear_current_matrices (f);
8696 changed_count++;
8697 f->garbaged = 0;
8698 f->resized_p = 0;
8702 frame_garbaged = 0;
8703 if (changed_count)
8704 ++windows_or_buffers_changed;
8709 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
8710 is non-zero update selected_frame. Value is non-zero if the
8711 mini-windows height has been changed. */
8713 static int
8714 echo_area_display (update_frame_p)
8715 int update_frame_p;
8717 Lisp_Object mini_window;
8718 struct window *w;
8719 struct frame *f;
8720 int window_height_changed_p = 0;
8721 struct frame *sf = SELECTED_FRAME ();
8723 mini_window = FRAME_MINIBUF_WINDOW (sf);
8724 w = XWINDOW (mini_window);
8725 f = XFRAME (WINDOW_FRAME (w));
8727 /* Don't display if frame is invisible or not yet initialized. */
8728 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
8729 return 0;
8731 /* The terminal frame is used as the first Emacs frame on the Mac OS. */
8732 #ifndef MAC_OS8
8733 #ifdef HAVE_WINDOW_SYSTEM
8734 /* When Emacs starts, selected_frame may be the initial terminal
8735 frame. If we let this through, a message would be displayed on
8736 the terminal. */
8737 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
8738 return 0;
8739 #endif /* HAVE_WINDOW_SYSTEM */
8740 #endif
8742 /* Redraw garbaged frames. */
8743 if (frame_garbaged)
8744 clear_garbaged_frames ();
8746 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
8748 echo_area_window = mini_window;
8749 window_height_changed_p = display_echo_area (w);
8750 w->must_be_updated_p = 1;
8752 /* Update the display, unless called from redisplay_internal.
8753 Also don't update the screen during redisplay itself. The
8754 update will happen at the end of redisplay, and an update
8755 here could cause confusion. */
8756 if (update_frame_p && !redisplaying_p)
8758 int n = 0;
8760 /* If the display update has been interrupted by pending
8761 input, update mode lines in the frame. Due to the
8762 pending input, it might have been that redisplay hasn't
8763 been called, so that mode lines above the echo area are
8764 garbaged. This looks odd, so we prevent it here. */
8765 if (!display_completed)
8766 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
8768 if (window_height_changed_p
8769 /* Don't do this if Emacs is shutting down. Redisplay
8770 needs to run hooks. */
8771 && !NILP (Vrun_hooks))
8773 /* Must update other windows. Likewise as in other
8774 cases, don't let this update be interrupted by
8775 pending input. */
8776 int count = SPECPDL_INDEX ();
8777 specbind (Qredisplay_dont_pause, Qt);
8778 windows_or_buffers_changed = 1;
8779 redisplay_internal (0);
8780 unbind_to (count, Qnil);
8782 else if (FRAME_WINDOW_P (f) && n == 0)
8784 /* Window configuration is the same as before.
8785 Can do with a display update of the echo area,
8786 unless we displayed some mode lines. */
8787 update_single_window (w, 1);
8788 FRAME_RIF (f)->flush_display (f);
8790 else
8791 update_frame (f, 1, 1);
8793 /* If cursor is in the echo area, make sure that the next
8794 redisplay displays the minibuffer, so that the cursor will
8795 be replaced with what the minibuffer wants. */
8796 if (cursor_in_echo_area)
8797 ++windows_or_buffers_changed;
8800 else if (!EQ (mini_window, selected_window))
8801 windows_or_buffers_changed++;
8803 /* Last displayed message is now the current message. */
8804 echo_area_buffer[1] = echo_area_buffer[0];
8805 /* Inform read_char that we're not echoing. */
8806 echo_message_buffer = Qnil;
8808 /* Prevent redisplay optimization in redisplay_internal by resetting
8809 this_line_start_pos. This is done because the mini-buffer now
8810 displays the message instead of its buffer text. */
8811 if (EQ (mini_window, selected_window))
8812 CHARPOS (this_line_start_pos) = 0;
8814 return window_height_changed_p;
8819 /***********************************************************************
8820 Mode Lines and Frame Titles
8821 ***********************************************************************/
8823 /* A buffer for constructing non-propertized mode-line strings and
8824 frame titles in it; allocated from the heap in init_xdisp and
8825 resized as needed in store_mode_line_noprop_char. */
8827 static char *mode_line_noprop_buf;
8829 /* The buffer's end, and a current output position in it. */
8831 static char *mode_line_noprop_buf_end;
8832 static char *mode_line_noprop_ptr;
8834 #define MODE_LINE_NOPROP_LEN(start) \
8835 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
8837 static enum {
8838 MODE_LINE_DISPLAY = 0,
8839 MODE_LINE_TITLE,
8840 MODE_LINE_NOPROP,
8841 MODE_LINE_STRING
8842 } mode_line_target;
8844 /* Alist that caches the results of :propertize.
8845 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
8846 static Lisp_Object mode_line_proptrans_alist;
8848 /* List of strings making up the mode-line. */
8849 static Lisp_Object mode_line_string_list;
8851 /* Base face property when building propertized mode line string. */
8852 static Lisp_Object mode_line_string_face;
8853 static Lisp_Object mode_line_string_face_prop;
8856 /* Unwind data for mode line strings */
8858 static Lisp_Object Vmode_line_unwind_vector;
8860 static Lisp_Object
8861 format_mode_line_unwind_data (obuf, save_proptrans)
8862 struct buffer *obuf;
8864 Lisp_Object vector;
8866 /* Reduce consing by keeping one vector in
8867 Vwith_echo_area_save_vector. */
8868 vector = Vmode_line_unwind_vector;
8869 Vmode_line_unwind_vector = Qnil;
8871 if (NILP (vector))
8872 vector = Fmake_vector (make_number (7), Qnil);
8874 AREF (vector, 0) = make_number (mode_line_target);
8875 AREF (vector, 1) = make_number (MODE_LINE_NOPROP_LEN (0));
8876 AREF (vector, 2) = mode_line_string_list;
8877 AREF (vector, 3) = (save_proptrans ? mode_line_proptrans_alist : Qt);
8878 AREF (vector, 4) = mode_line_string_face;
8879 AREF (vector, 5) = mode_line_string_face_prop;
8881 if (obuf)
8882 XSETBUFFER (AREF (vector, 6), obuf);
8883 else
8884 AREF (vector, 6) = Qnil;
8886 return vector;
8889 static Lisp_Object
8890 unwind_format_mode_line (vector)
8891 Lisp_Object vector;
8893 mode_line_target = XINT (AREF (vector, 0));
8894 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
8895 mode_line_string_list = AREF (vector, 2);
8896 if (! EQ (AREF (vector, 3), Qt))
8897 mode_line_proptrans_alist = AREF (vector, 3);
8898 mode_line_string_face = AREF (vector, 4);
8899 mode_line_string_face_prop = AREF (vector, 5);
8901 if (!NILP (AREF (vector, 6)))
8903 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
8904 AREF (vector, 6) = Qnil;
8907 Vmode_line_unwind_vector = vector;
8908 return Qnil;
8912 /* Store a single character C for the frame title in mode_line_noprop_buf.
8913 Re-allocate mode_line_noprop_buf if necessary. */
8915 static void
8916 #ifdef PROTOTYPES
8917 store_mode_line_noprop_char (char c)
8918 #else
8919 store_mode_line_noprop_char (c)
8920 char c;
8921 #endif
8923 /* If output position has reached the end of the allocated buffer,
8924 double the buffer's size. */
8925 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
8927 int len = MODE_LINE_NOPROP_LEN (0);
8928 int new_size = 2 * len * sizeof *mode_line_noprop_buf;
8929 mode_line_noprop_buf = (char *) xrealloc (mode_line_noprop_buf, new_size);
8930 mode_line_noprop_buf_end = mode_line_noprop_buf + new_size;
8931 mode_line_noprop_ptr = mode_line_noprop_buf + len;
8934 *mode_line_noprop_ptr++ = c;
8938 /* Store part of a frame title in mode_line_noprop_buf, beginning at
8939 mode_line_noprop_ptr. STR is the string to store. Do not copy
8940 characters that yield more columns than PRECISION; PRECISION <= 0
8941 means copy the whole string. Pad with spaces until FIELD_WIDTH
8942 number of characters have been copied; FIELD_WIDTH <= 0 means don't
8943 pad. Called from display_mode_element when it is used to build a
8944 frame title. */
8946 static int
8947 store_mode_line_noprop (str, field_width, precision)
8948 const unsigned char *str;
8949 int field_width, precision;
8951 int n = 0;
8952 int dummy, nbytes;
8954 /* Copy at most PRECISION chars from STR. */
8955 nbytes = strlen (str);
8956 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
8957 while (nbytes--)
8958 store_mode_line_noprop_char (*str++);
8960 /* Fill up with spaces until FIELD_WIDTH reached. */
8961 while (field_width > 0
8962 && n < field_width)
8964 store_mode_line_noprop_char (' ');
8965 ++n;
8968 return n;
8971 /***********************************************************************
8972 Frame Titles
8973 ***********************************************************************/
8975 #ifdef HAVE_WINDOW_SYSTEM
8977 /* Set the title of FRAME, if it has changed. The title format is
8978 Vicon_title_format if FRAME is iconified, otherwise it is
8979 frame_title_format. */
8981 static void
8982 x_consider_frame_title (frame)
8983 Lisp_Object frame;
8985 struct frame *f = XFRAME (frame);
8987 if (FRAME_WINDOW_P (f)
8988 || FRAME_MINIBUF_ONLY_P (f)
8989 || f->explicit_name)
8991 /* Do we have more than one visible frame on this X display? */
8992 Lisp_Object tail;
8993 Lisp_Object fmt;
8994 int title_start;
8995 char *title;
8996 int len;
8997 struct it it;
8998 int count = SPECPDL_INDEX ();
9000 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
9002 Lisp_Object other_frame = XCAR (tail);
9003 struct frame *tf = XFRAME (other_frame);
9005 if (tf != f
9006 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
9007 && !FRAME_MINIBUF_ONLY_P (tf)
9008 && !EQ (other_frame, tip_frame)
9009 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
9010 break;
9013 /* Set global variable indicating that multiple frames exist. */
9014 multiple_frames = CONSP (tail);
9016 /* Switch to the buffer of selected window of the frame. Set up
9017 mode_line_target so that display_mode_element will output into
9018 mode_line_noprop_buf; then display the title. */
9019 record_unwind_protect (unwind_format_mode_line,
9020 format_mode_line_unwind_data (current_buffer, 0));
9022 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
9023 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
9025 mode_line_target = MODE_LINE_TITLE;
9026 title_start = MODE_LINE_NOPROP_LEN (0);
9027 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
9028 NULL, DEFAULT_FACE_ID);
9029 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
9030 len = MODE_LINE_NOPROP_LEN (title_start);
9031 title = mode_line_noprop_buf + title_start;
9032 unbind_to (count, Qnil);
9034 /* Set the title only if it's changed. This avoids consing in
9035 the common case where it hasn't. (If it turns out that we've
9036 already wasted too much time by walking through the list with
9037 display_mode_element, then we might need to optimize at a
9038 higher level than this.) */
9039 if (! STRINGP (f->name)
9040 || SBYTES (f->name) != len
9041 || bcmp (title, SDATA (f->name), len) != 0)
9042 x_implicitly_set_name (f, make_string (title, len), Qnil);
9046 #endif /* not HAVE_WINDOW_SYSTEM */
9051 /***********************************************************************
9052 Menu Bars
9053 ***********************************************************************/
9056 /* Prepare for redisplay by updating menu-bar item lists when
9057 appropriate. This can call eval. */
9059 void
9060 prepare_menu_bars ()
9062 int all_windows;
9063 struct gcpro gcpro1, gcpro2;
9064 struct frame *f;
9065 Lisp_Object tooltip_frame;
9067 #ifdef HAVE_WINDOW_SYSTEM
9068 tooltip_frame = tip_frame;
9069 #else
9070 tooltip_frame = Qnil;
9071 #endif
9073 /* Update all frame titles based on their buffer names, etc. We do
9074 this before the menu bars so that the buffer-menu will show the
9075 up-to-date frame titles. */
9076 #ifdef HAVE_WINDOW_SYSTEM
9077 if (windows_or_buffers_changed || update_mode_lines)
9079 Lisp_Object tail, frame;
9081 FOR_EACH_FRAME (tail, frame)
9083 f = XFRAME (frame);
9084 if (!EQ (frame, tooltip_frame)
9085 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
9086 x_consider_frame_title (frame);
9089 #endif /* HAVE_WINDOW_SYSTEM */
9091 /* Update the menu bar item lists, if appropriate. This has to be
9092 done before any actual redisplay or generation of display lines. */
9093 all_windows = (update_mode_lines
9094 || buffer_shared > 1
9095 || windows_or_buffers_changed);
9096 if (all_windows)
9098 Lisp_Object tail, frame;
9099 int count = SPECPDL_INDEX ();
9100 /* 1 means that update_menu_bar has run its hooks
9101 so any further calls to update_menu_bar shouldn't do so again. */
9102 int menu_bar_hooks_run = 0;
9104 record_unwind_save_match_data ();
9106 FOR_EACH_FRAME (tail, frame)
9108 f = XFRAME (frame);
9110 /* Ignore tooltip frame. */
9111 if (EQ (frame, tooltip_frame))
9112 continue;
9114 /* If a window on this frame changed size, report that to
9115 the user and clear the size-change flag. */
9116 if (FRAME_WINDOW_SIZES_CHANGED (f))
9118 Lisp_Object functions;
9120 /* Clear flag first in case we get an error below. */
9121 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
9122 functions = Vwindow_size_change_functions;
9123 GCPRO2 (tail, functions);
9125 while (CONSP (functions))
9127 call1 (XCAR (functions), frame);
9128 functions = XCDR (functions);
9130 UNGCPRO;
9133 GCPRO1 (tail);
9134 menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
9135 #ifdef HAVE_WINDOW_SYSTEM
9136 update_tool_bar (f, 0);
9137 #ifdef MAC_OS
9138 mac_update_title_bar (f, 0);
9139 #endif
9140 #endif
9141 UNGCPRO;
9144 unbind_to (count, Qnil);
9146 else
9148 struct frame *sf = SELECTED_FRAME ();
9149 update_menu_bar (sf, 1, 0);
9150 #ifdef HAVE_WINDOW_SYSTEM
9151 update_tool_bar (sf, 1);
9152 #ifdef MAC_OS
9153 mac_update_title_bar (sf, 1);
9154 #endif
9155 #endif
9158 /* Motif needs this. See comment in xmenu.c. Turn it off when
9159 pending_menu_activation is not defined. */
9160 #ifdef USE_X_TOOLKIT
9161 pending_menu_activation = 0;
9162 #endif
9166 /* Update the menu bar item list for frame F. This has to be done
9167 before we start to fill in any display lines, because it can call
9168 eval.
9170 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
9172 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
9173 already ran the menu bar hooks for this redisplay, so there
9174 is no need to run them again. The return value is the
9175 updated value of this flag, to pass to the next call. */
9177 static int
9178 update_menu_bar (f, save_match_data, hooks_run)
9179 struct frame *f;
9180 int save_match_data;
9181 int hooks_run;
9183 Lisp_Object window;
9184 register struct window *w;
9186 /* If called recursively during a menu update, do nothing. This can
9187 happen when, for instance, an activate-menubar-hook causes a
9188 redisplay. */
9189 if (inhibit_menubar_update)
9190 return hooks_run;
9192 window = FRAME_SELECTED_WINDOW (f);
9193 w = XWINDOW (window);
9195 #if 0 /* The if statement below this if statement used to include the
9196 condition !NILP (w->update_mode_line), rather than using
9197 update_mode_lines directly, and this if statement may have
9198 been added to make that condition work. Now the if
9199 statement below matches its comment, this isn't needed. */
9200 if (update_mode_lines)
9201 w->update_mode_line = Qt;
9202 #endif
9204 if (FRAME_WINDOW_P (f)
9206 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
9207 || defined (USE_GTK)
9208 FRAME_EXTERNAL_MENU_BAR (f)
9209 #else
9210 FRAME_MENU_BAR_LINES (f) > 0
9211 #endif
9212 : FRAME_MENU_BAR_LINES (f) > 0)
9214 /* If the user has switched buffers or windows, we need to
9215 recompute to reflect the new bindings. But we'll
9216 recompute when update_mode_lines is set too; that means
9217 that people can use force-mode-line-update to request
9218 that the menu bar be recomputed. The adverse effect on
9219 the rest of the redisplay algorithm is about the same as
9220 windows_or_buffers_changed anyway. */
9221 if (windows_or_buffers_changed
9222 /* This used to test w->update_mode_line, but we believe
9223 there is no need to recompute the menu in that case. */
9224 || update_mode_lines
9225 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
9226 < BUF_MODIFF (XBUFFER (w->buffer)))
9227 != !NILP (w->last_had_star))
9228 || ((!NILP (Vtransient_mark_mode)
9229 && !NILP (XBUFFER (w->buffer)->mark_active))
9230 != !NILP (w->region_showing)))
9232 struct buffer *prev = current_buffer;
9233 int count = SPECPDL_INDEX ();
9235 specbind (Qinhibit_menubar_update, Qt);
9237 set_buffer_internal_1 (XBUFFER (w->buffer));
9238 if (save_match_data)
9239 record_unwind_save_match_data ();
9240 if (NILP (Voverriding_local_map_menu_flag))
9242 specbind (Qoverriding_terminal_local_map, Qnil);
9243 specbind (Qoverriding_local_map, Qnil);
9246 if (!hooks_run)
9248 /* Run the Lucid hook. */
9249 safe_run_hooks (Qactivate_menubar_hook);
9251 /* If it has changed current-menubar from previous value,
9252 really recompute the menu-bar from the value. */
9253 if (! NILP (Vlucid_menu_bar_dirty_flag))
9254 call0 (Qrecompute_lucid_menubar);
9256 safe_run_hooks (Qmenu_bar_update_hook);
9258 hooks_run = 1;
9261 XSETFRAME (Vmenu_updating_frame, f);
9262 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
9264 /* Redisplay the menu bar in case we changed it. */
9265 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
9266 || defined (USE_GTK)
9267 if (FRAME_WINDOW_P (f))
9269 #ifdef MAC_OS
9270 /* All frames on Mac OS share the same menubar. So only
9271 the selected frame should be allowed to set it. */
9272 if (f == SELECTED_FRAME ())
9273 #endif
9274 set_frame_menubar (f, 0, 0);
9276 else
9277 /* On a terminal screen, the menu bar is an ordinary screen
9278 line, and this makes it get updated. */
9279 w->update_mode_line = Qt;
9280 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
9281 /* In the non-toolkit version, the menu bar is an ordinary screen
9282 line, and this makes it get updated. */
9283 w->update_mode_line = Qt;
9284 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
9286 unbind_to (count, Qnil);
9287 set_buffer_internal_1 (prev);
9291 return hooks_run;
9296 /***********************************************************************
9297 Output Cursor
9298 ***********************************************************************/
9300 #ifdef HAVE_WINDOW_SYSTEM
9302 /* EXPORT:
9303 Nominal cursor position -- where to draw output.
9304 HPOS and VPOS are window relative glyph matrix coordinates.
9305 X and Y are window relative pixel coordinates. */
9307 struct cursor_pos output_cursor;
9310 /* EXPORT:
9311 Set the global variable output_cursor to CURSOR. All cursor
9312 positions are relative to updated_window. */
9314 void
9315 set_output_cursor (cursor)
9316 struct cursor_pos *cursor;
9318 output_cursor.hpos = cursor->hpos;
9319 output_cursor.vpos = cursor->vpos;
9320 output_cursor.x = cursor->x;
9321 output_cursor.y = cursor->y;
9325 /* EXPORT for RIF:
9326 Set a nominal cursor position.
9328 HPOS and VPOS are column/row positions in a window glyph matrix. X
9329 and Y are window text area relative pixel positions.
9331 If this is done during an update, updated_window will contain the
9332 window that is being updated and the position is the future output
9333 cursor position for that window. If updated_window is null, use
9334 selected_window and display the cursor at the given position. */
9336 void
9337 x_cursor_to (vpos, hpos, y, x)
9338 int vpos, hpos, y, x;
9340 struct window *w;
9342 /* If updated_window is not set, work on selected_window. */
9343 if (updated_window)
9344 w = updated_window;
9345 else
9346 w = XWINDOW (selected_window);
9348 /* Set the output cursor. */
9349 output_cursor.hpos = hpos;
9350 output_cursor.vpos = vpos;
9351 output_cursor.x = x;
9352 output_cursor.y = y;
9354 /* If not called as part of an update, really display the cursor.
9355 This will also set the cursor position of W. */
9356 if (updated_window == NULL)
9358 BLOCK_INPUT;
9359 display_and_set_cursor (w, 1, hpos, vpos, x, y);
9360 if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
9361 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
9362 UNBLOCK_INPUT;
9366 #endif /* HAVE_WINDOW_SYSTEM */
9369 /***********************************************************************
9370 Tool-bars
9371 ***********************************************************************/
9373 #ifdef HAVE_WINDOW_SYSTEM
9375 /* Where the mouse was last time we reported a mouse event. */
9377 FRAME_PTR last_mouse_frame;
9379 /* Tool-bar item index of the item on which a mouse button was pressed
9380 or -1. */
9382 int last_tool_bar_item;
9385 /* Update the tool-bar item list for frame F. This has to be done
9386 before we start to fill in any display lines. Called from
9387 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
9388 and restore it here. */
9390 static void
9391 update_tool_bar (f, save_match_data)
9392 struct frame *f;
9393 int save_match_data;
9395 #if defined (USE_GTK) || USE_MAC_TOOLBAR
9396 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
9397 #else
9398 int do_update = WINDOWP (f->tool_bar_window)
9399 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
9400 #endif
9402 if (do_update)
9404 Lisp_Object window;
9405 struct window *w;
9407 window = FRAME_SELECTED_WINDOW (f);
9408 w = XWINDOW (window);
9410 /* If the user has switched buffers or windows, we need to
9411 recompute to reflect the new bindings. But we'll
9412 recompute when update_mode_lines is set too; that means
9413 that people can use force-mode-line-update to request
9414 that the menu bar be recomputed. The adverse effect on
9415 the rest of the redisplay algorithm is about the same as
9416 windows_or_buffers_changed anyway. */
9417 if (windows_or_buffers_changed
9418 || !NILP (w->update_mode_line)
9419 || update_mode_lines
9420 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
9421 < BUF_MODIFF (XBUFFER (w->buffer)))
9422 != !NILP (w->last_had_star))
9423 || ((!NILP (Vtransient_mark_mode)
9424 && !NILP (XBUFFER (w->buffer)->mark_active))
9425 != !NILP (w->region_showing)))
9427 struct buffer *prev = current_buffer;
9428 int count = SPECPDL_INDEX ();
9429 Lisp_Object new_tool_bar;
9430 int new_n_tool_bar;
9431 struct gcpro gcpro1;
9433 /* Set current_buffer to the buffer of the selected
9434 window of the frame, so that we get the right local
9435 keymaps. */
9436 set_buffer_internal_1 (XBUFFER (w->buffer));
9438 /* Save match data, if we must. */
9439 if (save_match_data)
9440 record_unwind_save_match_data ();
9442 /* Make sure that we don't accidentally use bogus keymaps. */
9443 if (NILP (Voverriding_local_map_menu_flag))
9445 specbind (Qoverriding_terminal_local_map, Qnil);
9446 specbind (Qoverriding_local_map, Qnil);
9449 GCPRO1 (new_tool_bar);
9451 /* Build desired tool-bar items from keymaps. */
9452 new_tool_bar = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
9453 &new_n_tool_bar);
9455 /* Redisplay the tool-bar if we changed it. */
9456 if (new_n_tool_bar != f->n_tool_bar_items
9457 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
9459 /* Redisplay that happens asynchronously due to an expose event
9460 may access f->tool_bar_items. Make sure we update both
9461 variables within BLOCK_INPUT so no such event interrupts. */
9462 BLOCK_INPUT;
9463 f->tool_bar_items = new_tool_bar;
9464 f->n_tool_bar_items = new_n_tool_bar;
9465 w->update_mode_line = Qt;
9466 UNBLOCK_INPUT;
9469 UNGCPRO;
9471 unbind_to (count, Qnil);
9472 set_buffer_internal_1 (prev);
9478 /* Set F->desired_tool_bar_string to a Lisp string representing frame
9479 F's desired tool-bar contents. F->tool_bar_items must have
9480 been set up previously by calling prepare_menu_bars. */
9482 static void
9483 build_desired_tool_bar_string (f)
9484 struct frame *f;
9486 int i, size, size_needed;
9487 struct gcpro gcpro1, gcpro2, gcpro3;
9488 Lisp_Object image, plist, props;
9490 image = plist = props = Qnil;
9491 GCPRO3 (image, plist, props);
9493 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
9494 Otherwise, make a new string. */
9496 /* The size of the string we might be able to reuse. */
9497 size = (STRINGP (f->desired_tool_bar_string)
9498 ? SCHARS (f->desired_tool_bar_string)
9499 : 0);
9501 /* We need one space in the string for each image. */
9502 size_needed = f->n_tool_bar_items;
9504 /* Reuse f->desired_tool_bar_string, if possible. */
9505 if (size < size_needed || NILP (f->desired_tool_bar_string))
9506 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
9507 make_number (' '));
9508 else
9510 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
9511 Fremove_text_properties (make_number (0), make_number (size),
9512 props, f->desired_tool_bar_string);
9515 /* Put a `display' property on the string for the images to display,
9516 put a `menu_item' property on tool-bar items with a value that
9517 is the index of the item in F's tool-bar item vector. */
9518 for (i = 0; i < f->n_tool_bar_items; ++i)
9520 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
9522 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
9523 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
9524 int hmargin, vmargin, relief, idx, end;
9525 extern Lisp_Object QCrelief, QCmargin, QCconversion;
9527 /* If image is a vector, choose the image according to the
9528 button state. */
9529 image = PROP (TOOL_BAR_ITEM_IMAGES);
9530 if (VECTORP (image))
9532 if (enabled_p)
9533 idx = (selected_p
9534 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
9535 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
9536 else
9537 idx = (selected_p
9538 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
9539 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
9541 xassert (ASIZE (image) >= idx);
9542 image = AREF (image, idx);
9544 else
9545 idx = -1;
9547 /* Ignore invalid image specifications. */
9548 if (!valid_image_p (image))
9549 continue;
9551 /* Display the tool-bar button pressed, or depressed. */
9552 plist = Fcopy_sequence (XCDR (image));
9554 /* Compute margin and relief to draw. */
9555 relief = (tool_bar_button_relief >= 0
9556 ? tool_bar_button_relief
9557 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
9558 hmargin = vmargin = relief;
9560 if (INTEGERP (Vtool_bar_button_margin)
9561 && XINT (Vtool_bar_button_margin) > 0)
9563 hmargin += XFASTINT (Vtool_bar_button_margin);
9564 vmargin += XFASTINT (Vtool_bar_button_margin);
9566 else if (CONSP (Vtool_bar_button_margin))
9568 if (INTEGERP (XCAR (Vtool_bar_button_margin))
9569 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
9570 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
9572 if (INTEGERP (XCDR (Vtool_bar_button_margin))
9573 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
9574 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
9577 if (auto_raise_tool_bar_buttons_p)
9579 /* Add a `:relief' property to the image spec if the item is
9580 selected. */
9581 if (selected_p)
9583 plist = Fplist_put (plist, QCrelief, make_number (-relief));
9584 hmargin -= relief;
9585 vmargin -= relief;
9588 else
9590 /* If image is selected, display it pressed, i.e. with a
9591 negative relief. If it's not selected, display it with a
9592 raised relief. */
9593 plist = Fplist_put (plist, QCrelief,
9594 (selected_p
9595 ? make_number (-relief)
9596 : make_number (relief)));
9597 hmargin -= relief;
9598 vmargin -= relief;
9601 /* Put a margin around the image. */
9602 if (hmargin || vmargin)
9604 if (hmargin == vmargin)
9605 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
9606 else
9607 plist = Fplist_put (plist, QCmargin,
9608 Fcons (make_number (hmargin),
9609 make_number (vmargin)));
9612 /* If button is not enabled, and we don't have special images
9613 for the disabled state, make the image appear disabled by
9614 applying an appropriate algorithm to it. */
9615 if (!enabled_p && idx < 0)
9616 plist = Fplist_put (plist, QCconversion, Qdisabled);
9618 /* Put a `display' text property on the string for the image to
9619 display. Put a `menu-item' property on the string that gives
9620 the start of this item's properties in the tool-bar items
9621 vector. */
9622 image = Fcons (Qimage, plist);
9623 props = list4 (Qdisplay, image,
9624 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
9626 /* Let the last image hide all remaining spaces in the tool bar
9627 string. The string can be longer than needed when we reuse a
9628 previous string. */
9629 if (i + 1 == f->n_tool_bar_items)
9630 end = SCHARS (f->desired_tool_bar_string);
9631 else
9632 end = i + 1;
9633 Fadd_text_properties (make_number (i), make_number (end),
9634 props, f->desired_tool_bar_string);
9635 #undef PROP
9638 UNGCPRO;
9642 /* Display one line of the tool-bar of frame IT->f.
9644 HEIGHT specifies the desired height of the tool-bar line.
9645 If the actual height of the glyph row is less than HEIGHT, the
9646 row's height is increased to HEIGHT, and the icons are centered
9647 vertically in the new height.
9649 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
9650 count a final empty row in case the tool-bar width exactly matches
9651 the window width.
9654 static void
9655 display_tool_bar_line (it, height)
9656 struct it *it;
9657 int height;
9659 struct glyph_row *row = it->glyph_row;
9660 int max_x = it->last_visible_x;
9661 struct glyph *last;
9663 prepare_desired_row (row);
9664 row->y = it->current_y;
9666 /* Note that this isn't made use of if the face hasn't a box,
9667 so there's no need to check the face here. */
9668 it->start_of_box_run_p = 1;
9670 while (it->current_x < max_x)
9672 int x, n_glyphs_before, i, nglyphs;
9673 struct it it_before;
9675 /* Get the next display element. */
9676 if (!get_next_display_element (it))
9678 /* Don't count empty row if we are counting needed tool-bar lines. */
9679 if (height < 0 && !it->hpos)
9680 return;
9681 break;
9684 /* Produce glyphs. */
9685 n_glyphs_before = row->used[TEXT_AREA];
9686 it_before = *it;
9688 PRODUCE_GLYPHS (it);
9690 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
9691 i = 0;
9692 x = it_before.current_x;
9693 while (i < nglyphs)
9695 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
9697 if (x + glyph->pixel_width > max_x)
9699 /* Glyph doesn't fit on line. Backtrack. */
9700 row->used[TEXT_AREA] = n_glyphs_before;
9701 *it = it_before;
9702 /* If this is the only glyph on this line, it will never fit on the
9703 toolbar, so skip it. But ensure there is at least one glyph,
9704 so we don't accidentally disable the tool-bar. */
9705 if (n_glyphs_before == 0
9706 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
9707 break;
9708 goto out;
9711 ++it->hpos;
9712 x += glyph->pixel_width;
9713 ++i;
9716 /* Stop at line ends. */
9717 if (ITERATOR_AT_END_OF_LINE_P (it))
9718 break;
9720 set_iterator_to_next (it, 1);
9723 out:;
9725 row->displays_text_p = row->used[TEXT_AREA] != 0;
9727 /* Use default face for the border below the tool bar.
9729 FIXME: When auto-resize-tool-bars is grow-only, there is
9730 no additional border below the possibly empty tool-bar lines.
9731 So to make the extra empty lines look "normal", we have to
9732 use the tool-bar face for the border too. */
9733 if (!row->displays_text_p && !EQ (Vauto_resize_tool_bars, Qgrow_only))
9734 it->face_id = DEFAULT_FACE_ID;
9736 extend_face_to_end_of_line (it);
9737 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
9738 last->right_box_line_p = 1;
9739 if (last == row->glyphs[TEXT_AREA])
9740 last->left_box_line_p = 1;
9742 /* Make line the desired height and center it vertically. */
9743 if ((height -= it->max_ascent + it->max_descent) > 0)
9745 /* Don't add more than one line height. */
9746 height %= FRAME_LINE_HEIGHT (it->f);
9747 it->max_ascent += height / 2;
9748 it->max_descent += (height + 1) / 2;
9751 compute_line_metrics (it);
9753 /* If line is empty, make it occupy the rest of the tool-bar. */
9754 if (!row->displays_text_p)
9756 row->height = row->phys_height = it->last_visible_y - row->y;
9757 row->visible_height = row->height;
9758 row->ascent = row->phys_ascent = 0;
9759 row->extra_line_spacing = 0;
9762 row->full_width_p = 1;
9763 row->continued_p = 0;
9764 row->truncated_on_left_p = 0;
9765 row->truncated_on_right_p = 0;
9767 it->current_x = it->hpos = 0;
9768 it->current_y += row->height;
9769 ++it->vpos;
9770 ++it->glyph_row;
9774 /* Max tool-bar height. */
9776 #define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
9777 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
9779 /* Value is the number of screen lines needed to make all tool-bar
9780 items of frame F visible. The number of actual rows needed is
9781 returned in *N_ROWS if non-NULL. */
9783 static int
9784 tool_bar_lines_needed (f, n_rows)
9785 struct frame *f;
9786 int *n_rows;
9788 struct window *w = XWINDOW (f->tool_bar_window);
9789 struct it it;
9790 /* tool_bar_lines_needed is called from redisplay_tool_bar after building
9791 the desired matrix, so use (unused) mode-line row as temporary row to
9792 avoid destroying the first tool-bar row. */
9793 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
9795 /* Initialize an iterator for iteration over
9796 F->desired_tool_bar_string in the tool-bar window of frame F. */
9797 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
9798 it.first_visible_x = 0;
9799 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
9800 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
9802 while (!ITERATOR_AT_END_P (&it))
9804 clear_glyph_row (temp_row);
9805 it.glyph_row = temp_row;
9806 display_tool_bar_line (&it, -1);
9808 clear_glyph_row (temp_row);
9810 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
9811 if (n_rows)
9812 *n_rows = it.vpos > 0 ? it.vpos : -1;
9814 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
9818 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
9819 0, 1, 0,
9820 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
9821 (frame)
9822 Lisp_Object frame;
9824 struct frame *f;
9825 struct window *w;
9826 int nlines = 0;
9828 if (NILP (frame))
9829 frame = selected_frame;
9830 else
9831 CHECK_FRAME (frame);
9832 f = XFRAME (frame);
9834 if (WINDOWP (f->tool_bar_window)
9835 || (w = XWINDOW (f->tool_bar_window),
9836 WINDOW_TOTAL_LINES (w) > 0))
9838 update_tool_bar (f, 1);
9839 if (f->n_tool_bar_items)
9841 build_desired_tool_bar_string (f);
9842 nlines = tool_bar_lines_needed (f, NULL);
9846 return make_number (nlines);
9850 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
9851 height should be changed. */
9853 static int
9854 redisplay_tool_bar (f)
9855 struct frame *f;
9857 struct window *w;
9858 struct it it;
9859 struct glyph_row *row;
9861 #if defined (USE_GTK) || USE_MAC_TOOLBAR
9862 if (FRAME_EXTERNAL_TOOL_BAR (f))
9863 update_frame_tool_bar (f);
9864 return 0;
9865 #endif
9867 /* If frame hasn't a tool-bar window or if it is zero-height, don't
9868 do anything. This means you must start with tool-bar-lines
9869 non-zero to get the auto-sizing effect. Or in other words, you
9870 can turn off tool-bars by specifying tool-bar-lines zero. */
9871 if (!WINDOWP (f->tool_bar_window)
9872 || (w = XWINDOW (f->tool_bar_window),
9873 WINDOW_TOTAL_LINES (w) == 0))
9874 return 0;
9876 /* Set up an iterator for the tool-bar window. */
9877 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
9878 it.first_visible_x = 0;
9879 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
9880 row = it.glyph_row;
9882 /* Build a string that represents the contents of the tool-bar. */
9883 build_desired_tool_bar_string (f);
9884 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
9886 if (f->n_tool_bar_rows == 0)
9888 int nlines;
9890 if ((nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
9891 nlines != WINDOW_TOTAL_LINES (w)))
9893 extern Lisp_Object Qtool_bar_lines;
9894 Lisp_Object frame;
9895 int old_height = WINDOW_TOTAL_LINES (w);
9897 XSETFRAME (frame, f);
9898 Fmodify_frame_parameters (frame,
9899 Fcons (Fcons (Qtool_bar_lines,
9900 make_number (nlines)),
9901 Qnil));
9902 if (WINDOW_TOTAL_LINES (w) != old_height)
9904 clear_glyph_matrix (w->desired_matrix);
9905 fonts_changed_p = 1;
9906 return 1;
9911 /* Display as many lines as needed to display all tool-bar items. */
9913 if (f->n_tool_bar_rows > 0)
9915 int border, rows, height, extra;
9917 if (INTEGERP (Vtool_bar_border))
9918 border = XINT (Vtool_bar_border);
9919 else if (EQ (Vtool_bar_border, Qinternal_border_width))
9920 border = FRAME_INTERNAL_BORDER_WIDTH (f);
9921 else if (EQ (Vtool_bar_border, Qborder_width))
9922 border = f->border_width;
9923 else
9924 border = 0;
9925 if (border < 0)
9926 border = 0;
9928 rows = f->n_tool_bar_rows;
9929 height = max (1, (it.last_visible_y - border) / rows);
9930 extra = it.last_visible_y - border - height * rows;
9932 while (it.current_y < it.last_visible_y)
9934 int h = 0;
9935 if (extra > 0 && rows-- > 0)
9937 h = (extra + rows - 1) / rows;
9938 extra -= h;
9940 display_tool_bar_line (&it, height + h);
9943 else
9945 while (it.current_y < it.last_visible_y)
9946 display_tool_bar_line (&it, 0);
9949 /* It doesn't make much sense to try scrolling in the tool-bar
9950 window, so don't do it. */
9951 w->desired_matrix->no_scrolling_p = 1;
9952 w->must_be_updated_p = 1;
9954 if (!NILP (Vauto_resize_tool_bars))
9956 int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
9957 int change_height_p = 0;
9959 /* If we couldn't display everything, change the tool-bar's
9960 height if there is room for more. */
9961 if (IT_STRING_CHARPOS (it) < it.end_charpos
9962 && it.current_y < max_tool_bar_height)
9963 change_height_p = 1;
9965 row = it.glyph_row - 1;
9967 /* If there are blank lines at the end, except for a partially
9968 visible blank line at the end that is smaller than
9969 FRAME_LINE_HEIGHT, change the tool-bar's height. */
9970 if (!row->displays_text_p
9971 && row->height >= FRAME_LINE_HEIGHT (f))
9972 change_height_p = 1;
9974 /* If row displays tool-bar items, but is partially visible,
9975 change the tool-bar's height. */
9976 if (row->displays_text_p
9977 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y
9978 && MATRIX_ROW_BOTTOM_Y (row) < max_tool_bar_height)
9979 change_height_p = 1;
9981 /* Resize windows as needed by changing the `tool-bar-lines'
9982 frame parameter. */
9983 if (change_height_p)
9985 extern Lisp_Object Qtool_bar_lines;
9986 Lisp_Object frame;
9987 int old_height = WINDOW_TOTAL_LINES (w);
9988 int nrows;
9989 int nlines = tool_bar_lines_needed (f, &nrows);
9991 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
9992 && !f->minimize_tool_bar_window_p)
9993 ? (nlines > old_height)
9994 : (nlines != old_height));
9995 f->minimize_tool_bar_window_p = 0;
9997 if (change_height_p)
9999 XSETFRAME (frame, f);
10000 Fmodify_frame_parameters (frame,
10001 Fcons (Fcons (Qtool_bar_lines,
10002 make_number (nlines)),
10003 Qnil));
10004 if (WINDOW_TOTAL_LINES (w) != old_height)
10006 clear_glyph_matrix (w->desired_matrix);
10007 f->n_tool_bar_rows = nrows;
10008 fonts_changed_p = 1;
10009 return 1;
10015 f->minimize_tool_bar_window_p = 0;
10016 return 0;
10020 /* Get information about the tool-bar item which is displayed in GLYPH
10021 on frame F. Return in *PROP_IDX the index where tool-bar item
10022 properties start in F->tool_bar_items. Value is zero if
10023 GLYPH doesn't display a tool-bar item. */
10025 static int
10026 tool_bar_item_info (f, glyph, prop_idx)
10027 struct frame *f;
10028 struct glyph *glyph;
10029 int *prop_idx;
10031 Lisp_Object prop;
10032 int success_p;
10033 int charpos;
10035 /* This function can be called asynchronously, which means we must
10036 exclude any possibility that Fget_text_property signals an
10037 error. */
10038 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
10039 charpos = max (0, charpos);
10041 /* Get the text property `menu-item' at pos. The value of that
10042 property is the start index of this item's properties in
10043 F->tool_bar_items. */
10044 prop = Fget_text_property (make_number (charpos),
10045 Qmenu_item, f->current_tool_bar_string);
10046 if (INTEGERP (prop))
10048 *prop_idx = XINT (prop);
10049 success_p = 1;
10051 else
10052 success_p = 0;
10054 return success_p;
10058 /* Get information about the tool-bar item at position X/Y on frame F.
10059 Return in *GLYPH a pointer to the glyph of the tool-bar item in
10060 the current matrix of the tool-bar window of F, or NULL if not
10061 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
10062 item in F->tool_bar_items. Value is
10064 -1 if X/Y is not on a tool-bar item
10065 0 if X/Y is on the same item that was highlighted before.
10066 1 otherwise. */
10068 static int
10069 get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
10070 struct frame *f;
10071 int x, y;
10072 struct glyph **glyph;
10073 int *hpos, *vpos, *prop_idx;
10075 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10076 struct window *w = XWINDOW (f->tool_bar_window);
10077 int area;
10079 /* Find the glyph under X/Y. */
10080 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
10081 if (*glyph == NULL)
10082 return -1;
10084 /* Get the start of this tool-bar item's properties in
10085 f->tool_bar_items. */
10086 if (!tool_bar_item_info (f, *glyph, prop_idx))
10087 return -1;
10089 /* Is mouse on the highlighted item? */
10090 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
10091 && *vpos >= dpyinfo->mouse_face_beg_row
10092 && *vpos <= dpyinfo->mouse_face_end_row
10093 && (*vpos > dpyinfo->mouse_face_beg_row
10094 || *hpos >= dpyinfo->mouse_face_beg_col)
10095 && (*vpos < dpyinfo->mouse_face_end_row
10096 || *hpos < dpyinfo->mouse_face_end_col
10097 || dpyinfo->mouse_face_past_end))
10098 return 0;
10100 return 1;
10104 /* EXPORT:
10105 Handle mouse button event on the tool-bar of frame F, at
10106 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
10107 0 for button release. MODIFIERS is event modifiers for button
10108 release. */
10110 void
10111 handle_tool_bar_click (f, x, y, down_p, modifiers)
10112 struct frame *f;
10113 int x, y, down_p;
10114 unsigned int modifiers;
10116 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10117 struct window *w = XWINDOW (f->tool_bar_window);
10118 int hpos, vpos, prop_idx;
10119 struct glyph *glyph;
10120 Lisp_Object enabled_p;
10122 /* If not on the highlighted tool-bar item, return. */
10123 frame_to_window_pixel_xy (w, &x, &y);
10124 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
10125 return;
10127 /* If item is disabled, do nothing. */
10128 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
10129 if (NILP (enabled_p))
10130 return;
10132 if (down_p)
10134 /* Show item in pressed state. */
10135 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
10136 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
10137 last_tool_bar_item = prop_idx;
10139 else
10141 Lisp_Object key, frame;
10142 struct input_event event;
10143 EVENT_INIT (event);
10145 /* Show item in released state. */
10146 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
10147 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
10149 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
10151 XSETFRAME (frame, f);
10152 event.kind = TOOL_BAR_EVENT;
10153 event.frame_or_window = frame;
10154 event.arg = frame;
10155 kbd_buffer_store_event (&event);
10157 event.kind = TOOL_BAR_EVENT;
10158 event.frame_or_window = frame;
10159 event.arg = key;
10160 event.modifiers = modifiers;
10161 kbd_buffer_store_event (&event);
10162 last_tool_bar_item = -1;
10167 /* Possibly highlight a tool-bar item on frame F when mouse moves to
10168 tool-bar window-relative coordinates X/Y. Called from
10169 note_mouse_highlight. */
10171 static void
10172 note_tool_bar_highlight (f, x, y)
10173 struct frame *f;
10174 int x, y;
10176 Lisp_Object window = f->tool_bar_window;
10177 struct window *w = XWINDOW (window);
10178 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10179 int hpos, vpos;
10180 struct glyph *glyph;
10181 struct glyph_row *row;
10182 int i;
10183 Lisp_Object enabled_p;
10184 int prop_idx;
10185 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
10186 int mouse_down_p, rc;
10188 /* Function note_mouse_highlight is called with negative x(y
10189 values when mouse moves outside of the frame. */
10190 if (x <= 0 || y <= 0)
10192 clear_mouse_face (dpyinfo);
10193 return;
10196 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
10197 if (rc < 0)
10199 /* Not on tool-bar item. */
10200 clear_mouse_face (dpyinfo);
10201 return;
10203 else if (rc == 0)
10204 /* On same tool-bar item as before. */
10205 goto set_help_echo;
10207 clear_mouse_face (dpyinfo);
10209 /* Mouse is down, but on different tool-bar item? */
10210 mouse_down_p = (dpyinfo->grabbed
10211 && f == last_mouse_frame
10212 && FRAME_LIVE_P (f));
10213 if (mouse_down_p
10214 && last_tool_bar_item != prop_idx)
10215 return;
10217 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
10218 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
10220 /* If tool-bar item is not enabled, don't highlight it. */
10221 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
10222 if (!NILP (enabled_p))
10224 /* Compute the x-position of the glyph. In front and past the
10225 image is a space. We include this in the highlighted area. */
10226 row = MATRIX_ROW (w->current_matrix, vpos);
10227 for (i = x = 0; i < hpos; ++i)
10228 x += row->glyphs[TEXT_AREA][i].pixel_width;
10230 /* Record this as the current active region. */
10231 dpyinfo->mouse_face_beg_col = hpos;
10232 dpyinfo->mouse_face_beg_row = vpos;
10233 dpyinfo->mouse_face_beg_x = x;
10234 dpyinfo->mouse_face_beg_y = row->y;
10235 dpyinfo->mouse_face_past_end = 0;
10237 dpyinfo->mouse_face_end_col = hpos + 1;
10238 dpyinfo->mouse_face_end_row = vpos;
10239 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
10240 dpyinfo->mouse_face_end_y = row->y;
10241 dpyinfo->mouse_face_window = window;
10242 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
10244 /* Display it as active. */
10245 show_mouse_face (dpyinfo, draw);
10246 dpyinfo->mouse_face_image_state = draw;
10249 set_help_echo:
10251 /* Set help_echo_string to a help string to display for this tool-bar item.
10252 XTread_socket does the rest. */
10253 help_echo_object = help_echo_window = Qnil;
10254 help_echo_pos = -1;
10255 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
10256 if (NILP (help_echo_string))
10257 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
10260 #endif /* HAVE_WINDOW_SYSTEM */
10264 /************************************************************************
10265 Horizontal scrolling
10266 ************************************************************************/
10268 static int hscroll_window_tree P_ ((Lisp_Object));
10269 static int hscroll_windows P_ ((Lisp_Object));
10271 /* For all leaf windows in the window tree rooted at WINDOW, set their
10272 hscroll value so that PT is (i) visible in the window, and (ii) so
10273 that it is not within a certain margin at the window's left and
10274 right border. Value is non-zero if any window's hscroll has been
10275 changed. */
10277 static int
10278 hscroll_window_tree (window)
10279 Lisp_Object window;
10281 int hscrolled_p = 0;
10282 int hscroll_relative_p = FLOATP (Vhscroll_step);
10283 int hscroll_step_abs = 0;
10284 double hscroll_step_rel = 0;
10286 if (hscroll_relative_p)
10288 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
10289 if (hscroll_step_rel < 0)
10291 hscroll_relative_p = 0;
10292 hscroll_step_abs = 0;
10295 else if (INTEGERP (Vhscroll_step))
10297 hscroll_step_abs = XINT (Vhscroll_step);
10298 if (hscroll_step_abs < 0)
10299 hscroll_step_abs = 0;
10301 else
10302 hscroll_step_abs = 0;
10304 while (WINDOWP (window))
10306 struct window *w = XWINDOW (window);
10308 if (WINDOWP (w->hchild))
10309 hscrolled_p |= hscroll_window_tree (w->hchild);
10310 else if (WINDOWP (w->vchild))
10311 hscrolled_p |= hscroll_window_tree (w->vchild);
10312 else if (w->cursor.vpos >= 0)
10314 int h_margin;
10315 int text_area_width;
10316 struct glyph_row *current_cursor_row
10317 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
10318 struct glyph_row *desired_cursor_row
10319 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
10320 struct glyph_row *cursor_row
10321 = (desired_cursor_row->enabled_p
10322 ? desired_cursor_row
10323 : current_cursor_row);
10325 text_area_width = window_box_width (w, TEXT_AREA);
10327 /* Scroll when cursor is inside this scroll margin. */
10328 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
10330 if ((XFASTINT (w->hscroll)
10331 && w->cursor.x <= h_margin)
10332 || (cursor_row->enabled_p
10333 && cursor_row->truncated_on_right_p
10334 && (w->cursor.x >= text_area_width - h_margin)))
10336 struct it it;
10337 int hscroll;
10338 struct buffer *saved_current_buffer;
10339 int pt;
10340 int wanted_x;
10342 /* Find point in a display of infinite width. */
10343 saved_current_buffer = current_buffer;
10344 current_buffer = XBUFFER (w->buffer);
10346 if (w == XWINDOW (selected_window))
10347 pt = BUF_PT (current_buffer);
10348 else
10350 pt = marker_position (w->pointm);
10351 pt = max (BEGV, pt);
10352 pt = min (ZV, pt);
10355 /* Move iterator to pt starting at cursor_row->start in
10356 a line with infinite width. */
10357 init_to_row_start (&it, w, cursor_row);
10358 it.last_visible_x = INFINITY;
10359 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
10360 current_buffer = saved_current_buffer;
10362 /* Position cursor in window. */
10363 if (!hscroll_relative_p && hscroll_step_abs == 0)
10364 hscroll = max (0, (it.current_x
10365 - (ITERATOR_AT_END_OF_LINE_P (&it)
10366 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
10367 : (text_area_width / 2))))
10368 / FRAME_COLUMN_WIDTH (it.f);
10369 else if (w->cursor.x >= text_area_width - h_margin)
10371 if (hscroll_relative_p)
10372 wanted_x = text_area_width * (1 - hscroll_step_rel)
10373 - h_margin;
10374 else
10375 wanted_x = text_area_width
10376 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
10377 - h_margin;
10378 hscroll
10379 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
10381 else
10383 if (hscroll_relative_p)
10384 wanted_x = text_area_width * hscroll_step_rel
10385 + h_margin;
10386 else
10387 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
10388 + h_margin;
10389 hscroll
10390 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
10392 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
10394 /* Don't call Fset_window_hscroll if value hasn't
10395 changed because it will prevent redisplay
10396 optimizations. */
10397 if (XFASTINT (w->hscroll) != hscroll)
10399 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
10400 w->hscroll = make_number (hscroll);
10401 hscrolled_p = 1;
10406 window = w->next;
10409 /* Value is non-zero if hscroll of any leaf window has been changed. */
10410 return hscrolled_p;
10414 /* Set hscroll so that cursor is visible and not inside horizontal
10415 scroll margins for all windows in the tree rooted at WINDOW. See
10416 also hscroll_window_tree above. Value is non-zero if any window's
10417 hscroll has been changed. If it has, desired matrices on the frame
10418 of WINDOW are cleared. */
10420 static int
10421 hscroll_windows (window)
10422 Lisp_Object window;
10424 int hscrolled_p;
10426 if (automatic_hscrolling_p)
10428 hscrolled_p = hscroll_window_tree (window);
10429 if (hscrolled_p)
10430 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
10432 else
10433 hscrolled_p = 0;
10434 return hscrolled_p;
10439 /************************************************************************
10440 Redisplay
10441 ************************************************************************/
10443 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
10444 to a non-zero value. This is sometimes handy to have in a debugger
10445 session. */
10447 #if GLYPH_DEBUG
10449 /* First and last unchanged row for try_window_id. */
10451 int debug_first_unchanged_at_end_vpos;
10452 int debug_last_unchanged_at_beg_vpos;
10454 /* Delta vpos and y. */
10456 int debug_dvpos, debug_dy;
10458 /* Delta in characters and bytes for try_window_id. */
10460 int debug_delta, debug_delta_bytes;
10462 /* Values of window_end_pos and window_end_vpos at the end of
10463 try_window_id. */
10465 EMACS_INT debug_end_pos, debug_end_vpos;
10467 /* Append a string to W->desired_matrix->method. FMT is a printf
10468 format string. A1...A9 are a supplement for a variable-length
10469 argument list. If trace_redisplay_p is non-zero also printf the
10470 resulting string to stderr. */
10472 static void
10473 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
10474 struct window *w;
10475 char *fmt;
10476 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
10478 char buffer[512];
10479 char *method = w->desired_matrix->method;
10480 int len = strlen (method);
10481 int size = sizeof w->desired_matrix->method;
10482 int remaining = size - len - 1;
10484 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
10485 if (len && remaining)
10487 method[len] = '|';
10488 --remaining, ++len;
10491 strncpy (method + len, buffer, remaining);
10493 if (trace_redisplay_p)
10494 fprintf (stderr, "%p (%s): %s\n",
10496 ((BUFFERP (w->buffer)
10497 && STRINGP (XBUFFER (w->buffer)->name))
10498 ? (char *) SDATA (XBUFFER (w->buffer)->name)
10499 : "no buffer"),
10500 buffer);
10503 #endif /* GLYPH_DEBUG */
10506 /* Value is non-zero if all changes in window W, which displays
10507 current_buffer, are in the text between START and END. START is a
10508 buffer position, END is given as a distance from Z. Used in
10509 redisplay_internal for display optimization. */
10511 static INLINE int
10512 text_outside_line_unchanged_p (w, start, end)
10513 struct window *w;
10514 int start, end;
10516 int unchanged_p = 1;
10518 /* If text or overlays have changed, see where. */
10519 if (XFASTINT (w->last_modified) < MODIFF
10520 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
10522 /* Gap in the line? */
10523 if (GPT < start || Z - GPT < end)
10524 unchanged_p = 0;
10526 /* Changes start in front of the line, or end after it? */
10527 if (unchanged_p
10528 && (BEG_UNCHANGED < start - 1
10529 || END_UNCHANGED < end))
10530 unchanged_p = 0;
10532 /* If selective display, can't optimize if changes start at the
10533 beginning of the line. */
10534 if (unchanged_p
10535 && INTEGERP (current_buffer->selective_display)
10536 && XINT (current_buffer->selective_display) > 0
10537 && (BEG_UNCHANGED < start || GPT <= start))
10538 unchanged_p = 0;
10540 /* If there are overlays at the start or end of the line, these
10541 may have overlay strings with newlines in them. A change at
10542 START, for instance, may actually concern the display of such
10543 overlay strings as well, and they are displayed on different
10544 lines. So, quickly rule out this case. (For the future, it
10545 might be desirable to implement something more telling than
10546 just BEG/END_UNCHANGED.) */
10547 if (unchanged_p)
10549 if (BEG + BEG_UNCHANGED == start
10550 && overlay_touches_p (start))
10551 unchanged_p = 0;
10552 if (END_UNCHANGED == end
10553 && overlay_touches_p (Z - end))
10554 unchanged_p = 0;
10558 return unchanged_p;
10562 /* Do a frame update, taking possible shortcuts into account. This is
10563 the main external entry point for redisplay.
10565 If the last redisplay displayed an echo area message and that message
10566 is no longer requested, we clear the echo area or bring back the
10567 mini-buffer if that is in use. */
10569 void
10570 redisplay ()
10572 redisplay_internal (0);
10576 static Lisp_Object
10577 overlay_arrow_string_or_property (var)
10578 Lisp_Object var;
10580 Lisp_Object val;
10582 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
10583 return val;
10585 return Voverlay_arrow_string;
10588 /* Return 1 if there are any overlay-arrows in current_buffer. */
10589 static int
10590 overlay_arrow_in_current_buffer_p ()
10592 Lisp_Object vlist;
10594 for (vlist = Voverlay_arrow_variable_list;
10595 CONSP (vlist);
10596 vlist = XCDR (vlist))
10598 Lisp_Object var = XCAR (vlist);
10599 Lisp_Object val;
10601 if (!SYMBOLP (var))
10602 continue;
10603 val = find_symbol_value (var);
10604 if (MARKERP (val)
10605 && current_buffer == XMARKER (val)->buffer)
10606 return 1;
10608 return 0;
10612 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
10613 has changed. */
10615 static int
10616 overlay_arrows_changed_p ()
10618 Lisp_Object vlist;
10620 for (vlist = Voverlay_arrow_variable_list;
10621 CONSP (vlist);
10622 vlist = XCDR (vlist))
10624 Lisp_Object var = XCAR (vlist);
10625 Lisp_Object val, pstr;
10627 if (!SYMBOLP (var))
10628 continue;
10629 val = find_symbol_value (var);
10630 if (!MARKERP (val))
10631 continue;
10632 if (! EQ (COERCE_MARKER (val),
10633 Fget (var, Qlast_arrow_position))
10634 || ! (pstr = overlay_arrow_string_or_property (var),
10635 EQ (pstr, Fget (var, Qlast_arrow_string))))
10636 return 1;
10638 return 0;
10641 /* Mark overlay arrows to be updated on next redisplay. */
10643 static void
10644 update_overlay_arrows (up_to_date)
10645 int up_to_date;
10647 Lisp_Object vlist;
10649 for (vlist = Voverlay_arrow_variable_list;
10650 CONSP (vlist);
10651 vlist = XCDR (vlist))
10653 Lisp_Object var = XCAR (vlist);
10655 if (!SYMBOLP (var))
10656 continue;
10658 if (up_to_date > 0)
10660 Lisp_Object val = find_symbol_value (var);
10661 Fput (var, Qlast_arrow_position,
10662 COERCE_MARKER (val));
10663 Fput (var, Qlast_arrow_string,
10664 overlay_arrow_string_or_property (var));
10666 else if (up_to_date < 0
10667 || !NILP (Fget (var, Qlast_arrow_position)))
10669 Fput (var, Qlast_arrow_position, Qt);
10670 Fput (var, Qlast_arrow_string, Qt);
10676 /* Return overlay arrow string to display at row.
10677 Return integer (bitmap number) for arrow bitmap in left fringe.
10678 Return nil if no overlay arrow. */
10680 static Lisp_Object
10681 overlay_arrow_at_row (it, row)
10682 struct it *it;
10683 struct glyph_row *row;
10685 Lisp_Object vlist;
10687 for (vlist = Voverlay_arrow_variable_list;
10688 CONSP (vlist);
10689 vlist = XCDR (vlist))
10691 Lisp_Object var = XCAR (vlist);
10692 Lisp_Object val;
10694 if (!SYMBOLP (var))
10695 continue;
10697 val = find_symbol_value (var);
10699 if (MARKERP (val)
10700 && current_buffer == XMARKER (val)->buffer
10701 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
10703 if (FRAME_WINDOW_P (it->f)
10704 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
10706 #ifdef HAVE_WINDOW_SYSTEM
10707 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
10709 int fringe_bitmap;
10710 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
10711 return make_number (fringe_bitmap);
10713 #endif
10714 return make_number (-1); /* Use default arrow bitmap */
10716 return overlay_arrow_string_or_property (var);
10720 return Qnil;
10723 /* Return 1 if point moved out of or into a composition. Otherwise
10724 return 0. PREV_BUF and PREV_PT are the last point buffer and
10725 position. BUF and PT are the current point buffer and position. */
10728 check_point_in_composition (prev_buf, prev_pt, buf, pt)
10729 struct buffer *prev_buf, *buf;
10730 int prev_pt, pt;
10732 int start, end;
10733 Lisp_Object prop;
10734 Lisp_Object buffer;
10736 XSETBUFFER (buffer, buf);
10737 /* Check a composition at the last point if point moved within the
10738 same buffer. */
10739 if (prev_buf == buf)
10741 if (prev_pt == pt)
10742 /* Point didn't move. */
10743 return 0;
10745 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
10746 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
10747 && COMPOSITION_VALID_P (start, end, prop)
10748 && start < prev_pt && end > prev_pt)
10749 /* The last point was within the composition. Return 1 iff
10750 point moved out of the composition. */
10751 return (pt <= start || pt >= end);
10754 /* Check a composition at the current point. */
10755 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
10756 && find_composition (pt, -1, &start, &end, &prop, buffer)
10757 && COMPOSITION_VALID_P (start, end, prop)
10758 && start < pt && end > pt);
10762 /* Reconsider the setting of B->clip_changed which is displayed
10763 in window W. */
10765 static INLINE void
10766 reconsider_clip_changes (w, b)
10767 struct window *w;
10768 struct buffer *b;
10770 if (b->clip_changed
10771 && !NILP (w->window_end_valid)
10772 && w->current_matrix->buffer == b
10773 && w->current_matrix->zv == BUF_ZV (b)
10774 && w->current_matrix->begv == BUF_BEGV (b))
10775 b->clip_changed = 0;
10777 /* If display wasn't paused, and W is not a tool bar window, see if
10778 point has been moved into or out of a composition. In that case,
10779 we set b->clip_changed to 1 to force updating the screen. If
10780 b->clip_changed has already been set to 1, we can skip this
10781 check. */
10782 if (!b->clip_changed
10783 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
10785 int pt;
10787 if (w == XWINDOW (selected_window))
10788 pt = BUF_PT (current_buffer);
10789 else
10790 pt = marker_position (w->pointm);
10792 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
10793 || pt != XINT (w->last_point))
10794 && check_point_in_composition (w->current_matrix->buffer,
10795 XINT (w->last_point),
10796 XBUFFER (w->buffer), pt))
10797 b->clip_changed = 1;
10802 /* Select FRAME to forward the values of frame-local variables into C
10803 variables so that the redisplay routines can access those values
10804 directly. */
10806 static void
10807 select_frame_for_redisplay (frame)
10808 Lisp_Object frame;
10810 Lisp_Object tail, sym, val;
10811 Lisp_Object old = selected_frame;
10813 xassert (FRAMEP (frame) && FRAME_LIVE_P (XFRAME (frame)));
10815 selected_frame = frame;
10817 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
10818 if (CONSP (XCAR (tail))
10819 && (sym = XCAR (XCAR (tail)),
10820 SYMBOLP (sym))
10821 && (sym = indirect_variable (sym),
10822 val = SYMBOL_VALUE (sym),
10823 (BUFFER_LOCAL_VALUEP (val)))
10824 && XBUFFER_LOCAL_VALUE (val)->check_frame)
10825 /* Use find_symbol_value rather than Fsymbol_value
10826 to avoid an error if it is void. */
10827 find_symbol_value (sym);
10829 for (tail = XFRAME (old)->param_alist; CONSP (tail); tail = XCDR (tail))
10830 if (CONSP (XCAR (tail))
10831 && (sym = XCAR (XCAR (tail)),
10832 SYMBOLP (sym))
10833 && (sym = indirect_variable (sym),
10834 val = SYMBOL_VALUE (sym),
10835 (BUFFER_LOCAL_VALUEP (val)))
10836 && XBUFFER_LOCAL_VALUE (val)->check_frame)
10837 find_symbol_value (sym);
10841 #define STOP_POLLING \
10842 do { if (! polling_stopped_here) stop_polling (); \
10843 polling_stopped_here = 1; } while (0)
10845 #define RESUME_POLLING \
10846 do { if (polling_stopped_here) start_polling (); \
10847 polling_stopped_here = 0; } while (0)
10850 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
10851 response to any user action; therefore, we should preserve the echo
10852 area. (Actually, our caller does that job.) Perhaps in the future
10853 avoid recentering windows if it is not necessary; currently that
10854 causes some problems. */
10856 static void
10857 redisplay_internal (preserve_echo_area)
10858 int preserve_echo_area;
10860 struct window *w = XWINDOW (selected_window);
10861 struct frame *f;
10862 int pause;
10863 int must_finish = 0;
10864 struct text_pos tlbufpos, tlendpos;
10865 int number_of_visible_frames;
10866 int count, count1;
10867 struct frame *sf;
10868 int polling_stopped_here = 0;
10869 Lisp_Object old_frame = selected_frame;
10871 /* Non-zero means redisplay has to consider all windows on all
10872 frames. Zero means, only selected_window is considered. */
10873 int consider_all_windows_p;
10875 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
10877 /* No redisplay if running in batch mode or frame is not yet fully
10878 initialized, or redisplay is explicitly turned off by setting
10879 Vinhibit_redisplay. */
10880 if (noninteractive
10881 || !NILP (Vinhibit_redisplay))
10882 return;
10884 /* Don't examine these until after testing Vinhibit_redisplay.
10885 When Emacs is shutting down, perhaps because its connection to
10886 X has dropped, we should not look at them at all. */
10887 f = XFRAME (w->frame);
10888 sf = SELECTED_FRAME ();
10890 if (!f->glyphs_initialized_p)
10891 return;
10893 /* The flag redisplay_performed_directly_p is set by
10894 direct_output_for_insert when it already did the whole screen
10895 update necessary. */
10896 if (redisplay_performed_directly_p)
10898 redisplay_performed_directly_p = 0;
10899 if (!hscroll_windows (selected_window))
10900 return;
10903 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (MAC_OS)
10904 if (popup_activated ())
10905 return;
10906 #endif
10908 /* I don't think this happens but let's be paranoid. */
10909 if (redisplaying_p)
10910 return;
10912 /* Record a function that resets redisplaying_p to its old value
10913 when we leave this function. */
10914 count = SPECPDL_INDEX ();
10915 record_unwind_protect (unwind_redisplay,
10916 Fcons (make_number (redisplaying_p), selected_frame));
10917 ++redisplaying_p;
10918 specbind (Qinhibit_free_realized_faces, Qnil);
10921 Lisp_Object tail, frame;
10923 FOR_EACH_FRAME (tail, frame)
10925 struct frame *f = XFRAME (frame);
10926 f->already_hscrolled_p = 0;
10930 retry:
10931 if (!EQ (old_frame, selected_frame)
10932 && FRAME_LIVE_P (XFRAME (old_frame)))
10933 /* When running redisplay, we play a bit fast-and-loose and allow e.g.
10934 selected_frame and selected_window to be temporarily out-of-sync so
10935 when we come back here via `goto retry', we need to resync because we
10936 may need to run Elisp code (via prepare_menu_bars). */
10937 select_frame_for_redisplay (old_frame);
10939 pause = 0;
10940 reconsider_clip_changes (w, current_buffer);
10941 last_escape_glyph_frame = NULL;
10942 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
10944 /* If new fonts have been loaded that make a glyph matrix adjustment
10945 necessary, do it. */
10946 if (fonts_changed_p)
10948 adjust_glyphs (NULL);
10949 ++windows_or_buffers_changed;
10950 fonts_changed_p = 0;
10953 /* If face_change_count is non-zero, init_iterator will free all
10954 realized faces, which includes the faces referenced from current
10955 matrices. So, we can't reuse current matrices in this case. */
10956 if (face_change_count)
10957 ++windows_or_buffers_changed;
10959 if (FRAME_TERMCAP_P (sf)
10960 && FRAME_TTY (sf)->previous_frame != sf)
10962 /* Since frames on a single ASCII terminal share the same
10963 display area, displaying a different frame means redisplay
10964 the whole thing. */
10965 windows_or_buffers_changed++;
10966 SET_FRAME_GARBAGED (sf);
10967 FRAME_TTY (sf)->previous_frame = sf;
10970 /* Set the visible flags for all frames. Do this before checking
10971 for resized or garbaged frames; they want to know if their frames
10972 are visible. See the comment in frame.h for
10973 FRAME_SAMPLE_VISIBILITY. */
10975 Lisp_Object tail, frame;
10977 number_of_visible_frames = 0;
10979 FOR_EACH_FRAME (tail, frame)
10981 struct frame *f = XFRAME (frame);
10983 FRAME_SAMPLE_VISIBILITY (f);
10984 if (FRAME_VISIBLE_P (f))
10985 ++number_of_visible_frames;
10986 clear_desired_matrices (f);
10991 /* Notice any pending interrupt request to change frame size. */
10992 do_pending_window_change (1);
10994 /* Clear frames marked as garbaged. */
10995 if (frame_garbaged)
10996 clear_garbaged_frames ();
10998 /* Build menubar and tool-bar items. */
10999 if (NILP (Vmemory_full))
11000 prepare_menu_bars ();
11002 if (windows_or_buffers_changed)
11003 update_mode_lines++;
11005 /* Detect case that we need to write or remove a star in the mode line. */
11006 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
11008 w->update_mode_line = Qt;
11009 if (buffer_shared > 1)
11010 update_mode_lines++;
11013 /* Avoid invocation of point motion hooks by `current_column' below. */
11014 count1 = SPECPDL_INDEX ();
11015 specbind (Qinhibit_point_motion_hooks, Qt);
11017 /* If %c is in the mode line, update it if needed. */
11018 if (!NILP (w->column_number_displayed)
11019 /* This alternative quickly identifies a common case
11020 where no change is needed. */
11021 && !(PT == XFASTINT (w->last_point)
11022 && XFASTINT (w->last_modified) >= MODIFF
11023 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
11024 && (XFASTINT (w->column_number_displayed)
11025 != (int) current_column ())) /* iftc */
11026 w->update_mode_line = Qt;
11028 unbind_to (count1, Qnil);
11030 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
11032 /* The variable buffer_shared is set in redisplay_window and
11033 indicates that we redisplay a buffer in different windows. See
11034 there. */
11035 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
11036 || cursor_type_changed);
11038 /* If specs for an arrow have changed, do thorough redisplay
11039 to ensure we remove any arrow that should no longer exist. */
11040 if (overlay_arrows_changed_p ())
11041 consider_all_windows_p = windows_or_buffers_changed = 1;
11043 /* Normally the message* functions will have already displayed and
11044 updated the echo area, but the frame may have been trashed, or
11045 the update may have been preempted, so display the echo area
11046 again here. Checking message_cleared_p captures the case that
11047 the echo area should be cleared. */
11048 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
11049 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
11050 || (message_cleared_p
11051 && minibuf_level == 0
11052 /* If the mini-window is currently selected, this means the
11053 echo-area doesn't show through. */
11054 && !MINI_WINDOW_P (XWINDOW (selected_window))))
11056 int window_height_changed_p = echo_area_display (0);
11057 must_finish = 1;
11059 /* If we don't display the current message, don't clear the
11060 message_cleared_p flag, because, if we did, we wouldn't clear
11061 the echo area in the next redisplay which doesn't preserve
11062 the echo area. */
11063 if (!display_last_displayed_message_p)
11064 message_cleared_p = 0;
11066 if (fonts_changed_p)
11067 goto retry;
11068 else if (window_height_changed_p)
11070 consider_all_windows_p = 1;
11071 ++update_mode_lines;
11072 ++windows_or_buffers_changed;
11074 /* If window configuration was changed, frames may have been
11075 marked garbaged. Clear them or we will experience
11076 surprises wrt scrolling. */
11077 if (frame_garbaged)
11078 clear_garbaged_frames ();
11081 else if (EQ (selected_window, minibuf_window)
11082 && (current_buffer->clip_changed
11083 || XFASTINT (w->last_modified) < MODIFF
11084 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
11085 && resize_mini_window (w, 0))
11087 /* Resized active mini-window to fit the size of what it is
11088 showing if its contents might have changed. */
11089 must_finish = 1;
11090 consider_all_windows_p = 1;
11091 ++windows_or_buffers_changed;
11092 ++update_mode_lines;
11094 /* If window configuration was changed, frames may have been
11095 marked garbaged. Clear them or we will experience
11096 surprises wrt scrolling. */
11097 if (frame_garbaged)
11098 clear_garbaged_frames ();
11102 /* If showing the region, and mark has changed, we must redisplay
11103 the whole window. The assignment to this_line_start_pos prevents
11104 the optimization directly below this if-statement. */
11105 if (((!NILP (Vtransient_mark_mode)
11106 && !NILP (XBUFFER (w->buffer)->mark_active))
11107 != !NILP (w->region_showing))
11108 || (!NILP (w->region_showing)
11109 && !EQ (w->region_showing,
11110 Fmarker_position (XBUFFER (w->buffer)->mark))))
11111 CHARPOS (this_line_start_pos) = 0;
11113 /* Optimize the case that only the line containing the cursor in the
11114 selected window has changed. Variables starting with this_ are
11115 set in display_line and record information about the line
11116 containing the cursor. */
11117 tlbufpos = this_line_start_pos;
11118 tlendpos = this_line_end_pos;
11119 if (!consider_all_windows_p
11120 && CHARPOS (tlbufpos) > 0
11121 && NILP (w->update_mode_line)
11122 && !current_buffer->clip_changed
11123 && !current_buffer->prevent_redisplay_optimizations_p
11124 && FRAME_VISIBLE_P (XFRAME (w->frame))
11125 && !FRAME_OBSCURED_P (XFRAME (w->frame))
11126 /* Make sure recorded data applies to current buffer, etc. */
11127 && this_line_buffer == current_buffer
11128 && current_buffer == XBUFFER (w->buffer)
11129 && NILP (w->force_start)
11130 && NILP (w->optional_new_start)
11131 /* Point must be on the line that we have info recorded about. */
11132 && PT >= CHARPOS (tlbufpos)
11133 && PT <= Z - CHARPOS (tlendpos)
11134 /* All text outside that line, including its final newline,
11135 must be unchanged */
11136 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
11137 CHARPOS (tlendpos)))
11139 if (CHARPOS (tlbufpos) > BEGV
11140 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
11141 && (CHARPOS (tlbufpos) == ZV
11142 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
11143 /* Former continuation line has disappeared by becoming empty */
11144 goto cancel;
11145 else if (XFASTINT (w->last_modified) < MODIFF
11146 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
11147 || MINI_WINDOW_P (w))
11149 /* We have to handle the case of continuation around a
11150 wide-column character (See the comment in indent.c around
11151 line 885).
11153 For instance, in the following case:
11155 -------- Insert --------
11156 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
11157 J_I_ ==> J_I_ `^^' are cursors.
11158 ^^ ^^
11159 -------- --------
11161 As we have to redraw the line above, we should goto cancel. */
11163 struct it it;
11164 int line_height_before = this_line_pixel_height;
11166 /* Note that start_display will handle the case that the
11167 line starting at tlbufpos is a continuation lines. */
11168 start_display (&it, w, tlbufpos);
11170 /* Implementation note: It this still necessary? */
11171 if (it.current_x != this_line_start_x)
11172 goto cancel;
11174 TRACE ((stderr, "trying display optimization 1\n"));
11175 w->cursor.vpos = -1;
11176 overlay_arrow_seen = 0;
11177 it.vpos = this_line_vpos;
11178 it.current_y = this_line_y;
11179 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
11180 display_line (&it);
11182 /* If line contains point, is not continued,
11183 and ends at same distance from eob as before, we win */
11184 if (w->cursor.vpos >= 0
11185 /* Line is not continued, otherwise this_line_start_pos
11186 would have been set to 0 in display_line. */
11187 && CHARPOS (this_line_start_pos)
11188 /* Line ends as before. */
11189 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
11190 /* Line has same height as before. Otherwise other lines
11191 would have to be shifted up or down. */
11192 && this_line_pixel_height == line_height_before)
11194 /* If this is not the window's last line, we must adjust
11195 the charstarts of the lines below. */
11196 if (it.current_y < it.last_visible_y)
11198 struct glyph_row *row
11199 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
11200 int delta, delta_bytes;
11202 if (Z - CHARPOS (tlendpos) == ZV)
11204 /* This line ends at end of (accessible part of)
11205 buffer. There is no newline to count. */
11206 delta = (Z
11207 - CHARPOS (tlendpos)
11208 - MATRIX_ROW_START_CHARPOS (row));
11209 delta_bytes = (Z_BYTE
11210 - BYTEPOS (tlendpos)
11211 - MATRIX_ROW_START_BYTEPOS (row));
11213 else
11215 /* This line ends in a newline. Must take
11216 account of the newline and the rest of the
11217 text that follows. */
11218 delta = (Z
11219 - CHARPOS (tlendpos)
11220 - MATRIX_ROW_START_CHARPOS (row));
11221 delta_bytes = (Z_BYTE
11222 - BYTEPOS (tlendpos)
11223 - MATRIX_ROW_START_BYTEPOS (row));
11226 increment_matrix_positions (w->current_matrix,
11227 this_line_vpos + 1,
11228 w->current_matrix->nrows,
11229 delta, delta_bytes);
11232 /* If this row displays text now but previously didn't,
11233 or vice versa, w->window_end_vpos may have to be
11234 adjusted. */
11235 if ((it.glyph_row - 1)->displays_text_p)
11237 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
11238 XSETINT (w->window_end_vpos, this_line_vpos);
11240 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
11241 && this_line_vpos > 0)
11242 XSETINT (w->window_end_vpos, this_line_vpos - 1);
11243 w->window_end_valid = Qnil;
11245 /* Update hint: No need to try to scroll in update_window. */
11246 w->desired_matrix->no_scrolling_p = 1;
11248 #if GLYPH_DEBUG
11249 *w->desired_matrix->method = 0;
11250 debug_method_add (w, "optimization 1");
11251 #endif
11252 #ifdef HAVE_WINDOW_SYSTEM
11253 update_window_fringes (w, 0);
11254 #endif
11255 goto update;
11257 else
11258 goto cancel;
11260 else if (/* Cursor position hasn't changed. */
11261 PT == XFASTINT (w->last_point)
11262 /* Make sure the cursor was last displayed
11263 in this window. Otherwise we have to reposition it. */
11264 && 0 <= w->cursor.vpos
11265 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
11267 if (!must_finish)
11269 do_pending_window_change (1);
11271 /* We used to always goto end_of_redisplay here, but this
11272 isn't enough if we have a blinking cursor. */
11273 if (w->cursor_off_p == w->last_cursor_off_p)
11274 goto end_of_redisplay;
11276 goto update;
11278 /* If highlighting the region, or if the cursor is in the echo area,
11279 then we can't just move the cursor. */
11280 else if (! (!NILP (Vtransient_mark_mode)
11281 && !NILP (current_buffer->mark_active))
11282 && (EQ (selected_window, current_buffer->last_selected_window)
11283 || highlight_nonselected_windows)
11284 && NILP (w->region_showing)
11285 && NILP (Vshow_trailing_whitespace)
11286 && !cursor_in_echo_area)
11288 struct it it;
11289 struct glyph_row *row;
11291 /* Skip from tlbufpos to PT and see where it is. Note that
11292 PT may be in invisible text. If so, we will end at the
11293 next visible position. */
11294 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
11295 NULL, DEFAULT_FACE_ID);
11296 it.current_x = this_line_start_x;
11297 it.current_y = this_line_y;
11298 it.vpos = this_line_vpos;
11300 /* The call to move_it_to stops in front of PT, but
11301 moves over before-strings. */
11302 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
11304 if (it.vpos == this_line_vpos
11305 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
11306 row->enabled_p))
11308 xassert (this_line_vpos == it.vpos);
11309 xassert (this_line_y == it.current_y);
11310 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11311 #if GLYPH_DEBUG
11312 *w->desired_matrix->method = 0;
11313 debug_method_add (w, "optimization 3");
11314 #endif
11315 goto update;
11317 else
11318 goto cancel;
11321 cancel:
11322 /* Text changed drastically or point moved off of line. */
11323 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
11326 CHARPOS (this_line_start_pos) = 0;
11327 consider_all_windows_p |= buffer_shared > 1;
11328 ++clear_face_cache_count;
11329 #ifdef HAVE_WINDOW_SYSTEM
11330 ++clear_image_cache_count;
11331 #endif
11333 /* Build desired matrices, and update the display. If
11334 consider_all_windows_p is non-zero, do it for all windows on all
11335 frames. Otherwise do it for selected_window, only. */
11337 if (consider_all_windows_p)
11339 Lisp_Object tail, frame;
11341 FOR_EACH_FRAME (tail, frame)
11342 XFRAME (frame)->updated_p = 0;
11344 /* Recompute # windows showing selected buffer. This will be
11345 incremented each time such a window is displayed. */
11346 buffer_shared = 0;
11348 FOR_EACH_FRAME (tail, frame)
11350 struct frame *f = XFRAME (frame);
11352 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
11354 if (! EQ (frame, selected_frame))
11355 /* Select the frame, for the sake of frame-local
11356 variables. */
11357 select_frame_for_redisplay (frame);
11359 /* Mark all the scroll bars to be removed; we'll redeem
11360 the ones we want when we redisplay their windows. */
11361 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
11362 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
11364 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
11365 redisplay_windows (FRAME_ROOT_WINDOW (f));
11367 /* Any scroll bars which redisplay_windows should have
11368 nuked should now go away. */
11369 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
11370 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
11372 /* If fonts changed, display again. */
11373 /* ??? rms: I suspect it is a mistake to jump all the way
11374 back to retry here. It should just retry this frame. */
11375 if (fonts_changed_p)
11376 goto retry;
11378 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
11380 /* See if we have to hscroll. */
11381 if (!f->already_hscrolled_p)
11383 f->already_hscrolled_p = 1;
11384 if (hscroll_windows (f->root_window))
11385 goto retry;
11388 /* Prevent various kinds of signals during display
11389 update. stdio is not robust about handling
11390 signals, which can cause an apparent I/O
11391 error. */
11392 if (interrupt_input)
11393 unrequest_sigio ();
11394 STOP_POLLING;
11396 /* Update the display. */
11397 set_window_update_flags (XWINDOW (f->root_window), 1);
11398 pause |= update_frame (f, 0, 0);
11399 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
11400 if (pause)
11401 break;
11402 #endif
11404 f->updated_p = 1;
11409 if (!pause)
11411 /* Do the mark_window_display_accurate after all windows have
11412 been redisplayed because this call resets flags in buffers
11413 which are needed for proper redisplay. */
11414 FOR_EACH_FRAME (tail, frame)
11416 struct frame *f = XFRAME (frame);
11417 if (f->updated_p)
11419 mark_window_display_accurate (f->root_window, 1);
11420 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
11421 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
11426 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
11428 Lisp_Object mini_window;
11429 struct frame *mini_frame;
11431 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
11432 /* Use list_of_error, not Qerror, so that
11433 we catch only errors and don't run the debugger. */
11434 internal_condition_case_1 (redisplay_window_1, selected_window,
11435 list_of_error,
11436 redisplay_window_error);
11438 /* Compare desired and current matrices, perform output. */
11440 update:
11441 /* If fonts changed, display again. */
11442 if (fonts_changed_p)
11443 goto retry;
11445 /* Prevent various kinds of signals during display update.
11446 stdio is not robust about handling signals,
11447 which can cause an apparent I/O error. */
11448 if (interrupt_input)
11449 unrequest_sigio ();
11450 STOP_POLLING;
11452 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
11454 if (hscroll_windows (selected_window))
11455 goto retry;
11457 XWINDOW (selected_window)->must_be_updated_p = 1;
11458 pause = update_frame (sf, 0, 0);
11461 /* We may have called echo_area_display at the top of this
11462 function. If the echo area is on another frame, that may
11463 have put text on a frame other than the selected one, so the
11464 above call to update_frame would not have caught it. Catch
11465 it here. */
11466 mini_window = FRAME_MINIBUF_WINDOW (sf);
11467 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
11469 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
11471 XWINDOW (mini_window)->must_be_updated_p = 1;
11472 pause |= update_frame (mini_frame, 0, 0);
11473 if (!pause && hscroll_windows (mini_window))
11474 goto retry;
11478 /* If display was paused because of pending input, make sure we do a
11479 thorough update the next time. */
11480 if (pause)
11482 /* Prevent the optimization at the beginning of
11483 redisplay_internal that tries a single-line update of the
11484 line containing the cursor in the selected window. */
11485 CHARPOS (this_line_start_pos) = 0;
11487 /* Let the overlay arrow be updated the next time. */
11488 update_overlay_arrows (0);
11490 /* If we pause after scrolling, some rows in the current
11491 matrices of some windows are not valid. */
11492 if (!WINDOW_FULL_WIDTH_P (w)
11493 && !FRAME_WINDOW_P (XFRAME (w->frame)))
11494 update_mode_lines = 1;
11496 else
11498 if (!consider_all_windows_p)
11500 /* This has already been done above if
11501 consider_all_windows_p is set. */
11502 mark_window_display_accurate_1 (w, 1);
11504 /* Say overlay arrows are up to date. */
11505 update_overlay_arrows (1);
11507 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
11508 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
11511 update_mode_lines = 0;
11512 windows_or_buffers_changed = 0;
11513 cursor_type_changed = 0;
11516 /* Start SIGIO interrupts coming again. Having them off during the
11517 code above makes it less likely one will discard output, but not
11518 impossible, since there might be stuff in the system buffer here.
11519 But it is much hairier to try to do anything about that. */
11520 if (interrupt_input)
11521 request_sigio ();
11522 RESUME_POLLING;
11524 /* If a frame has become visible which was not before, redisplay
11525 again, so that we display it. Expose events for such a frame
11526 (which it gets when becoming visible) don't call the parts of
11527 redisplay constructing glyphs, so simply exposing a frame won't
11528 display anything in this case. So, we have to display these
11529 frames here explicitly. */
11530 if (!pause)
11532 Lisp_Object tail, frame;
11533 int new_count = 0;
11535 FOR_EACH_FRAME (tail, frame)
11537 int this_is_visible = 0;
11539 if (XFRAME (frame)->visible)
11540 this_is_visible = 1;
11541 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
11542 if (XFRAME (frame)->visible)
11543 this_is_visible = 1;
11545 if (this_is_visible)
11546 new_count++;
11549 if (new_count != number_of_visible_frames)
11550 windows_or_buffers_changed++;
11553 /* Change frame size now if a change is pending. */
11554 do_pending_window_change (1);
11556 /* If we just did a pending size change, or have additional
11557 visible frames, redisplay again. */
11558 if (windows_or_buffers_changed && !pause)
11559 goto retry;
11561 /* Clear the face cache eventually. */
11562 if (consider_all_windows_p)
11564 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
11566 clear_face_cache (0);
11567 clear_face_cache_count = 0;
11569 #ifdef HAVE_WINDOW_SYSTEM
11570 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
11572 Lisp_Object tail, frame;
11573 FOR_EACH_FRAME (tail, frame)
11575 struct frame *f = XFRAME (frame);
11576 if (FRAME_WINDOW_P (f))
11577 clear_image_cache (f, 0);
11579 clear_image_cache_count = 0;
11581 #endif /* HAVE_WINDOW_SYSTEM */
11584 end_of_redisplay:
11585 unbind_to (count, Qnil);
11586 RESUME_POLLING;
11590 /* Redisplay, but leave alone any recent echo area message unless
11591 another message has been requested in its place.
11593 This is useful in situations where you need to redisplay but no
11594 user action has occurred, making it inappropriate for the message
11595 area to be cleared. See tracking_off and
11596 wait_reading_process_output for examples of these situations.
11598 FROM_WHERE is an integer saying from where this function was
11599 called. This is useful for debugging. */
11601 void
11602 redisplay_preserve_echo_area (from_where)
11603 int from_where;
11605 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
11607 if (!NILP (echo_area_buffer[1]))
11609 /* We have a previously displayed message, but no current
11610 message. Redisplay the previous message. */
11611 display_last_displayed_message_p = 1;
11612 redisplay_internal (1);
11613 display_last_displayed_message_p = 0;
11615 else
11616 redisplay_internal (1);
11618 if (FRAME_RIF (SELECTED_FRAME ()) != NULL
11619 && FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
11620 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (NULL);
11624 /* Function registered with record_unwind_protect in
11625 redisplay_internal. Reset redisplaying_p to the value it had
11626 before redisplay_internal was called, and clear
11627 prevent_freeing_realized_faces_p. It also selects the previously
11628 selected frame, unless it has been deleted (by an X connection
11629 failure during redisplay, for example). */
11631 static Lisp_Object
11632 unwind_redisplay (val)
11633 Lisp_Object val;
11635 Lisp_Object old_redisplaying_p, old_frame;
11637 old_redisplaying_p = XCAR (val);
11638 redisplaying_p = XFASTINT (old_redisplaying_p);
11639 old_frame = XCDR (val);
11640 if (! EQ (old_frame, selected_frame)
11641 && FRAME_LIVE_P (XFRAME (old_frame)))
11642 select_frame_for_redisplay (old_frame);
11643 return Qnil;
11647 /* Mark the display of window W as accurate or inaccurate. If
11648 ACCURATE_P is non-zero mark display of W as accurate. If
11649 ACCURATE_P is zero, arrange for W to be redisplayed the next time
11650 redisplay_internal is called. */
11652 static void
11653 mark_window_display_accurate_1 (w, accurate_p)
11654 struct window *w;
11655 int accurate_p;
11657 if (BUFFERP (w->buffer))
11659 struct buffer *b = XBUFFER (w->buffer);
11661 w->last_modified
11662 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
11663 w->last_overlay_modified
11664 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
11665 w->last_had_star
11666 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
11668 if (accurate_p)
11670 b->clip_changed = 0;
11671 b->prevent_redisplay_optimizations_p = 0;
11673 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
11674 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
11675 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
11676 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
11678 w->current_matrix->buffer = b;
11679 w->current_matrix->begv = BUF_BEGV (b);
11680 w->current_matrix->zv = BUF_ZV (b);
11682 w->last_cursor = w->cursor;
11683 w->last_cursor_off_p = w->cursor_off_p;
11685 if (w == XWINDOW (selected_window))
11686 w->last_point = make_number (BUF_PT (b));
11687 else
11688 w->last_point = make_number (XMARKER (w->pointm)->charpos);
11692 if (accurate_p)
11694 w->window_end_valid = w->buffer;
11695 #if 0 /* This is incorrect with variable-height lines. */
11696 xassert (XINT (w->window_end_vpos)
11697 < (WINDOW_TOTAL_LINES (w)
11698 - (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
11699 #endif
11700 w->update_mode_line = Qnil;
11705 /* Mark the display of windows in the window tree rooted at WINDOW as
11706 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
11707 windows as accurate. If ACCURATE_P is zero, arrange for windows to
11708 be redisplayed the next time redisplay_internal is called. */
11710 void
11711 mark_window_display_accurate (window, accurate_p)
11712 Lisp_Object window;
11713 int accurate_p;
11715 struct window *w;
11717 for (; !NILP (window); window = w->next)
11719 w = XWINDOW (window);
11720 mark_window_display_accurate_1 (w, accurate_p);
11722 if (!NILP (w->vchild))
11723 mark_window_display_accurate (w->vchild, accurate_p);
11724 if (!NILP (w->hchild))
11725 mark_window_display_accurate (w->hchild, accurate_p);
11728 if (accurate_p)
11730 update_overlay_arrows (1);
11732 else
11734 /* Force a thorough redisplay the next time by setting
11735 last_arrow_position and last_arrow_string to t, which is
11736 unequal to any useful value of Voverlay_arrow_... */
11737 update_overlay_arrows (-1);
11742 /* Return value in display table DP (Lisp_Char_Table *) for character
11743 C. Since a display table doesn't have any parent, we don't have to
11744 follow parent. Do not call this function directly but use the
11745 macro DISP_CHAR_VECTOR. */
11747 Lisp_Object
11748 disp_char_vector (dp, c)
11749 struct Lisp_Char_Table *dp;
11750 int c;
11752 int code[4], i;
11753 Lisp_Object val;
11755 if (SINGLE_BYTE_CHAR_P (c))
11756 return (dp->contents[c]);
11758 SPLIT_CHAR (c, code[0], code[1], code[2]);
11759 if (code[1] < 32)
11760 code[1] = -1;
11761 else if (code[2] < 32)
11762 code[2] = -1;
11764 /* Here, the possible range of code[0] (== charset ID) is
11765 128..max_charset. Since the top level char table contains data
11766 for multibyte characters after 256th element, we must increment
11767 code[0] by 128 to get a correct index. */
11768 code[0] += 128;
11769 code[3] = -1; /* anchor */
11771 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
11773 val = dp->contents[code[i]];
11774 if (!SUB_CHAR_TABLE_P (val))
11775 return (NILP (val) ? dp->defalt : val);
11778 /* Here, val is a sub char table. We return the default value of
11779 it. */
11780 return (dp->defalt);
11785 /***********************************************************************
11786 Window Redisplay
11787 ***********************************************************************/
11789 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
11791 static void
11792 redisplay_windows (window)
11793 Lisp_Object window;
11795 while (!NILP (window))
11797 struct window *w = XWINDOW (window);
11799 if (!NILP (w->hchild))
11800 redisplay_windows (w->hchild);
11801 else if (!NILP (w->vchild))
11802 redisplay_windows (w->vchild);
11803 else
11805 displayed_buffer = XBUFFER (w->buffer);
11806 /* Use list_of_error, not Qerror, so that
11807 we catch only errors and don't run the debugger. */
11808 internal_condition_case_1 (redisplay_window_0, window,
11809 list_of_error,
11810 redisplay_window_error);
11813 window = w->next;
11817 static Lisp_Object
11818 redisplay_window_error ()
11820 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
11821 return Qnil;
11824 static Lisp_Object
11825 redisplay_window_0 (window)
11826 Lisp_Object window;
11828 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
11829 redisplay_window (window, 0);
11830 return Qnil;
11833 static Lisp_Object
11834 redisplay_window_1 (window)
11835 Lisp_Object window;
11837 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
11838 redisplay_window (window, 1);
11839 return Qnil;
11843 /* Increment GLYPH until it reaches END or CONDITION fails while
11844 adding (GLYPH)->pixel_width to X. */
11846 #define SKIP_GLYPHS(glyph, end, x, condition) \
11847 do \
11849 (x) += (glyph)->pixel_width; \
11850 ++(glyph); \
11852 while ((glyph) < (end) && (condition))
11855 /* Set cursor position of W. PT is assumed to be displayed in ROW.
11856 DELTA is the number of bytes by which positions recorded in ROW
11857 differ from current buffer positions.
11859 Return 0 if cursor is not on this row. 1 otherwise. */
11862 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
11863 struct window *w;
11864 struct glyph_row *row;
11865 struct glyph_matrix *matrix;
11866 int delta, delta_bytes, dy, dvpos;
11868 struct glyph *glyph = row->glyphs[TEXT_AREA];
11869 struct glyph *end = glyph + row->used[TEXT_AREA];
11870 struct glyph *cursor = NULL;
11871 /* The first glyph that starts a sequence of glyphs from string. */
11872 struct glyph *string_start;
11873 /* The X coordinate of string_start. */
11874 int string_start_x;
11875 /* The last known character position. */
11876 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
11877 /* The last known character position before string_start. */
11878 int string_before_pos;
11879 int x = row->x;
11880 int cursor_x = x;
11881 int cursor_from_overlay_pos = 0;
11882 int pt_old = PT - delta;
11884 /* Skip over glyphs not having an object at the start of the row.
11885 These are special glyphs like truncation marks on terminal
11886 frames. */
11887 if (row->displays_text_p)
11888 while (glyph < end
11889 && INTEGERP (glyph->object)
11890 && glyph->charpos < 0)
11892 x += glyph->pixel_width;
11893 ++glyph;
11896 string_start = NULL;
11897 while (glyph < end
11898 && !INTEGERP (glyph->object)
11899 && (!BUFFERP (glyph->object)
11900 || (last_pos = glyph->charpos) < pt_old))
11902 if (! STRINGP (glyph->object))
11904 string_start = NULL;
11905 x += glyph->pixel_width;
11906 ++glyph;
11907 if (cursor_from_overlay_pos
11908 && last_pos >= cursor_from_overlay_pos)
11910 cursor_from_overlay_pos = 0;
11911 cursor = 0;
11914 else
11916 if (string_start == NULL)
11918 string_before_pos = last_pos;
11919 string_start = glyph;
11920 string_start_x = x;
11922 /* Skip all glyphs from string. */
11925 Lisp_Object cprop;
11926 int pos;
11927 if ((cursor == NULL || glyph > cursor)
11928 && (cprop = Fget_char_property (make_number ((glyph)->charpos),
11929 Qcursor, (glyph)->object),
11930 !NILP (cprop))
11931 && (pos = string_buffer_position (w, glyph->object,
11932 string_before_pos),
11933 (pos == 0 /* From overlay */
11934 || pos == pt_old)))
11936 /* Estimate overlay buffer position from the buffer
11937 positions of the glyphs before and after the overlay.
11938 Add 1 to last_pos so that if point corresponds to the
11939 glyph right after the overlay, we still use a 'cursor'
11940 property found in that overlay. */
11941 cursor_from_overlay_pos = (pos ? 0 : last_pos
11942 + (INTEGERP (cprop) ? XINT (cprop) : 0));
11943 cursor = glyph;
11944 cursor_x = x;
11946 x += glyph->pixel_width;
11947 ++glyph;
11949 while (glyph < end && EQ (glyph->object, string_start->object));
11953 if (cursor != NULL)
11955 glyph = cursor;
11956 x = cursor_x;
11958 else if (row->ends_in_ellipsis_p && glyph == end)
11960 /* Scan back over the ellipsis glyphs, decrementing positions. */
11961 while (glyph > row->glyphs[TEXT_AREA]
11962 && (glyph - 1)->charpos == last_pos)
11963 glyph--, x -= glyph->pixel_width;
11964 /* That loop always goes one position too far,
11965 including the glyph before the ellipsis.
11966 So scan forward over that one. */
11967 x += glyph->pixel_width;
11968 glyph++;
11970 else if (string_start
11971 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
11973 /* We may have skipped over point because the previous glyphs
11974 are from string. As there's no easy way to know the
11975 character position of the current glyph, find the correct
11976 glyph on point by scanning from string_start again. */
11977 Lisp_Object limit;
11978 Lisp_Object string;
11979 struct glyph *stop = glyph;
11980 int pos;
11982 limit = make_number (pt_old + 1);
11983 glyph = string_start;
11984 x = string_start_x;
11985 string = glyph->object;
11986 pos = string_buffer_position (w, string, string_before_pos);
11987 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
11988 because we always put cursor after overlay strings. */
11989 while (pos == 0 && glyph < stop)
11991 string = glyph->object;
11992 SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string));
11993 if (glyph < stop)
11994 pos = string_buffer_position (w, glyph->object, string_before_pos);
11997 while (glyph < stop)
11999 pos = XINT (Fnext_single_char_property_change
12000 (make_number (pos), Qdisplay, Qnil, limit));
12001 if (pos > pt_old)
12002 break;
12003 /* Skip glyphs from the same string. */
12004 string = glyph->object;
12005 SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string));
12006 /* Skip glyphs from an overlay. */
12007 while (glyph < stop
12008 && ! string_buffer_position (w, glyph->object, pos))
12010 string = glyph->object;
12011 SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string));
12015 /* If we reached the end of the line, and end was from a string,
12016 cursor is not on this line. */
12017 if (glyph == end && row->continued_p)
12018 return 0;
12021 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
12022 w->cursor.x = x;
12023 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
12024 w->cursor.y = row->y + dy;
12026 if (w == XWINDOW (selected_window))
12028 if (!row->continued_p
12029 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
12030 && row->x == 0)
12032 this_line_buffer = XBUFFER (w->buffer);
12034 CHARPOS (this_line_start_pos)
12035 = MATRIX_ROW_START_CHARPOS (row) + delta;
12036 BYTEPOS (this_line_start_pos)
12037 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
12039 CHARPOS (this_line_end_pos)
12040 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
12041 BYTEPOS (this_line_end_pos)
12042 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
12044 this_line_y = w->cursor.y;
12045 this_line_pixel_height = row->height;
12046 this_line_vpos = w->cursor.vpos;
12047 this_line_start_x = row->x;
12049 else
12050 CHARPOS (this_line_start_pos) = 0;
12053 return 1;
12057 /* Run window scroll functions, if any, for WINDOW with new window
12058 start STARTP. Sets the window start of WINDOW to that position.
12060 We assume that the window's buffer is really current. */
12062 static INLINE struct text_pos
12063 run_window_scroll_functions (window, startp)
12064 Lisp_Object window;
12065 struct text_pos startp;
12067 struct window *w = XWINDOW (window);
12068 SET_MARKER_FROM_TEXT_POS (w->start, startp);
12070 if (current_buffer != XBUFFER (w->buffer))
12071 abort ();
12073 if (!NILP (Vwindow_scroll_functions))
12075 run_hook_with_args_2 (Qwindow_scroll_functions, window,
12076 make_number (CHARPOS (startp)));
12077 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12078 /* In case the hook functions switch buffers. */
12079 if (current_buffer != XBUFFER (w->buffer))
12080 set_buffer_internal_1 (XBUFFER (w->buffer));
12083 return startp;
12087 /* Make sure the line containing the cursor is fully visible.
12088 A value of 1 means there is nothing to be done.
12089 (Either the line is fully visible, or it cannot be made so,
12090 or we cannot tell.)
12092 If FORCE_P is non-zero, return 0 even if partial visible cursor row
12093 is higher than window.
12095 A value of 0 means the caller should do scrolling
12096 as if point had gone off the screen. */
12098 static int
12099 cursor_row_fully_visible_p (w, force_p, current_matrix_p)
12100 struct window *w;
12101 int force_p;
12102 int current_matrix_p;
12104 struct glyph_matrix *matrix;
12105 struct glyph_row *row;
12106 int window_height;
12108 if (!make_cursor_line_fully_visible_p)
12109 return 1;
12111 /* It's not always possible to find the cursor, e.g, when a window
12112 is full of overlay strings. Don't do anything in that case. */
12113 if (w->cursor.vpos < 0)
12114 return 1;
12116 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
12117 row = MATRIX_ROW (matrix, w->cursor.vpos);
12119 /* If the cursor row is not partially visible, there's nothing to do. */
12120 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
12121 return 1;
12123 /* If the row the cursor is in is taller than the window's height,
12124 it's not clear what to do, so do nothing. */
12125 window_height = window_box_height (w);
12126 if (row->height >= window_height)
12128 if (!force_p || MINI_WINDOW_P (w)
12129 || w->vscroll || w->cursor.vpos == 0)
12130 return 1;
12132 return 0;
12134 #if 0
12135 /* This code used to try to scroll the window just enough to make
12136 the line visible. It returned 0 to say that the caller should
12137 allocate larger glyph matrices. */
12139 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
12141 int dy = row->height - row->visible_height;
12142 w->vscroll = 0;
12143 w->cursor.y += dy;
12144 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
12146 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
12148 int dy = - (row->height - row->visible_height);
12149 w->vscroll = dy;
12150 w->cursor.y += dy;
12151 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
12154 /* When we change the cursor y-position of the selected window,
12155 change this_line_y as well so that the display optimization for
12156 the cursor line of the selected window in redisplay_internal uses
12157 the correct y-position. */
12158 if (w == XWINDOW (selected_window))
12159 this_line_y = w->cursor.y;
12161 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
12162 redisplay with larger matrices. */
12163 if (matrix->nrows < required_matrix_height (w))
12165 fonts_changed_p = 1;
12166 return 0;
12169 return 1;
12170 #endif /* 0 */
12174 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
12175 non-zero means only WINDOW is redisplayed in redisplay_internal.
12176 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
12177 in redisplay_window to bring a partially visible line into view in
12178 the case that only the cursor has moved.
12180 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
12181 last screen line's vertical height extends past the end of the screen.
12183 Value is
12185 1 if scrolling succeeded
12187 0 if scrolling didn't find point.
12189 -1 if new fonts have been loaded so that we must interrupt
12190 redisplay, adjust glyph matrices, and try again. */
12192 enum
12194 SCROLLING_SUCCESS,
12195 SCROLLING_FAILED,
12196 SCROLLING_NEED_LARGER_MATRICES
12199 static int
12200 try_scrolling (window, just_this_one_p, scroll_conservatively,
12201 scroll_step, temp_scroll_step, last_line_misfit)
12202 Lisp_Object window;
12203 int just_this_one_p;
12204 EMACS_INT scroll_conservatively, scroll_step;
12205 int temp_scroll_step;
12206 int last_line_misfit;
12208 struct window *w = XWINDOW (window);
12209 struct frame *f = XFRAME (w->frame);
12210 struct text_pos scroll_margin_pos;
12211 struct text_pos pos;
12212 struct text_pos startp;
12213 struct it it;
12214 Lisp_Object window_end;
12215 int this_scroll_margin;
12216 int dy = 0;
12217 int scroll_max;
12218 int rc;
12219 int amount_to_scroll = 0;
12220 Lisp_Object aggressive;
12221 int height;
12222 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
12224 #if GLYPH_DEBUG
12225 debug_method_add (w, "try_scrolling");
12226 #endif
12228 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12230 /* Compute scroll margin height in pixels. We scroll when point is
12231 within this distance from the top or bottom of the window. */
12232 if (scroll_margin > 0)
12234 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
12235 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
12237 else
12238 this_scroll_margin = 0;
12240 /* Force scroll_conservatively to have a reasonable value so it doesn't
12241 cause an overflow while computing how much to scroll. */
12242 if (scroll_conservatively)
12243 scroll_conservatively = min (scroll_conservatively,
12244 MOST_POSITIVE_FIXNUM / FRAME_LINE_HEIGHT (f));
12246 /* Compute how much we should try to scroll maximally to bring point
12247 into view. */
12248 if (scroll_step || scroll_conservatively || temp_scroll_step)
12249 scroll_max = max (scroll_step,
12250 max (scroll_conservatively, temp_scroll_step));
12251 else if (NUMBERP (current_buffer->scroll_down_aggressively)
12252 || NUMBERP (current_buffer->scroll_up_aggressively))
12253 /* We're trying to scroll because of aggressive scrolling
12254 but no scroll_step is set. Choose an arbitrary one. Maybe
12255 there should be a variable for this. */
12256 scroll_max = 10;
12257 else
12258 scroll_max = 0;
12259 scroll_max *= FRAME_LINE_HEIGHT (f);
12261 /* Decide whether we have to scroll down. Start at the window end
12262 and move this_scroll_margin up to find the position of the scroll
12263 margin. */
12264 window_end = Fwindow_end (window, Qt);
12266 too_near_end:
12268 CHARPOS (scroll_margin_pos) = XINT (window_end);
12269 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
12271 if (this_scroll_margin || extra_scroll_margin_lines)
12273 start_display (&it, w, scroll_margin_pos);
12274 if (this_scroll_margin)
12275 move_it_vertically_backward (&it, this_scroll_margin);
12276 if (extra_scroll_margin_lines)
12277 move_it_by_lines (&it, - extra_scroll_margin_lines, 0);
12278 scroll_margin_pos = it.current.pos;
12281 if (PT >= CHARPOS (scroll_margin_pos))
12283 int y0;
12285 /* Point is in the scroll margin at the bottom of the window, or
12286 below. Compute a new window start that makes point visible. */
12288 /* Compute the distance from the scroll margin to PT.
12289 Give up if the distance is greater than scroll_max. */
12290 start_display (&it, w, scroll_margin_pos);
12291 y0 = it.current_y;
12292 move_it_to (&it, PT, 0, it.last_visible_y, -1,
12293 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
12295 /* To make point visible, we have to move the window start
12296 down so that the line the cursor is in is visible, which
12297 means we have to add in the height of the cursor line. */
12298 dy = line_bottom_y (&it) - y0;
12300 if (dy > scroll_max)
12301 return SCROLLING_FAILED;
12303 /* Move the window start down. If scrolling conservatively,
12304 move it just enough down to make point visible. If
12305 scroll_step is set, move it down by scroll_step. */
12306 start_display (&it, w, startp);
12308 if (scroll_conservatively)
12309 /* Set AMOUNT_TO_SCROLL to at least one line,
12310 and at most scroll_conservatively lines. */
12311 amount_to_scroll
12312 = min (max (dy, FRAME_LINE_HEIGHT (f)),
12313 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
12314 else if (scroll_step || temp_scroll_step)
12315 amount_to_scroll = scroll_max;
12316 else
12318 aggressive = current_buffer->scroll_up_aggressively;
12319 height = WINDOW_BOX_TEXT_HEIGHT (w);
12320 if (NUMBERP (aggressive))
12322 double float_amount = XFLOATINT (aggressive) * height;
12323 amount_to_scroll = float_amount;
12324 if (amount_to_scroll == 0 && float_amount > 0)
12325 amount_to_scroll = 1;
12329 if (amount_to_scroll <= 0)
12330 return SCROLLING_FAILED;
12332 /* If moving by amount_to_scroll leaves STARTP unchanged,
12333 move it down one screen line. */
12335 move_it_vertically (&it, amount_to_scroll);
12336 if (CHARPOS (it.current.pos) == CHARPOS (startp))
12337 move_it_by_lines (&it, 1, 1);
12338 startp = it.current.pos;
12340 else
12342 /* See if point is inside the scroll margin at the top of the
12343 window. */
12344 scroll_margin_pos = startp;
12345 if (this_scroll_margin)
12347 start_display (&it, w, startp);
12348 move_it_vertically (&it, this_scroll_margin);
12349 scroll_margin_pos = it.current.pos;
12352 if (PT < CHARPOS (scroll_margin_pos))
12354 /* Point is in the scroll margin at the top of the window or
12355 above what is displayed in the window. */
12356 int y0;
12358 /* Compute the vertical distance from PT to the scroll
12359 margin position. Give up if distance is greater than
12360 scroll_max. */
12361 SET_TEXT_POS (pos, PT, PT_BYTE);
12362 start_display (&it, w, pos);
12363 y0 = it.current_y;
12364 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
12365 it.last_visible_y, -1,
12366 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
12367 dy = it.current_y - y0;
12368 if (dy > scroll_max)
12369 return SCROLLING_FAILED;
12371 /* Compute new window start. */
12372 start_display (&it, w, startp);
12374 if (scroll_conservatively)
12375 amount_to_scroll
12376 = max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
12377 else if (scroll_step || temp_scroll_step)
12378 amount_to_scroll = scroll_max;
12379 else
12381 aggressive = current_buffer->scroll_down_aggressively;
12382 height = WINDOW_BOX_TEXT_HEIGHT (w);
12383 if (NUMBERP (aggressive))
12385 double float_amount = XFLOATINT (aggressive) * height;
12386 amount_to_scroll = float_amount;
12387 if (amount_to_scroll == 0 && float_amount > 0)
12388 amount_to_scroll = 1;
12392 if (amount_to_scroll <= 0)
12393 return SCROLLING_FAILED;
12395 move_it_vertically_backward (&it, amount_to_scroll);
12396 startp = it.current.pos;
12400 /* Run window scroll functions. */
12401 startp = run_window_scroll_functions (window, startp);
12403 /* Display the window. Give up if new fonts are loaded, or if point
12404 doesn't appear. */
12405 if (!try_window (window, startp, 0))
12406 rc = SCROLLING_NEED_LARGER_MATRICES;
12407 else if (w->cursor.vpos < 0)
12409 clear_glyph_matrix (w->desired_matrix);
12410 rc = SCROLLING_FAILED;
12412 else
12414 /* Maybe forget recorded base line for line number display. */
12415 if (!just_this_one_p
12416 || current_buffer->clip_changed
12417 || BEG_UNCHANGED < CHARPOS (startp))
12418 w->base_line_number = Qnil;
12420 /* If cursor ends up on a partially visible line,
12421 treat that as being off the bottom of the screen. */
12422 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0))
12424 clear_glyph_matrix (w->desired_matrix);
12425 ++extra_scroll_margin_lines;
12426 goto too_near_end;
12428 rc = SCROLLING_SUCCESS;
12431 return rc;
12435 /* Compute a suitable window start for window W if display of W starts
12436 on a continuation line. Value is non-zero if a new window start
12437 was computed.
12439 The new window start will be computed, based on W's width, starting
12440 from the start of the continued line. It is the start of the
12441 screen line with the minimum distance from the old start W->start. */
12443 static int
12444 compute_window_start_on_continuation_line (w)
12445 struct window *w;
12447 struct text_pos pos, start_pos;
12448 int window_start_changed_p = 0;
12450 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
12452 /* If window start is on a continuation line... Window start may be
12453 < BEGV in case there's invisible text at the start of the
12454 buffer (M-x rmail, for example). */
12455 if (CHARPOS (start_pos) > BEGV
12456 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
12458 struct it it;
12459 struct glyph_row *row;
12461 /* Handle the case that the window start is out of range. */
12462 if (CHARPOS (start_pos) < BEGV)
12463 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
12464 else if (CHARPOS (start_pos) > ZV)
12465 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
12467 /* Find the start of the continued line. This should be fast
12468 because scan_buffer is fast (newline cache). */
12469 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
12470 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
12471 row, DEFAULT_FACE_ID);
12472 reseat_at_previous_visible_line_start (&it);
12474 /* If the line start is "too far" away from the window start,
12475 say it takes too much time to compute a new window start. */
12476 if (CHARPOS (start_pos) - IT_CHARPOS (it)
12477 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
12479 int min_distance, distance;
12481 /* Move forward by display lines to find the new window
12482 start. If window width was enlarged, the new start can
12483 be expected to be > the old start. If window width was
12484 decreased, the new window start will be < the old start.
12485 So, we're looking for the display line start with the
12486 minimum distance from the old window start. */
12487 pos = it.current.pos;
12488 min_distance = INFINITY;
12489 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
12490 distance < min_distance)
12492 min_distance = distance;
12493 pos = it.current.pos;
12494 move_it_by_lines (&it, 1, 0);
12497 /* Set the window start there. */
12498 SET_MARKER_FROM_TEXT_POS (w->start, pos);
12499 window_start_changed_p = 1;
12503 return window_start_changed_p;
12507 /* Try cursor movement in case text has not changed in window WINDOW,
12508 with window start STARTP. Value is
12510 CURSOR_MOVEMENT_SUCCESS if successful
12512 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
12514 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
12515 display. *SCROLL_STEP is set to 1, under certain circumstances, if
12516 we want to scroll as if scroll-step were set to 1. See the code.
12518 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
12519 which case we have to abort this redisplay, and adjust matrices
12520 first. */
12522 enum
12524 CURSOR_MOVEMENT_SUCCESS,
12525 CURSOR_MOVEMENT_CANNOT_BE_USED,
12526 CURSOR_MOVEMENT_MUST_SCROLL,
12527 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
12530 static int
12531 try_cursor_movement (window, startp, scroll_step)
12532 Lisp_Object window;
12533 struct text_pos startp;
12534 int *scroll_step;
12536 struct window *w = XWINDOW (window);
12537 struct frame *f = XFRAME (w->frame);
12538 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
12540 #if GLYPH_DEBUG
12541 if (inhibit_try_cursor_movement)
12542 return rc;
12543 #endif
12545 /* Handle case where text has not changed, only point, and it has
12546 not moved off the frame. */
12547 if (/* Point may be in this window. */
12548 PT >= CHARPOS (startp)
12549 /* Selective display hasn't changed. */
12550 && !current_buffer->clip_changed
12551 /* Function force-mode-line-update is used to force a thorough
12552 redisplay. It sets either windows_or_buffers_changed or
12553 update_mode_lines. So don't take a shortcut here for these
12554 cases. */
12555 && !update_mode_lines
12556 && !windows_or_buffers_changed
12557 && !cursor_type_changed
12558 /* Can't use this case if highlighting a region. When a
12559 region exists, cursor movement has to do more than just
12560 set the cursor. */
12561 && !(!NILP (Vtransient_mark_mode)
12562 && !NILP (current_buffer->mark_active))
12563 && NILP (w->region_showing)
12564 && NILP (Vshow_trailing_whitespace)
12565 /* Right after splitting windows, last_point may be nil. */
12566 && INTEGERP (w->last_point)
12567 /* This code is not used for mini-buffer for the sake of the case
12568 of redisplaying to replace an echo area message; since in
12569 that case the mini-buffer contents per se are usually
12570 unchanged. This code is of no real use in the mini-buffer
12571 since the handling of this_line_start_pos, etc., in redisplay
12572 handles the same cases. */
12573 && !EQ (window, minibuf_window)
12574 /* When splitting windows or for new windows, it happens that
12575 redisplay is called with a nil window_end_vpos or one being
12576 larger than the window. This should really be fixed in
12577 window.c. I don't have this on my list, now, so we do
12578 approximately the same as the old redisplay code. --gerd. */
12579 && INTEGERP (w->window_end_vpos)
12580 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
12581 && (FRAME_WINDOW_P (f)
12582 || !overlay_arrow_in_current_buffer_p ()))
12584 int this_scroll_margin, top_scroll_margin;
12585 struct glyph_row *row = NULL;
12587 #if GLYPH_DEBUG
12588 debug_method_add (w, "cursor movement");
12589 #endif
12591 /* Scroll if point within this distance from the top or bottom
12592 of the window. This is a pixel value. */
12593 this_scroll_margin = max (0, scroll_margin);
12594 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
12595 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
12597 top_scroll_margin = this_scroll_margin;
12598 if (WINDOW_WANTS_HEADER_LINE_P (w))
12599 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
12601 /* Start with the row the cursor was displayed during the last
12602 not paused redisplay. Give up if that row is not valid. */
12603 if (w->last_cursor.vpos < 0
12604 || w->last_cursor.vpos >= w->current_matrix->nrows)
12605 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12606 else
12608 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
12609 if (row->mode_line_p)
12610 ++row;
12611 if (!row->enabled_p)
12612 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12615 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
12617 int scroll_p = 0;
12618 int last_y = window_text_bottom_y (w) - this_scroll_margin;
12620 if (PT > XFASTINT (w->last_point))
12622 /* Point has moved forward. */
12623 while (MATRIX_ROW_END_CHARPOS (row) < PT
12624 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
12626 xassert (row->enabled_p);
12627 ++row;
12630 /* The end position of a row equals the start position
12631 of the next row. If PT is there, we would rather
12632 display it in the next line. */
12633 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
12634 && MATRIX_ROW_END_CHARPOS (row) == PT
12635 && !cursor_row_p (w, row))
12636 ++row;
12638 /* If within the scroll margin, scroll. Note that
12639 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
12640 the next line would be drawn, and that
12641 this_scroll_margin can be zero. */
12642 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
12643 || PT > MATRIX_ROW_END_CHARPOS (row)
12644 /* Line is completely visible last line in window
12645 and PT is to be set in the next line. */
12646 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
12647 && PT == MATRIX_ROW_END_CHARPOS (row)
12648 && !row->ends_at_zv_p
12649 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
12650 scroll_p = 1;
12652 else if (PT < XFASTINT (w->last_point))
12654 /* Cursor has to be moved backward. Note that PT >=
12655 CHARPOS (startp) because of the outer if-statement. */
12656 while (!row->mode_line_p
12657 && (MATRIX_ROW_START_CHARPOS (row) > PT
12658 || (MATRIX_ROW_START_CHARPOS (row) == PT
12659 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
12660 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
12661 row > w->current_matrix->rows
12662 && (row-1)->ends_in_newline_from_string_p))))
12663 && (row->y > top_scroll_margin
12664 || CHARPOS (startp) == BEGV))
12666 xassert (row->enabled_p);
12667 --row;
12670 /* Consider the following case: Window starts at BEGV,
12671 there is invisible, intangible text at BEGV, so that
12672 display starts at some point START > BEGV. It can
12673 happen that we are called with PT somewhere between
12674 BEGV and START. Try to handle that case. */
12675 if (row < w->current_matrix->rows
12676 || row->mode_line_p)
12678 row = w->current_matrix->rows;
12679 if (row->mode_line_p)
12680 ++row;
12683 /* Due to newlines in overlay strings, we may have to
12684 skip forward over overlay strings. */
12685 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
12686 && MATRIX_ROW_END_CHARPOS (row) == PT
12687 && !cursor_row_p (w, row))
12688 ++row;
12690 /* If within the scroll margin, scroll. */
12691 if (row->y < top_scroll_margin
12692 && CHARPOS (startp) != BEGV)
12693 scroll_p = 1;
12695 else
12697 /* Cursor did not move. So don't scroll even if cursor line
12698 is partially visible, as it was so before. */
12699 rc = CURSOR_MOVEMENT_SUCCESS;
12702 if (PT < MATRIX_ROW_START_CHARPOS (row)
12703 || PT > MATRIX_ROW_END_CHARPOS (row))
12705 /* if PT is not in the glyph row, give up. */
12706 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12708 else if (rc != CURSOR_MOVEMENT_SUCCESS
12709 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
12710 && make_cursor_line_fully_visible_p)
12712 if (PT == MATRIX_ROW_END_CHARPOS (row)
12713 && !row->ends_at_zv_p
12714 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
12715 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12716 else if (row->height > window_box_height (w))
12718 /* If we end up in a partially visible line, let's
12719 make it fully visible, except when it's taller
12720 than the window, in which case we can't do much
12721 about it. */
12722 *scroll_step = 1;
12723 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12725 else
12727 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
12728 if (!cursor_row_fully_visible_p (w, 0, 1))
12729 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12730 else
12731 rc = CURSOR_MOVEMENT_SUCCESS;
12734 else if (scroll_p)
12735 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12736 else
12740 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
12742 rc = CURSOR_MOVEMENT_SUCCESS;
12743 break;
12745 ++row;
12747 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
12748 && MATRIX_ROW_START_CHARPOS (row) == PT
12749 && cursor_row_p (w, row));
12754 return rc;
12757 void
12758 set_vertical_scroll_bar (w)
12759 struct window *w;
12761 int start, end, whole;
12763 /* Calculate the start and end positions for the current window.
12764 At some point, it would be nice to choose between scrollbars
12765 which reflect the whole buffer size, with special markers
12766 indicating narrowing, and scrollbars which reflect only the
12767 visible region.
12769 Note that mini-buffers sometimes aren't displaying any text. */
12770 if (!MINI_WINDOW_P (w)
12771 || (w == XWINDOW (minibuf_window)
12772 && NILP (echo_area_buffer[0])))
12774 struct buffer *buf = XBUFFER (w->buffer);
12775 whole = BUF_ZV (buf) - BUF_BEGV (buf);
12776 start = marker_position (w->start) - BUF_BEGV (buf);
12777 /* I don't think this is guaranteed to be right. For the
12778 moment, we'll pretend it is. */
12779 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
12781 if (end < start)
12782 end = start;
12783 if (whole < (end - start))
12784 whole = end - start;
12786 else
12787 start = end = whole = 0;
12789 /* Indicate what this scroll bar ought to be displaying now. */
12790 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
12791 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
12792 (w, end - start, whole, start);
12796 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
12797 selected_window is redisplayed.
12799 We can return without actually redisplaying the window if
12800 fonts_changed_p is nonzero. In that case, redisplay_internal will
12801 retry. */
12803 static void
12804 redisplay_window (window, just_this_one_p)
12805 Lisp_Object window;
12806 int just_this_one_p;
12808 struct window *w = XWINDOW (window);
12809 struct frame *f = XFRAME (w->frame);
12810 struct buffer *buffer = XBUFFER (w->buffer);
12811 struct buffer *old = current_buffer;
12812 struct text_pos lpoint, opoint, startp;
12813 int update_mode_line;
12814 int tem;
12815 struct it it;
12816 /* Record it now because it's overwritten. */
12817 int current_matrix_up_to_date_p = 0;
12818 int used_current_matrix_p = 0;
12819 /* This is less strict than current_matrix_up_to_date_p.
12820 It indictes that the buffer contents and narrowing are unchanged. */
12821 int buffer_unchanged_p = 0;
12822 int temp_scroll_step = 0;
12823 int count = SPECPDL_INDEX ();
12824 int rc;
12825 int centering_position = -1;
12826 int last_line_misfit = 0;
12827 int beg_unchanged, end_unchanged;
12829 SET_TEXT_POS (lpoint, PT, PT_BYTE);
12830 opoint = lpoint;
12832 /* W must be a leaf window here. */
12833 xassert (!NILP (w->buffer));
12834 #if GLYPH_DEBUG
12835 *w->desired_matrix->method = 0;
12836 #endif
12838 specbind (Qinhibit_point_motion_hooks, Qt);
12840 reconsider_clip_changes (w, buffer);
12842 /* Has the mode line to be updated? */
12843 update_mode_line = (!NILP (w->update_mode_line)
12844 || update_mode_lines
12845 || buffer->clip_changed
12846 || buffer->prevent_redisplay_optimizations_p);
12848 if (MINI_WINDOW_P (w))
12850 if (w == XWINDOW (echo_area_window)
12851 && !NILP (echo_area_buffer[0]))
12853 if (update_mode_line)
12854 /* We may have to update a tty frame's menu bar or a
12855 tool-bar. Example `M-x C-h C-h C-g'. */
12856 goto finish_menu_bars;
12857 else
12858 /* We've already displayed the echo area glyphs in this window. */
12859 goto finish_scroll_bars;
12861 else if ((w != XWINDOW (minibuf_window)
12862 || minibuf_level == 0)
12863 /* When buffer is nonempty, redisplay window normally. */
12864 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
12865 /* Quail displays non-mini buffers in minibuffer window.
12866 In that case, redisplay the window normally. */
12867 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
12869 /* W is a mini-buffer window, but it's not active, so clear
12870 it. */
12871 int yb = window_text_bottom_y (w);
12872 struct glyph_row *row;
12873 int y;
12875 for (y = 0, row = w->desired_matrix->rows;
12876 y < yb;
12877 y += row->height, ++row)
12878 blank_row (w, row, y);
12879 goto finish_scroll_bars;
12882 clear_glyph_matrix (w->desired_matrix);
12885 /* Otherwise set up data on this window; select its buffer and point
12886 value. */
12887 /* Really select the buffer, for the sake of buffer-local
12888 variables. */
12889 set_buffer_internal_1 (XBUFFER (w->buffer));
12890 SET_TEXT_POS (opoint, PT, PT_BYTE);
12892 beg_unchanged = BEG_UNCHANGED;
12893 end_unchanged = END_UNCHANGED;
12895 current_matrix_up_to_date_p
12896 = (!NILP (w->window_end_valid)
12897 && !current_buffer->clip_changed
12898 && !current_buffer->prevent_redisplay_optimizations_p
12899 && XFASTINT (w->last_modified) >= MODIFF
12900 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
12902 buffer_unchanged_p
12903 = (!NILP (w->window_end_valid)
12904 && !current_buffer->clip_changed
12905 && XFASTINT (w->last_modified) >= MODIFF
12906 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
12908 /* When windows_or_buffers_changed is non-zero, we can't rely on
12909 the window end being valid, so set it to nil there. */
12910 if (windows_or_buffers_changed)
12912 /* If window starts on a continuation line, maybe adjust the
12913 window start in case the window's width changed. */
12914 if (XMARKER (w->start)->buffer == current_buffer)
12915 compute_window_start_on_continuation_line (w);
12917 w->window_end_valid = Qnil;
12920 /* Some sanity checks. */
12921 CHECK_WINDOW_END (w);
12922 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
12923 abort ();
12924 if (BYTEPOS (opoint) < CHARPOS (opoint))
12925 abort ();
12927 /* If %c is in mode line, update it if needed. */
12928 if (!NILP (w->column_number_displayed)
12929 /* This alternative quickly identifies a common case
12930 where no change is needed. */
12931 && !(PT == XFASTINT (w->last_point)
12932 && XFASTINT (w->last_modified) >= MODIFF
12933 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
12934 && (XFASTINT (w->column_number_displayed)
12935 != (int) current_column ())) /* iftc */
12936 update_mode_line = 1;
12938 /* Count number of windows showing the selected buffer. An indirect
12939 buffer counts as its base buffer. */
12940 if (!just_this_one_p)
12942 struct buffer *current_base, *window_base;
12943 current_base = current_buffer;
12944 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
12945 if (current_base->base_buffer)
12946 current_base = current_base->base_buffer;
12947 if (window_base->base_buffer)
12948 window_base = window_base->base_buffer;
12949 if (current_base == window_base)
12950 buffer_shared++;
12953 /* Point refers normally to the selected window. For any other
12954 window, set up appropriate value. */
12955 if (!EQ (window, selected_window))
12957 int new_pt = XMARKER (w->pointm)->charpos;
12958 int new_pt_byte = marker_byte_position (w->pointm);
12959 if (new_pt < BEGV)
12961 new_pt = BEGV;
12962 new_pt_byte = BEGV_BYTE;
12963 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
12965 else if (new_pt > (ZV - 1))
12967 new_pt = ZV;
12968 new_pt_byte = ZV_BYTE;
12969 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
12972 /* We don't use SET_PT so that the point-motion hooks don't run. */
12973 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
12976 /* If any of the character widths specified in the display table
12977 have changed, invalidate the width run cache. It's true that
12978 this may be a bit late to catch such changes, but the rest of
12979 redisplay goes (non-fatally) haywire when the display table is
12980 changed, so why should we worry about doing any better? */
12981 if (current_buffer->width_run_cache)
12983 struct Lisp_Char_Table *disptab = buffer_display_table ();
12985 if (! disptab_matches_widthtab (disptab,
12986 XVECTOR (current_buffer->width_table)))
12988 invalidate_region_cache (current_buffer,
12989 current_buffer->width_run_cache,
12990 BEG, Z);
12991 recompute_width_table (current_buffer, disptab);
12995 /* If window-start is screwed up, choose a new one. */
12996 if (XMARKER (w->start)->buffer != current_buffer)
12997 goto recenter;
12999 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13001 /* If someone specified a new starting point but did not insist,
13002 check whether it can be used. */
13003 if (!NILP (w->optional_new_start)
13004 && CHARPOS (startp) >= BEGV
13005 && CHARPOS (startp) <= ZV)
13007 w->optional_new_start = Qnil;
13008 start_display (&it, w, startp);
13009 move_it_to (&it, PT, 0, it.last_visible_y, -1,
13010 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
13011 if (IT_CHARPOS (it) == PT)
13012 w->force_start = Qt;
13013 /* IT may overshoot PT if text at PT is invisible. */
13014 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
13015 w->force_start = Qt;
13018 force_start:
13020 /* Handle case where place to start displaying has been specified,
13021 unless the specified location is outside the accessible range. */
13022 if (!NILP (w->force_start)
13023 || w->frozen_window_start_p)
13025 /* We set this later on if we have to adjust point. */
13026 int new_vpos = -1;
13027 int val;
13029 w->force_start = Qnil;
13030 w->vscroll = 0;
13031 w->window_end_valid = Qnil;
13033 /* Forget any recorded base line for line number display. */
13034 if (!buffer_unchanged_p)
13035 w->base_line_number = Qnil;
13037 /* Redisplay the mode line. Select the buffer properly for that.
13038 Also, run the hook window-scroll-functions
13039 because we have scrolled. */
13040 /* Note, we do this after clearing force_start because
13041 if there's an error, it is better to forget about force_start
13042 than to get into an infinite loop calling the hook functions
13043 and having them get more errors. */
13044 if (!update_mode_line
13045 || ! NILP (Vwindow_scroll_functions))
13047 update_mode_line = 1;
13048 w->update_mode_line = Qt;
13049 startp = run_window_scroll_functions (window, startp);
13052 w->last_modified = make_number (0);
13053 w->last_overlay_modified = make_number (0);
13054 if (CHARPOS (startp) < BEGV)
13055 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
13056 else if (CHARPOS (startp) > ZV)
13057 SET_TEXT_POS (startp, ZV, ZV_BYTE);
13059 /* Redisplay, then check if cursor has been set during the
13060 redisplay. Give up if new fonts were loaded. */
13061 val = try_window (window, startp, 1);
13062 if (!val)
13064 w->force_start = Qt;
13065 clear_glyph_matrix (w->desired_matrix);
13066 goto need_larger_matrices;
13068 /* Point was outside the scroll margins. */
13069 if (val < 0)
13070 new_vpos = window_box_height (w) / 2;
13072 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
13074 /* If point does not appear, try to move point so it does
13075 appear. The desired matrix has been built above, so we
13076 can use it here. */
13077 new_vpos = window_box_height (w) / 2;
13080 if (!cursor_row_fully_visible_p (w, 0, 0))
13082 /* Point does appear, but on a line partly visible at end of window.
13083 Move it back to a fully-visible line. */
13084 new_vpos = window_box_height (w);
13087 /* If we need to move point for either of the above reasons,
13088 now actually do it. */
13089 if (new_vpos >= 0)
13091 struct glyph_row *row;
13093 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
13094 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
13095 ++row;
13097 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
13098 MATRIX_ROW_START_BYTEPOS (row));
13100 if (w != XWINDOW (selected_window))
13101 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
13102 else if (current_buffer == old)
13103 SET_TEXT_POS (lpoint, PT, PT_BYTE);
13105 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
13107 /* If we are highlighting the region, then we just changed
13108 the region, so redisplay to show it. */
13109 if (!NILP (Vtransient_mark_mode)
13110 && !NILP (current_buffer->mark_active))
13112 clear_glyph_matrix (w->desired_matrix);
13113 if (!try_window (window, startp, 0))
13114 goto need_larger_matrices;
13118 #if GLYPH_DEBUG
13119 debug_method_add (w, "forced window start");
13120 #endif
13121 goto done;
13124 /* Handle case where text has not changed, only point, and it has
13125 not moved off the frame, and we are not retrying after hscroll.
13126 (current_matrix_up_to_date_p is nonzero when retrying.) */
13127 if (current_matrix_up_to_date_p
13128 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
13129 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
13131 switch (rc)
13133 case CURSOR_MOVEMENT_SUCCESS:
13134 used_current_matrix_p = 1;
13135 goto done;
13137 #if 0 /* try_cursor_movement never returns this value. */
13138 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES:
13139 goto need_larger_matrices;
13140 #endif
13142 case CURSOR_MOVEMENT_MUST_SCROLL:
13143 goto try_to_scroll;
13145 default:
13146 abort ();
13149 /* If current starting point was originally the beginning of a line
13150 but no longer is, find a new starting point. */
13151 else if (!NILP (w->start_at_line_beg)
13152 && !(CHARPOS (startp) <= BEGV
13153 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
13155 #if GLYPH_DEBUG
13156 debug_method_add (w, "recenter 1");
13157 #endif
13158 goto recenter;
13161 /* Try scrolling with try_window_id. Value is > 0 if update has
13162 been done, it is -1 if we know that the same window start will
13163 not work. It is 0 if unsuccessful for some other reason. */
13164 else if ((tem = try_window_id (w)) != 0)
13166 #if GLYPH_DEBUG
13167 debug_method_add (w, "try_window_id %d", tem);
13168 #endif
13170 if (fonts_changed_p)
13171 goto need_larger_matrices;
13172 if (tem > 0)
13173 goto done;
13175 /* Otherwise try_window_id has returned -1 which means that we
13176 don't want the alternative below this comment to execute. */
13178 else if (CHARPOS (startp) >= BEGV
13179 && CHARPOS (startp) <= ZV
13180 && PT >= CHARPOS (startp)
13181 && (CHARPOS (startp) < ZV
13182 /* Avoid starting at end of buffer. */
13183 || CHARPOS (startp) == BEGV
13184 || (XFASTINT (w->last_modified) >= MODIFF
13185 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
13188 /* If first window line is a continuation line, and window start
13189 is inside the modified region, but the first change is before
13190 current window start, we must select a new window start.
13192 However, if this is the result of a down-mouse event (e.g. by
13193 extending the mouse-drag-overlay), we don't want to select a
13194 new window start, since that would change the position under
13195 the mouse, resulting in an unwanted mouse-movement rather
13196 than a simple mouse-click. */
13197 if (NILP (w->start_at_line_beg)
13198 && NILP (do_mouse_tracking)
13199 && CHARPOS (startp) > BEGV
13200 && CHARPOS (startp) > BEG + beg_unchanged
13201 && CHARPOS (startp) <= Z - end_unchanged)
13203 w->force_start = Qt;
13204 if (XMARKER (w->start)->buffer == current_buffer)
13205 compute_window_start_on_continuation_line (w);
13206 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13207 goto force_start;
13210 #if GLYPH_DEBUG
13211 debug_method_add (w, "same window start");
13212 #endif
13214 /* Try to redisplay starting at same place as before.
13215 If point has not moved off frame, accept the results. */
13216 if (!current_matrix_up_to_date_p
13217 /* Don't use try_window_reusing_current_matrix in this case
13218 because a window scroll function can have changed the
13219 buffer. */
13220 || !NILP (Vwindow_scroll_functions)
13221 || MINI_WINDOW_P (w)
13222 || !(used_current_matrix_p
13223 = try_window_reusing_current_matrix (w)))
13225 IF_DEBUG (debug_method_add (w, "1"));
13226 if (try_window (window, startp, 1) < 0)
13227 /* -1 means we need to scroll.
13228 0 means we need new matrices, but fonts_changed_p
13229 is set in that case, so we will detect it below. */
13230 goto try_to_scroll;
13233 if (fonts_changed_p)
13234 goto need_larger_matrices;
13236 if (w->cursor.vpos >= 0)
13238 if (!just_this_one_p
13239 || current_buffer->clip_changed
13240 || BEG_UNCHANGED < CHARPOS (startp))
13241 /* Forget any recorded base line for line number display. */
13242 w->base_line_number = Qnil;
13244 if (!cursor_row_fully_visible_p (w, 1, 0))
13246 clear_glyph_matrix (w->desired_matrix);
13247 last_line_misfit = 1;
13249 /* Drop through and scroll. */
13250 else
13251 goto done;
13253 else
13254 clear_glyph_matrix (w->desired_matrix);
13257 try_to_scroll:
13259 w->last_modified = make_number (0);
13260 w->last_overlay_modified = make_number (0);
13262 /* Redisplay the mode line. Select the buffer properly for that. */
13263 if (!update_mode_line)
13265 update_mode_line = 1;
13266 w->update_mode_line = Qt;
13269 /* Try to scroll by specified few lines. */
13270 if ((scroll_conservatively
13271 || scroll_step
13272 || temp_scroll_step
13273 || NUMBERP (current_buffer->scroll_up_aggressively)
13274 || NUMBERP (current_buffer->scroll_down_aggressively))
13275 && !current_buffer->clip_changed
13276 && CHARPOS (startp) >= BEGV
13277 && CHARPOS (startp) <= ZV)
13279 /* The function returns -1 if new fonts were loaded, 1 if
13280 successful, 0 if not successful. */
13281 int rc = try_scrolling (window, just_this_one_p,
13282 scroll_conservatively,
13283 scroll_step,
13284 temp_scroll_step, last_line_misfit);
13285 switch (rc)
13287 case SCROLLING_SUCCESS:
13288 goto done;
13290 case SCROLLING_NEED_LARGER_MATRICES:
13291 goto need_larger_matrices;
13293 case SCROLLING_FAILED:
13294 break;
13296 default:
13297 abort ();
13301 /* Finally, just choose place to start which centers point */
13303 recenter:
13304 if (centering_position < 0)
13305 centering_position = window_box_height (w) / 2;
13307 #if GLYPH_DEBUG
13308 debug_method_add (w, "recenter");
13309 #endif
13311 /* w->vscroll = 0; */
13313 /* Forget any previously recorded base line for line number display. */
13314 if (!buffer_unchanged_p)
13315 w->base_line_number = Qnil;
13317 /* Move backward half the height of the window. */
13318 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
13319 it.current_y = it.last_visible_y;
13320 move_it_vertically_backward (&it, centering_position);
13321 xassert (IT_CHARPOS (it) >= BEGV);
13323 /* The function move_it_vertically_backward may move over more
13324 than the specified y-distance. If it->w is small, e.g. a
13325 mini-buffer window, we may end up in front of the window's
13326 display area. Start displaying at the start of the line
13327 containing PT in this case. */
13328 if (it.current_y <= 0)
13330 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
13331 move_it_vertically_backward (&it, 0);
13332 #if 0
13333 /* I think this assert is bogus if buffer contains
13334 invisible text or images. KFS. */
13335 xassert (IT_CHARPOS (it) <= PT);
13336 #endif
13337 it.current_y = 0;
13340 it.current_x = it.hpos = 0;
13342 /* Set startp here explicitly in case that helps avoid an infinite loop
13343 in case the window-scroll-functions functions get errors. */
13344 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
13346 /* Run scroll hooks. */
13347 startp = run_window_scroll_functions (window, it.current.pos);
13349 /* Redisplay the window. */
13350 if (!current_matrix_up_to_date_p
13351 || windows_or_buffers_changed
13352 || cursor_type_changed
13353 /* Don't use try_window_reusing_current_matrix in this case
13354 because it can have changed the buffer. */
13355 || !NILP (Vwindow_scroll_functions)
13356 || !just_this_one_p
13357 || MINI_WINDOW_P (w)
13358 || !(used_current_matrix_p
13359 = try_window_reusing_current_matrix (w)))
13360 try_window (window, startp, 0);
13362 /* If new fonts have been loaded (due to fontsets), give up. We
13363 have to start a new redisplay since we need to re-adjust glyph
13364 matrices. */
13365 if (fonts_changed_p)
13366 goto need_larger_matrices;
13368 /* If cursor did not appear assume that the middle of the window is
13369 in the first line of the window. Do it again with the next line.
13370 (Imagine a window of height 100, displaying two lines of height
13371 60. Moving back 50 from it->last_visible_y will end in the first
13372 line.) */
13373 if (w->cursor.vpos < 0)
13375 if (!NILP (w->window_end_valid)
13376 && PT >= Z - XFASTINT (w->window_end_pos))
13378 clear_glyph_matrix (w->desired_matrix);
13379 move_it_by_lines (&it, 1, 0);
13380 try_window (window, it.current.pos, 0);
13382 else if (PT < IT_CHARPOS (it))
13384 clear_glyph_matrix (w->desired_matrix);
13385 move_it_by_lines (&it, -1, 0);
13386 try_window (window, it.current.pos, 0);
13388 else
13390 /* Not much we can do about it. */
13394 /* Consider the following case: Window starts at BEGV, there is
13395 invisible, intangible text at BEGV, so that display starts at
13396 some point START > BEGV. It can happen that we are called with
13397 PT somewhere between BEGV and START. Try to handle that case. */
13398 if (w->cursor.vpos < 0)
13400 struct glyph_row *row = w->current_matrix->rows;
13401 if (row->mode_line_p)
13402 ++row;
13403 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13406 if (!cursor_row_fully_visible_p (w, 0, 0))
13408 /* If vscroll is enabled, disable it and try again. */
13409 if (w->vscroll)
13411 w->vscroll = 0;
13412 clear_glyph_matrix (w->desired_matrix);
13413 goto recenter;
13416 /* If centering point failed to make the whole line visible,
13417 put point at the top instead. That has to make the whole line
13418 visible, if it can be done. */
13419 if (centering_position == 0)
13420 goto done;
13422 clear_glyph_matrix (w->desired_matrix);
13423 centering_position = 0;
13424 goto recenter;
13427 done:
13429 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13430 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
13431 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
13432 ? Qt : Qnil);
13434 /* Display the mode line, if we must. */
13435 if ((update_mode_line
13436 /* If window not full width, must redo its mode line
13437 if (a) the window to its side is being redone and
13438 (b) we do a frame-based redisplay. This is a consequence
13439 of how inverted lines are drawn in frame-based redisplay. */
13440 || (!just_this_one_p
13441 && !FRAME_WINDOW_P (f)
13442 && !WINDOW_FULL_WIDTH_P (w))
13443 /* Line number to display. */
13444 || INTEGERP (w->base_line_pos)
13445 /* Column number is displayed and different from the one displayed. */
13446 || (!NILP (w->column_number_displayed)
13447 && (XFASTINT (w->column_number_displayed)
13448 != (int) current_column ()))) /* iftc */
13449 /* This means that the window has a mode line. */
13450 && (WINDOW_WANTS_MODELINE_P (w)
13451 || WINDOW_WANTS_HEADER_LINE_P (w)))
13453 display_mode_lines (w);
13455 /* If mode line height has changed, arrange for a thorough
13456 immediate redisplay using the correct mode line height. */
13457 if (WINDOW_WANTS_MODELINE_P (w)
13458 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
13460 fonts_changed_p = 1;
13461 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
13462 = DESIRED_MODE_LINE_HEIGHT (w);
13465 /* If top line height has changed, arrange for a thorough
13466 immediate redisplay using the correct mode line height. */
13467 if (WINDOW_WANTS_HEADER_LINE_P (w)
13468 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
13470 fonts_changed_p = 1;
13471 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
13472 = DESIRED_HEADER_LINE_HEIGHT (w);
13475 if (fonts_changed_p)
13476 goto need_larger_matrices;
13479 if (!line_number_displayed
13480 && !BUFFERP (w->base_line_pos))
13482 w->base_line_pos = Qnil;
13483 w->base_line_number = Qnil;
13486 finish_menu_bars:
13488 /* When we reach a frame's selected window, redo the frame's menu bar. */
13489 if (update_mode_line
13490 && EQ (FRAME_SELECTED_WINDOW (f), window))
13492 int redisplay_menu_p = 0;
13493 int redisplay_tool_bar_p = 0;
13495 if (FRAME_WINDOW_P (f))
13497 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
13498 || defined (USE_GTK)
13499 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
13500 #else
13501 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
13502 #endif
13504 else
13505 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
13507 if (redisplay_menu_p)
13508 display_menu_bar (w);
13510 #ifdef HAVE_WINDOW_SYSTEM
13511 if (FRAME_WINDOW_P (f))
13513 #if defined (USE_GTK) || USE_MAC_TOOLBAR
13514 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
13515 #else
13516 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
13517 && (FRAME_TOOL_BAR_LINES (f) > 0
13518 || !NILP (Vauto_resize_tool_bars));
13519 #endif
13521 if (redisplay_tool_bar_p && redisplay_tool_bar (f))
13523 extern int ignore_mouse_drag_p;
13524 ignore_mouse_drag_p = 1;
13527 #endif
13530 #ifdef HAVE_WINDOW_SYSTEM
13531 if (FRAME_WINDOW_P (f)
13532 && update_window_fringes (w, (just_this_one_p
13533 || (!used_current_matrix_p && !overlay_arrow_seen)
13534 || w->pseudo_window_p)))
13536 update_begin (f);
13537 BLOCK_INPUT;
13538 if (draw_window_fringes (w, 1))
13539 x_draw_vertical_border (w);
13540 UNBLOCK_INPUT;
13541 update_end (f);
13543 #endif /* HAVE_WINDOW_SYSTEM */
13545 /* We go to this label, with fonts_changed_p nonzero,
13546 if it is necessary to try again using larger glyph matrices.
13547 We have to redeem the scroll bar even in this case,
13548 because the loop in redisplay_internal expects that. */
13549 need_larger_matrices:
13551 finish_scroll_bars:
13553 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
13555 /* Set the thumb's position and size. */
13556 set_vertical_scroll_bar (w);
13558 /* Note that we actually used the scroll bar attached to this
13559 window, so it shouldn't be deleted at the end of redisplay. */
13560 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
13561 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
13564 /* Restore current_buffer and value of point in it. */
13565 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
13566 set_buffer_internal_1 (old);
13567 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
13568 shorter. This can be caused by log truncation in *Messages*. */
13569 if (CHARPOS (lpoint) <= ZV)
13570 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
13572 unbind_to (count, Qnil);
13576 /* Build the complete desired matrix of WINDOW with a window start
13577 buffer position POS.
13579 Value is 1 if successful. It is zero if fonts were loaded during
13580 redisplay which makes re-adjusting glyph matrices necessary, and -1
13581 if point would appear in the scroll margins.
13582 (We check that only if CHECK_MARGINS is nonzero. */
13585 try_window (window, pos, check_margins)
13586 Lisp_Object window;
13587 struct text_pos pos;
13588 int check_margins;
13590 struct window *w = XWINDOW (window);
13591 struct it it;
13592 struct glyph_row *last_text_row = NULL;
13593 struct frame *f = XFRAME (w->frame);
13595 /* Make POS the new window start. */
13596 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
13598 /* Mark cursor position as unknown. No overlay arrow seen. */
13599 w->cursor.vpos = -1;
13600 overlay_arrow_seen = 0;
13602 /* Initialize iterator and info to start at POS. */
13603 start_display (&it, w, pos);
13605 /* Display all lines of W. */
13606 while (it.current_y < it.last_visible_y)
13608 if (display_line (&it))
13609 last_text_row = it.glyph_row - 1;
13610 if (fonts_changed_p)
13611 return 0;
13614 /* Don't let the cursor end in the scroll margins. */
13615 if (check_margins
13616 && !MINI_WINDOW_P (w))
13618 int this_scroll_margin;
13620 this_scroll_margin = max (0, scroll_margin);
13621 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13622 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
13624 if ((w->cursor.y >= 0 /* not vscrolled */
13625 && w->cursor.y < this_scroll_margin
13626 && CHARPOS (pos) > BEGV
13627 && IT_CHARPOS (it) < ZV)
13628 /* rms: considering make_cursor_line_fully_visible_p here
13629 seems to give wrong results. We don't want to recenter
13630 when the last line is partly visible, we want to allow
13631 that case to be handled in the usual way. */
13632 || (w->cursor.y + 1) > it.last_visible_y)
13634 w->cursor.vpos = -1;
13635 clear_glyph_matrix (w->desired_matrix);
13636 return -1;
13640 /* If bottom moved off end of frame, change mode line percentage. */
13641 if (XFASTINT (w->window_end_pos) <= 0
13642 && Z != IT_CHARPOS (it))
13643 w->update_mode_line = Qt;
13645 /* Set window_end_pos to the offset of the last character displayed
13646 on the window from the end of current_buffer. Set
13647 window_end_vpos to its row number. */
13648 if (last_text_row)
13650 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
13651 w->window_end_bytepos
13652 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13653 w->window_end_pos
13654 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13655 w->window_end_vpos
13656 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
13657 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
13658 ->displays_text_p);
13660 else
13662 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
13663 w->window_end_pos = make_number (Z - ZV);
13664 w->window_end_vpos = make_number (0);
13667 /* But that is not valid info until redisplay finishes. */
13668 w->window_end_valid = Qnil;
13669 return 1;
13674 /************************************************************************
13675 Window redisplay reusing current matrix when buffer has not changed
13676 ************************************************************************/
13678 /* Try redisplay of window W showing an unchanged buffer with a
13679 different window start than the last time it was displayed by
13680 reusing its current matrix. Value is non-zero if successful.
13681 W->start is the new window start. */
13683 static int
13684 try_window_reusing_current_matrix (w)
13685 struct window *w;
13687 struct frame *f = XFRAME (w->frame);
13688 struct glyph_row *row, *bottom_row;
13689 struct it it;
13690 struct run run;
13691 struct text_pos start, new_start;
13692 int nrows_scrolled, i;
13693 struct glyph_row *last_text_row;
13694 struct glyph_row *last_reused_text_row;
13695 struct glyph_row *start_row;
13696 int start_vpos, min_y, max_y;
13698 #if GLYPH_DEBUG
13699 if (inhibit_try_window_reusing)
13700 return 0;
13701 #endif
13703 if (/* This function doesn't handle terminal frames. */
13704 !FRAME_WINDOW_P (f)
13705 /* Don't try to reuse the display if windows have been split
13706 or such. */
13707 || windows_or_buffers_changed
13708 || cursor_type_changed)
13709 return 0;
13711 /* Can't do this if region may have changed. */
13712 if ((!NILP (Vtransient_mark_mode)
13713 && !NILP (current_buffer->mark_active))
13714 || !NILP (w->region_showing)
13715 || !NILP (Vshow_trailing_whitespace))
13716 return 0;
13718 /* If top-line visibility has changed, give up. */
13719 if (WINDOW_WANTS_HEADER_LINE_P (w)
13720 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
13721 return 0;
13723 /* Give up if old or new display is scrolled vertically. We could
13724 make this function handle this, but right now it doesn't. */
13725 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
13726 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
13727 return 0;
13729 /* The variable new_start now holds the new window start. The old
13730 start `start' can be determined from the current matrix. */
13731 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
13732 start = start_row->start.pos;
13733 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
13735 /* Clear the desired matrix for the display below. */
13736 clear_glyph_matrix (w->desired_matrix);
13738 if (CHARPOS (new_start) <= CHARPOS (start))
13740 int first_row_y;
13742 /* Don't use this method if the display starts with an ellipsis
13743 displayed for invisible text. It's not easy to handle that case
13744 below, and it's certainly not worth the effort since this is
13745 not a frequent case. */
13746 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
13747 return 0;
13749 IF_DEBUG (debug_method_add (w, "twu1"));
13751 /* Display up to a row that can be reused. The variable
13752 last_text_row is set to the last row displayed that displays
13753 text. Note that it.vpos == 0 if or if not there is a
13754 header-line; it's not the same as the MATRIX_ROW_VPOS! */
13755 start_display (&it, w, new_start);
13756 first_row_y = it.current_y;
13757 w->cursor.vpos = -1;
13758 last_text_row = last_reused_text_row = NULL;
13760 while (it.current_y < it.last_visible_y
13761 && !fonts_changed_p)
13763 /* If we have reached into the characters in the START row,
13764 that means the line boundaries have changed. So we
13765 can't start copying with the row START. Maybe it will
13766 work to start copying with the following row. */
13767 while (IT_CHARPOS (it) > CHARPOS (start))
13769 /* Advance to the next row as the "start". */
13770 start_row++;
13771 start = start_row->start.pos;
13772 /* If there are no more rows to try, or just one, give up. */
13773 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
13774 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
13775 || CHARPOS (start) == ZV)
13777 clear_glyph_matrix (w->desired_matrix);
13778 return 0;
13781 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
13783 /* If we have reached alignment,
13784 we can copy the rest of the rows. */
13785 if (IT_CHARPOS (it) == CHARPOS (start))
13786 break;
13788 if (display_line (&it))
13789 last_text_row = it.glyph_row - 1;
13792 /* A value of current_y < last_visible_y means that we stopped
13793 at the previous window start, which in turn means that we
13794 have at least one reusable row. */
13795 if (it.current_y < it.last_visible_y)
13797 /* IT.vpos always starts from 0; it counts text lines. */
13798 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
13800 /* Find PT if not already found in the lines displayed. */
13801 if (w->cursor.vpos < 0)
13803 int dy = it.current_y - start_row->y;
13805 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
13806 row = row_containing_pos (w, PT, row, NULL, dy);
13807 if (row)
13808 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
13809 dy, nrows_scrolled);
13810 else
13812 clear_glyph_matrix (w->desired_matrix);
13813 return 0;
13817 /* Scroll the display. Do it before the current matrix is
13818 changed. The problem here is that update has not yet
13819 run, i.e. part of the current matrix is not up to date.
13820 scroll_run_hook will clear the cursor, and use the
13821 current matrix to get the height of the row the cursor is
13822 in. */
13823 run.current_y = start_row->y;
13824 run.desired_y = it.current_y;
13825 run.height = it.last_visible_y - it.current_y;
13827 if (run.height > 0 && run.current_y != run.desired_y)
13829 update_begin (f);
13830 FRAME_RIF (f)->update_window_begin_hook (w);
13831 FRAME_RIF (f)->clear_window_mouse_face (w);
13832 FRAME_RIF (f)->scroll_run_hook (w, &run);
13833 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
13834 update_end (f);
13837 /* Shift current matrix down by nrows_scrolled lines. */
13838 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
13839 rotate_matrix (w->current_matrix,
13840 start_vpos,
13841 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
13842 nrows_scrolled);
13844 /* Disable lines that must be updated. */
13845 for (i = 0; i < nrows_scrolled; ++i)
13846 (start_row + i)->enabled_p = 0;
13848 /* Re-compute Y positions. */
13849 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
13850 max_y = it.last_visible_y;
13851 for (row = start_row + nrows_scrolled;
13852 row < bottom_row;
13853 ++row)
13855 row->y = it.current_y;
13856 row->visible_height = row->height;
13858 if (row->y < min_y)
13859 row->visible_height -= min_y - row->y;
13860 if (row->y + row->height > max_y)
13861 row->visible_height -= row->y + row->height - max_y;
13862 row->redraw_fringe_bitmaps_p = 1;
13864 it.current_y += row->height;
13866 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
13867 last_reused_text_row = row;
13868 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
13869 break;
13872 /* Disable lines in the current matrix which are now
13873 below the window. */
13874 for (++row; row < bottom_row; ++row)
13875 row->enabled_p = row->mode_line_p = 0;
13878 /* Update window_end_pos etc.; last_reused_text_row is the last
13879 reused row from the current matrix containing text, if any.
13880 The value of last_text_row is the last displayed line
13881 containing text. */
13882 if (last_reused_text_row)
13884 w->window_end_bytepos
13885 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
13886 w->window_end_pos
13887 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
13888 w->window_end_vpos
13889 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
13890 w->current_matrix));
13892 else if (last_text_row)
13894 w->window_end_bytepos
13895 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13896 w->window_end_pos
13897 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13898 w->window_end_vpos
13899 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
13901 else
13903 /* This window must be completely empty. */
13904 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
13905 w->window_end_pos = make_number (Z - ZV);
13906 w->window_end_vpos = make_number (0);
13908 w->window_end_valid = Qnil;
13910 /* Update hint: don't try scrolling again in update_window. */
13911 w->desired_matrix->no_scrolling_p = 1;
13913 #if GLYPH_DEBUG
13914 debug_method_add (w, "try_window_reusing_current_matrix 1");
13915 #endif
13916 return 1;
13918 else if (CHARPOS (new_start) > CHARPOS (start))
13920 struct glyph_row *pt_row, *row;
13921 struct glyph_row *first_reusable_row;
13922 struct glyph_row *first_row_to_display;
13923 int dy;
13924 int yb = window_text_bottom_y (w);
13926 /* Find the row starting at new_start, if there is one. Don't
13927 reuse a partially visible line at the end. */
13928 first_reusable_row = start_row;
13929 while (first_reusable_row->enabled_p
13930 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
13931 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
13932 < CHARPOS (new_start)))
13933 ++first_reusable_row;
13935 /* Give up if there is no row to reuse. */
13936 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
13937 || !first_reusable_row->enabled_p
13938 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
13939 != CHARPOS (new_start)))
13940 return 0;
13942 /* We can reuse fully visible rows beginning with
13943 first_reusable_row to the end of the window. Set
13944 first_row_to_display to the first row that cannot be reused.
13945 Set pt_row to the row containing point, if there is any. */
13946 pt_row = NULL;
13947 for (first_row_to_display = first_reusable_row;
13948 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
13949 ++first_row_to_display)
13951 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
13952 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
13953 pt_row = first_row_to_display;
13956 /* Start displaying at the start of first_row_to_display. */
13957 xassert (first_row_to_display->y < yb);
13958 init_to_row_start (&it, w, first_row_to_display);
13960 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
13961 - start_vpos);
13962 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
13963 - nrows_scrolled);
13964 it.current_y = (first_row_to_display->y - first_reusable_row->y
13965 + WINDOW_HEADER_LINE_HEIGHT (w));
13967 /* Display lines beginning with first_row_to_display in the
13968 desired matrix. Set last_text_row to the last row displayed
13969 that displays text. */
13970 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
13971 if (pt_row == NULL)
13972 w->cursor.vpos = -1;
13973 last_text_row = NULL;
13974 while (it.current_y < it.last_visible_y && !fonts_changed_p)
13975 if (display_line (&it))
13976 last_text_row = it.glyph_row - 1;
13978 /* Give up If point isn't in a row displayed or reused. */
13979 if (w->cursor.vpos < 0)
13981 clear_glyph_matrix (w->desired_matrix);
13982 return 0;
13985 /* If point is in a reused row, adjust y and vpos of the cursor
13986 position. */
13987 if (pt_row)
13989 w->cursor.vpos -= nrows_scrolled;
13990 w->cursor.y -= first_reusable_row->y - start_row->y;
13993 /* Scroll the display. */
13994 run.current_y = first_reusable_row->y;
13995 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
13996 run.height = it.last_visible_y - run.current_y;
13997 dy = run.current_y - run.desired_y;
13999 if (run.height)
14001 update_begin (f);
14002 FRAME_RIF (f)->update_window_begin_hook (w);
14003 FRAME_RIF (f)->clear_window_mouse_face (w);
14004 FRAME_RIF (f)->scroll_run_hook (w, &run);
14005 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
14006 update_end (f);
14009 /* Adjust Y positions of reused rows. */
14010 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
14011 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
14012 max_y = it.last_visible_y;
14013 for (row = first_reusable_row; row < first_row_to_display; ++row)
14015 row->y -= dy;
14016 row->visible_height = row->height;
14017 if (row->y < min_y)
14018 row->visible_height -= min_y - row->y;
14019 if (row->y + row->height > max_y)
14020 row->visible_height -= row->y + row->height - max_y;
14021 row->redraw_fringe_bitmaps_p = 1;
14024 /* Scroll the current matrix. */
14025 xassert (nrows_scrolled > 0);
14026 rotate_matrix (w->current_matrix,
14027 start_vpos,
14028 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
14029 -nrows_scrolled);
14031 /* Disable rows not reused. */
14032 for (row -= nrows_scrolled; row < bottom_row; ++row)
14033 row->enabled_p = 0;
14035 /* Point may have moved to a different line, so we cannot assume that
14036 the previous cursor position is valid; locate the correct row. */
14037 if (pt_row)
14039 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
14040 row < bottom_row && PT >= MATRIX_ROW_END_CHARPOS (row);
14041 row++)
14043 w->cursor.vpos++;
14044 w->cursor.y = row->y;
14046 if (row < bottom_row)
14048 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
14049 while (glyph->charpos < PT)
14051 w->cursor.hpos++;
14052 w->cursor.x += glyph->pixel_width;
14053 glyph++;
14058 /* Adjust window end. A null value of last_text_row means that
14059 the window end is in reused rows which in turn means that
14060 only its vpos can have changed. */
14061 if (last_text_row)
14063 w->window_end_bytepos
14064 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
14065 w->window_end_pos
14066 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
14067 w->window_end_vpos
14068 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
14070 else
14072 w->window_end_vpos
14073 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
14076 w->window_end_valid = Qnil;
14077 w->desired_matrix->no_scrolling_p = 1;
14079 #if GLYPH_DEBUG
14080 debug_method_add (w, "try_window_reusing_current_matrix 2");
14081 #endif
14082 return 1;
14085 return 0;
14090 /************************************************************************
14091 Window redisplay reusing current matrix when buffer has changed
14092 ************************************************************************/
14094 static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *));
14095 static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *,
14096 int *, int *));
14097 static struct glyph_row *
14098 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
14099 struct glyph_row *));
14102 /* Return the last row in MATRIX displaying text. If row START is
14103 non-null, start searching with that row. IT gives the dimensions
14104 of the display. Value is null if matrix is empty; otherwise it is
14105 a pointer to the row found. */
14107 static struct glyph_row *
14108 find_last_row_displaying_text (matrix, it, start)
14109 struct glyph_matrix *matrix;
14110 struct it *it;
14111 struct glyph_row *start;
14113 struct glyph_row *row, *row_found;
14115 /* Set row_found to the last row in IT->w's current matrix
14116 displaying text. The loop looks funny but think of partially
14117 visible lines. */
14118 row_found = NULL;
14119 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
14120 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
14122 xassert (row->enabled_p);
14123 row_found = row;
14124 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
14125 break;
14126 ++row;
14129 return row_found;
14133 /* Return the last row in the current matrix of W that is not affected
14134 by changes at the start of current_buffer that occurred since W's
14135 current matrix was built. Value is null if no such row exists.
14137 BEG_UNCHANGED us the number of characters unchanged at the start of
14138 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
14139 first changed character in current_buffer. Characters at positions <
14140 BEG + BEG_UNCHANGED are at the same buffer positions as they were
14141 when the current matrix was built. */
14143 static struct glyph_row *
14144 find_last_unchanged_at_beg_row (w)
14145 struct window *w;
14147 int first_changed_pos = BEG + BEG_UNCHANGED;
14148 struct glyph_row *row;
14149 struct glyph_row *row_found = NULL;
14150 int yb = window_text_bottom_y (w);
14152 /* Find the last row displaying unchanged text. */
14153 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
14154 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
14155 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
14157 if (/* If row ends before first_changed_pos, it is unchanged,
14158 except in some case. */
14159 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
14160 /* When row ends in ZV and we write at ZV it is not
14161 unchanged. */
14162 && !row->ends_at_zv_p
14163 /* When first_changed_pos is the end of a continued line,
14164 row is not unchanged because it may be no longer
14165 continued. */
14166 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
14167 && (row->continued_p
14168 || row->exact_window_width_line_p)))
14169 row_found = row;
14171 /* Stop if last visible row. */
14172 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
14173 break;
14175 ++row;
14178 return row_found;
14182 /* Find the first glyph row in the current matrix of W that is not
14183 affected by changes at the end of current_buffer since the
14184 time W's current matrix was built.
14186 Return in *DELTA the number of chars by which buffer positions in
14187 unchanged text at the end of current_buffer must be adjusted.
14189 Return in *DELTA_BYTES the corresponding number of bytes.
14191 Value is null if no such row exists, i.e. all rows are affected by
14192 changes. */
14194 static struct glyph_row *
14195 find_first_unchanged_at_end_row (w, delta, delta_bytes)
14196 struct window *w;
14197 int *delta, *delta_bytes;
14199 struct glyph_row *row;
14200 struct glyph_row *row_found = NULL;
14202 *delta = *delta_bytes = 0;
14204 /* Display must not have been paused, otherwise the current matrix
14205 is not up to date. */
14206 if (NILP (w->window_end_valid))
14207 abort ();
14209 /* A value of window_end_pos >= END_UNCHANGED means that the window
14210 end is in the range of changed text. If so, there is no
14211 unchanged row at the end of W's current matrix. */
14212 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
14213 return NULL;
14215 /* Set row to the last row in W's current matrix displaying text. */
14216 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
14218 /* If matrix is entirely empty, no unchanged row exists. */
14219 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
14221 /* The value of row is the last glyph row in the matrix having a
14222 meaningful buffer position in it. The end position of row
14223 corresponds to window_end_pos. This allows us to translate
14224 buffer positions in the current matrix to current buffer
14225 positions for characters not in changed text. */
14226 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
14227 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
14228 int last_unchanged_pos, last_unchanged_pos_old;
14229 struct glyph_row *first_text_row
14230 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
14232 *delta = Z - Z_old;
14233 *delta_bytes = Z_BYTE - Z_BYTE_old;
14235 /* Set last_unchanged_pos to the buffer position of the last
14236 character in the buffer that has not been changed. Z is the
14237 index + 1 of the last character in current_buffer, i.e. by
14238 subtracting END_UNCHANGED we get the index of the last
14239 unchanged character, and we have to add BEG to get its buffer
14240 position. */
14241 last_unchanged_pos = Z - END_UNCHANGED + BEG;
14242 last_unchanged_pos_old = last_unchanged_pos - *delta;
14244 /* Search backward from ROW for a row displaying a line that
14245 starts at a minimum position >= last_unchanged_pos_old. */
14246 for (; row > first_text_row; --row)
14248 /* This used to abort, but it can happen.
14249 It is ok to just stop the search instead here. KFS. */
14250 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
14251 break;
14253 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
14254 row_found = row;
14258 if (row_found && !MATRIX_ROW_DISPLAYS_TEXT_P (row_found))
14259 abort ();
14261 return row_found;
14265 /* Make sure that glyph rows in the current matrix of window W
14266 reference the same glyph memory as corresponding rows in the
14267 frame's frame matrix. This function is called after scrolling W's
14268 current matrix on a terminal frame in try_window_id and
14269 try_window_reusing_current_matrix. */
14271 static void
14272 sync_frame_with_window_matrix_rows (w)
14273 struct window *w;
14275 struct frame *f = XFRAME (w->frame);
14276 struct glyph_row *window_row, *window_row_end, *frame_row;
14278 /* Preconditions: W must be a leaf window and full-width. Its frame
14279 must have a frame matrix. */
14280 xassert (NILP (w->hchild) && NILP (w->vchild));
14281 xassert (WINDOW_FULL_WIDTH_P (w));
14282 xassert (!FRAME_WINDOW_P (f));
14284 /* If W is a full-width window, glyph pointers in W's current matrix
14285 have, by definition, to be the same as glyph pointers in the
14286 corresponding frame matrix. Note that frame matrices have no
14287 marginal areas (see build_frame_matrix). */
14288 window_row = w->current_matrix->rows;
14289 window_row_end = window_row + w->current_matrix->nrows;
14290 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
14291 while (window_row < window_row_end)
14293 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
14294 struct glyph *end = window_row->glyphs[LAST_AREA];
14296 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
14297 frame_row->glyphs[TEXT_AREA] = start;
14298 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
14299 frame_row->glyphs[LAST_AREA] = end;
14301 /* Disable frame rows whose corresponding window rows have
14302 been disabled in try_window_id. */
14303 if (!window_row->enabled_p)
14304 frame_row->enabled_p = 0;
14306 ++window_row, ++frame_row;
14311 /* Find the glyph row in window W containing CHARPOS. Consider all
14312 rows between START and END (not inclusive). END null means search
14313 all rows to the end of the display area of W. Value is the row
14314 containing CHARPOS or null. */
14316 struct glyph_row *
14317 row_containing_pos (w, charpos, start, end, dy)
14318 struct window *w;
14319 int charpos;
14320 struct glyph_row *start, *end;
14321 int dy;
14323 struct glyph_row *row = start;
14324 int last_y;
14326 /* If we happen to start on a header-line, skip that. */
14327 if (row->mode_line_p)
14328 ++row;
14330 if ((end && row >= end) || !row->enabled_p)
14331 return NULL;
14333 last_y = window_text_bottom_y (w) - dy;
14335 while (1)
14337 /* Give up if we have gone too far. */
14338 if (end && row >= end)
14339 return NULL;
14340 /* This formerly returned if they were equal.
14341 I think that both quantities are of a "last plus one" type;
14342 if so, when they are equal, the row is within the screen. -- rms. */
14343 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
14344 return NULL;
14346 /* If it is in this row, return this row. */
14347 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
14348 || (MATRIX_ROW_END_CHARPOS (row) == charpos
14349 /* The end position of a row equals the start
14350 position of the next row. If CHARPOS is there, we
14351 would rather display it in the next line, except
14352 when this line ends in ZV. */
14353 && !row->ends_at_zv_p
14354 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
14355 && charpos >= MATRIX_ROW_START_CHARPOS (row))
14356 return row;
14357 ++row;
14362 /* Try to redisplay window W by reusing its existing display. W's
14363 current matrix must be up to date when this function is called,
14364 i.e. window_end_valid must not be nil.
14366 Value is
14368 1 if display has been updated
14369 0 if otherwise unsuccessful
14370 -1 if redisplay with same window start is known not to succeed
14372 The following steps are performed:
14374 1. Find the last row in the current matrix of W that is not
14375 affected by changes at the start of current_buffer. If no such row
14376 is found, give up.
14378 2. Find the first row in W's current matrix that is not affected by
14379 changes at the end of current_buffer. Maybe there is no such row.
14381 3. Display lines beginning with the row + 1 found in step 1 to the
14382 row found in step 2 or, if step 2 didn't find a row, to the end of
14383 the window.
14385 4. If cursor is not known to appear on the window, give up.
14387 5. If display stopped at the row found in step 2, scroll the
14388 display and current matrix as needed.
14390 6. Maybe display some lines at the end of W, if we must. This can
14391 happen under various circumstances, like a partially visible line
14392 becoming fully visible, or because newly displayed lines are displayed
14393 in smaller font sizes.
14395 7. Update W's window end information. */
14397 static int
14398 try_window_id (w)
14399 struct window *w;
14401 struct frame *f = XFRAME (w->frame);
14402 struct glyph_matrix *current_matrix = w->current_matrix;
14403 struct glyph_matrix *desired_matrix = w->desired_matrix;
14404 struct glyph_row *last_unchanged_at_beg_row;
14405 struct glyph_row *first_unchanged_at_end_row;
14406 struct glyph_row *row;
14407 struct glyph_row *bottom_row;
14408 int bottom_vpos;
14409 struct it it;
14410 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
14411 struct text_pos start_pos;
14412 struct run run;
14413 int first_unchanged_at_end_vpos = 0;
14414 struct glyph_row *last_text_row, *last_text_row_at_end;
14415 struct text_pos start;
14416 int first_changed_charpos, last_changed_charpos;
14418 #if GLYPH_DEBUG
14419 if (inhibit_try_window_id)
14420 return 0;
14421 #endif
14423 /* This is handy for debugging. */
14424 #if 0
14425 #define GIVE_UP(X) \
14426 do { \
14427 fprintf (stderr, "try_window_id give up %d\n", (X)); \
14428 return 0; \
14429 } while (0)
14430 #else
14431 #define GIVE_UP(X) return 0
14432 #endif
14434 SET_TEXT_POS_FROM_MARKER (start, w->start);
14436 /* Don't use this for mini-windows because these can show
14437 messages and mini-buffers, and we don't handle that here. */
14438 if (MINI_WINDOW_P (w))
14439 GIVE_UP (1);
14441 /* This flag is used to prevent redisplay optimizations. */
14442 if (windows_or_buffers_changed || cursor_type_changed)
14443 GIVE_UP (2);
14445 /* Verify that narrowing has not changed.
14446 Also verify that we were not told to prevent redisplay optimizations.
14447 It would be nice to further
14448 reduce the number of cases where this prevents try_window_id. */
14449 if (current_buffer->clip_changed
14450 || current_buffer->prevent_redisplay_optimizations_p)
14451 GIVE_UP (3);
14453 /* Window must either use window-based redisplay or be full width. */
14454 if (!FRAME_WINDOW_P (f)
14455 && (!FRAME_LINE_INS_DEL_OK (f)
14456 || !WINDOW_FULL_WIDTH_P (w)))
14457 GIVE_UP (4);
14459 /* Give up if point is not known NOT to appear in W. */
14460 if (PT < CHARPOS (start))
14461 GIVE_UP (5);
14463 /* Another way to prevent redisplay optimizations. */
14464 if (XFASTINT (w->last_modified) == 0)
14465 GIVE_UP (6);
14467 /* Verify that window is not hscrolled. */
14468 if (XFASTINT (w->hscroll) != 0)
14469 GIVE_UP (7);
14471 /* Verify that display wasn't paused. */
14472 if (NILP (w->window_end_valid))
14473 GIVE_UP (8);
14475 /* Can't use this if highlighting a region because a cursor movement
14476 will do more than just set the cursor. */
14477 if (!NILP (Vtransient_mark_mode)
14478 && !NILP (current_buffer->mark_active))
14479 GIVE_UP (9);
14481 /* Likewise if highlighting trailing whitespace. */
14482 if (!NILP (Vshow_trailing_whitespace))
14483 GIVE_UP (11);
14485 /* Likewise if showing a region. */
14486 if (!NILP (w->region_showing))
14487 GIVE_UP (10);
14489 /* Can use this if overlay arrow position and or string have changed. */
14490 if (overlay_arrows_changed_p ())
14491 GIVE_UP (12);
14494 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
14495 only if buffer has really changed. The reason is that the gap is
14496 initially at Z for freshly visited files. The code below would
14497 set end_unchanged to 0 in that case. */
14498 if (MODIFF > SAVE_MODIFF
14499 /* This seems to happen sometimes after saving a buffer. */
14500 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
14502 if (GPT - BEG < BEG_UNCHANGED)
14503 BEG_UNCHANGED = GPT - BEG;
14504 if (Z - GPT < END_UNCHANGED)
14505 END_UNCHANGED = Z - GPT;
14508 /* The position of the first and last character that has been changed. */
14509 first_changed_charpos = BEG + BEG_UNCHANGED;
14510 last_changed_charpos = Z - END_UNCHANGED;
14512 /* If window starts after a line end, and the last change is in
14513 front of that newline, then changes don't affect the display.
14514 This case happens with stealth-fontification. Note that although
14515 the display is unchanged, glyph positions in the matrix have to
14516 be adjusted, of course. */
14517 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
14518 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
14519 && ((last_changed_charpos < CHARPOS (start)
14520 && CHARPOS (start) == BEGV)
14521 || (last_changed_charpos < CHARPOS (start) - 1
14522 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
14524 int Z_old, delta, Z_BYTE_old, delta_bytes;
14525 struct glyph_row *r0;
14527 /* Compute how many chars/bytes have been added to or removed
14528 from the buffer. */
14529 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
14530 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
14531 delta = Z - Z_old;
14532 delta_bytes = Z_BYTE - Z_BYTE_old;
14534 /* Give up if PT is not in the window. Note that it already has
14535 been checked at the start of try_window_id that PT is not in
14536 front of the window start. */
14537 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
14538 GIVE_UP (13);
14540 /* If window start is unchanged, we can reuse the whole matrix
14541 as is, after adjusting glyph positions. No need to compute
14542 the window end again, since its offset from Z hasn't changed. */
14543 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
14544 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
14545 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
14546 /* PT must not be in a partially visible line. */
14547 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
14548 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
14550 /* Adjust positions in the glyph matrix. */
14551 if (delta || delta_bytes)
14553 struct glyph_row *r1
14554 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
14555 increment_matrix_positions (w->current_matrix,
14556 MATRIX_ROW_VPOS (r0, current_matrix),
14557 MATRIX_ROW_VPOS (r1, current_matrix),
14558 delta, delta_bytes);
14561 /* Set the cursor. */
14562 row = row_containing_pos (w, PT, r0, NULL, 0);
14563 if (row)
14564 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
14565 else
14566 abort ();
14567 return 1;
14571 /* Handle the case that changes are all below what is displayed in
14572 the window, and that PT is in the window. This shortcut cannot
14573 be taken if ZV is visible in the window, and text has been added
14574 there that is visible in the window. */
14575 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
14576 /* ZV is not visible in the window, or there are no
14577 changes at ZV, actually. */
14578 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
14579 || first_changed_charpos == last_changed_charpos))
14581 struct glyph_row *r0;
14583 /* Give up if PT is not in the window. Note that it already has
14584 been checked at the start of try_window_id that PT is not in
14585 front of the window start. */
14586 if (PT >= MATRIX_ROW_END_CHARPOS (row))
14587 GIVE_UP (14);
14589 /* If window start is unchanged, we can reuse the whole matrix
14590 as is, without changing glyph positions since no text has
14591 been added/removed in front of the window end. */
14592 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
14593 if (TEXT_POS_EQUAL_P (start, r0->start.pos)
14594 /* PT must not be in a partially visible line. */
14595 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
14596 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
14598 /* We have to compute the window end anew since text
14599 can have been added/removed after it. */
14600 w->window_end_pos
14601 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
14602 w->window_end_bytepos
14603 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
14605 /* Set the cursor. */
14606 row = row_containing_pos (w, PT, r0, NULL, 0);
14607 if (row)
14608 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
14609 else
14610 abort ();
14611 return 2;
14615 /* Give up if window start is in the changed area.
14617 The condition used to read
14619 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
14621 but why that was tested escapes me at the moment. */
14622 if (CHARPOS (start) >= first_changed_charpos
14623 && CHARPOS (start) <= last_changed_charpos)
14624 GIVE_UP (15);
14626 /* Check that window start agrees with the start of the first glyph
14627 row in its current matrix. Check this after we know the window
14628 start is not in changed text, otherwise positions would not be
14629 comparable. */
14630 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
14631 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
14632 GIVE_UP (16);
14634 /* Give up if the window ends in strings. Overlay strings
14635 at the end are difficult to handle, so don't try. */
14636 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
14637 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
14638 GIVE_UP (20);
14640 /* Compute the position at which we have to start displaying new
14641 lines. Some of the lines at the top of the window might be
14642 reusable because they are not displaying changed text. Find the
14643 last row in W's current matrix not affected by changes at the
14644 start of current_buffer. Value is null if changes start in the
14645 first line of window. */
14646 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
14647 if (last_unchanged_at_beg_row)
14649 /* Avoid starting to display in the moddle of a character, a TAB
14650 for instance. This is easier than to set up the iterator
14651 exactly, and it's not a frequent case, so the additional
14652 effort wouldn't really pay off. */
14653 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
14654 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
14655 && last_unchanged_at_beg_row > w->current_matrix->rows)
14656 --last_unchanged_at_beg_row;
14658 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
14659 GIVE_UP (17);
14661 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
14662 GIVE_UP (18);
14663 start_pos = it.current.pos;
14665 /* Start displaying new lines in the desired matrix at the same
14666 vpos we would use in the current matrix, i.e. below
14667 last_unchanged_at_beg_row. */
14668 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
14669 current_matrix);
14670 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
14671 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
14673 xassert (it.hpos == 0 && it.current_x == 0);
14675 else
14677 /* There are no reusable lines at the start of the window.
14678 Start displaying in the first text line. */
14679 start_display (&it, w, start);
14680 it.vpos = it.first_vpos;
14681 start_pos = it.current.pos;
14684 /* Find the first row that is not affected by changes at the end of
14685 the buffer. Value will be null if there is no unchanged row, in
14686 which case we must redisplay to the end of the window. delta
14687 will be set to the value by which buffer positions beginning with
14688 first_unchanged_at_end_row have to be adjusted due to text
14689 changes. */
14690 first_unchanged_at_end_row
14691 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
14692 IF_DEBUG (debug_delta = delta);
14693 IF_DEBUG (debug_delta_bytes = delta_bytes);
14695 /* Set stop_pos to the buffer position up to which we will have to
14696 display new lines. If first_unchanged_at_end_row != NULL, this
14697 is the buffer position of the start of the line displayed in that
14698 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
14699 that we don't stop at a buffer position. */
14700 stop_pos = 0;
14701 if (first_unchanged_at_end_row)
14703 xassert (last_unchanged_at_beg_row == NULL
14704 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
14706 /* If this is a continuation line, move forward to the next one
14707 that isn't. Changes in lines above affect this line.
14708 Caution: this may move first_unchanged_at_end_row to a row
14709 not displaying text. */
14710 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
14711 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
14712 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
14713 < it.last_visible_y))
14714 ++first_unchanged_at_end_row;
14716 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
14717 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
14718 >= it.last_visible_y))
14719 first_unchanged_at_end_row = NULL;
14720 else
14722 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
14723 + delta);
14724 first_unchanged_at_end_vpos
14725 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
14726 xassert (stop_pos >= Z - END_UNCHANGED);
14729 else if (last_unchanged_at_beg_row == NULL)
14730 GIVE_UP (19);
14733 #if GLYPH_DEBUG
14735 /* Either there is no unchanged row at the end, or the one we have
14736 now displays text. This is a necessary condition for the window
14737 end pos calculation at the end of this function. */
14738 xassert (first_unchanged_at_end_row == NULL
14739 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
14741 debug_last_unchanged_at_beg_vpos
14742 = (last_unchanged_at_beg_row
14743 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
14744 : -1);
14745 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
14747 #endif /* GLYPH_DEBUG != 0 */
14750 /* Display new lines. Set last_text_row to the last new line
14751 displayed which has text on it, i.e. might end up as being the
14752 line where the window_end_vpos is. */
14753 w->cursor.vpos = -1;
14754 last_text_row = NULL;
14755 overlay_arrow_seen = 0;
14756 while (it.current_y < it.last_visible_y
14757 && !fonts_changed_p
14758 && (first_unchanged_at_end_row == NULL
14759 || IT_CHARPOS (it) < stop_pos))
14761 if (display_line (&it))
14762 last_text_row = it.glyph_row - 1;
14765 if (fonts_changed_p)
14766 return -1;
14769 /* Compute differences in buffer positions, y-positions etc. for
14770 lines reused at the bottom of the window. Compute what we can
14771 scroll. */
14772 if (first_unchanged_at_end_row
14773 /* No lines reused because we displayed everything up to the
14774 bottom of the window. */
14775 && it.current_y < it.last_visible_y)
14777 dvpos = (it.vpos
14778 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
14779 current_matrix));
14780 dy = it.current_y - first_unchanged_at_end_row->y;
14781 run.current_y = first_unchanged_at_end_row->y;
14782 run.desired_y = run.current_y + dy;
14783 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
14785 else
14787 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
14788 first_unchanged_at_end_row = NULL;
14790 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
14793 /* Find the cursor if not already found. We have to decide whether
14794 PT will appear on this window (it sometimes doesn't, but this is
14795 not a very frequent case.) This decision has to be made before
14796 the current matrix is altered. A value of cursor.vpos < 0 means
14797 that PT is either in one of the lines beginning at
14798 first_unchanged_at_end_row or below the window. Don't care for
14799 lines that might be displayed later at the window end; as
14800 mentioned, this is not a frequent case. */
14801 if (w->cursor.vpos < 0)
14803 /* Cursor in unchanged rows at the top? */
14804 if (PT < CHARPOS (start_pos)
14805 && last_unchanged_at_beg_row)
14807 row = row_containing_pos (w, PT,
14808 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
14809 last_unchanged_at_beg_row + 1, 0);
14810 if (row)
14811 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
14814 /* Start from first_unchanged_at_end_row looking for PT. */
14815 else if (first_unchanged_at_end_row)
14817 row = row_containing_pos (w, PT - delta,
14818 first_unchanged_at_end_row, NULL, 0);
14819 if (row)
14820 set_cursor_from_row (w, row, w->current_matrix, delta,
14821 delta_bytes, dy, dvpos);
14824 /* Give up if cursor was not found. */
14825 if (w->cursor.vpos < 0)
14827 clear_glyph_matrix (w->desired_matrix);
14828 return -1;
14832 /* Don't let the cursor end in the scroll margins. */
14834 int this_scroll_margin, cursor_height;
14836 this_scroll_margin = max (0, scroll_margin);
14837 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
14838 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
14839 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
14841 if ((w->cursor.y < this_scroll_margin
14842 && CHARPOS (start) > BEGV)
14843 /* Old redisplay didn't take scroll margin into account at the bottom,
14844 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
14845 || (w->cursor.y + (make_cursor_line_fully_visible_p
14846 ? cursor_height + this_scroll_margin
14847 : 1)) > it.last_visible_y)
14849 w->cursor.vpos = -1;
14850 clear_glyph_matrix (w->desired_matrix);
14851 return -1;
14855 /* Scroll the display. Do it before changing the current matrix so
14856 that xterm.c doesn't get confused about where the cursor glyph is
14857 found. */
14858 if (dy && run.height)
14860 update_begin (f);
14862 if (FRAME_WINDOW_P (f))
14864 FRAME_RIF (f)->update_window_begin_hook (w);
14865 FRAME_RIF (f)->clear_window_mouse_face (w);
14866 FRAME_RIF (f)->scroll_run_hook (w, &run);
14867 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
14869 else
14871 /* Terminal frame. In this case, dvpos gives the number of
14872 lines to scroll by; dvpos < 0 means scroll up. */
14873 int first_unchanged_at_end_vpos
14874 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
14875 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
14876 int end = (WINDOW_TOP_EDGE_LINE (w)
14877 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
14878 + window_internal_height (w));
14880 /* Perform the operation on the screen. */
14881 if (dvpos > 0)
14883 /* Scroll last_unchanged_at_beg_row to the end of the
14884 window down dvpos lines. */
14885 set_terminal_window (f, end);
14887 /* On dumb terminals delete dvpos lines at the end
14888 before inserting dvpos empty lines. */
14889 if (!FRAME_SCROLL_REGION_OK (f))
14890 ins_del_lines (f, end - dvpos, -dvpos);
14892 /* Insert dvpos empty lines in front of
14893 last_unchanged_at_beg_row. */
14894 ins_del_lines (f, from, dvpos);
14896 else if (dvpos < 0)
14898 /* Scroll up last_unchanged_at_beg_vpos to the end of
14899 the window to last_unchanged_at_beg_vpos - |dvpos|. */
14900 set_terminal_window (f, end);
14902 /* Delete dvpos lines in front of
14903 last_unchanged_at_beg_vpos. ins_del_lines will set
14904 the cursor to the given vpos and emit |dvpos| delete
14905 line sequences. */
14906 ins_del_lines (f, from + dvpos, dvpos);
14908 /* On a dumb terminal insert dvpos empty lines at the
14909 end. */
14910 if (!FRAME_SCROLL_REGION_OK (f))
14911 ins_del_lines (f, end + dvpos, -dvpos);
14914 set_terminal_window (f, 0);
14917 update_end (f);
14920 /* Shift reused rows of the current matrix to the right position.
14921 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
14922 text. */
14923 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
14924 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
14925 if (dvpos < 0)
14927 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
14928 bottom_vpos, dvpos);
14929 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
14930 bottom_vpos, 0);
14932 else if (dvpos > 0)
14934 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
14935 bottom_vpos, dvpos);
14936 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
14937 first_unchanged_at_end_vpos + dvpos, 0);
14940 /* For frame-based redisplay, make sure that current frame and window
14941 matrix are in sync with respect to glyph memory. */
14942 if (!FRAME_WINDOW_P (f))
14943 sync_frame_with_window_matrix_rows (w);
14945 /* Adjust buffer positions in reused rows. */
14946 if (delta || delta_bytes)
14947 increment_matrix_positions (current_matrix,
14948 first_unchanged_at_end_vpos + dvpos,
14949 bottom_vpos, delta, delta_bytes);
14951 /* Adjust Y positions. */
14952 if (dy)
14953 shift_glyph_matrix (w, current_matrix,
14954 first_unchanged_at_end_vpos + dvpos,
14955 bottom_vpos, dy);
14957 if (first_unchanged_at_end_row)
14959 first_unchanged_at_end_row += dvpos;
14960 if (first_unchanged_at_end_row->y >= it.last_visible_y
14961 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
14962 first_unchanged_at_end_row = NULL;
14965 /* If scrolling up, there may be some lines to display at the end of
14966 the window. */
14967 last_text_row_at_end = NULL;
14968 if (dy < 0)
14970 /* Scrolling up can leave for example a partially visible line
14971 at the end of the window to be redisplayed. */
14972 /* Set last_row to the glyph row in the current matrix where the
14973 window end line is found. It has been moved up or down in
14974 the matrix by dvpos. */
14975 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
14976 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
14978 /* If last_row is the window end line, it should display text. */
14979 xassert (last_row->displays_text_p);
14981 /* If window end line was partially visible before, begin
14982 displaying at that line. Otherwise begin displaying with the
14983 line following it. */
14984 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
14986 init_to_row_start (&it, w, last_row);
14987 it.vpos = last_vpos;
14988 it.current_y = last_row->y;
14990 else
14992 init_to_row_end (&it, w, last_row);
14993 it.vpos = 1 + last_vpos;
14994 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
14995 ++last_row;
14998 /* We may start in a continuation line. If so, we have to
14999 get the right continuation_lines_width and current_x. */
15000 it.continuation_lines_width = last_row->continuation_lines_width;
15001 it.hpos = it.current_x = 0;
15003 /* Display the rest of the lines at the window end. */
15004 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
15005 while (it.current_y < it.last_visible_y
15006 && !fonts_changed_p)
15008 /* Is it always sure that the display agrees with lines in
15009 the current matrix? I don't think so, so we mark rows
15010 displayed invalid in the current matrix by setting their
15011 enabled_p flag to zero. */
15012 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
15013 if (display_line (&it))
15014 last_text_row_at_end = it.glyph_row - 1;
15018 /* Update window_end_pos and window_end_vpos. */
15019 if (first_unchanged_at_end_row
15020 && !last_text_row_at_end)
15022 /* Window end line if one of the preserved rows from the current
15023 matrix. Set row to the last row displaying text in current
15024 matrix starting at first_unchanged_at_end_row, after
15025 scrolling. */
15026 xassert (first_unchanged_at_end_row->displays_text_p);
15027 row = find_last_row_displaying_text (w->current_matrix, &it,
15028 first_unchanged_at_end_row);
15029 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
15031 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
15032 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
15033 w->window_end_vpos
15034 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
15035 xassert (w->window_end_bytepos >= 0);
15036 IF_DEBUG (debug_method_add (w, "A"));
15038 else if (last_text_row_at_end)
15040 w->window_end_pos
15041 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
15042 w->window_end_bytepos
15043 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
15044 w->window_end_vpos
15045 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
15046 xassert (w->window_end_bytepos >= 0);
15047 IF_DEBUG (debug_method_add (w, "B"));
15049 else if (last_text_row)
15051 /* We have displayed either to the end of the window or at the
15052 end of the window, i.e. the last row with text is to be found
15053 in the desired matrix. */
15054 w->window_end_pos
15055 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
15056 w->window_end_bytepos
15057 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
15058 w->window_end_vpos
15059 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
15060 xassert (w->window_end_bytepos >= 0);
15062 else if (first_unchanged_at_end_row == NULL
15063 && last_text_row == NULL
15064 && last_text_row_at_end == NULL)
15066 /* Displayed to end of window, but no line containing text was
15067 displayed. Lines were deleted at the end of the window. */
15068 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
15069 int vpos = XFASTINT (w->window_end_vpos);
15070 struct glyph_row *current_row = current_matrix->rows + vpos;
15071 struct glyph_row *desired_row = desired_matrix->rows + vpos;
15073 for (row = NULL;
15074 row == NULL && vpos >= first_vpos;
15075 --vpos, --current_row, --desired_row)
15077 if (desired_row->enabled_p)
15079 if (desired_row->displays_text_p)
15080 row = desired_row;
15082 else if (current_row->displays_text_p)
15083 row = current_row;
15086 xassert (row != NULL);
15087 w->window_end_vpos = make_number (vpos + 1);
15088 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
15089 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
15090 xassert (w->window_end_bytepos >= 0);
15091 IF_DEBUG (debug_method_add (w, "C"));
15093 else
15094 abort ();
15096 #if 0 /* This leads to problems, for instance when the cursor is
15097 at ZV, and the cursor line displays no text. */
15098 /* Disable rows below what's displayed in the window. This makes
15099 debugging easier. */
15100 enable_glyph_matrix_rows (current_matrix,
15101 XFASTINT (w->window_end_vpos) + 1,
15102 bottom_vpos, 0);
15103 #endif
15105 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
15106 debug_end_vpos = XFASTINT (w->window_end_vpos));
15108 /* Record that display has not been completed. */
15109 w->window_end_valid = Qnil;
15110 w->desired_matrix->no_scrolling_p = 1;
15111 return 3;
15113 #undef GIVE_UP
15118 /***********************************************************************
15119 More debugging support
15120 ***********************************************************************/
15122 #if GLYPH_DEBUG
15124 void dump_glyph_row P_ ((struct glyph_row *, int, int));
15125 void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
15126 void dump_glyph P_ ((struct glyph_row *, struct glyph *, int));
15129 /* Dump the contents of glyph matrix MATRIX on stderr.
15131 GLYPHS 0 means don't show glyph contents.
15132 GLYPHS 1 means show glyphs in short form
15133 GLYPHS > 1 means show glyphs in long form. */
15135 void
15136 dump_glyph_matrix (matrix, glyphs)
15137 struct glyph_matrix *matrix;
15138 int glyphs;
15140 int i;
15141 for (i = 0; i < matrix->nrows; ++i)
15142 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
15146 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
15147 the glyph row and area where the glyph comes from. */
15149 void
15150 dump_glyph (row, glyph, area)
15151 struct glyph_row *row;
15152 struct glyph *glyph;
15153 int area;
15155 if (glyph->type == CHAR_GLYPH)
15157 fprintf (stderr,
15158 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
15159 glyph - row->glyphs[TEXT_AREA],
15160 'C',
15161 glyph->charpos,
15162 (BUFFERP (glyph->object)
15163 ? 'B'
15164 : (STRINGP (glyph->object)
15165 ? 'S'
15166 : '-')),
15167 glyph->pixel_width,
15168 glyph->u.ch,
15169 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
15170 ? glyph->u.ch
15171 : '.'),
15172 glyph->face_id,
15173 glyph->left_box_line_p,
15174 glyph->right_box_line_p);
15176 else if (glyph->type == STRETCH_GLYPH)
15178 fprintf (stderr,
15179 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
15180 glyph - row->glyphs[TEXT_AREA],
15181 'S',
15182 glyph->charpos,
15183 (BUFFERP (glyph->object)
15184 ? 'B'
15185 : (STRINGP (glyph->object)
15186 ? 'S'
15187 : '-')),
15188 glyph->pixel_width,
15190 '.',
15191 glyph->face_id,
15192 glyph->left_box_line_p,
15193 glyph->right_box_line_p);
15195 else if (glyph->type == IMAGE_GLYPH)
15197 fprintf (stderr,
15198 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
15199 glyph - row->glyphs[TEXT_AREA],
15200 'I',
15201 glyph->charpos,
15202 (BUFFERP (glyph->object)
15203 ? 'B'
15204 : (STRINGP (glyph->object)
15205 ? 'S'
15206 : '-')),
15207 glyph->pixel_width,
15208 glyph->u.img_id,
15209 '.',
15210 glyph->face_id,
15211 glyph->left_box_line_p,
15212 glyph->right_box_line_p);
15214 else if (glyph->type == COMPOSITE_GLYPH)
15216 fprintf (stderr,
15217 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
15218 glyph - row->glyphs[TEXT_AREA],
15219 '+',
15220 glyph->charpos,
15221 (BUFFERP (glyph->object)
15222 ? 'B'
15223 : (STRINGP (glyph->object)
15224 ? 'S'
15225 : '-')),
15226 glyph->pixel_width,
15227 glyph->u.cmp_id,
15228 '.',
15229 glyph->face_id,
15230 glyph->left_box_line_p,
15231 glyph->right_box_line_p);
15236 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
15237 GLYPHS 0 means don't show glyph contents.
15238 GLYPHS 1 means show glyphs in short form
15239 GLYPHS > 1 means show glyphs in long form. */
15241 void
15242 dump_glyph_row (row, vpos, glyphs)
15243 struct glyph_row *row;
15244 int vpos, glyphs;
15246 if (glyphs != 1)
15248 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
15249 fprintf (stderr, "======================================================================\n");
15251 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d\
15252 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
15253 vpos,
15254 MATRIX_ROW_START_CHARPOS (row),
15255 MATRIX_ROW_END_CHARPOS (row),
15256 row->used[TEXT_AREA],
15257 row->contains_overlapping_glyphs_p,
15258 row->enabled_p,
15259 row->truncated_on_left_p,
15260 row->truncated_on_right_p,
15261 row->continued_p,
15262 MATRIX_ROW_CONTINUATION_LINE_P (row),
15263 row->displays_text_p,
15264 row->ends_at_zv_p,
15265 row->fill_line_p,
15266 row->ends_in_middle_of_char_p,
15267 row->starts_in_middle_of_char_p,
15268 row->mouse_face_p,
15269 row->x,
15270 row->y,
15271 row->pixel_width,
15272 row->height,
15273 row->visible_height,
15274 row->ascent,
15275 row->phys_ascent);
15276 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
15277 row->end.overlay_string_index,
15278 row->continuation_lines_width);
15279 fprintf (stderr, "%9d %5d\n",
15280 CHARPOS (row->start.string_pos),
15281 CHARPOS (row->end.string_pos));
15282 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
15283 row->end.dpvec_index);
15286 if (glyphs > 1)
15288 int area;
15290 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
15292 struct glyph *glyph = row->glyphs[area];
15293 struct glyph *glyph_end = glyph + row->used[area];
15295 /* Glyph for a line end in text. */
15296 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
15297 ++glyph_end;
15299 if (glyph < glyph_end)
15300 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
15302 for (; glyph < glyph_end; ++glyph)
15303 dump_glyph (row, glyph, area);
15306 else if (glyphs == 1)
15308 int area;
15310 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
15312 char *s = (char *) alloca (row->used[area] + 1);
15313 int i;
15315 for (i = 0; i < row->used[area]; ++i)
15317 struct glyph *glyph = row->glyphs[area] + i;
15318 if (glyph->type == CHAR_GLYPH
15319 && glyph->u.ch < 0x80
15320 && glyph->u.ch >= ' ')
15321 s[i] = glyph->u.ch;
15322 else
15323 s[i] = '.';
15326 s[i] = '\0';
15327 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
15333 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
15334 Sdump_glyph_matrix, 0, 1, "p",
15335 doc: /* Dump the current matrix of the selected window to stderr.
15336 Shows contents of glyph row structures. With non-nil
15337 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
15338 glyphs in short form, otherwise show glyphs in long form. */)
15339 (glyphs)
15340 Lisp_Object glyphs;
15342 struct window *w = XWINDOW (selected_window);
15343 struct buffer *buffer = XBUFFER (w->buffer);
15345 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
15346 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
15347 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
15348 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
15349 fprintf (stderr, "=============================================\n");
15350 dump_glyph_matrix (w->current_matrix,
15351 NILP (glyphs) ? 0 : XINT (glyphs));
15352 return Qnil;
15356 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
15357 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
15360 struct frame *f = XFRAME (selected_frame);
15361 dump_glyph_matrix (f->current_matrix, 1);
15362 return Qnil;
15366 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
15367 doc: /* Dump glyph row ROW to stderr.
15368 GLYPH 0 means don't dump glyphs.
15369 GLYPH 1 means dump glyphs in short form.
15370 GLYPH > 1 or omitted means dump glyphs in long form. */)
15371 (row, glyphs)
15372 Lisp_Object row, glyphs;
15374 struct glyph_matrix *matrix;
15375 int vpos;
15377 CHECK_NUMBER (row);
15378 matrix = XWINDOW (selected_window)->current_matrix;
15379 vpos = XINT (row);
15380 if (vpos >= 0 && vpos < matrix->nrows)
15381 dump_glyph_row (MATRIX_ROW (matrix, vpos),
15382 vpos,
15383 INTEGERP (glyphs) ? XINT (glyphs) : 2);
15384 return Qnil;
15388 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
15389 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
15390 GLYPH 0 means don't dump glyphs.
15391 GLYPH 1 means dump glyphs in short form.
15392 GLYPH > 1 or omitted means dump glyphs in long form. */)
15393 (row, glyphs)
15394 Lisp_Object row, glyphs;
15396 struct frame *sf = SELECTED_FRAME ();
15397 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
15398 int vpos;
15400 CHECK_NUMBER (row);
15401 vpos = XINT (row);
15402 if (vpos >= 0 && vpos < m->nrows)
15403 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
15404 INTEGERP (glyphs) ? XINT (glyphs) : 2);
15405 return Qnil;
15409 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
15410 doc: /* Toggle tracing of redisplay.
15411 With ARG, turn tracing on if and only if ARG is positive. */)
15412 (arg)
15413 Lisp_Object arg;
15415 if (NILP (arg))
15416 trace_redisplay_p = !trace_redisplay_p;
15417 else
15419 arg = Fprefix_numeric_value (arg);
15420 trace_redisplay_p = XINT (arg) > 0;
15423 return Qnil;
15427 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
15428 doc: /* Like `format', but print result to stderr.
15429 usage: (trace-to-stderr STRING &rest OBJECTS) */)
15430 (nargs, args)
15431 int nargs;
15432 Lisp_Object *args;
15434 Lisp_Object s = Fformat (nargs, args);
15435 fprintf (stderr, "%s", SDATA (s));
15436 return Qnil;
15439 #endif /* GLYPH_DEBUG */
15443 /***********************************************************************
15444 Building Desired Matrix Rows
15445 ***********************************************************************/
15447 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
15448 Used for non-window-redisplay windows, and for windows w/o left fringe. */
15450 static struct glyph_row *
15451 get_overlay_arrow_glyph_row (w, overlay_arrow_string)
15452 struct window *w;
15453 Lisp_Object overlay_arrow_string;
15455 struct frame *f = XFRAME (WINDOW_FRAME (w));
15456 struct buffer *buffer = XBUFFER (w->buffer);
15457 struct buffer *old = current_buffer;
15458 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
15459 int arrow_len = SCHARS (overlay_arrow_string);
15460 const unsigned char *arrow_end = arrow_string + arrow_len;
15461 const unsigned char *p;
15462 struct it it;
15463 int multibyte_p;
15464 int n_glyphs_before;
15466 set_buffer_temp (buffer);
15467 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
15468 it.glyph_row->used[TEXT_AREA] = 0;
15469 SET_TEXT_POS (it.position, 0, 0);
15471 multibyte_p = !NILP (buffer->enable_multibyte_characters);
15472 p = arrow_string;
15473 while (p < arrow_end)
15475 Lisp_Object face, ilisp;
15477 /* Get the next character. */
15478 if (multibyte_p)
15479 it.c = string_char_and_length (p, arrow_len, &it.len);
15480 else
15481 it.c = *p, it.len = 1;
15482 p += it.len;
15484 /* Get its face. */
15485 ilisp = make_number (p - arrow_string);
15486 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
15487 it.face_id = compute_char_face (f, it.c, face);
15489 /* Compute its width, get its glyphs. */
15490 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
15491 SET_TEXT_POS (it.position, -1, -1);
15492 PRODUCE_GLYPHS (&it);
15494 /* If this character doesn't fit any more in the line, we have
15495 to remove some glyphs. */
15496 if (it.current_x > it.last_visible_x)
15498 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
15499 break;
15503 set_buffer_temp (old);
15504 return it.glyph_row;
15508 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
15509 glyphs are only inserted for terminal frames since we can't really
15510 win with truncation glyphs when partially visible glyphs are
15511 involved. Which glyphs to insert is determined by
15512 produce_special_glyphs. */
15514 static void
15515 insert_left_trunc_glyphs (it)
15516 struct it *it;
15518 struct it truncate_it;
15519 struct glyph *from, *end, *to, *toend;
15521 xassert (!FRAME_WINDOW_P (it->f));
15523 /* Get the truncation glyphs. */
15524 truncate_it = *it;
15525 truncate_it.current_x = 0;
15526 truncate_it.face_id = DEFAULT_FACE_ID;
15527 truncate_it.glyph_row = &scratch_glyph_row;
15528 truncate_it.glyph_row->used[TEXT_AREA] = 0;
15529 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
15530 truncate_it.object = make_number (0);
15531 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
15533 /* Overwrite glyphs from IT with truncation glyphs. */
15534 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
15535 end = from + truncate_it.glyph_row->used[TEXT_AREA];
15536 to = it->glyph_row->glyphs[TEXT_AREA];
15537 toend = to + it->glyph_row->used[TEXT_AREA];
15539 while (from < end)
15540 *to++ = *from++;
15542 /* There may be padding glyphs left over. Overwrite them too. */
15543 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
15545 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
15546 while (from < end)
15547 *to++ = *from++;
15550 if (to > toend)
15551 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
15555 /* Compute the pixel height and width of IT->glyph_row.
15557 Most of the time, ascent and height of a display line will be equal
15558 to the max_ascent and max_height values of the display iterator
15559 structure. This is not the case if
15561 1. We hit ZV without displaying anything. In this case, max_ascent
15562 and max_height will be zero.
15564 2. We have some glyphs that don't contribute to the line height.
15565 (The glyph row flag contributes_to_line_height_p is for future
15566 pixmap extensions).
15568 The first case is easily covered by using default values because in
15569 these cases, the line height does not really matter, except that it
15570 must not be zero. */
15572 static void
15573 compute_line_metrics (it)
15574 struct it *it;
15576 struct glyph_row *row = it->glyph_row;
15577 int area, i;
15579 if (FRAME_WINDOW_P (it->f))
15581 int i, min_y, max_y;
15583 /* The line may consist of one space only, that was added to
15584 place the cursor on it. If so, the row's height hasn't been
15585 computed yet. */
15586 if (row->height == 0)
15588 if (it->max_ascent + it->max_descent == 0)
15589 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
15590 row->ascent = it->max_ascent;
15591 row->height = it->max_ascent + it->max_descent;
15592 row->phys_ascent = it->max_phys_ascent;
15593 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
15594 row->extra_line_spacing = it->max_extra_line_spacing;
15597 /* Compute the width of this line. */
15598 row->pixel_width = row->x;
15599 for (i = 0; i < row->used[TEXT_AREA]; ++i)
15600 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
15602 xassert (row->pixel_width >= 0);
15603 xassert (row->ascent >= 0 && row->height > 0);
15605 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
15606 || MATRIX_ROW_OVERLAPS_PRED_P (row));
15608 /* If first line's physical ascent is larger than its logical
15609 ascent, use the physical ascent, and make the row taller.
15610 This makes accented characters fully visible. */
15611 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
15612 && row->phys_ascent > row->ascent)
15614 row->height += row->phys_ascent - row->ascent;
15615 row->ascent = row->phys_ascent;
15618 /* Compute how much of the line is visible. */
15619 row->visible_height = row->height;
15621 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
15622 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
15624 if (row->y < min_y)
15625 row->visible_height -= min_y - row->y;
15626 if (row->y + row->height > max_y)
15627 row->visible_height -= row->y + row->height - max_y;
15629 else
15631 row->pixel_width = row->used[TEXT_AREA];
15632 if (row->continued_p)
15633 row->pixel_width -= it->continuation_pixel_width;
15634 else if (row->truncated_on_right_p)
15635 row->pixel_width -= it->truncation_pixel_width;
15636 row->ascent = row->phys_ascent = 0;
15637 row->height = row->phys_height = row->visible_height = 1;
15638 row->extra_line_spacing = 0;
15641 /* Compute a hash code for this row. */
15642 row->hash = 0;
15643 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
15644 for (i = 0; i < row->used[area]; ++i)
15645 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
15646 + row->glyphs[area][i].u.val
15647 + row->glyphs[area][i].face_id
15648 + row->glyphs[area][i].padding_p
15649 + (row->glyphs[area][i].type << 2));
15651 it->max_ascent = it->max_descent = 0;
15652 it->max_phys_ascent = it->max_phys_descent = 0;
15656 /* Append one space to the glyph row of iterator IT if doing a
15657 window-based redisplay. The space has the same face as
15658 IT->face_id. Value is non-zero if a space was added.
15660 This function is called to make sure that there is always one glyph
15661 at the end of a glyph row that the cursor can be set on under
15662 window-systems. (If there weren't such a glyph we would not know
15663 how wide and tall a box cursor should be displayed).
15665 At the same time this space let's a nicely handle clearing to the
15666 end of the line if the row ends in italic text. */
15668 static int
15669 append_space_for_newline (it, default_face_p)
15670 struct it *it;
15671 int default_face_p;
15673 if (FRAME_WINDOW_P (it->f))
15675 int n = it->glyph_row->used[TEXT_AREA];
15677 if (it->glyph_row->glyphs[TEXT_AREA] + n
15678 < it->glyph_row->glyphs[1 + TEXT_AREA])
15680 /* Save some values that must not be changed.
15681 Must save IT->c and IT->len because otherwise
15682 ITERATOR_AT_END_P wouldn't work anymore after
15683 append_space_for_newline has been called. */
15684 enum display_element_type saved_what = it->what;
15685 int saved_c = it->c, saved_len = it->len;
15686 int saved_x = it->current_x;
15687 int saved_face_id = it->face_id;
15688 struct text_pos saved_pos;
15689 Lisp_Object saved_object;
15690 struct face *face;
15692 saved_object = it->object;
15693 saved_pos = it->position;
15695 it->what = IT_CHARACTER;
15696 bzero (&it->position, sizeof it->position);
15697 it->object = make_number (0);
15698 it->c = ' ';
15699 it->len = 1;
15701 if (default_face_p)
15702 it->face_id = DEFAULT_FACE_ID;
15703 else if (it->face_before_selective_p)
15704 it->face_id = it->saved_face_id;
15705 face = FACE_FROM_ID (it->f, it->face_id);
15706 it->face_id = FACE_FOR_CHAR (it->f, face, 0);
15708 PRODUCE_GLYPHS (it);
15710 it->override_ascent = -1;
15711 it->constrain_row_ascent_descent_p = 0;
15712 it->current_x = saved_x;
15713 it->object = saved_object;
15714 it->position = saved_pos;
15715 it->what = saved_what;
15716 it->face_id = saved_face_id;
15717 it->len = saved_len;
15718 it->c = saved_c;
15719 return 1;
15723 return 0;
15727 /* Extend the face of the last glyph in the text area of IT->glyph_row
15728 to the end of the display line. Called from display_line.
15729 If the glyph row is empty, add a space glyph to it so that we
15730 know the face to draw. Set the glyph row flag fill_line_p. */
15732 static void
15733 extend_face_to_end_of_line (it)
15734 struct it *it;
15736 struct face *face;
15737 struct frame *f = it->f;
15739 /* If line is already filled, do nothing. */
15740 if (it->current_x >= it->last_visible_x)
15741 return;
15743 /* Face extension extends the background and box of IT->face_id
15744 to the end of the line. If the background equals the background
15745 of the frame, we don't have to do anything. */
15746 if (it->face_before_selective_p)
15747 face = FACE_FROM_ID (it->f, it->saved_face_id);
15748 else
15749 face = FACE_FROM_ID (f, it->face_id);
15751 if (FRAME_WINDOW_P (f)
15752 && it->glyph_row->displays_text_p
15753 && face->box == FACE_NO_BOX
15754 && face->background == FRAME_BACKGROUND_PIXEL (f)
15755 && !face->stipple)
15756 return;
15758 /* Set the glyph row flag indicating that the face of the last glyph
15759 in the text area has to be drawn to the end of the text area. */
15760 it->glyph_row->fill_line_p = 1;
15762 /* If current character of IT is not ASCII, make sure we have the
15763 ASCII face. This will be automatically undone the next time
15764 get_next_display_element returns a multibyte character. Note
15765 that the character will always be single byte in unibyte text. */
15766 if (!SINGLE_BYTE_CHAR_P (it->c))
15768 it->face_id = FACE_FOR_CHAR (f, face, 0);
15771 if (FRAME_WINDOW_P (f))
15773 /* If the row is empty, add a space with the current face of IT,
15774 so that we know which face to draw. */
15775 if (it->glyph_row->used[TEXT_AREA] == 0)
15777 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
15778 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
15779 it->glyph_row->used[TEXT_AREA] = 1;
15782 else
15784 /* Save some values that must not be changed. */
15785 int saved_x = it->current_x;
15786 struct text_pos saved_pos;
15787 Lisp_Object saved_object;
15788 enum display_element_type saved_what = it->what;
15789 int saved_face_id = it->face_id;
15791 saved_object = it->object;
15792 saved_pos = it->position;
15794 it->what = IT_CHARACTER;
15795 bzero (&it->position, sizeof it->position);
15796 it->object = make_number (0);
15797 it->c = ' ';
15798 it->len = 1;
15799 it->face_id = face->id;
15801 PRODUCE_GLYPHS (it);
15803 while (it->current_x <= it->last_visible_x)
15804 PRODUCE_GLYPHS (it);
15806 /* Don't count these blanks really. It would let us insert a left
15807 truncation glyph below and make us set the cursor on them, maybe. */
15808 it->current_x = saved_x;
15809 it->object = saved_object;
15810 it->position = saved_pos;
15811 it->what = saved_what;
15812 it->face_id = saved_face_id;
15817 /* Value is non-zero if text starting at CHARPOS in current_buffer is
15818 trailing whitespace. */
15820 static int
15821 trailing_whitespace_p (charpos)
15822 int charpos;
15824 int bytepos = CHAR_TO_BYTE (charpos);
15825 int c = 0;
15827 while (bytepos < ZV_BYTE
15828 && (c = FETCH_CHAR (bytepos),
15829 c == ' ' || c == '\t'))
15830 ++bytepos;
15832 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
15834 if (bytepos != PT_BYTE)
15835 return 1;
15837 return 0;
15841 /* Highlight trailing whitespace, if any, in ROW. */
15843 void
15844 highlight_trailing_whitespace (f, row)
15845 struct frame *f;
15846 struct glyph_row *row;
15848 int used = row->used[TEXT_AREA];
15850 if (used)
15852 struct glyph *start = row->glyphs[TEXT_AREA];
15853 struct glyph *glyph = start + used - 1;
15855 /* Skip over glyphs inserted to display the cursor at the
15856 end of a line, for extending the face of the last glyph
15857 to the end of the line on terminals, and for truncation
15858 and continuation glyphs. */
15859 while (glyph >= start
15860 && glyph->type == CHAR_GLYPH
15861 && INTEGERP (glyph->object))
15862 --glyph;
15864 /* If last glyph is a space or stretch, and it's trailing
15865 whitespace, set the face of all trailing whitespace glyphs in
15866 IT->glyph_row to `trailing-whitespace'. */
15867 if (glyph >= start
15868 && BUFFERP (glyph->object)
15869 && (glyph->type == STRETCH_GLYPH
15870 || (glyph->type == CHAR_GLYPH
15871 && glyph->u.ch == ' '))
15872 && trailing_whitespace_p (glyph->charpos))
15874 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0, 0);
15875 if (face_id < 0)
15876 return;
15878 while (glyph >= start
15879 && BUFFERP (glyph->object)
15880 && (glyph->type == STRETCH_GLYPH
15881 || (glyph->type == CHAR_GLYPH
15882 && glyph->u.ch == ' ')))
15883 (glyph--)->face_id = face_id;
15889 /* Value is non-zero if glyph row ROW in window W should be
15890 used to hold the cursor. */
15892 static int
15893 cursor_row_p (w, row)
15894 struct window *w;
15895 struct glyph_row *row;
15897 int cursor_row_p = 1;
15899 if (PT == MATRIX_ROW_END_CHARPOS (row))
15901 /* Suppose the row ends on a string.
15902 Unless the row is continued, that means it ends on a newline
15903 in the string. If it's anything other than a display string
15904 (e.g. a before-string from an overlay), we don't want the
15905 cursor there. (This heuristic seems to give the optimal
15906 behavior for the various types of multi-line strings.) */
15907 if (CHARPOS (row->end.string_pos) >= 0)
15909 if (row->continued_p)
15910 cursor_row_p = 1;
15911 else
15913 /* Check for `display' property. */
15914 struct glyph *beg = row->glyphs[TEXT_AREA];
15915 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
15916 struct glyph *glyph;
15918 cursor_row_p = 0;
15919 for (glyph = end; glyph >= beg; --glyph)
15920 if (STRINGP (glyph->object))
15922 Lisp_Object prop
15923 = Fget_char_property (make_number (PT),
15924 Qdisplay, Qnil);
15925 cursor_row_p =
15926 (!NILP (prop)
15927 && display_prop_string_p (prop, glyph->object));
15928 break;
15932 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
15934 /* If the row ends in middle of a real character,
15935 and the line is continued, we want the cursor here.
15936 That's because MATRIX_ROW_END_CHARPOS would equal
15937 PT if PT is before the character. */
15938 if (!row->ends_in_ellipsis_p)
15939 cursor_row_p = row->continued_p;
15940 else
15941 /* If the row ends in an ellipsis, then
15942 MATRIX_ROW_END_CHARPOS will equal point after the invisible text.
15943 We want that position to be displayed after the ellipsis. */
15944 cursor_row_p = 0;
15946 /* If the row ends at ZV, display the cursor at the end of that
15947 row instead of at the start of the row below. */
15948 else if (row->ends_at_zv_p)
15949 cursor_row_p = 1;
15950 else
15951 cursor_row_p = 0;
15954 return cursor_row_p;
15958 /* Construct the glyph row IT->glyph_row in the desired matrix of
15959 IT->w from text at the current position of IT. See dispextern.h
15960 for an overview of struct it. Value is non-zero if
15961 IT->glyph_row displays text, as opposed to a line displaying ZV
15962 only. */
15964 static int
15965 display_line (it)
15966 struct it *it;
15968 struct glyph_row *row = it->glyph_row;
15969 Lisp_Object overlay_arrow_string;
15971 /* We always start displaying at hpos zero even if hscrolled. */
15972 xassert (it->hpos == 0 && it->current_x == 0);
15974 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
15975 >= it->w->desired_matrix->nrows)
15977 it->w->nrows_scale_factor++;
15978 fonts_changed_p = 1;
15979 return 0;
15982 /* Is IT->w showing the region? */
15983 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
15985 /* Clear the result glyph row and enable it. */
15986 prepare_desired_row (row);
15988 row->y = it->current_y;
15989 row->start = it->start;
15990 row->continuation_lines_width = it->continuation_lines_width;
15991 row->displays_text_p = 1;
15992 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
15993 it->starts_in_middle_of_char_p = 0;
15995 /* Arrange the overlays nicely for our purposes. Usually, we call
15996 display_line on only one line at a time, in which case this
15997 can't really hurt too much, or we call it on lines which appear
15998 one after another in the buffer, in which case all calls to
15999 recenter_overlay_lists but the first will be pretty cheap. */
16000 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
16002 /* Move over display elements that are not visible because we are
16003 hscrolled. This may stop at an x-position < IT->first_visible_x
16004 if the first glyph is partially visible or if we hit a line end. */
16005 if (it->current_x < it->first_visible_x)
16007 move_it_in_display_line_to (it, ZV, it->first_visible_x,
16008 MOVE_TO_POS | MOVE_TO_X);
16011 /* Get the initial row height. This is either the height of the
16012 text hscrolled, if there is any, or zero. */
16013 row->ascent = it->max_ascent;
16014 row->height = it->max_ascent + it->max_descent;
16015 row->phys_ascent = it->max_phys_ascent;
16016 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
16017 row->extra_line_spacing = it->max_extra_line_spacing;
16019 /* Loop generating characters. The loop is left with IT on the next
16020 character to display. */
16021 while (1)
16023 int n_glyphs_before, hpos_before, x_before;
16024 int x, i, nglyphs;
16025 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
16027 /* Retrieve the next thing to display. Value is zero if end of
16028 buffer reached. */
16029 if (!get_next_display_element (it))
16031 /* Maybe add a space at the end of this line that is used to
16032 display the cursor there under X. Set the charpos of the
16033 first glyph of blank lines not corresponding to any text
16034 to -1. */
16035 #ifdef HAVE_WINDOW_SYSTEM
16036 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
16037 row->exact_window_width_line_p = 1;
16038 else
16039 #endif /* HAVE_WINDOW_SYSTEM */
16040 if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
16041 || row->used[TEXT_AREA] == 0)
16043 row->glyphs[TEXT_AREA]->charpos = -1;
16044 row->displays_text_p = 0;
16046 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
16047 && (!MINI_WINDOW_P (it->w)
16048 || (minibuf_level && EQ (it->window, minibuf_window))))
16049 row->indicate_empty_line_p = 1;
16052 it->continuation_lines_width = 0;
16053 row->ends_at_zv_p = 1;
16054 break;
16057 /* Now, get the metrics of what we want to display. This also
16058 generates glyphs in `row' (which is IT->glyph_row). */
16059 n_glyphs_before = row->used[TEXT_AREA];
16060 x = it->current_x;
16062 /* Remember the line height so far in case the next element doesn't
16063 fit on the line. */
16064 if (!it->truncate_lines_p)
16066 ascent = it->max_ascent;
16067 descent = it->max_descent;
16068 phys_ascent = it->max_phys_ascent;
16069 phys_descent = it->max_phys_descent;
16072 PRODUCE_GLYPHS (it);
16074 /* If this display element was in marginal areas, continue with
16075 the next one. */
16076 if (it->area != TEXT_AREA)
16078 row->ascent = max (row->ascent, it->max_ascent);
16079 row->height = max (row->height, it->max_ascent + it->max_descent);
16080 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16081 row->phys_height = max (row->phys_height,
16082 it->max_phys_ascent + it->max_phys_descent);
16083 row->extra_line_spacing = max (row->extra_line_spacing,
16084 it->max_extra_line_spacing);
16085 set_iterator_to_next (it, 1);
16086 continue;
16089 /* Does the display element fit on the line? If we truncate
16090 lines, we should draw past the right edge of the window. If
16091 we don't truncate, we want to stop so that we can display the
16092 continuation glyph before the right margin. If lines are
16093 continued, there are two possible strategies for characters
16094 resulting in more than 1 glyph (e.g. tabs): Display as many
16095 glyphs as possible in this line and leave the rest for the
16096 continuation line, or display the whole element in the next
16097 line. Original redisplay did the former, so we do it also. */
16098 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
16099 hpos_before = it->hpos;
16100 x_before = x;
16102 if (/* Not a newline. */
16103 nglyphs > 0
16104 /* Glyphs produced fit entirely in the line. */
16105 && it->current_x < it->last_visible_x)
16107 it->hpos += nglyphs;
16108 row->ascent = max (row->ascent, it->max_ascent);
16109 row->height = max (row->height, it->max_ascent + it->max_descent);
16110 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16111 row->phys_height = max (row->phys_height,
16112 it->max_phys_ascent + it->max_phys_descent);
16113 row->extra_line_spacing = max (row->extra_line_spacing,
16114 it->max_extra_line_spacing);
16115 if (it->current_x - it->pixel_width < it->first_visible_x)
16116 row->x = x - it->first_visible_x;
16118 else
16120 int new_x;
16121 struct glyph *glyph;
16123 for (i = 0; i < nglyphs; ++i, x = new_x)
16125 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
16126 new_x = x + glyph->pixel_width;
16128 if (/* Lines are continued. */
16129 !it->truncate_lines_p
16130 && (/* Glyph doesn't fit on the line. */
16131 new_x > it->last_visible_x
16132 /* Or it fits exactly on a window system frame. */
16133 || (new_x == it->last_visible_x
16134 && FRAME_WINDOW_P (it->f))))
16136 /* End of a continued line. */
16138 if (it->hpos == 0
16139 || (new_x == it->last_visible_x
16140 && FRAME_WINDOW_P (it->f)))
16142 /* Current glyph is the only one on the line or
16143 fits exactly on the line. We must continue
16144 the line because we can't draw the cursor
16145 after the glyph. */
16146 row->continued_p = 1;
16147 it->current_x = new_x;
16148 it->continuation_lines_width += new_x;
16149 ++it->hpos;
16150 if (i == nglyphs - 1)
16152 set_iterator_to_next (it, 1);
16153 #ifdef HAVE_WINDOW_SYSTEM
16154 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
16156 if (!get_next_display_element (it))
16158 row->exact_window_width_line_p = 1;
16159 it->continuation_lines_width = 0;
16160 row->continued_p = 0;
16161 row->ends_at_zv_p = 1;
16163 else if (ITERATOR_AT_END_OF_LINE_P (it))
16165 row->continued_p = 0;
16166 row->exact_window_width_line_p = 1;
16169 #endif /* HAVE_WINDOW_SYSTEM */
16172 else if (CHAR_GLYPH_PADDING_P (*glyph)
16173 && !FRAME_WINDOW_P (it->f))
16175 /* A padding glyph that doesn't fit on this line.
16176 This means the whole character doesn't fit
16177 on the line. */
16178 row->used[TEXT_AREA] = n_glyphs_before;
16180 /* Fill the rest of the row with continuation
16181 glyphs like in 20.x. */
16182 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
16183 < row->glyphs[1 + TEXT_AREA])
16184 produce_special_glyphs (it, IT_CONTINUATION);
16186 row->continued_p = 1;
16187 it->current_x = x_before;
16188 it->continuation_lines_width += x_before;
16190 /* Restore the height to what it was before the
16191 element not fitting on the line. */
16192 it->max_ascent = ascent;
16193 it->max_descent = descent;
16194 it->max_phys_ascent = phys_ascent;
16195 it->max_phys_descent = phys_descent;
16197 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
16199 /* A TAB that extends past the right edge of the
16200 window. This produces a single glyph on
16201 window system frames. We leave the glyph in
16202 this row and let it fill the row, but don't
16203 consume the TAB. */
16204 it->continuation_lines_width += it->last_visible_x;
16205 row->ends_in_middle_of_char_p = 1;
16206 row->continued_p = 1;
16207 glyph->pixel_width = it->last_visible_x - x;
16208 it->starts_in_middle_of_char_p = 1;
16210 else
16212 /* Something other than a TAB that draws past
16213 the right edge of the window. Restore
16214 positions to values before the element. */
16215 row->used[TEXT_AREA] = n_glyphs_before + i;
16217 /* Display continuation glyphs. */
16218 if (!FRAME_WINDOW_P (it->f))
16219 produce_special_glyphs (it, IT_CONTINUATION);
16220 row->continued_p = 1;
16222 it->current_x = x_before;
16223 it->continuation_lines_width += x;
16224 extend_face_to_end_of_line (it);
16226 if (nglyphs > 1 && i > 0)
16228 row->ends_in_middle_of_char_p = 1;
16229 it->starts_in_middle_of_char_p = 1;
16232 /* Restore the height to what it was before the
16233 element not fitting on the line. */
16234 it->max_ascent = ascent;
16235 it->max_descent = descent;
16236 it->max_phys_ascent = phys_ascent;
16237 it->max_phys_descent = phys_descent;
16240 break;
16242 else if (new_x > it->first_visible_x)
16244 /* Increment number of glyphs actually displayed. */
16245 ++it->hpos;
16247 if (x < it->first_visible_x)
16248 /* Glyph is partially visible, i.e. row starts at
16249 negative X position. */
16250 row->x = x - it->first_visible_x;
16252 else
16254 /* Glyph is completely off the left margin of the
16255 window. This should not happen because of the
16256 move_it_in_display_line at the start of this
16257 function, unless the text display area of the
16258 window is empty. */
16259 xassert (it->first_visible_x <= it->last_visible_x);
16263 row->ascent = max (row->ascent, it->max_ascent);
16264 row->height = max (row->height, it->max_ascent + it->max_descent);
16265 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16266 row->phys_height = max (row->phys_height,
16267 it->max_phys_ascent + it->max_phys_descent);
16268 row->extra_line_spacing = max (row->extra_line_spacing,
16269 it->max_extra_line_spacing);
16271 /* End of this display line if row is continued. */
16272 if (row->continued_p || row->ends_at_zv_p)
16273 break;
16276 at_end_of_line:
16277 /* Is this a line end? If yes, we're also done, after making
16278 sure that a non-default face is extended up to the right
16279 margin of the window. */
16280 if (ITERATOR_AT_END_OF_LINE_P (it))
16282 int used_before = row->used[TEXT_AREA];
16284 row->ends_in_newline_from_string_p = STRINGP (it->object);
16286 #ifdef HAVE_WINDOW_SYSTEM
16287 /* Add a space at the end of the line that is used to
16288 display the cursor there. */
16289 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
16290 append_space_for_newline (it, 0);
16291 #endif /* HAVE_WINDOW_SYSTEM */
16293 /* Extend the face to the end of the line. */
16294 extend_face_to_end_of_line (it);
16296 /* Make sure we have the position. */
16297 if (used_before == 0)
16298 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
16300 /* Consume the line end. This skips over invisible lines. */
16301 set_iterator_to_next (it, 1);
16302 it->continuation_lines_width = 0;
16303 break;
16306 /* Proceed with next display element. Note that this skips
16307 over lines invisible because of selective display. */
16308 set_iterator_to_next (it, 1);
16310 /* If we truncate lines, we are done when the last displayed
16311 glyphs reach past the right margin of the window. */
16312 if (it->truncate_lines_p
16313 && (FRAME_WINDOW_P (it->f)
16314 ? (it->current_x >= it->last_visible_x)
16315 : (it->current_x > it->last_visible_x)))
16317 /* Maybe add truncation glyphs. */
16318 if (!FRAME_WINDOW_P (it->f))
16320 int i, n;
16322 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
16323 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
16324 break;
16326 for (n = row->used[TEXT_AREA]; i < n; ++i)
16328 row->used[TEXT_AREA] = i;
16329 produce_special_glyphs (it, IT_TRUNCATION);
16332 #ifdef HAVE_WINDOW_SYSTEM
16333 else
16335 /* Don't truncate if we can overflow newline into fringe. */
16336 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
16338 if (!get_next_display_element (it))
16340 it->continuation_lines_width = 0;
16341 row->ends_at_zv_p = 1;
16342 row->exact_window_width_line_p = 1;
16343 break;
16345 if (ITERATOR_AT_END_OF_LINE_P (it))
16347 row->exact_window_width_line_p = 1;
16348 goto at_end_of_line;
16352 #endif /* HAVE_WINDOW_SYSTEM */
16354 row->truncated_on_right_p = 1;
16355 it->continuation_lines_width = 0;
16356 reseat_at_next_visible_line_start (it, 0);
16357 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
16358 it->hpos = hpos_before;
16359 it->current_x = x_before;
16360 break;
16364 /* If line is not empty and hscrolled, maybe insert truncation glyphs
16365 at the left window margin. */
16366 if (it->first_visible_x
16367 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
16369 if (!FRAME_WINDOW_P (it->f))
16370 insert_left_trunc_glyphs (it);
16371 row->truncated_on_left_p = 1;
16374 /* If the start of this line is the overlay arrow-position, then
16375 mark this glyph row as the one containing the overlay arrow.
16376 This is clearly a mess with variable size fonts. It would be
16377 better to let it be displayed like cursors under X. */
16378 if ((row->displays_text_p || !overlay_arrow_seen)
16379 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
16380 !NILP (overlay_arrow_string)))
16382 /* Overlay arrow in window redisplay is a fringe bitmap. */
16383 if (STRINGP (overlay_arrow_string))
16385 struct glyph_row *arrow_row
16386 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
16387 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
16388 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
16389 struct glyph *p = row->glyphs[TEXT_AREA];
16390 struct glyph *p2, *end;
16392 /* Copy the arrow glyphs. */
16393 while (glyph < arrow_end)
16394 *p++ = *glyph++;
16396 /* Throw away padding glyphs. */
16397 p2 = p;
16398 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
16399 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
16400 ++p2;
16401 if (p2 > p)
16403 while (p2 < end)
16404 *p++ = *p2++;
16405 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
16408 else
16410 xassert (INTEGERP (overlay_arrow_string));
16411 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
16413 overlay_arrow_seen = 1;
16416 /* Compute pixel dimensions of this line. */
16417 compute_line_metrics (it);
16419 /* Remember the position at which this line ends. */
16420 row->end = it->current;
16422 /* Record whether this row ends inside an ellipsis. */
16423 row->ends_in_ellipsis_p
16424 = (it->method == GET_FROM_DISPLAY_VECTOR
16425 && it->ellipsis_p);
16427 /* Save fringe bitmaps in this row. */
16428 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
16429 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
16430 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
16431 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
16433 it->left_user_fringe_bitmap = 0;
16434 it->left_user_fringe_face_id = 0;
16435 it->right_user_fringe_bitmap = 0;
16436 it->right_user_fringe_face_id = 0;
16438 /* Maybe set the cursor. */
16439 if (it->w->cursor.vpos < 0
16440 && PT >= MATRIX_ROW_START_CHARPOS (row)
16441 && PT <= MATRIX_ROW_END_CHARPOS (row)
16442 && cursor_row_p (it->w, row))
16443 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
16445 /* Highlight trailing whitespace. */
16446 if (!NILP (Vshow_trailing_whitespace))
16447 highlight_trailing_whitespace (it->f, it->glyph_row);
16449 /* Prepare for the next line. This line starts horizontally at (X
16450 HPOS) = (0 0). Vertical positions are incremented. As a
16451 convenience for the caller, IT->glyph_row is set to the next
16452 row to be used. */
16453 it->current_x = it->hpos = 0;
16454 it->current_y += row->height;
16455 ++it->vpos;
16456 ++it->glyph_row;
16457 it->start = it->current;
16458 return row->displays_text_p;
16463 /***********************************************************************
16464 Menu Bar
16465 ***********************************************************************/
16467 /* Redisplay the menu bar in the frame for window W.
16469 The menu bar of X frames that don't have X toolkit support is
16470 displayed in a special window W->frame->menu_bar_window.
16472 The menu bar of terminal frames is treated specially as far as
16473 glyph matrices are concerned. Menu bar lines are not part of
16474 windows, so the update is done directly on the frame matrix rows
16475 for the menu bar. */
16477 static void
16478 display_menu_bar (w)
16479 struct window *w;
16481 struct frame *f = XFRAME (WINDOW_FRAME (w));
16482 struct it it;
16483 Lisp_Object items;
16484 int i;
16486 /* Don't do all this for graphical frames. */
16487 #ifdef HAVE_NTGUI
16488 if (FRAME_W32_P (f))
16489 return;
16490 #endif
16491 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
16492 if (FRAME_X_P (f))
16493 return;
16494 #endif
16495 #ifdef MAC_OS
16496 if (FRAME_MAC_P (f))
16497 return;
16498 #endif
16500 #ifdef USE_X_TOOLKIT
16501 xassert (!FRAME_WINDOW_P (f));
16502 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
16503 it.first_visible_x = 0;
16504 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
16505 #else /* not USE_X_TOOLKIT */
16506 if (FRAME_WINDOW_P (f))
16508 /* Menu bar lines are displayed in the desired matrix of the
16509 dummy window menu_bar_window. */
16510 struct window *menu_w;
16511 xassert (WINDOWP (f->menu_bar_window));
16512 menu_w = XWINDOW (f->menu_bar_window);
16513 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
16514 MENU_FACE_ID);
16515 it.first_visible_x = 0;
16516 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
16518 else
16520 /* This is a TTY frame, i.e. character hpos/vpos are used as
16521 pixel x/y. */
16522 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
16523 MENU_FACE_ID);
16524 it.first_visible_x = 0;
16525 it.last_visible_x = FRAME_COLS (f);
16527 #endif /* not USE_X_TOOLKIT */
16529 if (! mode_line_inverse_video)
16530 /* Force the menu-bar to be displayed in the default face. */
16531 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
16533 /* Clear all rows of the menu bar. */
16534 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
16536 struct glyph_row *row = it.glyph_row + i;
16537 clear_glyph_row (row);
16538 row->enabled_p = 1;
16539 row->full_width_p = 1;
16542 /* Display all items of the menu bar. */
16543 items = FRAME_MENU_BAR_ITEMS (it.f);
16544 for (i = 0; i < XVECTOR (items)->size; i += 4)
16546 Lisp_Object string;
16548 /* Stop at nil string. */
16549 string = AREF (items, i + 1);
16550 if (NILP (string))
16551 break;
16553 /* Remember where item was displayed. */
16554 AREF (items, i + 3) = make_number (it.hpos);
16556 /* Display the item, pad with one space. */
16557 if (it.current_x < it.last_visible_x)
16558 display_string (NULL, string, Qnil, 0, 0, &it,
16559 SCHARS (string) + 1, 0, 0, -1);
16562 /* Fill out the line with spaces. */
16563 if (it.current_x < it.last_visible_x)
16564 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
16566 /* Compute the total height of the lines. */
16567 compute_line_metrics (&it);
16572 /***********************************************************************
16573 Mode Line
16574 ***********************************************************************/
16576 /* Redisplay mode lines in the window tree whose root is WINDOW. If
16577 FORCE is non-zero, redisplay mode lines unconditionally.
16578 Otherwise, redisplay only mode lines that are garbaged. Value is
16579 the number of windows whose mode lines were redisplayed. */
16581 static int
16582 redisplay_mode_lines (window, force)
16583 Lisp_Object window;
16584 int force;
16586 int nwindows = 0;
16588 while (!NILP (window))
16590 struct window *w = XWINDOW (window);
16592 if (WINDOWP (w->hchild))
16593 nwindows += redisplay_mode_lines (w->hchild, force);
16594 else if (WINDOWP (w->vchild))
16595 nwindows += redisplay_mode_lines (w->vchild, force);
16596 else if (force
16597 || FRAME_GARBAGED_P (XFRAME (w->frame))
16598 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
16600 struct text_pos lpoint;
16601 struct buffer *old = current_buffer;
16603 /* Set the window's buffer for the mode line display. */
16604 SET_TEXT_POS (lpoint, PT, PT_BYTE);
16605 set_buffer_internal_1 (XBUFFER (w->buffer));
16607 /* Point refers normally to the selected window. For any
16608 other window, set up appropriate value. */
16609 if (!EQ (window, selected_window))
16611 struct text_pos pt;
16613 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
16614 if (CHARPOS (pt) < BEGV)
16615 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
16616 else if (CHARPOS (pt) > (ZV - 1))
16617 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
16618 else
16619 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
16622 /* Display mode lines. */
16623 clear_glyph_matrix (w->desired_matrix);
16624 if (display_mode_lines (w))
16626 ++nwindows;
16627 w->must_be_updated_p = 1;
16630 /* Restore old settings. */
16631 set_buffer_internal_1 (old);
16632 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
16635 window = w->next;
16638 return nwindows;
16642 /* Display the mode and/or top line of window W. Value is the number
16643 of mode lines displayed. */
16645 static int
16646 display_mode_lines (w)
16647 struct window *w;
16649 Lisp_Object old_selected_window, old_selected_frame;
16650 int n = 0;
16652 old_selected_frame = selected_frame;
16653 selected_frame = w->frame;
16654 old_selected_window = selected_window;
16655 XSETWINDOW (selected_window, w);
16657 /* These will be set while the mode line specs are processed. */
16658 line_number_displayed = 0;
16659 w->column_number_displayed = Qnil;
16661 if (WINDOW_WANTS_MODELINE_P (w))
16663 struct window *sel_w = XWINDOW (old_selected_window);
16665 /* Select mode line face based on the real selected window. */
16666 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
16667 current_buffer->mode_line_format);
16668 ++n;
16671 if (WINDOW_WANTS_HEADER_LINE_P (w))
16673 display_mode_line (w, HEADER_LINE_FACE_ID,
16674 current_buffer->header_line_format);
16675 ++n;
16678 selected_frame = old_selected_frame;
16679 selected_window = old_selected_window;
16680 return n;
16684 /* Display mode or top line of window W. FACE_ID specifies which line
16685 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
16686 FORMAT is the mode line format to display. Value is the pixel
16687 height of the mode line displayed. */
16689 static int
16690 display_mode_line (w, face_id, format)
16691 struct window *w;
16692 enum face_id face_id;
16693 Lisp_Object format;
16695 struct it it;
16696 struct face *face;
16697 int count = SPECPDL_INDEX ();
16699 init_iterator (&it, w, -1, -1, NULL, face_id);
16700 /* Don't extend on a previously drawn mode-line.
16701 This may happen if called from pos_visible_p. */
16702 it.glyph_row->enabled_p = 0;
16703 prepare_desired_row (it.glyph_row);
16705 it.glyph_row->mode_line_p = 1;
16707 if (! mode_line_inverse_video)
16708 /* Force the mode-line to be displayed in the default face. */
16709 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
16711 record_unwind_protect (unwind_format_mode_line,
16712 format_mode_line_unwind_data (NULL, 0));
16714 mode_line_target = MODE_LINE_DISPLAY;
16716 /* Temporarily make frame's keyboard the current kboard so that
16717 kboard-local variables in the mode_line_format will get the right
16718 values. */
16719 push_kboard (FRAME_KBOARD (it.f));
16720 record_unwind_save_match_data ();
16721 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
16722 pop_kboard ();
16724 unbind_to (count, Qnil);
16726 /* Fill up with spaces. */
16727 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
16729 compute_line_metrics (&it);
16730 it.glyph_row->full_width_p = 1;
16731 it.glyph_row->continued_p = 0;
16732 it.glyph_row->truncated_on_left_p = 0;
16733 it.glyph_row->truncated_on_right_p = 0;
16735 /* Make a 3D mode-line have a shadow at its right end. */
16736 face = FACE_FROM_ID (it.f, face_id);
16737 extend_face_to_end_of_line (&it);
16738 if (face->box != FACE_NO_BOX)
16740 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
16741 + it.glyph_row->used[TEXT_AREA] - 1);
16742 last->right_box_line_p = 1;
16745 return it.glyph_row->height;
16748 /* Move element ELT in LIST to the front of LIST.
16749 Return the updated list. */
16751 static Lisp_Object
16752 move_elt_to_front (elt, list)
16753 Lisp_Object elt, list;
16755 register Lisp_Object tail, prev;
16756 register Lisp_Object tem;
16758 tail = list;
16759 prev = Qnil;
16760 while (CONSP (tail))
16762 tem = XCAR (tail);
16764 if (EQ (elt, tem))
16766 /* Splice out the link TAIL. */
16767 if (NILP (prev))
16768 list = XCDR (tail);
16769 else
16770 Fsetcdr (prev, XCDR (tail));
16772 /* Now make it the first. */
16773 Fsetcdr (tail, list);
16774 return tail;
16776 else
16777 prev = tail;
16778 tail = XCDR (tail);
16779 QUIT;
16782 /* Not found--return unchanged LIST. */
16783 return list;
16786 /* Contribute ELT to the mode line for window IT->w. How it
16787 translates into text depends on its data type.
16789 IT describes the display environment in which we display, as usual.
16791 DEPTH is the depth in recursion. It is used to prevent
16792 infinite recursion here.
16794 FIELD_WIDTH is the number of characters the display of ELT should
16795 occupy in the mode line, and PRECISION is the maximum number of
16796 characters to display from ELT's representation. See
16797 display_string for details.
16799 Returns the hpos of the end of the text generated by ELT.
16801 PROPS is a property list to add to any string we encounter.
16803 If RISKY is nonzero, remove (disregard) any properties in any string
16804 we encounter, and ignore :eval and :propertize.
16806 The global variable `mode_line_target' determines whether the
16807 output is passed to `store_mode_line_noprop',
16808 `store_mode_line_string', or `display_string'. */
16810 static int
16811 display_mode_element (it, depth, field_width, precision, elt, props, risky)
16812 struct it *it;
16813 int depth;
16814 int field_width, precision;
16815 Lisp_Object elt, props;
16816 int risky;
16818 int n = 0, field, prec;
16819 int literal = 0;
16821 tail_recurse:
16822 if (depth > 100)
16823 elt = build_string ("*too-deep*");
16825 depth++;
16827 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
16829 case Lisp_String:
16831 /* A string: output it and check for %-constructs within it. */
16832 unsigned char c;
16833 int offset = 0;
16835 if (SCHARS (elt) > 0
16836 && (!NILP (props) || risky))
16838 Lisp_Object oprops, aelt;
16839 oprops = Ftext_properties_at (make_number (0), elt);
16841 /* If the starting string's properties are not what
16842 we want, translate the string. Also, if the string
16843 is risky, do that anyway. */
16845 if (NILP (Fequal (props, oprops)) || risky)
16847 /* If the starting string has properties,
16848 merge the specified ones onto the existing ones. */
16849 if (! NILP (oprops) && !risky)
16851 Lisp_Object tem;
16853 oprops = Fcopy_sequence (oprops);
16854 tem = props;
16855 while (CONSP (tem))
16857 oprops = Fplist_put (oprops, XCAR (tem),
16858 XCAR (XCDR (tem)));
16859 tem = XCDR (XCDR (tem));
16861 props = oprops;
16864 aelt = Fassoc (elt, mode_line_proptrans_alist);
16865 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
16867 /* AELT is what we want. Move it to the front
16868 without consing. */
16869 elt = XCAR (aelt);
16870 mode_line_proptrans_alist
16871 = move_elt_to_front (aelt, mode_line_proptrans_alist);
16873 else
16875 Lisp_Object tem;
16877 /* If AELT has the wrong props, it is useless.
16878 so get rid of it. */
16879 if (! NILP (aelt))
16880 mode_line_proptrans_alist
16881 = Fdelq (aelt, mode_line_proptrans_alist);
16883 elt = Fcopy_sequence (elt);
16884 Fset_text_properties (make_number (0), Flength (elt),
16885 props, elt);
16886 /* Add this item to mode_line_proptrans_alist. */
16887 mode_line_proptrans_alist
16888 = Fcons (Fcons (elt, props),
16889 mode_line_proptrans_alist);
16890 /* Truncate mode_line_proptrans_alist
16891 to at most 50 elements. */
16892 tem = Fnthcdr (make_number (50),
16893 mode_line_proptrans_alist);
16894 if (! NILP (tem))
16895 XSETCDR (tem, Qnil);
16900 offset = 0;
16902 if (literal)
16904 prec = precision - n;
16905 switch (mode_line_target)
16907 case MODE_LINE_NOPROP:
16908 case MODE_LINE_TITLE:
16909 n += store_mode_line_noprop (SDATA (elt), -1, prec);
16910 break;
16911 case MODE_LINE_STRING:
16912 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
16913 break;
16914 case MODE_LINE_DISPLAY:
16915 n += display_string (NULL, elt, Qnil, 0, 0, it,
16916 0, prec, 0, STRING_MULTIBYTE (elt));
16917 break;
16920 break;
16923 /* Handle the non-literal case. */
16925 while ((precision <= 0 || n < precision)
16926 && SREF (elt, offset) != 0
16927 && (mode_line_target != MODE_LINE_DISPLAY
16928 || it->current_x < it->last_visible_x))
16930 int last_offset = offset;
16932 /* Advance to end of string or next format specifier. */
16933 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
16936 if (offset - 1 != last_offset)
16938 int nchars, nbytes;
16940 /* Output to end of string or up to '%'. Field width
16941 is length of string. Don't output more than
16942 PRECISION allows us. */
16943 offset--;
16945 prec = c_string_width (SDATA (elt) + last_offset,
16946 offset - last_offset, precision - n,
16947 &nchars, &nbytes);
16949 switch (mode_line_target)
16951 case MODE_LINE_NOPROP:
16952 case MODE_LINE_TITLE:
16953 n += store_mode_line_noprop (SDATA (elt) + last_offset, 0, prec);
16954 break;
16955 case MODE_LINE_STRING:
16957 int bytepos = last_offset;
16958 int charpos = string_byte_to_char (elt, bytepos);
16959 int endpos = (precision <= 0
16960 ? string_byte_to_char (elt, offset)
16961 : charpos + nchars);
16963 n += store_mode_line_string (NULL,
16964 Fsubstring (elt, make_number (charpos),
16965 make_number (endpos)),
16966 0, 0, 0, Qnil);
16968 break;
16969 case MODE_LINE_DISPLAY:
16971 int bytepos = last_offset;
16972 int charpos = string_byte_to_char (elt, bytepos);
16974 if (precision <= 0)
16975 nchars = string_byte_to_char (elt, offset) - charpos;
16976 n += display_string (NULL, elt, Qnil, 0, charpos,
16977 it, 0, nchars, 0,
16978 STRING_MULTIBYTE (elt));
16980 break;
16983 else /* c == '%' */
16985 int percent_position = offset;
16987 /* Get the specified minimum width. Zero means
16988 don't pad. */
16989 field = 0;
16990 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
16991 field = field * 10 + c - '0';
16993 /* Don't pad beyond the total padding allowed. */
16994 if (field_width - n > 0 && field > field_width - n)
16995 field = field_width - n;
16997 /* Note that either PRECISION <= 0 or N < PRECISION. */
16998 prec = precision - n;
17000 if (c == 'M')
17001 n += display_mode_element (it, depth, field, prec,
17002 Vglobal_mode_string, props,
17003 risky);
17004 else if (c != 0)
17006 int multibyte;
17007 int bytepos, charpos;
17008 unsigned char *spec;
17010 bytepos = percent_position;
17011 charpos = (STRING_MULTIBYTE (elt)
17012 ? string_byte_to_char (elt, bytepos)
17013 : bytepos);
17015 spec
17016 = decode_mode_spec (it->w, c, field, prec, &multibyte);
17018 switch (mode_line_target)
17020 case MODE_LINE_NOPROP:
17021 case MODE_LINE_TITLE:
17022 n += store_mode_line_noprop (spec, field, prec);
17023 break;
17024 case MODE_LINE_STRING:
17026 int len = strlen (spec);
17027 Lisp_Object tem = make_string (spec, len);
17028 props = Ftext_properties_at (make_number (charpos), elt);
17029 /* Should only keep face property in props */
17030 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
17032 break;
17033 case MODE_LINE_DISPLAY:
17035 int nglyphs_before, nwritten;
17037 nglyphs_before = it->glyph_row->used[TEXT_AREA];
17038 nwritten = display_string (spec, Qnil, elt,
17039 charpos, 0, it,
17040 field, prec, 0,
17041 multibyte);
17043 /* Assign to the glyphs written above the
17044 string where the `%x' came from, position
17045 of the `%'. */
17046 if (nwritten > 0)
17048 struct glyph *glyph
17049 = (it->glyph_row->glyphs[TEXT_AREA]
17050 + nglyphs_before);
17051 int i;
17053 for (i = 0; i < nwritten; ++i)
17055 glyph[i].object = elt;
17056 glyph[i].charpos = charpos;
17059 n += nwritten;
17062 break;
17065 else /* c == 0 */
17066 break;
17070 break;
17072 case Lisp_Symbol:
17073 /* A symbol: process the value of the symbol recursively
17074 as if it appeared here directly. Avoid error if symbol void.
17075 Special case: if value of symbol is a string, output the string
17076 literally. */
17078 register Lisp_Object tem;
17080 /* If the variable is not marked as risky to set
17081 then its contents are risky to use. */
17082 if (NILP (Fget (elt, Qrisky_local_variable)))
17083 risky = 1;
17085 tem = Fboundp (elt);
17086 if (!NILP (tem))
17088 tem = Fsymbol_value (elt);
17089 /* If value is a string, output that string literally:
17090 don't check for % within it. */
17091 if (STRINGP (tem))
17092 literal = 1;
17094 if (!EQ (tem, elt))
17096 /* Give up right away for nil or t. */
17097 elt = tem;
17098 goto tail_recurse;
17102 break;
17104 case Lisp_Cons:
17106 register Lisp_Object car, tem;
17108 /* A cons cell: five distinct cases.
17109 If first element is :eval or :propertize, do something special.
17110 If first element is a string or a cons, process all the elements
17111 and effectively concatenate them.
17112 If first element is a negative number, truncate displaying cdr to
17113 at most that many characters. If positive, pad (with spaces)
17114 to at least that many characters.
17115 If first element is a symbol, process the cadr or caddr recursively
17116 according to whether the symbol's value is non-nil or nil. */
17117 car = XCAR (elt);
17118 if (EQ (car, QCeval))
17120 /* An element of the form (:eval FORM) means evaluate FORM
17121 and use the result as mode line elements. */
17123 if (risky)
17124 break;
17126 if (CONSP (XCDR (elt)))
17128 Lisp_Object spec;
17129 spec = safe_eval (XCAR (XCDR (elt)));
17130 n += display_mode_element (it, depth, field_width - n,
17131 precision - n, spec, props,
17132 risky);
17135 else if (EQ (car, QCpropertize))
17137 /* An element of the form (:propertize ELT PROPS...)
17138 means display ELT but applying properties PROPS. */
17140 if (risky)
17141 break;
17143 if (CONSP (XCDR (elt)))
17144 n += display_mode_element (it, depth, field_width - n,
17145 precision - n, XCAR (XCDR (elt)),
17146 XCDR (XCDR (elt)), risky);
17148 else if (SYMBOLP (car))
17150 tem = Fboundp (car);
17151 elt = XCDR (elt);
17152 if (!CONSP (elt))
17153 goto invalid;
17154 /* elt is now the cdr, and we know it is a cons cell.
17155 Use its car if CAR has a non-nil value. */
17156 if (!NILP (tem))
17158 tem = Fsymbol_value (car);
17159 if (!NILP (tem))
17161 elt = XCAR (elt);
17162 goto tail_recurse;
17165 /* Symbol's value is nil (or symbol is unbound)
17166 Get the cddr of the original list
17167 and if possible find the caddr and use that. */
17168 elt = XCDR (elt);
17169 if (NILP (elt))
17170 break;
17171 else if (!CONSP (elt))
17172 goto invalid;
17173 elt = XCAR (elt);
17174 goto tail_recurse;
17176 else if (INTEGERP (car))
17178 register int lim = XINT (car);
17179 elt = XCDR (elt);
17180 if (lim < 0)
17182 /* Negative int means reduce maximum width. */
17183 if (precision <= 0)
17184 precision = -lim;
17185 else
17186 precision = min (precision, -lim);
17188 else if (lim > 0)
17190 /* Padding specified. Don't let it be more than
17191 current maximum. */
17192 if (precision > 0)
17193 lim = min (precision, lim);
17195 /* If that's more padding than already wanted, queue it.
17196 But don't reduce padding already specified even if
17197 that is beyond the current truncation point. */
17198 field_width = max (lim, field_width);
17200 goto tail_recurse;
17202 else if (STRINGP (car) || CONSP (car))
17204 register int limit = 50;
17205 /* Limit is to protect against circular lists. */
17206 while (CONSP (elt)
17207 && --limit > 0
17208 && (precision <= 0 || n < precision))
17210 n += display_mode_element (it, depth,
17211 /* Do padding only after the last
17212 element in the list. */
17213 (! CONSP (XCDR (elt))
17214 ? field_width - n
17215 : 0),
17216 precision - n, XCAR (elt),
17217 props, risky);
17218 elt = XCDR (elt);
17222 break;
17224 default:
17225 invalid:
17226 elt = build_string ("*invalid*");
17227 goto tail_recurse;
17230 /* Pad to FIELD_WIDTH. */
17231 if (field_width > 0 && n < field_width)
17233 switch (mode_line_target)
17235 case MODE_LINE_NOPROP:
17236 case MODE_LINE_TITLE:
17237 n += store_mode_line_noprop ("", field_width - n, 0);
17238 break;
17239 case MODE_LINE_STRING:
17240 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
17241 break;
17242 case MODE_LINE_DISPLAY:
17243 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
17244 0, 0, 0);
17245 break;
17249 return n;
17252 /* Store a mode-line string element in mode_line_string_list.
17254 If STRING is non-null, display that C string. Otherwise, the Lisp
17255 string LISP_STRING is displayed.
17257 FIELD_WIDTH is the minimum number of output glyphs to produce.
17258 If STRING has fewer characters than FIELD_WIDTH, pad to the right
17259 with spaces. FIELD_WIDTH <= 0 means don't pad.
17261 PRECISION is the maximum number of characters to output from
17262 STRING. PRECISION <= 0 means don't truncate the string.
17264 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
17265 properties to the string.
17267 PROPS are the properties to add to the string.
17268 The mode_line_string_face face property is always added to the string.
17271 static int
17272 store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
17273 char *string;
17274 Lisp_Object lisp_string;
17275 int copy_string;
17276 int field_width;
17277 int precision;
17278 Lisp_Object props;
17280 int len;
17281 int n = 0;
17283 if (string != NULL)
17285 len = strlen (string);
17286 if (precision > 0 && len > precision)
17287 len = precision;
17288 lisp_string = make_string (string, len);
17289 if (NILP (props))
17290 props = mode_line_string_face_prop;
17291 else if (!NILP (mode_line_string_face))
17293 Lisp_Object face = Fplist_get (props, Qface);
17294 props = Fcopy_sequence (props);
17295 if (NILP (face))
17296 face = mode_line_string_face;
17297 else
17298 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
17299 props = Fplist_put (props, Qface, face);
17301 Fadd_text_properties (make_number (0), make_number (len),
17302 props, lisp_string);
17304 else
17306 len = XFASTINT (Flength (lisp_string));
17307 if (precision > 0 && len > precision)
17309 len = precision;
17310 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
17311 precision = -1;
17313 if (!NILP (mode_line_string_face))
17315 Lisp_Object face;
17316 if (NILP (props))
17317 props = Ftext_properties_at (make_number (0), lisp_string);
17318 face = Fplist_get (props, Qface);
17319 if (NILP (face))
17320 face = mode_line_string_face;
17321 else
17322 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
17323 props = Fcons (Qface, Fcons (face, Qnil));
17324 if (copy_string)
17325 lisp_string = Fcopy_sequence (lisp_string);
17327 if (!NILP (props))
17328 Fadd_text_properties (make_number (0), make_number (len),
17329 props, lisp_string);
17332 if (len > 0)
17334 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
17335 n += len;
17338 if (field_width > len)
17340 field_width -= len;
17341 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
17342 if (!NILP (props))
17343 Fadd_text_properties (make_number (0), make_number (field_width),
17344 props, lisp_string);
17345 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
17346 n += field_width;
17349 return n;
17353 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
17354 1, 4, 0,
17355 doc: /* Format a string out of a mode line format specification.
17356 First arg FORMAT specifies the mode line format (see `mode-line-format'
17357 for details) to use.
17359 Optional second arg FACE specifies the face property to put
17360 on all characters for which no face is specified.
17361 The value t means whatever face the window's mode line currently uses
17362 \(either `mode-line' or `mode-line-inactive', depending).
17363 A value of nil means the default is no face property.
17364 If FACE is an integer, the value string has no text properties.
17366 Optional third and fourth args WINDOW and BUFFER specify the window
17367 and buffer to use as the context for the formatting (defaults
17368 are the selected window and the window's buffer). */)
17369 (format, face, window, buffer)
17370 Lisp_Object format, face, window, buffer;
17372 struct it it;
17373 int len;
17374 struct window *w;
17375 struct buffer *old_buffer = NULL;
17376 int face_id = -1;
17377 int no_props = INTEGERP (face);
17378 int count = SPECPDL_INDEX ();
17379 Lisp_Object str;
17380 int string_start = 0;
17382 if (NILP (window))
17383 window = selected_window;
17384 CHECK_WINDOW (window);
17385 w = XWINDOW (window);
17387 if (NILP (buffer))
17388 buffer = w->buffer;
17389 CHECK_BUFFER (buffer);
17391 if (NILP (format))
17392 return empty_unibyte_string;
17394 if (no_props)
17395 face = Qnil;
17397 if (!NILP (face))
17399 if (EQ (face, Qt))
17400 face = (EQ (window, selected_window) ? Qmode_line : Qmode_line_inactive);
17401 face_id = lookup_named_face (XFRAME (WINDOW_FRAME (w)), face, 0, 0);
17404 if (face_id < 0)
17405 face_id = DEFAULT_FACE_ID;
17407 if (XBUFFER (buffer) != current_buffer)
17408 old_buffer = current_buffer;
17410 /* Save things including mode_line_proptrans_alist,
17411 and set that to nil so that we don't alter the outer value. */
17412 record_unwind_protect (unwind_format_mode_line,
17413 format_mode_line_unwind_data (old_buffer, 1));
17414 mode_line_proptrans_alist = Qnil;
17416 if (old_buffer)
17417 set_buffer_internal_1 (XBUFFER (buffer));
17419 init_iterator (&it, w, -1, -1, NULL, face_id);
17421 if (no_props)
17423 mode_line_target = MODE_LINE_NOPROP;
17424 mode_line_string_face_prop = Qnil;
17425 mode_line_string_list = Qnil;
17426 string_start = MODE_LINE_NOPROP_LEN (0);
17428 else
17430 mode_line_target = MODE_LINE_STRING;
17431 mode_line_string_list = Qnil;
17432 mode_line_string_face = face;
17433 mode_line_string_face_prop
17434 = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil)));
17437 push_kboard (FRAME_KBOARD (it.f));
17438 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
17439 pop_kboard ();
17441 if (no_props)
17443 len = MODE_LINE_NOPROP_LEN (string_start);
17444 str = make_string (mode_line_noprop_buf + string_start, len);
17446 else
17448 mode_line_string_list = Fnreverse (mode_line_string_list);
17449 str = Fmapconcat (intern ("identity"), mode_line_string_list,
17450 empty_unibyte_string);
17453 unbind_to (count, Qnil);
17454 return str;
17457 /* Write a null-terminated, right justified decimal representation of
17458 the positive integer D to BUF using a minimal field width WIDTH. */
17460 static void
17461 pint2str (buf, width, d)
17462 register char *buf;
17463 register int width;
17464 register int d;
17466 register char *p = buf;
17468 if (d <= 0)
17469 *p++ = '0';
17470 else
17472 while (d > 0)
17474 *p++ = d % 10 + '0';
17475 d /= 10;
17479 for (width -= (int) (p - buf); width > 0; --width)
17480 *p++ = ' ';
17481 *p-- = '\0';
17482 while (p > buf)
17484 d = *buf;
17485 *buf++ = *p;
17486 *p-- = d;
17490 /* Write a null-terminated, right justified decimal and "human
17491 readable" representation of the nonnegative integer D to BUF using
17492 a minimal field width WIDTH. D should be smaller than 999.5e24. */
17494 static const char power_letter[] =
17496 0, /* not used */
17497 'k', /* kilo */
17498 'M', /* mega */
17499 'G', /* giga */
17500 'T', /* tera */
17501 'P', /* peta */
17502 'E', /* exa */
17503 'Z', /* zetta */
17504 'Y' /* yotta */
17507 static void
17508 pint2hrstr (buf, width, d)
17509 char *buf;
17510 int width;
17511 int d;
17513 /* We aim to represent the nonnegative integer D as
17514 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
17515 int quotient = d;
17516 int remainder = 0;
17517 /* -1 means: do not use TENTHS. */
17518 int tenths = -1;
17519 int exponent = 0;
17521 /* Length of QUOTIENT.TENTHS as a string. */
17522 int length;
17524 char * psuffix;
17525 char * p;
17527 if (1000 <= quotient)
17529 /* Scale to the appropriate EXPONENT. */
17532 remainder = quotient % 1000;
17533 quotient /= 1000;
17534 exponent++;
17536 while (1000 <= quotient);
17538 /* Round to nearest and decide whether to use TENTHS or not. */
17539 if (quotient <= 9)
17541 tenths = remainder / 100;
17542 if (50 <= remainder % 100)
17544 if (tenths < 9)
17545 tenths++;
17546 else
17548 quotient++;
17549 if (quotient == 10)
17550 tenths = -1;
17551 else
17552 tenths = 0;
17556 else
17557 if (500 <= remainder)
17559 if (quotient < 999)
17560 quotient++;
17561 else
17563 quotient = 1;
17564 exponent++;
17565 tenths = 0;
17570 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
17571 if (tenths == -1 && quotient <= 99)
17572 if (quotient <= 9)
17573 length = 1;
17574 else
17575 length = 2;
17576 else
17577 length = 3;
17578 p = psuffix = buf + max (width, length);
17580 /* Print EXPONENT. */
17581 if (exponent)
17582 *psuffix++ = power_letter[exponent];
17583 *psuffix = '\0';
17585 /* Print TENTHS. */
17586 if (tenths >= 0)
17588 *--p = '0' + tenths;
17589 *--p = '.';
17592 /* Print QUOTIENT. */
17595 int digit = quotient % 10;
17596 *--p = '0' + digit;
17598 while ((quotient /= 10) != 0);
17600 /* Print leading spaces. */
17601 while (buf < p)
17602 *--p = ' ';
17605 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
17606 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
17607 type of CODING_SYSTEM. Return updated pointer into BUF. */
17609 static unsigned char invalid_eol_type[] = "(*invalid*)";
17611 static char *
17612 decode_mode_spec_coding (coding_system, buf, eol_flag)
17613 Lisp_Object coding_system;
17614 register char *buf;
17615 int eol_flag;
17617 Lisp_Object val;
17618 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
17619 const unsigned char *eol_str;
17620 int eol_str_len;
17621 /* The EOL conversion we are using. */
17622 Lisp_Object eoltype;
17624 val = Fget (coding_system, Qcoding_system);
17625 eoltype = Qnil;
17627 if (!VECTORP (val)) /* Not yet decided. */
17629 if (multibyte)
17630 *buf++ = '-';
17631 if (eol_flag)
17632 eoltype = eol_mnemonic_undecided;
17633 /* Don't mention EOL conversion if it isn't decided. */
17635 else
17637 Lisp_Object eolvalue;
17639 eolvalue = Fget (coding_system, Qeol_type);
17641 if (multibyte)
17642 *buf++ = XFASTINT (AREF (val, 1));
17644 if (eol_flag)
17646 /* The EOL conversion that is normal on this system. */
17648 if (NILP (eolvalue)) /* Not yet decided. */
17649 eoltype = eol_mnemonic_undecided;
17650 else if (VECTORP (eolvalue)) /* Not yet decided. */
17651 eoltype = eol_mnemonic_undecided;
17652 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
17653 eoltype = (XFASTINT (eolvalue) == 0
17654 ? eol_mnemonic_unix
17655 : (XFASTINT (eolvalue) == 1
17656 ? eol_mnemonic_dos : eol_mnemonic_mac));
17660 if (eol_flag)
17662 /* Mention the EOL conversion if it is not the usual one. */
17663 if (STRINGP (eoltype))
17665 eol_str = SDATA (eoltype);
17666 eol_str_len = SBYTES (eoltype);
17668 else if (INTEGERP (eoltype)
17669 && CHAR_VALID_P (XINT (eoltype), 0))
17671 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
17672 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
17673 eol_str = tmp;
17675 else
17677 eol_str = invalid_eol_type;
17678 eol_str_len = sizeof (invalid_eol_type) - 1;
17680 bcopy (eol_str, buf, eol_str_len);
17681 buf += eol_str_len;
17684 return buf;
17687 /* Return a string for the output of a mode line %-spec for window W,
17688 generated by character C. PRECISION >= 0 means don't return a
17689 string longer than that value. FIELD_WIDTH > 0 means pad the
17690 string returned with spaces to that value. Return 1 in *MULTIBYTE
17691 if the result is multibyte text.
17693 Note we operate on the current buffer for most purposes,
17694 the exception being w->base_line_pos. */
17696 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
17698 static char *
17699 decode_mode_spec (w, c, field_width, precision, multibyte)
17700 struct window *w;
17701 register int c;
17702 int field_width, precision;
17703 int *multibyte;
17705 Lisp_Object obj;
17706 struct frame *f = XFRAME (WINDOW_FRAME (w));
17707 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
17708 struct buffer *b = current_buffer;
17710 obj = Qnil;
17711 *multibyte = 0;
17713 switch (c)
17715 case '*':
17716 if (!NILP (b->read_only))
17717 return "%";
17718 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
17719 return "*";
17720 return "-";
17722 case '+':
17723 /* This differs from %* only for a modified read-only buffer. */
17724 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
17725 return "*";
17726 if (!NILP (b->read_only))
17727 return "%";
17728 return "-";
17730 case '&':
17731 /* This differs from %* in ignoring read-only-ness. */
17732 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
17733 return "*";
17734 return "-";
17736 case '%':
17737 return "%";
17739 case '[':
17741 int i;
17742 char *p;
17744 if (command_loop_level > 5)
17745 return "[[[... ";
17746 p = decode_mode_spec_buf;
17747 for (i = 0; i < command_loop_level; i++)
17748 *p++ = '[';
17749 *p = 0;
17750 return decode_mode_spec_buf;
17753 case ']':
17755 int i;
17756 char *p;
17758 if (command_loop_level > 5)
17759 return " ...]]]";
17760 p = decode_mode_spec_buf;
17761 for (i = 0; i < command_loop_level; i++)
17762 *p++ = ']';
17763 *p = 0;
17764 return decode_mode_spec_buf;
17767 case '-':
17769 register int i;
17771 /* Let lots_of_dashes be a string of infinite length. */
17772 if (mode_line_target == MODE_LINE_NOPROP ||
17773 mode_line_target == MODE_LINE_STRING)
17774 return "--";
17775 if (field_width <= 0
17776 || field_width > sizeof (lots_of_dashes))
17778 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
17779 decode_mode_spec_buf[i] = '-';
17780 decode_mode_spec_buf[i] = '\0';
17781 return decode_mode_spec_buf;
17783 else
17784 return lots_of_dashes;
17787 case 'b':
17788 obj = b->name;
17789 break;
17791 case 'c':
17792 /* %c and %l are ignored in `frame-title-format'.
17793 (In redisplay_internal, the frame title is drawn _before_ the
17794 windows are updated, so the stuff which depends on actual
17795 window contents (such as %l) may fail to render properly, or
17796 even crash emacs.) */
17797 if (mode_line_target == MODE_LINE_TITLE)
17798 return "";
17799 else
17801 int col = (int) current_column (); /* iftc */
17802 w->column_number_displayed = make_number (col);
17803 pint2str (decode_mode_spec_buf, field_width, col);
17804 return decode_mode_spec_buf;
17807 case 'e':
17808 #ifndef SYSTEM_MALLOC
17810 if (NILP (Vmemory_full))
17811 return "";
17812 else
17813 return "!MEM FULL! ";
17815 #else
17816 return "";
17817 #endif
17819 case 'F':
17820 /* %F displays the frame name. */
17821 if (!NILP (f->title))
17822 return (char *) SDATA (f->title);
17823 if (f->explicit_name || ! FRAME_WINDOW_P (f))
17824 return (char *) SDATA (f->name);
17825 return "Emacs";
17827 case 'f':
17828 obj = b->filename;
17829 break;
17831 case 'i':
17833 int size = ZV - BEGV;
17834 pint2str (decode_mode_spec_buf, field_width, size);
17835 return decode_mode_spec_buf;
17838 case 'I':
17840 int size = ZV - BEGV;
17841 pint2hrstr (decode_mode_spec_buf, field_width, size);
17842 return decode_mode_spec_buf;
17845 case 'l':
17847 int startpos, startpos_byte, line, linepos, linepos_byte;
17848 int topline, nlines, junk, height;
17850 /* %c and %l are ignored in `frame-title-format'. */
17851 if (mode_line_target == MODE_LINE_TITLE)
17852 return "";
17854 startpos = XMARKER (w->start)->charpos;
17855 startpos_byte = marker_byte_position (w->start);
17856 height = WINDOW_TOTAL_LINES (w);
17858 /* If we decided that this buffer isn't suitable for line numbers,
17859 don't forget that too fast. */
17860 if (EQ (w->base_line_pos, w->buffer))
17861 goto no_value;
17862 /* But do forget it, if the window shows a different buffer now. */
17863 else if (BUFFERP (w->base_line_pos))
17864 w->base_line_pos = Qnil;
17866 /* If the buffer is very big, don't waste time. */
17867 if (INTEGERP (Vline_number_display_limit)
17868 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
17870 w->base_line_pos = Qnil;
17871 w->base_line_number = Qnil;
17872 goto no_value;
17875 if (!NILP (w->base_line_number)
17876 && !NILP (w->base_line_pos)
17877 && XFASTINT (w->base_line_pos) <= startpos)
17879 line = XFASTINT (w->base_line_number);
17880 linepos = XFASTINT (w->base_line_pos);
17881 linepos_byte = buf_charpos_to_bytepos (b, linepos);
17883 else
17885 line = 1;
17886 linepos = BUF_BEGV (b);
17887 linepos_byte = BUF_BEGV_BYTE (b);
17890 /* Count lines from base line to window start position. */
17891 nlines = display_count_lines (linepos, linepos_byte,
17892 startpos_byte,
17893 startpos, &junk);
17895 topline = nlines + line;
17897 /* Determine a new base line, if the old one is too close
17898 or too far away, or if we did not have one.
17899 "Too close" means it's plausible a scroll-down would
17900 go back past it. */
17901 if (startpos == BUF_BEGV (b))
17903 w->base_line_number = make_number (topline);
17904 w->base_line_pos = make_number (BUF_BEGV (b));
17906 else if (nlines < height + 25 || nlines > height * 3 + 50
17907 || linepos == BUF_BEGV (b))
17909 int limit = BUF_BEGV (b);
17910 int limit_byte = BUF_BEGV_BYTE (b);
17911 int position;
17912 int distance = (height * 2 + 30) * line_number_display_limit_width;
17914 if (startpos - distance > limit)
17916 limit = startpos - distance;
17917 limit_byte = CHAR_TO_BYTE (limit);
17920 nlines = display_count_lines (startpos, startpos_byte,
17921 limit_byte,
17922 - (height * 2 + 30),
17923 &position);
17924 /* If we couldn't find the lines we wanted within
17925 line_number_display_limit_width chars per line,
17926 give up on line numbers for this window. */
17927 if (position == limit_byte && limit == startpos - distance)
17929 w->base_line_pos = w->buffer;
17930 w->base_line_number = Qnil;
17931 goto no_value;
17934 w->base_line_number = make_number (topline - nlines);
17935 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
17938 /* Now count lines from the start pos to point. */
17939 nlines = display_count_lines (startpos, startpos_byte,
17940 PT_BYTE, PT, &junk);
17942 /* Record that we did display the line number. */
17943 line_number_displayed = 1;
17945 /* Make the string to show. */
17946 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
17947 return decode_mode_spec_buf;
17948 no_value:
17950 char* p = decode_mode_spec_buf;
17951 int pad = field_width - 2;
17952 while (pad-- > 0)
17953 *p++ = ' ';
17954 *p++ = '?';
17955 *p++ = '?';
17956 *p = '\0';
17957 return decode_mode_spec_buf;
17960 break;
17962 case 'm':
17963 obj = b->mode_name;
17964 break;
17966 case 'n':
17967 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
17968 return " Narrow";
17969 break;
17971 case 'p':
17973 int pos = marker_position (w->start);
17974 int total = BUF_ZV (b) - BUF_BEGV (b);
17976 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
17978 if (pos <= BUF_BEGV (b))
17979 return "All";
17980 else
17981 return "Bottom";
17983 else if (pos <= BUF_BEGV (b))
17984 return "Top";
17985 else
17987 if (total > 1000000)
17988 /* Do it differently for a large value, to avoid overflow. */
17989 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
17990 else
17991 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
17992 /* We can't normally display a 3-digit number,
17993 so get us a 2-digit number that is close. */
17994 if (total == 100)
17995 total = 99;
17996 sprintf (decode_mode_spec_buf, "%2d%%", total);
17997 return decode_mode_spec_buf;
18001 /* Display percentage of size above the bottom of the screen. */
18002 case 'P':
18004 int toppos = marker_position (w->start);
18005 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
18006 int total = BUF_ZV (b) - BUF_BEGV (b);
18008 if (botpos >= BUF_ZV (b))
18010 if (toppos <= BUF_BEGV (b))
18011 return "All";
18012 else
18013 return "Bottom";
18015 else
18017 if (total > 1000000)
18018 /* Do it differently for a large value, to avoid overflow. */
18019 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
18020 else
18021 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
18022 /* We can't normally display a 3-digit number,
18023 so get us a 2-digit number that is close. */
18024 if (total == 100)
18025 total = 99;
18026 if (toppos <= BUF_BEGV (b))
18027 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
18028 else
18029 sprintf (decode_mode_spec_buf, "%2d%%", total);
18030 return decode_mode_spec_buf;
18034 case 's':
18035 /* status of process */
18036 obj = Fget_buffer_process (Fcurrent_buffer ());
18037 if (NILP (obj))
18038 return "no process";
18039 #ifdef subprocesses
18040 obj = Fsymbol_name (Fprocess_status (obj));
18041 #endif
18042 break;
18044 case '@':
18046 Lisp_Object val;
18047 val = call1 (intern ("file-remote-p"), current_buffer->directory);
18048 if (NILP (val))
18049 return "-";
18050 else
18051 return "@";
18054 case 't': /* indicate TEXT or BINARY */
18055 #ifdef MODE_LINE_BINARY_TEXT
18056 return MODE_LINE_BINARY_TEXT (b);
18057 #else
18058 return "T";
18059 #endif
18061 case 'z':
18062 /* coding-system (not including end-of-line format) */
18063 case 'Z':
18064 /* coding-system (including end-of-line type) */
18066 int eol_flag = (c == 'Z');
18067 char *p = decode_mode_spec_buf;
18069 if (! FRAME_WINDOW_P (f))
18071 /* No need to mention EOL here--the terminal never needs
18072 to do EOL conversion. */
18073 p = decode_mode_spec_coding (FRAME_KEYBOARD_CODING (f)->symbol, p, 0);
18074 p = decode_mode_spec_coding (FRAME_TERMINAL_CODING (f)->symbol, p, 0);
18076 p = decode_mode_spec_coding (b->buffer_file_coding_system,
18077 p, eol_flag);
18079 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
18080 #ifdef subprocesses
18081 obj = Fget_buffer_process (Fcurrent_buffer ());
18082 if (PROCESSP (obj))
18084 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
18085 p, eol_flag);
18086 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
18087 p, eol_flag);
18089 #endif /* subprocesses */
18090 #endif /* 0 */
18091 *p = 0;
18092 return decode_mode_spec_buf;
18096 if (STRINGP (obj))
18098 *multibyte = STRING_MULTIBYTE (obj);
18099 return (char *) SDATA (obj);
18101 else
18102 return "";
18106 /* Count up to COUNT lines starting from START / START_BYTE.
18107 But don't go beyond LIMIT_BYTE.
18108 Return the number of lines thus found (always nonnegative).
18110 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
18112 static int
18113 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
18114 int start, start_byte, limit_byte, count;
18115 int *byte_pos_ptr;
18117 register unsigned char *cursor;
18118 unsigned char *base;
18120 register int ceiling;
18121 register unsigned char *ceiling_addr;
18122 int orig_count = count;
18124 /* If we are not in selective display mode,
18125 check only for newlines. */
18126 int selective_display = (!NILP (current_buffer->selective_display)
18127 && !INTEGERP (current_buffer->selective_display));
18129 if (count > 0)
18131 while (start_byte < limit_byte)
18133 ceiling = BUFFER_CEILING_OF (start_byte);
18134 ceiling = min (limit_byte - 1, ceiling);
18135 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
18136 base = (cursor = BYTE_POS_ADDR (start_byte));
18137 while (1)
18139 if (selective_display)
18140 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
18142 else
18143 while (*cursor != '\n' && ++cursor != ceiling_addr)
18146 if (cursor != ceiling_addr)
18148 if (--count == 0)
18150 start_byte += cursor - base + 1;
18151 *byte_pos_ptr = start_byte;
18152 return orig_count;
18154 else
18155 if (++cursor == ceiling_addr)
18156 break;
18158 else
18159 break;
18161 start_byte += cursor - base;
18164 else
18166 while (start_byte > limit_byte)
18168 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
18169 ceiling = max (limit_byte, ceiling);
18170 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
18171 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
18172 while (1)
18174 if (selective_display)
18175 while (--cursor != ceiling_addr
18176 && *cursor != '\n' && *cursor != 015)
18178 else
18179 while (--cursor != ceiling_addr && *cursor != '\n')
18182 if (cursor != ceiling_addr)
18184 if (++count == 0)
18186 start_byte += cursor - base + 1;
18187 *byte_pos_ptr = start_byte;
18188 /* When scanning backwards, we should
18189 not count the newline posterior to which we stop. */
18190 return - orig_count - 1;
18193 else
18194 break;
18196 /* Here we add 1 to compensate for the last decrement
18197 of CURSOR, which took it past the valid range. */
18198 start_byte += cursor - base + 1;
18202 *byte_pos_ptr = limit_byte;
18204 if (count < 0)
18205 return - orig_count + count;
18206 return orig_count - count;
18212 /***********************************************************************
18213 Displaying strings
18214 ***********************************************************************/
18216 /* Display a NUL-terminated string, starting with index START.
18218 If STRING is non-null, display that C string. Otherwise, the Lisp
18219 string LISP_STRING is displayed.
18221 If FACE_STRING is not nil, FACE_STRING_POS is a position in
18222 FACE_STRING. Display STRING or LISP_STRING with the face at
18223 FACE_STRING_POS in FACE_STRING:
18225 Display the string in the environment given by IT, but use the
18226 standard display table, temporarily.
18228 FIELD_WIDTH is the minimum number of output glyphs to produce.
18229 If STRING has fewer characters than FIELD_WIDTH, pad to the right
18230 with spaces. If STRING has more characters, more than FIELD_WIDTH
18231 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
18233 PRECISION is the maximum number of characters to output from
18234 STRING. PRECISION < 0 means don't truncate the string.
18236 This is roughly equivalent to printf format specifiers:
18238 FIELD_WIDTH PRECISION PRINTF
18239 ----------------------------------------
18240 -1 -1 %s
18241 -1 10 %.10s
18242 10 -1 %10s
18243 20 10 %20.10s
18245 MULTIBYTE zero means do not display multibyte chars, > 0 means do
18246 display them, and < 0 means obey the current buffer's value of
18247 enable_multibyte_characters.
18249 Value is the number of columns displayed. */
18251 static int
18252 display_string (string, lisp_string, face_string, face_string_pos,
18253 start, it, field_width, precision, max_x, multibyte)
18254 unsigned char *string;
18255 Lisp_Object lisp_string;
18256 Lisp_Object face_string;
18257 int face_string_pos;
18258 int start;
18259 struct it *it;
18260 int field_width, precision, max_x;
18261 int multibyte;
18263 int hpos_at_start = it->hpos;
18264 int saved_face_id = it->face_id;
18265 struct glyph_row *row = it->glyph_row;
18267 /* Initialize the iterator IT for iteration over STRING beginning
18268 with index START. */
18269 reseat_to_string (it, string, lisp_string, start,
18270 precision, field_width, multibyte);
18272 /* If displaying STRING, set up the face of the iterator
18273 from LISP_STRING, if that's given. */
18274 if (STRINGP (face_string))
18276 int endptr;
18277 struct face *face;
18279 it->face_id
18280 = face_at_string_position (it->w, face_string, face_string_pos,
18281 0, it->region_beg_charpos,
18282 it->region_end_charpos,
18283 &endptr, it->base_face_id, 0);
18284 face = FACE_FROM_ID (it->f, it->face_id);
18285 it->face_box_p = face->box != FACE_NO_BOX;
18288 /* Set max_x to the maximum allowed X position. Don't let it go
18289 beyond the right edge of the window. */
18290 if (max_x <= 0)
18291 max_x = it->last_visible_x;
18292 else
18293 max_x = min (max_x, it->last_visible_x);
18295 /* Skip over display elements that are not visible. because IT->w is
18296 hscrolled. */
18297 if (it->current_x < it->first_visible_x)
18298 move_it_in_display_line_to (it, 100000, it->first_visible_x,
18299 MOVE_TO_POS | MOVE_TO_X);
18301 row->ascent = it->max_ascent;
18302 row->height = it->max_ascent + it->max_descent;
18303 row->phys_ascent = it->max_phys_ascent;
18304 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
18305 row->extra_line_spacing = it->max_extra_line_spacing;
18307 /* This condition is for the case that we are called with current_x
18308 past last_visible_x. */
18309 while (it->current_x < max_x)
18311 int x_before, x, n_glyphs_before, i, nglyphs;
18313 /* Get the next display element. */
18314 if (!get_next_display_element (it))
18315 break;
18317 /* Produce glyphs. */
18318 x_before = it->current_x;
18319 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
18320 PRODUCE_GLYPHS (it);
18322 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
18323 i = 0;
18324 x = x_before;
18325 while (i < nglyphs)
18327 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
18329 if (!it->truncate_lines_p
18330 && x + glyph->pixel_width > max_x)
18332 /* End of continued line or max_x reached. */
18333 if (CHAR_GLYPH_PADDING_P (*glyph))
18335 /* A wide character is unbreakable. */
18336 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
18337 it->current_x = x_before;
18339 else
18341 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
18342 it->current_x = x;
18344 break;
18346 else if (x + glyph->pixel_width > it->first_visible_x)
18348 /* Glyph is at least partially visible. */
18349 ++it->hpos;
18350 if (x < it->first_visible_x)
18351 it->glyph_row->x = x - it->first_visible_x;
18353 else
18355 /* Glyph is off the left margin of the display area.
18356 Should not happen. */
18357 abort ();
18360 row->ascent = max (row->ascent, it->max_ascent);
18361 row->height = max (row->height, it->max_ascent + it->max_descent);
18362 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
18363 row->phys_height = max (row->phys_height,
18364 it->max_phys_ascent + it->max_phys_descent);
18365 row->extra_line_spacing = max (row->extra_line_spacing,
18366 it->max_extra_line_spacing);
18367 x += glyph->pixel_width;
18368 ++i;
18371 /* Stop if max_x reached. */
18372 if (i < nglyphs)
18373 break;
18375 /* Stop at line ends. */
18376 if (ITERATOR_AT_END_OF_LINE_P (it))
18378 it->continuation_lines_width = 0;
18379 break;
18382 set_iterator_to_next (it, 1);
18384 /* Stop if truncating at the right edge. */
18385 if (it->truncate_lines_p
18386 && it->current_x >= it->last_visible_x)
18388 /* Add truncation mark, but don't do it if the line is
18389 truncated at a padding space. */
18390 if (IT_CHARPOS (*it) < it->string_nchars)
18392 if (!FRAME_WINDOW_P (it->f))
18394 int i, n;
18396 if (it->current_x > it->last_visible_x)
18398 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
18399 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
18400 break;
18401 for (n = row->used[TEXT_AREA]; i < n; ++i)
18403 row->used[TEXT_AREA] = i;
18404 produce_special_glyphs (it, IT_TRUNCATION);
18407 produce_special_glyphs (it, IT_TRUNCATION);
18409 it->glyph_row->truncated_on_right_p = 1;
18411 break;
18415 /* Maybe insert a truncation at the left. */
18416 if (it->first_visible_x
18417 && IT_CHARPOS (*it) > 0)
18419 if (!FRAME_WINDOW_P (it->f))
18420 insert_left_trunc_glyphs (it);
18421 it->glyph_row->truncated_on_left_p = 1;
18424 it->face_id = saved_face_id;
18426 /* Value is number of columns displayed. */
18427 return it->hpos - hpos_at_start;
18432 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
18433 appears as an element of LIST or as the car of an element of LIST.
18434 If PROPVAL is a list, compare each element against LIST in that
18435 way, and return 1/2 if any element of PROPVAL is found in LIST.
18436 Otherwise return 0. This function cannot quit.
18437 The return value is 2 if the text is invisible but with an ellipsis
18438 and 1 if it's invisible and without an ellipsis. */
18441 invisible_p (propval, list)
18442 register Lisp_Object propval;
18443 Lisp_Object list;
18445 register Lisp_Object tail, proptail;
18447 for (tail = list; CONSP (tail); tail = XCDR (tail))
18449 register Lisp_Object tem;
18450 tem = XCAR (tail);
18451 if (EQ (propval, tem))
18452 return 1;
18453 if (CONSP (tem) && EQ (propval, XCAR (tem)))
18454 return NILP (XCDR (tem)) ? 1 : 2;
18457 if (CONSP (propval))
18459 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
18461 Lisp_Object propelt;
18462 propelt = XCAR (proptail);
18463 for (tail = list; CONSP (tail); tail = XCDR (tail))
18465 register Lisp_Object tem;
18466 tem = XCAR (tail);
18467 if (EQ (propelt, tem))
18468 return 1;
18469 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
18470 return NILP (XCDR (tem)) ? 1 : 2;
18475 return 0;
18478 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
18479 doc: /* Non-nil if the property makes the text invisible.
18480 POS-OR-PROP can be a marker or number, in which case it is taken to be
18481 a position in the current buffer and the value of the `invisible' property
18482 is checked; or it can be some other value, which is then presumed to be the
18483 value of the `invisible' property of the text of interest.
18484 The non-nil value returned can be t for truly invisible text or something
18485 else if the text is replaced by an ellipsis. */)
18486 (pos_or_prop)
18487 Lisp_Object pos_or_prop;
18489 Lisp_Object prop
18490 = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
18491 ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
18492 : pos_or_prop);
18493 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
18494 return (invis == 0 ? Qnil
18495 : invis == 1 ? Qt
18496 : make_number (invis));
18499 /* Calculate a width or height in pixels from a specification using
18500 the following elements:
18502 SPEC ::=
18503 NUM - a (fractional) multiple of the default font width/height
18504 (NUM) - specifies exactly NUM pixels
18505 UNIT - a fixed number of pixels, see below.
18506 ELEMENT - size of a display element in pixels, see below.
18507 (NUM . SPEC) - equals NUM * SPEC
18508 (+ SPEC SPEC ...) - add pixel values
18509 (- SPEC SPEC ...) - subtract pixel values
18510 (- SPEC) - negate pixel value
18512 NUM ::=
18513 INT or FLOAT - a number constant
18514 SYMBOL - use symbol's (buffer local) variable binding.
18516 UNIT ::=
18517 in - pixels per inch *)
18518 mm - pixels per 1/1000 meter *)
18519 cm - pixels per 1/100 meter *)
18520 width - width of current font in pixels.
18521 height - height of current font in pixels.
18523 *) using the ratio(s) defined in display-pixels-per-inch.
18525 ELEMENT ::=
18527 left-fringe - left fringe width in pixels
18528 right-fringe - right fringe width in pixels
18530 left-margin - left margin width in pixels
18531 right-margin - right margin width in pixels
18533 scroll-bar - scroll-bar area width in pixels
18535 Examples:
18537 Pixels corresponding to 5 inches:
18538 (5 . in)
18540 Total width of non-text areas on left side of window (if scroll-bar is on left):
18541 '(space :width (+ left-fringe left-margin scroll-bar))
18543 Align to first text column (in header line):
18544 '(space :align-to 0)
18546 Align to middle of text area minus half the width of variable `my-image'
18547 containing a loaded image:
18548 '(space :align-to (0.5 . (- text my-image)))
18550 Width of left margin minus width of 1 character in the default font:
18551 '(space :width (- left-margin 1))
18553 Width of left margin minus width of 2 characters in the current font:
18554 '(space :width (- left-margin (2 . width)))
18556 Center 1 character over left-margin (in header line):
18557 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
18559 Different ways to express width of left fringe plus left margin minus one pixel:
18560 '(space :width (- (+ left-fringe left-margin) (1)))
18561 '(space :width (+ left-fringe left-margin (- (1))))
18562 '(space :width (+ left-fringe left-margin (-1)))
18566 #define NUMVAL(X) \
18567 ((INTEGERP (X) || FLOATP (X)) \
18568 ? XFLOATINT (X) \
18569 : - 1)
18572 calc_pixel_width_or_height (res, it, prop, font, width_p, align_to)
18573 double *res;
18574 struct it *it;
18575 Lisp_Object prop;
18576 void *font;
18577 int width_p, *align_to;
18579 double pixels;
18581 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
18582 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
18584 if (NILP (prop))
18585 return OK_PIXELS (0);
18587 xassert (FRAME_LIVE_P (it->f));
18589 if (SYMBOLP (prop))
18591 if (SCHARS (SYMBOL_NAME (prop)) == 2)
18593 char *unit = SDATA (SYMBOL_NAME (prop));
18595 if (unit[0] == 'i' && unit[1] == 'n')
18596 pixels = 1.0;
18597 else if (unit[0] == 'm' && unit[1] == 'm')
18598 pixels = 25.4;
18599 else if (unit[0] == 'c' && unit[1] == 'm')
18600 pixels = 2.54;
18601 else
18602 pixels = 0;
18603 if (pixels > 0)
18605 double ppi;
18606 #ifdef HAVE_WINDOW_SYSTEM
18607 if (FRAME_WINDOW_P (it->f)
18608 && (ppi = (width_p
18609 ? FRAME_X_DISPLAY_INFO (it->f)->resx
18610 : FRAME_X_DISPLAY_INFO (it->f)->resy),
18611 ppi > 0))
18612 return OK_PIXELS (ppi / pixels);
18613 #endif
18615 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
18616 || (CONSP (Vdisplay_pixels_per_inch)
18617 && (ppi = (width_p
18618 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
18619 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
18620 ppi > 0)))
18621 return OK_PIXELS (ppi / pixels);
18623 return 0;
18627 #ifdef HAVE_WINDOW_SYSTEM
18628 if (EQ (prop, Qheight))
18629 return OK_PIXELS (font ? FONT_HEIGHT ((XFontStruct *)font) : FRAME_LINE_HEIGHT (it->f));
18630 if (EQ (prop, Qwidth))
18631 return OK_PIXELS (font ? FONT_WIDTH ((XFontStruct *)font) : FRAME_COLUMN_WIDTH (it->f));
18632 #else
18633 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
18634 return OK_PIXELS (1);
18635 #endif
18637 if (EQ (prop, Qtext))
18638 return OK_PIXELS (width_p
18639 ? window_box_width (it->w, TEXT_AREA)
18640 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
18642 if (align_to && *align_to < 0)
18644 *res = 0;
18645 if (EQ (prop, Qleft))
18646 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
18647 if (EQ (prop, Qright))
18648 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
18649 if (EQ (prop, Qcenter))
18650 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
18651 + window_box_width (it->w, TEXT_AREA) / 2);
18652 if (EQ (prop, Qleft_fringe))
18653 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
18654 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
18655 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
18656 if (EQ (prop, Qright_fringe))
18657 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
18658 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
18659 : window_box_right_offset (it->w, TEXT_AREA));
18660 if (EQ (prop, Qleft_margin))
18661 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
18662 if (EQ (prop, Qright_margin))
18663 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
18664 if (EQ (prop, Qscroll_bar))
18665 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
18667 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
18668 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
18669 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
18670 : 0)));
18672 else
18674 if (EQ (prop, Qleft_fringe))
18675 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
18676 if (EQ (prop, Qright_fringe))
18677 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
18678 if (EQ (prop, Qleft_margin))
18679 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
18680 if (EQ (prop, Qright_margin))
18681 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
18682 if (EQ (prop, Qscroll_bar))
18683 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
18686 prop = Fbuffer_local_value (prop, it->w->buffer);
18689 if (INTEGERP (prop) || FLOATP (prop))
18691 int base_unit = (width_p
18692 ? FRAME_COLUMN_WIDTH (it->f)
18693 : FRAME_LINE_HEIGHT (it->f));
18694 return OK_PIXELS (XFLOATINT (prop) * base_unit);
18697 if (CONSP (prop))
18699 Lisp_Object car = XCAR (prop);
18700 Lisp_Object cdr = XCDR (prop);
18702 if (SYMBOLP (car))
18704 #ifdef HAVE_WINDOW_SYSTEM
18705 if (FRAME_WINDOW_P (it->f)
18706 && valid_image_p (prop))
18708 int id = lookup_image (it->f, prop);
18709 struct image *img = IMAGE_FROM_ID (it->f, id);
18711 return OK_PIXELS (width_p ? img->width : img->height);
18713 #endif
18714 if (EQ (car, Qplus) || EQ (car, Qminus))
18716 int first = 1;
18717 double px;
18719 pixels = 0;
18720 while (CONSP (cdr))
18722 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
18723 font, width_p, align_to))
18724 return 0;
18725 if (first)
18726 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
18727 else
18728 pixels += px;
18729 cdr = XCDR (cdr);
18731 if (EQ (car, Qminus))
18732 pixels = -pixels;
18733 return OK_PIXELS (pixels);
18736 car = Fbuffer_local_value (car, it->w->buffer);
18739 if (INTEGERP (car) || FLOATP (car))
18741 double fact;
18742 pixels = XFLOATINT (car);
18743 if (NILP (cdr))
18744 return OK_PIXELS (pixels);
18745 if (calc_pixel_width_or_height (&fact, it, cdr,
18746 font, width_p, align_to))
18747 return OK_PIXELS (pixels * fact);
18748 return 0;
18751 return 0;
18754 return 0;
18758 /***********************************************************************
18759 Glyph Display
18760 ***********************************************************************/
18762 #ifdef HAVE_WINDOW_SYSTEM
18764 #if GLYPH_DEBUG
18766 void
18767 dump_glyph_string (s)
18768 struct glyph_string *s;
18770 fprintf (stderr, "glyph string\n");
18771 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
18772 s->x, s->y, s->width, s->height);
18773 fprintf (stderr, " ybase = %d\n", s->ybase);
18774 fprintf (stderr, " hl = %d\n", s->hl);
18775 fprintf (stderr, " left overhang = %d, right = %d\n",
18776 s->left_overhang, s->right_overhang);
18777 fprintf (stderr, " nchars = %d\n", s->nchars);
18778 fprintf (stderr, " extends to end of line = %d\n",
18779 s->extends_to_end_of_line_p);
18780 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
18781 fprintf (stderr, " bg width = %d\n", s->background_width);
18784 #endif /* GLYPH_DEBUG */
18786 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
18787 of XChar2b structures for S; it can't be allocated in
18788 init_glyph_string because it must be allocated via `alloca'. W
18789 is the window on which S is drawn. ROW and AREA are the glyph row
18790 and area within the row from which S is constructed. START is the
18791 index of the first glyph structure covered by S. HL is a
18792 face-override for drawing S. */
18794 #ifdef HAVE_NTGUI
18795 #define OPTIONAL_HDC(hdc) hdc,
18796 #define DECLARE_HDC(hdc) HDC hdc;
18797 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
18798 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
18799 #endif
18801 #ifndef OPTIONAL_HDC
18802 #define OPTIONAL_HDC(hdc)
18803 #define DECLARE_HDC(hdc)
18804 #define ALLOCATE_HDC(hdc, f)
18805 #define RELEASE_HDC(hdc, f)
18806 #endif
18808 static void
18809 init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
18810 struct glyph_string *s;
18811 DECLARE_HDC (hdc)
18812 XChar2b *char2b;
18813 struct window *w;
18814 struct glyph_row *row;
18815 enum glyph_row_area area;
18816 int start;
18817 enum draw_glyphs_face hl;
18819 bzero (s, sizeof *s);
18820 s->w = w;
18821 s->f = XFRAME (w->frame);
18822 #ifdef HAVE_NTGUI
18823 s->hdc = hdc;
18824 #endif
18825 s->display = FRAME_X_DISPLAY (s->f);
18826 s->window = FRAME_X_WINDOW (s->f);
18827 s->char2b = char2b;
18828 s->hl = hl;
18829 s->row = row;
18830 s->area = area;
18831 s->first_glyph = row->glyphs[area] + start;
18832 s->height = row->height;
18833 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
18835 /* Display the internal border below the tool-bar window. */
18836 if (WINDOWP (s->f->tool_bar_window)
18837 && s->w == XWINDOW (s->f->tool_bar_window))
18838 s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
18840 s->ybase = s->y + row->ascent;
18844 /* Append the list of glyph strings with head H and tail T to the list
18845 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
18847 static INLINE void
18848 append_glyph_string_lists (head, tail, h, t)
18849 struct glyph_string **head, **tail;
18850 struct glyph_string *h, *t;
18852 if (h)
18854 if (*head)
18855 (*tail)->next = h;
18856 else
18857 *head = h;
18858 h->prev = *tail;
18859 *tail = t;
18864 /* Prepend the list of glyph strings with head H and tail T to the
18865 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
18866 result. */
18868 static INLINE void
18869 prepend_glyph_string_lists (head, tail, h, t)
18870 struct glyph_string **head, **tail;
18871 struct glyph_string *h, *t;
18873 if (h)
18875 if (*head)
18876 (*head)->prev = t;
18877 else
18878 *tail = t;
18879 t->next = *head;
18880 *head = h;
18885 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
18886 Set *HEAD and *TAIL to the resulting list. */
18888 static INLINE void
18889 append_glyph_string (head, tail, s)
18890 struct glyph_string **head, **tail;
18891 struct glyph_string *s;
18893 s->next = s->prev = NULL;
18894 append_glyph_string_lists (head, tail, s, s);
18898 /* Get face and two-byte form of character glyph GLYPH on frame F.
18899 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
18900 a pointer to a realized face that is ready for display. */
18902 static INLINE struct face *
18903 get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
18904 struct frame *f;
18905 struct glyph *glyph;
18906 XChar2b *char2b;
18907 int *two_byte_p;
18909 struct face *face;
18911 xassert (glyph->type == CHAR_GLYPH);
18912 face = FACE_FROM_ID (f, glyph->face_id);
18914 if (two_byte_p)
18915 *two_byte_p = 0;
18917 if (!glyph->multibyte_p)
18919 /* Unibyte case. We don't have to encode, but we have to make
18920 sure to use a face suitable for unibyte. */
18921 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
18923 else if (glyph->u.ch < 128)
18925 /* Case of ASCII in a face known to fit ASCII. */
18926 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
18928 else
18930 int c1, c2, charset;
18932 /* Split characters into bytes. If c2 is -1 afterwards, C is
18933 really a one-byte character so that byte1 is zero. */
18934 SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
18935 if (c2 > 0)
18936 STORE_XCHAR2B (char2b, c1, c2);
18937 else
18938 STORE_XCHAR2B (char2b, 0, c1);
18940 /* Maybe encode the character in *CHAR2B. */
18941 if (charset != CHARSET_ASCII)
18943 struct font_info *font_info
18944 = FONT_INFO_FROM_ID (f, face->font_info_id);
18945 if (font_info)
18946 glyph->font_type
18947 = FRAME_RIF (f)->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
18951 /* Make sure X resources of the face are allocated. */
18952 xassert (face != NULL);
18953 PREPARE_FACE_FOR_DISPLAY (f, face);
18954 return face;
18958 /* Fill glyph string S with composition components specified by S->cmp.
18960 FACES is an array of faces for all components of this composition.
18961 S->gidx is the index of the first component for S.
18963 OVERLAPS non-zero means S should draw the foreground only, and use
18964 its physical height for clipping. See also draw_glyphs.
18966 Value is the index of a component not in S. */
18968 static int
18969 fill_composite_glyph_string (s, faces, overlaps)
18970 struct glyph_string *s;
18971 struct face **faces;
18972 int overlaps;
18974 int i;
18976 xassert (s);
18978 s->for_overlaps = overlaps;
18980 s->face = faces[s->gidx];
18981 s->font = s->face->font;
18982 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
18984 /* For all glyphs of this composition, starting at the offset
18985 S->gidx, until we reach the end of the definition or encounter a
18986 glyph that requires the different face, add it to S. */
18987 ++s->nchars;
18988 for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
18989 ++s->nchars;
18991 /* All glyph strings for the same composition has the same width,
18992 i.e. the width set for the first component of the composition. */
18994 s->width = s->first_glyph->pixel_width;
18996 /* If the specified font could not be loaded, use the frame's
18997 default font, but record the fact that we couldn't load it in
18998 the glyph string so that we can draw rectangles for the
18999 characters of the glyph string. */
19000 if (s->font == NULL)
19002 s->font_not_found_p = 1;
19003 s->font = FRAME_FONT (s->f);
19006 /* Adjust base line for subscript/superscript text. */
19007 s->ybase += s->first_glyph->voffset;
19009 xassert (s->face && s->face->gc);
19011 /* This glyph string must always be drawn with 16-bit functions. */
19012 s->two_byte_p = 1;
19014 return s->gidx + s->nchars;
19018 /* Fill glyph string S from a sequence of character glyphs.
19020 FACE_ID is the face id of the string. START is the index of the
19021 first glyph to consider, END is the index of the last + 1.
19022 OVERLAPS non-zero means S should draw the foreground only, and use
19023 its physical height for clipping. See also draw_glyphs.
19025 Value is the index of the first glyph not in S. */
19027 static int
19028 fill_glyph_string (s, face_id, start, end, overlaps)
19029 struct glyph_string *s;
19030 int face_id;
19031 int start, end, overlaps;
19033 struct glyph *glyph, *last;
19034 int voffset;
19035 int glyph_not_available_p;
19037 xassert (s->f == XFRAME (s->w->frame));
19038 xassert (s->nchars == 0);
19039 xassert (start >= 0 && end > start);
19041 s->for_overlaps = overlaps,
19042 glyph = s->row->glyphs[s->area] + start;
19043 last = s->row->glyphs[s->area] + end;
19044 voffset = glyph->voffset;
19046 glyph_not_available_p = glyph->glyph_not_available_p;
19048 while (glyph < last
19049 && glyph->type == CHAR_GLYPH
19050 && glyph->voffset == voffset
19051 /* Same face id implies same font, nowadays. */
19052 && glyph->face_id == face_id
19053 && glyph->glyph_not_available_p == glyph_not_available_p)
19055 int two_byte_p;
19057 s->face = get_glyph_face_and_encoding (s->f, glyph,
19058 s->char2b + s->nchars,
19059 &two_byte_p);
19060 s->two_byte_p = two_byte_p;
19061 ++s->nchars;
19062 xassert (s->nchars <= end - start);
19063 s->width += glyph->pixel_width;
19064 ++glyph;
19067 s->font = s->face->font;
19068 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
19070 /* If the specified font could not be loaded, use the frame's font,
19071 but record the fact that we couldn't load it in
19072 S->font_not_found_p so that we can draw rectangles for the
19073 characters of the glyph string. */
19074 if (s->font == NULL || glyph_not_available_p)
19076 s->font_not_found_p = 1;
19077 s->font = FRAME_FONT (s->f);
19080 /* Adjust base line for subscript/superscript text. */
19081 s->ybase += voffset;
19083 xassert (s->face && s->face->gc);
19084 return glyph - s->row->glyphs[s->area];
19088 /* Fill glyph string S from image glyph S->first_glyph. */
19090 static void
19091 fill_image_glyph_string (s)
19092 struct glyph_string *s;
19094 xassert (s->first_glyph->type == IMAGE_GLYPH);
19095 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
19096 xassert (s->img);
19097 s->slice = s->first_glyph->slice;
19098 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
19099 s->font = s->face->font;
19100 s->width = s->first_glyph->pixel_width;
19102 /* Adjust base line for subscript/superscript text. */
19103 s->ybase += s->first_glyph->voffset;
19107 /* Fill glyph string S from a sequence of stretch glyphs.
19109 ROW is the glyph row in which the glyphs are found, AREA is the
19110 area within the row. START is the index of the first glyph to
19111 consider, END is the index of the last + 1.
19113 Value is the index of the first glyph not in S. */
19115 static int
19116 fill_stretch_glyph_string (s, row, area, start, end)
19117 struct glyph_string *s;
19118 struct glyph_row *row;
19119 enum glyph_row_area area;
19120 int start, end;
19122 struct glyph *glyph, *last;
19123 int voffset, face_id;
19125 xassert (s->first_glyph->type == STRETCH_GLYPH);
19127 glyph = s->row->glyphs[s->area] + start;
19128 last = s->row->glyphs[s->area] + end;
19129 face_id = glyph->face_id;
19130 s->face = FACE_FROM_ID (s->f, face_id);
19131 s->font = s->face->font;
19132 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
19133 s->width = glyph->pixel_width;
19134 s->nchars = 1;
19135 voffset = glyph->voffset;
19137 for (++glyph;
19138 (glyph < last
19139 && glyph->type == STRETCH_GLYPH
19140 && glyph->voffset == voffset
19141 && glyph->face_id == face_id);
19142 ++glyph)
19143 s->width += glyph->pixel_width;
19145 /* Adjust base line for subscript/superscript text. */
19146 s->ybase += voffset;
19148 /* The case that face->gc == 0 is handled when drawing the glyph
19149 string by calling PREPARE_FACE_FOR_DISPLAY. */
19150 xassert (s->face);
19151 return glyph - s->row->glyphs[s->area];
19155 /* EXPORT for RIF:
19156 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
19157 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
19158 assumed to be zero. */
19160 void
19161 x_get_glyph_overhangs (glyph, f, left, right)
19162 struct glyph *glyph;
19163 struct frame *f;
19164 int *left, *right;
19166 *left = *right = 0;
19168 if (glyph->type == CHAR_GLYPH)
19170 XFontStruct *font;
19171 struct face *face;
19172 struct font_info *font_info;
19173 XChar2b char2b;
19174 XCharStruct *pcm;
19176 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
19177 font = face->font;
19178 font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
19179 if (font /* ++KFS: Should this be font_info ? */
19180 && (pcm = FRAME_RIF (f)->per_char_metric (font, &char2b, glyph->font_type)))
19182 if (pcm->rbearing > pcm->width)
19183 *right = pcm->rbearing - pcm->width;
19184 if (pcm->lbearing < 0)
19185 *left = -pcm->lbearing;
19191 /* Return the index of the first glyph preceding glyph string S that
19192 is overwritten by S because of S's left overhang. Value is -1
19193 if no glyphs are overwritten. */
19195 static int
19196 left_overwritten (s)
19197 struct glyph_string *s;
19199 int k;
19201 if (s->left_overhang)
19203 int x = 0, i;
19204 struct glyph *glyphs = s->row->glyphs[s->area];
19205 int first = s->first_glyph - glyphs;
19207 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
19208 x -= glyphs[i].pixel_width;
19210 k = i + 1;
19212 else
19213 k = -1;
19215 return k;
19219 /* Return the index of the first glyph preceding glyph string S that
19220 is overwriting S because of its right overhang. Value is -1 if no
19221 glyph in front of S overwrites S. */
19223 static int
19224 left_overwriting (s)
19225 struct glyph_string *s;
19227 int i, k, x;
19228 struct glyph *glyphs = s->row->glyphs[s->area];
19229 int first = s->first_glyph - glyphs;
19231 k = -1;
19232 x = 0;
19233 for (i = first - 1; i >= 0; --i)
19235 int left, right;
19236 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
19237 if (x + right > 0)
19238 k = i;
19239 x -= glyphs[i].pixel_width;
19242 return k;
19246 /* Return the index of the last glyph following glyph string S that is
19247 not overwritten by S because of S's right overhang. Value is -1 if
19248 no such glyph is found. */
19250 static int
19251 right_overwritten (s)
19252 struct glyph_string *s;
19254 int k = -1;
19256 if (s->right_overhang)
19258 int x = 0, i;
19259 struct glyph *glyphs = s->row->glyphs[s->area];
19260 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
19261 int end = s->row->used[s->area];
19263 for (i = first; i < end && s->right_overhang > x; ++i)
19264 x += glyphs[i].pixel_width;
19266 k = i;
19269 return k;
19273 /* Return the index of the last glyph following glyph string S that
19274 overwrites S because of its left overhang. Value is negative
19275 if no such glyph is found. */
19277 static int
19278 right_overwriting (s)
19279 struct glyph_string *s;
19281 int i, k, x;
19282 int end = s->row->used[s->area];
19283 struct glyph *glyphs = s->row->glyphs[s->area];
19284 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
19286 k = -1;
19287 x = 0;
19288 for (i = first; i < end; ++i)
19290 int left, right;
19291 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
19292 if (x - left < 0)
19293 k = i;
19294 x += glyphs[i].pixel_width;
19297 return k;
19301 /* Get face and two-byte form of character C in face FACE_ID on frame
19302 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
19303 means we want to display multibyte text. DISPLAY_P non-zero means
19304 make sure that X resources for the face returned are allocated.
19305 Value is a pointer to a realized face that is ready for display if
19306 DISPLAY_P is non-zero. */
19308 static INLINE struct face *
19309 get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
19310 struct frame *f;
19311 int c, face_id;
19312 XChar2b *char2b;
19313 int multibyte_p, display_p;
19315 struct face *face = FACE_FROM_ID (f, face_id);
19317 if (!multibyte_p)
19319 /* Unibyte case. We don't have to encode, but we have to make
19320 sure to use a face suitable for unibyte. */
19321 STORE_XCHAR2B (char2b, 0, c);
19322 face_id = FACE_FOR_CHAR (f, face, c);
19323 face = FACE_FROM_ID (f, face_id);
19325 else if (c < 128)
19327 /* Case of ASCII in a face known to fit ASCII. */
19328 STORE_XCHAR2B (char2b, 0, c);
19330 else
19332 int c1, c2, charset;
19334 /* Split characters into bytes. If c2 is -1 afterwards, C is
19335 really a one-byte character so that byte1 is zero. */
19336 SPLIT_CHAR (c, charset, c1, c2);
19337 if (c2 > 0)
19338 STORE_XCHAR2B (char2b, c1, c2);
19339 else
19340 STORE_XCHAR2B (char2b, 0, c1);
19342 /* Maybe encode the character in *CHAR2B. */
19343 if (face->font != NULL)
19345 struct font_info *font_info
19346 = FONT_INFO_FROM_ID (f, face->font_info_id);
19347 if (font_info)
19348 FRAME_RIF (f)->encode_char (c, char2b, font_info, 0);
19352 /* Make sure X resources of the face are allocated. */
19353 #ifdef HAVE_X_WINDOWS
19354 if (display_p)
19355 #endif
19357 xassert (face != NULL);
19358 PREPARE_FACE_FOR_DISPLAY (f, face);
19361 return face;
19365 /* Set background width of glyph string S. START is the index of the
19366 first glyph following S. LAST_X is the right-most x-position + 1
19367 in the drawing area. */
19369 static INLINE void
19370 set_glyph_string_background_width (s, start, last_x)
19371 struct glyph_string *s;
19372 int start;
19373 int last_x;
19375 /* If the face of this glyph string has to be drawn to the end of
19376 the drawing area, set S->extends_to_end_of_line_p. */
19378 if (start == s->row->used[s->area]
19379 && s->area == TEXT_AREA
19380 && ((s->row->fill_line_p
19381 && (s->hl == DRAW_NORMAL_TEXT
19382 || s->hl == DRAW_IMAGE_RAISED
19383 || s->hl == DRAW_IMAGE_SUNKEN))
19384 || s->hl == DRAW_MOUSE_FACE))
19385 s->extends_to_end_of_line_p = 1;
19387 /* If S extends its face to the end of the line, set its
19388 background_width to the distance to the right edge of the drawing
19389 area. */
19390 if (s->extends_to_end_of_line_p)
19391 s->background_width = last_x - s->x + 1;
19392 else
19393 s->background_width = s->width;
19397 /* Compute overhangs and x-positions for glyph string S and its
19398 predecessors, or successors. X is the starting x-position for S.
19399 BACKWARD_P non-zero means process predecessors. */
19401 static void
19402 compute_overhangs_and_x (s, x, backward_p)
19403 struct glyph_string *s;
19404 int x;
19405 int backward_p;
19407 if (backward_p)
19409 while (s)
19411 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
19412 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
19413 x -= s->width;
19414 s->x = x;
19415 s = s->prev;
19418 else
19420 while (s)
19422 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
19423 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
19424 s->x = x;
19425 x += s->width;
19426 s = s->next;
19433 /* The following macros are only called from draw_glyphs below.
19434 They reference the following parameters of that function directly:
19435 `w', `row', `area', and `overlap_p'
19436 as well as the following local variables:
19437 `s', `f', and `hdc' (in W32) */
19439 #ifdef HAVE_NTGUI
19440 /* On W32, silently add local `hdc' variable to argument list of
19441 init_glyph_string. */
19442 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
19443 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
19444 #else
19445 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
19446 init_glyph_string (s, char2b, w, row, area, start, hl)
19447 #endif
19449 /* Add a glyph string for a stretch glyph to the list of strings
19450 between HEAD and TAIL. START is the index of the stretch glyph in
19451 row area AREA of glyph row ROW. END is the index of the last glyph
19452 in that glyph row area. X is the current output position assigned
19453 to the new glyph string constructed. HL overrides that face of the
19454 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
19455 is the right-most x-position of the drawing area. */
19457 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
19458 and below -- keep them on one line. */
19459 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
19460 do \
19462 s = (struct glyph_string *) alloca (sizeof *s); \
19463 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
19464 START = fill_stretch_glyph_string (s, row, area, START, END); \
19465 append_glyph_string (&HEAD, &TAIL, s); \
19466 s->x = (X); \
19468 while (0)
19471 /* Add a glyph string for an image glyph to the list of strings
19472 between HEAD and TAIL. START is the index of the image glyph in
19473 row area AREA of glyph row ROW. END is the index of the last glyph
19474 in that glyph row area. X is the current output position assigned
19475 to the new glyph string constructed. HL overrides that face of the
19476 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
19477 is the right-most x-position of the drawing area. */
19479 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
19480 do \
19482 s = (struct glyph_string *) alloca (sizeof *s); \
19483 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
19484 fill_image_glyph_string (s); \
19485 append_glyph_string (&HEAD, &TAIL, s); \
19486 ++START; \
19487 s->x = (X); \
19489 while (0)
19492 /* Add a glyph string for a sequence of character glyphs to the list
19493 of strings between HEAD and TAIL. START is the index of the first
19494 glyph in row area AREA of glyph row ROW that is part of the new
19495 glyph string. END is the index of the last glyph in that glyph row
19496 area. X is the current output position assigned to the new glyph
19497 string constructed. HL overrides that face of the glyph; e.g. it
19498 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
19499 right-most x-position of the drawing area. */
19501 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
19502 do \
19504 int c, face_id; \
19505 XChar2b *char2b; \
19507 c = (row)->glyphs[area][START].u.ch; \
19508 face_id = (row)->glyphs[area][START].face_id; \
19510 s = (struct glyph_string *) alloca (sizeof *s); \
19511 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
19512 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
19513 append_glyph_string (&HEAD, &TAIL, s); \
19514 s->x = (X); \
19515 START = fill_glyph_string (s, face_id, START, END, overlaps); \
19517 while (0)
19520 /* Add a glyph string for a composite sequence to the list of strings
19521 between HEAD and TAIL. START is the index of the first glyph in
19522 row area AREA of glyph row ROW that is part of the new glyph
19523 string. END is the index of the last glyph in that glyph row area.
19524 X is the current output position assigned to the new glyph string
19525 constructed. HL overrides that face of the glyph; e.g. it is
19526 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
19527 x-position of the drawing area. */
19529 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
19530 do { \
19531 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
19532 int face_id = (row)->glyphs[area][START].face_id; \
19533 struct face *base_face = FACE_FROM_ID (f, face_id); \
19534 struct composition *cmp = composition_table[cmp_id]; \
19535 int glyph_len = cmp->glyph_len; \
19536 XChar2b *char2b; \
19537 struct face **faces; \
19538 struct glyph_string *first_s = NULL; \
19539 int n; \
19541 base_face = base_face->ascii_face; \
19542 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
19543 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
19544 /* At first, fill in `char2b' and `faces'. */ \
19545 for (n = 0; n < glyph_len; n++) \
19547 int c = COMPOSITION_GLYPH (cmp, n); \
19548 int this_face_id = FACE_FOR_CHAR (f, base_face, c); \
19549 faces[n] = FACE_FROM_ID (f, this_face_id); \
19550 get_char_face_and_encoding (f, c, this_face_id, \
19551 char2b + n, 1, 1); \
19554 /* Make glyph_strings for each glyph sequence that is drawable by \
19555 the same face, and append them to HEAD/TAIL. */ \
19556 for (n = 0; n < cmp->glyph_len;) \
19558 s = (struct glyph_string *) alloca (sizeof *s); \
19559 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \
19560 append_glyph_string (&(HEAD), &(TAIL), s); \
19561 s->cmp = cmp; \
19562 s->gidx = n; \
19563 s->x = (X); \
19565 if (n == 0) \
19566 first_s = s; \
19568 n = fill_composite_glyph_string (s, faces, overlaps); \
19571 ++START; \
19572 s = first_s; \
19573 } while (0)
19576 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
19577 of AREA of glyph row ROW on window W between indices START and END.
19578 HL overrides the face for drawing glyph strings, e.g. it is
19579 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
19580 x-positions of the drawing area.
19582 This is an ugly monster macro construct because we must use alloca
19583 to allocate glyph strings (because draw_glyphs can be called
19584 asynchronously). */
19586 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
19587 do \
19589 HEAD = TAIL = NULL; \
19590 while (START < END) \
19592 struct glyph *first_glyph = (row)->glyphs[area] + START; \
19593 switch (first_glyph->type) \
19595 case CHAR_GLYPH: \
19596 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
19597 HL, X, LAST_X); \
19598 break; \
19600 case COMPOSITE_GLYPH: \
19601 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
19602 HL, X, LAST_X); \
19603 break; \
19605 case STRETCH_GLYPH: \
19606 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
19607 HL, X, LAST_X); \
19608 break; \
19610 case IMAGE_GLYPH: \
19611 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
19612 HL, X, LAST_X); \
19613 break; \
19615 default: \
19616 abort (); \
19619 set_glyph_string_background_width (s, START, LAST_X); \
19620 (X) += s->width; \
19623 while (0)
19626 /* Draw glyphs between START and END in AREA of ROW on window W,
19627 starting at x-position X. X is relative to AREA in W. HL is a
19628 face-override with the following meaning:
19630 DRAW_NORMAL_TEXT draw normally
19631 DRAW_CURSOR draw in cursor face
19632 DRAW_MOUSE_FACE draw in mouse face.
19633 DRAW_INVERSE_VIDEO draw in mode line face
19634 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
19635 DRAW_IMAGE_RAISED draw an image with a raised relief around it
19637 If OVERLAPS is non-zero, draw only the foreground of characters and
19638 clip to the physical height of ROW. Non-zero value also defines
19639 the overlapping part to be drawn:
19641 OVERLAPS_PRED overlap with preceding rows
19642 OVERLAPS_SUCC overlap with succeeding rows
19643 OVERLAPS_BOTH overlap with both preceding/succeeding rows
19644 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
19646 Value is the x-position reached, relative to AREA of W. */
19648 static int
19649 draw_glyphs (w, x, row, area, start, end, hl, overlaps)
19650 struct window *w;
19651 int x;
19652 struct glyph_row *row;
19653 enum glyph_row_area area;
19654 int start, end;
19655 enum draw_glyphs_face hl;
19656 int overlaps;
19658 struct glyph_string *head, *tail;
19659 struct glyph_string *s;
19660 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
19661 int last_x, area_width;
19662 int x_reached;
19663 int i, j;
19664 struct frame *f = XFRAME (WINDOW_FRAME (w));
19665 DECLARE_HDC (hdc);
19667 ALLOCATE_HDC (hdc, f);
19669 /* Let's rather be paranoid than getting a SEGV. */
19670 end = min (end, row->used[area]);
19671 start = max (0, start);
19672 start = min (end, start);
19674 /* Translate X to frame coordinates. Set last_x to the right
19675 end of the drawing area. */
19676 if (row->full_width_p)
19678 /* X is relative to the left edge of W, without scroll bars
19679 or fringes. */
19680 x += WINDOW_LEFT_EDGE_X (w);
19681 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
19683 else
19685 int area_left = window_box_left (w, area);
19686 x += area_left;
19687 area_width = window_box_width (w, area);
19688 last_x = area_left + area_width;
19691 /* Build a doubly-linked list of glyph_string structures between
19692 head and tail from what we have to draw. Note that the macro
19693 BUILD_GLYPH_STRINGS will modify its start parameter. That's
19694 the reason we use a separate variable `i'. */
19695 i = start;
19696 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
19697 if (tail)
19698 x_reached = tail->x + tail->background_width;
19699 else
19700 x_reached = x;
19702 /* If there are any glyphs with lbearing < 0 or rbearing > width in
19703 the row, redraw some glyphs in front or following the glyph
19704 strings built above. */
19705 if (head && !overlaps && row->contains_overlapping_glyphs_p)
19707 int dummy_x = 0;
19708 struct glyph_string *h, *t;
19710 /* Compute overhangs for all glyph strings. */
19711 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
19712 for (s = head; s; s = s->next)
19713 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
19715 /* Prepend glyph strings for glyphs in front of the first glyph
19716 string that are overwritten because of the first glyph
19717 string's left overhang. The background of all strings
19718 prepended must be drawn because the first glyph string
19719 draws over it. */
19720 i = left_overwritten (head);
19721 if (i >= 0)
19723 j = i;
19724 BUILD_GLYPH_STRINGS (j, start, h, t,
19725 DRAW_NORMAL_TEXT, dummy_x, last_x);
19726 start = i;
19727 compute_overhangs_and_x (t, head->x, 1);
19728 prepend_glyph_string_lists (&head, &tail, h, t);
19729 clip_head = head;
19732 /* Prepend glyph strings for glyphs in front of the first glyph
19733 string that overwrite that glyph string because of their
19734 right overhang. For these strings, only the foreground must
19735 be drawn, because it draws over the glyph string at `head'.
19736 The background must not be drawn because this would overwrite
19737 right overhangs of preceding glyphs for which no glyph
19738 strings exist. */
19739 i = left_overwriting (head);
19740 if (i >= 0)
19742 clip_head = head;
19743 BUILD_GLYPH_STRINGS (i, start, h, t,
19744 DRAW_NORMAL_TEXT, dummy_x, last_x);
19745 for (s = h; s; s = s->next)
19746 s->background_filled_p = 1;
19747 compute_overhangs_and_x (t, head->x, 1);
19748 prepend_glyph_string_lists (&head, &tail, h, t);
19751 /* Append glyphs strings for glyphs following the last glyph
19752 string tail that are overwritten by tail. The background of
19753 these strings has to be drawn because tail's foreground draws
19754 over it. */
19755 i = right_overwritten (tail);
19756 if (i >= 0)
19758 BUILD_GLYPH_STRINGS (end, i, h, t,
19759 DRAW_NORMAL_TEXT, x, last_x);
19760 compute_overhangs_and_x (h, tail->x + tail->width, 0);
19761 append_glyph_string_lists (&head, &tail, h, t);
19762 clip_tail = tail;
19765 /* Append glyph strings for glyphs following the last glyph
19766 string tail that overwrite tail. The foreground of such
19767 glyphs has to be drawn because it writes into the background
19768 of tail. The background must not be drawn because it could
19769 paint over the foreground of following glyphs. */
19770 i = right_overwriting (tail);
19771 if (i >= 0)
19773 clip_tail = tail;
19774 BUILD_GLYPH_STRINGS (end, i, h, t,
19775 DRAW_NORMAL_TEXT, x, last_x);
19776 for (s = h; s; s = s->next)
19777 s->background_filled_p = 1;
19778 compute_overhangs_and_x (h, tail->x + tail->width, 0);
19779 append_glyph_string_lists (&head, &tail, h, t);
19781 if (clip_head || clip_tail)
19782 for (s = head; s; s = s->next)
19784 s->clip_head = clip_head;
19785 s->clip_tail = clip_tail;
19789 /* Draw all strings. */
19790 for (s = head; s; s = s->next)
19791 FRAME_RIF (f)->draw_glyph_string (s);
19793 if (area == TEXT_AREA
19794 && !row->full_width_p
19795 /* When drawing overlapping rows, only the glyph strings'
19796 foreground is drawn, which doesn't erase a cursor
19797 completely. */
19798 && !overlaps)
19800 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
19801 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
19802 : (tail ? tail->x + tail->background_width : x));
19804 int text_left = window_box_left (w, TEXT_AREA);
19805 x0 -= text_left;
19806 x1 -= text_left;
19808 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
19809 row->y, MATRIX_ROW_BOTTOM_Y (row));
19812 /* Value is the x-position up to which drawn, relative to AREA of W.
19813 This doesn't include parts drawn because of overhangs. */
19814 if (row->full_width_p)
19815 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
19816 else
19817 x_reached -= window_box_left (w, area);
19819 RELEASE_HDC (hdc, f);
19821 return x_reached;
19824 /* Expand row matrix if too narrow. Don't expand if area
19825 is not present. */
19827 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
19829 if (!fonts_changed_p \
19830 && (it->glyph_row->glyphs[area] \
19831 < it->glyph_row->glyphs[area + 1])) \
19833 it->w->ncols_scale_factor++; \
19834 fonts_changed_p = 1; \
19838 /* Store one glyph for IT->char_to_display in IT->glyph_row.
19839 Called from x_produce_glyphs when IT->glyph_row is non-null. */
19841 static INLINE void
19842 append_glyph (it)
19843 struct it *it;
19845 struct glyph *glyph;
19846 enum glyph_row_area area = it->area;
19848 xassert (it->glyph_row);
19849 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
19851 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
19852 if (glyph < it->glyph_row->glyphs[area + 1])
19854 glyph->charpos = CHARPOS (it->position);
19855 glyph->object = it->object;
19856 glyph->pixel_width = it->pixel_width;
19857 glyph->ascent = it->ascent;
19858 glyph->descent = it->descent;
19859 glyph->voffset = it->voffset;
19860 glyph->type = CHAR_GLYPH;
19861 glyph->multibyte_p = it->multibyte_p;
19862 glyph->left_box_line_p = it->start_of_box_run_p;
19863 glyph->right_box_line_p = it->end_of_box_run_p;
19864 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
19865 || it->phys_descent > it->descent);
19866 glyph->padding_p = 0;
19867 glyph->glyph_not_available_p = it->glyph_not_available_p;
19868 glyph->face_id = it->face_id;
19869 glyph->u.ch = it->char_to_display;
19870 glyph->slice = null_glyph_slice;
19871 glyph->font_type = FONT_TYPE_UNKNOWN;
19872 ++it->glyph_row->used[area];
19874 else
19875 IT_EXPAND_MATRIX_WIDTH (it, area);
19878 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
19879 Called from x_produce_glyphs when IT->glyph_row is non-null. */
19881 static INLINE void
19882 append_composite_glyph (it)
19883 struct it *it;
19885 struct glyph *glyph;
19886 enum glyph_row_area area = it->area;
19888 xassert (it->glyph_row);
19890 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
19891 if (glyph < it->glyph_row->glyphs[area + 1])
19893 glyph->charpos = CHARPOS (it->position);
19894 glyph->object = it->object;
19895 glyph->pixel_width = it->pixel_width;
19896 glyph->ascent = it->ascent;
19897 glyph->descent = it->descent;
19898 glyph->voffset = it->voffset;
19899 glyph->type = COMPOSITE_GLYPH;
19900 glyph->multibyte_p = it->multibyte_p;
19901 glyph->left_box_line_p = it->start_of_box_run_p;
19902 glyph->right_box_line_p = it->end_of_box_run_p;
19903 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
19904 || it->phys_descent > it->descent);
19905 glyph->padding_p = 0;
19906 glyph->glyph_not_available_p = 0;
19907 glyph->face_id = it->face_id;
19908 glyph->u.cmp_id = it->cmp_id;
19909 glyph->slice = null_glyph_slice;
19910 glyph->font_type = FONT_TYPE_UNKNOWN;
19911 ++it->glyph_row->used[area];
19913 else
19914 IT_EXPAND_MATRIX_WIDTH (it, area);
19918 /* Change IT->ascent and IT->height according to the setting of
19919 IT->voffset. */
19921 static INLINE void
19922 take_vertical_position_into_account (it)
19923 struct it *it;
19925 if (it->voffset)
19927 if (it->voffset < 0)
19928 /* Increase the ascent so that we can display the text higher
19929 in the line. */
19930 it->ascent -= it->voffset;
19931 else
19932 /* Increase the descent so that we can display the text lower
19933 in the line. */
19934 it->descent += it->voffset;
19939 /* Produce glyphs/get display metrics for the image IT is loaded with.
19940 See the description of struct display_iterator in dispextern.h for
19941 an overview of struct display_iterator. */
19943 static void
19944 produce_image_glyph (it)
19945 struct it *it;
19947 struct image *img;
19948 struct face *face;
19949 int glyph_ascent, crop;
19950 struct glyph_slice slice;
19952 xassert (it->what == IT_IMAGE);
19954 face = FACE_FROM_ID (it->f, it->face_id);
19955 xassert (face);
19956 /* Make sure X resources of the face is loaded. */
19957 PREPARE_FACE_FOR_DISPLAY (it->f, face);
19959 if (it->image_id < 0)
19961 /* Fringe bitmap. */
19962 it->ascent = it->phys_ascent = 0;
19963 it->descent = it->phys_descent = 0;
19964 it->pixel_width = 0;
19965 it->nglyphs = 0;
19966 return;
19969 img = IMAGE_FROM_ID (it->f, it->image_id);
19970 xassert (img);
19971 /* Make sure X resources of the image is loaded. */
19972 prepare_image_for_display (it->f, img);
19974 slice.x = slice.y = 0;
19975 slice.width = img->width;
19976 slice.height = img->height;
19978 if (INTEGERP (it->slice.x))
19979 slice.x = XINT (it->slice.x);
19980 else if (FLOATP (it->slice.x))
19981 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
19983 if (INTEGERP (it->slice.y))
19984 slice.y = XINT (it->slice.y);
19985 else if (FLOATP (it->slice.y))
19986 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
19988 if (INTEGERP (it->slice.width))
19989 slice.width = XINT (it->slice.width);
19990 else if (FLOATP (it->slice.width))
19991 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
19993 if (INTEGERP (it->slice.height))
19994 slice.height = XINT (it->slice.height);
19995 else if (FLOATP (it->slice.height))
19996 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
19998 if (slice.x >= img->width)
19999 slice.x = img->width;
20000 if (slice.y >= img->height)
20001 slice.y = img->height;
20002 if (slice.x + slice.width >= img->width)
20003 slice.width = img->width - slice.x;
20004 if (slice.y + slice.height > img->height)
20005 slice.height = img->height - slice.y;
20007 if (slice.width == 0 || slice.height == 0)
20008 return;
20010 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
20012 it->descent = slice.height - glyph_ascent;
20013 if (slice.y == 0)
20014 it->descent += img->vmargin;
20015 if (slice.y + slice.height == img->height)
20016 it->descent += img->vmargin;
20017 it->phys_descent = it->descent;
20019 it->pixel_width = slice.width;
20020 if (slice.x == 0)
20021 it->pixel_width += img->hmargin;
20022 if (slice.x + slice.width == img->width)
20023 it->pixel_width += img->hmargin;
20025 /* It's quite possible for images to have an ascent greater than
20026 their height, so don't get confused in that case. */
20027 if (it->descent < 0)
20028 it->descent = 0;
20030 #if 0 /* this breaks image tiling */
20031 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
20032 int face_ascent = face->font ? FONT_BASE (face->font) : FRAME_BASELINE_OFFSET (it->f);
20033 if (face_ascent > it->ascent)
20034 it->ascent = it->phys_ascent = face_ascent;
20035 #endif
20037 it->nglyphs = 1;
20039 if (face->box != FACE_NO_BOX)
20041 if (face->box_line_width > 0)
20043 if (slice.y == 0)
20044 it->ascent += face->box_line_width;
20045 if (slice.y + slice.height == img->height)
20046 it->descent += face->box_line_width;
20049 if (it->start_of_box_run_p && slice.x == 0)
20050 it->pixel_width += eabs (face->box_line_width);
20051 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
20052 it->pixel_width += eabs (face->box_line_width);
20055 take_vertical_position_into_account (it);
20057 /* Automatically crop wide image glyphs at right edge so we can
20058 draw the cursor on same display row. */
20059 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
20060 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
20062 it->pixel_width -= crop;
20063 slice.width -= crop;
20066 if (it->glyph_row)
20068 struct glyph *glyph;
20069 enum glyph_row_area area = it->area;
20071 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
20072 if (glyph < it->glyph_row->glyphs[area + 1])
20074 glyph->charpos = CHARPOS (it->position);
20075 glyph->object = it->object;
20076 glyph->pixel_width = it->pixel_width;
20077 glyph->ascent = glyph_ascent;
20078 glyph->descent = it->descent;
20079 glyph->voffset = it->voffset;
20080 glyph->type = IMAGE_GLYPH;
20081 glyph->multibyte_p = it->multibyte_p;
20082 glyph->left_box_line_p = it->start_of_box_run_p;
20083 glyph->right_box_line_p = it->end_of_box_run_p;
20084 glyph->overlaps_vertically_p = 0;
20085 glyph->padding_p = 0;
20086 glyph->glyph_not_available_p = 0;
20087 glyph->face_id = it->face_id;
20088 glyph->u.img_id = img->id;
20089 glyph->slice = slice;
20090 glyph->font_type = FONT_TYPE_UNKNOWN;
20091 ++it->glyph_row->used[area];
20093 else
20094 IT_EXPAND_MATRIX_WIDTH (it, area);
20099 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
20100 of the glyph, WIDTH and HEIGHT are the width and height of the
20101 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
20103 static void
20104 append_stretch_glyph (it, object, width, height, ascent)
20105 struct it *it;
20106 Lisp_Object object;
20107 int width, height;
20108 int ascent;
20110 struct glyph *glyph;
20111 enum glyph_row_area area = it->area;
20113 xassert (ascent >= 0 && ascent <= height);
20115 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
20116 if (glyph < it->glyph_row->glyphs[area + 1])
20118 glyph->charpos = CHARPOS (it->position);
20119 glyph->object = object;
20120 glyph->pixel_width = width;
20121 glyph->ascent = ascent;
20122 glyph->descent = height - ascent;
20123 glyph->voffset = it->voffset;
20124 glyph->type = STRETCH_GLYPH;
20125 glyph->multibyte_p = it->multibyte_p;
20126 glyph->left_box_line_p = it->start_of_box_run_p;
20127 glyph->right_box_line_p = it->end_of_box_run_p;
20128 glyph->overlaps_vertically_p = 0;
20129 glyph->padding_p = 0;
20130 glyph->glyph_not_available_p = 0;
20131 glyph->face_id = it->face_id;
20132 glyph->u.stretch.ascent = ascent;
20133 glyph->u.stretch.height = height;
20134 glyph->slice = null_glyph_slice;
20135 glyph->font_type = FONT_TYPE_UNKNOWN;
20136 ++it->glyph_row->used[area];
20138 else
20139 IT_EXPAND_MATRIX_WIDTH (it, area);
20143 /* Produce a stretch glyph for iterator IT. IT->object is the value
20144 of the glyph property displayed. The value must be a list
20145 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
20146 being recognized:
20148 1. `:width WIDTH' specifies that the space should be WIDTH *
20149 canonical char width wide. WIDTH may be an integer or floating
20150 point number.
20152 2. `:relative-width FACTOR' specifies that the width of the stretch
20153 should be computed from the width of the first character having the
20154 `glyph' property, and should be FACTOR times that width.
20156 3. `:align-to HPOS' specifies that the space should be wide enough
20157 to reach HPOS, a value in canonical character units.
20159 Exactly one of the above pairs must be present.
20161 4. `:height HEIGHT' specifies that the height of the stretch produced
20162 should be HEIGHT, measured in canonical character units.
20164 5. `:relative-height FACTOR' specifies that the height of the
20165 stretch should be FACTOR times the height of the characters having
20166 the glyph property.
20168 Either none or exactly one of 4 or 5 must be present.
20170 6. `:ascent ASCENT' specifies that ASCENT percent of the height
20171 of the stretch should be used for the ascent of the stretch.
20172 ASCENT must be in the range 0 <= ASCENT <= 100. */
20174 static void
20175 produce_stretch_glyph (it)
20176 struct it *it;
20178 /* (space :width WIDTH :height HEIGHT ...) */
20179 Lisp_Object prop, plist;
20180 int width = 0, height = 0, align_to = -1;
20181 int zero_width_ok_p = 0, zero_height_ok_p = 0;
20182 int ascent = 0;
20183 double tem;
20184 struct face *face = FACE_FROM_ID (it->f, it->face_id);
20185 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
20187 PREPARE_FACE_FOR_DISPLAY (it->f, face);
20189 /* List should start with `space'. */
20190 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
20191 plist = XCDR (it->object);
20193 /* Compute the width of the stretch. */
20194 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
20195 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
20197 /* Absolute width `:width WIDTH' specified and valid. */
20198 zero_width_ok_p = 1;
20199 width = (int)tem;
20201 else if (prop = Fplist_get (plist, QCrelative_width),
20202 NUMVAL (prop) > 0)
20204 /* Relative width `:relative-width FACTOR' specified and valid.
20205 Compute the width of the characters having the `glyph'
20206 property. */
20207 struct it it2;
20208 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
20210 it2 = *it;
20211 if (it->multibyte_p)
20213 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
20214 - IT_BYTEPOS (*it));
20215 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
20217 else
20218 it2.c = *p, it2.len = 1;
20220 it2.glyph_row = NULL;
20221 it2.what = IT_CHARACTER;
20222 x_produce_glyphs (&it2);
20223 width = NUMVAL (prop) * it2.pixel_width;
20225 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
20226 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
20228 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
20229 align_to = (align_to < 0
20231 : align_to - window_box_left_offset (it->w, TEXT_AREA));
20232 else if (align_to < 0)
20233 align_to = window_box_left_offset (it->w, TEXT_AREA);
20234 width = max (0, (int)tem + align_to - it->current_x);
20235 zero_width_ok_p = 1;
20237 else
20238 /* Nothing specified -> width defaults to canonical char width. */
20239 width = FRAME_COLUMN_WIDTH (it->f);
20241 if (width <= 0 && (width < 0 || !zero_width_ok_p))
20242 width = 1;
20244 /* Compute height. */
20245 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
20246 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
20248 height = (int)tem;
20249 zero_height_ok_p = 1;
20251 else if (prop = Fplist_get (plist, QCrelative_height),
20252 NUMVAL (prop) > 0)
20253 height = FONT_HEIGHT (font) * NUMVAL (prop);
20254 else
20255 height = FONT_HEIGHT (font);
20257 if (height <= 0 && (height < 0 || !zero_height_ok_p))
20258 height = 1;
20260 /* Compute percentage of height used for ascent. If
20261 `:ascent ASCENT' is present and valid, use that. Otherwise,
20262 derive the ascent from the font in use. */
20263 if (prop = Fplist_get (plist, QCascent),
20264 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
20265 ascent = height * NUMVAL (prop) / 100.0;
20266 else if (!NILP (prop)
20267 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
20268 ascent = min (max (0, (int)tem), height);
20269 else
20270 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
20272 if (width > 0 && !it->truncate_lines_p
20273 && it->current_x + width > it->last_visible_x)
20274 width = it->last_visible_x - it->current_x - 1;
20276 if (width > 0 && height > 0 && it->glyph_row)
20278 Lisp_Object object = it->stack[it->sp - 1].string;
20279 if (!STRINGP (object))
20280 object = it->w->buffer;
20281 append_stretch_glyph (it, object, width, height, ascent);
20284 it->pixel_width = width;
20285 it->ascent = it->phys_ascent = ascent;
20286 it->descent = it->phys_descent = height - it->ascent;
20287 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
20289 take_vertical_position_into_account (it);
20292 /* Get line-height and line-spacing property at point.
20293 If line-height has format (HEIGHT TOTAL), return TOTAL
20294 in TOTAL_HEIGHT. */
20296 static Lisp_Object
20297 get_line_height_property (it, prop)
20298 struct it *it;
20299 Lisp_Object prop;
20301 Lisp_Object position;
20303 if (STRINGP (it->object))
20304 position = make_number (IT_STRING_CHARPOS (*it));
20305 else if (BUFFERP (it->object))
20306 position = make_number (IT_CHARPOS (*it));
20307 else
20308 return Qnil;
20310 return Fget_char_property (position, prop, it->object);
20313 /* Calculate line-height and line-spacing properties.
20314 An integer value specifies explicit pixel value.
20315 A float value specifies relative value to current face height.
20316 A cons (float . face-name) specifies relative value to
20317 height of specified face font.
20319 Returns height in pixels, or nil. */
20322 static Lisp_Object
20323 calc_line_height_property (it, val, font, boff, override)
20324 struct it *it;
20325 Lisp_Object val;
20326 XFontStruct *font;
20327 int boff, override;
20329 Lisp_Object face_name = Qnil;
20330 int ascent, descent, height;
20332 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
20333 return val;
20335 if (CONSP (val))
20337 face_name = XCAR (val);
20338 val = XCDR (val);
20339 if (!NUMBERP (val))
20340 val = make_number (1);
20341 if (NILP (face_name))
20343 height = it->ascent + it->descent;
20344 goto scale;
20348 if (NILP (face_name))
20350 font = FRAME_FONT (it->f);
20351 boff = FRAME_BASELINE_OFFSET (it->f);
20353 else if (EQ (face_name, Qt))
20355 override = 0;
20357 else
20359 int face_id;
20360 struct face *face;
20361 struct font_info *font_info;
20363 face_id = lookup_named_face (it->f, face_name, ' ', 0);
20364 if (face_id < 0)
20365 return make_number (-1);
20367 face = FACE_FROM_ID (it->f, face_id);
20368 font = face->font;
20369 if (font == NULL)
20370 return make_number (-1);
20372 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
20373 boff = font_info->baseline_offset;
20374 if (font_info->vertical_centering)
20375 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
20378 ascent = FONT_BASE (font) + boff;
20379 descent = FONT_DESCENT (font) - boff;
20381 if (override)
20383 it->override_ascent = ascent;
20384 it->override_descent = descent;
20385 it->override_boff = boff;
20388 height = ascent + descent;
20390 scale:
20391 if (FLOATP (val))
20392 height = (int)(XFLOAT_DATA (val) * height);
20393 else if (INTEGERP (val))
20394 height *= XINT (val);
20396 return make_number (height);
20400 /* RIF:
20401 Produce glyphs/get display metrics for the display element IT is
20402 loaded with. See the description of struct it in dispextern.h
20403 for an overview of struct it. */
20405 void
20406 x_produce_glyphs (it)
20407 struct it *it;
20409 int extra_line_spacing = it->extra_line_spacing;
20411 it->glyph_not_available_p = 0;
20413 if (it->what == IT_CHARACTER)
20415 XChar2b char2b;
20416 XFontStruct *font;
20417 struct face *face = FACE_FROM_ID (it->f, it->face_id);
20418 XCharStruct *pcm;
20419 int font_not_found_p;
20420 struct font_info *font_info;
20421 int boff; /* baseline offset */
20422 /* We may change it->multibyte_p upon unibyte<->multibyte
20423 conversion. So, save the current value now and restore it
20424 later.
20426 Note: It seems that we don't have to record multibyte_p in
20427 struct glyph because the character code itself tells if or
20428 not the character is multibyte. Thus, in the future, we must
20429 consider eliminating the field `multibyte_p' in the struct
20430 glyph. */
20431 int saved_multibyte_p = it->multibyte_p;
20433 /* Maybe translate single-byte characters to multibyte, or the
20434 other way. */
20435 it->char_to_display = it->c;
20436 if (!ASCII_BYTE_P (it->c))
20438 if (unibyte_display_via_language_environment
20439 && SINGLE_BYTE_CHAR_P (it->c)
20440 && (it->c >= 0240
20441 || !NILP (Vnonascii_translation_table)))
20443 it->char_to_display = unibyte_char_to_multibyte (it->c);
20444 it->multibyte_p = 1;
20445 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
20446 face = FACE_FROM_ID (it->f, it->face_id);
20448 else if (!SINGLE_BYTE_CHAR_P (it->c)
20449 && !it->multibyte_p)
20451 it->multibyte_p = 1;
20452 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
20453 face = FACE_FROM_ID (it->f, it->face_id);
20457 /* Get font to use. Encode IT->char_to_display. */
20458 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
20459 &char2b, it->multibyte_p, 0);
20460 font = face->font;
20462 /* When no suitable font found, use the default font. */
20463 font_not_found_p = font == NULL;
20464 if (font_not_found_p)
20466 font = FRAME_FONT (it->f);
20467 boff = FRAME_BASELINE_OFFSET (it->f);
20468 font_info = NULL;
20470 else
20472 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
20473 boff = font_info->baseline_offset;
20474 if (font_info->vertical_centering)
20475 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
20478 if (it->char_to_display >= ' '
20479 && (!it->multibyte_p || it->char_to_display < 128))
20481 /* Either unibyte or ASCII. */
20482 int stretched_p;
20484 it->nglyphs = 1;
20486 pcm = FRAME_RIF (it->f)->per_char_metric
20487 (font, &char2b, FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
20489 if (it->override_ascent >= 0)
20491 it->ascent = it->override_ascent;
20492 it->descent = it->override_descent;
20493 boff = it->override_boff;
20495 else
20497 it->ascent = FONT_BASE (font) + boff;
20498 it->descent = FONT_DESCENT (font) - boff;
20501 if (pcm)
20503 it->phys_ascent = pcm->ascent + boff;
20504 it->phys_descent = pcm->descent - boff;
20505 it->pixel_width = pcm->width;
20507 else
20509 it->glyph_not_available_p = 1;
20510 it->phys_ascent = it->ascent;
20511 it->phys_descent = it->descent;
20512 it->pixel_width = FONT_WIDTH (font);
20515 if (it->constrain_row_ascent_descent_p)
20517 if (it->descent > it->max_descent)
20519 it->ascent += it->descent - it->max_descent;
20520 it->descent = it->max_descent;
20522 if (it->ascent > it->max_ascent)
20524 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
20525 it->ascent = it->max_ascent;
20527 it->phys_ascent = min (it->phys_ascent, it->ascent);
20528 it->phys_descent = min (it->phys_descent, it->descent);
20529 extra_line_spacing = 0;
20532 /* If this is a space inside a region of text with
20533 `space-width' property, change its width. */
20534 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
20535 if (stretched_p)
20536 it->pixel_width *= XFLOATINT (it->space_width);
20538 /* If face has a box, add the box thickness to the character
20539 height. If character has a box line to the left and/or
20540 right, add the box line width to the character's width. */
20541 if (face->box != FACE_NO_BOX)
20543 int thick = face->box_line_width;
20545 if (thick > 0)
20547 it->ascent += thick;
20548 it->descent += thick;
20550 else
20551 thick = -thick;
20553 if (it->start_of_box_run_p)
20554 it->pixel_width += thick;
20555 if (it->end_of_box_run_p)
20556 it->pixel_width += thick;
20559 /* If face has an overline, add the height of the overline
20560 (1 pixel) and a 1 pixel margin to the character height. */
20561 if (face->overline_p)
20562 it->ascent += overline_margin;
20564 if (it->constrain_row_ascent_descent_p)
20566 if (it->ascent > it->max_ascent)
20567 it->ascent = it->max_ascent;
20568 if (it->descent > it->max_descent)
20569 it->descent = it->max_descent;
20572 take_vertical_position_into_account (it);
20574 /* If we have to actually produce glyphs, do it. */
20575 if (it->glyph_row)
20577 if (stretched_p)
20579 /* Translate a space with a `space-width' property
20580 into a stretch glyph. */
20581 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
20582 / FONT_HEIGHT (font));
20583 append_stretch_glyph (it, it->object, it->pixel_width,
20584 it->ascent + it->descent, ascent);
20586 else
20587 append_glyph (it);
20589 /* If characters with lbearing or rbearing are displayed
20590 in this line, record that fact in a flag of the
20591 glyph row. This is used to optimize X output code. */
20592 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
20593 it->glyph_row->contains_overlapping_glyphs_p = 1;
20596 else if (it->char_to_display == '\n')
20598 /* A newline has no width but we need the height of the line.
20599 But if previous part of the line set a height, don't
20600 increase that height */
20602 Lisp_Object height;
20603 Lisp_Object total_height = Qnil;
20605 it->override_ascent = -1;
20606 it->pixel_width = 0;
20607 it->nglyphs = 0;
20609 height = get_line_height_property(it, Qline_height);
20610 /* Split (line-height total-height) list */
20611 if (CONSP (height)
20612 && CONSP (XCDR (height))
20613 && NILP (XCDR (XCDR (height))))
20615 total_height = XCAR (XCDR (height));
20616 height = XCAR (height);
20618 height = calc_line_height_property(it, height, font, boff, 1);
20620 if (it->override_ascent >= 0)
20622 it->ascent = it->override_ascent;
20623 it->descent = it->override_descent;
20624 boff = it->override_boff;
20626 else
20628 it->ascent = FONT_BASE (font) + boff;
20629 it->descent = FONT_DESCENT (font) - boff;
20632 if (EQ (height, Qt))
20634 if (it->descent > it->max_descent)
20636 it->ascent += it->descent - it->max_descent;
20637 it->descent = it->max_descent;
20639 if (it->ascent > it->max_ascent)
20641 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
20642 it->ascent = it->max_ascent;
20644 it->phys_ascent = min (it->phys_ascent, it->ascent);
20645 it->phys_descent = min (it->phys_descent, it->descent);
20646 it->constrain_row_ascent_descent_p = 1;
20647 extra_line_spacing = 0;
20649 else
20651 Lisp_Object spacing;
20653 it->phys_ascent = it->ascent;
20654 it->phys_descent = it->descent;
20656 if ((it->max_ascent > 0 || it->max_descent > 0)
20657 && face->box != FACE_NO_BOX
20658 && face->box_line_width > 0)
20660 it->ascent += face->box_line_width;
20661 it->descent += face->box_line_width;
20663 if (!NILP (height)
20664 && XINT (height) > it->ascent + it->descent)
20665 it->ascent = XINT (height) - it->descent;
20667 if (!NILP (total_height))
20668 spacing = calc_line_height_property(it, total_height, font, boff, 0);
20669 else
20671 spacing = get_line_height_property(it, Qline_spacing);
20672 spacing = calc_line_height_property(it, spacing, font, boff, 0);
20674 if (INTEGERP (spacing))
20676 extra_line_spacing = XINT (spacing);
20677 if (!NILP (total_height))
20678 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
20682 else if (it->char_to_display == '\t')
20684 int tab_width = it->tab_width * FRAME_SPACE_WIDTH (it->f);
20685 int x = it->current_x + it->continuation_lines_width;
20686 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
20688 /* If the distance from the current position to the next tab
20689 stop is less than a space character width, use the
20690 tab stop after that. */
20691 if (next_tab_x - x < FRAME_SPACE_WIDTH (it->f))
20692 next_tab_x += tab_width;
20694 it->pixel_width = next_tab_x - x;
20695 it->nglyphs = 1;
20696 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
20697 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
20699 if (it->glyph_row)
20701 append_stretch_glyph (it, it->object, it->pixel_width,
20702 it->ascent + it->descent, it->ascent);
20705 else
20707 /* A multi-byte character. Assume that the display width of the
20708 character is the width of the character multiplied by the
20709 width of the font. */
20711 /* If we found a font, this font should give us the right
20712 metrics. If we didn't find a font, use the frame's
20713 default font and calculate the width of the character
20714 from the charset width; this is what old redisplay code
20715 did. */
20717 pcm = FRAME_RIF (it->f)->per_char_metric (font, &char2b,
20718 FONT_TYPE_FOR_MULTIBYTE (font, it->c));
20720 if (font_not_found_p || !pcm)
20722 int charset = CHAR_CHARSET (it->char_to_display);
20724 it->glyph_not_available_p = 1;
20725 it->pixel_width = (FRAME_COLUMN_WIDTH (it->f)
20726 * CHARSET_WIDTH (charset));
20727 it->phys_ascent = FONT_BASE (font) + boff;
20728 it->phys_descent = FONT_DESCENT (font) - boff;
20730 else
20732 it->pixel_width = pcm->width;
20733 it->phys_ascent = pcm->ascent + boff;
20734 it->phys_descent = pcm->descent - boff;
20735 if (it->glyph_row
20736 && (pcm->lbearing < 0
20737 || pcm->rbearing > pcm->width))
20738 it->glyph_row->contains_overlapping_glyphs_p = 1;
20740 it->nglyphs = 1;
20741 it->ascent = FONT_BASE (font) + boff;
20742 it->descent = FONT_DESCENT (font) - boff;
20743 if (face->box != FACE_NO_BOX)
20745 int thick = face->box_line_width;
20747 if (thick > 0)
20749 it->ascent += thick;
20750 it->descent += thick;
20752 else
20753 thick = - thick;
20755 if (it->start_of_box_run_p)
20756 it->pixel_width += thick;
20757 if (it->end_of_box_run_p)
20758 it->pixel_width += thick;
20761 /* If face has an overline, add the height of the overline
20762 (1 pixel) and a 1 pixel margin to the character height. */
20763 if (face->overline_p)
20764 it->ascent += overline_margin;
20766 take_vertical_position_into_account (it);
20768 if (it->glyph_row)
20769 append_glyph (it);
20771 it->multibyte_p = saved_multibyte_p;
20773 else if (it->what == IT_COMPOSITION)
20775 /* Note: A composition is represented as one glyph in the
20776 glyph matrix. There are no padding glyphs. */
20777 XChar2b char2b;
20778 XFontStruct *font;
20779 struct face *face = FACE_FROM_ID (it->f, it->face_id);
20780 XCharStruct *pcm;
20781 int font_not_found_p;
20782 struct font_info *font_info;
20783 int boff; /* baseline offset */
20784 struct composition *cmp = composition_table[it->cmp_id];
20786 /* Maybe translate single-byte characters to multibyte. */
20787 it->char_to_display = it->c;
20788 if (unibyte_display_via_language_environment
20789 && SINGLE_BYTE_CHAR_P (it->c)
20790 && (it->c >= 0240
20791 || (it->c >= 0200
20792 && !NILP (Vnonascii_translation_table))))
20794 it->char_to_display = unibyte_char_to_multibyte (it->c);
20797 /* Get face and font to use. Encode IT->char_to_display. */
20798 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
20799 face = FACE_FROM_ID (it->f, it->face_id);
20800 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
20801 &char2b, it->multibyte_p, 0);
20802 font = face->font;
20804 /* When no suitable font found, use the default font. */
20805 font_not_found_p = font == NULL;
20806 if (font_not_found_p)
20808 font = FRAME_FONT (it->f);
20809 boff = FRAME_BASELINE_OFFSET (it->f);
20810 font_info = NULL;
20812 else
20814 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
20815 boff = font_info->baseline_offset;
20816 if (font_info->vertical_centering)
20817 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
20820 /* There are no padding glyphs, so there is only one glyph to
20821 produce for the composition. Important is that pixel_width,
20822 ascent and descent are the values of what is drawn by
20823 draw_glyphs (i.e. the values of the overall glyphs composed). */
20824 it->nglyphs = 1;
20826 /* If we have not yet calculated pixel size data of glyphs of
20827 the composition for the current face font, calculate them
20828 now. Theoretically, we have to check all fonts for the
20829 glyphs, but that requires much time and memory space. So,
20830 here we check only the font of the first glyph. This leads
20831 to incorrect display very rarely, and C-l (recenter) can
20832 correct the display anyway. */
20833 if (cmp->font != (void *) font)
20835 /* Ascent and descent of the font of the first character of
20836 this composition (adjusted by baseline offset). Ascent
20837 and descent of overall glyphs should not be less than
20838 them respectively. */
20839 int font_ascent = FONT_BASE (font) + boff;
20840 int font_descent = FONT_DESCENT (font) - boff;
20841 /* Bounding box of the overall glyphs. */
20842 int leftmost, rightmost, lowest, highest;
20843 int i, width, ascent, descent;
20845 cmp->font = (void *) font;
20847 /* Initialize the bounding box. */
20848 if (font_info
20849 && (pcm = FRAME_RIF (it->f)->per_char_metric (font, &char2b,
20850 FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
20852 width = pcm->width;
20853 ascent = pcm->ascent;
20854 descent = pcm->descent;
20856 else
20858 width = FONT_WIDTH (font);
20859 ascent = FONT_BASE (font);
20860 descent = FONT_DESCENT (font);
20863 rightmost = width;
20864 lowest = - descent + boff;
20865 highest = ascent + boff;
20866 leftmost = 0;
20868 if (font_info
20869 && font_info->default_ascent
20870 && CHAR_TABLE_P (Vuse_default_ascent)
20871 && !NILP (Faref (Vuse_default_ascent,
20872 make_number (it->char_to_display))))
20873 highest = font_info->default_ascent + boff;
20875 /* Draw the first glyph at the normal position. It may be
20876 shifted to right later if some other glyphs are drawn at
20877 the left. */
20878 cmp->offsets[0] = 0;
20879 cmp->offsets[1] = boff;
20881 /* Set cmp->offsets for the remaining glyphs. */
20882 for (i = 1; i < cmp->glyph_len; i++)
20884 int left, right, btm, top;
20885 int ch = COMPOSITION_GLYPH (cmp, i);
20886 int face_id = FACE_FOR_CHAR (it->f, face, ch);
20888 face = FACE_FROM_ID (it->f, face_id);
20889 get_char_face_and_encoding (it->f, ch, face->id,
20890 &char2b, it->multibyte_p, 0);
20891 font = face->font;
20892 if (font == NULL)
20894 font = FRAME_FONT (it->f);
20895 boff = FRAME_BASELINE_OFFSET (it->f);
20896 font_info = NULL;
20898 else
20900 font_info
20901 = FONT_INFO_FROM_ID (it->f, face->font_info_id);
20902 boff = font_info->baseline_offset;
20903 if (font_info->vertical_centering)
20904 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
20907 if (font_info
20908 && (pcm = FRAME_RIF (it->f)->per_char_metric (font, &char2b,
20909 FONT_TYPE_FOR_MULTIBYTE (font, ch))))
20911 width = pcm->width;
20912 ascent = pcm->ascent;
20913 descent = pcm->descent;
20915 else
20917 width = FONT_WIDTH (font);
20918 ascent = 1;
20919 descent = 0;
20922 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
20924 /* Relative composition with or without
20925 alternate chars. */
20926 left = (leftmost + rightmost - width) / 2;
20927 btm = - descent + boff;
20928 if (font_info && font_info->relative_compose
20929 && (! CHAR_TABLE_P (Vignore_relative_composition)
20930 || NILP (Faref (Vignore_relative_composition,
20931 make_number (ch)))))
20934 if (- descent >= font_info->relative_compose)
20935 /* One extra pixel between two glyphs. */
20936 btm = highest + 1;
20937 else if (ascent <= 0)
20938 /* One extra pixel between two glyphs. */
20939 btm = lowest - 1 - ascent - descent;
20942 else
20944 /* A composition rule is specified by an integer
20945 value that encodes global and new reference
20946 points (GREF and NREF). GREF and NREF are
20947 specified by numbers as below:
20949 0---1---2 -- ascent
20953 9--10--11 -- center
20955 ---3---4---5--- baseline
20957 6---7---8 -- descent
20959 int rule = COMPOSITION_RULE (cmp, i);
20960 int gref, nref, grefx, grefy, nrefx, nrefy;
20962 COMPOSITION_DECODE_RULE (rule, gref, nref);
20963 grefx = gref % 3, nrefx = nref % 3;
20964 grefy = gref / 3, nrefy = nref / 3;
20966 left = (leftmost
20967 + grefx * (rightmost - leftmost) / 2
20968 - nrefx * width / 2);
20969 btm = ((grefy == 0 ? highest
20970 : grefy == 1 ? 0
20971 : grefy == 2 ? lowest
20972 : (highest + lowest) / 2)
20973 - (nrefy == 0 ? ascent + descent
20974 : nrefy == 1 ? descent - boff
20975 : nrefy == 2 ? 0
20976 : (ascent + descent) / 2));
20979 cmp->offsets[i * 2] = left;
20980 cmp->offsets[i * 2 + 1] = btm + descent;
20982 /* Update the bounding box of the overall glyphs. */
20983 right = left + width;
20984 top = btm + descent + ascent;
20985 if (left < leftmost)
20986 leftmost = left;
20987 if (right > rightmost)
20988 rightmost = right;
20989 if (top > highest)
20990 highest = top;
20991 if (btm < lowest)
20992 lowest = btm;
20995 /* If there are glyphs whose x-offsets are negative,
20996 shift all glyphs to the right and make all x-offsets
20997 non-negative. */
20998 if (leftmost < 0)
21000 for (i = 0; i < cmp->glyph_len; i++)
21001 cmp->offsets[i * 2] -= leftmost;
21002 rightmost -= leftmost;
21005 cmp->pixel_width = rightmost;
21006 cmp->ascent = highest;
21007 cmp->descent = - lowest;
21008 if (cmp->ascent < font_ascent)
21009 cmp->ascent = font_ascent;
21010 if (cmp->descent < font_descent)
21011 cmp->descent = font_descent;
21014 it->pixel_width = cmp->pixel_width;
21015 it->ascent = it->phys_ascent = cmp->ascent;
21016 it->descent = it->phys_descent = cmp->descent;
21018 if (face->box != FACE_NO_BOX)
21020 int thick = face->box_line_width;
21022 if (thick > 0)
21024 it->ascent += thick;
21025 it->descent += thick;
21027 else
21028 thick = - thick;
21030 if (it->start_of_box_run_p)
21031 it->pixel_width += thick;
21032 if (it->end_of_box_run_p)
21033 it->pixel_width += thick;
21036 /* If face has an overline, add the height of the overline
21037 (1 pixel) and a 1 pixel margin to the character height. */
21038 if (face->overline_p)
21039 it->ascent += overline_margin;
21041 take_vertical_position_into_account (it);
21043 if (it->glyph_row)
21044 append_composite_glyph (it);
21046 else if (it->what == IT_IMAGE)
21047 produce_image_glyph (it);
21048 else if (it->what == IT_STRETCH)
21049 produce_stretch_glyph (it);
21051 /* Accumulate dimensions. Note: can't assume that it->descent > 0
21052 because this isn't true for images with `:ascent 100'. */
21053 xassert (it->ascent >= 0 && it->descent >= 0);
21054 if (it->area == TEXT_AREA)
21055 it->current_x += it->pixel_width;
21057 if (extra_line_spacing > 0)
21059 it->descent += extra_line_spacing;
21060 if (extra_line_spacing > it->max_extra_line_spacing)
21061 it->max_extra_line_spacing = extra_line_spacing;
21064 it->max_ascent = max (it->max_ascent, it->ascent);
21065 it->max_descent = max (it->max_descent, it->descent);
21066 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
21067 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
21070 /* EXPORT for RIF:
21071 Output LEN glyphs starting at START at the nominal cursor position.
21072 Advance the nominal cursor over the text. The global variable
21073 updated_window contains the window being updated, updated_row is
21074 the glyph row being updated, and updated_area is the area of that
21075 row being updated. */
21077 void
21078 x_write_glyphs (start, len)
21079 struct glyph *start;
21080 int len;
21082 int x, hpos;
21084 xassert (updated_window && updated_row);
21085 BLOCK_INPUT;
21087 /* Write glyphs. */
21089 hpos = start - updated_row->glyphs[updated_area];
21090 x = draw_glyphs (updated_window, output_cursor.x,
21091 updated_row, updated_area,
21092 hpos, hpos + len,
21093 DRAW_NORMAL_TEXT, 0);
21095 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
21096 if (updated_area == TEXT_AREA
21097 && updated_window->phys_cursor_on_p
21098 && updated_window->phys_cursor.vpos == output_cursor.vpos
21099 && updated_window->phys_cursor.hpos >= hpos
21100 && updated_window->phys_cursor.hpos < hpos + len)
21101 updated_window->phys_cursor_on_p = 0;
21103 UNBLOCK_INPUT;
21105 /* Advance the output cursor. */
21106 output_cursor.hpos += len;
21107 output_cursor.x = x;
21111 /* EXPORT for RIF:
21112 Insert LEN glyphs from START at the nominal cursor position. */
21114 void
21115 x_insert_glyphs (start, len)
21116 struct glyph *start;
21117 int len;
21119 struct frame *f;
21120 struct window *w;
21121 int line_height, shift_by_width, shifted_region_width;
21122 struct glyph_row *row;
21123 struct glyph *glyph;
21124 int frame_x, frame_y, hpos;
21126 xassert (updated_window && updated_row);
21127 BLOCK_INPUT;
21128 w = updated_window;
21129 f = XFRAME (WINDOW_FRAME (w));
21131 /* Get the height of the line we are in. */
21132 row = updated_row;
21133 line_height = row->height;
21135 /* Get the width of the glyphs to insert. */
21136 shift_by_width = 0;
21137 for (glyph = start; glyph < start + len; ++glyph)
21138 shift_by_width += glyph->pixel_width;
21140 /* Get the width of the region to shift right. */
21141 shifted_region_width = (window_box_width (w, updated_area)
21142 - output_cursor.x
21143 - shift_by_width);
21145 /* Shift right. */
21146 frame_x = window_box_left (w, updated_area) + output_cursor.x;
21147 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
21149 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
21150 line_height, shift_by_width);
21152 /* Write the glyphs. */
21153 hpos = start - row->glyphs[updated_area];
21154 draw_glyphs (w, output_cursor.x, row, updated_area,
21155 hpos, hpos + len,
21156 DRAW_NORMAL_TEXT, 0);
21158 /* Advance the output cursor. */
21159 output_cursor.hpos += len;
21160 output_cursor.x += shift_by_width;
21161 UNBLOCK_INPUT;
21165 /* EXPORT for RIF:
21166 Erase the current text line from the nominal cursor position
21167 (inclusive) to pixel column TO_X (exclusive). The idea is that
21168 everything from TO_X onward is already erased.
21170 TO_X is a pixel position relative to updated_area of
21171 updated_window. TO_X == -1 means clear to the end of this area. */
21173 void
21174 x_clear_end_of_line (to_x)
21175 int to_x;
21177 struct frame *f;
21178 struct window *w = updated_window;
21179 int max_x, min_y, max_y;
21180 int from_x, from_y, to_y;
21182 xassert (updated_window && updated_row);
21183 f = XFRAME (w->frame);
21185 if (updated_row->full_width_p)
21186 max_x = WINDOW_TOTAL_WIDTH (w);
21187 else
21188 max_x = window_box_width (w, updated_area);
21189 max_y = window_text_bottom_y (w);
21191 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
21192 of window. For TO_X > 0, truncate to end of drawing area. */
21193 if (to_x == 0)
21194 return;
21195 else if (to_x < 0)
21196 to_x = max_x;
21197 else
21198 to_x = min (to_x, max_x);
21200 to_y = min (max_y, output_cursor.y + updated_row->height);
21202 /* Notice if the cursor will be cleared by this operation. */
21203 if (!updated_row->full_width_p)
21204 notice_overwritten_cursor (w, updated_area,
21205 output_cursor.x, -1,
21206 updated_row->y,
21207 MATRIX_ROW_BOTTOM_Y (updated_row));
21209 from_x = output_cursor.x;
21211 /* Translate to frame coordinates. */
21212 if (updated_row->full_width_p)
21214 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
21215 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
21217 else
21219 int area_left = window_box_left (w, updated_area);
21220 from_x += area_left;
21221 to_x += area_left;
21224 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
21225 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
21226 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
21228 /* Prevent inadvertently clearing to end of the X window. */
21229 if (to_x > from_x && to_y > from_y)
21231 BLOCK_INPUT;
21232 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
21233 to_x - from_x, to_y - from_y);
21234 UNBLOCK_INPUT;
21238 #endif /* HAVE_WINDOW_SYSTEM */
21242 /***********************************************************************
21243 Cursor types
21244 ***********************************************************************/
21246 /* Value is the internal representation of the specified cursor type
21247 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
21248 of the bar cursor. */
21250 static enum text_cursor_kinds
21251 get_specified_cursor_type (arg, width)
21252 Lisp_Object arg;
21253 int *width;
21255 enum text_cursor_kinds type;
21257 if (NILP (arg))
21258 return NO_CURSOR;
21260 if (EQ (arg, Qbox))
21261 return FILLED_BOX_CURSOR;
21263 if (EQ (arg, Qhollow))
21264 return HOLLOW_BOX_CURSOR;
21266 if (EQ (arg, Qbar))
21268 *width = 2;
21269 return BAR_CURSOR;
21272 if (CONSP (arg)
21273 && EQ (XCAR (arg), Qbar)
21274 && INTEGERP (XCDR (arg))
21275 && XINT (XCDR (arg)) >= 0)
21277 *width = XINT (XCDR (arg));
21278 return BAR_CURSOR;
21281 if (EQ (arg, Qhbar))
21283 *width = 2;
21284 return HBAR_CURSOR;
21287 if (CONSP (arg)
21288 && EQ (XCAR (arg), Qhbar)
21289 && INTEGERP (XCDR (arg))
21290 && XINT (XCDR (arg)) >= 0)
21292 *width = XINT (XCDR (arg));
21293 return HBAR_CURSOR;
21296 /* Treat anything unknown as "hollow box cursor".
21297 It was bad to signal an error; people have trouble fixing
21298 .Xdefaults with Emacs, when it has something bad in it. */
21299 type = HOLLOW_BOX_CURSOR;
21301 return type;
21304 /* Set the default cursor types for specified frame. */
21305 void
21306 set_frame_cursor_types (f, arg)
21307 struct frame *f;
21308 Lisp_Object arg;
21310 int width;
21311 Lisp_Object tem;
21313 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
21314 FRAME_CURSOR_WIDTH (f) = width;
21316 /* By default, set up the blink-off state depending on the on-state. */
21318 tem = Fassoc (arg, Vblink_cursor_alist);
21319 if (!NILP (tem))
21321 FRAME_BLINK_OFF_CURSOR (f)
21322 = get_specified_cursor_type (XCDR (tem), &width);
21323 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
21325 else
21326 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
21330 /* Return the cursor we want to be displayed in window W. Return
21331 width of bar/hbar cursor through WIDTH arg. Return with
21332 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
21333 (i.e. if the `system caret' should track this cursor).
21335 In a mini-buffer window, we want the cursor only to appear if we
21336 are reading input from this window. For the selected window, we
21337 want the cursor type given by the frame parameter or buffer local
21338 setting of cursor-type. If explicitly marked off, draw no cursor.
21339 In all other cases, we want a hollow box cursor. */
21341 static enum text_cursor_kinds
21342 get_window_cursor_type (w, glyph, width, active_cursor)
21343 struct window *w;
21344 struct glyph *glyph;
21345 int *width;
21346 int *active_cursor;
21348 struct frame *f = XFRAME (w->frame);
21349 struct buffer *b = XBUFFER (w->buffer);
21350 int cursor_type = DEFAULT_CURSOR;
21351 Lisp_Object alt_cursor;
21352 int non_selected = 0;
21354 *active_cursor = 1;
21356 /* Echo area */
21357 if (cursor_in_echo_area
21358 && FRAME_HAS_MINIBUF_P (f)
21359 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
21361 if (w == XWINDOW (echo_area_window))
21363 if (EQ (b->cursor_type, Qt) || NILP (b->cursor_type))
21365 *width = FRAME_CURSOR_WIDTH (f);
21366 return FRAME_DESIRED_CURSOR (f);
21368 else
21369 return get_specified_cursor_type (b->cursor_type, width);
21372 *active_cursor = 0;
21373 non_selected = 1;
21376 /* Detect a nonselected window or nonselected frame. */
21377 else if (w != XWINDOW (f->selected_window)
21378 #ifdef HAVE_WINDOW_SYSTEM
21379 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
21380 #endif
21383 *active_cursor = 0;
21385 if (MINI_WINDOW_P (w) && minibuf_level == 0)
21386 return NO_CURSOR;
21388 non_selected = 1;
21391 /* Never display a cursor in a window in which cursor-type is nil. */
21392 if (NILP (b->cursor_type))
21393 return NO_CURSOR;
21395 /* Get the normal cursor type for this window. */
21396 if (EQ (b->cursor_type, Qt))
21398 cursor_type = FRAME_DESIRED_CURSOR (f);
21399 *width = FRAME_CURSOR_WIDTH (f);
21401 else
21402 cursor_type = get_specified_cursor_type (b->cursor_type, width);
21404 /* Use cursor-in-non-selected-windows instead
21405 for non-selected window or frame. */
21406 if (non_selected)
21408 alt_cursor = b->cursor_in_non_selected_windows;
21409 if (!EQ (Qt, alt_cursor))
21410 return get_specified_cursor_type (alt_cursor, width);
21411 /* t means modify the normal cursor type. */
21412 if (cursor_type == FILLED_BOX_CURSOR)
21413 cursor_type = HOLLOW_BOX_CURSOR;
21414 else if (cursor_type == BAR_CURSOR && *width > 1)
21415 --*width;
21416 return cursor_type;
21419 /* Use normal cursor if not blinked off. */
21420 if (!w->cursor_off_p)
21422 #ifdef HAVE_WINDOW_SYSTEM
21423 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
21425 if (cursor_type == FILLED_BOX_CURSOR)
21427 /* Using a block cursor on large images can be very annoying.
21428 So use a hollow cursor for "large" images.
21429 If image is not transparent (no mask), also use hollow cursor. */
21430 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
21431 if (img != NULL && IMAGEP (img->spec))
21433 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
21434 where N = size of default frame font size.
21435 This should cover most of the "tiny" icons people may use. */
21436 if (!img->mask
21437 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
21438 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
21439 cursor_type = HOLLOW_BOX_CURSOR;
21442 else if (cursor_type != NO_CURSOR)
21444 /* Display current only supports BOX and HOLLOW cursors for images.
21445 So for now, unconditionally use a HOLLOW cursor when cursor is
21446 not a solid box cursor. */
21447 cursor_type = HOLLOW_BOX_CURSOR;
21450 #endif
21451 return cursor_type;
21454 /* Cursor is blinked off, so determine how to "toggle" it. */
21456 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
21457 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
21458 return get_specified_cursor_type (XCDR (alt_cursor), width);
21460 /* Then see if frame has specified a specific blink off cursor type. */
21461 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
21463 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
21464 return FRAME_BLINK_OFF_CURSOR (f);
21467 #if 0
21468 /* Some people liked having a permanently visible blinking cursor,
21469 while others had very strong opinions against it. So it was
21470 decided to remove it. KFS 2003-09-03 */
21472 /* Finally perform built-in cursor blinking:
21473 filled box <-> hollow box
21474 wide [h]bar <-> narrow [h]bar
21475 narrow [h]bar <-> no cursor
21476 other type <-> no cursor */
21478 if (cursor_type == FILLED_BOX_CURSOR)
21479 return HOLLOW_BOX_CURSOR;
21481 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
21483 *width = 1;
21484 return cursor_type;
21486 #endif
21488 return NO_CURSOR;
21492 #ifdef HAVE_WINDOW_SYSTEM
21494 /* Notice when the text cursor of window W has been completely
21495 overwritten by a drawing operation that outputs glyphs in AREA
21496 starting at X0 and ending at X1 in the line starting at Y0 and
21497 ending at Y1. X coordinates are area-relative. X1 < 0 means all
21498 the rest of the line after X0 has been written. Y coordinates
21499 are window-relative. */
21501 static void
21502 notice_overwritten_cursor (w, area, x0, x1, y0, y1)
21503 struct window *w;
21504 enum glyph_row_area area;
21505 int x0, y0, x1, y1;
21507 int cx0, cx1, cy0, cy1;
21508 struct glyph_row *row;
21510 if (!w->phys_cursor_on_p)
21511 return;
21512 if (area != TEXT_AREA)
21513 return;
21515 if (w->phys_cursor.vpos < 0
21516 || w->phys_cursor.vpos >= w->current_matrix->nrows
21517 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
21518 !(row->enabled_p && row->displays_text_p)))
21519 return;
21521 if (row->cursor_in_fringe_p)
21523 row->cursor_in_fringe_p = 0;
21524 draw_fringe_bitmap (w, row, 0);
21525 w->phys_cursor_on_p = 0;
21526 return;
21529 cx0 = w->phys_cursor.x;
21530 cx1 = cx0 + w->phys_cursor_width;
21531 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
21532 return;
21534 /* The cursor image will be completely removed from the
21535 screen if the output area intersects the cursor area in
21536 y-direction. When we draw in [y0 y1[, and some part of
21537 the cursor is at y < y0, that part must have been drawn
21538 before. When scrolling, the cursor is erased before
21539 actually scrolling, so we don't come here. When not
21540 scrolling, the rows above the old cursor row must have
21541 changed, and in this case these rows must have written
21542 over the cursor image.
21544 Likewise if part of the cursor is below y1, with the
21545 exception of the cursor being in the first blank row at
21546 the buffer and window end because update_text_area
21547 doesn't draw that row. (Except when it does, but
21548 that's handled in update_text_area.) */
21550 cy0 = w->phys_cursor.y;
21551 cy1 = cy0 + w->phys_cursor_height;
21552 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
21553 return;
21555 w->phys_cursor_on_p = 0;
21558 #endif /* HAVE_WINDOW_SYSTEM */
21561 /************************************************************************
21562 Mouse Face
21563 ************************************************************************/
21565 #ifdef HAVE_WINDOW_SYSTEM
21567 /* EXPORT for RIF:
21568 Fix the display of area AREA of overlapping row ROW in window W
21569 with respect to the overlapping part OVERLAPS. */
21571 void
21572 x_fix_overlapping_area (w, row, area, overlaps)
21573 struct window *w;
21574 struct glyph_row *row;
21575 enum glyph_row_area area;
21576 int overlaps;
21578 int i, x;
21580 BLOCK_INPUT;
21582 x = 0;
21583 for (i = 0; i < row->used[area];)
21585 if (row->glyphs[area][i].overlaps_vertically_p)
21587 int start = i, start_x = x;
21591 x += row->glyphs[area][i].pixel_width;
21592 ++i;
21594 while (i < row->used[area]
21595 && row->glyphs[area][i].overlaps_vertically_p);
21597 draw_glyphs (w, start_x, row, area,
21598 start, i,
21599 DRAW_NORMAL_TEXT, overlaps);
21601 else
21603 x += row->glyphs[area][i].pixel_width;
21604 ++i;
21608 UNBLOCK_INPUT;
21612 /* EXPORT:
21613 Draw the cursor glyph of window W in glyph row ROW. See the
21614 comment of draw_glyphs for the meaning of HL. */
21616 void
21617 draw_phys_cursor_glyph (w, row, hl)
21618 struct window *w;
21619 struct glyph_row *row;
21620 enum draw_glyphs_face hl;
21622 /* If cursor hpos is out of bounds, don't draw garbage. This can
21623 happen in mini-buffer windows when switching between echo area
21624 glyphs and mini-buffer. */
21625 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
21627 int on_p = w->phys_cursor_on_p;
21628 int x1;
21629 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
21630 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
21631 hl, 0);
21632 w->phys_cursor_on_p = on_p;
21634 if (hl == DRAW_CURSOR)
21635 w->phys_cursor_width = x1 - w->phys_cursor.x;
21636 /* When we erase the cursor, and ROW is overlapped by other
21637 rows, make sure that these overlapping parts of other rows
21638 are redrawn. */
21639 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
21641 w->phys_cursor_width = x1 - w->phys_cursor.x;
21643 if (row > w->current_matrix->rows
21644 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
21645 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
21646 OVERLAPS_ERASED_CURSOR);
21648 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
21649 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
21650 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
21651 OVERLAPS_ERASED_CURSOR);
21657 /* EXPORT:
21658 Erase the image of a cursor of window W from the screen. */
21660 void
21661 erase_phys_cursor (w)
21662 struct window *w;
21664 struct frame *f = XFRAME (w->frame);
21665 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21666 int hpos = w->phys_cursor.hpos;
21667 int vpos = w->phys_cursor.vpos;
21668 int mouse_face_here_p = 0;
21669 struct glyph_matrix *active_glyphs = w->current_matrix;
21670 struct glyph_row *cursor_row;
21671 struct glyph *cursor_glyph;
21672 enum draw_glyphs_face hl;
21674 /* No cursor displayed or row invalidated => nothing to do on the
21675 screen. */
21676 if (w->phys_cursor_type == NO_CURSOR)
21677 goto mark_cursor_off;
21679 /* VPOS >= active_glyphs->nrows means that window has been resized.
21680 Don't bother to erase the cursor. */
21681 if (vpos >= active_glyphs->nrows)
21682 goto mark_cursor_off;
21684 /* If row containing cursor is marked invalid, there is nothing we
21685 can do. */
21686 cursor_row = MATRIX_ROW (active_glyphs, vpos);
21687 if (!cursor_row->enabled_p)
21688 goto mark_cursor_off;
21690 /* If line spacing is > 0, old cursor may only be partially visible in
21691 window after split-window. So adjust visible height. */
21692 cursor_row->visible_height = min (cursor_row->visible_height,
21693 window_text_bottom_y (w) - cursor_row->y);
21695 /* If row is completely invisible, don't attempt to delete a cursor which
21696 isn't there. This can happen if cursor is at top of a window, and
21697 we switch to a buffer with a header line in that window. */
21698 if (cursor_row->visible_height <= 0)
21699 goto mark_cursor_off;
21701 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
21702 if (cursor_row->cursor_in_fringe_p)
21704 cursor_row->cursor_in_fringe_p = 0;
21705 draw_fringe_bitmap (w, cursor_row, 0);
21706 goto mark_cursor_off;
21709 /* This can happen when the new row is shorter than the old one.
21710 In this case, either draw_glyphs or clear_end_of_line
21711 should have cleared the cursor. Note that we wouldn't be
21712 able to erase the cursor in this case because we don't have a
21713 cursor glyph at hand. */
21714 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
21715 goto mark_cursor_off;
21717 /* If the cursor is in the mouse face area, redisplay that when
21718 we clear the cursor. */
21719 if (! NILP (dpyinfo->mouse_face_window)
21720 && w == XWINDOW (dpyinfo->mouse_face_window)
21721 && (vpos > dpyinfo->mouse_face_beg_row
21722 || (vpos == dpyinfo->mouse_face_beg_row
21723 && hpos >= dpyinfo->mouse_face_beg_col))
21724 && (vpos < dpyinfo->mouse_face_end_row
21725 || (vpos == dpyinfo->mouse_face_end_row
21726 && hpos < dpyinfo->mouse_face_end_col))
21727 /* Don't redraw the cursor's spot in mouse face if it is at the
21728 end of a line (on a newline). The cursor appears there, but
21729 mouse highlighting does not. */
21730 && cursor_row->used[TEXT_AREA] > hpos)
21731 mouse_face_here_p = 1;
21733 /* Maybe clear the display under the cursor. */
21734 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
21736 int x, y, left_x;
21737 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
21738 int width;
21740 cursor_glyph = get_phys_cursor_glyph (w);
21741 if (cursor_glyph == NULL)
21742 goto mark_cursor_off;
21744 width = cursor_glyph->pixel_width;
21745 left_x = window_box_left_offset (w, TEXT_AREA);
21746 x = w->phys_cursor.x;
21747 if (x < left_x)
21748 width -= left_x - x;
21749 width = min (width, window_box_width (w, TEXT_AREA) - x);
21750 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
21751 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
21753 if (width > 0)
21754 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
21757 /* Erase the cursor by redrawing the character underneath it. */
21758 if (mouse_face_here_p)
21759 hl = DRAW_MOUSE_FACE;
21760 else
21761 hl = DRAW_NORMAL_TEXT;
21762 draw_phys_cursor_glyph (w, cursor_row, hl);
21764 mark_cursor_off:
21765 w->phys_cursor_on_p = 0;
21766 w->phys_cursor_type = NO_CURSOR;
21770 /* EXPORT:
21771 Display or clear cursor of window W. If ON is zero, clear the
21772 cursor. If it is non-zero, display the cursor. If ON is nonzero,
21773 where to put the cursor is specified by HPOS, VPOS, X and Y. */
21775 void
21776 display_and_set_cursor (w, on, hpos, vpos, x, y)
21777 struct window *w;
21778 int on, hpos, vpos, x, y;
21780 struct frame *f = XFRAME (w->frame);
21781 int new_cursor_type;
21782 int new_cursor_width;
21783 int active_cursor;
21784 struct glyph_row *glyph_row;
21785 struct glyph *glyph;
21787 /* This is pointless on invisible frames, and dangerous on garbaged
21788 windows and frames; in the latter case, the frame or window may
21789 be in the midst of changing its size, and x and y may be off the
21790 window. */
21791 if (! FRAME_VISIBLE_P (f)
21792 || FRAME_GARBAGED_P (f)
21793 || vpos >= w->current_matrix->nrows
21794 || hpos >= w->current_matrix->matrix_w)
21795 return;
21797 /* If cursor is off and we want it off, return quickly. */
21798 if (!on && !w->phys_cursor_on_p)
21799 return;
21801 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
21802 /* If cursor row is not enabled, we don't really know where to
21803 display the cursor. */
21804 if (!glyph_row->enabled_p)
21806 w->phys_cursor_on_p = 0;
21807 return;
21810 glyph = NULL;
21811 if (!glyph_row->exact_window_width_line_p
21812 || hpos < glyph_row->used[TEXT_AREA])
21813 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
21815 xassert (interrupt_input_blocked);
21817 /* Set new_cursor_type to the cursor we want to be displayed. */
21818 new_cursor_type = get_window_cursor_type (w, glyph,
21819 &new_cursor_width, &active_cursor);
21821 /* If cursor is currently being shown and we don't want it to be or
21822 it is in the wrong place, or the cursor type is not what we want,
21823 erase it. */
21824 if (w->phys_cursor_on_p
21825 && (!on
21826 || w->phys_cursor.x != x
21827 || w->phys_cursor.y != y
21828 || new_cursor_type != w->phys_cursor_type
21829 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
21830 && new_cursor_width != w->phys_cursor_width)))
21831 erase_phys_cursor (w);
21833 /* Don't check phys_cursor_on_p here because that flag is only set
21834 to zero in some cases where we know that the cursor has been
21835 completely erased, to avoid the extra work of erasing the cursor
21836 twice. In other words, phys_cursor_on_p can be 1 and the cursor
21837 still not be visible, or it has only been partly erased. */
21838 if (on)
21840 w->phys_cursor_ascent = glyph_row->ascent;
21841 w->phys_cursor_height = glyph_row->height;
21843 /* Set phys_cursor_.* before x_draw_.* is called because some
21844 of them may need the information. */
21845 w->phys_cursor.x = x;
21846 w->phys_cursor.y = glyph_row->y;
21847 w->phys_cursor.hpos = hpos;
21848 w->phys_cursor.vpos = vpos;
21851 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
21852 new_cursor_type, new_cursor_width,
21853 on, active_cursor);
21857 /* Switch the display of W's cursor on or off, according to the value
21858 of ON. */
21860 static void
21861 update_window_cursor (w, on)
21862 struct window *w;
21863 int on;
21865 /* Don't update cursor in windows whose frame is in the process
21866 of being deleted. */
21867 if (w->current_matrix)
21869 BLOCK_INPUT;
21870 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
21871 w->phys_cursor.x, w->phys_cursor.y);
21872 UNBLOCK_INPUT;
21877 /* Call update_window_cursor with parameter ON_P on all leaf windows
21878 in the window tree rooted at W. */
21880 static void
21881 update_cursor_in_window_tree (w, on_p)
21882 struct window *w;
21883 int on_p;
21885 while (w)
21887 if (!NILP (w->hchild))
21888 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
21889 else if (!NILP (w->vchild))
21890 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
21891 else
21892 update_window_cursor (w, on_p);
21894 w = NILP (w->next) ? 0 : XWINDOW (w->next);
21899 /* EXPORT:
21900 Display the cursor on window W, or clear it, according to ON_P.
21901 Don't change the cursor's position. */
21903 void
21904 x_update_cursor (f, on_p)
21905 struct frame *f;
21906 int on_p;
21908 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
21912 /* EXPORT:
21913 Clear the cursor of window W to background color, and mark the
21914 cursor as not shown. This is used when the text where the cursor
21915 is is about to be rewritten. */
21917 void
21918 x_clear_cursor (w)
21919 struct window *w;
21921 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
21922 update_window_cursor (w, 0);
21926 /* EXPORT:
21927 Display the active region described by mouse_face_* according to DRAW. */
21929 void
21930 show_mouse_face (dpyinfo, draw)
21931 Display_Info *dpyinfo;
21932 enum draw_glyphs_face draw;
21934 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
21935 struct frame *f = XFRAME (WINDOW_FRAME (w));
21937 if (/* If window is in the process of being destroyed, don't bother
21938 to do anything. */
21939 w->current_matrix != NULL
21940 /* Don't update mouse highlight if hidden */
21941 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
21942 /* Recognize when we are called to operate on rows that don't exist
21943 anymore. This can happen when a window is split. */
21944 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
21946 int phys_cursor_on_p = w->phys_cursor_on_p;
21947 struct glyph_row *row, *first, *last;
21949 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
21950 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
21952 for (row = first; row <= last && row->enabled_p; ++row)
21954 int start_hpos, end_hpos, start_x;
21956 /* For all but the first row, the highlight starts at column 0. */
21957 if (row == first)
21959 start_hpos = dpyinfo->mouse_face_beg_col;
21960 start_x = dpyinfo->mouse_face_beg_x;
21962 else
21964 start_hpos = 0;
21965 start_x = 0;
21968 if (row == last)
21969 end_hpos = dpyinfo->mouse_face_end_col;
21970 else
21972 end_hpos = row->used[TEXT_AREA];
21973 if (draw == DRAW_NORMAL_TEXT)
21974 row->fill_line_p = 1; /* Clear to end of line */
21977 if (end_hpos > start_hpos)
21979 draw_glyphs (w, start_x, row, TEXT_AREA,
21980 start_hpos, end_hpos,
21981 draw, 0);
21983 row->mouse_face_p
21984 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
21988 /* When we've written over the cursor, arrange for it to
21989 be displayed again. */
21990 if (phys_cursor_on_p && !w->phys_cursor_on_p)
21992 BLOCK_INPUT;
21993 display_and_set_cursor (w, 1,
21994 w->phys_cursor.hpos, w->phys_cursor.vpos,
21995 w->phys_cursor.x, w->phys_cursor.y);
21996 UNBLOCK_INPUT;
22000 /* Change the mouse cursor. */
22001 if (draw == DRAW_NORMAL_TEXT && !EQ (dpyinfo->mouse_face_window, f->tool_bar_window))
22002 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
22003 else if (draw == DRAW_MOUSE_FACE)
22004 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
22005 else
22006 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
22009 /* EXPORT:
22010 Clear out the mouse-highlighted active region.
22011 Redraw it un-highlighted first. Value is non-zero if mouse
22012 face was actually drawn unhighlighted. */
22015 clear_mouse_face (dpyinfo)
22016 Display_Info *dpyinfo;
22018 int cleared = 0;
22020 if (!dpyinfo->mouse_face_hidden && !NILP (dpyinfo->mouse_face_window))
22022 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
22023 cleared = 1;
22026 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
22027 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
22028 dpyinfo->mouse_face_window = Qnil;
22029 dpyinfo->mouse_face_overlay = Qnil;
22030 return cleared;
22034 /* EXPORT:
22035 Non-zero if physical cursor of window W is within mouse face. */
22038 cursor_in_mouse_face_p (w)
22039 struct window *w;
22041 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
22042 int in_mouse_face = 0;
22044 if (WINDOWP (dpyinfo->mouse_face_window)
22045 && XWINDOW (dpyinfo->mouse_face_window) == w)
22047 int hpos = w->phys_cursor.hpos;
22048 int vpos = w->phys_cursor.vpos;
22050 if (vpos >= dpyinfo->mouse_face_beg_row
22051 && vpos <= dpyinfo->mouse_face_end_row
22052 && (vpos > dpyinfo->mouse_face_beg_row
22053 || hpos >= dpyinfo->mouse_face_beg_col)
22054 && (vpos < dpyinfo->mouse_face_end_row
22055 || hpos < dpyinfo->mouse_face_end_col
22056 || dpyinfo->mouse_face_past_end))
22057 in_mouse_face = 1;
22060 return in_mouse_face;
22066 /* Find the glyph matrix position of buffer position CHARPOS in window
22067 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
22068 current glyphs must be up to date. If CHARPOS is above window
22069 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
22070 of last line in W. In the row containing CHARPOS, stop before glyphs
22071 having STOP as object. */
22073 #if 1 /* This is a version of fast_find_position that's more correct
22074 in the presence of hscrolling, for example. I didn't install
22075 it right away because the problem fixed is minor, it failed
22076 in 20.x as well, and I think it's too risky to install
22077 so near the release of 21.1. 2001-09-25 gerd. */
22079 static int
22080 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
22081 struct window *w;
22082 int charpos;
22083 int *hpos, *vpos, *x, *y;
22084 Lisp_Object stop;
22086 struct glyph_row *row, *first;
22087 struct glyph *glyph, *end;
22088 int past_end = 0;
22090 first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
22091 if (charpos < MATRIX_ROW_START_CHARPOS (first))
22093 *x = first->x;
22094 *y = first->y;
22095 *hpos = 0;
22096 *vpos = MATRIX_ROW_VPOS (first, w->current_matrix);
22097 return 1;
22100 row = row_containing_pos (w, charpos, first, NULL, 0);
22101 if (row == NULL)
22103 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
22104 past_end = 1;
22107 /* If whole rows or last part of a row came from a display overlay,
22108 row_containing_pos will skip over such rows because their end pos
22109 equals the start pos of the overlay or interval.
22111 Move back if we have a STOP object and previous row's
22112 end glyph came from STOP. */
22113 if (!NILP (stop))
22115 struct glyph_row *prev;
22116 while ((prev = row - 1, prev >= first)
22117 && MATRIX_ROW_END_CHARPOS (prev) == charpos
22118 && prev->used[TEXT_AREA] > 0)
22120 struct glyph *beg = prev->glyphs[TEXT_AREA];
22121 glyph = beg + prev->used[TEXT_AREA];
22122 while (--glyph >= beg
22123 && INTEGERP (glyph->object));
22124 if (glyph < beg
22125 || !EQ (stop, glyph->object))
22126 break;
22127 row = prev;
22131 *x = row->x;
22132 *y = row->y;
22133 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
22135 glyph = row->glyphs[TEXT_AREA];
22136 end = glyph + row->used[TEXT_AREA];
22138 /* Skip over glyphs not having an object at the start of the row.
22139 These are special glyphs like truncation marks on terminal
22140 frames. */
22141 if (row->displays_text_p)
22142 while (glyph < end
22143 && INTEGERP (glyph->object)
22144 && !EQ (stop, glyph->object)
22145 && glyph->charpos < 0)
22147 *x += glyph->pixel_width;
22148 ++glyph;
22151 while (glyph < end
22152 && !INTEGERP (glyph->object)
22153 && !EQ (stop, glyph->object)
22154 && (!BUFFERP (glyph->object)
22155 || glyph->charpos < charpos))
22157 *x += glyph->pixel_width;
22158 ++glyph;
22161 *hpos = glyph - row->glyphs[TEXT_AREA];
22162 return !past_end;
22165 #else /* not 1 */
22167 static int
22168 fast_find_position (w, pos, hpos, vpos, x, y, stop)
22169 struct window *w;
22170 int pos;
22171 int *hpos, *vpos, *x, *y;
22172 Lisp_Object stop;
22174 int i;
22175 int lastcol;
22176 int maybe_next_line_p = 0;
22177 int line_start_position;
22178 int yb = window_text_bottom_y (w);
22179 struct glyph_row *row, *best_row;
22180 int row_vpos, best_row_vpos;
22181 int current_x;
22183 row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
22184 row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
22186 while (row->y < yb)
22188 if (row->used[TEXT_AREA])
22189 line_start_position = row->glyphs[TEXT_AREA]->charpos;
22190 else
22191 line_start_position = 0;
22193 if (line_start_position > pos)
22194 break;
22195 /* If the position sought is the end of the buffer,
22196 don't include the blank lines at the bottom of the window. */
22197 else if (line_start_position == pos
22198 && pos == BUF_ZV (XBUFFER (w->buffer)))
22200 maybe_next_line_p = 1;
22201 break;
22203 else if (line_start_position > 0)
22205 best_row = row;
22206 best_row_vpos = row_vpos;
22209 if (row->y + row->height >= yb)
22210 break;
22212 ++row;
22213 ++row_vpos;
22216 /* Find the right column within BEST_ROW. */
22217 lastcol = 0;
22218 current_x = best_row->x;
22219 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
22221 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
22222 int charpos = glyph->charpos;
22224 if (BUFFERP (glyph->object))
22226 if (charpos == pos)
22228 *hpos = i;
22229 *vpos = best_row_vpos;
22230 *x = current_x;
22231 *y = best_row->y;
22232 return 1;
22234 else if (charpos > pos)
22235 break;
22237 else if (EQ (glyph->object, stop))
22238 break;
22240 if (charpos > 0)
22241 lastcol = i;
22242 current_x += glyph->pixel_width;
22245 /* If we're looking for the end of the buffer,
22246 and we didn't find it in the line we scanned,
22247 use the start of the following line. */
22248 if (maybe_next_line_p)
22250 ++best_row;
22251 ++best_row_vpos;
22252 lastcol = 0;
22253 current_x = best_row->x;
22256 *vpos = best_row_vpos;
22257 *hpos = lastcol + 1;
22258 *x = current_x;
22259 *y = best_row->y;
22260 return 0;
22263 #endif /* not 1 */
22266 /* Find the position of the glyph for position POS in OBJECT in
22267 window W's current matrix, and return in *X, *Y the pixel
22268 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
22270 RIGHT_P non-zero means return the position of the right edge of the
22271 glyph, RIGHT_P zero means return the left edge position.
22273 If no glyph for POS exists in the matrix, return the position of
22274 the glyph with the next smaller position that is in the matrix, if
22275 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
22276 exists in the matrix, return the position of the glyph with the
22277 next larger position in OBJECT.
22279 Value is non-zero if a glyph was found. */
22281 static int
22282 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
22283 struct window *w;
22284 int pos;
22285 Lisp_Object object;
22286 int *hpos, *vpos, *x, *y;
22287 int right_p;
22289 int yb = window_text_bottom_y (w);
22290 struct glyph_row *r;
22291 struct glyph *best_glyph = NULL;
22292 struct glyph_row *best_row = NULL;
22293 int best_x = 0;
22295 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
22296 r->enabled_p && r->y < yb;
22297 ++r)
22299 struct glyph *g = r->glyphs[TEXT_AREA];
22300 struct glyph *e = g + r->used[TEXT_AREA];
22301 int gx;
22303 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
22304 if (EQ (g->object, object))
22306 if (g->charpos == pos)
22308 best_glyph = g;
22309 best_x = gx;
22310 best_row = r;
22311 goto found;
22313 else if (best_glyph == NULL
22314 || ((eabs (g->charpos - pos)
22315 < eabs (best_glyph->charpos - pos))
22316 && (right_p
22317 ? g->charpos < pos
22318 : g->charpos > pos)))
22320 best_glyph = g;
22321 best_x = gx;
22322 best_row = r;
22327 found:
22329 if (best_glyph)
22331 *x = best_x;
22332 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
22334 if (right_p)
22336 *x += best_glyph->pixel_width;
22337 ++*hpos;
22340 *y = best_row->y;
22341 *vpos = best_row - w->current_matrix->rows;
22344 return best_glyph != NULL;
22348 /* See if position X, Y is within a hot-spot of an image. */
22350 static int
22351 on_hot_spot_p (hot_spot, x, y)
22352 Lisp_Object hot_spot;
22353 int x, y;
22355 if (!CONSP (hot_spot))
22356 return 0;
22358 if (EQ (XCAR (hot_spot), Qrect))
22360 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
22361 Lisp_Object rect = XCDR (hot_spot);
22362 Lisp_Object tem;
22363 if (!CONSP (rect))
22364 return 0;
22365 if (!CONSP (XCAR (rect)))
22366 return 0;
22367 if (!CONSP (XCDR (rect)))
22368 return 0;
22369 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
22370 return 0;
22371 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
22372 return 0;
22373 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
22374 return 0;
22375 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
22376 return 0;
22377 return 1;
22379 else if (EQ (XCAR (hot_spot), Qcircle))
22381 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
22382 Lisp_Object circ = XCDR (hot_spot);
22383 Lisp_Object lr, lx0, ly0;
22384 if (CONSP (circ)
22385 && CONSP (XCAR (circ))
22386 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
22387 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
22388 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
22390 double r = XFLOATINT (lr);
22391 double dx = XINT (lx0) - x;
22392 double dy = XINT (ly0) - y;
22393 return (dx * dx + dy * dy <= r * r);
22396 else if (EQ (XCAR (hot_spot), Qpoly))
22398 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
22399 if (VECTORP (XCDR (hot_spot)))
22401 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
22402 Lisp_Object *poly = v->contents;
22403 int n = v->size;
22404 int i;
22405 int inside = 0;
22406 Lisp_Object lx, ly;
22407 int x0, y0;
22409 /* Need an even number of coordinates, and at least 3 edges. */
22410 if (n < 6 || n & 1)
22411 return 0;
22413 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
22414 If count is odd, we are inside polygon. Pixels on edges
22415 may or may not be included depending on actual geometry of the
22416 polygon. */
22417 if ((lx = poly[n-2], !INTEGERP (lx))
22418 || (ly = poly[n-1], !INTEGERP (lx)))
22419 return 0;
22420 x0 = XINT (lx), y0 = XINT (ly);
22421 for (i = 0; i < n; i += 2)
22423 int x1 = x0, y1 = y0;
22424 if ((lx = poly[i], !INTEGERP (lx))
22425 || (ly = poly[i+1], !INTEGERP (ly)))
22426 return 0;
22427 x0 = XINT (lx), y0 = XINT (ly);
22429 /* Does this segment cross the X line? */
22430 if (x0 >= x)
22432 if (x1 >= x)
22433 continue;
22435 else if (x1 < x)
22436 continue;
22437 if (y > y0 && y > y1)
22438 continue;
22439 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
22440 inside = !inside;
22442 return inside;
22445 return 0;
22448 Lisp_Object
22449 find_hot_spot (map, x, y)
22450 Lisp_Object map;
22451 int x, y;
22453 while (CONSP (map))
22455 if (CONSP (XCAR (map))
22456 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
22457 return XCAR (map);
22458 map = XCDR (map);
22461 return Qnil;
22464 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
22465 3, 3, 0,
22466 doc: /* Lookup in image map MAP coordinates X and Y.
22467 An image map is an alist where each element has the format (AREA ID PLIST).
22468 An AREA is specified as either a rectangle, a circle, or a polygon:
22469 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
22470 pixel coordinates of the upper left and bottom right corners.
22471 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
22472 and the radius of the circle; r may be a float or integer.
22473 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
22474 vector describes one corner in the polygon.
22475 Returns the alist element for the first matching AREA in MAP. */)
22476 (map, x, y)
22477 Lisp_Object map;
22478 Lisp_Object x, y;
22480 if (NILP (map))
22481 return Qnil;
22483 CHECK_NUMBER (x);
22484 CHECK_NUMBER (y);
22486 return find_hot_spot (map, XINT (x), XINT (y));
22490 /* Display frame CURSOR, optionally using shape defined by POINTER. */
22491 static void
22492 define_frame_cursor1 (f, cursor, pointer)
22493 struct frame *f;
22494 Cursor cursor;
22495 Lisp_Object pointer;
22497 /* Do not change cursor shape while dragging mouse. */
22498 if (!NILP (do_mouse_tracking))
22499 return;
22501 if (!NILP (pointer))
22503 if (EQ (pointer, Qarrow))
22504 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
22505 else if (EQ (pointer, Qhand))
22506 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
22507 else if (EQ (pointer, Qtext))
22508 cursor = FRAME_X_OUTPUT (f)->text_cursor;
22509 else if (EQ (pointer, intern ("hdrag")))
22510 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
22511 #ifdef HAVE_X_WINDOWS
22512 else if (EQ (pointer, intern ("vdrag")))
22513 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
22514 #endif
22515 else if (EQ (pointer, intern ("hourglass")))
22516 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
22517 else if (EQ (pointer, Qmodeline))
22518 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
22519 else
22520 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
22523 if (cursor != No_Cursor)
22524 FRAME_RIF (f)->define_frame_cursor (f, cursor);
22527 /* Take proper action when mouse has moved to the mode or header line
22528 or marginal area AREA of window W, x-position X and y-position Y.
22529 X is relative to the start of the text display area of W, so the
22530 width of bitmap areas and scroll bars must be subtracted to get a
22531 position relative to the start of the mode line. */
22533 static void
22534 note_mode_line_or_margin_highlight (window, x, y, area)
22535 Lisp_Object window;
22536 int x, y;
22537 enum window_part area;
22539 struct window *w = XWINDOW (window);
22540 struct frame *f = XFRAME (w->frame);
22541 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
22542 Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
22543 Lisp_Object pointer = Qnil;
22544 int charpos, dx, dy, width, height;
22545 Lisp_Object string, object = Qnil;
22546 Lisp_Object pos, help;
22548 Lisp_Object mouse_face;
22549 int original_x_pixel = x;
22550 struct glyph * glyph = NULL, * row_start_glyph = NULL;
22551 struct glyph_row *row;
22553 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
22555 int x0;
22556 struct glyph *end;
22558 string = mode_line_string (w, area, &x, &y, &charpos,
22559 &object, &dx, &dy, &width, &height);
22561 row = (area == ON_MODE_LINE
22562 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
22563 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
22565 /* Find glyph */
22566 if (row->mode_line_p && row->enabled_p)
22568 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
22569 end = glyph + row->used[TEXT_AREA];
22571 for (x0 = original_x_pixel;
22572 glyph < end && x0 >= glyph->pixel_width;
22573 ++glyph)
22574 x0 -= glyph->pixel_width;
22576 if (glyph >= end)
22577 glyph = NULL;
22580 else
22582 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
22583 string = marginal_area_string (w, area, &x, &y, &charpos,
22584 &object, &dx, &dy, &width, &height);
22587 help = Qnil;
22589 if (IMAGEP (object))
22591 Lisp_Object image_map, hotspot;
22592 if ((image_map = Fplist_get (XCDR (object), QCmap),
22593 !NILP (image_map))
22594 && (hotspot = find_hot_spot (image_map, dx, dy),
22595 CONSP (hotspot))
22596 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
22598 Lisp_Object area_id, plist;
22600 area_id = XCAR (hotspot);
22601 /* Could check AREA_ID to see if we enter/leave this hot-spot.
22602 If so, we could look for mouse-enter, mouse-leave
22603 properties in PLIST (and do something...). */
22604 hotspot = XCDR (hotspot);
22605 if (CONSP (hotspot)
22606 && (plist = XCAR (hotspot), CONSP (plist)))
22608 pointer = Fplist_get (plist, Qpointer);
22609 if (NILP (pointer))
22610 pointer = Qhand;
22611 help = Fplist_get (plist, Qhelp_echo);
22612 if (!NILP (help))
22614 help_echo_string = help;
22615 /* Is this correct? ++kfs */
22616 XSETWINDOW (help_echo_window, w);
22617 help_echo_object = w->buffer;
22618 help_echo_pos = charpos;
22622 if (NILP (pointer))
22623 pointer = Fplist_get (XCDR (object), QCpointer);
22626 if (STRINGP (string))
22628 pos = make_number (charpos);
22629 /* If we're on a string with `help-echo' text property, arrange
22630 for the help to be displayed. This is done by setting the
22631 global variable help_echo_string to the help string. */
22632 if (NILP (help))
22634 help = Fget_text_property (pos, Qhelp_echo, string);
22635 if (!NILP (help))
22637 help_echo_string = help;
22638 XSETWINDOW (help_echo_window, w);
22639 help_echo_object = string;
22640 help_echo_pos = charpos;
22644 if (NILP (pointer))
22645 pointer = Fget_text_property (pos, Qpointer, string);
22647 /* Change the mouse pointer according to what is under X/Y. */
22648 if (NILP (pointer) && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
22650 Lisp_Object map;
22651 map = Fget_text_property (pos, Qlocal_map, string);
22652 if (!KEYMAPP (map))
22653 map = Fget_text_property (pos, Qkeymap, string);
22654 if (!KEYMAPP (map))
22655 cursor = dpyinfo->vertical_scroll_bar_cursor;
22658 /* Change the mouse face according to what is under X/Y. */
22659 mouse_face = Fget_text_property (pos, Qmouse_face, string);
22660 if (!NILP (mouse_face)
22661 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
22662 && glyph)
22664 Lisp_Object b, e;
22666 struct glyph * tmp_glyph;
22668 int gpos;
22669 int gseq_length;
22670 int total_pixel_width;
22671 int ignore;
22673 int vpos, hpos;
22675 b = Fprevious_single_property_change (make_number (charpos + 1),
22676 Qmouse_face, string, Qnil);
22677 if (NILP (b))
22678 b = make_number (0);
22680 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
22681 if (NILP (e))
22682 e = make_number (SCHARS (string));
22684 /* Calculate the position(glyph position: GPOS) of GLYPH in
22685 displayed string. GPOS is different from CHARPOS.
22687 CHARPOS is the position of glyph in internal string
22688 object. A mode line string format has structures which
22689 is converted to a flatten by emacs lisp interpreter.
22690 The internal string is an element of the structures.
22691 The displayed string is the flatten string. */
22692 gpos = 0;
22693 if (glyph > row_start_glyph)
22695 tmp_glyph = glyph - 1;
22696 while (tmp_glyph >= row_start_glyph
22697 && tmp_glyph->charpos >= XINT (b)
22698 && EQ (tmp_glyph->object, glyph->object))
22700 tmp_glyph--;
22701 gpos++;
22705 /* Calculate the lenght(glyph sequence length: GSEQ_LENGTH) of
22706 displayed string holding GLYPH.
22708 GSEQ_LENGTH is different from SCHARS (STRING).
22709 SCHARS (STRING) returns the length of the internal string. */
22710 for (tmp_glyph = glyph, gseq_length = gpos;
22711 tmp_glyph->charpos < XINT (e);
22712 tmp_glyph++, gseq_length++)
22714 if (!EQ (tmp_glyph->object, glyph->object))
22715 break;
22718 total_pixel_width = 0;
22719 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
22720 total_pixel_width += tmp_glyph->pixel_width;
22722 /* Pre calculation of re-rendering position */
22723 vpos = (x - gpos);
22724 hpos = (area == ON_MODE_LINE
22725 ? (w->current_matrix)->nrows - 1
22726 : 0);
22728 /* If the re-rendering position is included in the last
22729 re-rendering area, we should do nothing. */
22730 if ( EQ (window, dpyinfo->mouse_face_window)
22731 && dpyinfo->mouse_face_beg_col <= vpos
22732 && vpos < dpyinfo->mouse_face_end_col
22733 && dpyinfo->mouse_face_beg_row == hpos )
22734 return;
22736 if (clear_mouse_face (dpyinfo))
22737 cursor = No_Cursor;
22739 dpyinfo->mouse_face_beg_col = vpos;
22740 dpyinfo->mouse_face_beg_row = hpos;
22742 dpyinfo->mouse_face_beg_x = original_x_pixel - (total_pixel_width + dx);
22743 dpyinfo->mouse_face_beg_y = 0;
22745 dpyinfo->mouse_face_end_col = vpos + gseq_length;
22746 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_beg_row;
22748 dpyinfo->mouse_face_end_x = 0;
22749 dpyinfo->mouse_face_end_y = 0;
22751 dpyinfo->mouse_face_past_end = 0;
22752 dpyinfo->mouse_face_window = window;
22754 dpyinfo->mouse_face_face_id = face_at_string_position (w, string,
22755 charpos,
22756 0, 0, 0, &ignore,
22757 glyph->face_id, 1);
22758 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
22760 if (NILP (pointer))
22761 pointer = Qhand;
22763 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
22764 clear_mouse_face (dpyinfo);
22766 define_frame_cursor1 (f, cursor, pointer);
22770 /* EXPORT:
22771 Take proper action when the mouse has moved to position X, Y on
22772 frame F as regards highlighting characters that have mouse-face
22773 properties. Also de-highlighting chars where the mouse was before.
22774 X and Y can be negative or out of range. */
22776 void
22777 note_mouse_highlight (f, x, y)
22778 struct frame *f;
22779 int x, y;
22781 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
22782 enum window_part part;
22783 Lisp_Object window;
22784 struct window *w;
22785 Cursor cursor = No_Cursor;
22786 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
22787 struct buffer *b;
22789 /* When a menu is active, don't highlight because this looks odd. */
22790 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (MAC_OS)
22791 if (popup_activated ())
22792 return;
22793 #endif
22795 if (NILP (Vmouse_highlight)
22796 || !f->glyphs_initialized_p)
22797 return;
22799 dpyinfo->mouse_face_mouse_x = x;
22800 dpyinfo->mouse_face_mouse_y = y;
22801 dpyinfo->mouse_face_mouse_frame = f;
22803 if (dpyinfo->mouse_face_defer)
22804 return;
22806 if (gc_in_progress)
22808 dpyinfo->mouse_face_deferred_gc = 1;
22809 return;
22812 /* Which window is that in? */
22813 window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
22815 /* If we were displaying active text in another window, clear that.
22816 Also clear if we move out of text area in same window. */
22817 if (! EQ (window, dpyinfo->mouse_face_window)
22818 || (part != ON_TEXT && part != ON_MODE_LINE && part != ON_HEADER_LINE
22819 && !NILP (dpyinfo->mouse_face_window)))
22820 clear_mouse_face (dpyinfo);
22822 /* Not on a window -> return. */
22823 if (!WINDOWP (window))
22824 return;
22826 /* Reset help_echo_string. It will get recomputed below. */
22827 help_echo_string = Qnil;
22829 /* Convert to window-relative pixel coordinates. */
22830 w = XWINDOW (window);
22831 frame_to_window_pixel_xy (w, &x, &y);
22833 /* Handle tool-bar window differently since it doesn't display a
22834 buffer. */
22835 if (EQ (window, f->tool_bar_window))
22837 note_tool_bar_highlight (f, x, y);
22838 return;
22841 /* Mouse is on the mode, header line or margin? */
22842 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
22843 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
22845 note_mode_line_or_margin_highlight (window, x, y, part);
22846 return;
22849 if (part == ON_VERTICAL_BORDER)
22851 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
22852 help_echo_string = build_string ("drag-mouse-1: resize");
22854 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
22855 || part == ON_SCROLL_BAR)
22856 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
22857 else
22858 cursor = FRAME_X_OUTPUT (f)->text_cursor;
22860 /* Are we in a window whose display is up to date?
22861 And verify the buffer's text has not changed. */
22862 b = XBUFFER (w->buffer);
22863 if (part == ON_TEXT
22864 && EQ (w->window_end_valid, w->buffer)
22865 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
22866 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
22868 int hpos, vpos, pos, i, dx, dy, area;
22869 struct glyph *glyph;
22870 Lisp_Object object;
22871 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
22872 Lisp_Object *overlay_vec = NULL;
22873 int noverlays;
22874 struct buffer *obuf;
22875 int obegv, ozv, same_region;
22877 /* Find the glyph under X/Y. */
22878 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
22880 /* Look for :pointer property on image. */
22881 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
22883 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
22884 if (img != NULL && IMAGEP (img->spec))
22886 Lisp_Object image_map, hotspot;
22887 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
22888 !NILP (image_map))
22889 && (hotspot = find_hot_spot (image_map,
22890 glyph->slice.x + dx,
22891 glyph->slice.y + dy),
22892 CONSP (hotspot))
22893 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
22895 Lisp_Object area_id, plist;
22897 area_id = XCAR (hotspot);
22898 /* Could check AREA_ID to see if we enter/leave this hot-spot.
22899 If so, we could look for mouse-enter, mouse-leave
22900 properties in PLIST (and do something...). */
22901 hotspot = XCDR (hotspot);
22902 if (CONSP (hotspot)
22903 && (plist = XCAR (hotspot), CONSP (plist)))
22905 pointer = Fplist_get (plist, Qpointer);
22906 if (NILP (pointer))
22907 pointer = Qhand;
22908 help_echo_string = Fplist_get (plist, Qhelp_echo);
22909 if (!NILP (help_echo_string))
22911 help_echo_window = window;
22912 help_echo_object = glyph->object;
22913 help_echo_pos = glyph->charpos;
22917 if (NILP (pointer))
22918 pointer = Fplist_get (XCDR (img->spec), QCpointer);
22922 /* Clear mouse face if X/Y not over text. */
22923 if (glyph == NULL
22924 || area != TEXT_AREA
22925 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
22927 if (clear_mouse_face (dpyinfo))
22928 cursor = No_Cursor;
22929 if (NILP (pointer))
22931 if (area != TEXT_AREA)
22932 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
22933 else
22934 pointer = Vvoid_text_area_pointer;
22936 goto set_cursor;
22939 pos = glyph->charpos;
22940 object = glyph->object;
22941 if (!STRINGP (object) && !BUFFERP (object))
22942 goto set_cursor;
22944 /* If we get an out-of-range value, return now; avoid an error. */
22945 if (BUFFERP (object) && pos > BUF_Z (b))
22946 goto set_cursor;
22948 /* Make the window's buffer temporarily current for
22949 overlays_at and compute_char_face. */
22950 obuf = current_buffer;
22951 current_buffer = b;
22952 obegv = BEGV;
22953 ozv = ZV;
22954 BEGV = BEG;
22955 ZV = Z;
22957 /* Is this char mouse-active or does it have help-echo? */
22958 position = make_number (pos);
22960 if (BUFFERP (object))
22962 /* Put all the overlays we want in a vector in overlay_vec. */
22963 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
22964 /* Sort overlays into increasing priority order. */
22965 noverlays = sort_overlays (overlay_vec, noverlays, w);
22967 else
22968 noverlays = 0;
22970 same_region = (EQ (window, dpyinfo->mouse_face_window)
22971 && vpos >= dpyinfo->mouse_face_beg_row
22972 && vpos <= dpyinfo->mouse_face_end_row
22973 && (vpos > dpyinfo->mouse_face_beg_row
22974 || hpos >= dpyinfo->mouse_face_beg_col)
22975 && (vpos < dpyinfo->mouse_face_end_row
22976 || hpos < dpyinfo->mouse_face_end_col
22977 || dpyinfo->mouse_face_past_end));
22979 if (same_region)
22980 cursor = No_Cursor;
22982 /* Check mouse-face highlighting. */
22983 if (! same_region
22984 /* If there exists an overlay with mouse-face overlapping
22985 the one we are currently highlighting, we have to
22986 check if we enter the overlapping overlay, and then
22987 highlight only that. */
22988 || (OVERLAYP (dpyinfo->mouse_face_overlay)
22989 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
22991 /* Find the highest priority overlay that has a mouse-face
22992 property. */
22993 overlay = Qnil;
22994 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
22996 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
22997 if (!NILP (mouse_face))
22998 overlay = overlay_vec[i];
23001 /* If we're actually highlighting the same overlay as
23002 before, there's no need to do that again. */
23003 if (!NILP (overlay)
23004 && EQ (overlay, dpyinfo->mouse_face_overlay))
23005 goto check_help_echo;
23007 dpyinfo->mouse_face_overlay = overlay;
23009 /* Clear the display of the old active region, if any. */
23010 if (clear_mouse_face (dpyinfo))
23011 cursor = No_Cursor;
23013 /* If no overlay applies, get a text property. */
23014 if (NILP (overlay))
23015 mouse_face = Fget_text_property (position, Qmouse_face, object);
23017 /* Handle the overlay case. */
23018 if (!NILP (overlay))
23020 /* Find the range of text around this char that
23021 should be active. */
23022 Lisp_Object before, after;
23023 int ignore;
23025 before = Foverlay_start (overlay);
23026 after = Foverlay_end (overlay);
23027 /* Record this as the current active region. */
23028 fast_find_position (w, XFASTINT (before),
23029 &dpyinfo->mouse_face_beg_col,
23030 &dpyinfo->mouse_face_beg_row,
23031 &dpyinfo->mouse_face_beg_x,
23032 &dpyinfo->mouse_face_beg_y, Qnil);
23034 dpyinfo->mouse_face_past_end
23035 = !fast_find_position (w, XFASTINT (after),
23036 &dpyinfo->mouse_face_end_col,
23037 &dpyinfo->mouse_face_end_row,
23038 &dpyinfo->mouse_face_end_x,
23039 &dpyinfo->mouse_face_end_y, Qnil);
23040 dpyinfo->mouse_face_window = window;
23042 dpyinfo->mouse_face_face_id
23043 = face_at_buffer_position (w, pos, 0, 0,
23044 &ignore, pos + 1,
23045 !dpyinfo->mouse_face_hidden);
23047 /* Display it as active. */
23048 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
23049 cursor = No_Cursor;
23051 /* Handle the text property case. */
23052 else if (!NILP (mouse_face) && BUFFERP (object))
23054 /* Find the range of text around this char that
23055 should be active. */
23056 Lisp_Object before, after, beginning, end;
23057 int ignore;
23059 beginning = Fmarker_position (w->start);
23060 end = make_number (BUF_Z (XBUFFER (object))
23061 - XFASTINT (w->window_end_pos));
23062 before
23063 = Fprevious_single_property_change (make_number (pos + 1),
23064 Qmouse_face,
23065 object, beginning);
23066 after
23067 = Fnext_single_property_change (position, Qmouse_face,
23068 object, end);
23070 /* Record this as the current active region. */
23071 fast_find_position (w, XFASTINT (before),
23072 &dpyinfo->mouse_face_beg_col,
23073 &dpyinfo->mouse_face_beg_row,
23074 &dpyinfo->mouse_face_beg_x,
23075 &dpyinfo->mouse_face_beg_y, Qnil);
23076 dpyinfo->mouse_face_past_end
23077 = !fast_find_position (w, XFASTINT (after),
23078 &dpyinfo->mouse_face_end_col,
23079 &dpyinfo->mouse_face_end_row,
23080 &dpyinfo->mouse_face_end_x,
23081 &dpyinfo->mouse_face_end_y, Qnil);
23082 dpyinfo->mouse_face_window = window;
23084 if (BUFFERP (object))
23085 dpyinfo->mouse_face_face_id
23086 = face_at_buffer_position (w, pos, 0, 0,
23087 &ignore, pos + 1,
23088 !dpyinfo->mouse_face_hidden);
23090 /* Display it as active. */
23091 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
23092 cursor = No_Cursor;
23094 else if (!NILP (mouse_face) && STRINGP (object))
23096 Lisp_Object b, e;
23097 int ignore;
23099 b = Fprevious_single_property_change (make_number (pos + 1),
23100 Qmouse_face,
23101 object, Qnil);
23102 e = Fnext_single_property_change (position, Qmouse_face,
23103 object, Qnil);
23104 if (NILP (b))
23105 b = make_number (0);
23106 if (NILP (e))
23107 e = make_number (SCHARS (object) - 1);
23109 fast_find_string_pos (w, XINT (b), object,
23110 &dpyinfo->mouse_face_beg_col,
23111 &dpyinfo->mouse_face_beg_row,
23112 &dpyinfo->mouse_face_beg_x,
23113 &dpyinfo->mouse_face_beg_y, 0);
23114 fast_find_string_pos (w, XINT (e), object,
23115 &dpyinfo->mouse_face_end_col,
23116 &dpyinfo->mouse_face_end_row,
23117 &dpyinfo->mouse_face_end_x,
23118 &dpyinfo->mouse_face_end_y, 1);
23119 dpyinfo->mouse_face_past_end = 0;
23120 dpyinfo->mouse_face_window = window;
23121 dpyinfo->mouse_face_face_id
23122 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
23123 glyph->face_id, 1);
23124 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
23125 cursor = No_Cursor;
23127 else if (STRINGP (object) && NILP (mouse_face))
23129 /* A string which doesn't have mouse-face, but
23130 the text ``under'' it might have. */
23131 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
23132 int start = MATRIX_ROW_START_CHARPOS (r);
23134 pos = string_buffer_position (w, object, start);
23135 if (pos > 0)
23136 mouse_face = get_char_property_and_overlay (make_number (pos),
23137 Qmouse_face,
23138 w->buffer,
23139 &overlay);
23140 if (!NILP (mouse_face) && !NILP (overlay))
23142 Lisp_Object before = Foverlay_start (overlay);
23143 Lisp_Object after = Foverlay_end (overlay);
23144 int ignore;
23146 /* Note that we might not be able to find position
23147 BEFORE in the glyph matrix if the overlay is
23148 entirely covered by a `display' property. In
23149 this case, we overshoot. So let's stop in
23150 the glyph matrix before glyphs for OBJECT. */
23151 fast_find_position (w, XFASTINT (before),
23152 &dpyinfo->mouse_face_beg_col,
23153 &dpyinfo->mouse_face_beg_row,
23154 &dpyinfo->mouse_face_beg_x,
23155 &dpyinfo->mouse_face_beg_y,
23156 object);
23158 dpyinfo->mouse_face_past_end
23159 = !fast_find_position (w, XFASTINT (after),
23160 &dpyinfo->mouse_face_end_col,
23161 &dpyinfo->mouse_face_end_row,
23162 &dpyinfo->mouse_face_end_x,
23163 &dpyinfo->mouse_face_end_y,
23164 Qnil);
23165 dpyinfo->mouse_face_window = window;
23166 dpyinfo->mouse_face_face_id
23167 = face_at_buffer_position (w, pos, 0, 0,
23168 &ignore, pos + 1,
23169 !dpyinfo->mouse_face_hidden);
23171 /* Display it as active. */
23172 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
23173 cursor = No_Cursor;
23178 check_help_echo:
23180 /* Look for a `help-echo' property. */
23181 if (NILP (help_echo_string)) {
23182 Lisp_Object help, overlay;
23184 /* Check overlays first. */
23185 help = overlay = Qnil;
23186 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
23188 overlay = overlay_vec[i];
23189 help = Foverlay_get (overlay, Qhelp_echo);
23192 if (!NILP (help))
23194 help_echo_string = help;
23195 help_echo_window = window;
23196 help_echo_object = overlay;
23197 help_echo_pos = pos;
23199 else
23201 Lisp_Object object = glyph->object;
23202 int charpos = glyph->charpos;
23204 /* Try text properties. */
23205 if (STRINGP (object)
23206 && charpos >= 0
23207 && charpos < SCHARS (object))
23209 help = Fget_text_property (make_number (charpos),
23210 Qhelp_echo, object);
23211 if (NILP (help))
23213 /* If the string itself doesn't specify a help-echo,
23214 see if the buffer text ``under'' it does. */
23215 struct glyph_row *r
23216 = MATRIX_ROW (w->current_matrix, vpos);
23217 int start = MATRIX_ROW_START_CHARPOS (r);
23218 int pos = string_buffer_position (w, object, start);
23219 if (pos > 0)
23221 help = Fget_char_property (make_number (pos),
23222 Qhelp_echo, w->buffer);
23223 if (!NILP (help))
23225 charpos = pos;
23226 object = w->buffer;
23231 else if (BUFFERP (object)
23232 && charpos >= BEGV
23233 && charpos < ZV)
23234 help = Fget_text_property (make_number (charpos), Qhelp_echo,
23235 object);
23237 if (!NILP (help))
23239 help_echo_string = help;
23240 help_echo_window = window;
23241 help_echo_object = object;
23242 help_echo_pos = charpos;
23247 /* Look for a `pointer' property. */
23248 if (NILP (pointer))
23250 /* Check overlays first. */
23251 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
23252 pointer = Foverlay_get (overlay_vec[i], Qpointer);
23254 if (NILP (pointer))
23256 Lisp_Object object = glyph->object;
23257 int charpos = glyph->charpos;
23259 /* Try text properties. */
23260 if (STRINGP (object)
23261 && charpos >= 0
23262 && charpos < SCHARS (object))
23264 pointer = Fget_text_property (make_number (charpos),
23265 Qpointer, object);
23266 if (NILP (pointer))
23268 /* If the string itself doesn't specify a pointer,
23269 see if the buffer text ``under'' it does. */
23270 struct glyph_row *r
23271 = MATRIX_ROW (w->current_matrix, vpos);
23272 int start = MATRIX_ROW_START_CHARPOS (r);
23273 int pos = string_buffer_position (w, object, start);
23274 if (pos > 0)
23275 pointer = Fget_char_property (make_number (pos),
23276 Qpointer, w->buffer);
23279 else if (BUFFERP (object)
23280 && charpos >= BEGV
23281 && charpos < ZV)
23282 pointer = Fget_text_property (make_number (charpos),
23283 Qpointer, object);
23287 BEGV = obegv;
23288 ZV = ozv;
23289 current_buffer = obuf;
23292 set_cursor:
23294 define_frame_cursor1 (f, cursor, pointer);
23298 /* EXPORT for RIF:
23299 Clear any mouse-face on window W. This function is part of the
23300 redisplay interface, and is called from try_window_id and similar
23301 functions to ensure the mouse-highlight is off. */
23303 void
23304 x_clear_window_mouse_face (w)
23305 struct window *w;
23307 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
23308 Lisp_Object window;
23310 BLOCK_INPUT;
23311 XSETWINDOW (window, w);
23312 if (EQ (window, dpyinfo->mouse_face_window))
23313 clear_mouse_face (dpyinfo);
23314 UNBLOCK_INPUT;
23318 /* EXPORT:
23319 Just discard the mouse face information for frame F, if any.
23320 This is used when the size of F is changed. */
23322 void
23323 cancel_mouse_face (f)
23324 struct frame *f;
23326 Lisp_Object window;
23327 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
23329 window = dpyinfo->mouse_face_window;
23330 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
23332 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
23333 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
23334 dpyinfo->mouse_face_window = Qnil;
23339 #endif /* HAVE_WINDOW_SYSTEM */
23342 /***********************************************************************
23343 Exposure Events
23344 ***********************************************************************/
23346 #ifdef HAVE_WINDOW_SYSTEM
23348 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
23349 which intersects rectangle R. R is in window-relative coordinates. */
23351 static void
23352 expose_area (w, row, r, area)
23353 struct window *w;
23354 struct glyph_row *row;
23355 XRectangle *r;
23356 enum glyph_row_area area;
23358 struct glyph *first = row->glyphs[area];
23359 struct glyph *end = row->glyphs[area] + row->used[area];
23360 struct glyph *last;
23361 int first_x, start_x, x;
23363 if (area == TEXT_AREA && row->fill_line_p)
23364 /* If row extends face to end of line write the whole line. */
23365 draw_glyphs (w, 0, row, area,
23366 0, row->used[area],
23367 DRAW_NORMAL_TEXT, 0);
23368 else
23370 /* Set START_X to the window-relative start position for drawing glyphs of
23371 AREA. The first glyph of the text area can be partially visible.
23372 The first glyphs of other areas cannot. */
23373 start_x = window_box_left_offset (w, area);
23374 x = start_x;
23375 if (area == TEXT_AREA)
23376 x += row->x;
23378 /* Find the first glyph that must be redrawn. */
23379 while (first < end
23380 && x + first->pixel_width < r->x)
23382 x += first->pixel_width;
23383 ++first;
23386 /* Find the last one. */
23387 last = first;
23388 first_x = x;
23389 while (last < end
23390 && x < r->x + r->width)
23392 x += last->pixel_width;
23393 ++last;
23396 /* Repaint. */
23397 if (last > first)
23398 draw_glyphs (w, first_x - start_x, row, area,
23399 first - row->glyphs[area], last - row->glyphs[area],
23400 DRAW_NORMAL_TEXT, 0);
23405 /* Redraw the parts of the glyph row ROW on window W intersecting
23406 rectangle R. R is in window-relative coordinates. Value is
23407 non-zero if mouse-face was overwritten. */
23409 static int
23410 expose_line (w, row, r)
23411 struct window *w;
23412 struct glyph_row *row;
23413 XRectangle *r;
23415 xassert (row->enabled_p);
23417 if (row->mode_line_p || w->pseudo_window_p)
23418 draw_glyphs (w, 0, row, TEXT_AREA,
23419 0, row->used[TEXT_AREA],
23420 DRAW_NORMAL_TEXT, 0);
23421 else
23423 if (row->used[LEFT_MARGIN_AREA])
23424 expose_area (w, row, r, LEFT_MARGIN_AREA);
23425 if (row->used[TEXT_AREA])
23426 expose_area (w, row, r, TEXT_AREA);
23427 if (row->used[RIGHT_MARGIN_AREA])
23428 expose_area (w, row, r, RIGHT_MARGIN_AREA);
23429 draw_row_fringe_bitmaps (w, row);
23432 return row->mouse_face_p;
23436 /* Redraw those parts of glyphs rows during expose event handling that
23437 overlap other rows. Redrawing of an exposed line writes over parts
23438 of lines overlapping that exposed line; this function fixes that.
23440 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
23441 row in W's current matrix that is exposed and overlaps other rows.
23442 LAST_OVERLAPPING_ROW is the last such row. */
23444 static void
23445 expose_overlaps (w, first_overlapping_row, last_overlapping_row)
23446 struct window *w;
23447 struct glyph_row *first_overlapping_row;
23448 struct glyph_row *last_overlapping_row;
23450 struct glyph_row *row;
23452 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
23453 if (row->overlapping_p)
23455 xassert (row->enabled_p && !row->mode_line_p);
23457 if (row->used[LEFT_MARGIN_AREA])
23458 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
23460 if (row->used[TEXT_AREA])
23461 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
23463 if (row->used[RIGHT_MARGIN_AREA])
23464 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
23469 /* Return non-zero if W's cursor intersects rectangle R. */
23471 static int
23472 phys_cursor_in_rect_p (w, r)
23473 struct window *w;
23474 XRectangle *r;
23476 XRectangle cr, result;
23477 struct glyph *cursor_glyph;
23479 cursor_glyph = get_phys_cursor_glyph (w);
23480 if (cursor_glyph)
23482 /* r is relative to W's box, but w->phys_cursor.x is relative
23483 to left edge of W's TEXT area. Adjust it. */
23484 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
23485 cr.y = w->phys_cursor.y;
23486 cr.width = cursor_glyph->pixel_width;
23487 cr.height = w->phys_cursor_height;
23488 /* ++KFS: W32 version used W32-specific IntersectRect here, but
23489 I assume the effect is the same -- and this is portable. */
23490 return x_intersect_rectangles (&cr, r, &result);
23492 /* If we don't understand the format, pretend we're not in the hot-spot. */
23493 return 0;
23497 /* EXPORT:
23498 Draw a vertical window border to the right of window W if W doesn't
23499 have vertical scroll bars. */
23501 void
23502 x_draw_vertical_border (w)
23503 struct window *w;
23505 struct frame *f = XFRAME (WINDOW_FRAME (w));
23507 /* We could do better, if we knew what type of scroll-bar the adjacent
23508 windows (on either side) have... But we don't :-(
23509 However, I think this works ok. ++KFS 2003-04-25 */
23511 /* Redraw borders between horizontally adjacent windows. Don't
23512 do it for frames with vertical scroll bars because either the
23513 right scroll bar of a window, or the left scroll bar of its
23514 neighbor will suffice as a border. */
23515 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
23516 return;
23518 if (!WINDOW_RIGHTMOST_P (w)
23519 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
23521 int x0, x1, y0, y1;
23523 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
23524 y1 -= 1;
23526 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
23527 x1 -= 1;
23529 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
23531 else if (!WINDOW_LEFTMOST_P (w)
23532 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
23534 int x0, x1, y0, y1;
23536 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
23537 y1 -= 1;
23539 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
23540 x0 -= 1;
23542 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
23547 /* Redraw the part of window W intersection rectangle FR. Pixel
23548 coordinates in FR are frame-relative. Call this function with
23549 input blocked. Value is non-zero if the exposure overwrites
23550 mouse-face. */
23552 static int
23553 expose_window (w, fr)
23554 struct window *w;
23555 XRectangle *fr;
23557 struct frame *f = XFRAME (w->frame);
23558 XRectangle wr, r;
23559 int mouse_face_overwritten_p = 0;
23561 /* If window is not yet fully initialized, do nothing. This can
23562 happen when toolkit scroll bars are used and a window is split.
23563 Reconfiguring the scroll bar will generate an expose for a newly
23564 created window. */
23565 if (w->current_matrix == NULL)
23566 return 0;
23568 /* When we're currently updating the window, display and current
23569 matrix usually don't agree. Arrange for a thorough display
23570 later. */
23571 if (w == updated_window)
23573 SET_FRAME_GARBAGED (f);
23574 return 0;
23577 /* Frame-relative pixel rectangle of W. */
23578 wr.x = WINDOW_LEFT_EDGE_X (w);
23579 wr.y = WINDOW_TOP_EDGE_Y (w);
23580 wr.width = WINDOW_TOTAL_WIDTH (w);
23581 wr.height = WINDOW_TOTAL_HEIGHT (w);
23583 if (x_intersect_rectangles (fr, &wr, &r))
23585 int yb = window_text_bottom_y (w);
23586 struct glyph_row *row;
23587 int cursor_cleared_p;
23588 struct glyph_row *first_overlapping_row, *last_overlapping_row;
23590 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
23591 r.x, r.y, r.width, r.height));
23593 /* Convert to window coordinates. */
23594 r.x -= WINDOW_LEFT_EDGE_X (w);
23595 r.y -= WINDOW_TOP_EDGE_Y (w);
23597 /* Turn off the cursor. */
23598 if (!w->pseudo_window_p
23599 && phys_cursor_in_rect_p (w, &r))
23601 x_clear_cursor (w);
23602 cursor_cleared_p = 1;
23604 else
23605 cursor_cleared_p = 0;
23607 /* Update lines intersecting rectangle R. */
23608 first_overlapping_row = last_overlapping_row = NULL;
23609 for (row = w->current_matrix->rows;
23610 row->enabled_p;
23611 ++row)
23613 int y0 = row->y;
23614 int y1 = MATRIX_ROW_BOTTOM_Y (row);
23616 if ((y0 >= r.y && y0 < r.y + r.height)
23617 || (y1 > r.y && y1 < r.y + r.height)
23618 || (r.y >= y0 && r.y < y1)
23619 || (r.y + r.height > y0 && r.y + r.height < y1))
23621 /* A header line may be overlapping, but there is no need
23622 to fix overlapping areas for them. KFS 2005-02-12 */
23623 if (row->overlapping_p && !row->mode_line_p)
23625 if (first_overlapping_row == NULL)
23626 first_overlapping_row = row;
23627 last_overlapping_row = row;
23630 if (expose_line (w, row, &r))
23631 mouse_face_overwritten_p = 1;
23634 if (y1 >= yb)
23635 break;
23638 /* Display the mode line if there is one. */
23639 if (WINDOW_WANTS_MODELINE_P (w)
23640 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
23641 row->enabled_p)
23642 && row->y < r.y + r.height)
23644 if (expose_line (w, row, &r))
23645 mouse_face_overwritten_p = 1;
23648 if (!w->pseudo_window_p)
23650 /* Fix the display of overlapping rows. */
23651 if (first_overlapping_row)
23652 expose_overlaps (w, first_overlapping_row, last_overlapping_row);
23654 /* Draw border between windows. */
23655 x_draw_vertical_border (w);
23657 /* Turn the cursor on again. */
23658 if (cursor_cleared_p)
23659 update_window_cursor (w, 1);
23663 return mouse_face_overwritten_p;
23668 /* Redraw (parts) of all windows in the window tree rooted at W that
23669 intersect R. R contains frame pixel coordinates. Value is
23670 non-zero if the exposure overwrites mouse-face. */
23672 static int
23673 expose_window_tree (w, r)
23674 struct window *w;
23675 XRectangle *r;
23677 struct frame *f = XFRAME (w->frame);
23678 int mouse_face_overwritten_p = 0;
23680 while (w && !FRAME_GARBAGED_P (f))
23682 if (!NILP (w->hchild))
23683 mouse_face_overwritten_p
23684 |= expose_window_tree (XWINDOW (w->hchild), r);
23685 else if (!NILP (w->vchild))
23686 mouse_face_overwritten_p
23687 |= expose_window_tree (XWINDOW (w->vchild), r);
23688 else
23689 mouse_face_overwritten_p |= expose_window (w, r);
23691 w = NILP (w->next) ? NULL : XWINDOW (w->next);
23694 return mouse_face_overwritten_p;
23698 /* EXPORT:
23699 Redisplay an exposed area of frame F. X and Y are the upper-left
23700 corner of the exposed rectangle. W and H are width and height of
23701 the exposed area. All are pixel values. W or H zero means redraw
23702 the entire frame. */
23704 void
23705 expose_frame (f, x, y, w, h)
23706 struct frame *f;
23707 int x, y, w, h;
23709 XRectangle r;
23710 int mouse_face_overwritten_p = 0;
23712 TRACE ((stderr, "expose_frame "));
23714 /* No need to redraw if frame will be redrawn soon. */
23715 if (FRAME_GARBAGED_P (f))
23717 TRACE ((stderr, " garbaged\n"));
23718 return;
23721 /* If basic faces haven't been realized yet, there is no point in
23722 trying to redraw anything. This can happen when we get an expose
23723 event while Emacs is starting, e.g. by moving another window. */
23724 if (FRAME_FACE_CACHE (f) == NULL
23725 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
23727 TRACE ((stderr, " no faces\n"));
23728 return;
23731 if (w == 0 || h == 0)
23733 r.x = r.y = 0;
23734 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
23735 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
23737 else
23739 r.x = x;
23740 r.y = y;
23741 r.width = w;
23742 r.height = h;
23745 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
23746 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
23748 if (WINDOWP (f->tool_bar_window))
23749 mouse_face_overwritten_p
23750 |= expose_window (XWINDOW (f->tool_bar_window), &r);
23752 #ifdef HAVE_X_WINDOWS
23753 #ifndef MSDOS
23754 #ifndef USE_X_TOOLKIT
23755 if (WINDOWP (f->menu_bar_window))
23756 mouse_face_overwritten_p
23757 |= expose_window (XWINDOW (f->menu_bar_window), &r);
23758 #endif /* not USE_X_TOOLKIT */
23759 #endif
23760 #endif
23762 /* Some window managers support a focus-follows-mouse style with
23763 delayed raising of frames. Imagine a partially obscured frame,
23764 and moving the mouse into partially obscured mouse-face on that
23765 frame. The visible part of the mouse-face will be highlighted,
23766 then the WM raises the obscured frame. With at least one WM, KDE
23767 2.1, Emacs is not getting any event for the raising of the frame
23768 (even tried with SubstructureRedirectMask), only Expose events.
23769 These expose events will draw text normally, i.e. not
23770 highlighted. Which means we must redo the highlight here.
23771 Subsume it under ``we love X''. --gerd 2001-08-15 */
23772 /* Included in Windows version because Windows most likely does not
23773 do the right thing if any third party tool offers
23774 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
23775 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
23777 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
23778 if (f == dpyinfo->mouse_face_mouse_frame)
23780 int x = dpyinfo->mouse_face_mouse_x;
23781 int y = dpyinfo->mouse_face_mouse_y;
23782 clear_mouse_face (dpyinfo);
23783 note_mouse_highlight (f, x, y);
23789 /* EXPORT:
23790 Determine the intersection of two rectangles R1 and R2. Return
23791 the intersection in *RESULT. Value is non-zero if RESULT is not
23792 empty. */
23795 x_intersect_rectangles (r1, r2, result)
23796 XRectangle *r1, *r2, *result;
23798 XRectangle *left, *right;
23799 XRectangle *upper, *lower;
23800 int intersection_p = 0;
23802 /* Rearrange so that R1 is the left-most rectangle. */
23803 if (r1->x < r2->x)
23804 left = r1, right = r2;
23805 else
23806 left = r2, right = r1;
23808 /* X0 of the intersection is right.x0, if this is inside R1,
23809 otherwise there is no intersection. */
23810 if (right->x <= left->x + left->width)
23812 result->x = right->x;
23814 /* The right end of the intersection is the minimum of the
23815 the right ends of left and right. */
23816 result->width = (min (left->x + left->width, right->x + right->width)
23817 - result->x);
23819 /* Same game for Y. */
23820 if (r1->y < r2->y)
23821 upper = r1, lower = r2;
23822 else
23823 upper = r2, lower = r1;
23825 /* The upper end of the intersection is lower.y0, if this is inside
23826 of upper. Otherwise, there is no intersection. */
23827 if (lower->y <= upper->y + upper->height)
23829 result->y = lower->y;
23831 /* The lower end of the intersection is the minimum of the lower
23832 ends of upper and lower. */
23833 result->height = (min (lower->y + lower->height,
23834 upper->y + upper->height)
23835 - result->y);
23836 intersection_p = 1;
23840 return intersection_p;
23843 #endif /* HAVE_WINDOW_SYSTEM */
23846 /***********************************************************************
23847 Initialization
23848 ***********************************************************************/
23850 void
23851 syms_of_xdisp ()
23853 Vwith_echo_area_save_vector = Qnil;
23854 staticpro (&Vwith_echo_area_save_vector);
23856 Vmessage_stack = Qnil;
23857 staticpro (&Vmessage_stack);
23859 Qinhibit_redisplay = intern ("inhibit-redisplay");
23860 staticpro (&Qinhibit_redisplay);
23862 message_dolog_marker1 = Fmake_marker ();
23863 staticpro (&message_dolog_marker1);
23864 message_dolog_marker2 = Fmake_marker ();
23865 staticpro (&message_dolog_marker2);
23866 message_dolog_marker3 = Fmake_marker ();
23867 staticpro (&message_dolog_marker3);
23869 #if GLYPH_DEBUG
23870 defsubr (&Sdump_frame_glyph_matrix);
23871 defsubr (&Sdump_glyph_matrix);
23872 defsubr (&Sdump_glyph_row);
23873 defsubr (&Sdump_tool_bar_row);
23874 defsubr (&Strace_redisplay);
23875 defsubr (&Strace_to_stderr);
23876 #endif
23877 #ifdef HAVE_WINDOW_SYSTEM
23878 defsubr (&Stool_bar_lines_needed);
23879 defsubr (&Slookup_image_map);
23880 #endif
23881 defsubr (&Sformat_mode_line);
23882 defsubr (&Sinvisible_p);
23884 staticpro (&Qmenu_bar_update_hook);
23885 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
23887 staticpro (&Qoverriding_terminal_local_map);
23888 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
23890 staticpro (&Qoverriding_local_map);
23891 Qoverriding_local_map = intern ("overriding-local-map");
23893 staticpro (&Qwindow_scroll_functions);
23894 Qwindow_scroll_functions = intern ("window-scroll-functions");
23896 staticpro (&Qredisplay_end_trigger_functions);
23897 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
23899 staticpro (&Qinhibit_point_motion_hooks);
23900 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
23902 QCdata = intern (":data");
23903 staticpro (&QCdata);
23904 Qdisplay = intern ("display");
23905 staticpro (&Qdisplay);
23906 Qspace_width = intern ("space-width");
23907 staticpro (&Qspace_width);
23908 Qraise = intern ("raise");
23909 staticpro (&Qraise);
23910 Qslice = intern ("slice");
23911 staticpro (&Qslice);
23912 Qspace = intern ("space");
23913 staticpro (&Qspace);
23914 Qmargin = intern ("margin");
23915 staticpro (&Qmargin);
23916 Qpointer = intern ("pointer");
23917 staticpro (&Qpointer);
23918 Qleft_margin = intern ("left-margin");
23919 staticpro (&Qleft_margin);
23920 Qright_margin = intern ("right-margin");
23921 staticpro (&Qright_margin);
23922 Qcenter = intern ("center");
23923 staticpro (&Qcenter);
23924 Qline_height = intern ("line-height");
23925 staticpro (&Qline_height);
23926 QCalign_to = intern (":align-to");
23927 staticpro (&QCalign_to);
23928 QCrelative_width = intern (":relative-width");
23929 staticpro (&QCrelative_width);
23930 QCrelative_height = intern (":relative-height");
23931 staticpro (&QCrelative_height);
23932 QCeval = intern (":eval");
23933 staticpro (&QCeval);
23934 QCpropertize = intern (":propertize");
23935 staticpro (&QCpropertize);
23936 QCfile = intern (":file");
23937 staticpro (&QCfile);
23938 Qfontified = intern ("fontified");
23939 staticpro (&Qfontified);
23940 Qfontification_functions = intern ("fontification-functions");
23941 staticpro (&Qfontification_functions);
23942 Qtrailing_whitespace = intern ("trailing-whitespace");
23943 staticpro (&Qtrailing_whitespace);
23944 Qescape_glyph = intern ("escape-glyph");
23945 staticpro (&Qescape_glyph);
23946 Qnobreak_space = intern ("nobreak-space");
23947 staticpro (&Qnobreak_space);
23948 Qimage = intern ("image");
23949 staticpro (&Qimage);
23950 QCmap = intern (":map");
23951 staticpro (&QCmap);
23952 QCpointer = intern (":pointer");
23953 staticpro (&QCpointer);
23954 Qrect = intern ("rect");
23955 staticpro (&Qrect);
23956 Qcircle = intern ("circle");
23957 staticpro (&Qcircle);
23958 Qpoly = intern ("poly");
23959 staticpro (&Qpoly);
23960 Qmessage_truncate_lines = intern ("message-truncate-lines");
23961 staticpro (&Qmessage_truncate_lines);
23962 Qgrow_only = intern ("grow-only");
23963 staticpro (&Qgrow_only);
23964 Qinhibit_menubar_update = intern ("inhibit-menubar-update");
23965 staticpro (&Qinhibit_menubar_update);
23966 Qinhibit_eval_during_redisplay = intern ("inhibit-eval-during-redisplay");
23967 staticpro (&Qinhibit_eval_during_redisplay);
23968 Qposition = intern ("position");
23969 staticpro (&Qposition);
23970 Qbuffer_position = intern ("buffer-position");
23971 staticpro (&Qbuffer_position);
23972 Qobject = intern ("object");
23973 staticpro (&Qobject);
23974 Qbar = intern ("bar");
23975 staticpro (&Qbar);
23976 Qhbar = intern ("hbar");
23977 staticpro (&Qhbar);
23978 Qbox = intern ("box");
23979 staticpro (&Qbox);
23980 Qhollow = intern ("hollow");
23981 staticpro (&Qhollow);
23982 Qhand = intern ("hand");
23983 staticpro (&Qhand);
23984 Qarrow = intern ("arrow");
23985 staticpro (&Qarrow);
23986 Qtext = intern ("text");
23987 staticpro (&Qtext);
23988 Qrisky_local_variable = intern ("risky-local-variable");
23989 staticpro (&Qrisky_local_variable);
23990 Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
23991 staticpro (&Qinhibit_free_realized_faces);
23993 list_of_error = Fcons (Fcons (intern ("error"),
23994 Fcons (intern ("void-variable"), Qnil)),
23995 Qnil);
23996 staticpro (&list_of_error);
23998 Qlast_arrow_position = intern ("last-arrow-position");
23999 staticpro (&Qlast_arrow_position);
24000 Qlast_arrow_string = intern ("last-arrow-string");
24001 staticpro (&Qlast_arrow_string);
24003 Qoverlay_arrow_string = intern ("overlay-arrow-string");
24004 staticpro (&Qoverlay_arrow_string);
24005 Qoverlay_arrow_bitmap = intern ("overlay-arrow-bitmap");
24006 staticpro (&Qoverlay_arrow_bitmap);
24008 echo_buffer[0] = echo_buffer[1] = Qnil;
24009 staticpro (&echo_buffer[0]);
24010 staticpro (&echo_buffer[1]);
24012 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
24013 staticpro (&echo_area_buffer[0]);
24014 staticpro (&echo_area_buffer[1]);
24016 Vmessages_buffer_name = build_string ("*Messages*");
24017 staticpro (&Vmessages_buffer_name);
24019 mode_line_proptrans_alist = Qnil;
24020 staticpro (&mode_line_proptrans_alist);
24021 mode_line_string_list = Qnil;
24022 staticpro (&mode_line_string_list);
24023 mode_line_string_face = Qnil;
24024 staticpro (&mode_line_string_face);
24025 mode_line_string_face_prop = Qnil;
24026 staticpro (&mode_line_string_face_prop);
24027 Vmode_line_unwind_vector = Qnil;
24028 staticpro (&Vmode_line_unwind_vector);
24030 help_echo_string = Qnil;
24031 staticpro (&help_echo_string);
24032 help_echo_object = Qnil;
24033 staticpro (&help_echo_object);
24034 help_echo_window = Qnil;
24035 staticpro (&help_echo_window);
24036 previous_help_echo_string = Qnil;
24037 staticpro (&previous_help_echo_string);
24038 help_echo_pos = -1;
24040 #ifdef HAVE_WINDOW_SYSTEM
24041 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
24042 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
24043 For example, if a block cursor is over a tab, it will be drawn as
24044 wide as that tab on the display. */);
24045 x_stretch_cursor_p = 0;
24046 #endif
24048 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
24049 doc: /* *Non-nil means highlight trailing whitespace.
24050 The face used for trailing whitespace is `trailing-whitespace'. */);
24051 Vshow_trailing_whitespace = Qnil;
24053 DEFVAR_LISP ("nobreak-char-display", &Vnobreak_char_display,
24054 doc: /* *Control highlighting of nobreak space and soft hyphen.
24055 A value of t means highlight the character itself (for nobreak space,
24056 use face `nobreak-space').
24057 A value of nil means no highlighting.
24058 Other values mean display the escape glyph followed by an ordinary
24059 space or ordinary hyphen. */);
24060 Vnobreak_char_display = Qt;
24062 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
24063 doc: /* *The pointer shape to show in void text areas.
24064 A value of nil means to show the text pointer. Other options are `arrow',
24065 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
24066 Vvoid_text_area_pointer = Qarrow;
24068 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
24069 doc: /* Non-nil means don't actually do any redisplay.
24070 This is used for internal purposes. */);
24071 Vinhibit_redisplay = Qnil;
24073 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
24074 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
24075 Vglobal_mode_string = Qnil;
24077 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
24078 doc: /* Marker for where to display an arrow on top of the buffer text.
24079 This must be the beginning of a line in order to work.
24080 See also `overlay-arrow-string'. */);
24081 Voverlay_arrow_position = Qnil;
24083 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
24084 doc: /* String to display as an arrow in non-window frames.
24085 See also `overlay-arrow-position'. */);
24086 Voverlay_arrow_string = build_string ("=>");
24088 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list,
24089 doc: /* List of variables (symbols) which hold markers for overlay arrows.
24090 The symbols on this list are examined during redisplay to determine
24091 where to display overlay arrows. */);
24092 Voverlay_arrow_variable_list
24093 = Fcons (intern ("overlay-arrow-position"), Qnil);
24095 DEFVAR_INT ("scroll-step", &scroll_step,
24096 doc: /* *The number of lines to try scrolling a window by when point moves out.
24097 If that fails to bring point back on frame, point is centered instead.
24098 If this is zero, point is always centered after it moves off frame.
24099 If you want scrolling to always be a line at a time, you should set
24100 `scroll-conservatively' to a large value rather than set this to 1. */);
24102 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
24103 doc: /* *Scroll up to this many lines, to bring point back on screen.
24104 A value of zero means to scroll the text to center point vertically
24105 in the window. */);
24106 scroll_conservatively = 0;
24108 DEFVAR_INT ("scroll-margin", &scroll_margin,
24109 doc: /* *Number of lines of margin at the top and bottom of a window.
24110 Recenter the window whenever point gets within this many lines
24111 of the top or bottom of the window. */);
24112 scroll_margin = 0;
24114 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch,
24115 doc: /* Pixels per inch value for non-window system displays.
24116 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
24117 Vdisplay_pixels_per_inch = make_float (72.0);
24119 #if GLYPH_DEBUG
24120 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
24121 #endif
24123 DEFVAR_BOOL ("truncate-partial-width-windows",
24124 &truncate_partial_width_windows,
24125 doc: /* *Non-nil means truncate lines in all windows less than full frame wide. */);
24126 truncate_partial_width_windows = 1;
24128 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
24129 doc: /* When nil, display the mode-line/header-line/menu-bar in the default face.
24130 Any other value means to use the appropriate face, `mode-line',
24131 `header-line', or `menu' respectively. */);
24132 mode_line_inverse_video = 1;
24134 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
24135 doc: /* *Maximum buffer size for which line number should be displayed.
24136 If the buffer is bigger than this, the line number does not appear
24137 in the mode line. A value of nil means no limit. */);
24138 Vline_number_display_limit = Qnil;
24140 DEFVAR_INT ("line-number-display-limit-width",
24141 &line_number_display_limit_width,
24142 doc: /* *Maximum line width (in characters) for line number display.
24143 If the average length of the lines near point is bigger than this, then the
24144 line number may be omitted from the mode line. */);
24145 line_number_display_limit_width = 200;
24147 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
24148 doc: /* *Non-nil means highlight region even in nonselected windows. */);
24149 highlight_nonselected_windows = 0;
24151 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
24152 doc: /* Non-nil if more than one frame is visible on this display.
24153 Minibuffer-only frames don't count, but iconified frames do.
24154 This variable is not guaranteed to be accurate except while processing
24155 `frame-title-format' and `icon-title-format'. */);
24157 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
24158 doc: /* Template for displaying the title bar of visible frames.
24159 \(Assuming the window manager supports this feature.)
24161 This variable has the same structure as `mode-line-format', except that
24162 the %c and %l constructs are ignored. It is used only on frames for
24163 which no explicit name has been set \(see `modify-frame-parameters'). */);
24165 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
24166 doc: /* Template for displaying the title bar of an iconified frame.
24167 \(Assuming the window manager supports this feature.)
24168 This variable has the same structure as `mode-line-format' (which see),
24169 and is used only on frames for which no explicit name has been set
24170 \(see `modify-frame-parameters'). */);
24171 Vicon_title_format
24172 = Vframe_title_format
24173 = Fcons (intern ("multiple-frames"),
24174 Fcons (build_string ("%b"),
24175 Fcons (Fcons (empty_unibyte_string,
24176 Fcons (intern ("invocation-name"),
24177 Fcons (build_string ("@"),
24178 Fcons (intern ("system-name"),
24179 Qnil)))),
24180 Qnil)));
24182 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
24183 doc: /* Maximum number of lines to keep in the message log buffer.
24184 If nil, disable message logging. If t, log messages but don't truncate
24185 the buffer when it becomes large. */);
24186 Vmessage_log_max = make_number (100);
24188 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
24189 doc: /* Functions called before redisplay, if window sizes have changed.
24190 The value should be a list of functions that take one argument.
24191 Just before redisplay, for each frame, if any of its windows have changed
24192 size since the last redisplay, or have been split or deleted,
24193 all the functions in the list are called, with the frame as argument. */);
24194 Vwindow_size_change_functions = Qnil;
24196 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
24197 doc: /* List of functions to call before redisplaying a window with scrolling.
24198 Each function is called with two arguments, the window
24199 and its new display-start position. Note that the value of `window-end'
24200 is not valid when these functions are called. */);
24201 Vwindow_scroll_functions = Qnil;
24203 DEFVAR_LISP ("redisplay-end-trigger-functions", &Vredisplay_end_trigger_functions,
24204 doc: /* Functions called when redisplay of a window reaches the end trigger.
24205 Each function is called with two arguments, the window and the end trigger value.
24206 See `set-window-redisplay-end-trigger'. */);
24207 Vredisplay_end_trigger_functions = Qnil;
24209 DEFVAR_LISP ("mouse-autoselect-window", &Vmouse_autoselect_window,
24210 doc: /* *Non-nil means autoselect window with mouse pointer.
24211 If nil, do not autoselect windows.
24212 A positive number means delay autoselection by that many seconds: a
24213 window is autoselected only after the mouse has remained in that
24214 window for the duration of the delay.
24215 A negative number has a similar effect, but causes windows to be
24216 autoselected only after the mouse has stopped moving. \(Because of
24217 the way Emacs compares mouse events, you will occasionally wait twice
24218 that time before the window gets selected.\)
24219 Any other value means to autoselect window instantaneously when the
24220 mouse pointer enters it.
24222 Autoselection selects the minibuffer only if it is active, and never
24223 unselects the minibuffer if it is active.
24225 When customizing this variable make sure that the actual value of
24226 `focus-follows-mouse' matches the behavior of your window manager. */);
24227 Vmouse_autoselect_window = Qnil;
24229 DEFVAR_LISP ("auto-resize-tool-bars", &Vauto_resize_tool_bars,
24230 doc: /* *Non-nil means automatically resize tool-bars.
24231 This dynamically changes the tool-bar's height to the minimum height
24232 that is needed to make all tool-bar items visible.
24233 If value is `grow-only', the tool-bar's height is only increased
24234 automatically; to decrease the tool-bar height, use \\[recenter]. */);
24235 Vauto_resize_tool_bars = Qt;
24237 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
24238 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
24239 auto_raise_tool_bar_buttons_p = 1;
24241 DEFVAR_BOOL ("make-cursor-line-fully-visible", &make_cursor_line_fully_visible_p,
24242 doc: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
24243 make_cursor_line_fully_visible_p = 1;
24245 DEFVAR_LISP ("tool-bar-border", &Vtool_bar_border,
24246 doc: /* *Border below tool-bar in pixels.
24247 If an integer, use it as the height of the border.
24248 If it is one of `internal-border-width' or `border-width', use the
24249 value of the corresponding frame parameter.
24250 Otherwise, no border is added below the tool-bar. */);
24251 Vtool_bar_border = Qinternal_border_width;
24253 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
24254 doc: /* *Margin around tool-bar buttons in pixels.
24255 If an integer, use that for both horizontal and vertical margins.
24256 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
24257 HORZ specifying the horizontal margin, and VERT specifying the
24258 vertical margin. */);
24259 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
24261 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
24262 doc: /* *Relief thickness of tool-bar buttons. */);
24263 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
24265 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
24266 doc: /* List of functions to call to fontify regions of text.
24267 Each function is called with one argument POS. Functions must
24268 fontify a region starting at POS in the current buffer, and give
24269 fontified regions the property `fontified'. */);
24270 Vfontification_functions = Qnil;
24271 Fmake_variable_buffer_local (Qfontification_functions);
24273 DEFVAR_BOOL ("unibyte-display-via-language-environment",
24274 &unibyte_display_via_language_environment,
24275 doc: /* *Non-nil means display unibyte text according to language environment.
24276 Specifically this means that unibyte non-ASCII characters
24277 are displayed by converting them to the equivalent multibyte characters
24278 according to the current language environment. As a result, they are
24279 displayed according to the current fontset. */);
24280 unibyte_display_via_language_environment = 0;
24282 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
24283 doc: /* *Maximum height for resizing mini-windows.
24284 If a float, it specifies a fraction of the mini-window frame's height.
24285 If an integer, it specifies a number of lines. */);
24286 Vmax_mini_window_height = make_float (0.25);
24288 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
24289 doc: /* *How to resize mini-windows.
24290 A value of nil means don't automatically resize mini-windows.
24291 A value of t means resize them to fit the text displayed in them.
24292 A value of `grow-only', the default, means let mini-windows grow
24293 only, until their display becomes empty, at which point the windows
24294 go back to their normal size. */);
24295 Vresize_mini_windows = Qgrow_only;
24297 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
24298 doc: /* Alist specifying how to blink the cursor off.
24299 Each element has the form (ON-STATE . OFF-STATE). Whenever the
24300 `cursor-type' frame-parameter or variable equals ON-STATE,
24301 comparing using `equal', Emacs uses OFF-STATE to specify
24302 how to blink it off. ON-STATE and OFF-STATE are values for
24303 the `cursor-type' frame parameter.
24305 If a frame's ON-STATE has no entry in this list,
24306 the frame's other specifications determine how to blink the cursor off. */);
24307 Vblink_cursor_alist = Qnil;
24309 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
24310 doc: /* *Non-nil means scroll the display automatically to make point visible. */);
24311 automatic_hscrolling_p = 1;
24313 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
24314 doc: /* *How many columns away from the window edge point is allowed to get
24315 before automatic hscrolling will horizontally scroll the window. */);
24316 hscroll_margin = 5;
24318 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
24319 doc: /* *How many columns to scroll the window when point gets too close to the edge.
24320 When point is less than `hscroll-margin' columns from the window
24321 edge, automatic hscrolling will scroll the window by the amount of columns
24322 determined by this variable. If its value is a positive integer, scroll that
24323 many columns. If it's a positive floating-point number, it specifies the
24324 fraction of the window's width to scroll. If it's nil or zero, point will be
24325 centered horizontally after the scroll. Any other value, including negative
24326 numbers, are treated as if the value were zero.
24328 Automatic hscrolling always moves point outside the scroll margin, so if
24329 point was more than scroll step columns inside the margin, the window will
24330 scroll more than the value given by the scroll step.
24332 Note that the lower bound for automatic hscrolling specified by `scroll-left'
24333 and `scroll-right' overrides this variable's effect. */);
24334 Vhscroll_step = make_number (0);
24336 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
24337 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
24338 Bind this around calls to `message' to let it take effect. */);
24339 message_truncate_lines = 0;
24341 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
24342 doc: /* Normal hook run to update the menu bar definitions.
24343 Redisplay runs this hook before it redisplays the menu bar.
24344 This is used to update submenus such as Buffers,
24345 whose contents depend on various data. */);
24346 Vmenu_bar_update_hook = Qnil;
24348 DEFVAR_LISP ("menu-updating-frame", &Vmenu_updating_frame,
24349 doc: /* Frame for which we are updating a menu.
24350 The enable predicate for a menu binding should check this variable. */);
24351 Vmenu_updating_frame = Qnil;
24353 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
24354 doc: /* Non-nil means don't update menu bars. Internal use only. */);
24355 inhibit_menubar_update = 0;
24357 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
24358 doc: /* Non-nil means don't eval Lisp during redisplay. */);
24359 inhibit_eval_during_redisplay = 0;
24361 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
24362 doc: /* Non-nil means don't free realized faces. Internal use only. */);
24363 inhibit_free_realized_faces = 0;
24365 #if GLYPH_DEBUG
24366 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
24367 doc: /* Inhibit try_window_id display optimization. */);
24368 inhibit_try_window_id = 0;
24370 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
24371 doc: /* Inhibit try_window_reusing display optimization. */);
24372 inhibit_try_window_reusing = 0;
24374 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
24375 doc: /* Inhibit try_cursor_movement display optimization. */);
24376 inhibit_try_cursor_movement = 0;
24377 #endif /* GLYPH_DEBUG */
24379 DEFVAR_INT ("overline-margin", &overline_margin,
24380 doc: /* *Space between overline and text, in pixels.
24381 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
24382 margin to the caracter height. */);
24383 overline_margin = 2;
24387 /* Initialize this module when Emacs starts. */
24389 void
24390 init_xdisp ()
24392 Lisp_Object root_window;
24393 struct window *mini_w;
24395 current_header_line_height = current_mode_line_height = -1;
24397 CHARPOS (this_line_start_pos) = 0;
24399 mini_w = XWINDOW (minibuf_window);
24400 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
24402 if (!noninteractive)
24404 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
24405 int i;
24407 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
24408 set_window_height (root_window,
24409 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
24411 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
24412 set_window_height (minibuf_window, 1, 0);
24414 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
24415 mini_w->total_cols = make_number (FRAME_COLS (f));
24417 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
24418 scratch_glyph_row.glyphs[TEXT_AREA + 1]
24419 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
24421 /* The default ellipsis glyphs `...'. */
24422 for (i = 0; i < 3; ++i)
24423 default_invis_vector[i] = make_number ('.');
24427 /* Allocate the buffer for frame titles.
24428 Also used for `format-mode-line'. */
24429 int size = 100;
24430 mode_line_noprop_buf = (char *) xmalloc (size);
24431 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
24432 mode_line_noprop_ptr = mode_line_noprop_buf;
24433 mode_line_target = MODE_LINE_DISPLAY;
24436 help_echo_showing_p = 0;
24440 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
24441 (do not change this comment) */