(Button Types): For define-button-type, clarify type of NAME.
[emacs.git] / src / xdisp.c
blobd8619cdfa9ec8eff0144ddc9d814440a03383368
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, 2008 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 Qwindow_text_change_functions, Vwindow_text_change_functions;
236 Lisp_Object Qredisplay_end_trigger_functions, Vredisplay_end_trigger_functions;
237 Lisp_Object Qinhibit_point_motion_hooks;
238 Lisp_Object QCeval, QCfile, QCdata, QCpropertize;
239 Lisp_Object Qfontified;
240 Lisp_Object Qgrow_only;
241 Lisp_Object Qinhibit_eval_during_redisplay;
242 Lisp_Object Qbuffer_position, Qposition, Qobject;
244 /* Cursor shapes */
245 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
247 /* Pointer shapes */
248 Lisp_Object Qarrow, Qhand, Qtext;
250 Lisp_Object Qrisky_local_variable;
252 /* Holds the list (error). */
253 Lisp_Object list_of_error;
255 /* Functions called to fontify regions of text. */
257 Lisp_Object Vfontification_functions;
258 Lisp_Object Qfontification_functions;
260 /* Non-nil means automatically select any window when the mouse
261 cursor moves into it. */
262 Lisp_Object Vmouse_autoselect_window;
264 /* Non-zero means draw tool bar buttons raised when the mouse moves
265 over them. */
267 int auto_raise_tool_bar_buttons_p;
269 /* Non-zero means to reposition window if cursor line is only partially visible. */
271 int make_cursor_line_fully_visible_p;
273 /* Margin below tool bar in pixels. 0 or nil means no margin.
274 If value is `internal-border-width' or `border-width',
275 the corresponding frame parameter is used. */
277 Lisp_Object Vtool_bar_border;
279 /* Margin around tool bar buttons in pixels. */
281 Lisp_Object Vtool_bar_button_margin;
283 /* Thickness of shadow to draw around tool bar buttons. */
285 EMACS_INT tool_bar_button_relief;
287 /* Non-nil means automatically resize tool-bars so that all tool-bar
288 items are visible, and no blank lines remain.
290 If value is `grow-only', only make tool-bar bigger. */
292 Lisp_Object Vauto_resize_tool_bars;
294 /* Non-zero means draw block and hollow cursor as wide as the glyph
295 under it. For example, if a block cursor is over a tab, it will be
296 drawn as wide as that tab on the display. */
298 int x_stretch_cursor_p;
300 /* Non-nil means don't actually do any redisplay. */
302 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
304 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
306 int inhibit_eval_during_redisplay;
308 /* Names of text properties relevant for redisplay. */
310 Lisp_Object Qdisplay;
311 extern Lisp_Object Qface, Qinvisible, Qwidth;
313 /* Symbols used in text property values. */
315 Lisp_Object Vdisplay_pixels_per_inch;
316 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
317 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
318 Lisp_Object Qslice;
319 Lisp_Object Qcenter;
320 Lisp_Object Qmargin, Qpointer;
321 Lisp_Object Qline_height;
322 extern Lisp_Object Qheight;
323 extern Lisp_Object QCwidth, QCheight, QCascent;
324 extern Lisp_Object Qscroll_bar;
325 extern Lisp_Object Qcursor;
327 /* Non-nil means highlight trailing whitespace. */
329 Lisp_Object Vshow_trailing_whitespace;
331 /* Non-nil means escape non-break space and hyphens. */
333 Lisp_Object Vnobreak_char_display;
335 #ifdef HAVE_WINDOW_SYSTEM
336 extern Lisp_Object Voverflow_newline_into_fringe;
338 /* Test if overflow newline into fringe. Called with iterator IT
339 at or past right window margin, and with IT->current_x set. */
341 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) \
342 (!NILP (Voverflow_newline_into_fringe) \
343 && FRAME_WINDOW_P (it->f) \
344 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
345 && it->current_x == it->last_visible_x)
347 #endif /* HAVE_WINDOW_SYSTEM */
349 /* Non-nil means show the text cursor in void text areas
350 i.e. in blank areas after eol and eob. This used to be
351 the default in 21.3. */
353 Lisp_Object Vvoid_text_area_pointer;
355 /* Name of the face used to highlight trailing whitespace. */
357 Lisp_Object Qtrailing_whitespace;
359 /* Name and number of the face used to highlight escape glyphs. */
361 Lisp_Object Qescape_glyph;
363 /* Name and number of the face used to highlight non-breaking spaces. */
365 Lisp_Object Qnobreak_space;
367 /* The symbol `image' which is the car of the lists used to represent
368 images in Lisp. */
370 Lisp_Object Qimage;
372 /* The image map types. */
373 Lisp_Object QCmap, QCpointer;
374 Lisp_Object Qrect, Qcircle, Qpoly;
376 /* Non-zero means print newline to stdout before next mini-buffer
377 message. */
379 int noninteractive_need_newline;
381 /* Non-zero means print newline to message log before next message. */
383 static int message_log_need_newline;
385 /* Three markers that message_dolog uses.
386 It could allocate them itself, but that causes trouble
387 in handling memory-full errors. */
388 static Lisp_Object message_dolog_marker1;
389 static Lisp_Object message_dolog_marker2;
390 static Lisp_Object message_dolog_marker3;
392 /* The buffer position of the first character appearing entirely or
393 partially on the line of the selected window which contains the
394 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
395 redisplay optimization in redisplay_internal. */
397 static struct text_pos this_line_start_pos;
399 /* Number of characters past the end of the line above, including the
400 terminating newline. */
402 static struct text_pos this_line_end_pos;
404 /* The vertical positions and the height of this line. */
406 static int this_line_vpos;
407 static int this_line_y;
408 static int this_line_pixel_height;
410 /* X position at which this display line starts. Usually zero;
411 negative if first character is partially visible. */
413 static int this_line_start_x;
415 /* Buffer that this_line_.* variables are referring to. */
417 static struct buffer *this_line_buffer;
419 /* Nonzero means truncate lines in all windows less wide than the
420 frame. */
422 int truncate_partial_width_windows;
424 /* A flag to control how to display unibyte 8-bit character. */
426 int unibyte_display_via_language_environment;
428 /* Nonzero means we have more than one non-mini-buffer-only frame.
429 Not guaranteed to be accurate except while parsing
430 frame-title-format. */
432 int multiple_frames;
434 Lisp_Object Vglobal_mode_string;
437 /* List of variables (symbols) which hold markers for overlay arrows.
438 The symbols on this list are examined during redisplay to determine
439 where to display overlay arrows. */
441 Lisp_Object Voverlay_arrow_variable_list;
443 /* Marker for where to display an arrow on top of the buffer text. */
445 Lisp_Object Voverlay_arrow_position;
447 /* String to display for the arrow. Only used on terminal frames. */
449 Lisp_Object Voverlay_arrow_string;
451 /* Values of those variables at last redisplay are stored as
452 properties on `overlay-arrow-position' symbol. However, if
453 Voverlay_arrow_position is a marker, last-arrow-position is its
454 numerical position. */
456 Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
458 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
459 properties on a symbol in overlay-arrow-variable-list. */
461 Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
463 /* Like mode-line-format, but for the title bar on a visible frame. */
465 Lisp_Object Vframe_title_format;
467 /* Like mode-line-format, but for the title bar on an iconified frame. */
469 Lisp_Object Vicon_title_format;
471 /* List of functions to call when a window's size changes. These
472 functions get one arg, a frame on which one or more windows' sizes
473 have changed. */
475 static Lisp_Object Vwindow_size_change_functions;
477 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
479 /* Nonzero if an overlay arrow has been displayed in this window. */
481 static int overlay_arrow_seen;
483 /* Nonzero means highlight the region even in nonselected windows. */
485 int highlight_nonselected_windows;
487 /* If cursor motion alone moves point off frame, try scrolling this
488 many lines up or down if that will bring it back. */
490 static EMACS_INT scroll_step;
492 /* Nonzero means scroll just far enough to bring point back on the
493 screen, when appropriate. */
495 static EMACS_INT scroll_conservatively;
497 /* Recenter the window whenever point gets within this many lines of
498 the top or bottom of the window. This value is translated into a
499 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
500 that there is really a fixed pixel height scroll margin. */
502 EMACS_INT scroll_margin;
504 /* Number of windows showing the buffer of the selected window (or
505 another buffer with the same base buffer). keyboard.c refers to
506 this. */
508 int buffer_shared;
510 /* Vector containing glyphs for an ellipsis `...'. */
512 static Lisp_Object default_invis_vector[3];
514 /* Zero means display the mode-line/header-line/menu-bar in the default face
515 (this slightly odd definition is for compatibility with previous versions
516 of emacs), non-zero means display them using their respective faces.
518 This variable is deprecated. */
520 int mode_line_inverse_video;
522 /* Prompt to display in front of the mini-buffer contents. */
524 Lisp_Object minibuf_prompt;
526 /* Width of current mini-buffer prompt. Only set after display_line
527 of the line that contains the prompt. */
529 int minibuf_prompt_width;
531 /* This is the window where the echo area message was displayed. It
532 is always a mini-buffer window, but it may not be the same window
533 currently active as a mini-buffer. */
535 Lisp_Object echo_area_window;
537 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
538 pushes the current message and the value of
539 message_enable_multibyte on the stack, the function restore_message
540 pops the stack and displays MESSAGE again. */
542 Lisp_Object Vmessage_stack;
544 /* Nonzero means multibyte characters were enabled when the echo area
545 message was specified. */
547 int message_enable_multibyte;
549 /* Nonzero if we should redraw the mode lines on the next redisplay. */
551 int update_mode_lines;
553 /* Nonzero if window sizes or contents have changed since last
554 redisplay that finished. */
556 int windows_or_buffers_changed;
558 /* Nonzero means a frame's cursor type has been changed. */
560 int cursor_type_changed;
562 /* Nonzero after display_mode_line if %l was used and it displayed a
563 line number. */
565 int line_number_displayed;
567 /* Maximum buffer size for which to display line numbers. */
569 Lisp_Object Vline_number_display_limit;
571 /* Line width to consider when repositioning for line number display. */
573 static EMACS_INT line_number_display_limit_width;
575 /* Number of lines to keep in the message log buffer. t means
576 infinite. nil means don't log at all. */
578 Lisp_Object Vmessage_log_max;
580 /* The name of the *Messages* buffer, a string. */
582 static Lisp_Object Vmessages_buffer_name;
584 /* Current, index 0, and last displayed echo area message. Either
585 buffers from echo_buffers, or nil to indicate no message. */
587 Lisp_Object echo_area_buffer[2];
589 /* The buffers referenced from echo_area_buffer. */
591 static Lisp_Object echo_buffer[2];
593 /* A vector saved used in with_area_buffer to reduce consing. */
595 static Lisp_Object Vwith_echo_area_save_vector;
597 /* Non-zero means display_echo_area should display the last echo area
598 message again. Set by redisplay_preserve_echo_area. */
600 static int display_last_displayed_message_p;
602 /* Nonzero if echo area is being used by print; zero if being used by
603 message. */
605 int message_buf_print;
607 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
609 Lisp_Object Qinhibit_menubar_update;
610 int inhibit_menubar_update;
612 /* When evaluating expressions from menu bar items (enable conditions,
613 for instance), this is the frame they are being processed for. */
615 Lisp_Object Vmenu_updating_frame;
617 /* Maximum height for resizing mini-windows. Either a float
618 specifying a fraction of the available height, or an integer
619 specifying a number of lines. */
621 Lisp_Object Vmax_mini_window_height;
623 /* Non-zero means messages should be displayed with truncated
624 lines instead of being continued. */
626 int message_truncate_lines;
627 Lisp_Object Qmessage_truncate_lines;
629 /* Set to 1 in clear_message to make redisplay_internal aware
630 of an emptied echo area. */
632 static int message_cleared_p;
634 /* How to blink the default frame cursor off. */
635 Lisp_Object Vblink_cursor_alist;
637 /* A scratch glyph row with contents used for generating truncation
638 glyphs. Also used in direct_output_for_insert. */
640 #define MAX_SCRATCH_GLYPHS 100
641 struct glyph_row scratch_glyph_row;
642 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
644 /* Ascent and height of the last line processed by move_it_to. */
646 static int last_max_ascent, last_height;
648 /* Non-zero if there's a help-echo in the echo area. */
650 int help_echo_showing_p;
652 /* If >= 0, computed, exact values of mode-line and header-line height
653 to use in the macros CURRENT_MODE_LINE_HEIGHT and
654 CURRENT_HEADER_LINE_HEIGHT. */
656 int current_mode_line_height, current_header_line_height;
658 /* The maximum distance to look ahead for text properties. Values
659 that are too small let us call compute_char_face and similar
660 functions too often which is expensive. Values that are too large
661 let us call compute_char_face and alike too often because we
662 might not be interested in text properties that far away. */
664 #define TEXT_PROP_DISTANCE_LIMIT 100
666 #if GLYPH_DEBUG
668 /* Variables to turn off display optimizations from Lisp. */
670 int inhibit_try_window_id, inhibit_try_window_reusing;
671 int inhibit_try_cursor_movement;
673 /* Non-zero means print traces of redisplay if compiled with
674 GLYPH_DEBUG != 0. */
676 int trace_redisplay_p;
678 #endif /* GLYPH_DEBUG */
680 #ifdef DEBUG_TRACE_MOVE
681 /* Non-zero means trace with TRACE_MOVE to stderr. */
682 int trace_move;
684 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
685 #else
686 #define TRACE_MOVE(x) (void) 0
687 #endif
689 /* Non-zero means automatically scroll windows horizontally to make
690 point visible. */
692 int automatic_hscrolling_p;
693 Lisp_Object Qauto_hscroll_mode;
695 /* How close to the margin can point get before the window is scrolled
696 horizontally. */
697 EMACS_INT hscroll_margin;
699 /* How much to scroll horizontally when point is inside the above margin. */
700 Lisp_Object Vhscroll_step;
702 /* The variable `resize-mini-windows'. If nil, don't resize
703 mini-windows. If t, always resize them to fit the text they
704 display. If `grow-only', let mini-windows grow only until they
705 become empty. */
707 Lisp_Object Vresize_mini_windows;
709 /* Buffer being redisplayed -- for redisplay_window_error. */
711 struct buffer *displayed_buffer;
713 /* Space between overline and text. */
715 EMACS_INT overline_margin;
717 /* Value returned from text property handlers (see below). */
719 enum prop_handled
721 HANDLED_NORMALLY,
722 HANDLED_RECOMPUTE_PROPS,
723 HANDLED_OVERLAY_STRING_CONSUMED,
724 HANDLED_RETURN
727 /* A description of text properties that redisplay is interested
728 in. */
730 struct props
732 /* The name of the property. */
733 Lisp_Object *name;
735 /* A unique index for the property. */
736 enum prop_idx idx;
738 /* A handler function called to set up iterator IT from the property
739 at IT's current position. Value is used to steer handle_stop. */
740 enum prop_handled (*handler) P_ ((struct it *it));
743 static enum prop_handled handle_face_prop P_ ((struct it *));
744 static enum prop_handled handle_invisible_prop P_ ((struct it *));
745 static enum prop_handled handle_display_prop P_ ((struct it *));
746 static enum prop_handled handle_composition_prop P_ ((struct it *));
747 static enum prop_handled handle_overlay_change P_ ((struct it *));
748 static enum prop_handled handle_fontified_prop P_ ((struct it *));
750 /* Properties handled by iterators. */
752 static struct props it_props[] =
754 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
755 /* Handle `face' before `display' because some sub-properties of
756 `display' need to know the face. */
757 {&Qface, FACE_PROP_IDX, handle_face_prop},
758 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
759 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
760 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
761 {NULL, 0, NULL}
764 /* Value is the position described by X. If X is a marker, value is
765 the marker_position of X. Otherwise, value is X. */
767 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
769 /* Enumeration returned by some move_it_.* functions internally. */
771 enum move_it_result
773 /* Not used. Undefined value. */
774 MOVE_UNDEFINED,
776 /* Move ended at the requested buffer position or ZV. */
777 MOVE_POS_MATCH_OR_ZV,
779 /* Move ended at the requested X pixel position. */
780 MOVE_X_REACHED,
782 /* Move within a line ended at the end of a line that must be
783 continued. */
784 MOVE_LINE_CONTINUED,
786 /* Move within a line ended at the end of a line that would
787 be displayed truncated. */
788 MOVE_LINE_TRUNCATED,
790 /* Move within a line ended at a line end. */
791 MOVE_NEWLINE_OR_CR
794 /* This counter is used to clear the face cache every once in a while
795 in redisplay_internal. It is incremented for each redisplay.
796 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
797 cleared. */
799 #define CLEAR_FACE_CACHE_COUNT 500
800 static int clear_face_cache_count;
802 /* Similarly for the image cache. */
804 #ifdef HAVE_WINDOW_SYSTEM
805 #define CLEAR_IMAGE_CACHE_COUNT 101
806 static int clear_image_cache_count;
807 #endif
809 /* Non-zero while redisplay_internal is in progress. */
811 int redisplaying_p;
813 /* Non-zero means don't free realized faces. Bound while freeing
814 realized faces is dangerous because glyph matrices might still
815 reference them. */
817 int inhibit_free_realized_faces;
818 Lisp_Object Qinhibit_free_realized_faces;
820 /* If a string, XTread_socket generates an event to display that string.
821 (The display is done in read_char.) */
823 Lisp_Object help_echo_string;
824 Lisp_Object help_echo_window;
825 Lisp_Object help_echo_object;
826 int help_echo_pos;
828 /* Temporary variable for XTread_socket. */
830 Lisp_Object previous_help_echo_string;
832 /* Null glyph slice */
834 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
837 /* Function prototypes. */
839 static void setup_for_ellipsis P_ ((struct it *, int));
840 static void mark_window_display_accurate_1 P_ ((struct window *, int));
841 static int single_display_spec_string_p P_ ((Lisp_Object, Lisp_Object));
842 static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
843 static int cursor_row_p P_ ((struct window *, struct glyph_row *));
844 static int redisplay_mode_lines P_ ((Lisp_Object, int));
845 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
847 #if 0
848 static int invisible_text_between_p P_ ((struct it *, int, int));
849 #endif
851 static void pint2str P_ ((char *, int, int));
852 static void pint2hrstr P_ ((char *, int, int));
853 static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
854 struct text_pos));
855 static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
856 static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
857 static void store_mode_line_noprop_char P_ ((char));
858 static int store_mode_line_noprop P_ ((const unsigned char *, int, int));
859 static void x_consider_frame_title P_ ((Lisp_Object));
860 static void handle_stop P_ ((struct it *));
861 static int tool_bar_lines_needed P_ ((struct frame *, int *));
862 static int single_display_spec_intangible_p P_ ((Lisp_Object));
863 static void ensure_echo_area_buffers P_ ((void));
864 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
865 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
866 static int with_echo_area_buffer P_ ((struct window *, int,
867 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
868 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
869 static void clear_garbaged_frames P_ ((void));
870 static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
871 static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
872 static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
873 static int display_echo_area P_ ((struct window *));
874 static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
875 static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
876 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
877 static int string_char_and_length P_ ((const unsigned char *, int, int *));
878 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
879 struct text_pos));
880 static int compute_window_start_on_continuation_line P_ ((struct window *));
881 static Lisp_Object safe_eval_handler P_ ((Lisp_Object));
882 static void insert_left_trunc_glyphs P_ ((struct it *));
883 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *,
884 Lisp_Object));
885 static void extend_face_to_end_of_line P_ ((struct it *));
886 static int append_space_for_newline P_ ((struct it *, int));
887 static int cursor_row_fully_visible_p P_ ((struct window *, int, int));
888 static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
889 static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
890 static int trailing_whitespace_p P_ ((int));
891 static int message_log_check_duplicate P_ ((int, int, int, int));
892 static void push_it P_ ((struct it *));
893 static void pop_it P_ ((struct it *));
894 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
895 static void select_frame_for_redisplay P_ ((Lisp_Object));
896 static void redisplay_internal P_ ((int));
897 static int echo_area_display P_ ((int));
898 static void redisplay_windows P_ ((Lisp_Object));
899 static void redisplay_window P_ ((Lisp_Object, int));
900 static Lisp_Object redisplay_window_error ();
901 static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
902 static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
903 static int update_menu_bar P_ ((struct frame *, int, int));
904 static int try_window_reusing_current_matrix P_ ((struct window *));
905 static int try_window_id P_ ((struct window *));
906 static int display_line P_ ((struct it *));
907 static int display_mode_lines P_ ((struct window *));
908 static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
909 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
910 static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
911 static char *decode_mode_spec P_ ((struct window *, int, int, int, int *));
912 static void display_menu_bar P_ ((struct window *));
913 static int display_count_lines P_ ((int, int, int, int, int *));
914 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
915 int, int, struct it *, int, int, int, int));
916 static void compute_line_metrics P_ ((struct it *));
917 static void run_redisplay_end_trigger_hook P_ ((struct it *));
918 static int get_overlay_strings P_ ((struct it *, int));
919 static int get_overlay_strings_1 P_ ((struct it *, int, int));
920 static void next_overlay_string P_ ((struct it *));
921 static void reseat P_ ((struct it *, struct text_pos, int));
922 static void reseat_1 P_ ((struct it *, struct text_pos, int));
923 static void back_to_previous_visible_line_start P_ ((struct it *));
924 void reseat_at_previous_visible_line_start P_ ((struct it *));
925 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
926 static int next_element_from_ellipsis P_ ((struct it *));
927 static int next_element_from_display_vector P_ ((struct it *));
928 static int next_element_from_string P_ ((struct it *));
929 static int next_element_from_c_string P_ ((struct it *));
930 static int next_element_from_buffer P_ ((struct it *));
931 static int next_element_from_composition P_ ((struct it *));
932 static int next_element_from_image P_ ((struct it *));
933 static int next_element_from_stretch P_ ((struct it *));
934 static void load_overlay_strings P_ ((struct it *, int));
935 static int init_from_display_pos P_ ((struct it *, struct window *,
936 struct display_pos *));
937 static void reseat_to_string P_ ((struct it *, unsigned char *,
938 Lisp_Object, int, int, int, int));
939 static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
940 int, int, int));
941 void move_it_vertically_backward P_ ((struct it *, int));
942 static void init_to_row_start P_ ((struct it *, struct window *,
943 struct glyph_row *));
944 static int init_to_row_end P_ ((struct it *, struct window *,
945 struct glyph_row *));
946 static void back_to_previous_line_start P_ ((struct it *));
947 static int forward_to_next_line_start P_ ((struct it *, int *));
948 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
949 Lisp_Object, int));
950 static struct text_pos string_pos P_ ((int, Lisp_Object));
951 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
952 static int number_of_chars P_ ((unsigned char *, int));
953 static void compute_stop_pos P_ ((struct it *));
954 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
955 Lisp_Object));
956 static int face_before_or_after_it_pos P_ ((struct it *, int));
957 static int next_overlay_change P_ ((int));
958 static int handle_single_display_spec P_ ((struct it *, Lisp_Object,
959 Lisp_Object, Lisp_Object,
960 struct text_pos *, int));
961 static int underlying_face_id P_ ((struct it *));
962 static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
963 struct window *));
965 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
966 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
968 #ifdef HAVE_WINDOW_SYSTEM
970 static void update_tool_bar P_ ((struct frame *, int));
971 static void build_desired_tool_bar_string P_ ((struct frame *f));
972 static int redisplay_tool_bar P_ ((struct frame *));
973 static void display_tool_bar_line P_ ((struct it *, int));
974 static void notice_overwritten_cursor P_ ((struct window *,
975 enum glyph_row_area,
976 int, int, int, int));
980 #endif /* HAVE_WINDOW_SYSTEM */
983 /***********************************************************************
984 Window display dimensions
985 ***********************************************************************/
987 /* Return the bottom boundary y-position for text lines in window W.
988 This is the first y position at which a line cannot start.
989 It is relative to the top of the window.
991 This is the height of W minus the height of a mode line, if any. */
993 INLINE int
994 window_text_bottom_y (w)
995 struct window *w;
997 int height = WINDOW_TOTAL_HEIGHT (w);
999 if (WINDOW_WANTS_MODELINE_P (w))
1000 height -= CURRENT_MODE_LINE_HEIGHT (w);
1001 return height;
1004 /* Return the pixel width of display area AREA of window W. AREA < 0
1005 means return the total width of W, not including fringes to
1006 the left and right of the window. */
1008 INLINE int
1009 window_box_width (w, area)
1010 struct window *w;
1011 int area;
1013 int cols = XFASTINT (w->total_cols);
1014 int pixels = 0;
1016 if (!w->pseudo_window_p)
1018 cols -= WINDOW_SCROLL_BAR_COLS (w);
1020 if (area == TEXT_AREA)
1022 if (INTEGERP (w->left_margin_cols))
1023 cols -= XFASTINT (w->left_margin_cols);
1024 if (INTEGERP (w->right_margin_cols))
1025 cols -= XFASTINT (w->right_margin_cols);
1026 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
1028 else if (area == LEFT_MARGIN_AREA)
1030 cols = (INTEGERP (w->left_margin_cols)
1031 ? XFASTINT (w->left_margin_cols) : 0);
1032 pixels = 0;
1034 else if (area == RIGHT_MARGIN_AREA)
1036 cols = (INTEGERP (w->right_margin_cols)
1037 ? XFASTINT (w->right_margin_cols) : 0);
1038 pixels = 0;
1042 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1046 /* Return the pixel height of the display area of window W, not
1047 including mode lines of W, if any. */
1049 INLINE int
1050 window_box_height (w)
1051 struct window *w;
1053 struct frame *f = XFRAME (w->frame);
1054 int height = WINDOW_TOTAL_HEIGHT (w);
1056 xassert (height >= 0);
1058 /* Note: the code below that determines the mode-line/header-line
1059 height is essentially the same as that contained in the macro
1060 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1061 the appropriate glyph row has its `mode_line_p' flag set,
1062 and if it doesn't, uses estimate_mode_line_height instead. */
1064 if (WINDOW_WANTS_MODELINE_P (w))
1066 struct glyph_row *ml_row
1067 = (w->current_matrix && w->current_matrix->rows
1068 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1069 : 0);
1070 if (ml_row && ml_row->mode_line_p)
1071 height -= ml_row->height;
1072 else
1073 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1076 if (WINDOW_WANTS_HEADER_LINE_P (w))
1078 struct glyph_row *hl_row
1079 = (w->current_matrix && w->current_matrix->rows
1080 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1081 : 0);
1082 if (hl_row && hl_row->mode_line_p)
1083 height -= hl_row->height;
1084 else
1085 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1088 /* With a very small font and a mode-line that's taller than
1089 default, we might end up with a negative height. */
1090 return max (0, height);
1093 /* Return the window-relative coordinate of the left edge of display
1094 area AREA of window W. AREA < 0 means return the left edge of the
1095 whole window, to the right of the left fringe of W. */
1097 INLINE int
1098 window_box_left_offset (w, area)
1099 struct window *w;
1100 int area;
1102 int x;
1104 if (w->pseudo_window_p)
1105 return 0;
1107 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1109 if (area == TEXT_AREA)
1110 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1111 + window_box_width (w, LEFT_MARGIN_AREA));
1112 else if (area == RIGHT_MARGIN_AREA)
1113 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1114 + window_box_width (w, LEFT_MARGIN_AREA)
1115 + window_box_width (w, TEXT_AREA)
1116 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1118 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1119 else if (area == LEFT_MARGIN_AREA
1120 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1121 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1123 return x;
1127 /* Return the window-relative coordinate of the right edge of display
1128 area AREA of window W. AREA < 0 means return the left edge of the
1129 whole window, to the left of the right fringe of W. */
1131 INLINE int
1132 window_box_right_offset (w, area)
1133 struct window *w;
1134 int area;
1136 return window_box_left_offset (w, area) + window_box_width (w, area);
1139 /* Return the frame-relative coordinate of the left edge of display
1140 area AREA of window W. AREA < 0 means return the left edge of the
1141 whole window, to the right of the left fringe of W. */
1143 INLINE int
1144 window_box_left (w, area)
1145 struct window *w;
1146 int area;
1148 struct frame *f = XFRAME (w->frame);
1149 int x;
1151 if (w->pseudo_window_p)
1152 return FRAME_INTERNAL_BORDER_WIDTH (f);
1154 x = (WINDOW_LEFT_EDGE_X (w)
1155 + window_box_left_offset (w, area));
1157 return x;
1161 /* Return the frame-relative coordinate of the right edge of display
1162 area AREA of window W. AREA < 0 means return the left edge of the
1163 whole window, to the left of the right fringe of W. */
1165 INLINE int
1166 window_box_right (w, area)
1167 struct window *w;
1168 int area;
1170 return window_box_left (w, area) + window_box_width (w, area);
1173 /* Get the bounding box of the display area AREA of window W, without
1174 mode lines, in frame-relative coordinates. AREA < 0 means the
1175 whole window, not including the left and right fringes of
1176 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1177 coordinates of the upper-left corner of the box. Return in
1178 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1180 INLINE void
1181 window_box (w, area, box_x, box_y, box_width, box_height)
1182 struct window *w;
1183 int area;
1184 int *box_x, *box_y, *box_width, *box_height;
1186 if (box_width)
1187 *box_width = window_box_width (w, area);
1188 if (box_height)
1189 *box_height = window_box_height (w);
1190 if (box_x)
1191 *box_x = window_box_left (w, area);
1192 if (box_y)
1194 *box_y = WINDOW_TOP_EDGE_Y (w);
1195 if (WINDOW_WANTS_HEADER_LINE_P (w))
1196 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1201 /* Get the bounding box of the display area AREA of window W, without
1202 mode lines. AREA < 0 means the whole window, not including the
1203 left and right fringe of the window. Return in *TOP_LEFT_X
1204 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1205 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1206 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1207 box. */
1209 INLINE void
1210 window_box_edges (w, area, top_left_x, top_left_y,
1211 bottom_right_x, bottom_right_y)
1212 struct window *w;
1213 int area;
1214 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
1216 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1217 bottom_right_y);
1218 *bottom_right_x += *top_left_x;
1219 *bottom_right_y += *top_left_y;
1224 /***********************************************************************
1225 Utilities
1226 ***********************************************************************/
1228 /* Return the bottom y-position of the line the iterator IT is in.
1229 This can modify IT's settings. */
1232 line_bottom_y (it)
1233 struct it *it;
1235 int line_height = it->max_ascent + it->max_descent;
1236 int line_top_y = it->current_y;
1238 if (line_height == 0)
1240 if (last_height)
1241 line_height = last_height;
1242 else if (IT_CHARPOS (*it) < ZV)
1244 move_it_by_lines (it, 1, 1);
1245 line_height = (it->max_ascent || it->max_descent
1246 ? it->max_ascent + it->max_descent
1247 : last_height);
1249 else
1251 struct glyph_row *row = it->glyph_row;
1253 /* Use the default character height. */
1254 it->glyph_row = NULL;
1255 it->what = IT_CHARACTER;
1256 it->c = ' ';
1257 it->len = 1;
1258 PRODUCE_GLYPHS (it);
1259 line_height = it->ascent + it->descent;
1260 it->glyph_row = row;
1264 return line_top_y + line_height;
1268 /* Return 1 if position CHARPOS is visible in window W.
1269 CHARPOS < 0 means return info about WINDOW_END position.
1270 If visible, set *X and *Y to pixel coordinates of top left corner.
1271 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1272 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1275 pos_visible_p (w, charpos, x, y, rtop, rbot, rowh, vpos)
1276 struct window *w;
1277 int charpos, *x, *y, *rtop, *rbot, *rowh, *vpos;
1279 struct it it;
1280 struct text_pos top;
1281 int visible_p = 0;
1282 struct buffer *old_buffer = NULL;
1284 if (noninteractive)
1285 return visible_p;
1287 if (XBUFFER (w->buffer) != current_buffer)
1289 old_buffer = current_buffer;
1290 set_buffer_internal_1 (XBUFFER (w->buffer));
1293 SET_TEXT_POS_FROM_MARKER (top, w->start);
1295 /* Compute exact mode line heights. */
1296 if (WINDOW_WANTS_MODELINE_P (w))
1297 current_mode_line_height
1298 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1299 current_buffer->mode_line_format);
1301 if (WINDOW_WANTS_HEADER_LINE_P (w))
1302 current_header_line_height
1303 = display_mode_line (w, HEADER_LINE_FACE_ID,
1304 current_buffer->header_line_format);
1306 start_display (&it, w, top);
1307 move_it_to (&it, charpos, -1, it.last_visible_y-1, -1,
1308 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
1310 /* Note that we may overshoot because of invisible text. */
1311 if (charpos >= 0 && IT_CHARPOS (it) >= charpos)
1313 int top_x = it.current_x;
1314 int top_y = it.current_y;
1315 int bottom_y = (last_height = 0, line_bottom_y (&it));
1316 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1318 if (top_y < window_top_y)
1319 visible_p = bottom_y > window_top_y;
1320 else if (top_y < it.last_visible_y)
1321 visible_p = 1;
1322 if (visible_p)
1324 Lisp_Object window, prop;
1326 XSETWINDOW (window, w);
1327 prop = Fget_char_property (make_number (it.position.charpos),
1328 Qinvisible, window);
1330 /* If charpos coincides with invisible text covered with an
1331 ellipsis, use the first glyph of the ellipsis to compute
1332 the pixel positions. */
1333 if (TEXT_PROP_MEANS_INVISIBLE (prop) == 2)
1335 struct glyph_row *row = it.glyph_row;
1336 struct glyph *glyph = row->glyphs[TEXT_AREA];
1337 struct glyph *end = glyph + row->used[TEXT_AREA];
1338 int x = row->x;
1340 for (; glyph < end && glyph->charpos < charpos; glyph++)
1341 x += glyph->pixel_width;
1343 top_x = x;
1346 *x = top_x;
1347 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1348 *rtop = max (0, window_top_y - top_y);
1349 *rbot = max (0, bottom_y - it.last_visible_y);
1350 *rowh = max (0, (min (bottom_y, it.last_visible_y)
1351 - max (top_y, window_top_y)));
1352 *vpos = it.vpos;
1355 else
1357 struct it it2;
1359 it2 = it;
1360 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1361 move_it_by_lines (&it, 1, 0);
1362 if (charpos < IT_CHARPOS (it)
1363 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1365 visible_p = 1;
1366 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1367 *x = it2.current_x;
1368 *y = it2.current_y + it2.max_ascent - it2.ascent;
1369 *rtop = max (0, -it2.current_y);
1370 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1371 - it.last_visible_y));
1372 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
1373 it.last_visible_y)
1374 - max (it2.current_y,
1375 WINDOW_HEADER_LINE_HEIGHT (w))));
1376 *vpos = it2.vpos;
1380 if (old_buffer)
1381 set_buffer_internal_1 (old_buffer);
1383 current_header_line_height = current_mode_line_height = -1;
1385 if (visible_p && XFASTINT (w->hscroll) > 0)
1386 *x -= XFASTINT (w->hscroll) * WINDOW_FRAME_COLUMN_WIDTH (w);
1388 #if 0
1389 /* Debugging code. */
1390 if (visible_p)
1391 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1392 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
1393 else
1394 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
1395 #endif
1397 return visible_p;
1401 /* Return the next character from STR which is MAXLEN bytes long.
1402 Return in *LEN the length of the character. This is like
1403 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1404 we find one, we return a `?', but with the length of the invalid
1405 character. */
1407 static INLINE int
1408 string_char_and_length (str, maxlen, len)
1409 const unsigned char *str;
1410 int maxlen, *len;
1412 int c;
1414 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
1415 if (!CHAR_VALID_P (c, 1))
1416 /* We may not change the length here because other places in Emacs
1417 don't use this function, i.e. they silently accept invalid
1418 characters. */
1419 c = '?';
1421 return c;
1426 /* Given a position POS containing a valid character and byte position
1427 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1429 static struct text_pos
1430 string_pos_nchars_ahead (pos, string, nchars)
1431 struct text_pos pos;
1432 Lisp_Object string;
1433 int nchars;
1435 xassert (STRINGP (string) && nchars >= 0);
1437 if (STRING_MULTIBYTE (string))
1439 int rest = SBYTES (string) - BYTEPOS (pos);
1440 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1441 int len;
1443 while (nchars--)
1445 string_char_and_length (p, rest, &len);
1446 p += len, rest -= len;
1447 xassert (rest >= 0);
1448 CHARPOS (pos) += 1;
1449 BYTEPOS (pos) += len;
1452 else
1453 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1455 return pos;
1459 /* Value is the text position, i.e. character and byte position,
1460 for character position CHARPOS in STRING. */
1462 static INLINE struct text_pos
1463 string_pos (charpos, string)
1464 int charpos;
1465 Lisp_Object string;
1467 struct text_pos pos;
1468 xassert (STRINGP (string));
1469 xassert (charpos >= 0);
1470 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1471 return pos;
1475 /* Value is a text position, i.e. character and byte position, for
1476 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1477 means recognize multibyte characters. */
1479 static struct text_pos
1480 c_string_pos (charpos, s, multibyte_p)
1481 int charpos;
1482 unsigned char *s;
1483 int multibyte_p;
1485 struct text_pos pos;
1487 xassert (s != NULL);
1488 xassert (charpos >= 0);
1490 if (multibyte_p)
1492 int rest = strlen (s), len;
1494 SET_TEXT_POS (pos, 0, 0);
1495 while (charpos--)
1497 string_char_and_length (s, rest, &len);
1498 s += len, rest -= len;
1499 xassert (rest >= 0);
1500 CHARPOS (pos) += 1;
1501 BYTEPOS (pos) += len;
1504 else
1505 SET_TEXT_POS (pos, charpos, charpos);
1507 return pos;
1511 /* Value is the number of characters in C string S. MULTIBYTE_P
1512 non-zero means recognize multibyte characters. */
1514 static int
1515 number_of_chars (s, multibyte_p)
1516 unsigned char *s;
1517 int multibyte_p;
1519 int nchars;
1521 if (multibyte_p)
1523 int rest = strlen (s), len;
1524 unsigned char *p = (unsigned char *) s;
1526 for (nchars = 0; rest > 0; ++nchars)
1528 string_char_and_length (p, rest, &len);
1529 rest -= len, p += len;
1532 else
1533 nchars = strlen (s);
1535 return nchars;
1539 /* Compute byte position NEWPOS->bytepos corresponding to
1540 NEWPOS->charpos. POS is a known position in string STRING.
1541 NEWPOS->charpos must be >= POS.charpos. */
1543 static void
1544 compute_string_pos (newpos, pos, string)
1545 struct text_pos *newpos, pos;
1546 Lisp_Object string;
1548 xassert (STRINGP (string));
1549 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1551 if (STRING_MULTIBYTE (string))
1552 *newpos = string_pos_nchars_ahead (pos, string,
1553 CHARPOS (*newpos) - CHARPOS (pos));
1554 else
1555 BYTEPOS (*newpos) = CHARPOS (*newpos);
1558 /* EXPORT:
1559 Return an estimation of the pixel height of mode or top lines on
1560 frame F. FACE_ID specifies what line's height to estimate. */
1563 estimate_mode_line_height (f, face_id)
1564 struct frame *f;
1565 enum face_id face_id;
1567 #ifdef HAVE_WINDOW_SYSTEM
1568 if (FRAME_WINDOW_P (f))
1570 int height = FONT_HEIGHT (FRAME_FONT (f));
1572 /* This function is called so early when Emacs starts that the face
1573 cache and mode line face are not yet initialized. */
1574 if (FRAME_FACE_CACHE (f))
1576 struct face *face = FACE_FROM_ID (f, face_id);
1577 if (face)
1579 if (face->font)
1580 height = FONT_HEIGHT (face->font);
1581 if (face->box_line_width > 0)
1582 height += 2 * face->box_line_width;
1586 return height;
1588 #endif
1590 return 1;
1593 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1594 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1595 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1596 not force the value into range. */
1598 void
1599 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
1600 FRAME_PTR f;
1601 register int pix_x, pix_y;
1602 int *x, *y;
1603 NativeRectangle *bounds;
1604 int noclip;
1607 #ifdef HAVE_WINDOW_SYSTEM
1608 if (FRAME_WINDOW_P (f))
1610 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1611 even for negative values. */
1612 if (pix_x < 0)
1613 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1614 if (pix_y < 0)
1615 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1617 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1618 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1620 if (bounds)
1621 STORE_NATIVE_RECT (*bounds,
1622 FRAME_COL_TO_PIXEL_X (f, pix_x),
1623 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1624 FRAME_COLUMN_WIDTH (f) - 1,
1625 FRAME_LINE_HEIGHT (f) - 1);
1627 if (!noclip)
1629 if (pix_x < 0)
1630 pix_x = 0;
1631 else if (pix_x > FRAME_TOTAL_COLS (f))
1632 pix_x = FRAME_TOTAL_COLS (f);
1634 if (pix_y < 0)
1635 pix_y = 0;
1636 else if (pix_y > FRAME_LINES (f))
1637 pix_y = FRAME_LINES (f);
1640 #endif
1642 *x = pix_x;
1643 *y = pix_y;
1647 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1648 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1649 can't tell the positions because W's display is not up to date,
1650 return 0. */
1653 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
1654 struct window *w;
1655 int hpos, vpos;
1656 int *frame_x, *frame_y;
1658 #ifdef HAVE_WINDOW_SYSTEM
1659 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1661 int success_p;
1663 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1664 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1666 if (display_completed)
1668 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1669 struct glyph *glyph = row->glyphs[TEXT_AREA];
1670 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1672 hpos = row->x;
1673 vpos = row->y;
1674 while (glyph < end)
1676 hpos += glyph->pixel_width;
1677 ++glyph;
1680 /* If first glyph is partially visible, its first visible position is still 0. */
1681 if (hpos < 0)
1682 hpos = 0;
1684 success_p = 1;
1686 else
1688 hpos = vpos = 0;
1689 success_p = 0;
1692 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1693 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1694 return success_p;
1696 #endif
1698 *frame_x = hpos;
1699 *frame_y = vpos;
1700 return 1;
1704 #ifdef HAVE_WINDOW_SYSTEM
1706 /* Find the glyph under window-relative coordinates X/Y in window W.
1707 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1708 strings. Return in *HPOS and *VPOS the row and column number of
1709 the glyph found. Return in *AREA the glyph area containing X.
1710 Value is a pointer to the glyph found or null if X/Y is not on
1711 text, or we can't tell because W's current matrix is not up to
1712 date. */
1714 static struct glyph *
1715 x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
1716 struct window *w;
1717 int x, y;
1718 int *hpos, *vpos, *dx, *dy, *area;
1720 struct glyph *glyph, *end;
1721 struct glyph_row *row = NULL;
1722 int x0, i;
1724 /* Find row containing Y. Give up if some row is not enabled. */
1725 for (i = 0; i < w->current_matrix->nrows; ++i)
1727 row = MATRIX_ROW (w->current_matrix, i);
1728 if (!row->enabled_p)
1729 return NULL;
1730 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1731 break;
1734 *vpos = i;
1735 *hpos = 0;
1737 /* Give up if Y is not in the window. */
1738 if (i == w->current_matrix->nrows)
1739 return NULL;
1741 /* Get the glyph area containing X. */
1742 if (w->pseudo_window_p)
1744 *area = TEXT_AREA;
1745 x0 = 0;
1747 else
1749 if (x < window_box_left_offset (w, TEXT_AREA))
1751 *area = LEFT_MARGIN_AREA;
1752 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1754 else if (x < window_box_right_offset (w, TEXT_AREA))
1756 *area = TEXT_AREA;
1757 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1759 else
1761 *area = RIGHT_MARGIN_AREA;
1762 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1766 /* Find glyph containing X. */
1767 glyph = row->glyphs[*area];
1768 end = glyph + row->used[*area];
1769 x -= x0;
1770 while (glyph < end && x >= glyph->pixel_width)
1772 x -= glyph->pixel_width;
1773 ++glyph;
1776 if (glyph == end)
1777 return NULL;
1779 if (dx)
1781 *dx = x;
1782 *dy = y - (row->y + row->ascent - glyph->ascent);
1785 *hpos = glyph - row->glyphs[*area];
1786 return glyph;
1790 /* EXPORT:
1791 Convert frame-relative x/y to coordinates relative to window W.
1792 Takes pseudo-windows into account. */
1794 void
1795 frame_to_window_pixel_xy (w, x, y)
1796 struct window *w;
1797 int *x, *y;
1799 if (w->pseudo_window_p)
1801 /* A pseudo-window is always full-width, and starts at the
1802 left edge of the frame, plus a frame border. */
1803 struct frame *f = XFRAME (w->frame);
1804 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1805 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1807 else
1809 *x -= WINDOW_LEFT_EDGE_X (w);
1810 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1814 /* EXPORT:
1815 Return in RECTS[] at most N clipping rectangles for glyph string S.
1816 Return the number of stored rectangles. */
1819 get_glyph_string_clip_rects (s, rects, n)
1820 struct glyph_string *s;
1821 NativeRectangle *rects;
1822 int n;
1824 XRectangle r;
1826 if (n <= 0)
1827 return 0;
1829 if (s->row->full_width_p)
1831 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1832 r.x = WINDOW_LEFT_EDGE_X (s->w);
1833 r.width = WINDOW_TOTAL_WIDTH (s->w);
1835 /* Unless displaying a mode or menu bar line, which are always
1836 fully visible, clip to the visible part of the row. */
1837 if (s->w->pseudo_window_p)
1838 r.height = s->row->visible_height;
1839 else
1840 r.height = s->height;
1842 else
1844 /* This is a text line that may be partially visible. */
1845 r.x = window_box_left (s->w, s->area);
1846 r.width = window_box_width (s->w, s->area);
1847 r.height = s->row->visible_height;
1850 if (s->clip_head)
1851 if (r.x < s->clip_head->x)
1853 if (r.width >= s->clip_head->x - r.x)
1854 r.width -= s->clip_head->x - r.x;
1855 else
1856 r.width = 0;
1857 r.x = s->clip_head->x;
1859 if (s->clip_tail)
1860 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
1862 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
1863 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
1864 else
1865 r.width = 0;
1868 /* If S draws overlapping rows, it's sufficient to use the top and
1869 bottom of the window for clipping because this glyph string
1870 intentionally draws over other lines. */
1871 if (s->for_overlaps)
1873 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1874 r.height = window_text_bottom_y (s->w) - r.y;
1876 /* Alas, the above simple strategy does not work for the
1877 environments with anti-aliased text: if the same text is
1878 drawn onto the same place multiple times, it gets thicker.
1879 If the overlap we are processing is for the erased cursor, we
1880 take the intersection with the rectagle of the cursor. */
1881 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
1883 XRectangle rc, r_save = r;
1885 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
1886 rc.y = s->w->phys_cursor.y;
1887 rc.width = s->w->phys_cursor_width;
1888 rc.height = s->w->phys_cursor_height;
1890 x_intersect_rectangles (&r_save, &rc, &r);
1893 else
1895 /* Don't use S->y for clipping because it doesn't take partially
1896 visible lines into account. For example, it can be negative for
1897 partially visible lines at the top of a window. */
1898 if (!s->row->full_width_p
1899 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1900 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1901 else
1902 r.y = max (0, s->row->y);
1904 /* If drawing a tool-bar window, draw it over the internal border
1905 at the top of the window. */
1906 if (WINDOWP (s->f->tool_bar_window)
1907 && s->w == XWINDOW (s->f->tool_bar_window))
1908 r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
1911 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1913 /* If drawing the cursor, don't let glyph draw outside its
1914 advertised boundaries. Cleartype does this under some circumstances. */
1915 if (s->hl == DRAW_CURSOR)
1917 struct glyph *glyph = s->first_glyph;
1918 int height, max_y;
1920 if (s->x > r.x)
1922 r.width -= s->x - r.x;
1923 r.x = s->x;
1925 r.width = min (r.width, glyph->pixel_width);
1927 /* If r.y is below window bottom, ensure that we still see a cursor. */
1928 height = min (glyph->ascent + glyph->descent,
1929 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
1930 max_y = window_text_bottom_y (s->w) - height;
1931 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
1932 if (s->ybase - glyph->ascent > max_y)
1934 r.y = max_y;
1935 r.height = height;
1937 else
1939 /* Don't draw cursor glyph taller than our actual glyph. */
1940 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
1941 if (height < r.height)
1943 max_y = r.y + r.height;
1944 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
1945 r.height = min (max_y - r.y, height);
1950 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
1951 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
1953 #ifdef CONVERT_FROM_XRECT
1954 CONVERT_FROM_XRECT (r, *rects);
1955 #else
1956 *rects = r;
1957 #endif
1958 return 1;
1960 else
1962 /* If we are processing overlapping and allowed to return
1963 multiple clipping rectangles, we exclude the row of the glyph
1964 string from the clipping rectangle. This is to avoid drawing
1965 the same text on the environment with anti-aliasing. */
1966 #ifdef CONVERT_FROM_XRECT
1967 XRectangle rs[2];
1968 #else
1969 XRectangle *rs = rects;
1970 #endif
1971 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
1973 if (s->for_overlaps & OVERLAPS_PRED)
1975 rs[i] = r;
1976 if (r.y + r.height > row_y)
1978 if (r.y < row_y)
1979 rs[i].height = row_y - r.y;
1980 else
1981 rs[i].height = 0;
1983 i++;
1985 if (s->for_overlaps & OVERLAPS_SUCC)
1987 rs[i] = r;
1988 if (r.y < row_y + s->row->visible_height)
1990 if (r.y + r.height > row_y + s->row->visible_height)
1992 rs[i].y = row_y + s->row->visible_height;
1993 rs[i].height = r.y + r.height - rs[i].y;
1995 else
1996 rs[i].height = 0;
1998 i++;
2001 n = i;
2002 #ifdef CONVERT_FROM_XRECT
2003 for (i = 0; i < n; i++)
2004 CONVERT_FROM_XRECT (rs[i], rects[i]);
2005 #endif
2006 return n;
2010 /* EXPORT:
2011 Return in *NR the clipping rectangle for glyph string S. */
2013 void
2014 get_glyph_string_clip_rect (s, nr)
2015 struct glyph_string *s;
2016 NativeRectangle *nr;
2018 get_glyph_string_clip_rects (s, nr, 1);
2022 /* EXPORT:
2023 Return the position and height of the phys cursor in window W.
2024 Set w->phys_cursor_width to width of phys cursor.
2027 void
2028 get_phys_cursor_geometry (w, row, glyph, xp, yp, heightp)
2029 struct window *w;
2030 struct glyph_row *row;
2031 struct glyph *glyph;
2032 int *xp, *yp, *heightp;
2034 struct frame *f = XFRAME (WINDOW_FRAME (w));
2035 int x, y, wd, h, h0, y0;
2037 /* Compute the width of the rectangle to draw. If on a stretch
2038 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2039 rectangle as wide as the glyph, but use a canonical character
2040 width instead. */
2041 wd = glyph->pixel_width - 1;
2042 #ifdef HAVE_NTGUI
2043 wd++; /* Why? */
2044 #endif
2046 x = w->phys_cursor.x;
2047 if (x < 0)
2049 wd += x;
2050 x = 0;
2053 if (glyph->type == STRETCH_GLYPH
2054 && !x_stretch_cursor_p)
2055 wd = min (FRAME_COLUMN_WIDTH (f), wd);
2056 w->phys_cursor_width = wd;
2058 y = w->phys_cursor.y + row->ascent - glyph->ascent;
2060 /* If y is below window bottom, ensure that we still see a cursor. */
2061 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
2063 h = max (h0, glyph->ascent + glyph->descent);
2064 h0 = min (h0, glyph->ascent + glyph->descent);
2066 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
2067 if (y < y0)
2069 h = max (h - (y0 - y) + 1, h0);
2070 y = y0 - 1;
2072 else
2074 y0 = window_text_bottom_y (w) - h0;
2075 if (y > y0)
2077 h += y - y0;
2078 y = y0;
2082 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
2083 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
2084 *heightp = h;
2088 * Remember which glyph the mouse is over.
2091 void
2092 remember_mouse_glyph (f, gx, gy, rect)
2093 struct frame *f;
2094 int gx, gy;
2095 NativeRectangle *rect;
2097 Lisp_Object window;
2098 struct window *w;
2099 struct glyph_row *r, *gr, *end_row;
2100 enum window_part part;
2101 enum glyph_row_area area;
2102 int x, y, width, height;
2104 /* Try to determine frame pixel position and size of the glyph under
2105 frame pixel coordinates X/Y on frame F. */
2107 if (!f->glyphs_initialized_p
2108 || (window = window_from_coordinates (f, gx, gy, &part, &x, &y, 0),
2109 NILP (window)))
2111 width = FRAME_SMALLEST_CHAR_WIDTH (f);
2112 height = FRAME_SMALLEST_FONT_HEIGHT (f);
2113 goto virtual_glyph;
2116 w = XWINDOW (window);
2117 width = WINDOW_FRAME_COLUMN_WIDTH (w);
2118 height = WINDOW_FRAME_LINE_HEIGHT (w);
2120 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
2121 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
2123 if (w->pseudo_window_p)
2125 area = TEXT_AREA;
2126 part = ON_MODE_LINE; /* Don't adjust margin. */
2127 goto text_glyph;
2130 switch (part)
2132 case ON_LEFT_MARGIN:
2133 area = LEFT_MARGIN_AREA;
2134 goto text_glyph;
2136 case ON_RIGHT_MARGIN:
2137 area = RIGHT_MARGIN_AREA;
2138 goto text_glyph;
2140 case ON_HEADER_LINE:
2141 case ON_MODE_LINE:
2142 gr = (part == ON_HEADER_LINE
2143 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
2144 : MATRIX_MODE_LINE_ROW (w->current_matrix));
2145 gy = gr->y;
2146 area = TEXT_AREA;
2147 goto text_glyph_row_found;
2149 case ON_TEXT:
2150 area = TEXT_AREA;
2152 text_glyph:
2153 gr = 0; gy = 0;
2154 for (; r <= end_row && r->enabled_p; ++r)
2155 if (r->y + r->height > y)
2157 gr = r; gy = r->y;
2158 break;
2161 text_glyph_row_found:
2162 if (gr && gy <= y)
2164 struct glyph *g = gr->glyphs[area];
2165 struct glyph *end = g + gr->used[area];
2167 height = gr->height;
2168 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2169 if (gx + g->pixel_width > x)
2170 break;
2172 if (g < end)
2174 if (g->type == IMAGE_GLYPH)
2176 /* Don't remember when mouse is over image, as
2177 image may have hot-spots. */
2178 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2179 return;
2181 width = g->pixel_width;
2183 else
2185 /* Use nominal char spacing at end of line. */
2186 x -= gx;
2187 gx += (x / width) * width;
2190 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2191 gx += window_box_left_offset (w, area);
2193 else
2195 /* Use nominal line height at end of window. */
2196 gx = (x / width) * width;
2197 y -= gy;
2198 gy += (y / height) * height;
2200 break;
2202 case ON_LEFT_FRINGE:
2203 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2204 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2205 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2206 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2207 goto row_glyph;
2209 case ON_RIGHT_FRINGE:
2210 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2211 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2212 : window_box_right_offset (w, TEXT_AREA));
2213 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2214 goto row_glyph;
2216 case ON_SCROLL_BAR:
2217 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2219 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2220 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2221 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2222 : 0)));
2223 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2225 row_glyph:
2226 gr = 0, gy = 0;
2227 for (; r <= end_row && r->enabled_p; ++r)
2228 if (r->y + r->height > y)
2230 gr = r; gy = r->y;
2231 break;
2234 if (gr && gy <= y)
2235 height = gr->height;
2236 else
2238 /* Use nominal line height at end of window. */
2239 y -= gy;
2240 gy += (y / height) * height;
2242 break;
2244 default:
2246 virtual_glyph:
2247 /* If there is no glyph under the mouse, then we divide the screen
2248 into a grid of the smallest glyph in the frame, and use that
2249 as our "glyph". */
2251 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2252 round down even for negative values. */
2253 if (gx < 0)
2254 gx -= width - 1;
2255 if (gy < 0)
2256 gy -= height - 1;
2258 gx = (gx / width) * width;
2259 gy = (gy / height) * height;
2261 goto store_rect;
2264 gx += WINDOW_LEFT_EDGE_X (w);
2265 gy += WINDOW_TOP_EDGE_Y (w);
2267 store_rect:
2268 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2270 /* Visible feedback for debugging. */
2271 #if 0
2272 #if HAVE_X_WINDOWS
2273 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2274 f->output_data.x->normal_gc,
2275 gx, gy, width, height);
2276 #endif
2277 #endif
2281 #endif /* HAVE_WINDOW_SYSTEM */
2284 /***********************************************************************
2285 Lisp form evaluation
2286 ***********************************************************************/
2288 /* Error handler for safe_eval and safe_call. */
2290 static Lisp_Object
2291 safe_eval_handler (arg)
2292 Lisp_Object arg;
2294 add_to_log ("Error during redisplay: %s", arg, Qnil);
2295 return Qnil;
2299 /* Evaluate SEXPR and return the result, or nil if something went
2300 wrong. Prevent redisplay during the evaluation. */
2302 Lisp_Object
2303 safe_eval (sexpr)
2304 Lisp_Object sexpr;
2306 Lisp_Object val;
2308 if (inhibit_eval_during_redisplay)
2309 val = Qnil;
2310 else
2312 int count = SPECPDL_INDEX ();
2313 struct gcpro gcpro1;
2315 GCPRO1 (sexpr);
2316 specbind (Qinhibit_redisplay, Qt);
2317 /* Use Qt to ensure debugger does not run,
2318 so there is no possibility of wanting to redisplay. */
2319 val = internal_condition_case_1 (Feval, sexpr, Qt,
2320 safe_eval_handler);
2321 UNGCPRO;
2322 val = unbind_to (count, val);
2325 return val;
2329 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
2330 Return the result, or nil if something went wrong. Prevent
2331 redisplay during the evaluation. */
2333 Lisp_Object
2334 safe_call (nargs, args)
2335 int nargs;
2336 Lisp_Object *args;
2338 Lisp_Object val;
2340 if (inhibit_eval_during_redisplay)
2341 val = Qnil;
2342 else
2344 int count = SPECPDL_INDEX ();
2345 struct gcpro gcpro1;
2347 GCPRO1 (args[0]);
2348 gcpro1.nvars = nargs;
2349 specbind (Qinhibit_redisplay, Qt);
2350 /* Use Qt to ensure debugger does not run,
2351 so there is no possibility of wanting to redisplay. */
2352 val = internal_condition_case_2 (Ffuncall, nargs, args, Qt,
2353 safe_eval_handler);
2354 UNGCPRO;
2355 val = unbind_to (count, val);
2358 return val;
2362 /* Call function FN with one argument ARG.
2363 Return the result, or nil if something went wrong. */
2365 Lisp_Object
2366 safe_call1 (fn, arg)
2367 Lisp_Object fn, arg;
2369 Lisp_Object args[2];
2370 args[0] = fn;
2371 args[1] = arg;
2372 return safe_call (2, args);
2377 /***********************************************************************
2378 Debugging
2379 ***********************************************************************/
2381 #if 0
2383 /* Define CHECK_IT to perform sanity checks on iterators.
2384 This is for debugging. It is too slow to do unconditionally. */
2386 static void
2387 check_it (it)
2388 struct it *it;
2390 if (it->method == GET_FROM_STRING)
2392 xassert (STRINGP (it->string));
2393 xassert (IT_STRING_CHARPOS (*it) >= 0);
2395 else
2397 xassert (IT_STRING_CHARPOS (*it) < 0);
2398 if (it->method == GET_FROM_BUFFER)
2400 /* Check that character and byte positions agree. */
2401 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2405 if (it->dpvec)
2406 xassert (it->current.dpvec_index >= 0);
2407 else
2408 xassert (it->current.dpvec_index < 0);
2411 #define CHECK_IT(IT) check_it ((IT))
2413 #else /* not 0 */
2415 #define CHECK_IT(IT) (void) 0
2417 #endif /* not 0 */
2420 #if GLYPH_DEBUG
2422 /* Check that the window end of window W is what we expect it
2423 to be---the last row in the current matrix displaying text. */
2425 static void
2426 check_window_end (w)
2427 struct window *w;
2429 if (!MINI_WINDOW_P (w)
2430 && !NILP (w->window_end_valid))
2432 struct glyph_row *row;
2433 xassert ((row = MATRIX_ROW (w->current_matrix,
2434 XFASTINT (w->window_end_vpos)),
2435 !row->enabled_p
2436 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2437 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2441 #define CHECK_WINDOW_END(W) check_window_end ((W))
2443 #else /* not GLYPH_DEBUG */
2445 #define CHECK_WINDOW_END(W) (void) 0
2447 #endif /* not GLYPH_DEBUG */
2451 /***********************************************************************
2452 Iterator initialization
2453 ***********************************************************************/
2455 /* Initialize IT for displaying current_buffer in window W, starting
2456 at character position CHARPOS. CHARPOS < 0 means that no buffer
2457 position is specified which is useful when the iterator is assigned
2458 a position later. BYTEPOS is the byte position corresponding to
2459 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2461 If ROW is not null, calls to produce_glyphs with IT as parameter
2462 will produce glyphs in that row.
2464 BASE_FACE_ID is the id of a base face to use. It must be one of
2465 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2466 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2467 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2469 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2470 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2471 will be initialized to use the corresponding mode line glyph row of
2472 the desired matrix of W. */
2474 void
2475 init_iterator (it, w, charpos, bytepos, row, base_face_id)
2476 struct it *it;
2477 struct window *w;
2478 int charpos, bytepos;
2479 struct glyph_row *row;
2480 enum face_id base_face_id;
2482 int highlight_region_p;
2484 /* Some precondition checks. */
2485 xassert (w != NULL && it != NULL);
2486 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2487 && charpos <= ZV));
2489 /* If face attributes have been changed since the last redisplay,
2490 free realized faces now because they depend on face definitions
2491 that might have changed. Don't free faces while there might be
2492 desired matrices pending which reference these faces. */
2493 if (face_change_count && !inhibit_free_realized_faces)
2495 face_change_count = 0;
2496 free_all_realized_faces (Qnil);
2499 /* Use one of the mode line rows of W's desired matrix if
2500 appropriate. */
2501 if (row == NULL)
2503 if (base_face_id == MODE_LINE_FACE_ID
2504 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2505 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2506 else if (base_face_id == HEADER_LINE_FACE_ID)
2507 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2510 /* Clear IT. */
2511 bzero (it, sizeof *it);
2512 it->current.overlay_string_index = -1;
2513 it->current.dpvec_index = -1;
2514 it->base_face_id = base_face_id;
2515 it->string = Qnil;
2516 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2518 /* The window in which we iterate over current_buffer: */
2519 XSETWINDOW (it->window, w);
2520 it->w = w;
2521 it->f = XFRAME (w->frame);
2523 /* Extra space between lines (on window systems only). */
2524 if (base_face_id == DEFAULT_FACE_ID
2525 && FRAME_WINDOW_P (it->f))
2527 if (NATNUMP (current_buffer->extra_line_spacing))
2528 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
2529 else if (FLOATP (current_buffer->extra_line_spacing))
2530 it->extra_line_spacing = (XFLOAT_DATA (current_buffer->extra_line_spacing)
2531 * FRAME_LINE_HEIGHT (it->f));
2532 else if (it->f->extra_line_spacing > 0)
2533 it->extra_line_spacing = it->f->extra_line_spacing;
2534 it->max_extra_line_spacing = 0;
2537 /* If realized faces have been removed, e.g. because of face
2538 attribute changes of named faces, recompute them. When running
2539 in batch mode, the face cache of the initial frame is null. If
2540 we happen to get called, make a dummy face cache. */
2541 if (FRAME_FACE_CACHE (it->f) == NULL)
2542 init_frame_faces (it->f);
2543 if (FRAME_FACE_CACHE (it->f)->used == 0)
2544 recompute_basic_faces (it->f);
2546 /* Current value of the `slice', `space-width', and 'height' properties. */
2547 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2548 it->space_width = Qnil;
2549 it->font_height = Qnil;
2550 it->override_ascent = -1;
2552 /* Are control characters displayed as `^C'? */
2553 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
2555 /* -1 means everything between a CR and the following line end
2556 is invisible. >0 means lines indented more than this value are
2557 invisible. */
2558 it->selective = (INTEGERP (current_buffer->selective_display)
2559 ? XFASTINT (current_buffer->selective_display)
2560 : (!NILP (current_buffer->selective_display)
2561 ? -1 : 0));
2562 it->selective_display_ellipsis_p
2563 = !NILP (current_buffer->selective_display_ellipses);
2565 /* Display table to use. */
2566 it->dp = window_display_table (w);
2568 /* Are multibyte characters enabled in current_buffer? */
2569 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2571 /* Non-zero if we should highlight the region. */
2572 highlight_region_p
2573 = (!NILP (Vtransient_mark_mode)
2574 && !NILP (current_buffer->mark_active)
2575 && XMARKER (current_buffer->mark)->buffer != 0);
2577 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2578 start and end of a visible region in window IT->w. Set both to
2579 -1 to indicate no region. */
2580 if (highlight_region_p
2581 /* Maybe highlight only in selected window. */
2582 && (/* Either show region everywhere. */
2583 highlight_nonselected_windows
2584 /* Or show region in the selected window. */
2585 || w == XWINDOW (selected_window)
2586 /* Or show the region if we are in the mini-buffer and W is
2587 the window the mini-buffer refers to. */
2588 || (MINI_WINDOW_P (XWINDOW (selected_window))
2589 && WINDOWP (minibuf_selected_window)
2590 && w == XWINDOW (minibuf_selected_window))))
2592 int charpos = marker_position (current_buffer->mark);
2593 it->region_beg_charpos = min (PT, charpos);
2594 it->region_end_charpos = max (PT, charpos);
2596 else
2597 it->region_beg_charpos = it->region_end_charpos = -1;
2599 /* Get the position at which the redisplay_end_trigger hook should
2600 be run, if it is to be run at all. */
2601 if (MARKERP (w->redisplay_end_trigger)
2602 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2603 it->redisplay_end_trigger_charpos
2604 = marker_position (w->redisplay_end_trigger);
2605 else if (INTEGERP (w->redisplay_end_trigger))
2606 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2608 /* Correct bogus values of tab_width. */
2609 it->tab_width = XINT (current_buffer->tab_width);
2610 if (it->tab_width <= 0 || it->tab_width > 1000)
2611 it->tab_width = 8;
2613 /* Are lines in the display truncated? */
2614 it->truncate_lines_p
2615 = (base_face_id != DEFAULT_FACE_ID
2616 || XINT (it->w->hscroll)
2617 || (truncate_partial_width_windows
2618 && !WINDOW_FULL_WIDTH_P (it->w))
2619 || !NILP (current_buffer->truncate_lines));
2621 /* Get dimensions of truncation and continuation glyphs. These are
2622 displayed as fringe bitmaps under X, so we don't need them for such
2623 frames. */
2624 if (!FRAME_WINDOW_P (it->f))
2626 if (it->truncate_lines_p)
2628 /* We will need the truncation glyph. */
2629 xassert (it->glyph_row == NULL);
2630 produce_special_glyphs (it, IT_TRUNCATION);
2631 it->truncation_pixel_width = it->pixel_width;
2633 else
2635 /* We will need the continuation glyph. */
2636 xassert (it->glyph_row == NULL);
2637 produce_special_glyphs (it, IT_CONTINUATION);
2638 it->continuation_pixel_width = it->pixel_width;
2641 /* Reset these values to zero because the produce_special_glyphs
2642 above has changed them. */
2643 it->pixel_width = it->ascent = it->descent = 0;
2644 it->phys_ascent = it->phys_descent = 0;
2647 /* Set this after getting the dimensions of truncation and
2648 continuation glyphs, so that we don't produce glyphs when calling
2649 produce_special_glyphs, above. */
2650 it->glyph_row = row;
2651 it->area = TEXT_AREA;
2653 /* Get the dimensions of the display area. The display area
2654 consists of the visible window area plus a horizontally scrolled
2655 part to the left of the window. All x-values are relative to the
2656 start of this total display area. */
2657 if (base_face_id != DEFAULT_FACE_ID)
2659 /* Mode lines, menu bar in terminal frames. */
2660 it->first_visible_x = 0;
2661 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2663 else
2665 it->first_visible_x
2666 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2667 it->last_visible_x = (it->first_visible_x
2668 + window_box_width (w, TEXT_AREA));
2670 /* If we truncate lines, leave room for the truncator glyph(s) at
2671 the right margin. Otherwise, leave room for the continuation
2672 glyph(s). Truncation and continuation glyphs are not inserted
2673 for window-based redisplay. */
2674 if (!FRAME_WINDOW_P (it->f))
2676 if (it->truncate_lines_p)
2677 it->last_visible_x -= it->truncation_pixel_width;
2678 else
2679 it->last_visible_x -= it->continuation_pixel_width;
2682 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2683 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2686 /* Leave room for a border glyph. */
2687 if (!FRAME_WINDOW_P (it->f)
2688 && !WINDOW_RIGHTMOST_P (it->w))
2689 it->last_visible_x -= 1;
2691 it->last_visible_y = window_text_bottom_y (w);
2693 /* For mode lines and alike, arrange for the first glyph having a
2694 left box line if the face specifies a box. */
2695 if (base_face_id != DEFAULT_FACE_ID)
2697 struct face *face;
2699 it->face_id = base_face_id;
2701 /* If we have a boxed mode line, make the first character appear
2702 with a left box line. */
2703 face = FACE_FROM_ID (it->f, base_face_id);
2704 if (face->box != FACE_NO_BOX)
2705 it->start_of_box_run_p = 1;
2708 /* If a buffer position was specified, set the iterator there,
2709 getting overlays and face properties from that position. */
2710 if (charpos >= BUF_BEG (current_buffer))
2712 it->end_charpos = ZV;
2713 it->face_id = -1;
2714 IT_CHARPOS (*it) = charpos;
2716 /* Compute byte position if not specified. */
2717 if (bytepos < charpos)
2718 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2719 else
2720 IT_BYTEPOS (*it) = bytepos;
2722 it->start = it->current;
2724 /* Compute faces etc. */
2725 reseat (it, it->current.pos, 1);
2728 CHECK_IT (it);
2732 /* Initialize IT for the display of window W with window start POS. */
2734 void
2735 start_display (it, w, pos)
2736 struct it *it;
2737 struct window *w;
2738 struct text_pos pos;
2740 struct glyph_row *row;
2741 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2743 row = w->desired_matrix->rows + first_vpos;
2744 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2745 it->first_vpos = first_vpos;
2747 /* Don't reseat to previous visible line start if current start
2748 position is in a string or image. */
2749 if (it->method == GET_FROM_BUFFER && !it->truncate_lines_p)
2751 int start_at_line_beg_p;
2752 int first_y = it->current_y;
2754 /* If window start is not at a line start, skip forward to POS to
2755 get the correct continuation lines width. */
2756 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2757 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2758 if (!start_at_line_beg_p)
2760 int new_x;
2762 reseat_at_previous_visible_line_start (it);
2763 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2765 new_x = it->current_x + it->pixel_width;
2767 /* If lines are continued, this line may end in the middle
2768 of a multi-glyph character (e.g. a control character
2769 displayed as \003, or in the middle of an overlay
2770 string). In this case move_it_to above will not have
2771 taken us to the start of the continuation line but to the
2772 end of the continued line. */
2773 if (it->current_x > 0
2774 && !it->truncate_lines_p /* Lines are continued. */
2775 && (/* And glyph doesn't fit on the line. */
2776 new_x > it->last_visible_x
2777 /* Or it fits exactly and we're on a window
2778 system frame. */
2779 || (new_x == it->last_visible_x
2780 && FRAME_WINDOW_P (it->f))))
2782 if (it->current.dpvec_index >= 0
2783 || it->current.overlay_string_index >= 0)
2785 set_iterator_to_next (it, 1);
2786 move_it_in_display_line_to (it, -1, -1, 0);
2789 it->continuation_lines_width += it->current_x;
2792 /* We're starting a new display line, not affected by the
2793 height of the continued line, so clear the appropriate
2794 fields in the iterator structure. */
2795 it->max_ascent = it->max_descent = 0;
2796 it->max_phys_ascent = it->max_phys_descent = 0;
2798 it->current_y = first_y;
2799 it->vpos = 0;
2800 it->current_x = it->hpos = 0;
2804 #if 0 /* Don't assert the following because start_display is sometimes
2805 called intentionally with a window start that is not at a
2806 line start. Please leave this code in as a comment. */
2808 /* Window start should be on a line start, now. */
2809 xassert (it->continuation_lines_width
2810 || IT_CHARPOS (it) == BEGV
2811 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
2812 #endif /* 0 */
2816 /* Return 1 if POS is a position in ellipses displayed for invisible
2817 text. W is the window we display, for text property lookup. */
2819 static int
2820 in_ellipses_for_invisible_text_p (pos, w)
2821 struct display_pos *pos;
2822 struct window *w;
2824 Lisp_Object prop, window;
2825 int ellipses_p = 0;
2826 int charpos = CHARPOS (pos->pos);
2828 /* If POS specifies a position in a display vector, this might
2829 be for an ellipsis displayed for invisible text. We won't
2830 get the iterator set up for delivering that ellipsis unless
2831 we make sure that it gets aware of the invisible text. */
2832 if (pos->dpvec_index >= 0
2833 && pos->overlay_string_index < 0
2834 && CHARPOS (pos->string_pos) < 0
2835 && charpos > BEGV
2836 && (XSETWINDOW (window, w),
2837 prop = Fget_char_property (make_number (charpos),
2838 Qinvisible, window),
2839 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2841 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2842 window);
2843 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2846 return ellipses_p;
2850 /* Initialize IT for stepping through current_buffer in window W,
2851 starting at position POS that includes overlay string and display
2852 vector/ control character translation position information. Value
2853 is zero if there are overlay strings with newlines at POS. */
2855 static int
2856 init_from_display_pos (it, w, pos)
2857 struct it *it;
2858 struct window *w;
2859 struct display_pos *pos;
2861 int charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2862 int i, overlay_strings_with_newlines = 0;
2864 /* If POS specifies a position in a display vector, this might
2865 be for an ellipsis displayed for invisible text. We won't
2866 get the iterator set up for delivering that ellipsis unless
2867 we make sure that it gets aware of the invisible text. */
2868 if (in_ellipses_for_invisible_text_p (pos, w))
2870 --charpos;
2871 bytepos = 0;
2874 /* Keep in mind: the call to reseat in init_iterator skips invisible
2875 text, so we might end up at a position different from POS. This
2876 is only a problem when POS is a row start after a newline and an
2877 overlay starts there with an after-string, and the overlay has an
2878 invisible property. Since we don't skip invisible text in
2879 display_line and elsewhere immediately after consuming the
2880 newline before the row start, such a POS will not be in a string,
2881 but the call to init_iterator below will move us to the
2882 after-string. */
2883 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2885 /* This only scans the current chunk -- it should scan all chunks.
2886 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
2887 to 16 in 22.1 to make this a lesser problem. */
2888 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
2890 const char *s = SDATA (it->overlay_strings[i]);
2891 const char *e = s + SBYTES (it->overlay_strings[i]);
2893 while (s < e && *s != '\n')
2894 ++s;
2896 if (s < e)
2898 overlay_strings_with_newlines = 1;
2899 break;
2903 /* If position is within an overlay string, set up IT to the right
2904 overlay string. */
2905 if (pos->overlay_string_index >= 0)
2907 int relative_index;
2909 /* If the first overlay string happens to have a `display'
2910 property for an image, the iterator will be set up for that
2911 image, and we have to undo that setup first before we can
2912 correct the overlay string index. */
2913 if (it->method == GET_FROM_IMAGE)
2914 pop_it (it);
2916 /* We already have the first chunk of overlay strings in
2917 IT->overlay_strings. Load more until the one for
2918 pos->overlay_string_index is in IT->overlay_strings. */
2919 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
2921 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
2922 it->current.overlay_string_index = 0;
2923 while (n--)
2925 load_overlay_strings (it, 0);
2926 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
2930 it->current.overlay_string_index = pos->overlay_string_index;
2931 relative_index = (it->current.overlay_string_index
2932 % OVERLAY_STRING_CHUNK_SIZE);
2933 it->string = it->overlay_strings[relative_index];
2934 xassert (STRINGP (it->string));
2935 it->current.string_pos = pos->string_pos;
2936 it->method = GET_FROM_STRING;
2939 #if 0 /* This is bogus because POS not having an overlay string
2940 position does not mean it's after the string. Example: A
2941 line starting with a before-string and initialization of IT
2942 to the previous row's end position. */
2943 else if (it->current.overlay_string_index >= 0)
2945 /* If POS says we're already after an overlay string ending at
2946 POS, make sure to pop the iterator because it will be in
2947 front of that overlay string. When POS is ZV, we've thereby
2948 also ``processed'' overlay strings at ZV. */
2949 while (it->sp)
2950 pop_it (it);
2951 xassert (it->current.overlay_string_index == -1);
2952 xassert (it->method == GET_FROM_BUFFER);
2953 if (CHARPOS (pos->pos) == ZV)
2954 it->overlay_strings_at_end_processed_p = 1;
2956 #endif /* 0 */
2958 if (CHARPOS (pos->string_pos) >= 0)
2960 /* Recorded position is not in an overlay string, but in another
2961 string. This can only be a string from a `display' property.
2962 IT should already be filled with that string. */
2963 it->current.string_pos = pos->string_pos;
2964 xassert (STRINGP (it->string));
2967 /* Restore position in display vector translations, control
2968 character translations or ellipses. */
2969 if (pos->dpvec_index >= 0)
2971 if (it->dpvec == NULL)
2972 get_next_display_element (it);
2973 xassert (it->dpvec && it->current.dpvec_index == 0);
2974 it->current.dpvec_index = pos->dpvec_index;
2977 CHECK_IT (it);
2978 return !overlay_strings_with_newlines;
2982 /* Initialize IT for stepping through current_buffer in window W
2983 starting at ROW->start. */
2985 static void
2986 init_to_row_start (it, w, row)
2987 struct it *it;
2988 struct window *w;
2989 struct glyph_row *row;
2991 init_from_display_pos (it, w, &row->start);
2992 it->start = row->start;
2993 it->continuation_lines_width = row->continuation_lines_width;
2994 CHECK_IT (it);
2998 /* Initialize IT for stepping through current_buffer in window W
2999 starting in the line following ROW, i.e. starting at ROW->end.
3000 Value is zero if there are overlay strings with newlines at ROW's
3001 end position. */
3003 static int
3004 init_to_row_end (it, w, row)
3005 struct it *it;
3006 struct window *w;
3007 struct glyph_row *row;
3009 int success = 0;
3011 if (init_from_display_pos (it, w, &row->end))
3013 if (row->continued_p)
3014 it->continuation_lines_width
3015 = row->continuation_lines_width + row->pixel_width;
3016 CHECK_IT (it);
3017 success = 1;
3020 return success;
3026 /***********************************************************************
3027 Text properties
3028 ***********************************************************************/
3030 /* Called when IT reaches IT->stop_charpos. Handle text property and
3031 overlay changes. Set IT->stop_charpos to the next position where
3032 to stop. */
3034 static void
3035 handle_stop (it)
3036 struct it *it;
3038 enum prop_handled handled;
3039 int handle_overlay_change_p;
3040 struct props *p;
3042 it->dpvec = NULL;
3043 it->current.dpvec_index = -1;
3044 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
3045 it->ignore_overlay_strings_at_pos_p = 0;
3047 /* Use face of preceding text for ellipsis (if invisible) */
3048 if (it->selective_display_ellipsis_p)
3049 it->saved_face_id = it->face_id;
3053 handled = HANDLED_NORMALLY;
3055 /* Call text property handlers. */
3056 for (p = it_props; p->handler; ++p)
3058 handled = p->handler (it);
3060 if (handled == HANDLED_RECOMPUTE_PROPS)
3061 break;
3062 else if (handled == HANDLED_RETURN)
3064 /* We still want to show before and after strings from
3065 overlays even if the actual buffer text is replaced. */
3066 if (!handle_overlay_change_p || it->sp > 1)
3067 return;
3068 if (!get_overlay_strings_1 (it, 0, 0))
3069 return;
3070 it->ignore_overlay_strings_at_pos_p = 1;
3071 it->string_from_display_prop_p = 0;
3072 handle_overlay_change_p = 0;
3073 handled = HANDLED_RECOMPUTE_PROPS;
3074 break;
3076 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
3077 handle_overlay_change_p = 0;
3080 if (handled != HANDLED_RECOMPUTE_PROPS)
3082 /* Don't check for overlay strings below when set to deliver
3083 characters from a display vector. */
3084 if (it->method == GET_FROM_DISPLAY_VECTOR)
3085 handle_overlay_change_p = 0;
3087 /* Handle overlay changes.
3088 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
3089 if it finds overlays. */
3090 if (handle_overlay_change_p)
3091 handled = handle_overlay_change (it);
3094 while (handled == HANDLED_RECOMPUTE_PROPS);
3096 /* Determine where to stop next. */
3097 if (handled == HANDLED_NORMALLY)
3098 compute_stop_pos (it);
3102 /* Compute IT->stop_charpos from text property and overlay change
3103 information for IT's current position. */
3105 static void
3106 compute_stop_pos (it)
3107 struct it *it;
3109 register INTERVAL iv, next_iv;
3110 Lisp_Object object, limit, position;
3112 /* If nowhere else, stop at the end. */
3113 it->stop_charpos = it->end_charpos;
3115 if (STRINGP (it->string))
3117 /* Strings are usually short, so don't limit the search for
3118 properties. */
3119 object = it->string;
3120 limit = Qnil;
3121 position = make_number (IT_STRING_CHARPOS (*it));
3123 else
3125 int charpos;
3127 /* If next overlay change is in front of the current stop pos
3128 (which is IT->end_charpos), stop there. Note: value of
3129 next_overlay_change is point-max if no overlay change
3130 follows. */
3131 charpos = next_overlay_change (IT_CHARPOS (*it));
3132 if (charpos < it->stop_charpos)
3133 it->stop_charpos = charpos;
3135 /* If showing the region, we have to stop at the region
3136 start or end because the face might change there. */
3137 if (it->region_beg_charpos > 0)
3139 if (IT_CHARPOS (*it) < it->region_beg_charpos)
3140 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
3141 else if (IT_CHARPOS (*it) < it->region_end_charpos)
3142 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
3145 /* Set up variables for computing the stop position from text
3146 property changes. */
3147 XSETBUFFER (object, current_buffer);
3148 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3149 position = make_number (IT_CHARPOS (*it));
3153 /* Get the interval containing IT's position. Value is a null
3154 interval if there isn't such an interval. */
3155 iv = validate_interval_range (object, &position, &position, 0);
3156 if (!NULL_INTERVAL_P (iv))
3158 Lisp_Object values_here[LAST_PROP_IDX];
3159 struct props *p;
3161 /* Get properties here. */
3162 for (p = it_props; p->handler; ++p)
3163 values_here[p->idx] = textget (iv->plist, *p->name);
3165 /* Look for an interval following iv that has different
3166 properties. */
3167 for (next_iv = next_interval (iv);
3168 (!NULL_INTERVAL_P (next_iv)
3169 && (NILP (limit)
3170 || XFASTINT (limit) > next_iv->position));
3171 next_iv = next_interval (next_iv))
3173 for (p = it_props; p->handler; ++p)
3175 Lisp_Object new_value;
3177 new_value = textget (next_iv->plist, *p->name);
3178 if (!EQ (values_here[p->idx], new_value))
3179 break;
3182 if (p->handler)
3183 break;
3186 if (!NULL_INTERVAL_P (next_iv))
3188 if (INTEGERP (limit)
3189 && next_iv->position >= XFASTINT (limit))
3190 /* No text property change up to limit. */
3191 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3192 else
3193 /* Text properties change in next_iv. */
3194 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3198 xassert (STRINGP (it->string)
3199 || (it->stop_charpos >= BEGV
3200 && it->stop_charpos >= IT_CHARPOS (*it)));
3204 /* Return the position of the next overlay change after POS in
3205 current_buffer. Value is point-max if no overlay change
3206 follows. This is like `next-overlay-change' but doesn't use
3207 xmalloc. */
3209 static int
3210 next_overlay_change (pos)
3211 int pos;
3213 int noverlays;
3214 int endpos;
3215 Lisp_Object *overlays;
3216 int i;
3218 /* Get all overlays at the given position. */
3219 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
3221 /* If any of these overlays ends before endpos,
3222 use its ending point instead. */
3223 for (i = 0; i < noverlays; ++i)
3225 Lisp_Object oend;
3226 int oendpos;
3228 oend = OVERLAY_END (overlays[i]);
3229 oendpos = OVERLAY_POSITION (oend);
3230 endpos = min (endpos, oendpos);
3233 return endpos;
3238 /***********************************************************************
3239 Fontification
3240 ***********************************************************************/
3242 /* Handle changes in the `fontified' property of the current buffer by
3243 calling hook functions from Qfontification_functions to fontify
3244 regions of text. */
3246 static enum prop_handled
3247 handle_fontified_prop (it)
3248 struct it *it;
3250 Lisp_Object prop, pos;
3251 enum prop_handled handled = HANDLED_NORMALLY;
3253 if (!NILP (Vmemory_full))
3254 return handled;
3256 /* Get the value of the `fontified' property at IT's current buffer
3257 position. (The `fontified' property doesn't have a special
3258 meaning in strings.) If the value is nil, call functions from
3259 Qfontification_functions. */
3260 if (!STRINGP (it->string)
3261 && it->s == NULL
3262 && !NILP (Vfontification_functions)
3263 && !NILP (Vrun_hooks)
3264 && (pos = make_number (IT_CHARPOS (*it)),
3265 prop = Fget_char_property (pos, Qfontified, Qnil),
3266 /* Ignore the special cased nil value always present at EOB since
3267 no amount of fontifying will be able to change it. */
3268 NILP (prop) && IT_CHARPOS (*it) < Z))
3270 int count = SPECPDL_INDEX ();
3271 Lisp_Object val;
3273 val = Vfontification_functions;
3274 specbind (Qfontification_functions, Qnil);
3276 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3277 safe_call1 (val, pos);
3278 else
3280 Lisp_Object globals, fn;
3281 struct gcpro gcpro1, gcpro2;
3283 globals = Qnil;
3284 GCPRO2 (val, globals);
3286 for (; CONSP (val); val = XCDR (val))
3288 fn = XCAR (val);
3290 if (EQ (fn, Qt))
3292 /* A value of t indicates this hook has a local
3293 binding; it means to run the global binding too.
3294 In a global value, t should not occur. If it
3295 does, we must ignore it to avoid an endless
3296 loop. */
3297 for (globals = Fdefault_value (Qfontification_functions);
3298 CONSP (globals);
3299 globals = XCDR (globals))
3301 fn = XCAR (globals);
3302 if (!EQ (fn, Qt))
3303 safe_call1 (fn, pos);
3306 else
3307 safe_call1 (fn, pos);
3310 UNGCPRO;
3313 unbind_to (count, Qnil);
3315 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3316 something. This avoids an endless loop if they failed to
3317 fontify the text for which reason ever. */
3318 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3319 handled = HANDLED_RECOMPUTE_PROPS;
3322 return handled;
3327 /***********************************************************************
3328 Faces
3329 ***********************************************************************/
3331 /* Set up iterator IT from face properties at its current position.
3332 Called from handle_stop. */
3334 static enum prop_handled
3335 handle_face_prop (it)
3336 struct it *it;
3338 int new_face_id, next_stop;
3340 if (!STRINGP (it->string))
3342 new_face_id
3343 = face_at_buffer_position (it->w,
3344 IT_CHARPOS (*it),
3345 it->region_beg_charpos,
3346 it->region_end_charpos,
3347 &next_stop,
3348 (IT_CHARPOS (*it)
3349 + TEXT_PROP_DISTANCE_LIMIT),
3352 /* Is this a start of a run of characters with box face?
3353 Caveat: this can be called for a freshly initialized
3354 iterator; face_id is -1 in this case. We know that the new
3355 face will not change until limit, i.e. if the new face has a
3356 box, all characters up to limit will have one. But, as
3357 usual, we don't know whether limit is really the end. */
3358 if (new_face_id != it->face_id)
3360 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3362 /* If new face has a box but old face has not, this is
3363 the start of a run of characters with box, i.e. it has
3364 a shadow on the left side. The value of face_id of the
3365 iterator will be -1 if this is the initial call that gets
3366 the face. In this case, we have to look in front of IT's
3367 position and see whether there is a face != new_face_id. */
3368 it->start_of_box_run_p
3369 = (new_face->box != FACE_NO_BOX
3370 && (it->face_id >= 0
3371 || IT_CHARPOS (*it) == BEG
3372 || new_face_id != face_before_it_pos (it)));
3373 it->face_box_p = new_face->box != FACE_NO_BOX;
3376 else
3378 int base_face_id, bufpos;
3379 int i;
3380 Lisp_Object from_overlay
3381 = (it->current.overlay_string_index >= 0
3382 ? it->string_overlays[it->current.overlay_string_index]
3383 : Qnil);
3385 /* See if we got to this string directly or indirectly from
3386 an overlay property. That includes the before-string or
3387 after-string of an overlay, strings in display properties
3388 provided by an overlay, their text properties, etc.
3390 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
3391 if (! NILP (from_overlay))
3392 for (i = it->sp - 1; i >= 0; i--)
3394 if (it->stack[i].current.overlay_string_index >= 0)
3395 from_overlay
3396 = it->string_overlays[it->stack[i].current.overlay_string_index];
3397 else if (! NILP (it->stack[i].from_overlay))
3398 from_overlay = it->stack[i].from_overlay;
3400 if (!NILP (from_overlay))
3401 break;
3404 if (! NILP (from_overlay))
3406 bufpos = IT_CHARPOS (*it);
3407 /* For a string from an overlay, the base face depends
3408 only on text properties and ignores overlays. */
3409 base_face_id
3410 = face_for_overlay_string (it->w,
3411 IT_CHARPOS (*it),
3412 it->region_beg_charpos,
3413 it->region_end_charpos,
3414 &next_stop,
3415 (IT_CHARPOS (*it)
3416 + TEXT_PROP_DISTANCE_LIMIT),
3418 from_overlay);
3420 else
3422 bufpos = 0;
3424 /* For strings from a `display' property, use the face at
3425 IT's current buffer position as the base face to merge
3426 with, so that overlay strings appear in the same face as
3427 surrounding text, unless they specify their own
3428 faces. */
3429 base_face_id = underlying_face_id (it);
3432 new_face_id = face_at_string_position (it->w,
3433 it->string,
3434 IT_STRING_CHARPOS (*it),
3435 bufpos,
3436 it->region_beg_charpos,
3437 it->region_end_charpos,
3438 &next_stop,
3439 base_face_id, 0);
3441 #if 0 /* This shouldn't be neccessary. Let's check it. */
3442 /* If IT is used to display a mode line we would really like to
3443 use the mode line face instead of the frame's default face. */
3444 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
3445 && new_face_id == DEFAULT_FACE_ID)
3446 new_face_id = CURRENT_MODE_LINE_FACE_ID (it->w);
3447 #endif
3449 /* Is this a start of a run of characters with box? Caveat:
3450 this can be called for a freshly allocated iterator; face_id
3451 is -1 is this case. We know that the new face will not
3452 change until the next check pos, i.e. if the new face has a
3453 box, all characters up to that position will have a
3454 box. But, as usual, we don't know whether that position
3455 is really the end. */
3456 if (new_face_id != it->face_id)
3458 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3459 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3461 /* If new face has a box but old face hasn't, this is the
3462 start of a run of characters with box, i.e. it has a
3463 shadow on the left side. */
3464 it->start_of_box_run_p
3465 = new_face->box && (old_face == NULL || !old_face->box);
3466 it->face_box_p = new_face->box != FACE_NO_BOX;
3470 it->face_id = new_face_id;
3471 return HANDLED_NORMALLY;
3475 /* Return the ID of the face ``underlying'' IT's current position,
3476 which is in a string. If the iterator is associated with a
3477 buffer, return the face at IT's current buffer position.
3478 Otherwise, use the iterator's base_face_id. */
3480 static int
3481 underlying_face_id (it)
3482 struct it *it;
3484 int face_id = it->base_face_id, i;
3486 xassert (STRINGP (it->string));
3488 for (i = it->sp - 1; i >= 0; --i)
3489 if (NILP (it->stack[i].string))
3490 face_id = it->stack[i].face_id;
3492 return face_id;
3496 /* Compute the face one character before or after the current position
3497 of IT. BEFORE_P non-zero means get the face in front of IT's
3498 position. Value is the id of the face. */
3500 static int
3501 face_before_or_after_it_pos (it, before_p)
3502 struct it *it;
3503 int before_p;
3505 int face_id, limit;
3506 int next_check_charpos;
3507 struct text_pos pos;
3509 xassert (it->s == NULL);
3511 if (STRINGP (it->string))
3513 int bufpos, base_face_id;
3515 /* No face change past the end of the string (for the case
3516 we are padding with spaces). No face change before the
3517 string start. */
3518 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
3519 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
3520 return it->face_id;
3522 /* Set pos to the position before or after IT's current position. */
3523 if (before_p)
3524 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
3525 else
3526 /* For composition, we must check the character after the
3527 composition. */
3528 pos = (it->what == IT_COMPOSITION
3529 ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string)
3530 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
3532 if (it->current.overlay_string_index >= 0)
3533 bufpos = IT_CHARPOS (*it);
3534 else
3535 bufpos = 0;
3537 base_face_id = underlying_face_id (it);
3539 /* Get the face for ASCII, or unibyte. */
3540 face_id = face_at_string_position (it->w,
3541 it->string,
3542 CHARPOS (pos),
3543 bufpos,
3544 it->region_beg_charpos,
3545 it->region_end_charpos,
3546 &next_check_charpos,
3547 base_face_id, 0);
3549 /* Correct the face for charsets different from ASCII. Do it
3550 for the multibyte case only. The face returned above is
3551 suitable for unibyte text if IT->string is unibyte. */
3552 if (STRING_MULTIBYTE (it->string))
3554 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
3555 int rest = SBYTES (it->string) - BYTEPOS (pos);
3556 int c, len;
3557 struct face *face = FACE_FROM_ID (it->f, face_id);
3559 c = string_char_and_length (p, rest, &len);
3560 face_id = FACE_FOR_CHAR (it->f, face, c);
3563 else
3565 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3566 || (IT_CHARPOS (*it) <= BEGV && before_p))
3567 return it->face_id;
3569 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3570 pos = it->current.pos;
3572 if (before_p)
3573 DEC_TEXT_POS (pos, it->multibyte_p);
3574 else
3576 if (it->what == IT_COMPOSITION)
3577 /* For composition, we must check the position after the
3578 composition. */
3579 pos.charpos += it->cmp_len, pos.bytepos += it->len;
3580 else
3581 INC_TEXT_POS (pos, it->multibyte_p);
3584 /* Determine face for CHARSET_ASCII, or unibyte. */
3585 face_id = face_at_buffer_position (it->w,
3586 CHARPOS (pos),
3587 it->region_beg_charpos,
3588 it->region_end_charpos,
3589 &next_check_charpos,
3590 limit, 0);
3592 /* Correct the face for charsets different from ASCII. Do it
3593 for the multibyte case only. The face returned above is
3594 suitable for unibyte text if current_buffer is unibyte. */
3595 if (it->multibyte_p)
3597 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3598 struct face *face = FACE_FROM_ID (it->f, face_id);
3599 face_id = FACE_FOR_CHAR (it->f, face, c);
3603 return face_id;
3608 /***********************************************************************
3609 Invisible text
3610 ***********************************************************************/
3612 /* Set up iterator IT from invisible properties at its current
3613 position. Called from handle_stop. */
3615 static enum prop_handled
3616 handle_invisible_prop (it)
3617 struct it *it;
3619 enum prop_handled handled = HANDLED_NORMALLY;
3621 if (STRINGP (it->string))
3623 extern Lisp_Object Qinvisible;
3624 Lisp_Object prop, end_charpos, limit, charpos;
3626 /* Get the value of the invisible text property at the
3627 current position. Value will be nil if there is no such
3628 property. */
3629 charpos = make_number (IT_STRING_CHARPOS (*it));
3630 prop = Fget_text_property (charpos, Qinvisible, it->string);
3632 if (!NILP (prop)
3633 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3635 handled = HANDLED_RECOMPUTE_PROPS;
3637 /* Get the position at which the next change of the
3638 invisible text property can be found in IT->string.
3639 Value will be nil if the property value is the same for
3640 all the rest of IT->string. */
3641 XSETINT (limit, SCHARS (it->string));
3642 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3643 it->string, limit);
3645 /* Text at current position is invisible. The next
3646 change in the property is at position end_charpos.
3647 Move IT's current position to that position. */
3648 if (INTEGERP (end_charpos)
3649 && XFASTINT (end_charpos) < XFASTINT (limit))
3651 struct text_pos old;
3652 old = it->current.string_pos;
3653 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3654 compute_string_pos (&it->current.string_pos, old, it->string);
3656 else
3658 /* The rest of the string is invisible. If this is an
3659 overlay string, proceed with the next overlay string
3660 or whatever comes and return a character from there. */
3661 if (it->current.overlay_string_index >= 0)
3663 next_overlay_string (it);
3664 /* Don't check for overlay strings when we just
3665 finished processing them. */
3666 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3668 else
3670 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3671 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3676 else
3678 int invis_p;
3679 EMACS_INT newpos, next_stop, start_charpos;
3680 Lisp_Object pos, prop, overlay;
3682 /* First of all, is there invisible text at this position? */
3683 start_charpos = IT_CHARPOS (*it);
3684 pos = make_number (IT_CHARPOS (*it));
3685 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3686 &overlay);
3687 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3689 /* If we are on invisible text, skip over it. */
3690 if (invis_p && IT_CHARPOS (*it) < it->end_charpos)
3692 /* Record whether we have to display an ellipsis for the
3693 invisible text. */
3694 int display_ellipsis_p = invis_p == 2;
3696 handled = HANDLED_RECOMPUTE_PROPS;
3698 /* Loop skipping over invisible text. The loop is left at
3699 ZV or with IT on the first char being visible again. */
3702 /* Try to skip some invisible text. Return value is the
3703 position reached which can be equal to IT's position
3704 if there is nothing invisible here. This skips both
3705 over invisible text properties and overlays with
3706 invisible property. */
3707 newpos = skip_invisible (IT_CHARPOS (*it),
3708 &next_stop, ZV, it->window);
3710 /* If we skipped nothing at all we weren't at invisible
3711 text in the first place. If everything to the end of
3712 the buffer was skipped, end the loop. */
3713 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
3714 invis_p = 0;
3715 else
3717 /* We skipped some characters but not necessarily
3718 all there are. Check if we ended up on visible
3719 text. Fget_char_property returns the property of
3720 the char before the given position, i.e. if we
3721 get invis_p = 0, this means that the char at
3722 newpos is visible. */
3723 pos = make_number (newpos);
3724 prop = Fget_char_property (pos, Qinvisible, it->window);
3725 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3728 /* If we ended up on invisible text, proceed to
3729 skip starting with next_stop. */
3730 if (invis_p)
3731 IT_CHARPOS (*it) = next_stop;
3733 /* If there are adjacent invisible texts, don't lose the
3734 second one's ellipsis. */
3735 if (invis_p == 2)
3736 display_ellipsis_p = 1;
3738 while (invis_p);
3740 /* The position newpos is now either ZV or on visible text. */
3741 IT_CHARPOS (*it) = newpos;
3742 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3744 /* If there are before-strings at the start of invisible
3745 text, and the text is invisible because of a text
3746 property, arrange to show before-strings because 20.x did
3747 it that way. (If the text is invisible because of an
3748 overlay property instead of a text property, this is
3749 already handled in the overlay code.) */
3750 if (NILP (overlay)
3751 && get_overlay_strings (it, start_charpos))
3753 handled = HANDLED_RECOMPUTE_PROPS;
3754 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3756 else if (display_ellipsis_p)
3758 /* Make sure that the glyphs of the ellipsis will get
3759 correct `charpos' values. If we would not update
3760 it->position here, the glyphs would belong to the
3761 last visible character _before_ the invisible
3762 text, which confuses `set_cursor_from_row'.
3764 We use the last invisible position instead of the
3765 first because this way the cursor is always drawn on
3766 the first "." of the ellipsis, whenever PT is inside
3767 the invisible text. Otherwise the cursor would be
3768 placed _after_ the ellipsis when the point is after the
3769 first invisible character. */
3770 if (!STRINGP (it->object))
3772 it->position.charpos = IT_CHARPOS (*it) - 1;
3773 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
3775 setup_for_ellipsis (it, 0);
3776 /* Let the ellipsis display before
3777 considering any properties of the following char.
3778 Fixes jasonr@gnu.org 01 Oct 07 bug. */
3779 handled = HANDLED_RETURN;
3784 return handled;
3788 /* Make iterator IT return `...' next.
3789 Replaces LEN characters from buffer. */
3791 static void
3792 setup_for_ellipsis (it, len)
3793 struct it *it;
3794 int len;
3796 /* Use the display table definition for `...'. Invalid glyphs
3797 will be handled by the method returning elements from dpvec. */
3798 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3800 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3801 it->dpvec = v->contents;
3802 it->dpend = v->contents + v->size;
3804 else
3806 /* Default `...'. */
3807 it->dpvec = default_invis_vector;
3808 it->dpend = default_invis_vector + 3;
3811 it->dpvec_char_len = len;
3812 it->current.dpvec_index = 0;
3813 it->dpvec_face_id = -1;
3815 /* Remember the current face id in case glyphs specify faces.
3816 IT's face is restored in set_iterator_to_next.
3817 saved_face_id was set to preceding char's face in handle_stop. */
3818 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
3819 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
3821 it->method = GET_FROM_DISPLAY_VECTOR;
3822 it->ellipsis_p = 1;
3827 /***********************************************************************
3828 'display' property
3829 ***********************************************************************/
3831 /* Set up iterator IT from `display' property at its current position.
3832 Called from handle_stop.
3833 We return HANDLED_RETURN if some part of the display property
3834 overrides the display of the buffer text itself.
3835 Otherwise we return HANDLED_NORMALLY. */
3837 static enum prop_handled
3838 handle_display_prop (it)
3839 struct it *it;
3841 Lisp_Object prop, object, overlay;
3842 struct text_pos *position;
3843 /* Nonzero if some property replaces the display of the text itself. */
3844 int display_replaced_p = 0;
3846 if (STRINGP (it->string))
3848 object = it->string;
3849 position = &it->current.string_pos;
3851 else
3853 XSETWINDOW (object, it->w);
3854 position = &it->current.pos;
3857 /* Reset those iterator values set from display property values. */
3858 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
3859 it->space_width = Qnil;
3860 it->font_height = Qnil;
3861 it->voffset = 0;
3863 /* We don't support recursive `display' properties, i.e. string
3864 values that have a string `display' property, that have a string
3865 `display' property etc. */
3866 if (!it->string_from_display_prop_p)
3867 it->area = TEXT_AREA;
3869 prop = get_char_property_and_overlay (make_number (position->charpos),
3870 Qdisplay, object, &overlay);
3871 if (NILP (prop))
3872 return HANDLED_NORMALLY;
3873 /* Now OVERLAY is the overlay that gave us this property, or nil
3874 if it was a text property. */
3876 if (!STRINGP (it->string))
3877 object = it->w->buffer;
3879 if (CONSP (prop)
3880 /* Simple properties. */
3881 && !EQ (XCAR (prop), Qimage)
3882 && !EQ (XCAR (prop), Qspace)
3883 && !EQ (XCAR (prop), Qwhen)
3884 && !EQ (XCAR (prop), Qslice)
3885 && !EQ (XCAR (prop), Qspace_width)
3886 && !EQ (XCAR (prop), Qheight)
3887 && !EQ (XCAR (prop), Qraise)
3888 /* Marginal area specifications. */
3889 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
3890 && !EQ (XCAR (prop), Qleft_fringe)
3891 && !EQ (XCAR (prop), Qright_fringe)
3892 && !NILP (XCAR (prop)))
3894 for (; CONSP (prop); prop = XCDR (prop))
3896 if (handle_single_display_spec (it, XCAR (prop), object, overlay,
3897 position, display_replaced_p))
3899 display_replaced_p = 1;
3900 /* If some text in a string is replaced, `position' no
3901 longer points to the position of `object'. */
3902 if (STRINGP (object))
3903 break;
3907 else if (VECTORP (prop))
3909 int i;
3910 for (i = 0; i < ASIZE (prop); ++i)
3911 if (handle_single_display_spec (it, AREF (prop, i), object, overlay,
3912 position, display_replaced_p))
3914 display_replaced_p = 1;
3915 /* If some text in a string is replaced, `position' no
3916 longer points to the position of `object'. */
3917 if (STRINGP (object))
3918 break;
3921 else
3923 int ret = handle_single_display_spec (it, prop, object, overlay,
3924 position, 0);
3925 if (ret < 0) /* Replaced by "", i.e. nothing. */
3926 return HANDLED_RECOMPUTE_PROPS;
3927 if (ret)
3928 display_replaced_p = 1;
3931 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
3935 /* Value is the position of the end of the `display' property starting
3936 at START_POS in OBJECT. */
3938 static struct text_pos
3939 display_prop_end (it, object, start_pos)
3940 struct it *it;
3941 Lisp_Object object;
3942 struct text_pos start_pos;
3944 Lisp_Object end;
3945 struct text_pos end_pos;
3947 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
3948 Qdisplay, object, Qnil);
3949 CHARPOS (end_pos) = XFASTINT (end);
3950 if (STRINGP (object))
3951 compute_string_pos (&end_pos, start_pos, it->string);
3952 else
3953 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
3955 return end_pos;
3959 /* Set up IT from a single `display' specification PROP. OBJECT
3960 is the object in which the `display' property was found. *POSITION
3961 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3962 means that we previously saw a display specification which already
3963 replaced text display with something else, for example an image;
3964 we ignore such properties after the first one has been processed.
3966 OVERLAY is the overlay this `display' property came from,
3967 or nil if it was a text property.
3969 If PROP is a `space' or `image' specification, and in some other
3970 cases too, set *POSITION to the position where the `display'
3971 property ends.
3973 Value is non-zero if something was found which replaces the display
3974 of buffer or string text. Specifically, the value is -1 if that
3975 "something" is "nothing". */
3977 static int
3978 handle_single_display_spec (it, spec, object, overlay, position,
3979 display_replaced_before_p)
3980 struct it *it;
3981 Lisp_Object spec;
3982 Lisp_Object object;
3983 Lisp_Object overlay;
3984 struct text_pos *position;
3985 int display_replaced_before_p;
3987 Lisp_Object form;
3988 Lisp_Object location, value;
3989 struct text_pos start_pos, save_pos;
3990 int valid_p;
3992 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
3993 If the result is non-nil, use VALUE instead of SPEC. */
3994 form = Qt;
3995 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
3997 spec = XCDR (spec);
3998 if (!CONSP (spec))
3999 return 0;
4000 form = XCAR (spec);
4001 spec = XCDR (spec);
4004 if (!NILP (form) && !EQ (form, Qt))
4006 int count = SPECPDL_INDEX ();
4007 struct gcpro gcpro1;
4009 /* Bind `object' to the object having the `display' property, a
4010 buffer or string. Bind `position' to the position in the
4011 object where the property was found, and `buffer-position'
4012 to the current position in the buffer. */
4013 specbind (Qobject, object);
4014 specbind (Qposition, make_number (CHARPOS (*position)));
4015 specbind (Qbuffer_position,
4016 make_number (STRINGP (object)
4017 ? IT_CHARPOS (*it) : CHARPOS (*position)));
4018 GCPRO1 (form);
4019 form = safe_eval (form);
4020 UNGCPRO;
4021 unbind_to (count, Qnil);
4024 if (NILP (form))
4025 return 0;
4027 /* Handle `(height HEIGHT)' specifications. */
4028 if (CONSP (spec)
4029 && EQ (XCAR (spec), Qheight)
4030 && CONSP (XCDR (spec)))
4032 if (!FRAME_WINDOW_P (it->f))
4033 return 0;
4035 it->font_height = XCAR (XCDR (spec));
4036 if (!NILP (it->font_height))
4038 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4039 int new_height = -1;
4041 if (CONSP (it->font_height)
4042 && (EQ (XCAR (it->font_height), Qplus)
4043 || EQ (XCAR (it->font_height), Qminus))
4044 && CONSP (XCDR (it->font_height))
4045 && INTEGERP (XCAR (XCDR (it->font_height))))
4047 /* `(+ N)' or `(- N)' where N is an integer. */
4048 int steps = XINT (XCAR (XCDR (it->font_height)));
4049 if (EQ (XCAR (it->font_height), Qplus))
4050 steps = - steps;
4051 it->face_id = smaller_face (it->f, it->face_id, steps);
4053 else if (FUNCTIONP (it->font_height))
4055 /* Call function with current height as argument.
4056 Value is the new height. */
4057 Lisp_Object height;
4058 height = safe_call1 (it->font_height,
4059 face->lface[LFACE_HEIGHT_INDEX]);
4060 if (NUMBERP (height))
4061 new_height = XFLOATINT (height);
4063 else if (NUMBERP (it->font_height))
4065 /* Value is a multiple of the canonical char height. */
4066 struct face *face;
4068 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
4069 new_height = (XFLOATINT (it->font_height)
4070 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
4072 else
4074 /* Evaluate IT->font_height with `height' bound to the
4075 current specified height to get the new height. */
4076 int count = SPECPDL_INDEX ();
4078 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
4079 value = safe_eval (it->font_height);
4080 unbind_to (count, Qnil);
4082 if (NUMBERP (value))
4083 new_height = XFLOATINT (value);
4086 if (new_height > 0)
4087 it->face_id = face_with_height (it->f, it->face_id, new_height);
4090 return 0;
4093 /* Handle `(space-width WIDTH)'. */
4094 if (CONSP (spec)
4095 && EQ (XCAR (spec), Qspace_width)
4096 && CONSP (XCDR (spec)))
4098 if (!FRAME_WINDOW_P (it->f))
4099 return 0;
4101 value = XCAR (XCDR (spec));
4102 if (NUMBERP (value) && XFLOATINT (value) > 0)
4103 it->space_width = value;
4105 return 0;
4108 /* Handle `(slice X Y WIDTH HEIGHT)'. */
4109 if (CONSP (spec)
4110 && EQ (XCAR (spec), Qslice))
4112 Lisp_Object tem;
4114 if (!FRAME_WINDOW_P (it->f))
4115 return 0;
4117 if (tem = XCDR (spec), CONSP (tem))
4119 it->slice.x = XCAR (tem);
4120 if (tem = XCDR (tem), CONSP (tem))
4122 it->slice.y = XCAR (tem);
4123 if (tem = XCDR (tem), CONSP (tem))
4125 it->slice.width = XCAR (tem);
4126 if (tem = XCDR (tem), CONSP (tem))
4127 it->slice.height = XCAR (tem);
4132 return 0;
4135 /* Handle `(raise FACTOR)'. */
4136 if (CONSP (spec)
4137 && EQ (XCAR (spec), Qraise)
4138 && CONSP (XCDR (spec)))
4140 if (!FRAME_WINDOW_P (it->f))
4141 return 0;
4143 #ifdef HAVE_WINDOW_SYSTEM
4144 value = XCAR (XCDR (spec));
4145 if (NUMBERP (value))
4147 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4148 it->voffset = - (XFLOATINT (value)
4149 * (FONT_HEIGHT (face->font)));
4151 #endif /* HAVE_WINDOW_SYSTEM */
4153 return 0;
4156 /* Don't handle the other kinds of display specifications
4157 inside a string that we got from a `display' property. */
4158 if (it->string_from_display_prop_p)
4159 return 0;
4161 /* Characters having this form of property are not displayed, so
4162 we have to find the end of the property. */
4163 start_pos = *position;
4164 *position = display_prop_end (it, object, start_pos);
4165 value = Qnil;
4167 /* Stop the scan at that end position--we assume that all
4168 text properties change there. */
4169 it->stop_charpos = position->charpos;
4171 /* Handle `(left-fringe BITMAP [FACE])'
4172 and `(right-fringe BITMAP [FACE])'. */
4173 if (CONSP (spec)
4174 && (EQ (XCAR (spec), Qleft_fringe)
4175 || EQ (XCAR (spec), Qright_fringe))
4176 && CONSP (XCDR (spec)))
4178 int face_id = DEFAULT_FACE_ID;
4179 int fringe_bitmap;
4181 if (!FRAME_WINDOW_P (it->f))
4182 /* If we return here, POSITION has been advanced
4183 across the text with this property. */
4184 return 0;
4186 #ifdef HAVE_WINDOW_SYSTEM
4187 value = XCAR (XCDR (spec));
4188 if (!SYMBOLP (value)
4189 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
4190 /* If we return here, POSITION has been advanced
4191 across the text with this property. */
4192 return 0;
4194 if (CONSP (XCDR (XCDR (spec))))
4196 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
4197 int face_id2 = lookup_derived_face (it->f, face_name,
4198 'A', FRINGE_FACE_ID, 0);
4199 if (face_id2 >= 0)
4200 face_id = face_id2;
4203 /* Save current settings of IT so that we can restore them
4204 when we are finished with the glyph property value. */
4206 save_pos = it->position;
4207 it->position = *position;
4208 push_it (it);
4209 it->position = save_pos;
4211 it->area = TEXT_AREA;
4212 it->what = IT_IMAGE;
4213 it->image_id = -1; /* no image */
4214 it->position = start_pos;
4215 it->object = NILP (object) ? it->w->buffer : object;
4216 it->method = GET_FROM_IMAGE;
4217 it->from_overlay = Qnil;
4218 it->face_id = face_id;
4220 /* Say that we haven't consumed the characters with
4221 `display' property yet. The call to pop_it in
4222 set_iterator_to_next will clean this up. */
4223 *position = start_pos;
4225 if (EQ (XCAR (spec), Qleft_fringe))
4227 it->left_user_fringe_bitmap = fringe_bitmap;
4228 it->left_user_fringe_face_id = face_id;
4230 else
4232 it->right_user_fringe_bitmap = fringe_bitmap;
4233 it->right_user_fringe_face_id = face_id;
4235 #endif /* HAVE_WINDOW_SYSTEM */
4236 return 1;
4239 /* Prepare to handle `((margin left-margin) ...)',
4240 `((margin right-margin) ...)' and `((margin nil) ...)'
4241 prefixes for display specifications. */
4242 location = Qunbound;
4243 if (CONSP (spec) && CONSP (XCAR (spec)))
4245 Lisp_Object tem;
4247 value = XCDR (spec);
4248 if (CONSP (value))
4249 value = XCAR (value);
4251 tem = XCAR (spec);
4252 if (EQ (XCAR (tem), Qmargin)
4253 && (tem = XCDR (tem),
4254 tem = CONSP (tem) ? XCAR (tem) : Qnil,
4255 (NILP (tem)
4256 || EQ (tem, Qleft_margin)
4257 || EQ (tem, Qright_margin))))
4258 location = tem;
4261 if (EQ (location, Qunbound))
4263 location = Qnil;
4264 value = spec;
4267 /* After this point, VALUE is the property after any
4268 margin prefix has been stripped. It must be a string,
4269 an image specification, or `(space ...)'.
4271 LOCATION specifies where to display: `left-margin',
4272 `right-margin' or nil. */
4274 valid_p = (STRINGP (value)
4275 #ifdef HAVE_WINDOW_SYSTEM
4276 || (FRAME_WINDOW_P (it->f) && valid_image_p (value))
4277 #endif /* not HAVE_WINDOW_SYSTEM */
4278 || (CONSP (value) && EQ (XCAR (value), Qspace)));
4280 if (valid_p && !display_replaced_before_p)
4282 /* Save current settings of IT so that we can restore them
4283 when we are finished with the glyph property value. */
4284 save_pos = it->position;
4285 it->position = *position;
4286 push_it (it);
4287 it->position = save_pos;
4288 it->from_overlay = overlay;
4290 if (NILP (location))
4291 it->area = TEXT_AREA;
4292 else if (EQ (location, Qleft_margin))
4293 it->area = LEFT_MARGIN_AREA;
4294 else
4295 it->area = RIGHT_MARGIN_AREA;
4297 if (STRINGP (value))
4299 if (SCHARS (value) == 0)
4301 pop_it (it);
4302 return -1; /* Replaced by "", i.e. nothing. */
4304 it->string = value;
4305 it->multibyte_p = STRING_MULTIBYTE (it->string);
4306 it->current.overlay_string_index = -1;
4307 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4308 it->end_charpos = it->string_nchars = SCHARS (it->string);
4309 it->method = GET_FROM_STRING;
4310 it->stop_charpos = 0;
4311 it->string_from_display_prop_p = 1;
4312 /* Say that we haven't consumed the characters with
4313 `display' property yet. The call to pop_it in
4314 set_iterator_to_next will clean this up. */
4315 if (BUFFERP (object))
4316 it->current.pos = start_pos;
4318 else if (CONSP (value) && EQ (XCAR (value), Qspace))
4320 it->method = GET_FROM_STRETCH;
4321 it->object = value;
4322 it->position = start_pos;
4323 if (BUFFERP (object))
4324 it->current.pos = start_pos;
4326 #ifdef HAVE_WINDOW_SYSTEM
4327 else
4329 it->what = IT_IMAGE;
4330 it->image_id = lookup_image (it->f, value);
4331 it->position = start_pos;
4332 it->object = NILP (object) ? it->w->buffer : object;
4333 it->method = GET_FROM_IMAGE;
4335 /* Say that we haven't consumed the characters with
4336 `display' property yet. The call to pop_it in
4337 set_iterator_to_next will clean this up. */
4338 if (BUFFERP (object))
4339 it->current.pos = start_pos;
4341 #endif /* HAVE_WINDOW_SYSTEM */
4343 return 1;
4346 /* Invalid property or property not supported. Restore
4347 POSITION to what it was before. */
4348 *position = start_pos;
4349 return 0;
4353 /* Check if SPEC is a display sub-property value whose text should be
4354 treated as intangible. */
4356 static int
4357 single_display_spec_intangible_p (prop)
4358 Lisp_Object prop;
4360 /* Skip over `when FORM'. */
4361 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
4363 prop = XCDR (prop);
4364 if (!CONSP (prop))
4365 return 0;
4366 prop = XCDR (prop);
4369 if (STRINGP (prop))
4370 return 1;
4372 if (!CONSP (prop))
4373 return 0;
4375 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
4376 we don't need to treat text as intangible. */
4377 if (EQ (XCAR (prop), Qmargin))
4379 prop = XCDR (prop);
4380 if (!CONSP (prop))
4381 return 0;
4383 prop = XCDR (prop);
4384 if (!CONSP (prop)
4385 || EQ (XCAR (prop), Qleft_margin)
4386 || EQ (XCAR (prop), Qright_margin))
4387 return 0;
4390 return (CONSP (prop)
4391 && (EQ (XCAR (prop), Qimage)
4392 || EQ (XCAR (prop), Qspace)));
4396 /* Check if PROP is a display property value whose text should be
4397 treated as intangible. */
4400 display_prop_intangible_p (prop)
4401 Lisp_Object prop;
4403 if (CONSP (prop)
4404 && CONSP (XCAR (prop))
4405 && !EQ (Qmargin, XCAR (XCAR (prop))))
4407 /* A list of sub-properties. */
4408 while (CONSP (prop))
4410 if (single_display_spec_intangible_p (XCAR (prop)))
4411 return 1;
4412 prop = XCDR (prop);
4415 else if (VECTORP (prop))
4417 /* A vector of sub-properties. */
4418 int i;
4419 for (i = 0; i < ASIZE (prop); ++i)
4420 if (single_display_spec_intangible_p (AREF (prop, i)))
4421 return 1;
4423 else
4424 return single_display_spec_intangible_p (prop);
4426 return 0;
4430 /* Return 1 if PROP is a display sub-property value containing STRING. */
4432 static int
4433 single_display_spec_string_p (prop, string)
4434 Lisp_Object prop, string;
4436 if (EQ (string, prop))
4437 return 1;
4439 /* Skip over `when FORM'. */
4440 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
4442 prop = XCDR (prop);
4443 if (!CONSP (prop))
4444 return 0;
4445 prop = XCDR (prop);
4448 if (CONSP (prop))
4449 /* Skip over `margin LOCATION'. */
4450 if (EQ (XCAR (prop), Qmargin))
4452 prop = XCDR (prop);
4453 if (!CONSP (prop))
4454 return 0;
4456 prop = XCDR (prop);
4457 if (!CONSP (prop))
4458 return 0;
4461 return CONSP (prop) && EQ (XCAR (prop), string);
4465 /* Return 1 if STRING appears in the `display' property PROP. */
4467 static int
4468 display_prop_string_p (prop, string)
4469 Lisp_Object prop, string;
4471 if (CONSP (prop)
4472 && CONSP (XCAR (prop))
4473 && !EQ (Qmargin, XCAR (XCAR (prop))))
4475 /* A list of sub-properties. */
4476 while (CONSP (prop))
4478 if (single_display_spec_string_p (XCAR (prop), string))
4479 return 1;
4480 prop = XCDR (prop);
4483 else if (VECTORP (prop))
4485 /* A vector of sub-properties. */
4486 int i;
4487 for (i = 0; i < ASIZE (prop); ++i)
4488 if (single_display_spec_string_p (AREF (prop, i), string))
4489 return 1;
4491 else
4492 return single_display_spec_string_p (prop, string);
4494 return 0;
4498 /* Determine from which buffer position in W's buffer STRING comes
4499 from. AROUND_CHARPOS is an approximate position where it could
4500 be from. Value is the buffer position or 0 if it couldn't be
4501 determined.
4503 W's buffer must be current.
4505 This function is necessary because we don't record buffer positions
4506 in glyphs generated from strings (to keep struct glyph small).
4507 This function may only use code that doesn't eval because it is
4508 called asynchronously from note_mouse_highlight. */
4511 string_buffer_position (w, string, around_charpos)
4512 struct window *w;
4513 Lisp_Object string;
4514 int around_charpos;
4516 Lisp_Object limit, prop, pos;
4517 const int MAX_DISTANCE = 1000;
4518 int found = 0;
4520 pos = make_number (around_charpos);
4521 limit = make_number (min (XINT (pos) + MAX_DISTANCE, ZV));
4522 while (!found && !EQ (pos, limit))
4524 prop = Fget_char_property (pos, Qdisplay, Qnil);
4525 if (!NILP (prop) && display_prop_string_p (prop, string))
4526 found = 1;
4527 else
4528 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil, limit);
4531 if (!found)
4533 pos = make_number (around_charpos);
4534 limit = make_number (max (XINT (pos) - MAX_DISTANCE, BEGV));
4535 while (!found && !EQ (pos, limit))
4537 prop = Fget_char_property (pos, Qdisplay, Qnil);
4538 if (!NILP (prop) && display_prop_string_p (prop, string))
4539 found = 1;
4540 else
4541 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
4542 limit);
4546 return found ? XINT (pos) : 0;
4551 /***********************************************************************
4552 `composition' property
4553 ***********************************************************************/
4555 /* Set up iterator IT from `composition' property at its current
4556 position. Called from handle_stop. */
4558 static enum prop_handled
4559 handle_composition_prop (it)
4560 struct it *it;
4562 Lisp_Object prop, string;
4563 int pos, pos_byte, end;
4564 enum prop_handled handled = HANDLED_NORMALLY;
4566 if (STRINGP (it->string))
4568 pos = IT_STRING_CHARPOS (*it);
4569 pos_byte = IT_STRING_BYTEPOS (*it);
4570 string = it->string;
4572 else
4574 pos = IT_CHARPOS (*it);
4575 pos_byte = IT_BYTEPOS (*it);
4576 string = Qnil;
4579 /* If there's a valid composition and point is not inside of the
4580 composition (in the case that the composition is from the current
4581 buffer), draw a glyph composed from the composition components. */
4582 if (find_composition (pos, -1, &pos, &end, &prop, string)
4583 && COMPOSITION_VALID_P (pos, end, prop)
4584 && (STRINGP (it->string) || (PT <= pos || PT >= end)))
4586 int id = get_composition_id (pos, pos_byte, end - pos, prop, string);
4588 if (id >= 0)
4590 struct composition *cmp = composition_table[id];
4592 if (cmp->glyph_len == 0)
4594 /* No glyph. */
4595 if (STRINGP (it->string))
4597 IT_STRING_CHARPOS (*it) = end;
4598 IT_STRING_BYTEPOS (*it) = string_char_to_byte (it->string,
4599 end);
4601 else
4603 IT_CHARPOS (*it) = end;
4604 IT_BYTEPOS (*it) = CHAR_TO_BYTE (end);
4606 return HANDLED_RECOMPUTE_PROPS;
4609 it->stop_charpos = end;
4610 push_it (it);
4612 it->method = GET_FROM_COMPOSITION;
4613 it->cmp_id = id;
4614 it->cmp_len = COMPOSITION_LENGTH (prop);
4615 /* For a terminal, draw only the first character of the
4616 components. */
4617 it->c = COMPOSITION_GLYPH (composition_table[id], 0);
4618 it->len = (STRINGP (it->string)
4619 ? string_char_to_byte (it->string, end)
4620 : CHAR_TO_BYTE (end)) - pos_byte;
4621 handled = HANDLED_RETURN;
4625 return handled;
4630 /***********************************************************************
4631 Overlay strings
4632 ***********************************************************************/
4634 /* The following structure is used to record overlay strings for
4635 later sorting in load_overlay_strings. */
4637 struct overlay_entry
4639 Lisp_Object overlay;
4640 Lisp_Object string;
4641 int priority;
4642 int after_string_p;
4646 /* Set up iterator IT from overlay strings at its current position.
4647 Called from handle_stop. */
4649 static enum prop_handled
4650 handle_overlay_change (it)
4651 struct it *it;
4653 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
4654 return HANDLED_RECOMPUTE_PROPS;
4655 else
4656 return HANDLED_NORMALLY;
4660 /* Set up the next overlay string for delivery by IT, if there is an
4661 overlay string to deliver. Called by set_iterator_to_next when the
4662 end of the current overlay string is reached. If there are more
4663 overlay strings to display, IT->string and
4664 IT->current.overlay_string_index are set appropriately here.
4665 Otherwise IT->string is set to nil. */
4667 static void
4668 next_overlay_string (it)
4669 struct it *it;
4671 ++it->current.overlay_string_index;
4672 if (it->current.overlay_string_index == it->n_overlay_strings)
4674 /* No more overlay strings. Restore IT's settings to what
4675 they were before overlay strings were processed, and
4676 continue to deliver from current_buffer. */
4677 int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
4679 pop_it (it);
4680 xassert (it->sp > 0
4681 || it->method == GET_FROM_COMPOSITION
4682 || (NILP (it->string)
4683 && it->method == GET_FROM_BUFFER
4684 && it->stop_charpos >= BEGV
4685 && it->stop_charpos <= it->end_charpos));
4686 it->current.overlay_string_index = -1;
4687 it->n_overlay_strings = 0;
4689 /* If we're at the end of the buffer, record that we have
4690 processed the overlay strings there already, so that
4691 next_element_from_buffer doesn't try it again. */
4692 if (IT_CHARPOS (*it) >= it->end_charpos)
4693 it->overlay_strings_at_end_processed_p = 1;
4695 /* If we have to display `...' for invisible text, set
4696 the iterator up for that. */
4697 if (display_ellipsis_p)
4698 setup_for_ellipsis (it, 0);
4700 else
4702 /* There are more overlay strings to process. If
4703 IT->current.overlay_string_index has advanced to a position
4704 where we must load IT->overlay_strings with more strings, do
4705 it. */
4706 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
4708 if (it->current.overlay_string_index && i == 0)
4709 load_overlay_strings (it, 0);
4711 /* Initialize IT to deliver display elements from the overlay
4712 string. */
4713 it->string = it->overlay_strings[i];
4714 it->multibyte_p = STRING_MULTIBYTE (it->string);
4715 SET_TEXT_POS (it->current.string_pos, 0, 0);
4716 it->method = GET_FROM_STRING;
4717 it->stop_charpos = 0;
4720 CHECK_IT (it);
4724 /* Compare two overlay_entry structures E1 and E2. Used as a
4725 comparison function for qsort in load_overlay_strings. Overlay
4726 strings for the same position are sorted so that
4728 1. All after-strings come in front of before-strings, except
4729 when they come from the same overlay.
4731 2. Within after-strings, strings are sorted so that overlay strings
4732 from overlays with higher priorities come first.
4734 2. Within before-strings, strings are sorted so that overlay
4735 strings from overlays with higher priorities come last.
4737 Value is analogous to strcmp. */
4740 static int
4741 compare_overlay_entries (e1, e2)
4742 void *e1, *e2;
4744 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4745 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4746 int result;
4748 if (entry1->after_string_p != entry2->after_string_p)
4750 /* Let after-strings appear in front of before-strings if
4751 they come from different overlays. */
4752 if (EQ (entry1->overlay, entry2->overlay))
4753 result = entry1->after_string_p ? 1 : -1;
4754 else
4755 result = entry1->after_string_p ? -1 : 1;
4757 else if (entry1->after_string_p)
4758 /* After-strings sorted in order of decreasing priority. */
4759 result = entry2->priority - entry1->priority;
4760 else
4761 /* Before-strings sorted in order of increasing priority. */
4762 result = entry1->priority - entry2->priority;
4764 return result;
4768 /* Load the vector IT->overlay_strings with overlay strings from IT's
4769 current buffer position, or from CHARPOS if that is > 0. Set
4770 IT->n_overlays to the total number of overlay strings found.
4772 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4773 a time. On entry into load_overlay_strings,
4774 IT->current.overlay_string_index gives the number of overlay
4775 strings that have already been loaded by previous calls to this
4776 function.
4778 IT->add_overlay_start contains an additional overlay start
4779 position to consider for taking overlay strings from, if non-zero.
4780 This position comes into play when the overlay has an `invisible'
4781 property, and both before and after-strings. When we've skipped to
4782 the end of the overlay, because of its `invisible' property, we
4783 nevertheless want its before-string to appear.
4784 IT->add_overlay_start will contain the overlay start position
4785 in this case.
4787 Overlay strings are sorted so that after-string strings come in
4788 front of before-string strings. Within before and after-strings,
4789 strings are sorted by overlay priority. See also function
4790 compare_overlay_entries. */
4792 static void
4793 load_overlay_strings (it, charpos)
4794 struct it *it;
4795 int charpos;
4797 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
4798 Lisp_Object overlay, window, str, invisible;
4799 struct Lisp_Overlay *ov;
4800 int start, end;
4801 int size = 20;
4802 int n = 0, i, j, invis_p;
4803 struct overlay_entry *entries
4804 = (struct overlay_entry *) alloca (size * sizeof *entries);
4806 if (charpos <= 0)
4807 charpos = IT_CHARPOS (*it);
4809 /* Append the overlay string STRING of overlay OVERLAY to vector
4810 `entries' which has size `size' and currently contains `n'
4811 elements. AFTER_P non-zero means STRING is an after-string of
4812 OVERLAY. */
4813 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4814 do \
4816 Lisp_Object priority; \
4818 if (n == size) \
4820 int new_size = 2 * size; \
4821 struct overlay_entry *old = entries; \
4822 entries = \
4823 (struct overlay_entry *) alloca (new_size \
4824 * sizeof *entries); \
4825 bcopy (old, entries, size * sizeof *entries); \
4826 size = new_size; \
4829 entries[n].string = (STRING); \
4830 entries[n].overlay = (OVERLAY); \
4831 priority = Foverlay_get ((OVERLAY), Qpriority); \
4832 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4833 entries[n].after_string_p = (AFTER_P); \
4834 ++n; \
4836 while (0)
4838 /* Process overlay before the overlay center. */
4839 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4841 XSETMISC (overlay, ov);
4842 xassert (OVERLAYP (overlay));
4843 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4844 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4846 if (end < charpos)
4847 break;
4849 /* Skip this overlay if it doesn't start or end at IT's current
4850 position. */
4851 if (end != charpos && start != charpos)
4852 continue;
4854 /* Skip this overlay if it doesn't apply to IT->w. */
4855 window = Foverlay_get (overlay, Qwindow);
4856 if (WINDOWP (window) && XWINDOW (window) != it->w)
4857 continue;
4859 /* If the text ``under'' the overlay is invisible, both before-
4860 and after-strings from this overlay are visible; start and
4861 end position are indistinguishable. */
4862 invisible = Foverlay_get (overlay, Qinvisible);
4863 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4865 /* If overlay has a non-empty before-string, record it. */
4866 if ((start == charpos || (end == charpos && invis_p))
4867 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4868 && SCHARS (str))
4869 RECORD_OVERLAY_STRING (overlay, str, 0);
4871 /* If overlay has a non-empty after-string, record it. */
4872 if ((end == charpos || (start == charpos && invis_p))
4873 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4874 && SCHARS (str))
4875 RECORD_OVERLAY_STRING (overlay, str, 1);
4878 /* Process overlays after the overlay center. */
4879 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
4881 XSETMISC (overlay, ov);
4882 xassert (OVERLAYP (overlay));
4883 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4884 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4886 if (start > charpos)
4887 break;
4889 /* Skip this overlay if it doesn't start or end at IT's current
4890 position. */
4891 if (end != charpos && start != charpos)
4892 continue;
4894 /* Skip this overlay if it doesn't apply to IT->w. */
4895 window = Foverlay_get (overlay, Qwindow);
4896 if (WINDOWP (window) && XWINDOW (window) != it->w)
4897 continue;
4899 /* If the text ``under'' the overlay is invisible, it has a zero
4900 dimension, and both before- and after-strings apply. */
4901 invisible = Foverlay_get (overlay, Qinvisible);
4902 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4904 /* If overlay has a non-empty before-string, record it. */
4905 if ((start == charpos || (end == charpos && invis_p))
4906 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4907 && SCHARS (str))
4908 RECORD_OVERLAY_STRING (overlay, str, 0);
4910 /* If overlay has a non-empty after-string, record it. */
4911 if ((end == charpos || (start == charpos && invis_p))
4912 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4913 && SCHARS (str))
4914 RECORD_OVERLAY_STRING (overlay, str, 1);
4917 #undef RECORD_OVERLAY_STRING
4919 /* Sort entries. */
4920 if (n > 1)
4921 qsort (entries, n, sizeof *entries, compare_overlay_entries);
4923 /* Record the total number of strings to process. */
4924 it->n_overlay_strings = n;
4926 /* IT->current.overlay_string_index is the number of overlay strings
4927 that have already been consumed by IT. Copy some of the
4928 remaining overlay strings to IT->overlay_strings. */
4929 i = 0;
4930 j = it->current.overlay_string_index;
4931 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
4933 it->overlay_strings[i] = entries[j].string;
4934 it->string_overlays[i++] = entries[j++].overlay;
4937 CHECK_IT (it);
4941 /* Get the first chunk of overlay strings at IT's current buffer
4942 position, or at CHARPOS if that is > 0. Value is non-zero if at
4943 least one overlay string was found. */
4945 static int
4946 get_overlay_strings_1 (it, charpos, compute_stop_p)
4947 struct it *it;
4948 int charpos;
4950 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4951 process. This fills IT->overlay_strings with strings, and sets
4952 IT->n_overlay_strings to the total number of strings to process.
4953 IT->pos.overlay_string_index has to be set temporarily to zero
4954 because load_overlay_strings needs this; it must be set to -1
4955 when no overlay strings are found because a zero value would
4956 indicate a position in the first overlay string. */
4957 it->current.overlay_string_index = 0;
4958 load_overlay_strings (it, charpos);
4960 /* If we found overlay strings, set up IT to deliver display
4961 elements from the first one. Otherwise set up IT to deliver
4962 from current_buffer. */
4963 if (it->n_overlay_strings)
4965 /* Make sure we know settings in current_buffer, so that we can
4966 restore meaningful values when we're done with the overlay
4967 strings. */
4968 if (compute_stop_p)
4969 compute_stop_pos (it);
4970 xassert (it->face_id >= 0);
4972 /* Save IT's settings. They are restored after all overlay
4973 strings have been processed. */
4974 xassert (!compute_stop_p || it->sp == 0);
4975 push_it (it);
4977 /* Set up IT to deliver display elements from the first overlay
4978 string. */
4979 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4980 it->string = it->overlay_strings[0];
4981 it->from_overlay = Qnil;
4982 it->stop_charpos = 0;
4983 xassert (STRINGP (it->string));
4984 it->end_charpos = SCHARS (it->string);
4985 it->multibyte_p = STRING_MULTIBYTE (it->string);
4986 it->method = GET_FROM_STRING;
4987 return 1;
4990 it->current.overlay_string_index = -1;
4991 return 0;
4994 static int
4995 get_overlay_strings (it, charpos)
4996 struct it *it;
4997 int charpos;
4999 it->string = Qnil;
5000 it->method = GET_FROM_BUFFER;
5002 (void) get_overlay_strings_1 (it, charpos, 1);
5004 CHECK_IT (it);
5006 /* Value is non-zero if we found at least one overlay string. */
5007 return STRINGP (it->string);
5012 /***********************************************************************
5013 Saving and restoring state
5014 ***********************************************************************/
5016 /* Save current settings of IT on IT->stack. Called, for example,
5017 before setting up IT for an overlay string, to be able to restore
5018 IT's settings to what they were after the overlay string has been
5019 processed. */
5021 static void
5022 push_it (it)
5023 struct it *it;
5025 struct iterator_stack_entry *p;
5027 xassert (it->sp < IT_STACK_SIZE);
5028 p = it->stack + it->sp;
5030 p->stop_charpos = it->stop_charpos;
5031 xassert (it->face_id >= 0);
5032 p->face_id = it->face_id;
5033 p->string = it->string;
5034 p->method = it->method;
5035 p->from_overlay = it->from_overlay;
5036 switch (p->method)
5038 case GET_FROM_IMAGE:
5039 p->u.image.object = it->object;
5040 p->u.image.image_id = it->image_id;
5041 p->u.image.slice = it->slice;
5042 break;
5043 case GET_FROM_COMPOSITION:
5044 p->u.comp.object = it->object;
5045 p->u.comp.c = it->c;
5046 p->u.comp.len = it->len;
5047 p->u.comp.cmp_id = it->cmp_id;
5048 p->u.comp.cmp_len = it->cmp_len;
5049 break;
5050 case GET_FROM_STRETCH:
5051 p->u.stretch.object = it->object;
5052 break;
5054 p->position = it->position;
5055 p->current = it->current;
5056 p->end_charpos = it->end_charpos;
5057 p->string_nchars = it->string_nchars;
5058 p->area = it->area;
5059 p->multibyte_p = it->multibyte_p;
5060 p->space_width = it->space_width;
5061 p->font_height = it->font_height;
5062 p->voffset = it->voffset;
5063 p->string_from_display_prop_p = it->string_from_display_prop_p;
5064 p->display_ellipsis_p = 0;
5065 ++it->sp;
5069 /* Restore IT's settings from IT->stack. Called, for example, when no
5070 more overlay strings must be processed, and we return to delivering
5071 display elements from a buffer, or when the end of a string from a
5072 `display' property is reached and we return to delivering display
5073 elements from an overlay string, or from a buffer. */
5075 static void
5076 pop_it (it)
5077 struct it *it;
5079 struct iterator_stack_entry *p;
5081 xassert (it->sp > 0);
5082 --it->sp;
5083 p = it->stack + it->sp;
5084 it->stop_charpos = p->stop_charpos;
5085 it->face_id = p->face_id;
5086 it->current = p->current;
5087 it->position = p->position;
5088 it->string = p->string;
5089 it->from_overlay = p->from_overlay;
5090 if (NILP (it->string))
5091 SET_TEXT_POS (it->current.string_pos, -1, -1);
5092 it->method = p->method;
5093 switch (it->method)
5095 case GET_FROM_IMAGE:
5096 it->image_id = p->u.image.image_id;
5097 it->object = p->u.image.object;
5098 it->slice = p->u.image.slice;
5099 break;
5100 case GET_FROM_COMPOSITION:
5101 it->object = p->u.comp.object;
5102 it->c = p->u.comp.c;
5103 it->len = p->u.comp.len;
5104 it->cmp_id = p->u.comp.cmp_id;
5105 it->cmp_len = p->u.comp.cmp_len;
5106 break;
5107 case GET_FROM_STRETCH:
5108 it->object = p->u.comp.object;
5109 break;
5110 case GET_FROM_BUFFER:
5111 it->object = it->w->buffer;
5112 break;
5113 case GET_FROM_STRING:
5114 it->object = it->string;
5115 break;
5117 it->end_charpos = p->end_charpos;
5118 it->string_nchars = p->string_nchars;
5119 it->area = p->area;
5120 it->multibyte_p = p->multibyte_p;
5121 it->space_width = p->space_width;
5122 it->font_height = p->font_height;
5123 it->voffset = p->voffset;
5124 it->string_from_display_prop_p = p->string_from_display_prop_p;
5129 /***********************************************************************
5130 Moving over lines
5131 ***********************************************************************/
5133 /* Set IT's current position to the previous line start. */
5135 static void
5136 back_to_previous_line_start (it)
5137 struct it *it;
5139 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
5140 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
5144 /* Move IT to the next line start.
5146 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
5147 we skipped over part of the text (as opposed to moving the iterator
5148 continuously over the text). Otherwise, don't change the value
5149 of *SKIPPED_P.
5151 Newlines may come from buffer text, overlay strings, or strings
5152 displayed via the `display' property. That's the reason we can't
5153 simply use find_next_newline_no_quit.
5155 Note that this function may not skip over invisible text that is so
5156 because of text properties and immediately follows a newline. If
5157 it would, function reseat_at_next_visible_line_start, when called
5158 from set_iterator_to_next, would effectively make invisible
5159 characters following a newline part of the wrong glyph row, which
5160 leads to wrong cursor motion. */
5162 static int
5163 forward_to_next_line_start (it, skipped_p)
5164 struct it *it;
5165 int *skipped_p;
5167 int old_selective, newline_found_p, n;
5168 const int MAX_NEWLINE_DISTANCE = 500;
5170 /* If already on a newline, just consume it to avoid unintended
5171 skipping over invisible text below. */
5172 if (it->what == IT_CHARACTER
5173 && it->c == '\n'
5174 && CHARPOS (it->position) == IT_CHARPOS (*it))
5176 set_iterator_to_next (it, 0);
5177 it->c = 0;
5178 return 1;
5181 /* Don't handle selective display in the following. It's (a)
5182 unnecessary because it's done by the caller, and (b) leads to an
5183 infinite recursion because next_element_from_ellipsis indirectly
5184 calls this function. */
5185 old_selective = it->selective;
5186 it->selective = 0;
5188 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
5189 from buffer text. */
5190 for (n = newline_found_p = 0;
5191 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
5192 n += STRINGP (it->string) ? 0 : 1)
5194 if (!get_next_display_element (it))
5195 return 0;
5196 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
5197 set_iterator_to_next (it, 0);
5200 /* If we didn't find a newline near enough, see if we can use a
5201 short-cut. */
5202 if (!newline_found_p)
5204 int start = IT_CHARPOS (*it);
5205 int limit = find_next_newline_no_quit (start, 1);
5206 Lisp_Object pos;
5208 xassert (!STRINGP (it->string));
5210 /* If there isn't any `display' property in sight, and no
5211 overlays, we can just use the position of the newline in
5212 buffer text. */
5213 if (it->stop_charpos >= limit
5214 || ((pos = Fnext_single_property_change (make_number (start),
5215 Qdisplay,
5216 Qnil, make_number (limit)),
5217 NILP (pos))
5218 && next_overlay_change (start) == ZV))
5220 IT_CHARPOS (*it) = limit;
5221 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
5222 *skipped_p = newline_found_p = 1;
5224 else
5226 while (get_next_display_element (it)
5227 && !newline_found_p)
5229 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
5230 set_iterator_to_next (it, 0);
5235 it->selective = old_selective;
5236 return newline_found_p;
5240 /* Set IT's current position to the previous visible line start. Skip
5241 invisible text that is so either due to text properties or due to
5242 selective display. Caution: this does not change IT->current_x and
5243 IT->hpos. */
5245 static void
5246 back_to_previous_visible_line_start (it)
5247 struct it *it;
5249 while (IT_CHARPOS (*it) > BEGV)
5251 back_to_previous_line_start (it);
5253 if (IT_CHARPOS (*it) <= BEGV)
5254 break;
5256 /* If selective > 0, then lines indented more than that values
5257 are invisible. */
5258 if (it->selective > 0
5259 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5260 (double) it->selective)) /* iftc */
5261 continue;
5263 /* Check the newline before point for invisibility. */
5265 Lisp_Object prop;
5266 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
5267 Qinvisible, it->window);
5268 if (TEXT_PROP_MEANS_INVISIBLE (prop))
5269 continue;
5272 if (IT_CHARPOS (*it) <= BEGV)
5273 break;
5276 struct it it2;
5277 int pos;
5278 int beg, end;
5279 Lisp_Object val, overlay;
5281 /* If newline is part of a composition, continue from start of composition */
5282 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
5283 && beg < IT_CHARPOS (*it))
5284 goto replaced;
5286 /* If newline is replaced by a display property, find start of overlay
5287 or interval and continue search from that point. */
5288 it2 = *it;
5289 pos = --IT_CHARPOS (it2);
5290 --IT_BYTEPOS (it2);
5291 it2.sp = 0;
5292 if (handle_display_prop (&it2) == HANDLED_RETURN
5293 && !NILP (val = get_char_property_and_overlay
5294 (make_number (pos), Qdisplay, Qnil, &overlay))
5295 && (OVERLAYP (overlay)
5296 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
5297 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
5298 goto replaced;
5300 /* Newline is not replaced by anything -- so we are done. */
5301 break;
5303 replaced:
5304 if (beg < BEGV)
5305 beg = BEGV;
5306 IT_CHARPOS (*it) = beg;
5307 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
5311 it->continuation_lines_width = 0;
5313 xassert (IT_CHARPOS (*it) >= BEGV);
5314 xassert (IT_CHARPOS (*it) == BEGV
5315 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5316 CHECK_IT (it);
5320 /* Reseat iterator IT at the previous visible line start. Skip
5321 invisible text that is so either due to text properties or due to
5322 selective display. At the end, update IT's overlay information,
5323 face information etc. */
5325 void
5326 reseat_at_previous_visible_line_start (it)
5327 struct it *it;
5329 back_to_previous_visible_line_start (it);
5330 reseat (it, it->current.pos, 1);
5331 CHECK_IT (it);
5335 /* Reseat iterator IT on the next visible line start in the current
5336 buffer. ON_NEWLINE_P non-zero means position IT on the newline
5337 preceding the line start. Skip over invisible text that is so
5338 because of selective display. Compute faces, overlays etc at the
5339 new position. Note that this function does not skip over text that
5340 is invisible because of text properties. */
5342 static void
5343 reseat_at_next_visible_line_start (it, on_newline_p)
5344 struct it *it;
5345 int on_newline_p;
5347 int newline_found_p, skipped_p = 0;
5349 newline_found_p = forward_to_next_line_start (it, &skipped_p);
5351 /* Skip over lines that are invisible because they are indented
5352 more than the value of IT->selective. */
5353 if (it->selective > 0)
5354 while (IT_CHARPOS (*it) < ZV
5355 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5356 (double) it->selective)) /* iftc */
5358 xassert (IT_BYTEPOS (*it) == BEGV
5359 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5360 newline_found_p = forward_to_next_line_start (it, &skipped_p);
5363 /* Position on the newline if that's what's requested. */
5364 if (on_newline_p && newline_found_p)
5366 if (STRINGP (it->string))
5368 if (IT_STRING_CHARPOS (*it) > 0)
5370 --IT_STRING_CHARPOS (*it);
5371 --IT_STRING_BYTEPOS (*it);
5374 else if (IT_CHARPOS (*it) > BEGV)
5376 --IT_CHARPOS (*it);
5377 --IT_BYTEPOS (*it);
5378 reseat (it, it->current.pos, 0);
5381 else if (skipped_p)
5382 reseat (it, it->current.pos, 0);
5384 CHECK_IT (it);
5389 /***********************************************************************
5390 Changing an iterator's position
5391 ***********************************************************************/
5393 /* Change IT's current position to POS in current_buffer. If FORCE_P
5394 is non-zero, always check for text properties at the new position.
5395 Otherwise, text properties are only looked up if POS >=
5396 IT->check_charpos of a property. */
5398 static void
5399 reseat (it, pos, force_p)
5400 struct it *it;
5401 struct text_pos pos;
5402 int force_p;
5404 int original_pos = IT_CHARPOS (*it);
5406 reseat_1 (it, pos, 0);
5408 /* Determine where to check text properties. Avoid doing it
5409 where possible because text property lookup is very expensive. */
5410 if (force_p
5411 || CHARPOS (pos) > it->stop_charpos
5412 || CHARPOS (pos) < original_pos)
5413 handle_stop (it);
5415 CHECK_IT (it);
5419 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
5420 IT->stop_pos to POS, also. */
5422 static void
5423 reseat_1 (it, pos, set_stop_p)
5424 struct it *it;
5425 struct text_pos pos;
5426 int set_stop_p;
5428 /* Don't call this function when scanning a C string. */
5429 xassert (it->s == NULL);
5431 /* POS must be a reasonable value. */
5432 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
5434 it->current.pos = it->position = pos;
5435 it->end_charpos = ZV;
5436 it->dpvec = NULL;
5437 it->current.dpvec_index = -1;
5438 it->current.overlay_string_index = -1;
5439 IT_STRING_CHARPOS (*it) = -1;
5440 IT_STRING_BYTEPOS (*it) = -1;
5441 it->string = Qnil;
5442 it->method = GET_FROM_BUFFER;
5443 it->object = it->w->buffer;
5444 it->area = TEXT_AREA;
5445 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
5446 it->sp = 0;
5447 it->string_from_display_prop_p = 0;
5448 it->face_before_selective_p = 0;
5450 if (set_stop_p)
5451 it->stop_charpos = CHARPOS (pos);
5455 /* Set up IT for displaying a string, starting at CHARPOS in window W.
5456 If S is non-null, it is a C string to iterate over. Otherwise,
5457 STRING gives a Lisp string to iterate over.
5459 If PRECISION > 0, don't return more then PRECISION number of
5460 characters from the string.
5462 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
5463 characters have been returned. FIELD_WIDTH < 0 means an infinite
5464 field width.
5466 MULTIBYTE = 0 means disable processing of multibyte characters,
5467 MULTIBYTE > 0 means enable it,
5468 MULTIBYTE < 0 means use IT->multibyte_p.
5470 IT must be initialized via a prior call to init_iterator before
5471 calling this function. */
5473 static void
5474 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
5475 struct it *it;
5476 unsigned char *s;
5477 Lisp_Object string;
5478 int charpos;
5479 int precision, field_width, multibyte;
5481 /* No region in strings. */
5482 it->region_beg_charpos = it->region_end_charpos = -1;
5484 /* No text property checks performed by default, but see below. */
5485 it->stop_charpos = -1;
5487 /* Set iterator position and end position. */
5488 bzero (&it->current, sizeof it->current);
5489 it->current.overlay_string_index = -1;
5490 it->current.dpvec_index = -1;
5491 xassert (charpos >= 0);
5493 /* If STRING is specified, use its multibyteness, otherwise use the
5494 setting of MULTIBYTE, if specified. */
5495 if (multibyte >= 0)
5496 it->multibyte_p = multibyte > 0;
5498 if (s == NULL)
5500 xassert (STRINGP (string));
5501 it->string = string;
5502 it->s = NULL;
5503 it->end_charpos = it->string_nchars = SCHARS (string);
5504 it->method = GET_FROM_STRING;
5505 it->current.string_pos = string_pos (charpos, string);
5507 else
5509 it->s = s;
5510 it->string = Qnil;
5512 /* Note that we use IT->current.pos, not it->current.string_pos,
5513 for displaying C strings. */
5514 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
5515 if (it->multibyte_p)
5517 it->current.pos = c_string_pos (charpos, s, 1);
5518 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
5520 else
5522 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
5523 it->end_charpos = it->string_nchars = strlen (s);
5526 it->method = GET_FROM_C_STRING;
5529 /* PRECISION > 0 means don't return more than PRECISION characters
5530 from the string. */
5531 if (precision > 0 && it->end_charpos - charpos > precision)
5532 it->end_charpos = it->string_nchars = charpos + precision;
5534 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
5535 characters have been returned. FIELD_WIDTH == 0 means don't pad,
5536 FIELD_WIDTH < 0 means infinite field width. This is useful for
5537 padding with `-' at the end of a mode line. */
5538 if (field_width < 0)
5539 field_width = INFINITY;
5540 if (field_width > it->end_charpos - charpos)
5541 it->end_charpos = charpos + field_width;
5543 /* Use the standard display table for displaying strings. */
5544 if (DISP_TABLE_P (Vstandard_display_table))
5545 it->dp = XCHAR_TABLE (Vstandard_display_table);
5547 it->stop_charpos = charpos;
5548 CHECK_IT (it);
5553 /***********************************************************************
5554 Iteration
5555 ***********************************************************************/
5557 /* Map enum it_method value to corresponding next_element_from_* function. */
5559 static int (* get_next_element[NUM_IT_METHODS]) P_ ((struct it *it)) =
5561 next_element_from_buffer,
5562 next_element_from_display_vector,
5563 next_element_from_composition,
5564 next_element_from_string,
5565 next_element_from_c_string,
5566 next_element_from_image,
5567 next_element_from_stretch
5571 /* Load IT's display element fields with information about the next
5572 display element from the current position of IT. Value is zero if
5573 end of buffer (or C string) is reached. */
5575 static struct frame *last_escape_glyph_frame = NULL;
5576 static unsigned last_escape_glyph_face_id = (1 << FACE_ID_BITS);
5577 static int last_escape_glyph_merged_face_id = 0;
5580 get_next_display_element (it)
5581 struct it *it;
5583 /* Non-zero means that we found a display element. Zero means that
5584 we hit the end of what we iterate over. Performance note: the
5585 function pointer `method' used here turns out to be faster than
5586 using a sequence of if-statements. */
5587 int success_p;
5589 get_next:
5590 success_p = (*get_next_element[it->method]) (it);
5592 if (it->what == IT_CHARACTER)
5594 /* Map via display table or translate control characters.
5595 IT->c, IT->len etc. have been set to the next character by
5596 the function call above. If we have a display table, and it
5597 contains an entry for IT->c, translate it. Don't do this if
5598 IT->c itself comes from a display table, otherwise we could
5599 end up in an infinite recursion. (An alternative could be to
5600 count the recursion depth of this function and signal an
5601 error when a certain maximum depth is reached.) Is it worth
5602 it? */
5603 if (success_p && it->dpvec == NULL)
5605 Lisp_Object dv;
5607 if (it->dp
5608 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
5609 VECTORP (dv)))
5611 struct Lisp_Vector *v = XVECTOR (dv);
5613 /* Return the first character from the display table
5614 entry, if not empty. If empty, don't display the
5615 current character. */
5616 if (v->size)
5618 it->dpvec_char_len = it->len;
5619 it->dpvec = v->contents;
5620 it->dpend = v->contents + v->size;
5621 it->current.dpvec_index = 0;
5622 it->dpvec_face_id = -1;
5623 it->saved_face_id = it->face_id;
5624 it->method = GET_FROM_DISPLAY_VECTOR;
5625 it->ellipsis_p = 0;
5627 else
5629 set_iterator_to_next (it, 0);
5631 goto get_next;
5634 /* Translate control characters into `\003' or `^C' form.
5635 Control characters coming from a display table entry are
5636 currently not translated because we use IT->dpvec to hold
5637 the translation. This could easily be changed but I
5638 don't believe that it is worth doing.
5640 If it->multibyte_p is nonzero, eight-bit characters and
5641 non-printable multibyte characters are also translated to
5642 octal form.
5644 If it->multibyte_p is zero, eight-bit characters that
5645 don't have corresponding multibyte char code are also
5646 translated to octal form. */
5647 else if ((it->c < ' '
5648 && (it->area != TEXT_AREA
5649 /* In mode line, treat \n like other crl chars. */
5650 || (it->c != '\t'
5651 && it->glyph_row && it->glyph_row->mode_line_p)
5652 || (it->c != '\n' && it->c != '\t')))
5653 || (it->multibyte_p
5654 ? ((it->c >= 127
5655 && it->len == 1)
5656 || !CHAR_PRINTABLE_P (it->c)
5657 || (!NILP (Vnobreak_char_display)
5658 && (it->c == 0x8a0 || it->c == 0x8ad
5659 || it->c == 0x920 || it->c == 0x92d
5660 || it->c == 0xe20 || it->c == 0xe2d
5661 || it->c == 0xf20 || it->c == 0xf2d)))
5662 : (it->c >= 127
5663 && (!unibyte_display_via_language_environment
5664 || it->c == unibyte_char_to_multibyte (it->c)))))
5666 /* IT->c is a control character which must be displayed
5667 either as '\003' or as `^C' where the '\\' and '^'
5668 can be defined in the display table. Fill
5669 IT->ctl_chars with glyphs for what we have to
5670 display. Then, set IT->dpvec to these glyphs. */
5671 GLYPH g;
5672 int ctl_len;
5673 int face_id, lface_id = 0 ;
5674 GLYPH escape_glyph;
5676 /* Handle control characters with ^. */
5678 if (it->c < 128 && it->ctl_arrow_p)
5680 g = '^'; /* default glyph for Control */
5681 /* Set IT->ctl_chars[0] to the glyph for `^'. */
5682 if (it->dp
5683 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
5684 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
5686 g = XINT (DISP_CTRL_GLYPH (it->dp));
5687 lface_id = FAST_GLYPH_FACE (g);
5689 if (lface_id)
5691 g = FAST_GLYPH_CHAR (g);
5692 face_id = merge_faces (it->f, Qt, lface_id,
5693 it->face_id);
5695 else if (it->f == last_escape_glyph_frame
5696 && it->face_id == last_escape_glyph_face_id)
5698 face_id = last_escape_glyph_merged_face_id;
5700 else
5702 /* Merge the escape-glyph face into the current face. */
5703 face_id = merge_faces (it->f, Qescape_glyph, 0,
5704 it->face_id);
5705 last_escape_glyph_frame = it->f;
5706 last_escape_glyph_face_id = it->face_id;
5707 last_escape_glyph_merged_face_id = face_id;
5710 XSETINT (it->ctl_chars[0], g);
5711 g = it->c ^ 0100;
5712 XSETINT (it->ctl_chars[1], g);
5713 ctl_len = 2;
5714 goto display_control;
5717 /* Handle non-break space in the mode where it only gets
5718 highlighting. */
5720 if (EQ (Vnobreak_char_display, Qt)
5721 && (it->c == 0x8a0 || it->c == 0x920
5722 || it->c == 0xe20 || it->c == 0xf20))
5724 /* Merge the no-break-space face into the current face. */
5725 face_id = merge_faces (it->f, Qnobreak_space, 0,
5726 it->face_id);
5728 g = it->c = ' ';
5729 XSETINT (it->ctl_chars[0], g);
5730 ctl_len = 1;
5731 goto display_control;
5734 /* Handle sequences that start with the "escape glyph". */
5736 /* the default escape glyph is \. */
5737 escape_glyph = '\\';
5739 if (it->dp
5740 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
5741 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
5743 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
5744 lface_id = FAST_GLYPH_FACE (escape_glyph);
5746 if (lface_id)
5748 /* The display table specified a face.
5749 Merge it into face_id and also into escape_glyph. */
5750 escape_glyph = FAST_GLYPH_CHAR (escape_glyph);
5751 face_id = merge_faces (it->f, Qt, lface_id,
5752 it->face_id);
5754 else if (it->f == last_escape_glyph_frame
5755 && it->face_id == last_escape_glyph_face_id)
5757 face_id = last_escape_glyph_merged_face_id;
5759 else
5761 /* Merge the escape-glyph face into the current face. */
5762 face_id = merge_faces (it->f, Qescape_glyph, 0,
5763 it->face_id);
5764 last_escape_glyph_frame = it->f;
5765 last_escape_glyph_face_id = it->face_id;
5766 last_escape_glyph_merged_face_id = face_id;
5769 /* Handle soft hyphens in the mode where they only get
5770 highlighting. */
5772 if (EQ (Vnobreak_char_display, Qt)
5773 && (it->c == 0x8ad || it->c == 0x92d
5774 || it->c == 0xe2d || it->c == 0xf2d))
5776 g = it->c = '-';
5777 XSETINT (it->ctl_chars[0], g);
5778 ctl_len = 1;
5779 goto display_control;
5782 /* Handle non-break space and soft hyphen
5783 with the escape glyph. */
5785 if (it->c == 0x8a0 || it->c == 0x8ad
5786 || it->c == 0x920 || it->c == 0x92d
5787 || it->c == 0xe20 || it->c == 0xe2d
5788 || it->c == 0xf20 || it->c == 0xf2d)
5790 XSETINT (it->ctl_chars[0], escape_glyph);
5791 g = it->c = ((it->c & 0xf) == 0 ? ' ' : '-');
5792 XSETINT (it->ctl_chars[1], g);
5793 ctl_len = 2;
5794 goto display_control;
5798 unsigned char str[MAX_MULTIBYTE_LENGTH];
5799 int len;
5800 int i;
5802 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
5803 if (SINGLE_BYTE_CHAR_P (it->c))
5804 str[0] = it->c, len = 1;
5805 else
5807 len = CHAR_STRING_NO_SIGNAL (it->c, str);
5808 if (len < 0)
5810 /* It's an invalid character, which shouldn't
5811 happen actually, but due to bugs it may
5812 happen. Let's print the char as is, there's
5813 not much meaningful we can do with it. */
5814 str[0] = it->c;
5815 str[1] = it->c >> 8;
5816 str[2] = it->c >> 16;
5817 str[3] = it->c >> 24;
5818 len = 4;
5822 for (i = 0; i < len; i++)
5824 XSETINT (it->ctl_chars[i * 4], escape_glyph);
5825 /* Insert three more glyphs into IT->ctl_chars for
5826 the octal display of the character. */
5827 g = ((str[i] >> 6) & 7) + '0';
5828 XSETINT (it->ctl_chars[i * 4 + 1], g);
5829 g = ((str[i] >> 3) & 7) + '0';
5830 XSETINT (it->ctl_chars[i * 4 + 2], g);
5831 g = (str[i] & 7) + '0';
5832 XSETINT (it->ctl_chars[i * 4 + 3], g);
5834 ctl_len = len * 4;
5837 display_control:
5838 /* Set up IT->dpvec and return first character from it. */
5839 it->dpvec_char_len = it->len;
5840 it->dpvec = it->ctl_chars;
5841 it->dpend = it->dpvec + ctl_len;
5842 it->current.dpvec_index = 0;
5843 it->dpvec_face_id = face_id;
5844 it->saved_face_id = it->face_id;
5845 it->method = GET_FROM_DISPLAY_VECTOR;
5846 it->ellipsis_p = 0;
5847 goto get_next;
5851 /* Adjust face id for a multibyte character. There are no
5852 multibyte character in unibyte text. */
5853 if (it->multibyte_p
5854 && success_p
5855 && FRAME_WINDOW_P (it->f))
5857 struct face *face = FACE_FROM_ID (it->f, it->face_id);
5858 it->face_id = FACE_FOR_CHAR (it->f, face, it->c);
5862 /* Is this character the last one of a run of characters with
5863 box? If yes, set IT->end_of_box_run_p to 1. */
5864 if (it->face_box_p
5865 && it->s == NULL)
5867 int face_id;
5868 struct face *face;
5870 it->end_of_box_run_p
5871 = ((face_id = face_after_it_pos (it),
5872 face_id != it->face_id)
5873 && (face = FACE_FROM_ID (it->f, face_id),
5874 face->box == FACE_NO_BOX));
5877 /* Value is 0 if end of buffer or string reached. */
5878 return success_p;
5882 /* Move IT to the next display element.
5884 RESEAT_P non-zero means if called on a newline in buffer text,
5885 skip to the next visible line start.
5887 Functions get_next_display_element and set_iterator_to_next are
5888 separate because I find this arrangement easier to handle than a
5889 get_next_display_element function that also increments IT's
5890 position. The way it is we can first look at an iterator's current
5891 display element, decide whether it fits on a line, and if it does,
5892 increment the iterator position. The other way around we probably
5893 would either need a flag indicating whether the iterator has to be
5894 incremented the next time, or we would have to implement a
5895 decrement position function which would not be easy to write. */
5897 void
5898 set_iterator_to_next (it, reseat_p)
5899 struct it *it;
5900 int reseat_p;
5902 /* Reset flags indicating start and end of a sequence of characters
5903 with box. Reset them at the start of this function because
5904 moving the iterator to a new position might set them. */
5905 it->start_of_box_run_p = it->end_of_box_run_p = 0;
5907 switch (it->method)
5909 case GET_FROM_BUFFER:
5910 /* The current display element of IT is a character from
5911 current_buffer. Advance in the buffer, and maybe skip over
5912 invisible lines that are so because of selective display. */
5913 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
5914 reseat_at_next_visible_line_start (it, 0);
5915 else
5917 xassert (it->len != 0);
5918 IT_BYTEPOS (*it) += it->len;
5919 IT_CHARPOS (*it) += 1;
5920 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
5922 break;
5924 case GET_FROM_COMPOSITION:
5925 xassert (it->cmp_id >= 0 && it->cmp_id < n_compositions);
5926 xassert (it->sp > 0);
5927 pop_it (it);
5928 if (it->method == GET_FROM_STRING)
5930 IT_STRING_BYTEPOS (*it) += it->len;
5931 IT_STRING_CHARPOS (*it) += it->cmp_len;
5932 goto consider_string_end;
5934 else if (it->method == GET_FROM_BUFFER)
5936 IT_BYTEPOS (*it) += it->len;
5937 IT_CHARPOS (*it) += it->cmp_len;
5939 break;
5941 case GET_FROM_C_STRING:
5942 /* Current display element of IT is from a C string. */
5943 IT_BYTEPOS (*it) += it->len;
5944 IT_CHARPOS (*it) += 1;
5945 break;
5947 case GET_FROM_DISPLAY_VECTOR:
5948 /* Current display element of IT is from a display table entry.
5949 Advance in the display table definition. Reset it to null if
5950 end reached, and continue with characters from buffers/
5951 strings. */
5952 ++it->current.dpvec_index;
5954 /* Restore face of the iterator to what they were before the
5955 display vector entry (these entries may contain faces). */
5956 it->face_id = it->saved_face_id;
5958 if (it->dpvec + it->current.dpvec_index == it->dpend)
5960 int recheck_faces = it->ellipsis_p;
5962 if (it->s)
5963 it->method = GET_FROM_C_STRING;
5964 else if (STRINGP (it->string))
5965 it->method = GET_FROM_STRING;
5966 else
5968 it->method = GET_FROM_BUFFER;
5969 it->object = it->w->buffer;
5972 it->dpvec = NULL;
5973 it->current.dpvec_index = -1;
5975 /* Skip over characters which were displayed via IT->dpvec. */
5976 if (it->dpvec_char_len < 0)
5977 reseat_at_next_visible_line_start (it, 1);
5978 else if (it->dpvec_char_len > 0)
5980 if (it->method == GET_FROM_STRING
5981 && it->n_overlay_strings > 0)
5982 it->ignore_overlay_strings_at_pos_p = 1;
5983 it->len = it->dpvec_char_len;
5984 set_iterator_to_next (it, reseat_p);
5987 /* Maybe recheck faces after display vector */
5988 if (recheck_faces)
5989 it->stop_charpos = IT_CHARPOS (*it);
5991 break;
5993 case GET_FROM_STRING:
5994 /* Current display element is a character from a Lisp string. */
5995 xassert (it->s == NULL && STRINGP (it->string));
5996 IT_STRING_BYTEPOS (*it) += it->len;
5997 IT_STRING_CHARPOS (*it) += 1;
5999 consider_string_end:
6001 if (it->current.overlay_string_index >= 0)
6003 /* IT->string is an overlay string. Advance to the
6004 next, if there is one. */
6005 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
6006 next_overlay_string (it);
6008 else
6010 /* IT->string is not an overlay string. If we reached
6011 its end, and there is something on IT->stack, proceed
6012 with what is on the stack. This can be either another
6013 string, this time an overlay string, or a buffer. */
6014 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
6015 && it->sp > 0)
6017 pop_it (it);
6018 if (it->method == GET_FROM_STRING)
6019 goto consider_string_end;
6022 break;
6024 case GET_FROM_IMAGE:
6025 case GET_FROM_STRETCH:
6026 /* The position etc with which we have to proceed are on
6027 the stack. The position may be at the end of a string,
6028 if the `display' property takes up the whole string. */
6029 xassert (it->sp > 0);
6030 pop_it (it);
6031 if (it->method == GET_FROM_STRING)
6032 goto consider_string_end;
6033 break;
6035 default:
6036 /* There are no other methods defined, so this should be a bug. */
6037 abort ();
6040 xassert (it->method != GET_FROM_STRING
6041 || (STRINGP (it->string)
6042 && IT_STRING_CHARPOS (*it) >= 0));
6045 /* Load IT's display element fields with information about the next
6046 display element which comes from a display table entry or from the
6047 result of translating a control character to one of the forms `^C'
6048 or `\003'.
6050 IT->dpvec holds the glyphs to return as characters.
6051 IT->saved_face_id holds the face id before the display vector--
6052 it is restored into IT->face_idin set_iterator_to_next. */
6054 static int
6055 next_element_from_display_vector (it)
6056 struct it *it;
6058 /* Precondition. */
6059 xassert (it->dpvec && it->current.dpvec_index >= 0);
6061 it->face_id = it->saved_face_id;
6063 if (INTEGERP (*it->dpvec)
6064 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
6066 GLYPH g;
6068 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
6069 it->c = FAST_GLYPH_CHAR (g);
6070 it->len = CHAR_BYTES (it->c);
6072 /* The entry may contain a face id to use. Such a face id is
6073 the id of a Lisp face, not a realized face. A face id of
6074 zero means no face is specified. */
6075 if (it->dpvec_face_id >= 0)
6076 it->face_id = it->dpvec_face_id;
6077 else
6079 int lface_id = FAST_GLYPH_FACE (g);
6080 if (lface_id > 0)
6081 it->face_id = merge_faces (it->f, Qt, lface_id,
6082 it->saved_face_id);
6085 else
6086 /* Display table entry is invalid. Return a space. */
6087 it->c = ' ', it->len = 1;
6089 /* Don't change position and object of the iterator here. They are
6090 still the values of the character that had this display table
6091 entry or was translated, and that's what we want. */
6092 it->what = IT_CHARACTER;
6093 return 1;
6097 /* Load IT with the next display element from Lisp string IT->string.
6098 IT->current.string_pos is the current position within the string.
6099 If IT->current.overlay_string_index >= 0, the Lisp string is an
6100 overlay string. */
6102 static int
6103 next_element_from_string (it)
6104 struct it *it;
6106 struct text_pos position;
6108 xassert (STRINGP (it->string));
6109 xassert (IT_STRING_CHARPOS (*it) >= 0);
6110 position = it->current.string_pos;
6112 /* Time to check for invisible text? */
6113 if (IT_STRING_CHARPOS (*it) < it->end_charpos
6114 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
6116 handle_stop (it);
6118 /* Since a handler may have changed IT->method, we must
6119 recurse here. */
6120 return get_next_display_element (it);
6123 if (it->current.overlay_string_index >= 0)
6125 /* Get the next character from an overlay string. In overlay
6126 strings, There is no field width or padding with spaces to
6127 do. */
6128 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
6130 it->what = IT_EOB;
6131 return 0;
6133 else if (STRING_MULTIBYTE (it->string))
6135 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
6136 const unsigned char *s = (SDATA (it->string)
6137 + IT_STRING_BYTEPOS (*it));
6138 it->c = string_char_and_length (s, remaining, &it->len);
6140 else
6142 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
6143 it->len = 1;
6146 else
6148 /* Get the next character from a Lisp string that is not an
6149 overlay string. Such strings come from the mode line, for
6150 example. We may have to pad with spaces, or truncate the
6151 string. See also next_element_from_c_string. */
6152 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
6154 it->what = IT_EOB;
6155 return 0;
6157 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
6159 /* Pad with spaces. */
6160 it->c = ' ', it->len = 1;
6161 CHARPOS (position) = BYTEPOS (position) = -1;
6163 else if (STRING_MULTIBYTE (it->string))
6165 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
6166 const unsigned char *s = (SDATA (it->string)
6167 + IT_STRING_BYTEPOS (*it));
6168 it->c = string_char_and_length (s, maxlen, &it->len);
6170 else
6172 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
6173 it->len = 1;
6177 /* Record what we have and where it came from. */
6178 it->what = IT_CHARACTER;
6179 it->object = it->string;
6180 it->position = position;
6181 return 1;
6185 /* Load IT with next display element from C string IT->s.
6186 IT->string_nchars is the maximum number of characters to return
6187 from the string. IT->end_charpos may be greater than
6188 IT->string_nchars when this function is called, in which case we
6189 may have to return padding spaces. Value is zero if end of string
6190 reached, including padding spaces. */
6192 static int
6193 next_element_from_c_string (it)
6194 struct it *it;
6196 int success_p = 1;
6198 xassert (it->s);
6199 it->what = IT_CHARACTER;
6200 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
6201 it->object = Qnil;
6203 /* IT's position can be greater IT->string_nchars in case a field
6204 width or precision has been specified when the iterator was
6205 initialized. */
6206 if (IT_CHARPOS (*it) >= it->end_charpos)
6208 /* End of the game. */
6209 it->what = IT_EOB;
6210 success_p = 0;
6212 else if (IT_CHARPOS (*it) >= it->string_nchars)
6214 /* Pad with spaces. */
6215 it->c = ' ', it->len = 1;
6216 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
6218 else if (it->multibyte_p)
6220 /* Implementation note: The calls to strlen apparently aren't a
6221 performance problem because there is no noticeable performance
6222 difference between Emacs running in unibyte or multibyte mode. */
6223 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
6224 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
6225 maxlen, &it->len);
6227 else
6228 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
6230 return success_p;
6234 /* Set up IT to return characters from an ellipsis, if appropriate.
6235 The definition of the ellipsis glyphs may come from a display table
6236 entry. This function Fills IT with the first glyph from the
6237 ellipsis if an ellipsis is to be displayed. */
6239 static int
6240 next_element_from_ellipsis (it)
6241 struct it *it;
6243 if (it->selective_display_ellipsis_p)
6244 setup_for_ellipsis (it, it->len);
6245 else
6247 /* The face at the current position may be different from the
6248 face we find after the invisible text. Remember what it
6249 was in IT->saved_face_id, and signal that it's there by
6250 setting face_before_selective_p. */
6251 it->saved_face_id = it->face_id;
6252 it->method = GET_FROM_BUFFER;
6253 it->object = it->w->buffer;
6254 reseat_at_next_visible_line_start (it, 1);
6255 it->face_before_selective_p = 1;
6258 return get_next_display_element (it);
6262 /* Deliver an image display element. The iterator IT is already
6263 filled with image information (done in handle_display_prop). Value
6264 is always 1. */
6267 static int
6268 next_element_from_image (it)
6269 struct it *it;
6271 it->what = IT_IMAGE;
6272 return 1;
6276 /* Fill iterator IT with next display element from a stretch glyph
6277 property. IT->object is the value of the text property. Value is
6278 always 1. */
6280 static int
6281 next_element_from_stretch (it)
6282 struct it *it;
6284 it->what = IT_STRETCH;
6285 return 1;
6289 /* Load IT with the next display element from current_buffer. Value
6290 is zero if end of buffer reached. IT->stop_charpos is the next
6291 position at which to stop and check for text properties or buffer
6292 end. */
6294 static int
6295 next_element_from_buffer (it)
6296 struct it *it;
6298 int success_p = 1;
6300 /* Check this assumption, otherwise, we would never enter the
6301 if-statement, below. */
6302 xassert (IT_CHARPOS (*it) >= BEGV
6303 && IT_CHARPOS (*it) <= it->stop_charpos);
6305 if (IT_CHARPOS (*it) >= it->stop_charpos)
6307 if (IT_CHARPOS (*it) >= it->end_charpos)
6309 int overlay_strings_follow_p;
6311 /* End of the game, except when overlay strings follow that
6312 haven't been returned yet. */
6313 if (it->overlay_strings_at_end_processed_p)
6314 overlay_strings_follow_p = 0;
6315 else
6317 it->overlay_strings_at_end_processed_p = 1;
6318 overlay_strings_follow_p = get_overlay_strings (it, 0);
6321 if (overlay_strings_follow_p)
6322 success_p = get_next_display_element (it);
6323 else
6325 it->what = IT_EOB;
6326 it->position = it->current.pos;
6327 success_p = 0;
6330 else
6332 handle_stop (it);
6333 return get_next_display_element (it);
6336 else
6338 /* No face changes, overlays etc. in sight, so just return a
6339 character from current_buffer. */
6340 unsigned char *p;
6342 /* Maybe run the redisplay end trigger hook. Performance note:
6343 This doesn't seem to cost measurable time. */
6344 if (it->redisplay_end_trigger_charpos
6345 && it->glyph_row
6346 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
6347 run_redisplay_end_trigger_hook (it);
6349 /* Get the next character, maybe multibyte. */
6350 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
6351 if (it->multibyte_p && !ASCII_BYTE_P (*p))
6353 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
6354 - IT_BYTEPOS (*it));
6355 it->c = string_char_and_length (p, maxlen, &it->len);
6357 else
6358 it->c = *p, it->len = 1;
6360 /* Record what we have and where it came from. */
6361 it->what = IT_CHARACTER;
6362 it->object = it->w->buffer;
6363 it->position = it->current.pos;
6365 /* Normally we return the character found above, except when we
6366 really want to return an ellipsis for selective display. */
6367 if (it->selective)
6369 if (it->c == '\n')
6371 /* A value of selective > 0 means hide lines indented more
6372 than that number of columns. */
6373 if (it->selective > 0
6374 && IT_CHARPOS (*it) + 1 < ZV
6375 && indented_beyond_p (IT_CHARPOS (*it) + 1,
6376 IT_BYTEPOS (*it) + 1,
6377 (double) it->selective)) /* iftc */
6379 success_p = next_element_from_ellipsis (it);
6380 it->dpvec_char_len = -1;
6383 else if (it->c == '\r' && it->selective == -1)
6385 /* A value of selective == -1 means that everything from the
6386 CR to the end of the line is invisible, with maybe an
6387 ellipsis displayed for it. */
6388 success_p = next_element_from_ellipsis (it);
6389 it->dpvec_char_len = -1;
6394 /* Value is zero if end of buffer reached. */
6395 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
6396 return success_p;
6400 /* Run the redisplay end trigger hook for IT. */
6402 static void
6403 run_redisplay_end_trigger_hook (it)
6404 struct it *it;
6406 Lisp_Object args[3];
6408 /* IT->glyph_row should be non-null, i.e. we should be actually
6409 displaying something, or otherwise we should not run the hook. */
6410 xassert (it->glyph_row);
6412 /* Set up hook arguments. */
6413 args[0] = Qredisplay_end_trigger_functions;
6414 args[1] = it->window;
6415 XSETINT (args[2], it->redisplay_end_trigger_charpos);
6416 it->redisplay_end_trigger_charpos = 0;
6418 /* Since we are *trying* to run these functions, don't try to run
6419 them again, even if they get an error. */
6420 it->w->redisplay_end_trigger = Qnil;
6421 Frun_hook_with_args (3, args);
6423 /* Notice if it changed the face of the character we are on. */
6424 handle_face_prop (it);
6428 /* Deliver a composition display element. The iterator IT is already
6429 filled with composition information (done in
6430 handle_composition_prop). Value is always 1. */
6432 static int
6433 next_element_from_composition (it)
6434 struct it *it;
6436 it->what = IT_COMPOSITION;
6437 it->position = (STRINGP (it->string)
6438 ? it->current.string_pos
6439 : it->current.pos);
6440 if (STRINGP (it->string))
6441 it->object = it->string;
6442 else
6443 it->object = it->w->buffer;
6444 return 1;
6449 /***********************************************************************
6450 Moving an iterator without producing glyphs
6451 ***********************************************************************/
6453 /* Check if iterator is at a position corresponding to a valid buffer
6454 position after some move_it_ call. */
6456 #define IT_POS_VALID_AFTER_MOVE_P(it) \
6457 ((it)->method == GET_FROM_STRING \
6458 ? IT_STRING_CHARPOS (*it) == 0 \
6459 : 1)
6462 /* Move iterator IT to a specified buffer or X position within one
6463 line on the display without producing glyphs.
6465 OP should be a bit mask including some or all of these bits:
6466 MOVE_TO_X: Stop on reaching x-position TO_X.
6467 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
6468 Regardless of OP's value, stop in reaching the end of the display line.
6470 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
6471 This means, in particular, that TO_X includes window's horizontal
6472 scroll amount.
6474 The return value has several possible values that
6475 say what condition caused the scan to stop:
6477 MOVE_POS_MATCH_OR_ZV
6478 - when TO_POS or ZV was reached.
6480 MOVE_X_REACHED
6481 -when TO_X was reached before TO_POS or ZV were reached.
6483 MOVE_LINE_CONTINUED
6484 - when we reached the end of the display area and the line must
6485 be continued.
6487 MOVE_LINE_TRUNCATED
6488 - when we reached the end of the display area and the line is
6489 truncated.
6491 MOVE_NEWLINE_OR_CR
6492 - when we stopped at a line end, i.e. a newline or a CR and selective
6493 display is on. */
6495 static enum move_it_result
6496 move_it_in_display_line_to (it, to_charpos, to_x, op)
6497 struct it *it;
6498 int to_charpos, to_x, op;
6500 enum move_it_result result = MOVE_UNDEFINED;
6501 struct glyph_row *saved_glyph_row;
6503 /* Don't produce glyphs in produce_glyphs. */
6504 saved_glyph_row = it->glyph_row;
6505 it->glyph_row = NULL;
6507 #define BUFFER_POS_REACHED_P() \
6508 ((op & MOVE_TO_POS) != 0 \
6509 && BUFFERP (it->object) \
6510 && IT_CHARPOS (*it) >= to_charpos \
6511 && (it->method == GET_FROM_BUFFER \
6512 || (it->method == GET_FROM_DISPLAY_VECTOR \
6513 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
6516 while (1)
6518 int x, i, ascent = 0, descent = 0;
6520 /* Stop if we move beyond TO_CHARPOS (after an image or stretch glyph). */
6521 if ((op & MOVE_TO_POS) != 0
6522 && BUFFERP (it->object)
6523 && it->method == GET_FROM_BUFFER
6524 && IT_CHARPOS (*it) > to_charpos)
6526 result = MOVE_POS_MATCH_OR_ZV;
6527 break;
6530 /* Stop when ZV reached.
6531 We used to stop here when TO_CHARPOS reached as well, but that is
6532 too soon if this glyph does not fit on this line. So we handle it
6533 explicitly below. */
6534 if (!get_next_display_element (it)
6535 || (it->truncate_lines_p
6536 && BUFFER_POS_REACHED_P ()))
6538 result = MOVE_POS_MATCH_OR_ZV;
6539 break;
6542 /* The call to produce_glyphs will get the metrics of the
6543 display element IT is loaded with. We record in x the
6544 x-position before this display element in case it does not
6545 fit on the line. */
6546 x = it->current_x;
6548 /* Remember the line height so far in case the next element doesn't
6549 fit on the line. */
6550 if (!it->truncate_lines_p)
6552 ascent = it->max_ascent;
6553 descent = it->max_descent;
6556 PRODUCE_GLYPHS (it);
6558 if (it->area != TEXT_AREA)
6560 set_iterator_to_next (it, 1);
6561 continue;
6564 /* The number of glyphs we get back in IT->nglyphs will normally
6565 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
6566 character on a terminal frame, or (iii) a line end. For the
6567 second case, IT->nglyphs - 1 padding glyphs will be present
6568 (on X frames, there is only one glyph produced for a
6569 composite character.
6571 The behavior implemented below means, for continuation lines,
6572 that as many spaces of a TAB as fit on the current line are
6573 displayed there. For terminal frames, as many glyphs of a
6574 multi-glyph character are displayed in the current line, too.
6575 This is what the old redisplay code did, and we keep it that
6576 way. Under X, the whole shape of a complex character must
6577 fit on the line or it will be completely displayed in the
6578 next line.
6580 Note that both for tabs and padding glyphs, all glyphs have
6581 the same width. */
6582 if (it->nglyphs)
6584 /* More than one glyph or glyph doesn't fit on line. All
6585 glyphs have the same width. */
6586 int single_glyph_width = it->pixel_width / it->nglyphs;
6587 int new_x;
6588 int x_before_this_char = x;
6589 int hpos_before_this_char = it->hpos;
6591 for (i = 0; i < it->nglyphs; ++i, x = new_x)
6593 new_x = x + single_glyph_width;
6595 /* We want to leave anything reaching TO_X to the caller. */
6596 if ((op & MOVE_TO_X) && new_x > to_x)
6598 if (BUFFER_POS_REACHED_P ())
6599 goto buffer_pos_reached;
6600 it->current_x = x;
6601 result = MOVE_X_REACHED;
6602 break;
6604 else if (/* Lines are continued. */
6605 !it->truncate_lines_p
6606 && (/* And glyph doesn't fit on the line. */
6607 new_x > it->last_visible_x
6608 /* Or it fits exactly and we're on a window
6609 system frame. */
6610 || (new_x == it->last_visible_x
6611 && FRAME_WINDOW_P (it->f))))
6613 if (/* IT->hpos == 0 means the very first glyph
6614 doesn't fit on the line, e.g. a wide image. */
6615 it->hpos == 0
6616 || (new_x == it->last_visible_x
6617 && FRAME_WINDOW_P (it->f)))
6619 ++it->hpos;
6620 it->current_x = new_x;
6622 /* The character's last glyph just barely fits
6623 in this row. */
6624 if (i == it->nglyphs - 1)
6626 /* If this is the destination position,
6627 return a position *before* it in this row,
6628 now that we know it fits in this row. */
6629 if (BUFFER_POS_REACHED_P ())
6631 it->hpos = hpos_before_this_char;
6632 it->current_x = x_before_this_char;
6633 result = MOVE_POS_MATCH_OR_ZV;
6634 break;
6637 set_iterator_to_next (it, 1);
6638 #ifdef HAVE_WINDOW_SYSTEM
6639 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
6641 if (!get_next_display_element (it))
6643 result = MOVE_POS_MATCH_OR_ZV;
6644 break;
6646 if (BUFFER_POS_REACHED_P ())
6648 if (ITERATOR_AT_END_OF_LINE_P (it))
6649 result = MOVE_POS_MATCH_OR_ZV;
6650 else
6651 result = MOVE_LINE_CONTINUED;
6652 break;
6654 if (ITERATOR_AT_END_OF_LINE_P (it))
6656 result = MOVE_NEWLINE_OR_CR;
6657 break;
6660 #endif /* HAVE_WINDOW_SYSTEM */
6663 else
6665 it->current_x = x;
6666 it->max_ascent = ascent;
6667 it->max_descent = descent;
6670 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
6671 IT_CHARPOS (*it)));
6672 result = MOVE_LINE_CONTINUED;
6673 break;
6675 else if (BUFFER_POS_REACHED_P ())
6676 goto buffer_pos_reached;
6677 else if (new_x > it->first_visible_x)
6679 /* Glyph is visible. Increment number of glyphs that
6680 would be displayed. */
6681 ++it->hpos;
6683 else
6685 /* Glyph is completely off the left margin of the display
6686 area. Nothing to do. */
6690 if (result != MOVE_UNDEFINED)
6691 break;
6693 else if (BUFFER_POS_REACHED_P ())
6695 buffer_pos_reached:
6696 it->current_x = x;
6697 it->max_ascent = ascent;
6698 it->max_descent = descent;
6699 result = MOVE_POS_MATCH_OR_ZV;
6700 break;
6702 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
6704 /* Stop when TO_X specified and reached. This check is
6705 necessary here because of lines consisting of a line end,
6706 only. The line end will not produce any glyphs and we
6707 would never get MOVE_X_REACHED. */
6708 xassert (it->nglyphs == 0);
6709 result = MOVE_X_REACHED;
6710 break;
6713 /* Is this a line end? If yes, we're done. */
6714 if (ITERATOR_AT_END_OF_LINE_P (it))
6716 result = MOVE_NEWLINE_OR_CR;
6717 break;
6720 /* The current display element has been consumed. Advance
6721 to the next. */
6722 set_iterator_to_next (it, 1);
6724 /* Stop if lines are truncated and IT's current x-position is
6725 past the right edge of the window now. */
6726 if (it->truncate_lines_p
6727 && it->current_x >= it->last_visible_x)
6729 #ifdef HAVE_WINDOW_SYSTEM
6730 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
6732 if (!get_next_display_element (it)
6733 || BUFFER_POS_REACHED_P ())
6735 result = MOVE_POS_MATCH_OR_ZV;
6736 break;
6738 if (ITERATOR_AT_END_OF_LINE_P (it))
6740 result = MOVE_NEWLINE_OR_CR;
6741 break;
6744 #endif /* HAVE_WINDOW_SYSTEM */
6745 result = MOVE_LINE_TRUNCATED;
6746 break;
6750 #undef BUFFER_POS_REACHED_P
6752 /* Restore the iterator settings altered at the beginning of this
6753 function. */
6754 it->glyph_row = saved_glyph_row;
6755 return result;
6759 /* Move IT forward until it satisfies one or more of the criteria in
6760 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
6762 OP is a bit-mask that specifies where to stop, and in particular,
6763 which of those four position arguments makes a difference. See the
6764 description of enum move_operation_enum.
6766 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
6767 screen line, this function will set IT to the next position >
6768 TO_CHARPOS. */
6770 void
6771 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
6772 struct it *it;
6773 int to_charpos, to_x, to_y, to_vpos;
6774 int op;
6776 enum move_it_result skip, skip2 = MOVE_X_REACHED;
6777 int line_height;
6778 int reached = 0;
6780 for (;;)
6782 if (op & MOVE_TO_VPOS)
6784 /* If no TO_CHARPOS and no TO_X specified, stop at the
6785 start of the line TO_VPOS. */
6786 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
6788 if (it->vpos == to_vpos)
6790 reached = 1;
6791 break;
6793 else
6794 skip = move_it_in_display_line_to (it, -1, -1, 0);
6796 else
6798 /* TO_VPOS >= 0 means stop at TO_X in the line at
6799 TO_VPOS, or at TO_POS, whichever comes first. */
6800 if (it->vpos == to_vpos)
6802 reached = 2;
6803 break;
6806 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
6808 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
6810 reached = 3;
6811 break;
6813 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
6815 /* We have reached TO_X but not in the line we want. */
6816 skip = move_it_in_display_line_to (it, to_charpos,
6817 -1, MOVE_TO_POS);
6818 if (skip == MOVE_POS_MATCH_OR_ZV)
6820 reached = 4;
6821 break;
6826 else if (op & MOVE_TO_Y)
6828 struct it it_backup;
6830 /* TO_Y specified means stop at TO_X in the line containing
6831 TO_Y---or at TO_CHARPOS if this is reached first. The
6832 problem is that we can't really tell whether the line
6833 contains TO_Y before we have completely scanned it, and
6834 this may skip past TO_X. What we do is to first scan to
6835 TO_X.
6837 If TO_X is not specified, use a TO_X of zero. The reason
6838 is to make the outcome of this function more predictable.
6839 If we didn't use TO_X == 0, we would stop at the end of
6840 the line which is probably not what a caller would expect
6841 to happen. */
6842 skip = move_it_in_display_line_to (it, to_charpos,
6843 ((op & MOVE_TO_X)
6844 ? to_x : 0),
6845 (MOVE_TO_X
6846 | (op & MOVE_TO_POS)));
6848 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
6849 if (skip == MOVE_POS_MATCH_OR_ZV)
6851 reached = 5;
6852 break;
6855 /* If TO_X was reached, we would like to know whether TO_Y
6856 is in the line. This can only be said if we know the
6857 total line height which requires us to scan the rest of
6858 the line. */
6859 if (skip == MOVE_X_REACHED)
6861 it_backup = *it;
6862 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
6863 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
6864 op & MOVE_TO_POS);
6865 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
6868 /* Now, decide whether TO_Y is in this line. */
6869 line_height = it->max_ascent + it->max_descent;
6870 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
6872 if (to_y >= it->current_y
6873 && to_y < it->current_y + line_height)
6875 if (skip == MOVE_X_REACHED)
6876 /* If TO_Y is in this line and TO_X was reached above,
6877 we scanned too far. We have to restore IT's settings
6878 to the ones before skipping. */
6879 *it = it_backup;
6880 reached = 6;
6882 else if (skip == MOVE_X_REACHED)
6884 skip = skip2;
6885 if (skip == MOVE_POS_MATCH_OR_ZV)
6886 reached = 7;
6889 if (reached)
6890 break;
6892 else if (BUFFERP (it->object)
6893 && it->method == GET_FROM_BUFFER
6894 && IT_CHARPOS (*it) >= to_charpos)
6895 skip = MOVE_POS_MATCH_OR_ZV;
6896 else
6897 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
6899 switch (skip)
6901 case MOVE_POS_MATCH_OR_ZV:
6902 reached = 8;
6903 goto out;
6905 case MOVE_NEWLINE_OR_CR:
6906 set_iterator_to_next (it, 1);
6907 it->continuation_lines_width = 0;
6908 break;
6910 case MOVE_LINE_TRUNCATED:
6911 it->continuation_lines_width = 0;
6912 reseat_at_next_visible_line_start (it, 0);
6913 if ((op & MOVE_TO_POS) != 0
6914 && IT_CHARPOS (*it) > to_charpos)
6916 reached = 9;
6917 goto out;
6919 break;
6921 case MOVE_LINE_CONTINUED:
6922 /* For continued lines ending in a tab, some of the glyphs
6923 associated with the tab are displayed on the current
6924 line. Since it->current_x does not include these glyphs,
6925 we use it->last_visible_x instead. */
6926 it->continuation_lines_width +=
6927 (it->c == '\t') ? it->last_visible_x : it->current_x;
6928 break;
6930 default:
6931 abort ();
6934 /* Reset/increment for the next run. */
6935 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
6936 it->current_x = it->hpos = 0;
6937 it->current_y += it->max_ascent + it->max_descent;
6938 ++it->vpos;
6939 last_height = it->max_ascent + it->max_descent;
6940 last_max_ascent = it->max_ascent;
6941 it->max_ascent = it->max_descent = 0;
6944 out:
6946 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
6950 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
6952 If DY > 0, move IT backward at least that many pixels. DY = 0
6953 means move IT backward to the preceding line start or BEGV. This
6954 function may move over more than DY pixels if IT->current_y - DY
6955 ends up in the middle of a line; in this case IT->current_y will be
6956 set to the top of the line moved to. */
6958 void
6959 move_it_vertically_backward (it, dy)
6960 struct it *it;
6961 int dy;
6963 int nlines, h;
6964 struct it it2, it3;
6965 int start_pos;
6967 move_further_back:
6968 xassert (dy >= 0);
6970 start_pos = IT_CHARPOS (*it);
6972 /* Estimate how many newlines we must move back. */
6973 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
6975 /* Set the iterator's position that many lines back. */
6976 while (nlines-- && IT_CHARPOS (*it) > BEGV)
6977 back_to_previous_visible_line_start (it);
6979 /* Reseat the iterator here. When moving backward, we don't want
6980 reseat to skip forward over invisible text, set up the iterator
6981 to deliver from overlay strings at the new position etc. So,
6982 use reseat_1 here. */
6983 reseat_1 (it, it->current.pos, 1);
6985 /* We are now surely at a line start. */
6986 it->current_x = it->hpos = 0;
6987 it->continuation_lines_width = 0;
6989 /* Move forward and see what y-distance we moved. First move to the
6990 start of the next line so that we get its height. We need this
6991 height to be able to tell whether we reached the specified
6992 y-distance. */
6993 it2 = *it;
6994 it2.max_ascent = it2.max_descent = 0;
6997 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
6998 MOVE_TO_POS | MOVE_TO_VPOS);
7000 while (!IT_POS_VALID_AFTER_MOVE_P (&it2));
7001 xassert (IT_CHARPOS (*it) >= BEGV);
7002 it3 = it2;
7004 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
7005 xassert (IT_CHARPOS (*it) >= BEGV);
7006 /* H is the actual vertical distance from the position in *IT
7007 and the starting position. */
7008 h = it2.current_y - it->current_y;
7009 /* NLINES is the distance in number of lines. */
7010 nlines = it2.vpos - it->vpos;
7012 /* Correct IT's y and vpos position
7013 so that they are relative to the starting point. */
7014 it->vpos -= nlines;
7015 it->current_y -= h;
7017 if (dy == 0)
7019 /* DY == 0 means move to the start of the screen line. The
7020 value of nlines is > 0 if continuation lines were involved. */
7021 if (nlines > 0)
7022 move_it_by_lines (it, nlines, 1);
7023 #if 0
7024 /* I think this assert is bogus if buffer contains
7025 invisible text or images. KFS. */
7026 xassert (IT_CHARPOS (*it) <= start_pos);
7027 #endif
7029 else
7031 /* The y-position we try to reach, relative to *IT.
7032 Note that H has been subtracted in front of the if-statement. */
7033 int target_y = it->current_y + h - dy;
7034 int y0 = it3.current_y;
7035 int y1 = line_bottom_y (&it3);
7036 int line_height = y1 - y0;
7038 /* If we did not reach target_y, try to move further backward if
7039 we can. If we moved too far backward, try to move forward. */
7040 if (target_y < it->current_y
7041 /* This is heuristic. In a window that's 3 lines high, with
7042 a line height of 13 pixels each, recentering with point
7043 on the bottom line will try to move -39/2 = 19 pixels
7044 backward. Try to avoid moving into the first line. */
7045 && (it->current_y - target_y
7046 > min (window_box_height (it->w), line_height * 2 / 3))
7047 && IT_CHARPOS (*it) > BEGV)
7049 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
7050 target_y - it->current_y));
7051 dy = it->current_y - target_y;
7052 goto move_further_back;
7054 else if (target_y >= it->current_y + line_height
7055 && IT_CHARPOS (*it) < ZV)
7057 /* Should move forward by at least one line, maybe more.
7059 Note: Calling move_it_by_lines can be expensive on
7060 terminal frames, where compute_motion is used (via
7061 vmotion) to do the job, when there are very long lines
7062 and truncate-lines is nil. That's the reason for
7063 treating terminal frames specially here. */
7065 if (!FRAME_WINDOW_P (it->f))
7066 move_it_vertically (it, target_y - (it->current_y + line_height));
7067 else
7071 move_it_by_lines (it, 1, 1);
7073 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
7076 #if 0
7077 /* I think this assert is bogus if buffer contains
7078 invisible text or images. KFS. */
7079 xassert (IT_CHARPOS (*it) >= BEGV);
7080 #endif
7086 /* Move IT by a specified amount of pixel lines DY. DY negative means
7087 move backwards. DY = 0 means move to start of screen line. At the
7088 end, IT will be on the start of a screen line. */
7090 void
7091 move_it_vertically (it, dy)
7092 struct it *it;
7093 int dy;
7095 if (dy <= 0)
7096 move_it_vertically_backward (it, -dy);
7097 else
7099 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
7100 move_it_to (it, ZV, -1, it->current_y + dy, -1,
7101 MOVE_TO_POS | MOVE_TO_Y);
7102 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
7104 /* If buffer ends in ZV without a newline, move to the start of
7105 the line to satisfy the post-condition. */
7106 if (IT_CHARPOS (*it) == ZV
7107 && ZV > BEGV
7108 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
7109 move_it_by_lines (it, 0, 0);
7114 /* Move iterator IT past the end of the text line it is in. */
7116 void
7117 move_it_past_eol (it)
7118 struct it *it;
7120 enum move_it_result rc;
7122 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
7123 if (rc == MOVE_NEWLINE_OR_CR)
7124 set_iterator_to_next (it, 0);
7128 #if 0 /* Currently not used. */
7130 /* Return non-zero if some text between buffer positions START_CHARPOS
7131 and END_CHARPOS is invisible. IT->window is the window for text
7132 property lookup. */
7134 static int
7135 invisible_text_between_p (it, start_charpos, end_charpos)
7136 struct it *it;
7137 int start_charpos, end_charpos;
7139 Lisp_Object prop, limit;
7140 int invisible_found_p;
7142 xassert (it != NULL && start_charpos <= end_charpos);
7144 /* Is text at START invisible? */
7145 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
7146 it->window);
7147 if (TEXT_PROP_MEANS_INVISIBLE (prop))
7148 invisible_found_p = 1;
7149 else
7151 limit = Fnext_single_char_property_change (make_number (start_charpos),
7152 Qinvisible, Qnil,
7153 make_number (end_charpos));
7154 invisible_found_p = XFASTINT (limit) < end_charpos;
7157 return invisible_found_p;
7160 #endif /* 0 */
7163 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
7164 negative means move up. DVPOS == 0 means move to the start of the
7165 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
7166 NEED_Y_P is zero, IT->current_y will be left unchanged.
7168 Further optimization ideas: If we would know that IT->f doesn't use
7169 a face with proportional font, we could be faster for
7170 truncate-lines nil. */
7172 void
7173 move_it_by_lines (it, dvpos, need_y_p)
7174 struct it *it;
7175 int dvpos, need_y_p;
7177 struct position pos;
7179 /* The commented-out optimization uses vmotion on terminals. This
7180 gives bad results, because elements like it->what, on which
7181 callers such as pos_visible_p rely, aren't updated. */
7182 /* if (!FRAME_WINDOW_P (it->f))
7184 struct text_pos textpos;
7186 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
7187 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
7188 reseat (it, textpos, 1);
7189 it->vpos += pos.vpos;
7190 it->current_y += pos.vpos;
7192 else */
7194 if (dvpos == 0)
7196 /* DVPOS == 0 means move to the start of the screen line. */
7197 move_it_vertically_backward (it, 0);
7198 xassert (it->current_x == 0 && it->hpos == 0);
7199 /* Let next call to line_bottom_y calculate real line height */
7200 last_height = 0;
7202 else if (dvpos > 0)
7204 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
7205 if (!IT_POS_VALID_AFTER_MOVE_P (it))
7206 move_it_to (it, IT_CHARPOS (*it) + 1, -1, -1, -1, MOVE_TO_POS);
7208 else
7210 struct it it2;
7211 int start_charpos, i;
7213 /* Start at the beginning of the screen line containing IT's
7214 position. This may actually move vertically backwards,
7215 in case of overlays, so adjust dvpos accordingly. */
7216 dvpos += it->vpos;
7217 move_it_vertically_backward (it, 0);
7218 dvpos -= it->vpos;
7220 /* Go back -DVPOS visible lines and reseat the iterator there. */
7221 start_charpos = IT_CHARPOS (*it);
7222 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > BEGV; --i)
7223 back_to_previous_visible_line_start (it);
7224 reseat (it, it->current.pos, 1);
7226 /* Move further back if we end up in a string or an image. */
7227 while (!IT_POS_VALID_AFTER_MOVE_P (it))
7229 /* First try to move to start of display line. */
7230 dvpos += it->vpos;
7231 move_it_vertically_backward (it, 0);
7232 dvpos -= it->vpos;
7233 if (IT_POS_VALID_AFTER_MOVE_P (it))
7234 break;
7235 /* If start of line is still in string or image,
7236 move further back. */
7237 back_to_previous_visible_line_start (it);
7238 reseat (it, it->current.pos, 1);
7239 dvpos--;
7242 it->current_x = it->hpos = 0;
7244 /* Above call may have moved too far if continuation lines
7245 are involved. Scan forward and see if it did. */
7246 it2 = *it;
7247 it2.vpos = it2.current_y = 0;
7248 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
7249 it->vpos -= it2.vpos;
7250 it->current_y -= it2.current_y;
7251 it->current_x = it->hpos = 0;
7253 /* If we moved too far back, move IT some lines forward. */
7254 if (it2.vpos > -dvpos)
7256 int delta = it2.vpos + dvpos;
7257 it2 = *it;
7258 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
7259 /* Move back again if we got too far ahead. */
7260 if (IT_CHARPOS (*it) >= start_charpos)
7261 *it = it2;
7266 /* Return 1 if IT points into the middle of a display vector. */
7269 in_display_vector_p (it)
7270 struct it *it;
7272 return (it->method == GET_FROM_DISPLAY_VECTOR
7273 && it->current.dpvec_index > 0
7274 && it->dpvec + it->current.dpvec_index != it->dpend);
7278 /***********************************************************************
7279 Messages
7280 ***********************************************************************/
7283 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
7284 to *Messages*. */
7286 void
7287 add_to_log (format, arg1, arg2)
7288 char *format;
7289 Lisp_Object arg1, arg2;
7291 Lisp_Object args[3];
7292 Lisp_Object msg, fmt;
7293 char *buffer;
7294 int len;
7295 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
7296 USE_SAFE_ALLOCA;
7298 /* Do nothing if called asynchronously. Inserting text into
7299 a buffer may call after-change-functions and alike and
7300 that would means running Lisp asynchronously. */
7301 if (handling_signal)
7302 return;
7304 fmt = msg = Qnil;
7305 GCPRO4 (fmt, msg, arg1, arg2);
7307 args[0] = fmt = build_string (format);
7308 args[1] = arg1;
7309 args[2] = arg2;
7310 msg = Fformat (3, args);
7312 len = SBYTES (msg) + 1;
7313 SAFE_ALLOCA (buffer, char *, len);
7314 bcopy (SDATA (msg), buffer, len);
7316 message_dolog (buffer, len - 1, 1, 0);
7317 SAFE_FREE ();
7319 UNGCPRO;
7323 /* Output a newline in the *Messages* buffer if "needs" one. */
7325 void
7326 message_log_maybe_newline ()
7328 if (message_log_need_newline)
7329 message_dolog ("", 0, 1, 0);
7333 /* Add a string M of length NBYTES to the message log, optionally
7334 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
7335 nonzero, means interpret the contents of M as multibyte. This
7336 function calls low-level routines in order to bypass text property
7337 hooks, etc. which might not be safe to run.
7339 This may GC (insert may run before/after change hooks),
7340 so the buffer M must NOT point to a Lisp string. */
7342 void
7343 message_dolog (m, nbytes, nlflag, multibyte)
7344 const char *m;
7345 int nbytes, nlflag, multibyte;
7347 if (!NILP (Vmemory_full))
7348 return;
7350 if (!NILP (Vmessage_log_max))
7352 struct buffer *oldbuf;
7353 Lisp_Object oldpoint, oldbegv, oldzv;
7354 int old_windows_or_buffers_changed = windows_or_buffers_changed;
7355 int point_at_end = 0;
7356 int zv_at_end = 0;
7357 Lisp_Object old_deactivate_mark, tem;
7358 struct gcpro gcpro1;
7360 old_deactivate_mark = Vdeactivate_mark;
7361 oldbuf = current_buffer;
7362 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
7363 current_buffer->undo_list = Qt;
7365 oldpoint = message_dolog_marker1;
7366 set_marker_restricted (oldpoint, make_number (PT), Qnil);
7367 oldbegv = message_dolog_marker2;
7368 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
7369 oldzv = message_dolog_marker3;
7370 set_marker_restricted (oldzv, make_number (ZV), Qnil);
7371 GCPRO1 (old_deactivate_mark);
7373 if (PT == Z)
7374 point_at_end = 1;
7375 if (ZV == Z)
7376 zv_at_end = 1;
7378 BEGV = BEG;
7379 BEGV_BYTE = BEG_BYTE;
7380 ZV = Z;
7381 ZV_BYTE = Z_BYTE;
7382 TEMP_SET_PT_BOTH (Z, Z_BYTE);
7384 /* Insert the string--maybe converting multibyte to single byte
7385 or vice versa, so that all the text fits the buffer. */
7386 if (multibyte
7387 && NILP (current_buffer->enable_multibyte_characters))
7389 int i, c, char_bytes;
7390 unsigned char work[1];
7392 /* Convert a multibyte string to single-byte
7393 for the *Message* buffer. */
7394 for (i = 0; i < nbytes; i += char_bytes)
7396 c = string_char_and_length (m + i, nbytes - i, &char_bytes);
7397 work[0] = (SINGLE_BYTE_CHAR_P (c)
7399 : multibyte_char_to_unibyte (c, Qnil));
7400 insert_1_both (work, 1, 1, 1, 0, 0);
7403 else if (! multibyte
7404 && ! NILP (current_buffer->enable_multibyte_characters))
7406 int i, c, char_bytes;
7407 unsigned char *msg = (unsigned char *) m;
7408 unsigned char str[MAX_MULTIBYTE_LENGTH];
7409 /* Convert a single-byte string to multibyte
7410 for the *Message* buffer. */
7411 for (i = 0; i < nbytes; i++)
7413 c = unibyte_char_to_multibyte (msg[i]);
7414 char_bytes = CHAR_STRING (c, str);
7415 insert_1_both (str, 1, char_bytes, 1, 0, 0);
7418 else if (nbytes)
7419 insert_1 (m, nbytes, 1, 0, 0);
7421 if (nlflag)
7423 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
7424 insert_1 ("\n", 1, 1, 0, 0);
7426 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
7427 this_bol = PT;
7428 this_bol_byte = PT_BYTE;
7430 /* See if this line duplicates the previous one.
7431 If so, combine duplicates. */
7432 if (this_bol > BEG)
7434 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
7435 prev_bol = PT;
7436 prev_bol_byte = PT_BYTE;
7438 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
7439 this_bol, this_bol_byte);
7440 if (dup)
7442 del_range_both (prev_bol, prev_bol_byte,
7443 this_bol, this_bol_byte, 0);
7444 if (dup > 1)
7446 char dupstr[40];
7447 int duplen;
7449 /* If you change this format, don't forget to also
7450 change message_log_check_duplicate. */
7451 sprintf (dupstr, " [%d times]", dup);
7452 duplen = strlen (dupstr);
7453 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
7454 insert_1 (dupstr, duplen, 1, 0, 1);
7459 /* If we have more than the desired maximum number of lines
7460 in the *Messages* buffer now, delete the oldest ones.
7461 This is safe because we don't have undo in this buffer. */
7463 if (NATNUMP (Vmessage_log_max))
7465 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
7466 -XFASTINT (Vmessage_log_max) - 1, 0);
7467 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
7470 BEGV = XMARKER (oldbegv)->charpos;
7471 BEGV_BYTE = marker_byte_position (oldbegv);
7473 if (zv_at_end)
7475 ZV = Z;
7476 ZV_BYTE = Z_BYTE;
7478 else
7480 ZV = XMARKER (oldzv)->charpos;
7481 ZV_BYTE = marker_byte_position (oldzv);
7484 if (point_at_end)
7485 TEMP_SET_PT_BOTH (Z, Z_BYTE);
7486 else
7487 /* We can't do Fgoto_char (oldpoint) because it will run some
7488 Lisp code. */
7489 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
7490 XMARKER (oldpoint)->bytepos);
7492 UNGCPRO;
7493 unchain_marker (XMARKER (oldpoint));
7494 unchain_marker (XMARKER (oldbegv));
7495 unchain_marker (XMARKER (oldzv));
7497 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
7498 set_buffer_internal (oldbuf);
7499 if (NILP (tem))
7500 windows_or_buffers_changed = old_windows_or_buffers_changed;
7501 message_log_need_newline = !nlflag;
7502 Vdeactivate_mark = old_deactivate_mark;
7507 /* We are at the end of the buffer after just having inserted a newline.
7508 (Note: We depend on the fact we won't be crossing the gap.)
7509 Check to see if the most recent message looks a lot like the previous one.
7510 Return 0 if different, 1 if the new one should just replace it, or a
7511 value N > 1 if we should also append " [N times]". */
7513 static int
7514 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
7515 int prev_bol, this_bol;
7516 int prev_bol_byte, this_bol_byte;
7518 int i;
7519 int len = Z_BYTE - 1 - this_bol_byte;
7520 int seen_dots = 0;
7521 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
7522 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
7524 for (i = 0; i < len; i++)
7526 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
7527 seen_dots = 1;
7528 if (p1[i] != p2[i])
7529 return seen_dots;
7531 p1 += len;
7532 if (*p1 == '\n')
7533 return 2;
7534 if (*p1++ == ' ' && *p1++ == '[')
7536 int n = 0;
7537 while (*p1 >= '0' && *p1 <= '9')
7538 n = n * 10 + *p1++ - '0';
7539 if (strncmp (p1, " times]\n", 8) == 0)
7540 return n+1;
7542 return 0;
7546 /* Display an echo area message M with a specified length of NBYTES
7547 bytes. The string may include null characters. If M is 0, clear
7548 out any existing message, and let the mini-buffer text show
7549 through.
7551 This may GC, so the buffer M must NOT point to a Lisp string. */
7553 void
7554 message2 (m, nbytes, multibyte)
7555 const char *m;
7556 int nbytes;
7557 int multibyte;
7559 /* First flush out any partial line written with print. */
7560 message_log_maybe_newline ();
7561 if (m)
7562 message_dolog (m, nbytes, 1, multibyte);
7563 message2_nolog (m, nbytes, multibyte);
7567 /* The non-logging counterpart of message2. */
7569 void
7570 message2_nolog (m, nbytes, multibyte)
7571 const char *m;
7572 int nbytes, multibyte;
7574 struct frame *sf = SELECTED_FRAME ();
7575 message_enable_multibyte = multibyte;
7577 if (noninteractive)
7579 if (noninteractive_need_newline)
7580 putc ('\n', stderr);
7581 noninteractive_need_newline = 0;
7582 if (m)
7583 fwrite (m, nbytes, 1, stderr);
7584 if (cursor_in_echo_area == 0)
7585 fprintf (stderr, "\n");
7586 fflush (stderr);
7588 /* A null message buffer means that the frame hasn't really been
7589 initialized yet. Error messages get reported properly by
7590 cmd_error, so this must be just an informative message; toss it. */
7591 else if (INTERACTIVE
7592 && sf->glyphs_initialized_p
7593 && FRAME_MESSAGE_BUF (sf))
7595 Lisp_Object mini_window;
7596 struct frame *f;
7598 /* Get the frame containing the mini-buffer
7599 that the selected frame is using. */
7600 mini_window = FRAME_MINIBUF_WINDOW (sf);
7601 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
7603 FRAME_SAMPLE_VISIBILITY (f);
7604 if (FRAME_VISIBLE_P (sf)
7605 && ! FRAME_VISIBLE_P (f))
7606 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
7608 if (m)
7610 set_message (m, Qnil, nbytes, multibyte);
7611 if (minibuffer_auto_raise)
7612 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
7614 else
7615 clear_message (1, 1);
7617 do_pending_window_change (0);
7618 echo_area_display (1);
7619 do_pending_window_change (0);
7620 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
7621 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
7626 /* Display an echo area message M with a specified length of NBYTES
7627 bytes. The string may include null characters. If M is not a
7628 string, clear out any existing message, and let the mini-buffer
7629 text show through.
7631 This function cancels echoing. */
7633 void
7634 message3 (m, nbytes, multibyte)
7635 Lisp_Object m;
7636 int nbytes;
7637 int multibyte;
7639 struct gcpro gcpro1;
7641 GCPRO1 (m);
7642 clear_message (1,1);
7643 cancel_echoing ();
7645 /* First flush out any partial line written with print. */
7646 message_log_maybe_newline ();
7647 if (STRINGP (m))
7649 char *buffer;
7650 USE_SAFE_ALLOCA;
7652 SAFE_ALLOCA (buffer, char *, nbytes);
7653 bcopy (SDATA (m), buffer, nbytes);
7654 message_dolog (buffer, nbytes, 1, multibyte);
7655 SAFE_FREE ();
7657 message3_nolog (m, nbytes, multibyte);
7659 UNGCPRO;
7663 /* The non-logging version of message3.
7664 This does not cancel echoing, because it is used for echoing.
7665 Perhaps we need to make a separate function for echoing
7666 and make this cancel echoing. */
7668 void
7669 message3_nolog (m, nbytes, multibyte)
7670 Lisp_Object m;
7671 int nbytes, multibyte;
7673 struct frame *sf = SELECTED_FRAME ();
7674 message_enable_multibyte = multibyte;
7676 if (noninteractive)
7678 if (noninteractive_need_newline)
7679 putc ('\n', stderr);
7680 noninteractive_need_newline = 0;
7681 if (STRINGP (m))
7682 fwrite (SDATA (m), nbytes, 1, stderr);
7683 if (cursor_in_echo_area == 0)
7684 fprintf (stderr, "\n");
7685 fflush (stderr);
7687 /* A null message buffer means that the frame hasn't really been
7688 initialized yet. Error messages get reported properly by
7689 cmd_error, so this must be just an informative message; toss it. */
7690 else if (INTERACTIVE
7691 && sf->glyphs_initialized_p
7692 && FRAME_MESSAGE_BUF (sf))
7694 Lisp_Object mini_window;
7695 Lisp_Object frame;
7696 struct frame *f;
7698 /* Get the frame containing the mini-buffer
7699 that the selected frame is using. */
7700 mini_window = FRAME_MINIBUF_WINDOW (sf);
7701 frame = XWINDOW (mini_window)->frame;
7702 f = XFRAME (frame);
7704 FRAME_SAMPLE_VISIBILITY (f);
7705 if (FRAME_VISIBLE_P (sf)
7706 && !FRAME_VISIBLE_P (f))
7707 Fmake_frame_visible (frame);
7709 if (STRINGP (m) && SCHARS (m) > 0)
7711 set_message (NULL, m, nbytes, multibyte);
7712 if (minibuffer_auto_raise)
7713 Fraise_frame (frame);
7714 /* Assume we are not echoing.
7715 (If we are, echo_now will override this.) */
7716 echo_message_buffer = Qnil;
7718 else
7719 clear_message (1, 1);
7721 do_pending_window_change (0);
7722 echo_area_display (1);
7723 do_pending_window_change (0);
7724 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
7725 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
7730 /* Display a null-terminated echo area message M. If M is 0, clear
7731 out any existing message, and let the mini-buffer text show through.
7733 The buffer M must continue to exist until after the echo area gets
7734 cleared or some other message gets displayed there. Do not pass
7735 text that is stored in a Lisp string. Do not pass text in a buffer
7736 that was alloca'd. */
7738 void
7739 message1 (m)
7740 char *m;
7742 message2 (m, (m ? strlen (m) : 0), 0);
7746 /* The non-logging counterpart of message1. */
7748 void
7749 message1_nolog (m)
7750 char *m;
7752 message2_nolog (m, (m ? strlen (m) : 0), 0);
7755 /* Display a message M which contains a single %s
7756 which gets replaced with STRING. */
7758 void
7759 message_with_string (m, string, log)
7760 char *m;
7761 Lisp_Object string;
7762 int log;
7764 CHECK_STRING (string);
7766 if (noninteractive)
7768 if (m)
7770 if (noninteractive_need_newline)
7771 putc ('\n', stderr);
7772 noninteractive_need_newline = 0;
7773 fprintf (stderr, m, SDATA (string));
7774 if (cursor_in_echo_area == 0)
7775 fprintf (stderr, "\n");
7776 fflush (stderr);
7779 else if (INTERACTIVE)
7781 /* The frame whose minibuffer we're going to display the message on.
7782 It may be larger than the selected frame, so we need
7783 to use its buffer, not the selected frame's buffer. */
7784 Lisp_Object mini_window;
7785 struct frame *f, *sf = SELECTED_FRAME ();
7787 /* Get the frame containing the minibuffer
7788 that the selected frame is using. */
7789 mini_window = FRAME_MINIBUF_WINDOW (sf);
7790 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
7792 /* A null message buffer means that the frame hasn't really been
7793 initialized yet. Error messages get reported properly by
7794 cmd_error, so this must be just an informative message; toss it. */
7795 if (FRAME_MESSAGE_BUF (f))
7797 Lisp_Object args[2], message;
7798 struct gcpro gcpro1, gcpro2;
7800 args[0] = build_string (m);
7801 args[1] = message = string;
7802 GCPRO2 (args[0], message);
7803 gcpro1.nvars = 2;
7805 message = Fformat (2, args);
7807 if (log)
7808 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
7809 else
7810 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
7812 UNGCPRO;
7814 /* Print should start at the beginning of the message
7815 buffer next time. */
7816 message_buf_print = 0;
7822 /* Dump an informative message to the minibuf. If M is 0, clear out
7823 any existing message, and let the mini-buffer text show through. */
7825 /* VARARGS 1 */
7826 void
7827 message (m, a1, a2, a3)
7828 char *m;
7829 EMACS_INT a1, a2, a3;
7831 if (noninteractive)
7833 if (m)
7835 if (noninteractive_need_newline)
7836 putc ('\n', stderr);
7837 noninteractive_need_newline = 0;
7838 fprintf (stderr, m, a1, a2, a3);
7839 if (cursor_in_echo_area == 0)
7840 fprintf (stderr, "\n");
7841 fflush (stderr);
7844 else if (INTERACTIVE)
7846 /* The frame whose mini-buffer we're going to display the message
7847 on. It may be larger than the selected frame, so we need to
7848 use its buffer, not the selected frame's buffer. */
7849 Lisp_Object mini_window;
7850 struct frame *f, *sf = SELECTED_FRAME ();
7852 /* Get the frame containing the mini-buffer
7853 that the selected frame is using. */
7854 mini_window = FRAME_MINIBUF_WINDOW (sf);
7855 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
7857 /* A null message buffer means that the frame hasn't really been
7858 initialized yet. Error messages get reported properly by
7859 cmd_error, so this must be just an informative message; toss
7860 it. */
7861 if (FRAME_MESSAGE_BUF (f))
7863 if (m)
7865 int len;
7866 #ifdef NO_ARG_ARRAY
7867 char *a[3];
7868 a[0] = (char *) a1;
7869 a[1] = (char *) a2;
7870 a[2] = (char *) a3;
7872 len = doprnt (FRAME_MESSAGE_BUF (f),
7873 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
7874 #else
7875 len = doprnt (FRAME_MESSAGE_BUF (f),
7876 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
7877 (char **) &a1);
7878 #endif /* NO_ARG_ARRAY */
7880 message2 (FRAME_MESSAGE_BUF (f), len, 0);
7882 else
7883 message1 (0);
7885 /* Print should start at the beginning of the message
7886 buffer next time. */
7887 message_buf_print = 0;
7893 /* The non-logging version of message. */
7895 void
7896 message_nolog (m, a1, a2, a3)
7897 char *m;
7898 EMACS_INT a1, a2, a3;
7900 Lisp_Object old_log_max;
7901 old_log_max = Vmessage_log_max;
7902 Vmessage_log_max = Qnil;
7903 message (m, a1, a2, a3);
7904 Vmessage_log_max = old_log_max;
7908 /* Display the current message in the current mini-buffer. This is
7909 only called from error handlers in process.c, and is not time
7910 critical. */
7912 void
7913 update_echo_area ()
7915 if (!NILP (echo_area_buffer[0]))
7917 Lisp_Object string;
7918 string = Fcurrent_message ();
7919 message3 (string, SBYTES (string),
7920 !NILP (current_buffer->enable_multibyte_characters));
7925 /* Make sure echo area buffers in `echo_buffers' are live.
7926 If they aren't, make new ones. */
7928 static void
7929 ensure_echo_area_buffers ()
7931 int i;
7933 for (i = 0; i < 2; ++i)
7934 if (!BUFFERP (echo_buffer[i])
7935 || NILP (XBUFFER (echo_buffer[i])->name))
7937 char name[30];
7938 Lisp_Object old_buffer;
7939 int j;
7941 old_buffer = echo_buffer[i];
7942 sprintf (name, " *Echo Area %d*", i);
7943 echo_buffer[i] = Fget_buffer_create (build_string (name));
7944 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
7946 for (j = 0; j < 2; ++j)
7947 if (EQ (old_buffer, echo_area_buffer[j]))
7948 echo_area_buffer[j] = echo_buffer[i];
7953 /* Call FN with args A1..A4 with either the current or last displayed
7954 echo_area_buffer as current buffer.
7956 WHICH zero means use the current message buffer
7957 echo_area_buffer[0]. If that is nil, choose a suitable buffer
7958 from echo_buffer[] and clear it.
7960 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
7961 suitable buffer from echo_buffer[] and clear it.
7963 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
7964 that the current message becomes the last displayed one, make
7965 choose a suitable buffer for echo_area_buffer[0], and clear it.
7967 Value is what FN returns. */
7969 static int
7970 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
7971 struct window *w;
7972 int which;
7973 int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
7974 EMACS_INT a1;
7975 Lisp_Object a2;
7976 EMACS_INT a3, a4;
7978 Lisp_Object buffer;
7979 int this_one, the_other, clear_buffer_p, rc;
7980 int count = SPECPDL_INDEX ();
7982 /* If buffers aren't live, make new ones. */
7983 ensure_echo_area_buffers ();
7985 clear_buffer_p = 0;
7987 if (which == 0)
7988 this_one = 0, the_other = 1;
7989 else if (which > 0)
7990 this_one = 1, the_other = 0;
7991 else
7993 this_one = 0, the_other = 1;
7994 clear_buffer_p = 1;
7996 /* We need a fresh one in case the current echo buffer equals
7997 the one containing the last displayed echo area message. */
7998 if (!NILP (echo_area_buffer[this_one])
7999 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
8000 echo_area_buffer[this_one] = Qnil;
8003 /* Choose a suitable buffer from echo_buffer[] is we don't
8004 have one. */
8005 if (NILP (echo_area_buffer[this_one]))
8007 echo_area_buffer[this_one]
8008 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
8009 ? echo_buffer[the_other]
8010 : echo_buffer[this_one]);
8011 clear_buffer_p = 1;
8014 buffer = echo_area_buffer[this_one];
8016 /* Don't get confused by reusing the buffer used for echoing
8017 for a different purpose. */
8018 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
8019 cancel_echoing ();
8021 record_unwind_protect (unwind_with_echo_area_buffer,
8022 with_echo_area_buffer_unwind_data (w));
8024 /* Make the echo area buffer current. Note that for display
8025 purposes, it is not necessary that the displayed window's buffer
8026 == current_buffer, except for text property lookup. So, let's
8027 only set that buffer temporarily here without doing a full
8028 Fset_window_buffer. We must also change w->pointm, though,
8029 because otherwise an assertions in unshow_buffer fails, and Emacs
8030 aborts. */
8031 set_buffer_internal_1 (XBUFFER (buffer));
8032 if (w)
8034 w->buffer = buffer;
8035 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
8038 current_buffer->undo_list = Qt;
8039 current_buffer->read_only = Qnil;
8040 specbind (Qinhibit_read_only, Qt);
8041 specbind (Qinhibit_modification_hooks, Qt);
8043 if (clear_buffer_p && Z > BEG)
8044 del_range (BEG, Z);
8046 xassert (BEGV >= BEG);
8047 xassert (ZV <= Z && ZV >= BEGV);
8049 rc = fn (a1, a2, a3, a4);
8051 xassert (BEGV >= BEG);
8052 xassert (ZV <= Z && ZV >= BEGV);
8054 unbind_to (count, Qnil);
8055 return rc;
8059 /* Save state that should be preserved around the call to the function
8060 FN called in with_echo_area_buffer. */
8062 static Lisp_Object
8063 with_echo_area_buffer_unwind_data (w)
8064 struct window *w;
8066 int i = 0;
8067 Lisp_Object vector;
8069 /* Reduce consing by keeping one vector in
8070 Vwith_echo_area_save_vector. */
8071 vector = Vwith_echo_area_save_vector;
8072 Vwith_echo_area_save_vector = Qnil;
8074 if (NILP (vector))
8075 vector = Fmake_vector (make_number (7), Qnil);
8077 XSETBUFFER (AREF (vector, i), current_buffer); ++i;
8078 AREF (vector, i) = Vdeactivate_mark, ++i;
8079 AREF (vector, i) = make_number (windows_or_buffers_changed), ++i;
8081 if (w)
8083 XSETWINDOW (AREF (vector, i), w); ++i;
8084 AREF (vector, i) = w->buffer; ++i;
8085 AREF (vector, i) = make_number (XMARKER (w->pointm)->charpos); ++i;
8086 AREF (vector, i) = make_number (XMARKER (w->pointm)->bytepos); ++i;
8088 else
8090 int end = i + 4;
8091 for (; i < end; ++i)
8092 AREF (vector, i) = Qnil;
8095 xassert (i == ASIZE (vector));
8096 return vector;
8100 /* Restore global state from VECTOR which was created by
8101 with_echo_area_buffer_unwind_data. */
8103 static Lisp_Object
8104 unwind_with_echo_area_buffer (vector)
8105 Lisp_Object vector;
8107 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
8108 Vdeactivate_mark = AREF (vector, 1);
8109 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
8111 if (WINDOWP (AREF (vector, 3)))
8113 struct window *w;
8114 Lisp_Object buffer, charpos, bytepos;
8116 w = XWINDOW (AREF (vector, 3));
8117 buffer = AREF (vector, 4);
8118 charpos = AREF (vector, 5);
8119 bytepos = AREF (vector, 6);
8121 w->buffer = buffer;
8122 set_marker_both (w->pointm, buffer,
8123 XFASTINT (charpos), XFASTINT (bytepos));
8126 Vwith_echo_area_save_vector = vector;
8127 return Qnil;
8131 /* Set up the echo area for use by print functions. MULTIBYTE_P
8132 non-zero means we will print multibyte. */
8134 void
8135 setup_echo_area_for_printing (multibyte_p)
8136 int multibyte_p;
8138 /* If we can't find an echo area any more, exit. */
8139 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
8140 Fkill_emacs (Qnil);
8142 ensure_echo_area_buffers ();
8144 if (!message_buf_print)
8146 /* A message has been output since the last time we printed.
8147 Choose a fresh echo area buffer. */
8148 if (EQ (echo_area_buffer[1], echo_buffer[0]))
8149 echo_area_buffer[0] = echo_buffer[1];
8150 else
8151 echo_area_buffer[0] = echo_buffer[0];
8153 /* Switch to that buffer and clear it. */
8154 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
8155 current_buffer->truncate_lines = Qnil;
8157 if (Z > BEG)
8159 int count = SPECPDL_INDEX ();
8160 specbind (Qinhibit_read_only, Qt);
8161 /* Note that undo recording is always disabled. */
8162 del_range (BEG, Z);
8163 unbind_to (count, Qnil);
8165 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
8167 /* Set up the buffer for the multibyteness we need. */
8168 if (multibyte_p
8169 != !NILP (current_buffer->enable_multibyte_characters))
8170 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
8172 /* Raise the frame containing the echo area. */
8173 if (minibuffer_auto_raise)
8175 struct frame *sf = SELECTED_FRAME ();
8176 Lisp_Object mini_window;
8177 mini_window = FRAME_MINIBUF_WINDOW (sf);
8178 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
8181 message_log_maybe_newline ();
8182 message_buf_print = 1;
8184 else
8186 if (NILP (echo_area_buffer[0]))
8188 if (EQ (echo_area_buffer[1], echo_buffer[0]))
8189 echo_area_buffer[0] = echo_buffer[1];
8190 else
8191 echo_area_buffer[0] = echo_buffer[0];
8194 if (current_buffer != XBUFFER (echo_area_buffer[0]))
8196 /* Someone switched buffers between print requests. */
8197 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
8198 current_buffer->truncate_lines = Qnil;
8204 /* Display an echo area message in window W. Value is non-zero if W's
8205 height is changed. If display_last_displayed_message_p is
8206 non-zero, display the message that was last displayed, otherwise
8207 display the current message. */
8209 static int
8210 display_echo_area (w)
8211 struct window *w;
8213 int i, no_message_p, window_height_changed_p, count;
8215 /* Temporarily disable garbage collections while displaying the echo
8216 area. This is done because a GC can print a message itself.
8217 That message would modify the echo area buffer's contents while a
8218 redisplay of the buffer is going on, and seriously confuse
8219 redisplay. */
8220 count = inhibit_garbage_collection ();
8222 /* If there is no message, we must call display_echo_area_1
8223 nevertheless because it resizes the window. But we will have to
8224 reset the echo_area_buffer in question to nil at the end because
8225 with_echo_area_buffer will sets it to an empty buffer. */
8226 i = display_last_displayed_message_p ? 1 : 0;
8227 no_message_p = NILP (echo_area_buffer[i]);
8229 window_height_changed_p
8230 = with_echo_area_buffer (w, display_last_displayed_message_p,
8231 display_echo_area_1,
8232 (EMACS_INT) w, Qnil, 0, 0);
8234 if (no_message_p)
8235 echo_area_buffer[i] = Qnil;
8237 unbind_to (count, Qnil);
8238 return window_height_changed_p;
8242 /* Helper for display_echo_area. Display the current buffer which
8243 contains the current echo area message in window W, a mini-window,
8244 a pointer to which is passed in A1. A2..A4 are currently not used.
8245 Change the height of W so that all of the message is displayed.
8246 Value is non-zero if height of W was changed. */
8248 static int
8249 display_echo_area_1 (a1, a2, a3, a4)
8250 EMACS_INT a1;
8251 Lisp_Object a2;
8252 EMACS_INT a3, a4;
8254 struct window *w = (struct window *) a1;
8255 Lisp_Object window;
8256 struct text_pos start;
8257 int window_height_changed_p = 0;
8259 /* Do this before displaying, so that we have a large enough glyph
8260 matrix for the display. If we can't get enough space for the
8261 whole text, display the last N lines. That works by setting w->start. */
8262 window_height_changed_p = resize_mini_window (w, 0);
8264 /* Use the starting position chosen by resize_mini_window. */
8265 SET_TEXT_POS_FROM_MARKER (start, w->start);
8267 /* Display. */
8268 clear_glyph_matrix (w->desired_matrix);
8269 XSETWINDOW (window, w);
8270 try_window (window, start, 0);
8272 return window_height_changed_p;
8276 /* Resize the echo area window to exactly the size needed for the
8277 currently displayed message, if there is one. If a mini-buffer
8278 is active, don't shrink it. */
8280 void
8281 resize_echo_area_exactly ()
8283 if (BUFFERP (echo_area_buffer[0])
8284 && WINDOWP (echo_area_window))
8286 struct window *w = XWINDOW (echo_area_window);
8287 int resized_p;
8288 Lisp_Object resize_exactly;
8290 if (minibuf_level == 0)
8291 resize_exactly = Qt;
8292 else
8293 resize_exactly = Qnil;
8295 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
8296 (EMACS_INT) w, resize_exactly, 0, 0);
8297 if (resized_p)
8299 ++windows_or_buffers_changed;
8300 ++update_mode_lines;
8301 redisplay_internal (0);
8307 /* Callback function for with_echo_area_buffer, when used from
8308 resize_echo_area_exactly. A1 contains a pointer to the window to
8309 resize, EXACTLY non-nil means resize the mini-window exactly to the
8310 size of the text displayed. A3 and A4 are not used. Value is what
8311 resize_mini_window returns. */
8313 static int
8314 resize_mini_window_1 (a1, exactly, a3, a4)
8315 EMACS_INT a1;
8316 Lisp_Object exactly;
8317 EMACS_INT a3, a4;
8319 return resize_mini_window ((struct window *) a1, !NILP (exactly));
8323 /* Resize mini-window W to fit the size of its contents. EXACT:P
8324 means size the window exactly to the size needed. Otherwise, it's
8325 only enlarged until W's buffer is empty.
8327 Set W->start to the right place to begin display. If the whole
8328 contents fit, start at the beginning. Otherwise, start so as
8329 to make the end of the contents appear. This is particularly
8330 important for y-or-n-p, but seems desirable generally.
8332 Value is non-zero if the window height has been changed. */
8335 resize_mini_window (w, exact_p)
8336 struct window *w;
8337 int exact_p;
8339 struct frame *f = XFRAME (w->frame);
8340 int window_height_changed_p = 0;
8342 xassert (MINI_WINDOW_P (w));
8344 /* By default, start display at the beginning. */
8345 set_marker_both (w->start, w->buffer,
8346 BUF_BEGV (XBUFFER (w->buffer)),
8347 BUF_BEGV_BYTE (XBUFFER (w->buffer)));
8349 /* Don't resize windows while redisplaying a window; it would
8350 confuse redisplay functions when the size of the window they are
8351 displaying changes from under them. Such a resizing can happen,
8352 for instance, when which-func prints a long message while
8353 we are running fontification-functions. We're running these
8354 functions with safe_call which binds inhibit-redisplay to t. */
8355 if (!NILP (Vinhibit_redisplay))
8356 return 0;
8358 /* Nil means don't try to resize. */
8359 if (NILP (Vresize_mini_windows)
8360 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
8361 return 0;
8363 if (!FRAME_MINIBUF_ONLY_P (f))
8365 struct it it;
8366 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
8367 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
8368 int height, max_height;
8369 int unit = FRAME_LINE_HEIGHT (f);
8370 struct text_pos start;
8371 struct buffer *old_current_buffer = NULL;
8373 if (current_buffer != XBUFFER (w->buffer))
8375 old_current_buffer = current_buffer;
8376 set_buffer_internal (XBUFFER (w->buffer));
8379 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
8381 /* Compute the max. number of lines specified by the user. */
8382 if (FLOATP (Vmax_mini_window_height))
8383 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
8384 else if (INTEGERP (Vmax_mini_window_height))
8385 max_height = XINT (Vmax_mini_window_height);
8386 else
8387 max_height = total_height / 4;
8389 /* Correct that max. height if it's bogus. */
8390 max_height = max (1, max_height);
8391 max_height = min (total_height, max_height);
8393 /* Find out the height of the text in the window. */
8394 if (it.truncate_lines_p)
8395 height = 1;
8396 else
8398 last_height = 0;
8399 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
8400 if (it.max_ascent == 0 && it.max_descent == 0)
8401 height = it.current_y + last_height;
8402 else
8403 height = it.current_y + it.max_ascent + it.max_descent;
8404 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
8405 height = (height + unit - 1) / unit;
8408 /* Compute a suitable window start. */
8409 if (height > max_height)
8411 height = max_height;
8412 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
8413 move_it_vertically_backward (&it, (height - 1) * unit);
8414 start = it.current.pos;
8416 else
8417 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
8418 SET_MARKER_FROM_TEXT_POS (w->start, start);
8420 if (EQ (Vresize_mini_windows, Qgrow_only))
8422 /* Let it grow only, until we display an empty message, in which
8423 case the window shrinks again. */
8424 if (height > WINDOW_TOTAL_LINES (w))
8426 int old_height = WINDOW_TOTAL_LINES (w);
8427 freeze_window_starts (f, 1);
8428 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
8429 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8431 else if (height < WINDOW_TOTAL_LINES (w)
8432 && (exact_p || BEGV == ZV))
8434 int old_height = WINDOW_TOTAL_LINES (w);
8435 freeze_window_starts (f, 0);
8436 shrink_mini_window (w);
8437 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8440 else
8442 /* Always resize to exact size needed. */
8443 if (height > WINDOW_TOTAL_LINES (w))
8445 int old_height = WINDOW_TOTAL_LINES (w);
8446 freeze_window_starts (f, 1);
8447 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
8448 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8450 else if (height < WINDOW_TOTAL_LINES (w))
8452 int old_height = WINDOW_TOTAL_LINES (w);
8453 freeze_window_starts (f, 0);
8454 shrink_mini_window (w);
8456 if (height)
8458 freeze_window_starts (f, 1);
8459 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
8462 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8466 if (old_current_buffer)
8467 set_buffer_internal (old_current_buffer);
8470 return window_height_changed_p;
8474 /* Value is the current message, a string, or nil if there is no
8475 current message. */
8477 Lisp_Object
8478 current_message ()
8480 Lisp_Object msg;
8482 if (NILP (echo_area_buffer[0]))
8483 msg = Qnil;
8484 else
8486 with_echo_area_buffer (0, 0, current_message_1,
8487 (EMACS_INT) &msg, Qnil, 0, 0);
8488 if (NILP (msg))
8489 echo_area_buffer[0] = Qnil;
8492 return msg;
8496 static int
8497 current_message_1 (a1, a2, a3, a4)
8498 EMACS_INT a1;
8499 Lisp_Object a2;
8500 EMACS_INT a3, a4;
8502 Lisp_Object *msg = (Lisp_Object *) a1;
8504 if (Z > BEG)
8505 *msg = make_buffer_string (BEG, Z, 1);
8506 else
8507 *msg = Qnil;
8508 return 0;
8512 /* Push the current message on Vmessage_stack for later restauration
8513 by restore_message. Value is non-zero if the current message isn't
8514 empty. This is a relatively infrequent operation, so it's not
8515 worth optimizing. */
8518 push_message ()
8520 Lisp_Object msg;
8521 msg = current_message ();
8522 Vmessage_stack = Fcons (msg, Vmessage_stack);
8523 return STRINGP (msg);
8527 /* Restore message display from the top of Vmessage_stack. */
8529 void
8530 restore_message ()
8532 Lisp_Object msg;
8534 xassert (CONSP (Vmessage_stack));
8535 msg = XCAR (Vmessage_stack);
8536 if (STRINGP (msg))
8537 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
8538 else
8539 message3_nolog (msg, 0, 0);
8543 /* Handler for record_unwind_protect calling pop_message. */
8545 Lisp_Object
8546 pop_message_unwind (dummy)
8547 Lisp_Object dummy;
8549 pop_message ();
8550 return Qnil;
8553 /* Pop the top-most entry off Vmessage_stack. */
8555 void
8556 pop_message ()
8558 xassert (CONSP (Vmessage_stack));
8559 Vmessage_stack = XCDR (Vmessage_stack);
8563 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
8564 exits. If the stack is not empty, we have a missing pop_message
8565 somewhere. */
8567 void
8568 check_message_stack ()
8570 if (!NILP (Vmessage_stack))
8571 abort ();
8575 /* Truncate to NCHARS what will be displayed in the echo area the next
8576 time we display it---but don't redisplay it now. */
8578 void
8579 truncate_echo_area (nchars)
8580 int nchars;
8582 if (nchars == 0)
8583 echo_area_buffer[0] = Qnil;
8584 /* A null message buffer means that the frame hasn't really been
8585 initialized yet. Error messages get reported properly by
8586 cmd_error, so this must be just an informative message; toss it. */
8587 else if (!noninteractive
8588 && INTERACTIVE
8589 && !NILP (echo_area_buffer[0]))
8591 struct frame *sf = SELECTED_FRAME ();
8592 if (FRAME_MESSAGE_BUF (sf))
8593 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
8598 /* Helper function for truncate_echo_area. Truncate the current
8599 message to at most NCHARS characters. */
8601 static int
8602 truncate_message_1 (nchars, a2, a3, a4)
8603 EMACS_INT nchars;
8604 Lisp_Object a2;
8605 EMACS_INT a3, a4;
8607 if (BEG + nchars < Z)
8608 del_range (BEG + nchars, Z);
8609 if (Z == BEG)
8610 echo_area_buffer[0] = Qnil;
8611 return 0;
8615 /* Set the current message to a substring of S or STRING.
8617 If STRING is a Lisp string, set the message to the first NBYTES
8618 bytes from STRING. NBYTES zero means use the whole string. If
8619 STRING is multibyte, the message will be displayed multibyte.
8621 If S is not null, set the message to the first LEN bytes of S. LEN
8622 zero means use the whole string. MULTIBYTE_P non-zero means S is
8623 multibyte. Display the message multibyte in that case.
8625 Doesn't GC, as with_echo_area_buffer binds Qinhibit_modification_hooks
8626 to t before calling set_message_1 (which calls insert).
8629 void
8630 set_message (s, string, nbytes, multibyte_p)
8631 const char *s;
8632 Lisp_Object string;
8633 int nbytes, multibyte_p;
8635 message_enable_multibyte
8636 = ((s && multibyte_p)
8637 || (STRINGP (string) && STRING_MULTIBYTE (string)));
8639 with_echo_area_buffer (0, -1, set_message_1,
8640 (EMACS_INT) s, string, nbytes, multibyte_p);
8641 message_buf_print = 0;
8642 help_echo_showing_p = 0;
8646 /* Helper function for set_message. Arguments have the same meaning
8647 as there, with A1 corresponding to S and A2 corresponding to STRING
8648 This function is called with the echo area buffer being
8649 current. */
8651 static int
8652 set_message_1 (a1, a2, nbytes, multibyte_p)
8653 EMACS_INT a1;
8654 Lisp_Object a2;
8655 EMACS_INT nbytes, multibyte_p;
8657 const char *s = (const char *) a1;
8658 Lisp_Object string = a2;
8660 /* Change multibyteness of the echo buffer appropriately. */
8661 if (message_enable_multibyte
8662 != !NILP (current_buffer->enable_multibyte_characters))
8663 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
8665 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
8667 /* Insert new message at BEG. */
8668 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
8670 if (STRINGP (string))
8672 int nchars;
8674 if (nbytes == 0)
8675 nbytes = SBYTES (string);
8676 nchars = string_byte_to_char (string, nbytes);
8678 /* This function takes care of single/multibyte conversion. We
8679 just have to ensure that the echo area buffer has the right
8680 setting of enable_multibyte_characters. */
8681 insert_from_string (string, 0, 0, nchars, nbytes, 1);
8683 else if (s)
8685 if (nbytes == 0)
8686 nbytes = strlen (s);
8688 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
8690 /* Convert from multi-byte to single-byte. */
8691 int i, c, n;
8692 unsigned char work[1];
8694 /* Convert a multibyte string to single-byte. */
8695 for (i = 0; i < nbytes; i += n)
8697 c = string_char_and_length (s + i, nbytes - i, &n);
8698 work[0] = (SINGLE_BYTE_CHAR_P (c)
8700 : multibyte_char_to_unibyte (c, Qnil));
8701 insert_1_both (work, 1, 1, 1, 0, 0);
8704 else if (!multibyte_p
8705 && !NILP (current_buffer->enable_multibyte_characters))
8707 /* Convert from single-byte to multi-byte. */
8708 int i, c, n;
8709 const unsigned char *msg = (const unsigned char *) s;
8710 unsigned char str[MAX_MULTIBYTE_LENGTH];
8712 /* Convert a single-byte string to multibyte. */
8713 for (i = 0; i < nbytes; i++)
8715 c = unibyte_char_to_multibyte (msg[i]);
8716 n = CHAR_STRING (c, str);
8717 insert_1_both (str, 1, n, 1, 0, 0);
8720 else
8721 insert_1 (s, nbytes, 1, 0, 0);
8724 return 0;
8728 /* Clear messages. CURRENT_P non-zero means clear the current
8729 message. LAST_DISPLAYED_P non-zero means clear the message
8730 last displayed. */
8732 void
8733 clear_message (current_p, last_displayed_p)
8734 int current_p, last_displayed_p;
8736 if (current_p)
8738 echo_area_buffer[0] = Qnil;
8739 message_cleared_p = 1;
8742 if (last_displayed_p)
8743 echo_area_buffer[1] = Qnil;
8745 message_buf_print = 0;
8748 /* Clear garbaged frames.
8750 This function is used where the old redisplay called
8751 redraw_garbaged_frames which in turn called redraw_frame which in
8752 turn called clear_frame. The call to clear_frame was a source of
8753 flickering. I believe a clear_frame is not necessary. It should
8754 suffice in the new redisplay to invalidate all current matrices,
8755 and ensure a complete redisplay of all windows. */
8757 static void
8758 clear_garbaged_frames ()
8760 if (frame_garbaged)
8762 Lisp_Object tail, frame;
8763 int changed_count = 0;
8765 FOR_EACH_FRAME (tail, frame)
8767 struct frame *f = XFRAME (frame);
8769 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
8771 if (f->resized_p)
8773 Fredraw_frame (frame);
8774 f->force_flush_display_p = 1;
8776 clear_current_matrices (f);
8777 changed_count++;
8778 f->garbaged = 0;
8779 f->resized_p = 0;
8783 frame_garbaged = 0;
8784 if (changed_count)
8785 ++windows_or_buffers_changed;
8790 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
8791 is non-zero update selected_frame. Value is non-zero if the
8792 mini-windows height has been changed. */
8794 static int
8795 echo_area_display (update_frame_p)
8796 int update_frame_p;
8798 Lisp_Object mini_window;
8799 struct window *w;
8800 struct frame *f;
8801 int window_height_changed_p = 0;
8802 struct frame *sf = SELECTED_FRAME ();
8804 mini_window = FRAME_MINIBUF_WINDOW (sf);
8805 w = XWINDOW (mini_window);
8806 f = XFRAME (WINDOW_FRAME (w));
8808 /* Don't display if frame is invisible or not yet initialized. */
8809 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
8810 return 0;
8812 #ifdef HAVE_WINDOW_SYSTEM
8813 /* When Emacs starts, selected_frame may be the initial terminal
8814 frame. If we let this through, a message would be displayed on
8815 the terminal. */
8816 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
8817 return 0;
8818 #endif /* HAVE_WINDOW_SYSTEM */
8820 /* Redraw garbaged frames. */
8821 if (frame_garbaged)
8822 clear_garbaged_frames ();
8824 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
8826 echo_area_window = mini_window;
8827 window_height_changed_p = display_echo_area (w);
8828 w->must_be_updated_p = 1;
8830 /* Update the display, unless called from redisplay_internal.
8831 Also don't update the screen during redisplay itself. The
8832 update will happen at the end of redisplay, and an update
8833 here could cause confusion. */
8834 if (update_frame_p && !redisplaying_p)
8836 int n = 0;
8838 /* If the display update has been interrupted by pending
8839 input, update mode lines in the frame. Due to the
8840 pending input, it might have been that redisplay hasn't
8841 been called, so that mode lines above the echo area are
8842 garbaged. This looks odd, so we prevent it here. */
8843 if (!display_completed)
8844 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
8846 if (window_height_changed_p
8847 /* Don't do this if Emacs is shutting down. Redisplay
8848 needs to run hooks. */
8849 && !NILP (Vrun_hooks))
8851 /* Must update other windows. Likewise as in other
8852 cases, don't let this update be interrupted by
8853 pending input. */
8854 int count = SPECPDL_INDEX ();
8855 specbind (Qredisplay_dont_pause, Qt);
8856 windows_or_buffers_changed = 1;
8857 redisplay_internal (0);
8858 unbind_to (count, Qnil);
8860 else if (FRAME_WINDOW_P (f) && n == 0)
8862 /* Window configuration is the same as before.
8863 Can do with a display update of the echo area,
8864 unless we displayed some mode lines. */
8865 update_single_window (w, 1);
8866 FRAME_RIF (f)->flush_display (f);
8868 else
8869 update_frame (f, 1, 1);
8871 /* If cursor is in the echo area, make sure that the next
8872 redisplay displays the minibuffer, so that the cursor will
8873 be replaced with what the minibuffer wants. */
8874 if (cursor_in_echo_area)
8875 ++windows_or_buffers_changed;
8878 else if (!EQ (mini_window, selected_window))
8879 windows_or_buffers_changed++;
8881 /* Last displayed message is now the current message. */
8882 echo_area_buffer[1] = echo_area_buffer[0];
8883 /* Inform read_char that we're not echoing. */
8884 echo_message_buffer = Qnil;
8886 /* Prevent redisplay optimization in redisplay_internal by resetting
8887 this_line_start_pos. This is done because the mini-buffer now
8888 displays the message instead of its buffer text. */
8889 if (EQ (mini_window, selected_window))
8890 CHARPOS (this_line_start_pos) = 0;
8892 return window_height_changed_p;
8897 /***********************************************************************
8898 Mode Lines and Frame Titles
8899 ***********************************************************************/
8901 /* A buffer for constructing non-propertized mode-line strings and
8902 frame titles in it; allocated from the heap in init_xdisp and
8903 resized as needed in store_mode_line_noprop_char. */
8905 static char *mode_line_noprop_buf;
8907 /* The buffer's end, and a current output position in it. */
8909 static char *mode_line_noprop_buf_end;
8910 static char *mode_line_noprop_ptr;
8912 #define MODE_LINE_NOPROP_LEN(start) \
8913 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
8915 static enum {
8916 MODE_LINE_DISPLAY = 0,
8917 MODE_LINE_TITLE,
8918 MODE_LINE_NOPROP,
8919 MODE_LINE_STRING
8920 } mode_line_target;
8922 /* Alist that caches the results of :propertize.
8923 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
8924 static Lisp_Object mode_line_proptrans_alist;
8926 /* List of strings making up the mode-line. */
8927 static Lisp_Object mode_line_string_list;
8929 /* Base face property when building propertized mode line string. */
8930 static Lisp_Object mode_line_string_face;
8931 static Lisp_Object mode_line_string_face_prop;
8934 /* Unwind data for mode line strings */
8936 static Lisp_Object Vmode_line_unwind_vector;
8938 static Lisp_Object
8939 format_mode_line_unwind_data (obuf, save_proptrans)
8940 struct buffer *obuf;
8942 Lisp_Object vector;
8944 /* Reduce consing by keeping one vector in
8945 Vwith_echo_area_save_vector. */
8946 vector = Vmode_line_unwind_vector;
8947 Vmode_line_unwind_vector = Qnil;
8949 if (NILP (vector))
8950 vector = Fmake_vector (make_number (7), Qnil);
8952 AREF (vector, 0) = make_number (mode_line_target);
8953 AREF (vector, 1) = make_number (MODE_LINE_NOPROP_LEN (0));
8954 AREF (vector, 2) = mode_line_string_list;
8955 AREF (vector, 3) = (save_proptrans ? mode_line_proptrans_alist : Qt);
8956 AREF (vector, 4) = mode_line_string_face;
8957 AREF (vector, 5) = mode_line_string_face_prop;
8959 if (obuf)
8960 XSETBUFFER (AREF (vector, 6), obuf);
8961 else
8962 AREF (vector, 6) = Qnil;
8964 return vector;
8967 static Lisp_Object
8968 unwind_format_mode_line (vector)
8969 Lisp_Object vector;
8971 mode_line_target = XINT (AREF (vector, 0));
8972 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
8973 mode_line_string_list = AREF (vector, 2);
8974 if (! EQ (AREF (vector, 3), Qt))
8975 mode_line_proptrans_alist = AREF (vector, 3);
8976 mode_line_string_face = AREF (vector, 4);
8977 mode_line_string_face_prop = AREF (vector, 5);
8979 if (!NILP (AREF (vector, 6)))
8981 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
8982 AREF (vector, 6) = Qnil;
8985 Vmode_line_unwind_vector = vector;
8986 return Qnil;
8990 /* Store a single character C for the frame title in mode_line_noprop_buf.
8991 Re-allocate mode_line_noprop_buf if necessary. */
8993 static void
8994 #ifdef PROTOTYPES
8995 store_mode_line_noprop_char (char c)
8996 #else
8997 store_mode_line_noprop_char (c)
8998 char c;
8999 #endif
9001 /* If output position has reached the end of the allocated buffer,
9002 double the buffer's size. */
9003 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
9005 int len = MODE_LINE_NOPROP_LEN (0);
9006 int new_size = 2 * len * sizeof *mode_line_noprop_buf;
9007 mode_line_noprop_buf = (char *) xrealloc (mode_line_noprop_buf, new_size);
9008 mode_line_noprop_buf_end = mode_line_noprop_buf + new_size;
9009 mode_line_noprop_ptr = mode_line_noprop_buf + len;
9012 *mode_line_noprop_ptr++ = c;
9016 /* Store part of a frame title in mode_line_noprop_buf, beginning at
9017 mode_line_noprop_ptr. STR is the string to store. Do not copy
9018 characters that yield more columns than PRECISION; PRECISION <= 0
9019 means copy the whole string. Pad with spaces until FIELD_WIDTH
9020 number of characters have been copied; FIELD_WIDTH <= 0 means don't
9021 pad. Called from display_mode_element when it is used to build a
9022 frame title. */
9024 static int
9025 store_mode_line_noprop (str, field_width, precision)
9026 const unsigned char *str;
9027 int field_width, precision;
9029 int n = 0;
9030 int dummy, nbytes;
9032 /* Copy at most PRECISION chars from STR. */
9033 nbytes = strlen (str);
9034 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
9035 while (nbytes--)
9036 store_mode_line_noprop_char (*str++);
9038 /* Fill up with spaces until FIELD_WIDTH reached. */
9039 while (field_width > 0
9040 && n < field_width)
9042 store_mode_line_noprop_char (' ');
9043 ++n;
9046 return n;
9049 /***********************************************************************
9050 Frame Titles
9051 ***********************************************************************/
9053 #ifdef HAVE_WINDOW_SYSTEM
9055 /* Set the title of FRAME, if it has changed. The title format is
9056 Vicon_title_format if FRAME is iconified, otherwise it is
9057 frame_title_format. */
9059 static void
9060 x_consider_frame_title (frame)
9061 Lisp_Object frame;
9063 struct frame *f = XFRAME (frame);
9065 if (FRAME_WINDOW_P (f)
9066 || FRAME_MINIBUF_ONLY_P (f)
9067 || f->explicit_name)
9069 /* Do we have more than one visible frame on this X display? */
9070 Lisp_Object tail;
9071 Lisp_Object fmt;
9072 int title_start;
9073 char *title;
9074 int len;
9075 struct it it;
9076 int count = SPECPDL_INDEX ();
9078 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
9080 Lisp_Object other_frame = XCAR (tail);
9081 struct frame *tf = XFRAME (other_frame);
9083 if (tf != f
9084 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
9085 && !FRAME_MINIBUF_ONLY_P (tf)
9086 && !EQ (other_frame, tip_frame)
9087 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
9088 break;
9091 /* Set global variable indicating that multiple frames exist. */
9092 multiple_frames = CONSP (tail);
9094 /* Switch to the buffer of selected window of the frame. Set up
9095 mode_line_target so that display_mode_element will output into
9096 mode_line_noprop_buf; then display the title. */
9097 record_unwind_protect (unwind_format_mode_line,
9098 format_mode_line_unwind_data (current_buffer, 0));
9100 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
9101 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
9103 mode_line_target = MODE_LINE_TITLE;
9104 title_start = MODE_LINE_NOPROP_LEN (0);
9105 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
9106 NULL, DEFAULT_FACE_ID);
9107 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
9108 len = MODE_LINE_NOPROP_LEN (title_start);
9109 title = mode_line_noprop_buf + title_start;
9110 unbind_to (count, Qnil);
9112 /* Set the title only if it's changed. This avoids consing in
9113 the common case where it hasn't. (If it turns out that we've
9114 already wasted too much time by walking through the list with
9115 display_mode_element, then we might need to optimize at a
9116 higher level than this.) */
9117 if (! STRINGP (f->name)
9118 || SBYTES (f->name) != len
9119 || bcmp (title, SDATA (f->name), len) != 0)
9120 x_implicitly_set_name (f, make_string (title, len), Qnil);
9124 #endif /* not HAVE_WINDOW_SYSTEM */
9129 /***********************************************************************
9130 Menu Bars
9131 ***********************************************************************/
9134 /* Prepare for redisplay by updating menu-bar item lists when
9135 appropriate. This can call eval. */
9137 void
9138 prepare_menu_bars ()
9140 int all_windows;
9141 struct gcpro gcpro1, gcpro2;
9142 struct frame *f;
9143 Lisp_Object tooltip_frame;
9145 #ifdef HAVE_WINDOW_SYSTEM
9146 tooltip_frame = tip_frame;
9147 #else
9148 tooltip_frame = Qnil;
9149 #endif
9151 /* Update all frame titles based on their buffer names, etc. We do
9152 this before the menu bars so that the buffer-menu will show the
9153 up-to-date frame titles. */
9154 #ifdef HAVE_WINDOW_SYSTEM
9155 if (windows_or_buffers_changed || update_mode_lines)
9157 Lisp_Object tail, frame;
9159 FOR_EACH_FRAME (tail, frame)
9161 f = XFRAME (frame);
9162 if (!EQ (frame, tooltip_frame)
9163 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
9164 x_consider_frame_title (frame);
9167 #endif /* HAVE_WINDOW_SYSTEM */
9169 /* Update the menu bar item lists, if appropriate. This has to be
9170 done before any actual redisplay or generation of display lines. */
9171 all_windows = (update_mode_lines
9172 || buffer_shared > 1
9173 || windows_or_buffers_changed);
9174 if (all_windows)
9176 Lisp_Object tail, frame;
9177 int count = SPECPDL_INDEX ();
9178 /* 1 means that update_menu_bar has run its hooks
9179 so any further calls to update_menu_bar shouldn't do so again. */
9180 int menu_bar_hooks_run = 0;
9182 record_unwind_save_match_data ();
9184 FOR_EACH_FRAME (tail, frame)
9186 f = XFRAME (frame);
9188 /* Ignore tooltip frame. */
9189 if (EQ (frame, tooltip_frame))
9190 continue;
9192 /* If a window on this frame changed size, report that to
9193 the user and clear the size-change flag. */
9194 if (FRAME_WINDOW_SIZES_CHANGED (f))
9196 Lisp_Object functions;
9198 /* Clear flag first in case we get an error below. */
9199 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
9200 functions = Vwindow_size_change_functions;
9201 GCPRO2 (tail, functions);
9203 while (CONSP (functions))
9205 call1 (XCAR (functions), frame);
9206 functions = XCDR (functions);
9208 UNGCPRO;
9211 GCPRO1 (tail);
9212 menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
9213 #ifdef HAVE_WINDOW_SYSTEM
9214 update_tool_bar (f, 0);
9215 #ifdef MAC_OS
9216 mac_update_title_bar (f, 0);
9217 #endif
9218 #endif
9219 UNGCPRO;
9222 unbind_to (count, Qnil);
9224 else
9226 struct frame *sf = SELECTED_FRAME ();
9227 update_menu_bar (sf, 1, 0);
9228 #ifdef HAVE_WINDOW_SYSTEM
9229 update_tool_bar (sf, 1);
9230 #ifdef MAC_OS
9231 mac_update_title_bar (sf, 1);
9232 #endif
9233 #endif
9236 /* Motif needs this. See comment in xmenu.c. Turn it off when
9237 pending_menu_activation is not defined. */
9238 #ifdef USE_X_TOOLKIT
9239 pending_menu_activation = 0;
9240 #endif
9244 /* Update the menu bar item list for frame F. This has to be done
9245 before we start to fill in any display lines, because it can call
9246 eval.
9248 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
9250 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
9251 already ran the menu bar hooks for this redisplay, so there
9252 is no need to run them again. The return value is the
9253 updated value of this flag, to pass to the next call. */
9255 static int
9256 update_menu_bar (f, save_match_data, hooks_run)
9257 struct frame *f;
9258 int save_match_data;
9259 int hooks_run;
9261 Lisp_Object window;
9262 register struct window *w;
9264 /* If called recursively during a menu update, do nothing. This can
9265 happen when, for instance, an activate-menubar-hook causes a
9266 redisplay. */
9267 if (inhibit_menubar_update)
9268 return hooks_run;
9270 window = FRAME_SELECTED_WINDOW (f);
9271 w = XWINDOW (window);
9273 #if 0 /* The if statement below this if statement used to include the
9274 condition !NILP (w->update_mode_line), rather than using
9275 update_mode_lines directly, and this if statement may have
9276 been added to make that condition work. Now the if
9277 statement below matches its comment, this isn't needed. */
9278 if (update_mode_lines)
9279 w->update_mode_line = Qt;
9280 #endif
9282 if (FRAME_WINDOW_P (f)
9284 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
9285 || defined (USE_GTK)
9286 FRAME_EXTERNAL_MENU_BAR (f)
9287 #else
9288 FRAME_MENU_BAR_LINES (f) > 0
9289 #endif
9290 : FRAME_MENU_BAR_LINES (f) > 0)
9292 /* If the user has switched buffers or windows, we need to
9293 recompute to reflect the new bindings. But we'll
9294 recompute when update_mode_lines is set too; that means
9295 that people can use force-mode-line-update to request
9296 that the menu bar be recomputed. The adverse effect on
9297 the rest of the redisplay algorithm is about the same as
9298 windows_or_buffers_changed anyway. */
9299 if (windows_or_buffers_changed
9300 /* This used to test w->update_mode_line, but we believe
9301 there is no need to recompute the menu in that case. */
9302 || update_mode_lines
9303 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
9304 < BUF_MODIFF (XBUFFER (w->buffer)))
9305 != !NILP (w->last_had_star))
9306 || ((!NILP (Vtransient_mark_mode)
9307 && !NILP (XBUFFER (w->buffer)->mark_active))
9308 != !NILP (w->region_showing)))
9310 struct buffer *prev = current_buffer;
9311 int count = SPECPDL_INDEX ();
9313 specbind (Qinhibit_menubar_update, Qt);
9315 set_buffer_internal_1 (XBUFFER (w->buffer));
9316 if (save_match_data)
9317 record_unwind_save_match_data ();
9318 if (NILP (Voverriding_local_map_menu_flag))
9320 specbind (Qoverriding_terminal_local_map, Qnil);
9321 specbind (Qoverriding_local_map, Qnil);
9324 if (!hooks_run)
9326 /* Run the Lucid hook. */
9327 safe_run_hooks (Qactivate_menubar_hook);
9329 /* If it has changed current-menubar from previous value,
9330 really recompute the menu-bar from the value. */
9331 if (! NILP (Vlucid_menu_bar_dirty_flag))
9332 call0 (Qrecompute_lucid_menubar);
9334 safe_run_hooks (Qmenu_bar_update_hook);
9336 hooks_run = 1;
9339 XSETFRAME (Vmenu_updating_frame, f);
9340 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
9342 /* Redisplay the menu bar in case we changed it. */
9343 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
9344 || defined (USE_GTK)
9345 if (FRAME_WINDOW_P (f))
9347 #ifdef MAC_OS
9348 /* All frames on Mac OS share the same menubar. So only
9349 the selected frame should be allowed to set it. */
9350 if (f == SELECTED_FRAME ())
9351 #endif
9352 set_frame_menubar (f, 0, 0);
9354 else
9355 /* On a terminal screen, the menu bar is an ordinary screen
9356 line, and this makes it get updated. */
9357 w->update_mode_line = Qt;
9358 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
9359 /* In the non-toolkit version, the menu bar is an ordinary screen
9360 line, and this makes it get updated. */
9361 w->update_mode_line = Qt;
9362 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
9364 unbind_to (count, Qnil);
9365 set_buffer_internal_1 (prev);
9369 return hooks_run;
9374 /***********************************************************************
9375 Output Cursor
9376 ***********************************************************************/
9378 #ifdef HAVE_WINDOW_SYSTEM
9380 /* EXPORT:
9381 Nominal cursor position -- where to draw output.
9382 HPOS and VPOS are window relative glyph matrix coordinates.
9383 X and Y are window relative pixel coordinates. */
9385 struct cursor_pos output_cursor;
9388 /* EXPORT:
9389 Set the global variable output_cursor to CURSOR. All cursor
9390 positions are relative to updated_window. */
9392 void
9393 set_output_cursor (cursor)
9394 struct cursor_pos *cursor;
9396 output_cursor.hpos = cursor->hpos;
9397 output_cursor.vpos = cursor->vpos;
9398 output_cursor.x = cursor->x;
9399 output_cursor.y = cursor->y;
9403 /* EXPORT for RIF:
9404 Set a nominal cursor position.
9406 HPOS and VPOS are column/row positions in a window glyph matrix. X
9407 and Y are window text area relative pixel positions.
9409 If this is done during an update, updated_window will contain the
9410 window that is being updated and the position is the future output
9411 cursor position for that window. If updated_window is null, use
9412 selected_window and display the cursor at the given position. */
9414 void
9415 x_cursor_to (vpos, hpos, y, x)
9416 int vpos, hpos, y, x;
9418 struct window *w;
9420 /* If updated_window is not set, work on selected_window. */
9421 if (updated_window)
9422 w = updated_window;
9423 else
9424 w = XWINDOW (selected_window);
9426 /* Set the output cursor. */
9427 output_cursor.hpos = hpos;
9428 output_cursor.vpos = vpos;
9429 output_cursor.x = x;
9430 output_cursor.y = y;
9432 /* If not called as part of an update, really display the cursor.
9433 This will also set the cursor position of W. */
9434 if (updated_window == NULL)
9436 BLOCK_INPUT;
9437 display_and_set_cursor (w, 1, hpos, vpos, x, y);
9438 if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
9439 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
9440 UNBLOCK_INPUT;
9444 #endif /* HAVE_WINDOW_SYSTEM */
9447 /***********************************************************************
9448 Tool-bars
9449 ***********************************************************************/
9451 #ifdef HAVE_WINDOW_SYSTEM
9453 /* Where the mouse was last time we reported a mouse event. */
9455 FRAME_PTR last_mouse_frame;
9457 /* Tool-bar item index of the item on which a mouse button was pressed
9458 or -1. */
9460 int last_tool_bar_item;
9463 /* Update the tool-bar item list for frame F. This has to be done
9464 before we start to fill in any display lines. Called from
9465 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
9466 and restore it here. */
9468 static void
9469 update_tool_bar (f, save_match_data)
9470 struct frame *f;
9471 int save_match_data;
9473 #if defined (USE_GTK) || USE_MAC_TOOLBAR
9474 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
9475 #else
9476 int do_update = WINDOWP (f->tool_bar_window)
9477 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
9478 #endif
9480 if (do_update)
9482 Lisp_Object window;
9483 struct window *w;
9485 window = FRAME_SELECTED_WINDOW (f);
9486 w = XWINDOW (window);
9488 /* If the user has switched buffers or windows, we need to
9489 recompute to reflect the new bindings. But we'll
9490 recompute when update_mode_lines is set too; that means
9491 that people can use force-mode-line-update to request
9492 that the menu bar be recomputed. The adverse effect on
9493 the rest of the redisplay algorithm is about the same as
9494 windows_or_buffers_changed anyway. */
9495 if (windows_or_buffers_changed
9496 || !NILP (w->update_mode_line)
9497 || update_mode_lines
9498 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
9499 < BUF_MODIFF (XBUFFER (w->buffer)))
9500 != !NILP (w->last_had_star))
9501 || ((!NILP (Vtransient_mark_mode)
9502 && !NILP (XBUFFER (w->buffer)->mark_active))
9503 != !NILP (w->region_showing)))
9505 struct buffer *prev = current_buffer;
9506 int count = SPECPDL_INDEX ();
9507 Lisp_Object new_tool_bar;
9508 int new_n_tool_bar;
9509 struct gcpro gcpro1;
9511 /* Set current_buffer to the buffer of the selected
9512 window of the frame, so that we get the right local
9513 keymaps. */
9514 set_buffer_internal_1 (XBUFFER (w->buffer));
9516 /* Save match data, if we must. */
9517 if (save_match_data)
9518 record_unwind_save_match_data ();
9520 /* Make sure that we don't accidentally use bogus keymaps. */
9521 if (NILP (Voverriding_local_map_menu_flag))
9523 specbind (Qoverriding_terminal_local_map, Qnil);
9524 specbind (Qoverriding_local_map, Qnil);
9527 GCPRO1 (new_tool_bar);
9529 /* Build desired tool-bar items from keymaps. */
9530 new_tool_bar = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
9531 &new_n_tool_bar);
9533 /* Redisplay the tool-bar if we changed it. */
9534 if (new_n_tool_bar != f->n_tool_bar_items
9535 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
9537 /* Redisplay that happens asynchronously due to an expose event
9538 may access f->tool_bar_items. Make sure we update both
9539 variables within BLOCK_INPUT so no such event interrupts. */
9540 BLOCK_INPUT;
9541 f->tool_bar_items = new_tool_bar;
9542 f->n_tool_bar_items = new_n_tool_bar;
9543 w->update_mode_line = Qt;
9544 UNBLOCK_INPUT;
9547 UNGCPRO;
9549 unbind_to (count, Qnil);
9550 set_buffer_internal_1 (prev);
9556 /* Set F->desired_tool_bar_string to a Lisp string representing frame
9557 F's desired tool-bar contents. F->tool_bar_items must have
9558 been set up previously by calling prepare_menu_bars. */
9560 static void
9561 build_desired_tool_bar_string (f)
9562 struct frame *f;
9564 int i, size, size_needed;
9565 struct gcpro gcpro1, gcpro2, gcpro3;
9566 Lisp_Object image, plist, props;
9568 image = plist = props = Qnil;
9569 GCPRO3 (image, plist, props);
9571 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
9572 Otherwise, make a new string. */
9574 /* The size of the string we might be able to reuse. */
9575 size = (STRINGP (f->desired_tool_bar_string)
9576 ? SCHARS (f->desired_tool_bar_string)
9577 : 0);
9579 /* We need one space in the string for each image. */
9580 size_needed = f->n_tool_bar_items;
9582 /* Reuse f->desired_tool_bar_string, if possible. */
9583 if (size < size_needed || NILP (f->desired_tool_bar_string))
9584 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
9585 make_number (' '));
9586 else
9588 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
9589 Fremove_text_properties (make_number (0), make_number (size),
9590 props, f->desired_tool_bar_string);
9593 /* Put a `display' property on the string for the images to display,
9594 put a `menu_item' property on tool-bar items with a value that
9595 is the index of the item in F's tool-bar item vector. */
9596 for (i = 0; i < f->n_tool_bar_items; ++i)
9598 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
9600 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
9601 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
9602 int hmargin, vmargin, relief, idx, end;
9603 extern Lisp_Object QCrelief, QCmargin, QCconversion;
9605 /* If image is a vector, choose the image according to the
9606 button state. */
9607 image = PROP (TOOL_BAR_ITEM_IMAGES);
9608 if (VECTORP (image))
9610 if (enabled_p)
9611 idx = (selected_p
9612 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
9613 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
9614 else
9615 idx = (selected_p
9616 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
9617 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
9619 xassert (ASIZE (image) >= idx);
9620 image = AREF (image, idx);
9622 else
9623 idx = -1;
9625 /* Ignore invalid image specifications. */
9626 if (!valid_image_p (image))
9627 continue;
9629 /* Display the tool-bar button pressed, or depressed. */
9630 plist = Fcopy_sequence (XCDR (image));
9632 /* Compute margin and relief to draw. */
9633 relief = (tool_bar_button_relief >= 0
9634 ? tool_bar_button_relief
9635 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
9636 hmargin = vmargin = relief;
9638 if (INTEGERP (Vtool_bar_button_margin)
9639 && XINT (Vtool_bar_button_margin) > 0)
9641 hmargin += XFASTINT (Vtool_bar_button_margin);
9642 vmargin += XFASTINT (Vtool_bar_button_margin);
9644 else if (CONSP (Vtool_bar_button_margin))
9646 if (INTEGERP (XCAR (Vtool_bar_button_margin))
9647 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
9648 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
9650 if (INTEGERP (XCDR (Vtool_bar_button_margin))
9651 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
9652 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
9655 if (auto_raise_tool_bar_buttons_p)
9657 /* Add a `:relief' property to the image spec if the item is
9658 selected. */
9659 if (selected_p)
9661 plist = Fplist_put (plist, QCrelief, make_number (-relief));
9662 hmargin -= relief;
9663 vmargin -= relief;
9666 else
9668 /* If image is selected, display it pressed, i.e. with a
9669 negative relief. If it's not selected, display it with a
9670 raised relief. */
9671 plist = Fplist_put (plist, QCrelief,
9672 (selected_p
9673 ? make_number (-relief)
9674 : make_number (relief)));
9675 hmargin -= relief;
9676 vmargin -= relief;
9679 /* Put a margin around the image. */
9680 if (hmargin || vmargin)
9682 if (hmargin == vmargin)
9683 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
9684 else
9685 plist = Fplist_put (plist, QCmargin,
9686 Fcons (make_number (hmargin),
9687 make_number (vmargin)));
9690 /* If button is not enabled, and we don't have special images
9691 for the disabled state, make the image appear disabled by
9692 applying an appropriate algorithm to it. */
9693 if (!enabled_p && idx < 0)
9694 plist = Fplist_put (plist, QCconversion, Qdisabled);
9696 /* Put a `display' text property on the string for the image to
9697 display. Put a `menu-item' property on the string that gives
9698 the start of this item's properties in the tool-bar items
9699 vector. */
9700 image = Fcons (Qimage, plist);
9701 props = list4 (Qdisplay, image,
9702 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
9704 /* Let the last image hide all remaining spaces in the tool bar
9705 string. The string can be longer than needed when we reuse a
9706 previous string. */
9707 if (i + 1 == f->n_tool_bar_items)
9708 end = SCHARS (f->desired_tool_bar_string);
9709 else
9710 end = i + 1;
9711 Fadd_text_properties (make_number (i), make_number (end),
9712 props, f->desired_tool_bar_string);
9713 #undef PROP
9716 UNGCPRO;
9720 /* Display one line of the tool-bar of frame IT->f.
9722 HEIGHT specifies the desired height of the tool-bar line.
9723 If the actual height of the glyph row is less than HEIGHT, the
9724 row's height is increased to HEIGHT, and the icons are centered
9725 vertically in the new height.
9727 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
9728 count a final empty row in case the tool-bar width exactly matches
9729 the window width.
9732 static void
9733 display_tool_bar_line (it, height)
9734 struct it *it;
9735 int height;
9737 struct glyph_row *row = it->glyph_row;
9738 int max_x = it->last_visible_x;
9739 struct glyph *last;
9741 prepare_desired_row (row);
9742 row->y = it->current_y;
9744 /* Note that this isn't made use of if the face hasn't a box,
9745 so there's no need to check the face here. */
9746 it->start_of_box_run_p = 1;
9748 while (it->current_x < max_x)
9750 int x, n_glyphs_before, i, nglyphs;
9751 struct it it_before;
9753 /* Get the next display element. */
9754 if (!get_next_display_element (it))
9756 /* Don't count empty row if we are counting needed tool-bar lines. */
9757 if (height < 0 && !it->hpos)
9758 return;
9759 break;
9762 /* Produce glyphs. */
9763 n_glyphs_before = row->used[TEXT_AREA];
9764 it_before = *it;
9766 PRODUCE_GLYPHS (it);
9768 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
9769 i = 0;
9770 x = it_before.current_x;
9771 while (i < nglyphs)
9773 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
9775 if (x + glyph->pixel_width > max_x)
9777 /* Glyph doesn't fit on line. Backtrack. */
9778 row->used[TEXT_AREA] = n_glyphs_before;
9779 *it = it_before;
9780 /* If this is the only glyph on this line, it will never fit on the
9781 toolbar, so skip it. But ensure there is at least one glyph,
9782 so we don't accidentally disable the tool-bar. */
9783 if (n_glyphs_before == 0
9784 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
9785 break;
9786 goto out;
9789 ++it->hpos;
9790 x += glyph->pixel_width;
9791 ++i;
9794 /* Stop at line ends. */
9795 if (ITERATOR_AT_END_OF_LINE_P (it))
9796 break;
9798 set_iterator_to_next (it, 1);
9801 out:;
9803 row->displays_text_p = row->used[TEXT_AREA] != 0;
9805 /* Use default face for the border below the tool bar.
9807 FIXME: When auto-resize-tool-bars is grow-only, there is
9808 no additional border below the possibly empty tool-bar lines.
9809 So to make the extra empty lines look "normal", we have to
9810 use the tool-bar face for the border too. */
9811 if (!row->displays_text_p && !EQ (Vauto_resize_tool_bars, Qgrow_only))
9812 it->face_id = DEFAULT_FACE_ID;
9814 extend_face_to_end_of_line (it);
9815 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
9816 last->right_box_line_p = 1;
9817 if (last == row->glyphs[TEXT_AREA])
9818 last->left_box_line_p = 1;
9820 /* Make line the desired height and center it vertically. */
9821 if ((height -= it->max_ascent + it->max_descent) > 0)
9823 /* Don't add more than one line height. */
9824 height %= FRAME_LINE_HEIGHT (it->f);
9825 it->max_ascent += height / 2;
9826 it->max_descent += (height + 1) / 2;
9829 compute_line_metrics (it);
9831 /* If line is empty, make it occupy the rest of the tool-bar. */
9832 if (!row->displays_text_p)
9834 row->height = row->phys_height = it->last_visible_y - row->y;
9835 row->visible_height = row->height;
9836 row->ascent = row->phys_ascent = 0;
9837 row->extra_line_spacing = 0;
9840 row->full_width_p = 1;
9841 row->continued_p = 0;
9842 row->truncated_on_left_p = 0;
9843 row->truncated_on_right_p = 0;
9845 it->current_x = it->hpos = 0;
9846 it->current_y += row->height;
9847 ++it->vpos;
9848 ++it->glyph_row;
9852 /* Max tool-bar height. */
9854 #define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
9855 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
9857 /* Value is the number of screen lines needed to make all tool-bar
9858 items of frame F visible. The number of actual rows needed is
9859 returned in *N_ROWS if non-NULL. */
9861 static int
9862 tool_bar_lines_needed (f, n_rows)
9863 struct frame *f;
9864 int *n_rows;
9866 struct window *w = XWINDOW (f->tool_bar_window);
9867 struct it it;
9868 /* tool_bar_lines_needed is called from redisplay_tool_bar after building
9869 the desired matrix, so use (unused) mode-line row as temporary row to
9870 avoid destroying the first tool-bar row. */
9871 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
9873 /* Initialize an iterator for iteration over
9874 F->desired_tool_bar_string in the tool-bar window of frame F. */
9875 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
9876 it.first_visible_x = 0;
9877 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
9878 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
9880 while (!ITERATOR_AT_END_P (&it))
9882 clear_glyph_row (temp_row);
9883 it.glyph_row = temp_row;
9884 display_tool_bar_line (&it, -1);
9886 clear_glyph_row (temp_row);
9888 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
9889 if (n_rows)
9890 *n_rows = it.vpos > 0 ? it.vpos : -1;
9892 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
9896 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
9897 0, 1, 0,
9898 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
9899 (frame)
9900 Lisp_Object frame;
9902 struct frame *f;
9903 struct window *w;
9904 int nlines = 0;
9906 if (NILP (frame))
9907 frame = selected_frame;
9908 else
9909 CHECK_FRAME (frame);
9910 f = XFRAME (frame);
9912 if (WINDOWP (f->tool_bar_window)
9913 || (w = XWINDOW (f->tool_bar_window),
9914 WINDOW_TOTAL_LINES (w) > 0))
9916 update_tool_bar (f, 1);
9917 if (f->n_tool_bar_items)
9919 build_desired_tool_bar_string (f);
9920 nlines = tool_bar_lines_needed (f, NULL);
9924 return make_number (nlines);
9928 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
9929 height should be changed. */
9931 static int
9932 redisplay_tool_bar (f)
9933 struct frame *f;
9935 struct window *w;
9936 struct it it;
9937 struct glyph_row *row;
9939 #if defined (USE_GTK) || USE_MAC_TOOLBAR
9940 if (FRAME_EXTERNAL_TOOL_BAR (f))
9941 update_frame_tool_bar (f);
9942 return 0;
9943 #endif
9945 /* If frame hasn't a tool-bar window or if it is zero-height, don't
9946 do anything. This means you must start with tool-bar-lines
9947 non-zero to get the auto-sizing effect. Or in other words, you
9948 can turn off tool-bars by specifying tool-bar-lines zero. */
9949 if (!WINDOWP (f->tool_bar_window)
9950 || (w = XWINDOW (f->tool_bar_window),
9951 WINDOW_TOTAL_LINES (w) == 0))
9952 return 0;
9954 /* Set up an iterator for the tool-bar window. */
9955 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
9956 it.first_visible_x = 0;
9957 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
9958 row = it.glyph_row;
9960 /* Build a string that represents the contents of the tool-bar. */
9961 build_desired_tool_bar_string (f);
9962 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
9964 if (f->n_tool_bar_rows == 0)
9966 int nlines;
9968 if ((nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
9969 nlines != WINDOW_TOTAL_LINES (w)))
9971 extern Lisp_Object Qtool_bar_lines;
9972 Lisp_Object frame;
9973 int old_height = WINDOW_TOTAL_LINES (w);
9975 XSETFRAME (frame, f);
9976 Fmodify_frame_parameters (frame,
9977 Fcons (Fcons (Qtool_bar_lines,
9978 make_number (nlines)),
9979 Qnil));
9980 if (WINDOW_TOTAL_LINES (w) != old_height)
9982 clear_glyph_matrix (w->desired_matrix);
9983 fonts_changed_p = 1;
9984 return 1;
9989 /* Display as many lines as needed to display all tool-bar items. */
9991 if (f->n_tool_bar_rows > 0)
9993 int border, rows, height, extra;
9995 if (INTEGERP (Vtool_bar_border))
9996 border = XINT (Vtool_bar_border);
9997 else if (EQ (Vtool_bar_border, Qinternal_border_width))
9998 border = FRAME_INTERNAL_BORDER_WIDTH (f);
9999 else if (EQ (Vtool_bar_border, Qborder_width))
10000 border = f->border_width;
10001 else
10002 border = 0;
10003 if (border < 0)
10004 border = 0;
10006 rows = f->n_tool_bar_rows;
10007 height = max (1, (it.last_visible_y - border) / rows);
10008 extra = it.last_visible_y - border - height * rows;
10010 while (it.current_y < it.last_visible_y)
10012 int h = 0;
10013 if (extra > 0 && rows-- > 0)
10015 h = (extra + rows - 1) / rows;
10016 extra -= h;
10018 display_tool_bar_line (&it, height + h);
10021 else
10023 while (it.current_y < it.last_visible_y)
10024 display_tool_bar_line (&it, 0);
10027 /* It doesn't make much sense to try scrolling in the tool-bar
10028 window, so don't do it. */
10029 w->desired_matrix->no_scrolling_p = 1;
10030 w->must_be_updated_p = 1;
10032 if (!NILP (Vauto_resize_tool_bars))
10034 int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
10035 int change_height_p = 0;
10037 /* If we couldn't display everything, change the tool-bar's
10038 height if there is room for more. */
10039 if (IT_STRING_CHARPOS (it) < it.end_charpos
10040 && it.current_y < max_tool_bar_height)
10041 change_height_p = 1;
10043 row = it.glyph_row - 1;
10045 /* If there are blank lines at the end, except for a partially
10046 visible blank line at the end that is smaller than
10047 FRAME_LINE_HEIGHT, change the tool-bar's height. */
10048 if (!row->displays_text_p
10049 && row->height >= FRAME_LINE_HEIGHT (f))
10050 change_height_p = 1;
10052 /* If row displays tool-bar items, but is partially visible,
10053 change the tool-bar's height. */
10054 if (row->displays_text_p
10055 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y
10056 && MATRIX_ROW_BOTTOM_Y (row) < max_tool_bar_height)
10057 change_height_p = 1;
10059 /* Resize windows as needed by changing the `tool-bar-lines'
10060 frame parameter. */
10061 if (change_height_p)
10063 extern Lisp_Object Qtool_bar_lines;
10064 Lisp_Object frame;
10065 int old_height = WINDOW_TOTAL_LINES (w);
10066 int nrows;
10067 int nlines = tool_bar_lines_needed (f, &nrows);
10069 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
10070 && !f->minimize_tool_bar_window_p)
10071 ? (nlines > old_height)
10072 : (nlines != old_height));
10073 f->minimize_tool_bar_window_p = 0;
10075 if (change_height_p)
10077 XSETFRAME (frame, f);
10078 Fmodify_frame_parameters (frame,
10079 Fcons (Fcons (Qtool_bar_lines,
10080 make_number (nlines)),
10081 Qnil));
10082 if (WINDOW_TOTAL_LINES (w) != old_height)
10084 clear_glyph_matrix (w->desired_matrix);
10085 f->n_tool_bar_rows = nrows;
10086 fonts_changed_p = 1;
10087 return 1;
10093 f->minimize_tool_bar_window_p = 0;
10094 return 0;
10098 /* Get information about the tool-bar item which is displayed in GLYPH
10099 on frame F. Return in *PROP_IDX the index where tool-bar item
10100 properties start in F->tool_bar_items. Value is zero if
10101 GLYPH doesn't display a tool-bar item. */
10103 static int
10104 tool_bar_item_info (f, glyph, prop_idx)
10105 struct frame *f;
10106 struct glyph *glyph;
10107 int *prop_idx;
10109 Lisp_Object prop;
10110 int success_p;
10111 int charpos;
10113 /* This function can be called asynchronously, which means we must
10114 exclude any possibility that Fget_text_property signals an
10115 error. */
10116 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
10117 charpos = max (0, charpos);
10119 /* Get the text property `menu-item' at pos. The value of that
10120 property is the start index of this item's properties in
10121 F->tool_bar_items. */
10122 prop = Fget_text_property (make_number (charpos),
10123 Qmenu_item, f->current_tool_bar_string);
10124 if (INTEGERP (prop))
10126 *prop_idx = XINT (prop);
10127 success_p = 1;
10129 else
10130 success_p = 0;
10132 return success_p;
10136 /* Get information about the tool-bar item at position X/Y on frame F.
10137 Return in *GLYPH a pointer to the glyph of the tool-bar item in
10138 the current matrix of the tool-bar window of F, or NULL if not
10139 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
10140 item in F->tool_bar_items. Value is
10142 -1 if X/Y is not on a tool-bar item
10143 0 if X/Y is on the same item that was highlighted before.
10144 1 otherwise. */
10146 static int
10147 get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
10148 struct frame *f;
10149 int x, y;
10150 struct glyph **glyph;
10151 int *hpos, *vpos, *prop_idx;
10153 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10154 struct window *w = XWINDOW (f->tool_bar_window);
10155 int area;
10157 /* Find the glyph under X/Y. */
10158 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
10159 if (*glyph == NULL)
10160 return -1;
10162 /* Get the start of this tool-bar item's properties in
10163 f->tool_bar_items. */
10164 if (!tool_bar_item_info (f, *glyph, prop_idx))
10165 return -1;
10167 /* Is mouse on the highlighted item? */
10168 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
10169 && *vpos >= dpyinfo->mouse_face_beg_row
10170 && *vpos <= dpyinfo->mouse_face_end_row
10171 && (*vpos > dpyinfo->mouse_face_beg_row
10172 || *hpos >= dpyinfo->mouse_face_beg_col)
10173 && (*vpos < dpyinfo->mouse_face_end_row
10174 || *hpos < dpyinfo->mouse_face_end_col
10175 || dpyinfo->mouse_face_past_end))
10176 return 0;
10178 return 1;
10182 /* EXPORT:
10183 Handle mouse button event on the tool-bar of frame F, at
10184 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
10185 0 for button release. MODIFIERS is event modifiers for button
10186 release. */
10188 void
10189 handle_tool_bar_click (f, x, y, down_p, modifiers)
10190 struct frame *f;
10191 int x, y, down_p;
10192 unsigned int modifiers;
10194 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10195 struct window *w = XWINDOW (f->tool_bar_window);
10196 int hpos, vpos, prop_idx;
10197 struct glyph *glyph;
10198 Lisp_Object enabled_p;
10200 /* If not on the highlighted tool-bar item, return. */
10201 frame_to_window_pixel_xy (w, &x, &y);
10202 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
10203 return;
10205 /* If item is disabled, do nothing. */
10206 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
10207 if (NILP (enabled_p))
10208 return;
10210 if (down_p)
10212 /* Show item in pressed state. */
10213 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
10214 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
10215 last_tool_bar_item = prop_idx;
10217 else
10219 Lisp_Object key, frame;
10220 struct input_event event;
10221 EVENT_INIT (event);
10223 /* Show item in released state. */
10224 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
10225 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
10227 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
10229 XSETFRAME (frame, f);
10230 event.kind = TOOL_BAR_EVENT;
10231 event.frame_or_window = frame;
10232 event.arg = frame;
10233 kbd_buffer_store_event (&event);
10235 event.kind = TOOL_BAR_EVENT;
10236 event.frame_or_window = frame;
10237 event.arg = key;
10238 event.modifiers = modifiers;
10239 kbd_buffer_store_event (&event);
10240 last_tool_bar_item = -1;
10245 /* Possibly highlight a tool-bar item on frame F when mouse moves to
10246 tool-bar window-relative coordinates X/Y. Called from
10247 note_mouse_highlight. */
10249 static void
10250 note_tool_bar_highlight (f, x, y)
10251 struct frame *f;
10252 int x, y;
10254 Lisp_Object window = f->tool_bar_window;
10255 struct window *w = XWINDOW (window);
10256 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10257 int hpos, vpos;
10258 struct glyph *glyph;
10259 struct glyph_row *row;
10260 int i;
10261 Lisp_Object enabled_p;
10262 int prop_idx;
10263 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
10264 int mouse_down_p, rc;
10266 /* Function note_mouse_highlight is called with negative x(y
10267 values when mouse moves outside of the frame. */
10268 if (x <= 0 || y <= 0)
10270 clear_mouse_face (dpyinfo);
10271 return;
10274 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
10275 if (rc < 0)
10277 /* Not on tool-bar item. */
10278 clear_mouse_face (dpyinfo);
10279 return;
10281 else if (rc == 0)
10282 /* On same tool-bar item as before. */
10283 goto set_help_echo;
10285 clear_mouse_face (dpyinfo);
10287 /* Mouse is down, but on different tool-bar item? */
10288 mouse_down_p = (dpyinfo->grabbed
10289 && f == last_mouse_frame
10290 && FRAME_LIVE_P (f));
10291 if (mouse_down_p
10292 && last_tool_bar_item != prop_idx)
10293 return;
10295 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
10296 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
10298 /* If tool-bar item is not enabled, don't highlight it. */
10299 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
10300 if (!NILP (enabled_p))
10302 /* Compute the x-position of the glyph. In front and past the
10303 image is a space. We include this in the highlighted area. */
10304 row = MATRIX_ROW (w->current_matrix, vpos);
10305 for (i = x = 0; i < hpos; ++i)
10306 x += row->glyphs[TEXT_AREA][i].pixel_width;
10308 /* Record this as the current active region. */
10309 dpyinfo->mouse_face_beg_col = hpos;
10310 dpyinfo->mouse_face_beg_row = vpos;
10311 dpyinfo->mouse_face_beg_x = x;
10312 dpyinfo->mouse_face_beg_y = row->y;
10313 dpyinfo->mouse_face_past_end = 0;
10315 dpyinfo->mouse_face_end_col = hpos + 1;
10316 dpyinfo->mouse_face_end_row = vpos;
10317 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
10318 dpyinfo->mouse_face_end_y = row->y;
10319 dpyinfo->mouse_face_window = window;
10320 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
10322 /* Display it as active. */
10323 show_mouse_face (dpyinfo, draw);
10324 dpyinfo->mouse_face_image_state = draw;
10327 set_help_echo:
10329 /* Set help_echo_string to a help string to display for this tool-bar item.
10330 XTread_socket does the rest. */
10331 help_echo_object = help_echo_window = Qnil;
10332 help_echo_pos = -1;
10333 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
10334 if (NILP (help_echo_string))
10335 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
10338 #endif /* HAVE_WINDOW_SYSTEM */
10342 /************************************************************************
10343 Horizontal scrolling
10344 ************************************************************************/
10346 static int hscroll_window_tree P_ ((Lisp_Object));
10347 static int hscroll_windows P_ ((Lisp_Object));
10349 /* For all leaf windows in the window tree rooted at WINDOW, set their
10350 hscroll value so that PT is (i) visible in the window, and (ii) so
10351 that it is not within a certain margin at the window's left and
10352 right border. Value is non-zero if any window's hscroll has been
10353 changed. */
10355 static int
10356 hscroll_window_tree (window)
10357 Lisp_Object window;
10359 int hscrolled_p = 0;
10360 int hscroll_relative_p = FLOATP (Vhscroll_step);
10361 int hscroll_step_abs = 0;
10362 double hscroll_step_rel = 0;
10364 if (hscroll_relative_p)
10366 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
10367 if (hscroll_step_rel < 0)
10369 hscroll_relative_p = 0;
10370 hscroll_step_abs = 0;
10373 else if (INTEGERP (Vhscroll_step))
10375 hscroll_step_abs = XINT (Vhscroll_step);
10376 if (hscroll_step_abs < 0)
10377 hscroll_step_abs = 0;
10379 else
10380 hscroll_step_abs = 0;
10382 while (WINDOWP (window))
10384 struct window *w = XWINDOW (window);
10386 if (WINDOWP (w->hchild))
10387 hscrolled_p |= hscroll_window_tree (w->hchild);
10388 else if (WINDOWP (w->vchild))
10389 hscrolled_p |= hscroll_window_tree (w->vchild);
10390 else if (w->cursor.vpos >= 0)
10392 int h_margin;
10393 int text_area_width;
10394 struct glyph_row *current_cursor_row
10395 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
10396 struct glyph_row *desired_cursor_row
10397 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
10398 struct glyph_row *cursor_row
10399 = (desired_cursor_row->enabled_p
10400 ? desired_cursor_row
10401 : current_cursor_row);
10403 text_area_width = window_box_width (w, TEXT_AREA);
10405 /* Scroll when cursor is inside this scroll margin. */
10406 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
10408 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->buffer))
10409 && ((XFASTINT (w->hscroll)
10410 && w->cursor.x <= h_margin)
10411 || (cursor_row->enabled_p
10412 && cursor_row->truncated_on_right_p
10413 && (w->cursor.x >= text_area_width - h_margin))))
10415 struct it it;
10416 int hscroll;
10417 struct buffer *saved_current_buffer;
10418 int pt;
10419 int wanted_x;
10421 /* Find point in a display of infinite width. */
10422 saved_current_buffer = current_buffer;
10423 current_buffer = XBUFFER (w->buffer);
10425 if (w == XWINDOW (selected_window))
10426 pt = BUF_PT (current_buffer);
10427 else
10429 pt = marker_position (w->pointm);
10430 pt = max (BEGV, pt);
10431 pt = min (ZV, pt);
10434 /* Move iterator to pt starting at cursor_row->start in
10435 a line with infinite width. */
10436 init_to_row_start (&it, w, cursor_row);
10437 it.last_visible_x = INFINITY;
10438 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
10439 current_buffer = saved_current_buffer;
10441 /* Position cursor in window. */
10442 if (!hscroll_relative_p && hscroll_step_abs == 0)
10443 hscroll = max (0, (it.current_x
10444 - (ITERATOR_AT_END_OF_LINE_P (&it)
10445 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
10446 : (text_area_width / 2))))
10447 / FRAME_COLUMN_WIDTH (it.f);
10448 else if (w->cursor.x >= text_area_width - h_margin)
10450 if (hscroll_relative_p)
10451 wanted_x = text_area_width * (1 - hscroll_step_rel)
10452 - h_margin;
10453 else
10454 wanted_x = text_area_width
10455 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
10456 - h_margin;
10457 hscroll
10458 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
10460 else
10462 if (hscroll_relative_p)
10463 wanted_x = text_area_width * hscroll_step_rel
10464 + h_margin;
10465 else
10466 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
10467 + h_margin;
10468 hscroll
10469 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
10471 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
10473 /* Don't call Fset_window_hscroll if value hasn't
10474 changed because it will prevent redisplay
10475 optimizations. */
10476 if (XFASTINT (w->hscroll) != hscroll)
10478 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
10479 w->hscroll = make_number (hscroll);
10480 hscrolled_p = 1;
10485 window = w->next;
10488 /* Value is non-zero if hscroll of any leaf window has been changed. */
10489 return hscrolled_p;
10493 /* Set hscroll so that cursor is visible and not inside horizontal
10494 scroll margins for all windows in the tree rooted at WINDOW. See
10495 also hscroll_window_tree above. Value is non-zero if any window's
10496 hscroll has been changed. If it has, desired matrices on the frame
10497 of WINDOW are cleared. */
10499 static int
10500 hscroll_windows (window)
10501 Lisp_Object window;
10503 int hscrolled_p = hscroll_window_tree (window);
10504 if (hscrolled_p)
10505 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
10506 return hscrolled_p;
10511 /************************************************************************
10512 Redisplay
10513 ************************************************************************/
10515 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
10516 to a non-zero value. This is sometimes handy to have in a debugger
10517 session. */
10519 #if GLYPH_DEBUG
10521 /* First and last unchanged row for try_window_id. */
10523 int debug_first_unchanged_at_end_vpos;
10524 int debug_last_unchanged_at_beg_vpos;
10526 /* Delta vpos and y. */
10528 int debug_dvpos, debug_dy;
10530 /* Delta in characters and bytes for try_window_id. */
10532 int debug_delta, debug_delta_bytes;
10534 /* Values of window_end_pos and window_end_vpos at the end of
10535 try_window_id. */
10537 EMACS_INT debug_end_pos, debug_end_vpos;
10539 /* Append a string to W->desired_matrix->method. FMT is a printf
10540 format string. A1...A9 are a supplement for a variable-length
10541 argument list. If trace_redisplay_p is non-zero also printf the
10542 resulting string to stderr. */
10544 static void
10545 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
10546 struct window *w;
10547 char *fmt;
10548 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
10550 char buffer[512];
10551 char *method = w->desired_matrix->method;
10552 int len = strlen (method);
10553 int size = sizeof w->desired_matrix->method;
10554 int remaining = size - len - 1;
10556 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
10557 if (len && remaining)
10559 method[len] = '|';
10560 --remaining, ++len;
10563 strncpy (method + len, buffer, remaining);
10565 if (trace_redisplay_p)
10566 fprintf (stderr, "%p (%s): %s\n",
10568 ((BUFFERP (w->buffer)
10569 && STRINGP (XBUFFER (w->buffer)->name))
10570 ? (char *) SDATA (XBUFFER (w->buffer)->name)
10571 : "no buffer"),
10572 buffer);
10575 #endif /* GLYPH_DEBUG */
10578 /* Value is non-zero if all changes in window W, which displays
10579 current_buffer, are in the text between START and END. START is a
10580 buffer position, END is given as a distance from Z. Used in
10581 redisplay_internal for display optimization. */
10583 static INLINE int
10584 text_outside_line_unchanged_p (w, start, end)
10585 struct window *w;
10586 int start, end;
10588 int unchanged_p = 1;
10590 /* If text or overlays have changed, see where. */
10591 if (XFASTINT (w->last_modified) < MODIFF
10592 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
10594 /* Gap in the line? */
10595 if (GPT < start || Z - GPT < end)
10596 unchanged_p = 0;
10598 /* Changes start in front of the line, or end after it? */
10599 if (unchanged_p
10600 && (BEG_UNCHANGED < start - 1
10601 || END_UNCHANGED < end))
10602 unchanged_p = 0;
10604 /* If selective display, can't optimize if changes start at the
10605 beginning of the line. */
10606 if (unchanged_p
10607 && INTEGERP (current_buffer->selective_display)
10608 && XINT (current_buffer->selective_display) > 0
10609 && (BEG_UNCHANGED < start || GPT <= start))
10610 unchanged_p = 0;
10612 /* If there are overlays at the start or end of the line, these
10613 may have overlay strings with newlines in them. A change at
10614 START, for instance, may actually concern the display of such
10615 overlay strings as well, and they are displayed on different
10616 lines. So, quickly rule out this case. (For the future, it
10617 might be desirable to implement something more telling than
10618 just BEG/END_UNCHANGED.) */
10619 if (unchanged_p)
10621 if (BEG + BEG_UNCHANGED == start
10622 && overlay_touches_p (start))
10623 unchanged_p = 0;
10624 if (END_UNCHANGED == end
10625 && overlay_touches_p (Z - end))
10626 unchanged_p = 0;
10630 return unchanged_p;
10634 /* Do a frame update, taking possible shortcuts into account. This is
10635 the main external entry point for redisplay.
10637 If the last redisplay displayed an echo area message and that message
10638 is no longer requested, we clear the echo area or bring back the
10639 mini-buffer if that is in use. */
10641 void
10642 redisplay ()
10644 redisplay_internal (0);
10648 static Lisp_Object
10649 overlay_arrow_string_or_property (var)
10650 Lisp_Object var;
10652 Lisp_Object val;
10654 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
10655 return val;
10657 return Voverlay_arrow_string;
10660 /* Return 1 if there are any overlay-arrows in current_buffer. */
10661 static int
10662 overlay_arrow_in_current_buffer_p ()
10664 Lisp_Object vlist;
10666 for (vlist = Voverlay_arrow_variable_list;
10667 CONSP (vlist);
10668 vlist = XCDR (vlist))
10670 Lisp_Object var = XCAR (vlist);
10671 Lisp_Object val;
10673 if (!SYMBOLP (var))
10674 continue;
10675 val = find_symbol_value (var);
10676 if (MARKERP (val)
10677 && current_buffer == XMARKER (val)->buffer)
10678 return 1;
10680 return 0;
10684 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
10685 has changed. */
10687 static int
10688 overlay_arrows_changed_p ()
10690 Lisp_Object vlist;
10692 for (vlist = Voverlay_arrow_variable_list;
10693 CONSP (vlist);
10694 vlist = XCDR (vlist))
10696 Lisp_Object var = XCAR (vlist);
10697 Lisp_Object val, pstr;
10699 if (!SYMBOLP (var))
10700 continue;
10701 val = find_symbol_value (var);
10702 if (!MARKERP (val))
10703 continue;
10704 if (! EQ (COERCE_MARKER (val),
10705 Fget (var, Qlast_arrow_position))
10706 || ! (pstr = overlay_arrow_string_or_property (var),
10707 EQ (pstr, Fget (var, Qlast_arrow_string))))
10708 return 1;
10710 return 0;
10713 /* Mark overlay arrows to be updated on next redisplay. */
10715 static void
10716 update_overlay_arrows (up_to_date)
10717 int up_to_date;
10719 Lisp_Object vlist;
10721 for (vlist = Voverlay_arrow_variable_list;
10722 CONSP (vlist);
10723 vlist = XCDR (vlist))
10725 Lisp_Object var = XCAR (vlist);
10727 if (!SYMBOLP (var))
10728 continue;
10730 if (up_to_date > 0)
10732 Lisp_Object val = find_symbol_value (var);
10733 Fput (var, Qlast_arrow_position,
10734 COERCE_MARKER (val));
10735 Fput (var, Qlast_arrow_string,
10736 overlay_arrow_string_or_property (var));
10738 else if (up_to_date < 0
10739 || !NILP (Fget (var, Qlast_arrow_position)))
10741 Fput (var, Qlast_arrow_position, Qt);
10742 Fput (var, Qlast_arrow_string, Qt);
10748 /* Return overlay arrow string to display at row.
10749 Return integer (bitmap number) for arrow bitmap in left fringe.
10750 Return nil if no overlay arrow. */
10752 static Lisp_Object
10753 overlay_arrow_at_row (it, row)
10754 struct it *it;
10755 struct glyph_row *row;
10757 Lisp_Object vlist;
10759 for (vlist = Voverlay_arrow_variable_list;
10760 CONSP (vlist);
10761 vlist = XCDR (vlist))
10763 Lisp_Object var = XCAR (vlist);
10764 Lisp_Object val;
10766 if (!SYMBOLP (var))
10767 continue;
10769 val = find_symbol_value (var);
10771 if (MARKERP (val)
10772 && current_buffer == XMARKER (val)->buffer
10773 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
10775 if (FRAME_WINDOW_P (it->f)
10776 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
10778 #ifdef HAVE_WINDOW_SYSTEM
10779 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
10781 int fringe_bitmap;
10782 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
10783 return make_number (fringe_bitmap);
10785 #endif
10786 return make_number (-1); /* Use default arrow bitmap */
10788 return overlay_arrow_string_or_property (var);
10792 return Qnil;
10795 /* Return 1 if point moved out of or into a composition. Otherwise
10796 return 0. PREV_BUF and PREV_PT are the last point buffer and
10797 position. BUF and PT are the current point buffer and position. */
10800 check_point_in_composition (prev_buf, prev_pt, buf, pt)
10801 struct buffer *prev_buf, *buf;
10802 int prev_pt, pt;
10804 int start, end;
10805 Lisp_Object prop;
10806 Lisp_Object buffer;
10808 XSETBUFFER (buffer, buf);
10809 /* Check a composition at the last point if point moved within the
10810 same buffer. */
10811 if (prev_buf == buf)
10813 if (prev_pt == pt)
10814 /* Point didn't move. */
10815 return 0;
10817 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
10818 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
10819 && COMPOSITION_VALID_P (start, end, prop)
10820 && start < prev_pt && end > prev_pt)
10821 /* The last point was within the composition. Return 1 iff
10822 point moved out of the composition. */
10823 return (pt <= start || pt >= end);
10826 /* Check a composition at the current point. */
10827 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
10828 && find_composition (pt, -1, &start, &end, &prop, buffer)
10829 && COMPOSITION_VALID_P (start, end, prop)
10830 && start < pt && end > pt);
10834 /* Reconsider the setting of B->clip_changed which is displayed
10835 in window W. */
10837 static INLINE void
10838 reconsider_clip_changes (w, b)
10839 struct window *w;
10840 struct buffer *b;
10842 if (b->clip_changed
10843 && !NILP (w->window_end_valid)
10844 && w->current_matrix->buffer == b
10845 && w->current_matrix->zv == BUF_ZV (b)
10846 && w->current_matrix->begv == BUF_BEGV (b))
10847 b->clip_changed = 0;
10849 /* If display wasn't paused, and W is not a tool bar window, see if
10850 point has been moved into or out of a composition. In that case,
10851 we set b->clip_changed to 1 to force updating the screen. If
10852 b->clip_changed has already been set to 1, we can skip this
10853 check. */
10854 if (!b->clip_changed
10855 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
10857 int pt;
10859 if (w == XWINDOW (selected_window))
10860 pt = BUF_PT (current_buffer);
10861 else
10862 pt = marker_position (w->pointm);
10864 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
10865 || pt != XINT (w->last_point))
10866 && check_point_in_composition (w->current_matrix->buffer,
10867 XINT (w->last_point),
10868 XBUFFER (w->buffer), pt))
10869 b->clip_changed = 1;
10874 /* Select FRAME to forward the values of frame-local variables into C
10875 variables so that the redisplay routines can access those values
10876 directly. */
10878 static void
10879 select_frame_for_redisplay (frame)
10880 Lisp_Object frame;
10882 Lisp_Object tail, sym, val;
10883 Lisp_Object old = selected_frame;
10885 xassert (FRAMEP (frame) && FRAME_LIVE_P (XFRAME (frame)));
10887 selected_frame = frame;
10889 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
10890 if (CONSP (XCAR (tail))
10891 && (sym = XCAR (XCAR (tail)),
10892 SYMBOLP (sym))
10893 && (sym = indirect_variable (sym),
10894 val = SYMBOL_VALUE (sym),
10895 (BUFFER_LOCAL_VALUEP (val)))
10896 && XBUFFER_LOCAL_VALUE (val)->check_frame)
10897 /* Use find_symbol_value rather than Fsymbol_value
10898 to avoid an error if it is void. */
10899 find_symbol_value (sym);
10901 for (tail = XFRAME (old)->param_alist; CONSP (tail); tail = XCDR (tail))
10902 if (CONSP (XCAR (tail))
10903 && (sym = XCAR (XCAR (tail)),
10904 SYMBOLP (sym))
10905 && (sym = indirect_variable (sym),
10906 val = SYMBOL_VALUE (sym),
10907 (BUFFER_LOCAL_VALUEP (val)))
10908 && XBUFFER_LOCAL_VALUE (val)->check_frame)
10909 find_symbol_value (sym);
10913 #define STOP_POLLING \
10914 do { if (! polling_stopped_here) stop_polling (); \
10915 polling_stopped_here = 1; } while (0)
10917 #define RESUME_POLLING \
10918 do { if (polling_stopped_here) start_polling (); \
10919 polling_stopped_here = 0; } while (0)
10922 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
10923 response to any user action; therefore, we should preserve the echo
10924 area. (Actually, our caller does that job.) Perhaps in the future
10925 avoid recentering windows if it is not necessary; currently that
10926 causes some problems. */
10928 static void
10929 redisplay_internal (preserve_echo_area)
10930 int preserve_echo_area;
10932 struct window *w = XWINDOW (selected_window);
10933 struct frame *f;
10934 int pause;
10935 int must_finish = 0;
10936 struct text_pos tlbufpos, tlendpos;
10937 int number_of_visible_frames;
10938 int count, count1;
10939 struct frame *sf;
10940 int polling_stopped_here = 0;
10941 Lisp_Object old_frame = selected_frame;
10943 /* Non-zero means redisplay has to consider all windows on all
10944 frames. Zero means, only selected_window is considered. */
10945 int consider_all_windows_p;
10947 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
10949 /* No redisplay if running in batch mode or frame is not yet fully
10950 initialized, or redisplay is explicitly turned off by setting
10951 Vinhibit_redisplay. */
10952 if (noninteractive
10953 || !NILP (Vinhibit_redisplay))
10954 return;
10956 /* Don't examine these until after testing Vinhibit_redisplay.
10957 When Emacs is shutting down, perhaps because its connection to
10958 X has dropped, we should not look at them at all. */
10959 f = XFRAME (w->frame);
10960 sf = SELECTED_FRAME ();
10962 if (!f->glyphs_initialized_p)
10963 return;
10965 /* The flag redisplay_performed_directly_p is set by
10966 direct_output_for_insert when it already did the whole screen
10967 update necessary. */
10968 if (redisplay_performed_directly_p)
10970 redisplay_performed_directly_p = 0;
10971 if (!hscroll_windows (selected_window))
10972 return;
10975 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (MAC_OS)
10976 if (popup_activated ())
10977 return;
10978 #endif
10980 /* I don't think this happens but let's be paranoid. */
10981 if (redisplaying_p)
10982 return;
10984 /* Record a function that resets redisplaying_p to its old value
10985 when we leave this function. */
10986 count = SPECPDL_INDEX ();
10987 record_unwind_protect (unwind_redisplay,
10988 Fcons (make_number (redisplaying_p), selected_frame));
10989 ++redisplaying_p;
10990 specbind (Qinhibit_free_realized_faces, Qnil);
10993 Lisp_Object tail, frame;
10995 FOR_EACH_FRAME (tail, frame)
10997 struct frame *f = XFRAME (frame);
10998 f->already_hscrolled_p = 0;
11002 retry:
11003 if (!EQ (old_frame, selected_frame)
11004 && FRAME_LIVE_P (XFRAME (old_frame)))
11005 /* When running redisplay, we play a bit fast-and-loose and allow e.g.
11006 selected_frame and selected_window to be temporarily out-of-sync so
11007 when we come back here via `goto retry', we need to resync because we
11008 may need to run Elisp code (via prepare_menu_bars). */
11009 select_frame_for_redisplay (old_frame);
11011 pause = 0;
11012 reconsider_clip_changes (w, current_buffer);
11013 last_escape_glyph_frame = NULL;
11014 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
11016 /* If new fonts have been loaded that make a glyph matrix adjustment
11017 necessary, do it. */
11018 if (fonts_changed_p)
11020 adjust_glyphs (NULL);
11021 ++windows_or_buffers_changed;
11022 fonts_changed_p = 0;
11025 /* If face_change_count is non-zero, init_iterator will free all
11026 realized faces, which includes the faces referenced from current
11027 matrices. So, we can't reuse current matrices in this case. */
11028 if (face_change_count)
11029 ++windows_or_buffers_changed;
11031 if (FRAME_TERMCAP_P (sf)
11032 && FRAME_TTY (sf)->previous_frame != sf)
11034 /* Since frames on a single ASCII terminal share the same
11035 display area, displaying a different frame means redisplay
11036 the whole thing. */
11037 windows_or_buffers_changed++;
11038 SET_FRAME_GARBAGED (sf);
11039 FRAME_TTY (sf)->previous_frame = sf;
11042 /* Set the visible flags for all frames. Do this before checking
11043 for resized or garbaged frames; they want to know if their frames
11044 are visible. See the comment in frame.h for
11045 FRAME_SAMPLE_VISIBILITY. */
11047 Lisp_Object tail, frame;
11049 number_of_visible_frames = 0;
11051 FOR_EACH_FRAME (tail, frame)
11053 struct frame *f = XFRAME (frame);
11055 FRAME_SAMPLE_VISIBILITY (f);
11056 if (FRAME_VISIBLE_P (f))
11057 ++number_of_visible_frames;
11058 clear_desired_matrices (f);
11063 /* Notice any pending interrupt request to change frame size. */
11064 do_pending_window_change (1);
11066 /* Clear frames marked as garbaged. */
11067 if (frame_garbaged)
11068 clear_garbaged_frames ();
11070 /* Build menubar and tool-bar items. */
11071 if (NILP (Vmemory_full))
11072 prepare_menu_bars ();
11074 if (windows_or_buffers_changed)
11075 update_mode_lines++;
11077 /* Detect case that we need to write or remove a star in the mode line. */
11078 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
11080 w->update_mode_line = Qt;
11081 if (buffer_shared > 1)
11082 update_mode_lines++;
11085 /* Avoid invocation of point motion hooks by `current_column' below. */
11086 count1 = SPECPDL_INDEX ();
11087 specbind (Qinhibit_point_motion_hooks, Qt);
11089 /* If %c is in the mode line, update it if needed. */
11090 if (!NILP (w->column_number_displayed)
11091 /* This alternative quickly identifies a common case
11092 where no change is needed. */
11093 && !(PT == XFASTINT (w->last_point)
11094 && XFASTINT (w->last_modified) >= MODIFF
11095 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
11096 && (XFASTINT (w->column_number_displayed)
11097 != (int) current_column ())) /* iftc */
11098 w->update_mode_line = Qt;
11100 unbind_to (count1, Qnil);
11102 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
11104 /* The variable buffer_shared is set in redisplay_window and
11105 indicates that we redisplay a buffer in different windows. See
11106 there. */
11107 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
11108 || cursor_type_changed);
11110 /* If specs for an arrow have changed, do thorough redisplay
11111 to ensure we remove any arrow that should no longer exist. */
11112 if (overlay_arrows_changed_p ())
11113 consider_all_windows_p = windows_or_buffers_changed = 1;
11115 /* Normally the message* functions will have already displayed and
11116 updated the echo area, but the frame may have been trashed, or
11117 the update may have been preempted, so display the echo area
11118 again here. Checking message_cleared_p captures the case that
11119 the echo area should be cleared. */
11120 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
11121 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
11122 || (message_cleared_p
11123 && minibuf_level == 0
11124 /* If the mini-window is currently selected, this means the
11125 echo-area doesn't show through. */
11126 && !MINI_WINDOW_P (XWINDOW (selected_window))))
11128 int window_height_changed_p = echo_area_display (0);
11129 must_finish = 1;
11131 /* If we don't display the current message, don't clear the
11132 message_cleared_p flag, because, if we did, we wouldn't clear
11133 the echo area in the next redisplay which doesn't preserve
11134 the echo area. */
11135 if (!display_last_displayed_message_p)
11136 message_cleared_p = 0;
11138 if (fonts_changed_p)
11139 goto retry;
11140 else if (window_height_changed_p)
11142 consider_all_windows_p = 1;
11143 ++update_mode_lines;
11144 ++windows_or_buffers_changed;
11146 /* If window configuration was changed, frames may have been
11147 marked garbaged. Clear them or we will experience
11148 surprises wrt scrolling. */
11149 if (frame_garbaged)
11150 clear_garbaged_frames ();
11153 else if (EQ (selected_window, minibuf_window)
11154 && (current_buffer->clip_changed
11155 || XFASTINT (w->last_modified) < MODIFF
11156 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
11157 && resize_mini_window (w, 0))
11159 /* Resized active mini-window to fit the size of what it is
11160 showing if its contents might have changed. */
11161 must_finish = 1;
11162 consider_all_windows_p = 1;
11163 ++windows_or_buffers_changed;
11164 ++update_mode_lines;
11166 /* If window configuration was changed, frames may have been
11167 marked garbaged. Clear them or we will experience
11168 surprises wrt scrolling. */
11169 if (frame_garbaged)
11170 clear_garbaged_frames ();
11174 /* If showing the region, and mark has changed, we must redisplay
11175 the whole window. The assignment to this_line_start_pos prevents
11176 the optimization directly below this if-statement. */
11177 if (((!NILP (Vtransient_mark_mode)
11178 && !NILP (XBUFFER (w->buffer)->mark_active))
11179 != !NILP (w->region_showing))
11180 || (!NILP (w->region_showing)
11181 && !EQ (w->region_showing,
11182 Fmarker_position (XBUFFER (w->buffer)->mark))))
11183 CHARPOS (this_line_start_pos) = 0;
11185 /* Optimize the case that only the line containing the cursor in the
11186 selected window has changed. Variables starting with this_ are
11187 set in display_line and record information about the line
11188 containing the cursor. */
11189 tlbufpos = this_line_start_pos;
11190 tlendpos = this_line_end_pos;
11191 if (!consider_all_windows_p
11192 && CHARPOS (tlbufpos) > 0
11193 && NILP (w->update_mode_line)
11194 && !current_buffer->clip_changed
11195 && !current_buffer->prevent_redisplay_optimizations_p
11196 && FRAME_VISIBLE_P (XFRAME (w->frame))
11197 && !FRAME_OBSCURED_P (XFRAME (w->frame))
11198 /* Make sure recorded data applies to current buffer, etc. */
11199 && this_line_buffer == current_buffer
11200 && current_buffer == XBUFFER (w->buffer)
11201 && NILP (w->force_start)
11202 && NILP (w->optional_new_start)
11203 /* Point must be on the line that we have info recorded about. */
11204 && PT >= CHARPOS (tlbufpos)
11205 && PT <= Z - CHARPOS (tlendpos)
11206 /* All text outside that line, including its final newline,
11207 must be unchanged */
11208 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
11209 CHARPOS (tlendpos)))
11211 if (CHARPOS (tlbufpos) > BEGV
11212 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
11213 && (CHARPOS (tlbufpos) == ZV
11214 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
11215 /* Former continuation line has disappeared by becoming empty */
11216 goto cancel;
11217 else if (XFASTINT (w->last_modified) < MODIFF
11218 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
11219 || MINI_WINDOW_P (w))
11221 /* We have to handle the case of continuation around a
11222 wide-column character (See the comment in indent.c around
11223 line 885).
11225 For instance, in the following case:
11227 -------- Insert --------
11228 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
11229 J_I_ ==> J_I_ `^^' are cursors.
11230 ^^ ^^
11231 -------- --------
11233 As we have to redraw the line above, we should goto cancel. */
11235 struct it it;
11236 int line_height_before = this_line_pixel_height;
11238 /* Note that start_display will handle the case that the
11239 line starting at tlbufpos is a continuation lines. */
11240 start_display (&it, w, tlbufpos);
11242 /* Implementation note: It this still necessary? */
11243 if (it.current_x != this_line_start_x)
11244 goto cancel;
11246 TRACE ((stderr, "trying display optimization 1\n"));
11247 w->cursor.vpos = -1;
11248 overlay_arrow_seen = 0;
11249 it.vpos = this_line_vpos;
11250 it.current_y = this_line_y;
11251 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
11252 display_line (&it);
11254 /* If line contains point, is not continued,
11255 and ends at same distance from eob as before, we win */
11256 if (w->cursor.vpos >= 0
11257 /* Line is not continued, otherwise this_line_start_pos
11258 would have been set to 0 in display_line. */
11259 && CHARPOS (this_line_start_pos)
11260 /* Line ends as before. */
11261 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
11262 /* Line has same height as before. Otherwise other lines
11263 would have to be shifted up or down. */
11264 && this_line_pixel_height == line_height_before)
11266 /* If this is not the window's last line, we must adjust
11267 the charstarts of the lines below. */
11268 if (it.current_y < it.last_visible_y)
11270 struct glyph_row *row
11271 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
11272 int delta, delta_bytes;
11274 if (Z - CHARPOS (tlendpos) == ZV)
11276 /* This line ends at end of (accessible part of)
11277 buffer. There is no newline to count. */
11278 delta = (Z
11279 - CHARPOS (tlendpos)
11280 - MATRIX_ROW_START_CHARPOS (row));
11281 delta_bytes = (Z_BYTE
11282 - BYTEPOS (tlendpos)
11283 - MATRIX_ROW_START_BYTEPOS (row));
11285 else
11287 /* This line ends in a newline. Must take
11288 account of the newline and the rest of the
11289 text that follows. */
11290 delta = (Z
11291 - CHARPOS (tlendpos)
11292 - MATRIX_ROW_START_CHARPOS (row));
11293 delta_bytes = (Z_BYTE
11294 - BYTEPOS (tlendpos)
11295 - MATRIX_ROW_START_BYTEPOS (row));
11298 increment_matrix_positions (w->current_matrix,
11299 this_line_vpos + 1,
11300 w->current_matrix->nrows,
11301 delta, delta_bytes);
11304 /* If this row displays text now but previously didn't,
11305 or vice versa, w->window_end_vpos may have to be
11306 adjusted. */
11307 if ((it.glyph_row - 1)->displays_text_p)
11309 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
11310 XSETINT (w->window_end_vpos, this_line_vpos);
11312 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
11313 && this_line_vpos > 0)
11314 XSETINT (w->window_end_vpos, this_line_vpos - 1);
11315 w->window_end_valid = Qnil;
11317 /* Update hint: No need to try to scroll in update_window. */
11318 w->desired_matrix->no_scrolling_p = 1;
11320 #if GLYPH_DEBUG
11321 *w->desired_matrix->method = 0;
11322 debug_method_add (w, "optimization 1");
11323 #endif
11324 #ifdef HAVE_WINDOW_SYSTEM
11325 update_window_fringes (w, 0);
11326 #endif
11327 goto update;
11329 else
11330 goto cancel;
11332 else if (/* Cursor position hasn't changed. */
11333 PT == XFASTINT (w->last_point)
11334 /* Make sure the cursor was last displayed
11335 in this window. Otherwise we have to reposition it. */
11336 && 0 <= w->cursor.vpos
11337 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
11339 if (!must_finish)
11341 do_pending_window_change (1);
11343 /* We used to always goto end_of_redisplay here, but this
11344 isn't enough if we have a blinking cursor. */
11345 if (w->cursor_off_p == w->last_cursor_off_p)
11346 goto end_of_redisplay;
11348 goto update;
11350 /* If highlighting the region, or if the cursor is in the echo area,
11351 then we can't just move the cursor. */
11352 else if (! (!NILP (Vtransient_mark_mode)
11353 && !NILP (current_buffer->mark_active))
11354 && (EQ (selected_window, current_buffer->last_selected_window)
11355 || highlight_nonselected_windows)
11356 && NILP (w->region_showing)
11357 && NILP (Vshow_trailing_whitespace)
11358 && !cursor_in_echo_area)
11360 struct it it;
11361 struct glyph_row *row;
11363 /* Skip from tlbufpos to PT and see where it is. Note that
11364 PT may be in invisible text. If so, we will end at the
11365 next visible position. */
11366 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
11367 NULL, DEFAULT_FACE_ID);
11368 it.current_x = this_line_start_x;
11369 it.current_y = this_line_y;
11370 it.vpos = this_line_vpos;
11372 /* The call to move_it_to stops in front of PT, but
11373 moves over before-strings. */
11374 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
11376 if (it.vpos == this_line_vpos
11377 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
11378 row->enabled_p))
11380 xassert (this_line_vpos == it.vpos);
11381 xassert (this_line_y == it.current_y);
11382 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11383 #if GLYPH_DEBUG
11384 *w->desired_matrix->method = 0;
11385 debug_method_add (w, "optimization 3");
11386 #endif
11387 goto update;
11389 else
11390 goto cancel;
11393 cancel:
11394 /* Text changed drastically or point moved off of line. */
11395 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
11398 CHARPOS (this_line_start_pos) = 0;
11399 consider_all_windows_p |= buffer_shared > 1;
11400 ++clear_face_cache_count;
11401 #ifdef HAVE_WINDOW_SYSTEM
11402 ++clear_image_cache_count;
11403 #endif
11405 /* Build desired matrices, and update the display. If
11406 consider_all_windows_p is non-zero, do it for all windows on all
11407 frames. Otherwise do it for selected_window, only. */
11409 if (consider_all_windows_p)
11411 Lisp_Object tail, frame;
11413 FOR_EACH_FRAME (tail, frame)
11414 XFRAME (frame)->updated_p = 0;
11416 /* Recompute # windows showing selected buffer. This will be
11417 incremented each time such a window is displayed. */
11418 buffer_shared = 0;
11420 FOR_EACH_FRAME (tail, frame)
11422 struct frame *f = XFRAME (frame);
11424 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
11426 if (! EQ (frame, selected_frame))
11427 /* Select the frame, for the sake of frame-local
11428 variables. */
11429 select_frame_for_redisplay (frame);
11431 /* Mark all the scroll bars to be removed; we'll redeem
11432 the ones we want when we redisplay their windows. */
11433 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
11434 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
11436 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
11437 redisplay_windows (FRAME_ROOT_WINDOW (f));
11439 /* Any scroll bars which redisplay_windows should have
11440 nuked should now go away. */
11441 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
11442 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
11444 /* If fonts changed, display again. */
11445 /* ??? rms: I suspect it is a mistake to jump all the way
11446 back to retry here. It should just retry this frame. */
11447 if (fonts_changed_p)
11448 goto retry;
11450 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
11452 /* See if we have to hscroll. */
11453 if (!f->already_hscrolled_p)
11455 f->already_hscrolled_p = 1;
11456 if (hscroll_windows (f->root_window))
11457 goto retry;
11460 /* Prevent various kinds of signals during display
11461 update. stdio is not robust about handling
11462 signals, which can cause an apparent I/O
11463 error. */
11464 if (interrupt_input)
11465 unrequest_sigio ();
11466 STOP_POLLING;
11468 /* Update the display. */
11469 set_window_update_flags (XWINDOW (f->root_window), 1);
11470 pause |= update_frame (f, 0, 0);
11471 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
11472 if (pause)
11473 break;
11474 #endif
11476 f->updated_p = 1;
11481 if (!pause)
11483 /* Do the mark_window_display_accurate after all windows have
11484 been redisplayed because this call resets flags in buffers
11485 which are needed for proper redisplay. */
11486 FOR_EACH_FRAME (tail, frame)
11488 struct frame *f = XFRAME (frame);
11489 if (f->updated_p)
11491 mark_window_display_accurate (f->root_window, 1);
11492 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
11493 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
11498 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
11500 Lisp_Object mini_window;
11501 struct frame *mini_frame;
11503 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
11504 /* Use list_of_error, not Qerror, so that
11505 we catch only errors and don't run the debugger. */
11506 internal_condition_case_1 (redisplay_window_1, selected_window,
11507 list_of_error,
11508 redisplay_window_error);
11510 /* Compare desired and current matrices, perform output. */
11512 update:
11513 /* If fonts changed, display again. */
11514 if (fonts_changed_p)
11515 goto retry;
11517 /* Prevent various kinds of signals during display update.
11518 stdio is not robust about handling signals,
11519 which can cause an apparent I/O error. */
11520 if (interrupt_input)
11521 unrequest_sigio ();
11522 STOP_POLLING;
11524 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
11526 if (hscroll_windows (selected_window))
11527 goto retry;
11529 XWINDOW (selected_window)->must_be_updated_p = 1;
11530 pause = update_frame (sf, 0, 0);
11533 /* We may have called echo_area_display at the top of this
11534 function. If the echo area is on another frame, that may
11535 have put text on a frame other than the selected one, so the
11536 above call to update_frame would not have caught it. Catch
11537 it here. */
11538 mini_window = FRAME_MINIBUF_WINDOW (sf);
11539 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
11541 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
11543 XWINDOW (mini_window)->must_be_updated_p = 1;
11544 pause |= update_frame (mini_frame, 0, 0);
11545 if (!pause && hscroll_windows (mini_window))
11546 goto retry;
11550 /* If display was paused because of pending input, make sure we do a
11551 thorough update the next time. */
11552 if (pause)
11554 /* Prevent the optimization at the beginning of
11555 redisplay_internal that tries a single-line update of the
11556 line containing the cursor in the selected window. */
11557 CHARPOS (this_line_start_pos) = 0;
11559 /* Let the overlay arrow be updated the next time. */
11560 update_overlay_arrows (0);
11562 /* If we pause after scrolling, some rows in the current
11563 matrices of some windows are not valid. */
11564 if (!WINDOW_FULL_WIDTH_P (w)
11565 && !FRAME_WINDOW_P (XFRAME (w->frame)))
11566 update_mode_lines = 1;
11568 else
11570 if (!consider_all_windows_p)
11572 /* This has already been done above if
11573 consider_all_windows_p is set. */
11574 mark_window_display_accurate_1 (w, 1);
11576 /* Say overlay arrows are up to date. */
11577 update_overlay_arrows (1);
11579 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
11580 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
11583 update_mode_lines = 0;
11584 windows_or_buffers_changed = 0;
11585 cursor_type_changed = 0;
11588 /* Start SIGIO interrupts coming again. Having them off during the
11589 code above makes it less likely one will discard output, but not
11590 impossible, since there might be stuff in the system buffer here.
11591 But it is much hairier to try to do anything about that. */
11592 if (interrupt_input)
11593 request_sigio ();
11594 RESUME_POLLING;
11596 /* If a frame has become visible which was not before, redisplay
11597 again, so that we display it. Expose events for such a frame
11598 (which it gets when becoming visible) don't call the parts of
11599 redisplay constructing glyphs, so simply exposing a frame won't
11600 display anything in this case. So, we have to display these
11601 frames here explicitly. */
11602 if (!pause)
11604 Lisp_Object tail, frame;
11605 int new_count = 0;
11607 FOR_EACH_FRAME (tail, frame)
11609 int this_is_visible = 0;
11611 if (XFRAME (frame)->visible)
11612 this_is_visible = 1;
11613 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
11614 if (XFRAME (frame)->visible)
11615 this_is_visible = 1;
11617 if (this_is_visible)
11618 new_count++;
11621 if (new_count != number_of_visible_frames)
11622 windows_or_buffers_changed++;
11625 /* Change frame size now if a change is pending. */
11626 do_pending_window_change (1);
11628 /* If we just did a pending size change, or have additional
11629 visible frames, redisplay again. */
11630 if (windows_or_buffers_changed && !pause)
11631 goto retry;
11633 /* Clear the face cache eventually. */
11634 if (consider_all_windows_p)
11636 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
11638 clear_face_cache (0);
11639 clear_face_cache_count = 0;
11641 #ifdef HAVE_WINDOW_SYSTEM
11642 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
11644 Lisp_Object tail, frame;
11645 FOR_EACH_FRAME (tail, frame)
11647 struct frame *f = XFRAME (frame);
11648 if (FRAME_WINDOW_P (f))
11649 clear_image_cache (f, 0);
11651 clear_image_cache_count = 0;
11653 #endif /* HAVE_WINDOW_SYSTEM */
11656 end_of_redisplay:
11657 unbind_to (count, Qnil);
11658 RESUME_POLLING;
11662 /* Redisplay, but leave alone any recent echo area message unless
11663 another message has been requested in its place.
11665 This is useful in situations where you need to redisplay but no
11666 user action has occurred, making it inappropriate for the message
11667 area to be cleared. See tracking_off and
11668 wait_reading_process_output for examples of these situations.
11670 FROM_WHERE is an integer saying from where this function was
11671 called. This is useful for debugging. */
11673 void
11674 redisplay_preserve_echo_area (from_where)
11675 int from_where;
11677 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
11679 if (!NILP (echo_area_buffer[1]))
11681 /* We have a previously displayed message, but no current
11682 message. Redisplay the previous message. */
11683 display_last_displayed_message_p = 1;
11684 redisplay_internal (1);
11685 display_last_displayed_message_p = 0;
11687 else
11688 redisplay_internal (1);
11690 if (FRAME_RIF (SELECTED_FRAME ()) != NULL
11691 && FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
11692 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (NULL);
11696 /* Function registered with record_unwind_protect in
11697 redisplay_internal. Reset redisplaying_p to the value it had
11698 before redisplay_internal was called, and clear
11699 prevent_freeing_realized_faces_p. It also selects the previously
11700 selected frame, unless it has been deleted (by an X connection
11701 failure during redisplay, for example). */
11703 static Lisp_Object
11704 unwind_redisplay (val)
11705 Lisp_Object val;
11707 Lisp_Object old_redisplaying_p, old_frame;
11709 old_redisplaying_p = XCAR (val);
11710 redisplaying_p = XFASTINT (old_redisplaying_p);
11711 old_frame = XCDR (val);
11712 if (! EQ (old_frame, selected_frame)
11713 && FRAME_LIVE_P (XFRAME (old_frame)))
11714 select_frame_for_redisplay (old_frame);
11715 return Qnil;
11719 /* Mark the display of window W as accurate or inaccurate. If
11720 ACCURATE_P is non-zero mark display of W as accurate. If
11721 ACCURATE_P is zero, arrange for W to be redisplayed the next time
11722 redisplay_internal is called. */
11724 static void
11725 mark_window_display_accurate_1 (w, accurate_p)
11726 struct window *w;
11727 int accurate_p;
11729 if (BUFFERP (w->buffer))
11731 struct buffer *b = XBUFFER (w->buffer);
11733 w->last_modified
11734 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
11735 w->last_overlay_modified
11736 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
11737 w->last_had_star
11738 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
11740 if (accurate_p)
11742 b->clip_changed = 0;
11743 b->prevent_redisplay_optimizations_p = 0;
11745 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
11746 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
11747 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
11748 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
11750 w->current_matrix->buffer = b;
11751 w->current_matrix->begv = BUF_BEGV (b);
11752 w->current_matrix->zv = BUF_ZV (b);
11754 w->last_cursor = w->cursor;
11755 w->last_cursor_off_p = w->cursor_off_p;
11757 if (w == XWINDOW (selected_window))
11758 w->last_point = make_number (BUF_PT (b));
11759 else
11760 w->last_point = make_number (XMARKER (w->pointm)->charpos);
11764 if (accurate_p)
11766 w->window_end_valid = w->buffer;
11767 #if 0 /* This is incorrect with variable-height lines. */
11768 xassert (XINT (w->window_end_vpos)
11769 < (WINDOW_TOTAL_LINES (w)
11770 - (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
11771 #endif
11772 w->update_mode_line = Qnil;
11777 /* Mark the display of windows in the window tree rooted at WINDOW as
11778 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
11779 windows as accurate. If ACCURATE_P is zero, arrange for windows to
11780 be redisplayed the next time redisplay_internal is called. */
11782 void
11783 mark_window_display_accurate (window, accurate_p)
11784 Lisp_Object window;
11785 int accurate_p;
11787 struct window *w;
11789 for (; !NILP (window); window = w->next)
11791 w = XWINDOW (window);
11792 mark_window_display_accurate_1 (w, accurate_p);
11794 if (!NILP (w->vchild))
11795 mark_window_display_accurate (w->vchild, accurate_p);
11796 if (!NILP (w->hchild))
11797 mark_window_display_accurate (w->hchild, accurate_p);
11800 if (accurate_p)
11802 update_overlay_arrows (1);
11804 else
11806 /* Force a thorough redisplay the next time by setting
11807 last_arrow_position and last_arrow_string to t, which is
11808 unequal to any useful value of Voverlay_arrow_... */
11809 update_overlay_arrows (-1);
11814 /* Return value in display table DP (Lisp_Char_Table *) for character
11815 C. Since a display table doesn't have any parent, we don't have to
11816 follow parent. Do not call this function directly but use the
11817 macro DISP_CHAR_VECTOR. */
11819 Lisp_Object
11820 disp_char_vector (dp, c)
11821 struct Lisp_Char_Table *dp;
11822 int c;
11824 int code[4], i;
11825 Lisp_Object val;
11827 if (SINGLE_BYTE_CHAR_P (c))
11828 return (dp->contents[c]);
11830 SPLIT_CHAR (c, code[0], code[1], code[2]);
11831 if (code[1] < 32)
11832 code[1] = -1;
11833 else if (code[2] < 32)
11834 code[2] = -1;
11836 /* Here, the possible range of code[0] (== charset ID) is
11837 128..max_charset. Since the top level char table contains data
11838 for multibyte characters after 256th element, we must increment
11839 code[0] by 128 to get a correct index. */
11840 code[0] += 128;
11841 code[3] = -1; /* anchor */
11843 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
11845 val = dp->contents[code[i]];
11846 if (!SUB_CHAR_TABLE_P (val))
11847 return (NILP (val) ? dp->defalt : val);
11850 /* Here, val is a sub char table. We return the default value of
11851 it. */
11852 return (dp->defalt);
11857 /***********************************************************************
11858 Window Redisplay
11859 ***********************************************************************/
11861 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
11863 static void
11864 redisplay_windows (window)
11865 Lisp_Object window;
11867 while (!NILP (window))
11869 struct window *w = XWINDOW (window);
11871 if (!NILP (w->hchild))
11872 redisplay_windows (w->hchild);
11873 else if (!NILP (w->vchild))
11874 redisplay_windows (w->vchild);
11875 else
11877 displayed_buffer = XBUFFER (w->buffer);
11878 /* Use list_of_error, not Qerror, so that
11879 we catch only errors and don't run the debugger. */
11880 internal_condition_case_1 (redisplay_window_0, window,
11881 list_of_error,
11882 redisplay_window_error);
11885 window = w->next;
11889 static Lisp_Object
11890 redisplay_window_error ()
11892 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
11893 return Qnil;
11896 static Lisp_Object
11897 redisplay_window_0 (window)
11898 Lisp_Object window;
11900 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
11901 redisplay_window (window, 0);
11902 return Qnil;
11905 static Lisp_Object
11906 redisplay_window_1 (window)
11907 Lisp_Object window;
11909 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
11910 redisplay_window (window, 1);
11911 return Qnil;
11915 /* Increment GLYPH until it reaches END or CONDITION fails while
11916 adding (GLYPH)->pixel_width to X. */
11918 #define SKIP_GLYPHS(glyph, end, x, condition) \
11919 do \
11921 (x) += (glyph)->pixel_width; \
11922 ++(glyph); \
11924 while ((glyph) < (end) && (condition))
11927 /* Set cursor position of W. PT is assumed to be displayed in ROW.
11928 DELTA is the number of bytes by which positions recorded in ROW
11929 differ from current buffer positions.
11931 Return 0 if cursor is not on this row. 1 otherwise. */
11934 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
11935 struct window *w;
11936 struct glyph_row *row;
11937 struct glyph_matrix *matrix;
11938 int delta, delta_bytes, dy, dvpos;
11940 struct glyph *glyph = row->glyphs[TEXT_AREA];
11941 struct glyph *end = glyph + row->used[TEXT_AREA];
11942 struct glyph *cursor = NULL;
11943 /* The first glyph that starts a sequence of glyphs from string. */
11944 struct glyph *string_start;
11945 /* The X coordinate of string_start. */
11946 int string_start_x;
11947 /* The last known character position. */
11948 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
11949 /* The last known character position before string_start. */
11950 int string_before_pos;
11951 int x = row->x;
11952 int cursor_x = x;
11953 int cursor_from_overlay_pos = 0;
11954 int pt_old = PT - delta;
11956 /* Skip over glyphs not having an object at the start of the row.
11957 These are special glyphs like truncation marks on terminal
11958 frames. */
11959 if (row->displays_text_p)
11960 while (glyph < end
11961 && INTEGERP (glyph->object)
11962 && glyph->charpos < 0)
11964 x += glyph->pixel_width;
11965 ++glyph;
11968 string_start = NULL;
11969 while (glyph < end
11970 && !INTEGERP (glyph->object)
11971 && (!BUFFERP (glyph->object)
11972 || (last_pos = glyph->charpos) < pt_old))
11974 if (! STRINGP (glyph->object))
11976 string_start = NULL;
11977 x += glyph->pixel_width;
11978 ++glyph;
11979 if (cursor_from_overlay_pos
11980 && last_pos >= cursor_from_overlay_pos)
11982 cursor_from_overlay_pos = 0;
11983 cursor = 0;
11986 else
11988 if (string_start == NULL)
11990 string_before_pos = last_pos;
11991 string_start = glyph;
11992 string_start_x = x;
11994 /* Skip all glyphs from string. */
11997 Lisp_Object cprop;
11998 int pos;
11999 if ((cursor == NULL || glyph > cursor)
12000 && (cprop = Fget_char_property (make_number ((glyph)->charpos),
12001 Qcursor, (glyph)->object),
12002 !NILP (cprop))
12003 && (pos = string_buffer_position (w, glyph->object,
12004 string_before_pos),
12005 (pos == 0 /* From overlay */
12006 || pos == pt_old)))
12008 /* Estimate overlay buffer position from the buffer
12009 positions of the glyphs before and after the overlay.
12010 Add 1 to last_pos so that if point corresponds to the
12011 glyph right after the overlay, we still use a 'cursor'
12012 property found in that overlay. */
12013 cursor_from_overlay_pos = (pos ? 0 : last_pos
12014 + (INTEGERP (cprop) ? XINT (cprop) : 0));
12015 cursor = glyph;
12016 cursor_x = x;
12018 x += glyph->pixel_width;
12019 ++glyph;
12021 while (glyph < end && EQ (glyph->object, string_start->object));
12025 if (cursor != NULL)
12027 glyph = cursor;
12028 x = cursor_x;
12030 else if (row->ends_in_ellipsis_p && glyph == end)
12032 /* Scan back over the ellipsis glyphs, decrementing positions. */
12033 while (glyph > row->glyphs[TEXT_AREA]
12034 && (glyph - 1)->charpos == last_pos)
12035 glyph--, x -= glyph->pixel_width;
12036 /* That loop always goes one position too far,
12037 including the glyph before the ellipsis.
12038 So scan forward over that one. */
12039 x += glyph->pixel_width;
12040 glyph++;
12042 else if (string_start
12043 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
12045 /* We may have skipped over point because the previous glyphs
12046 are from string. As there's no easy way to know the
12047 character position of the current glyph, find the correct
12048 glyph on point by scanning from string_start again. */
12049 Lisp_Object limit;
12050 Lisp_Object string;
12051 struct glyph *stop = glyph;
12052 int pos;
12054 limit = make_number (pt_old + 1);
12055 glyph = string_start;
12056 x = string_start_x;
12057 string = glyph->object;
12058 pos = string_buffer_position (w, string, string_before_pos);
12059 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
12060 because we always put cursor after overlay strings. */
12061 while (pos == 0 && glyph < stop)
12063 string = glyph->object;
12064 SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string));
12065 if (glyph < stop)
12066 pos = string_buffer_position (w, glyph->object, string_before_pos);
12069 while (glyph < stop)
12071 pos = XINT (Fnext_single_char_property_change
12072 (make_number (pos), Qdisplay, Qnil, limit));
12073 if (pos > pt_old)
12074 break;
12075 /* Skip glyphs from the same string. */
12076 string = glyph->object;
12077 SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string));
12078 /* Skip glyphs from an overlay. */
12079 while (glyph < stop
12080 && ! string_buffer_position (w, glyph->object, pos))
12082 string = glyph->object;
12083 SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string));
12087 /* If we reached the end of the line, and end was from a string,
12088 cursor is not on this line. */
12089 if (glyph == end && row->continued_p)
12090 return 0;
12093 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
12094 w->cursor.x = x;
12095 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
12096 w->cursor.y = row->y + dy;
12098 if (w == XWINDOW (selected_window))
12100 if (!row->continued_p
12101 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
12102 && row->x == 0)
12104 this_line_buffer = XBUFFER (w->buffer);
12106 CHARPOS (this_line_start_pos)
12107 = MATRIX_ROW_START_CHARPOS (row) + delta;
12108 BYTEPOS (this_line_start_pos)
12109 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
12111 CHARPOS (this_line_end_pos)
12112 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
12113 BYTEPOS (this_line_end_pos)
12114 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
12116 this_line_y = w->cursor.y;
12117 this_line_pixel_height = row->height;
12118 this_line_vpos = w->cursor.vpos;
12119 this_line_start_x = row->x;
12121 else
12122 CHARPOS (this_line_start_pos) = 0;
12125 return 1;
12129 /* Run window scroll functions, if any, for WINDOW with new window
12130 start STARTP. Sets the window start of WINDOW to that position.
12132 We assume that the window's buffer is really current. */
12134 static INLINE struct text_pos
12135 run_window_scroll_functions (window, startp)
12136 Lisp_Object window;
12137 struct text_pos startp;
12139 struct window *w = XWINDOW (window);
12140 SET_MARKER_FROM_TEXT_POS (w->start, startp);
12142 if (current_buffer != XBUFFER (w->buffer))
12143 abort ();
12145 if (!NILP (Vwindow_scroll_functions))
12147 run_hook_with_args_2 (Qwindow_scroll_functions, window,
12148 make_number (CHARPOS (startp)));
12149 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12150 /* In case the hook functions switch buffers. */
12151 if (current_buffer != XBUFFER (w->buffer))
12152 set_buffer_internal_1 (XBUFFER (w->buffer));
12155 return startp;
12159 /* Make sure the line containing the cursor is fully visible.
12160 A value of 1 means there is nothing to be done.
12161 (Either the line is fully visible, or it cannot be made so,
12162 or we cannot tell.)
12164 If FORCE_P is non-zero, return 0 even if partial visible cursor row
12165 is higher than window.
12167 A value of 0 means the caller should do scrolling
12168 as if point had gone off the screen. */
12170 static int
12171 cursor_row_fully_visible_p (w, force_p, current_matrix_p)
12172 struct window *w;
12173 int force_p;
12174 int current_matrix_p;
12176 struct glyph_matrix *matrix;
12177 struct glyph_row *row;
12178 int window_height;
12180 if (!make_cursor_line_fully_visible_p)
12181 return 1;
12183 /* It's not always possible to find the cursor, e.g, when a window
12184 is full of overlay strings. Don't do anything in that case. */
12185 if (w->cursor.vpos < 0)
12186 return 1;
12188 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
12189 row = MATRIX_ROW (matrix, w->cursor.vpos);
12191 /* If the cursor row is not partially visible, there's nothing to do. */
12192 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
12193 return 1;
12195 /* If the row the cursor is in is taller than the window's height,
12196 it's not clear what to do, so do nothing. */
12197 window_height = window_box_height (w);
12198 if (row->height >= window_height)
12200 if (!force_p || MINI_WINDOW_P (w)
12201 || w->vscroll || w->cursor.vpos == 0)
12202 return 1;
12204 return 0;
12206 #if 0
12207 /* This code used to try to scroll the window just enough to make
12208 the line visible. It returned 0 to say that the caller should
12209 allocate larger glyph matrices. */
12211 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
12213 int dy = row->height - row->visible_height;
12214 w->vscroll = 0;
12215 w->cursor.y += dy;
12216 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
12218 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
12220 int dy = - (row->height - row->visible_height);
12221 w->vscroll = dy;
12222 w->cursor.y += dy;
12223 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
12226 /* When we change the cursor y-position of the selected window,
12227 change this_line_y as well so that the display optimization for
12228 the cursor line of the selected window in redisplay_internal uses
12229 the correct y-position. */
12230 if (w == XWINDOW (selected_window))
12231 this_line_y = w->cursor.y;
12233 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
12234 redisplay with larger matrices. */
12235 if (matrix->nrows < required_matrix_height (w))
12237 fonts_changed_p = 1;
12238 return 0;
12241 return 1;
12242 #endif /* 0 */
12246 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
12247 non-zero means only WINDOW is redisplayed in redisplay_internal.
12248 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
12249 in redisplay_window to bring a partially visible line into view in
12250 the case that only the cursor has moved.
12252 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
12253 last screen line's vertical height extends past the end of the screen.
12255 Value is
12257 1 if scrolling succeeded
12259 0 if scrolling didn't find point.
12261 -1 if new fonts have been loaded so that we must interrupt
12262 redisplay, adjust glyph matrices, and try again. */
12264 enum
12266 SCROLLING_SUCCESS,
12267 SCROLLING_FAILED,
12268 SCROLLING_NEED_LARGER_MATRICES
12271 static int
12272 try_scrolling (window, just_this_one_p, scroll_conservatively,
12273 scroll_step, temp_scroll_step, last_line_misfit)
12274 Lisp_Object window;
12275 int just_this_one_p;
12276 EMACS_INT scroll_conservatively, scroll_step;
12277 int temp_scroll_step;
12278 int last_line_misfit;
12280 struct window *w = XWINDOW (window);
12281 struct frame *f = XFRAME (w->frame);
12282 struct text_pos scroll_margin_pos;
12283 struct text_pos pos;
12284 struct text_pos startp;
12285 struct it it;
12286 Lisp_Object window_end;
12287 int this_scroll_margin;
12288 int dy = 0;
12289 int scroll_max;
12290 int rc;
12291 int amount_to_scroll = 0;
12292 Lisp_Object aggressive;
12293 int height;
12294 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
12296 #if GLYPH_DEBUG
12297 debug_method_add (w, "try_scrolling");
12298 #endif
12300 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12302 /* Compute scroll margin height in pixels. We scroll when point is
12303 within this distance from the top or bottom of the window. */
12304 if (scroll_margin > 0)
12306 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
12307 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
12309 else
12310 this_scroll_margin = 0;
12312 /* Force scroll_conservatively to have a reasonable value so it doesn't
12313 cause an overflow while computing how much to scroll. */
12314 if (scroll_conservatively)
12315 scroll_conservatively = min (scroll_conservatively,
12316 MOST_POSITIVE_FIXNUM / FRAME_LINE_HEIGHT (f));
12318 /* Compute how much we should try to scroll maximally to bring point
12319 into view. */
12320 if (scroll_step || scroll_conservatively || temp_scroll_step)
12321 scroll_max = max (scroll_step,
12322 max (scroll_conservatively, temp_scroll_step));
12323 else if (NUMBERP (current_buffer->scroll_down_aggressively)
12324 || NUMBERP (current_buffer->scroll_up_aggressively))
12325 /* We're trying to scroll because of aggressive scrolling
12326 but no scroll_step is set. Choose an arbitrary one. Maybe
12327 there should be a variable for this. */
12328 scroll_max = 10;
12329 else
12330 scroll_max = 0;
12331 scroll_max *= FRAME_LINE_HEIGHT (f);
12333 /* Decide whether we have to scroll down. Start at the window end
12334 and move this_scroll_margin up to find the position of the scroll
12335 margin. */
12336 window_end = Fwindow_end (window, Qt);
12338 too_near_end:
12340 CHARPOS (scroll_margin_pos) = XINT (window_end);
12341 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
12343 if (this_scroll_margin || extra_scroll_margin_lines)
12345 start_display (&it, w, scroll_margin_pos);
12346 if (this_scroll_margin)
12347 move_it_vertically_backward (&it, this_scroll_margin);
12348 if (extra_scroll_margin_lines)
12349 move_it_by_lines (&it, - extra_scroll_margin_lines, 0);
12350 scroll_margin_pos = it.current.pos;
12353 if (PT >= CHARPOS (scroll_margin_pos))
12355 int y0;
12357 /* Point is in the scroll margin at the bottom of the window, or
12358 below. Compute a new window start that makes point visible. */
12360 /* Compute the distance from the scroll margin to PT.
12361 Give up if the distance is greater than scroll_max. */
12362 start_display (&it, w, scroll_margin_pos);
12363 y0 = it.current_y;
12364 move_it_to (&it, PT, 0, it.last_visible_y, -1,
12365 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
12367 /* To make point visible, we have to move the window start
12368 down so that the line the cursor is in is visible, which
12369 means we have to add in the height of the cursor line. */
12370 dy = line_bottom_y (&it) - y0;
12372 if (dy > scroll_max)
12373 return SCROLLING_FAILED;
12375 /* Move the window start down. If scrolling conservatively,
12376 move it just enough down to make point visible. If
12377 scroll_step is set, move it down by scroll_step. */
12378 start_display (&it, w, startp);
12380 if (scroll_conservatively)
12381 /* Set AMOUNT_TO_SCROLL to at least one line,
12382 and at most scroll_conservatively lines. */
12383 amount_to_scroll
12384 = min (max (dy, FRAME_LINE_HEIGHT (f)),
12385 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
12386 else if (scroll_step || temp_scroll_step)
12387 amount_to_scroll = scroll_max;
12388 else
12390 aggressive = current_buffer->scroll_up_aggressively;
12391 height = WINDOW_BOX_TEXT_HEIGHT (w);
12392 if (NUMBERP (aggressive))
12394 double float_amount = XFLOATINT (aggressive) * height;
12395 amount_to_scroll = float_amount;
12396 if (amount_to_scroll == 0 && float_amount > 0)
12397 amount_to_scroll = 1;
12401 if (amount_to_scroll <= 0)
12402 return SCROLLING_FAILED;
12404 /* If moving by amount_to_scroll leaves STARTP unchanged,
12405 move it down one screen line. */
12407 move_it_vertically (&it, amount_to_scroll);
12408 if (CHARPOS (it.current.pos) == CHARPOS (startp))
12409 move_it_by_lines (&it, 1, 1);
12410 startp = it.current.pos;
12412 else
12414 /* See if point is inside the scroll margin at the top of the
12415 window. */
12416 scroll_margin_pos = startp;
12417 if (this_scroll_margin)
12419 start_display (&it, w, startp);
12420 move_it_vertically (&it, this_scroll_margin);
12421 scroll_margin_pos = it.current.pos;
12424 if (PT < CHARPOS (scroll_margin_pos))
12426 /* Point is in the scroll margin at the top of the window or
12427 above what is displayed in the window. */
12428 int y0;
12430 /* Compute the vertical distance from PT to the scroll
12431 margin position. Give up if distance is greater than
12432 scroll_max. */
12433 SET_TEXT_POS (pos, PT, PT_BYTE);
12434 start_display (&it, w, pos);
12435 y0 = it.current_y;
12436 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
12437 it.last_visible_y, -1,
12438 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
12439 dy = it.current_y - y0;
12440 if (dy > scroll_max)
12441 return SCROLLING_FAILED;
12443 /* Compute new window start. */
12444 start_display (&it, w, startp);
12446 if (scroll_conservatively)
12447 amount_to_scroll
12448 = max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
12449 else if (scroll_step || temp_scroll_step)
12450 amount_to_scroll = scroll_max;
12451 else
12453 aggressive = current_buffer->scroll_down_aggressively;
12454 height = WINDOW_BOX_TEXT_HEIGHT (w);
12455 if (NUMBERP (aggressive))
12457 double float_amount = XFLOATINT (aggressive) * height;
12458 amount_to_scroll = float_amount;
12459 if (amount_to_scroll == 0 && float_amount > 0)
12460 amount_to_scroll = 1;
12464 if (amount_to_scroll <= 0)
12465 return SCROLLING_FAILED;
12467 move_it_vertically_backward (&it, amount_to_scroll);
12468 startp = it.current.pos;
12472 /* Run window scroll functions. */
12473 startp = run_window_scroll_functions (window, startp);
12475 /* Display the window. Give up if new fonts are loaded, or if point
12476 doesn't appear. */
12477 if (!try_window (window, startp, 0))
12478 rc = SCROLLING_NEED_LARGER_MATRICES;
12479 else if (w->cursor.vpos < 0)
12481 clear_glyph_matrix (w->desired_matrix);
12482 rc = SCROLLING_FAILED;
12484 else
12486 /* Maybe forget recorded base line for line number display. */
12487 if (!just_this_one_p
12488 || current_buffer->clip_changed
12489 || BEG_UNCHANGED < CHARPOS (startp))
12490 w->base_line_number = Qnil;
12492 /* If cursor ends up on a partially visible line,
12493 treat that as being off the bottom of the screen. */
12494 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0))
12496 clear_glyph_matrix (w->desired_matrix);
12497 ++extra_scroll_margin_lines;
12498 goto too_near_end;
12500 rc = SCROLLING_SUCCESS;
12503 return rc;
12507 /* Compute a suitable window start for window W if display of W starts
12508 on a continuation line. Value is non-zero if a new window start
12509 was computed.
12511 The new window start will be computed, based on W's width, starting
12512 from the start of the continued line. It is the start of the
12513 screen line with the minimum distance from the old start W->start. */
12515 static int
12516 compute_window_start_on_continuation_line (w)
12517 struct window *w;
12519 struct text_pos pos, start_pos;
12520 int window_start_changed_p = 0;
12522 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
12524 /* If window start is on a continuation line... Window start may be
12525 < BEGV in case there's invisible text at the start of the
12526 buffer (M-x rmail, for example). */
12527 if (CHARPOS (start_pos) > BEGV
12528 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
12530 struct it it;
12531 struct glyph_row *row;
12533 /* Handle the case that the window start is out of range. */
12534 if (CHARPOS (start_pos) < BEGV)
12535 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
12536 else if (CHARPOS (start_pos) > ZV)
12537 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
12539 /* Find the start of the continued line. This should be fast
12540 because scan_buffer is fast (newline cache). */
12541 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
12542 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
12543 row, DEFAULT_FACE_ID);
12544 reseat_at_previous_visible_line_start (&it);
12546 /* If the line start is "too far" away from the window start,
12547 say it takes too much time to compute a new window start. */
12548 if (CHARPOS (start_pos) - IT_CHARPOS (it)
12549 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
12551 int min_distance, distance;
12553 /* Move forward by display lines to find the new window
12554 start. If window width was enlarged, the new start can
12555 be expected to be > the old start. If window width was
12556 decreased, the new window start will be < the old start.
12557 So, we're looking for the display line start with the
12558 minimum distance from the old window start. */
12559 pos = it.current.pos;
12560 min_distance = INFINITY;
12561 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
12562 distance < min_distance)
12564 min_distance = distance;
12565 pos = it.current.pos;
12566 move_it_by_lines (&it, 1, 0);
12569 /* Set the window start there. */
12570 SET_MARKER_FROM_TEXT_POS (w->start, pos);
12571 window_start_changed_p = 1;
12575 return window_start_changed_p;
12579 /* Try cursor movement in case text has not changed in window WINDOW,
12580 with window start STARTP. Value is
12582 CURSOR_MOVEMENT_SUCCESS if successful
12584 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
12586 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
12587 display. *SCROLL_STEP is set to 1, under certain circumstances, if
12588 we want to scroll as if scroll-step were set to 1. See the code.
12590 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
12591 which case we have to abort this redisplay, and adjust matrices
12592 first. */
12594 enum
12596 CURSOR_MOVEMENT_SUCCESS,
12597 CURSOR_MOVEMENT_CANNOT_BE_USED,
12598 CURSOR_MOVEMENT_MUST_SCROLL,
12599 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
12602 static int
12603 try_cursor_movement (window, startp, scroll_step)
12604 Lisp_Object window;
12605 struct text_pos startp;
12606 int *scroll_step;
12608 struct window *w = XWINDOW (window);
12609 struct frame *f = XFRAME (w->frame);
12610 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
12612 #if GLYPH_DEBUG
12613 if (inhibit_try_cursor_movement)
12614 return rc;
12615 #endif
12617 /* Handle case where text has not changed, only point, and it has
12618 not moved off the frame. */
12619 if (/* Point may be in this window. */
12620 PT >= CHARPOS (startp)
12621 /* Selective display hasn't changed. */
12622 && !current_buffer->clip_changed
12623 /* Function force-mode-line-update is used to force a thorough
12624 redisplay. It sets either windows_or_buffers_changed or
12625 update_mode_lines. So don't take a shortcut here for these
12626 cases. */
12627 && !update_mode_lines
12628 && !windows_or_buffers_changed
12629 && !cursor_type_changed
12630 /* Can't use this case if highlighting a region. When a
12631 region exists, cursor movement has to do more than just
12632 set the cursor. */
12633 && !(!NILP (Vtransient_mark_mode)
12634 && !NILP (current_buffer->mark_active))
12635 && NILP (w->region_showing)
12636 && NILP (Vshow_trailing_whitespace)
12637 /* Right after splitting windows, last_point may be nil. */
12638 && INTEGERP (w->last_point)
12639 /* This code is not used for mini-buffer for the sake of the case
12640 of redisplaying to replace an echo area message; since in
12641 that case the mini-buffer contents per se are usually
12642 unchanged. This code is of no real use in the mini-buffer
12643 since the handling of this_line_start_pos, etc., in redisplay
12644 handles the same cases. */
12645 && !EQ (window, minibuf_window)
12646 /* When splitting windows or for new windows, it happens that
12647 redisplay is called with a nil window_end_vpos or one being
12648 larger than the window. This should really be fixed in
12649 window.c. I don't have this on my list, now, so we do
12650 approximately the same as the old redisplay code. --gerd. */
12651 && INTEGERP (w->window_end_vpos)
12652 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
12653 && (FRAME_WINDOW_P (f)
12654 || !overlay_arrow_in_current_buffer_p ()))
12656 int this_scroll_margin, top_scroll_margin;
12657 struct glyph_row *row = NULL;
12659 #if GLYPH_DEBUG
12660 debug_method_add (w, "cursor movement");
12661 #endif
12663 /* Scroll if point within this distance from the top or bottom
12664 of the window. This is a pixel value. */
12665 this_scroll_margin = max (0, scroll_margin);
12666 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
12667 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
12669 top_scroll_margin = this_scroll_margin;
12670 if (WINDOW_WANTS_HEADER_LINE_P (w))
12671 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
12673 /* Start with the row the cursor was displayed during the last
12674 not paused redisplay. Give up if that row is not valid. */
12675 if (w->last_cursor.vpos < 0
12676 || w->last_cursor.vpos >= w->current_matrix->nrows)
12677 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12678 else
12680 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
12681 if (row->mode_line_p)
12682 ++row;
12683 if (!row->enabled_p)
12684 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12687 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
12689 int scroll_p = 0;
12690 int last_y = window_text_bottom_y (w) - this_scroll_margin;
12692 if (PT > XFASTINT (w->last_point))
12694 /* Point has moved forward. */
12695 while (MATRIX_ROW_END_CHARPOS (row) < PT
12696 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
12698 xassert (row->enabled_p);
12699 ++row;
12702 /* The end position of a row equals the start position
12703 of the next row. If PT is there, we would rather
12704 display it in the next line. */
12705 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
12706 && MATRIX_ROW_END_CHARPOS (row) == PT
12707 && !cursor_row_p (w, row))
12708 ++row;
12710 /* If within the scroll margin, scroll. Note that
12711 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
12712 the next line would be drawn, and that
12713 this_scroll_margin can be zero. */
12714 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
12715 || PT > MATRIX_ROW_END_CHARPOS (row)
12716 /* Line is completely visible last line in window
12717 and PT is to be set in the next line. */
12718 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
12719 && PT == MATRIX_ROW_END_CHARPOS (row)
12720 && !row->ends_at_zv_p
12721 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
12722 scroll_p = 1;
12724 else if (PT < XFASTINT (w->last_point))
12726 /* Cursor has to be moved backward. Note that PT >=
12727 CHARPOS (startp) because of the outer if-statement. */
12728 while (!row->mode_line_p
12729 && (MATRIX_ROW_START_CHARPOS (row) > PT
12730 || (MATRIX_ROW_START_CHARPOS (row) == PT
12731 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
12732 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
12733 row > w->current_matrix->rows
12734 && (row-1)->ends_in_newline_from_string_p))))
12735 && (row->y > top_scroll_margin
12736 || CHARPOS (startp) == BEGV))
12738 xassert (row->enabled_p);
12739 --row;
12742 /* Consider the following case: Window starts at BEGV,
12743 there is invisible, intangible text at BEGV, so that
12744 display starts at some point START > BEGV. It can
12745 happen that we are called with PT somewhere between
12746 BEGV and START. Try to handle that case. */
12747 if (row < w->current_matrix->rows
12748 || row->mode_line_p)
12750 row = w->current_matrix->rows;
12751 if (row->mode_line_p)
12752 ++row;
12755 /* Due to newlines in overlay strings, we may have to
12756 skip forward over overlay strings. */
12757 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
12758 && MATRIX_ROW_END_CHARPOS (row) == PT
12759 && !cursor_row_p (w, row))
12760 ++row;
12762 /* If within the scroll margin, scroll. */
12763 if (row->y < top_scroll_margin
12764 && CHARPOS (startp) != BEGV)
12765 scroll_p = 1;
12767 else
12769 /* Cursor did not move. So don't scroll even if cursor line
12770 is partially visible, as it was so before. */
12771 rc = CURSOR_MOVEMENT_SUCCESS;
12774 if (PT < MATRIX_ROW_START_CHARPOS (row)
12775 || PT > MATRIX_ROW_END_CHARPOS (row))
12777 /* if PT is not in the glyph row, give up. */
12778 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12780 else if (rc != CURSOR_MOVEMENT_SUCCESS
12781 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
12782 && make_cursor_line_fully_visible_p)
12784 if (PT == MATRIX_ROW_END_CHARPOS (row)
12785 && !row->ends_at_zv_p
12786 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
12787 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12788 else if (row->height > window_box_height (w))
12790 /* If we end up in a partially visible line, let's
12791 make it fully visible, except when it's taller
12792 than the window, in which case we can't do much
12793 about it. */
12794 *scroll_step = 1;
12795 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12797 else
12799 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
12800 if (!cursor_row_fully_visible_p (w, 0, 1))
12801 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12802 else
12803 rc = CURSOR_MOVEMENT_SUCCESS;
12806 else if (scroll_p)
12807 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12808 else
12812 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
12814 rc = CURSOR_MOVEMENT_SUCCESS;
12815 break;
12817 ++row;
12819 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
12820 && MATRIX_ROW_START_CHARPOS (row) == PT
12821 && cursor_row_p (w, row));
12826 return rc;
12829 void
12830 set_vertical_scroll_bar (w)
12831 struct window *w;
12833 int start, end, whole;
12835 /* Calculate the start and end positions for the current window.
12836 At some point, it would be nice to choose between scrollbars
12837 which reflect the whole buffer size, with special markers
12838 indicating narrowing, and scrollbars which reflect only the
12839 visible region.
12841 Note that mini-buffers sometimes aren't displaying any text. */
12842 if (!MINI_WINDOW_P (w)
12843 || (w == XWINDOW (minibuf_window)
12844 && NILP (echo_area_buffer[0])))
12846 struct buffer *buf = XBUFFER (w->buffer);
12847 whole = BUF_ZV (buf) - BUF_BEGV (buf);
12848 start = marker_position (w->start) - BUF_BEGV (buf);
12849 /* I don't think this is guaranteed to be right. For the
12850 moment, we'll pretend it is. */
12851 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
12853 if (end < start)
12854 end = start;
12855 if (whole < (end - start))
12856 whole = end - start;
12858 else
12859 start = end = whole = 0;
12861 /* Indicate what this scroll bar ought to be displaying now. */
12862 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
12863 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
12864 (w, end - start, whole, start);
12868 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
12869 selected_window is redisplayed.
12871 We can return without actually redisplaying the window if
12872 fonts_changed_p is nonzero. In that case, redisplay_internal will
12873 retry. */
12875 static void
12876 redisplay_window (window, just_this_one_p)
12877 Lisp_Object window;
12878 int just_this_one_p;
12880 struct window *w = XWINDOW (window);
12881 struct frame *f = XFRAME (w->frame);
12882 struct buffer *buffer = XBUFFER (w->buffer);
12883 struct buffer *old = current_buffer;
12884 struct text_pos lpoint, opoint, startp;
12885 int update_mode_line;
12886 int tem;
12887 struct it it;
12888 /* Record it now because it's overwritten. */
12889 int current_matrix_up_to_date_p = 0;
12890 int used_current_matrix_p = 0;
12891 /* This is less strict than current_matrix_up_to_date_p.
12892 It indictes that the buffer contents and narrowing are unchanged. */
12893 int buffer_unchanged_p = 0;
12894 int temp_scroll_step = 0;
12895 int count = SPECPDL_INDEX ();
12896 int rc;
12897 int centering_position = -1;
12898 int last_line_misfit = 0;
12899 int beg_unchanged, end_unchanged;
12901 SET_TEXT_POS (lpoint, PT, PT_BYTE);
12902 opoint = lpoint;
12904 /* W must be a leaf window here. */
12905 xassert (!NILP (w->buffer));
12906 #if GLYPH_DEBUG
12907 *w->desired_matrix->method = 0;
12908 #endif
12910 restart:
12911 reconsider_clip_changes (w, buffer);
12913 /* Has the mode line to be updated? */
12914 update_mode_line = (!NILP (w->update_mode_line)
12915 || update_mode_lines
12916 || buffer->clip_changed
12917 || buffer->prevent_redisplay_optimizations_p);
12919 if (MINI_WINDOW_P (w))
12921 if (w == XWINDOW (echo_area_window)
12922 && !NILP (echo_area_buffer[0]))
12924 if (update_mode_line)
12925 /* We may have to update a tty frame's menu bar or a
12926 tool-bar. Example `M-x C-h C-h C-g'. */
12927 goto finish_menu_bars;
12928 else
12929 /* We've already displayed the echo area glyphs in this window. */
12930 goto finish_scroll_bars;
12932 else if ((w != XWINDOW (minibuf_window)
12933 || minibuf_level == 0)
12934 /* When buffer is nonempty, redisplay window normally. */
12935 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
12936 /* Quail displays non-mini buffers in minibuffer window.
12937 In that case, redisplay the window normally. */
12938 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
12940 /* W is a mini-buffer window, but it's not active, so clear
12941 it. */
12942 int yb = window_text_bottom_y (w);
12943 struct glyph_row *row;
12944 int y;
12946 for (y = 0, row = w->desired_matrix->rows;
12947 y < yb;
12948 y += row->height, ++row)
12949 blank_row (w, row, y);
12950 goto finish_scroll_bars;
12953 clear_glyph_matrix (w->desired_matrix);
12956 /* Otherwise set up data on this window; select its buffer and point
12957 value. */
12958 /* Really select the buffer, for the sake of buffer-local
12959 variables. */
12960 set_buffer_internal_1 (XBUFFER (w->buffer));
12962 current_matrix_up_to_date_p
12963 = (!NILP (w->window_end_valid)
12964 && !current_buffer->clip_changed
12965 && !current_buffer->prevent_redisplay_optimizations_p
12966 && XFASTINT (w->last_modified) >= MODIFF
12967 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
12969 /* Run the window-bottom-change-functions
12970 if it is possible that the text on the screen has changed
12971 (either due to modification of the text, or any other reason). */
12972 if (!current_matrix_up_to_date_p
12973 && !NILP (Vwindow_text_change_functions))
12975 safe_run_hooks (Qwindow_text_change_functions);
12976 goto restart;
12979 beg_unchanged = BEG_UNCHANGED;
12980 end_unchanged = END_UNCHANGED;
12982 SET_TEXT_POS (opoint, PT, PT_BYTE);
12984 specbind (Qinhibit_point_motion_hooks, Qt);
12986 buffer_unchanged_p
12987 = (!NILP (w->window_end_valid)
12988 && !current_buffer->clip_changed
12989 && XFASTINT (w->last_modified) >= MODIFF
12990 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
12992 /* When windows_or_buffers_changed is non-zero, we can't rely on
12993 the window end being valid, so set it to nil there. */
12994 if (windows_or_buffers_changed)
12996 /* If window starts on a continuation line, maybe adjust the
12997 window start in case the window's width changed. */
12998 if (XMARKER (w->start)->buffer == current_buffer)
12999 compute_window_start_on_continuation_line (w);
13001 w->window_end_valid = Qnil;
13004 /* Some sanity checks. */
13005 CHECK_WINDOW_END (w);
13006 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
13007 abort ();
13008 if (BYTEPOS (opoint) < CHARPOS (opoint))
13009 abort ();
13011 /* If %c is in mode line, update it if needed. */
13012 if (!NILP (w->column_number_displayed)
13013 /* This alternative quickly identifies a common case
13014 where no change is needed. */
13015 && !(PT == XFASTINT (w->last_point)
13016 && XFASTINT (w->last_modified) >= MODIFF
13017 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
13018 && (XFASTINT (w->column_number_displayed)
13019 != (int) current_column ())) /* iftc */
13020 update_mode_line = 1;
13022 /* Count number of windows showing the selected buffer. An indirect
13023 buffer counts as its base buffer. */
13024 if (!just_this_one_p)
13026 struct buffer *current_base, *window_base;
13027 current_base = current_buffer;
13028 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
13029 if (current_base->base_buffer)
13030 current_base = current_base->base_buffer;
13031 if (window_base->base_buffer)
13032 window_base = window_base->base_buffer;
13033 if (current_base == window_base)
13034 buffer_shared++;
13037 /* Point refers normally to the selected window. For any other
13038 window, set up appropriate value. */
13039 if (!EQ (window, selected_window))
13041 int new_pt = XMARKER (w->pointm)->charpos;
13042 int new_pt_byte = marker_byte_position (w->pointm);
13043 if (new_pt < BEGV)
13045 new_pt = BEGV;
13046 new_pt_byte = BEGV_BYTE;
13047 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
13049 else if (new_pt > (ZV - 1))
13051 new_pt = ZV;
13052 new_pt_byte = ZV_BYTE;
13053 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
13056 /* We don't use SET_PT so that the point-motion hooks don't run. */
13057 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
13060 /* If any of the character widths specified in the display table
13061 have changed, invalidate the width run cache. It's true that
13062 this may be a bit late to catch such changes, but the rest of
13063 redisplay goes (non-fatally) haywire when the display table is
13064 changed, so why should we worry about doing any better? */
13065 if (current_buffer->width_run_cache)
13067 struct Lisp_Char_Table *disptab = buffer_display_table ();
13069 if (! disptab_matches_widthtab (disptab,
13070 XVECTOR (current_buffer->width_table)))
13072 invalidate_region_cache (current_buffer,
13073 current_buffer->width_run_cache,
13074 BEG, Z);
13075 recompute_width_table (current_buffer, disptab);
13079 /* If window-start is screwed up, choose a new one. */
13080 if (XMARKER (w->start)->buffer != current_buffer)
13081 goto recenter;
13083 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13085 /* If someone specified a new starting point but did not insist,
13086 check whether it can be used. */
13087 if (!NILP (w->optional_new_start)
13088 && CHARPOS (startp) >= BEGV
13089 && CHARPOS (startp) <= ZV)
13091 w->optional_new_start = Qnil;
13092 start_display (&it, w, startp);
13093 move_it_to (&it, PT, 0, it.last_visible_y, -1,
13094 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
13095 if (IT_CHARPOS (it) == PT)
13096 w->force_start = Qt;
13097 /* IT may overshoot PT if text at PT is invisible. */
13098 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
13099 w->force_start = Qt;
13102 force_start:
13104 /* Handle case where place to start displaying has been specified,
13105 unless the specified location is outside the accessible range. */
13106 if (!NILP (w->force_start)
13107 || w->frozen_window_start_p)
13109 /* We set this later on if we have to adjust point. */
13110 int new_vpos = -1;
13111 int val;
13113 w->force_start = Qnil;
13114 w->vscroll = 0;
13115 w->window_end_valid = Qnil;
13117 /* Forget any recorded base line for line number display. */
13118 if (!buffer_unchanged_p)
13119 w->base_line_number = Qnil;
13121 /* Redisplay the mode line. Select the buffer properly for that.
13122 Also, run the hook window-scroll-functions
13123 because we have scrolled. */
13124 /* Note, we do this after clearing force_start because
13125 if there's an error, it is better to forget about force_start
13126 than to get into an infinite loop calling the hook functions
13127 and having them get more errors. */
13128 if (!update_mode_line
13129 || ! NILP (Vwindow_scroll_functions))
13131 update_mode_line = 1;
13132 w->update_mode_line = Qt;
13133 startp = run_window_scroll_functions (window, startp);
13136 w->last_modified = make_number (0);
13137 w->last_overlay_modified = make_number (0);
13138 if (CHARPOS (startp) < BEGV)
13139 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
13140 else if (CHARPOS (startp) > ZV)
13141 SET_TEXT_POS (startp, ZV, ZV_BYTE);
13143 /* Redisplay, then check if cursor has been set during the
13144 redisplay. Give up if new fonts were loaded. */
13145 val = try_window (window, startp, 1);
13146 if (!val)
13148 w->force_start = Qt;
13149 clear_glyph_matrix (w->desired_matrix);
13150 goto need_larger_matrices;
13152 /* Point was outside the scroll margins. */
13153 if (val < 0)
13154 new_vpos = window_box_height (w) / 2;
13156 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
13158 /* If point does not appear, try to move point so it does
13159 appear. The desired matrix has been built above, so we
13160 can use it here. */
13161 new_vpos = window_box_height (w) / 2;
13164 if (!cursor_row_fully_visible_p (w, 0, 0))
13166 /* Point does appear, but on a line partly visible at end of window.
13167 Move it back to a fully-visible line. */
13168 new_vpos = window_box_height (w);
13171 /* If we need to move point for either of the above reasons,
13172 now actually do it. */
13173 if (new_vpos >= 0)
13175 struct glyph_row *row;
13177 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
13178 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
13179 ++row;
13181 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
13182 MATRIX_ROW_START_BYTEPOS (row));
13184 if (w != XWINDOW (selected_window))
13185 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
13186 else if (current_buffer == old)
13187 SET_TEXT_POS (lpoint, PT, PT_BYTE);
13189 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
13191 /* If we are highlighting the region, then we just changed
13192 the region, so redisplay to show it. */
13193 if (!NILP (Vtransient_mark_mode)
13194 && !NILP (current_buffer->mark_active))
13196 clear_glyph_matrix (w->desired_matrix);
13197 if (!try_window (window, startp, 0))
13198 goto need_larger_matrices;
13202 #if GLYPH_DEBUG
13203 debug_method_add (w, "forced window start");
13204 #endif
13205 goto done;
13208 /* Handle case where text has not changed, only point, and it has
13209 not moved off the frame, and we are not retrying after hscroll.
13210 (current_matrix_up_to_date_p is nonzero when retrying.) */
13211 if (current_matrix_up_to_date_p
13212 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
13213 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
13215 switch (rc)
13217 case CURSOR_MOVEMENT_SUCCESS:
13218 used_current_matrix_p = 1;
13219 goto done;
13221 #if 0 /* try_cursor_movement never returns this value. */
13222 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES:
13223 goto need_larger_matrices;
13224 #endif
13226 case CURSOR_MOVEMENT_MUST_SCROLL:
13227 goto try_to_scroll;
13229 default:
13230 abort ();
13233 /* If current starting point was originally the beginning of a line
13234 but no longer is, find a new starting point. */
13235 else if (!NILP (w->start_at_line_beg)
13236 && !(CHARPOS (startp) <= BEGV
13237 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
13239 #if GLYPH_DEBUG
13240 debug_method_add (w, "recenter 1");
13241 #endif
13242 goto recenter;
13245 /* Try scrolling with try_window_id. Value is > 0 if update has
13246 been done, it is -1 if we know that the same window start will
13247 not work. It is 0 if unsuccessful for some other reason. */
13248 else if ((tem = try_window_id (w)) != 0)
13250 #if GLYPH_DEBUG
13251 debug_method_add (w, "try_window_id %d", tem);
13252 #endif
13254 if (fonts_changed_p)
13255 goto need_larger_matrices;
13256 if (tem > 0)
13257 goto done;
13259 /* Otherwise try_window_id has returned -1 which means that we
13260 don't want the alternative below this comment to execute. */
13262 else if (CHARPOS (startp) >= BEGV
13263 && CHARPOS (startp) <= ZV
13264 && PT >= CHARPOS (startp)
13265 && (CHARPOS (startp) < ZV
13266 /* Avoid starting at end of buffer. */
13267 || CHARPOS (startp) == BEGV
13268 || (XFASTINT (w->last_modified) >= MODIFF
13269 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
13272 /* If first window line is a continuation line, and window start
13273 is inside the modified region, but the first change is before
13274 current window start, we must select a new window start.
13276 However, if this is the result of a down-mouse event (e.g. by
13277 extending the mouse-drag-overlay), we don't want to select a
13278 new window start, since that would change the position under
13279 the mouse, resulting in an unwanted mouse-movement rather
13280 than a simple mouse-click. */
13281 if (NILP (w->start_at_line_beg)
13282 && NILP (do_mouse_tracking)
13283 && CHARPOS (startp) > BEGV
13284 && CHARPOS (startp) > BEG + beg_unchanged
13285 && CHARPOS (startp) <= Z - end_unchanged)
13287 w->force_start = Qt;
13288 if (XMARKER (w->start)->buffer == current_buffer)
13289 compute_window_start_on_continuation_line (w);
13290 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13291 goto force_start;
13294 #if GLYPH_DEBUG
13295 debug_method_add (w, "same window start");
13296 #endif
13298 /* Try to redisplay starting at same place as before.
13299 If point has not moved off frame, accept the results. */
13300 if (!current_matrix_up_to_date_p
13301 /* Don't use try_window_reusing_current_matrix in this case
13302 because a window scroll function can have changed the
13303 buffer. */
13304 || !NILP (Vwindow_scroll_functions)
13305 || MINI_WINDOW_P (w)
13306 || !(used_current_matrix_p
13307 = try_window_reusing_current_matrix (w)))
13309 IF_DEBUG (debug_method_add (w, "1"));
13310 if (try_window (window, startp, 1) < 0)
13311 /* -1 means we need to scroll.
13312 0 means we need new matrices, but fonts_changed_p
13313 is set in that case, so we will detect it below. */
13314 goto try_to_scroll;
13317 if (fonts_changed_p)
13318 goto need_larger_matrices;
13320 if (w->cursor.vpos >= 0)
13322 if (!just_this_one_p
13323 || current_buffer->clip_changed
13324 || BEG_UNCHANGED < CHARPOS (startp))
13325 /* Forget any recorded base line for line number display. */
13326 w->base_line_number = Qnil;
13328 if (!cursor_row_fully_visible_p (w, 1, 0))
13330 clear_glyph_matrix (w->desired_matrix);
13331 last_line_misfit = 1;
13333 /* Drop through and scroll. */
13334 else
13335 goto done;
13337 else
13338 clear_glyph_matrix (w->desired_matrix);
13341 try_to_scroll:
13343 w->last_modified = make_number (0);
13344 w->last_overlay_modified = make_number (0);
13346 /* Redisplay the mode line. Select the buffer properly for that. */
13347 if (!update_mode_line)
13349 update_mode_line = 1;
13350 w->update_mode_line = Qt;
13353 /* Try to scroll by specified few lines. */
13354 if ((scroll_conservatively
13355 || scroll_step
13356 || temp_scroll_step
13357 || NUMBERP (current_buffer->scroll_up_aggressively)
13358 || NUMBERP (current_buffer->scroll_down_aggressively))
13359 && !current_buffer->clip_changed
13360 && CHARPOS (startp) >= BEGV
13361 && CHARPOS (startp) <= ZV)
13363 /* The function returns -1 if new fonts were loaded, 1 if
13364 successful, 0 if not successful. */
13365 int rc = try_scrolling (window, just_this_one_p,
13366 scroll_conservatively,
13367 scroll_step,
13368 temp_scroll_step, last_line_misfit);
13369 switch (rc)
13371 case SCROLLING_SUCCESS:
13372 goto done;
13374 case SCROLLING_NEED_LARGER_MATRICES:
13375 goto need_larger_matrices;
13377 case SCROLLING_FAILED:
13378 break;
13380 default:
13381 abort ();
13385 /* Finally, just choose place to start which centers point */
13387 recenter:
13388 if (centering_position < 0)
13389 centering_position = window_box_height (w) / 2;
13391 #if GLYPH_DEBUG
13392 debug_method_add (w, "recenter");
13393 #endif
13395 /* w->vscroll = 0; */
13397 /* Forget any previously recorded base line for line number display. */
13398 if (!buffer_unchanged_p)
13399 w->base_line_number = Qnil;
13401 /* Move backward half the height of the window. */
13402 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
13403 it.current_y = it.last_visible_y;
13404 move_it_vertically_backward (&it, centering_position);
13405 xassert (IT_CHARPOS (it) >= BEGV);
13407 /* The function move_it_vertically_backward may move over more
13408 than the specified y-distance. If it->w is small, e.g. a
13409 mini-buffer window, we may end up in front of the window's
13410 display area. Start displaying at the start of the line
13411 containing PT in this case. */
13412 if (it.current_y <= 0)
13414 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
13415 move_it_vertically_backward (&it, 0);
13416 #if 0
13417 /* I think this assert is bogus if buffer contains
13418 invisible text or images. KFS. */
13419 xassert (IT_CHARPOS (it) <= PT);
13420 #endif
13421 it.current_y = 0;
13424 it.current_x = it.hpos = 0;
13426 /* Set startp here explicitly in case that helps avoid an infinite loop
13427 in case the window-scroll-functions functions get errors. */
13428 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
13430 /* Run scroll hooks. */
13431 startp = run_window_scroll_functions (window, it.current.pos);
13433 /* Redisplay the window. */
13434 if (!current_matrix_up_to_date_p
13435 || windows_or_buffers_changed
13436 || cursor_type_changed
13437 /* Don't use try_window_reusing_current_matrix in this case
13438 because it can have changed the buffer. */
13439 || !NILP (Vwindow_scroll_functions)
13440 || !just_this_one_p
13441 || MINI_WINDOW_P (w)
13442 || !(used_current_matrix_p
13443 = try_window_reusing_current_matrix (w)))
13444 try_window (window, startp, 0);
13446 /* If new fonts have been loaded (due to fontsets), give up. We
13447 have to start a new redisplay since we need to re-adjust glyph
13448 matrices. */
13449 if (fonts_changed_p)
13450 goto need_larger_matrices;
13452 /* If cursor did not appear assume that the middle of the window is
13453 in the first line of the window. Do it again with the next line.
13454 (Imagine a window of height 100, displaying two lines of height
13455 60. Moving back 50 from it->last_visible_y will end in the first
13456 line.) */
13457 if (w->cursor.vpos < 0)
13459 if (!NILP (w->window_end_valid)
13460 && PT >= Z - XFASTINT (w->window_end_pos))
13462 clear_glyph_matrix (w->desired_matrix);
13463 move_it_by_lines (&it, 1, 0);
13464 try_window (window, it.current.pos, 0);
13466 else if (PT < IT_CHARPOS (it))
13468 clear_glyph_matrix (w->desired_matrix);
13469 move_it_by_lines (&it, -1, 0);
13470 try_window (window, it.current.pos, 0);
13472 else
13474 /* Not much we can do about it. */
13478 /* Consider the following case: Window starts at BEGV, there is
13479 invisible, intangible text at BEGV, so that display starts at
13480 some point START > BEGV. It can happen that we are called with
13481 PT somewhere between BEGV and START. Try to handle that case. */
13482 if (w->cursor.vpos < 0)
13484 struct glyph_row *row = w->current_matrix->rows;
13485 if (row->mode_line_p)
13486 ++row;
13487 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13490 if (!cursor_row_fully_visible_p (w, 0, 0))
13492 /* If vscroll is enabled, disable it and try again. */
13493 if (w->vscroll)
13495 w->vscroll = 0;
13496 clear_glyph_matrix (w->desired_matrix);
13497 goto recenter;
13500 /* If centering point failed to make the whole line visible,
13501 put point at the top instead. That has to make the whole line
13502 visible, if it can be done. */
13503 if (centering_position == 0)
13504 goto done;
13506 clear_glyph_matrix (w->desired_matrix);
13507 centering_position = 0;
13508 goto recenter;
13511 done:
13513 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13514 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
13515 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
13516 ? Qt : Qnil);
13518 /* Display the mode line, if we must. */
13519 if ((update_mode_line
13520 /* If window not full width, must redo its mode line
13521 if (a) the window to its side is being redone and
13522 (b) we do a frame-based redisplay. This is a consequence
13523 of how inverted lines are drawn in frame-based redisplay. */
13524 || (!just_this_one_p
13525 && !FRAME_WINDOW_P (f)
13526 && !WINDOW_FULL_WIDTH_P (w))
13527 /* Line number to display. */
13528 || INTEGERP (w->base_line_pos)
13529 /* Column number is displayed and different from the one displayed. */
13530 || (!NILP (w->column_number_displayed)
13531 && (XFASTINT (w->column_number_displayed)
13532 != (int) current_column ()))) /* iftc */
13533 /* This means that the window has a mode line. */
13534 && (WINDOW_WANTS_MODELINE_P (w)
13535 || WINDOW_WANTS_HEADER_LINE_P (w)))
13537 display_mode_lines (w);
13539 /* If mode line height has changed, arrange for a thorough
13540 immediate redisplay using the correct mode line height. */
13541 if (WINDOW_WANTS_MODELINE_P (w)
13542 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
13544 fonts_changed_p = 1;
13545 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
13546 = DESIRED_MODE_LINE_HEIGHT (w);
13549 /* If top line height has changed, arrange for a thorough
13550 immediate redisplay using the correct mode line height. */
13551 if (WINDOW_WANTS_HEADER_LINE_P (w)
13552 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
13554 fonts_changed_p = 1;
13555 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
13556 = DESIRED_HEADER_LINE_HEIGHT (w);
13559 if (fonts_changed_p)
13560 goto need_larger_matrices;
13563 if (!line_number_displayed
13564 && !BUFFERP (w->base_line_pos))
13566 w->base_line_pos = Qnil;
13567 w->base_line_number = Qnil;
13570 finish_menu_bars:
13572 /* When we reach a frame's selected window, redo the frame's menu bar. */
13573 if (update_mode_line
13574 && EQ (FRAME_SELECTED_WINDOW (f), window))
13576 int redisplay_menu_p = 0;
13577 int redisplay_tool_bar_p = 0;
13579 if (FRAME_WINDOW_P (f))
13581 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
13582 || defined (USE_GTK)
13583 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
13584 #else
13585 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
13586 #endif
13588 else
13589 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
13591 if (redisplay_menu_p)
13592 display_menu_bar (w);
13594 #ifdef HAVE_WINDOW_SYSTEM
13595 if (FRAME_WINDOW_P (f))
13597 #if defined (USE_GTK) || USE_MAC_TOOLBAR
13598 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
13599 #else
13600 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
13601 && (FRAME_TOOL_BAR_LINES (f) > 0
13602 || !NILP (Vauto_resize_tool_bars));
13603 #endif
13605 if (redisplay_tool_bar_p && redisplay_tool_bar (f))
13607 extern int ignore_mouse_drag_p;
13608 ignore_mouse_drag_p = 1;
13611 #endif
13614 #ifdef HAVE_WINDOW_SYSTEM
13615 if (FRAME_WINDOW_P (f)
13616 && update_window_fringes (w, (just_this_one_p
13617 || (!used_current_matrix_p && !overlay_arrow_seen)
13618 || w->pseudo_window_p)))
13620 update_begin (f);
13621 BLOCK_INPUT;
13622 if (draw_window_fringes (w, 1))
13623 x_draw_vertical_border (w);
13624 UNBLOCK_INPUT;
13625 update_end (f);
13627 #endif /* HAVE_WINDOW_SYSTEM */
13629 /* We go to this label, with fonts_changed_p nonzero,
13630 if it is necessary to try again using larger glyph matrices.
13631 We have to redeem the scroll bar even in this case,
13632 because the loop in redisplay_internal expects that. */
13633 need_larger_matrices:
13635 finish_scroll_bars:
13637 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
13639 /* Set the thumb's position and size. */
13640 set_vertical_scroll_bar (w);
13642 /* Note that we actually used the scroll bar attached to this
13643 window, so it shouldn't be deleted at the end of redisplay. */
13644 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
13645 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
13648 /* Restore current_buffer and value of point in it. */
13649 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
13650 set_buffer_internal_1 (old);
13651 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
13652 shorter. This can be caused by log truncation in *Messages*. */
13653 if (CHARPOS (lpoint) <= ZV)
13654 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
13656 unbind_to (count, Qnil);
13660 /* Build the complete desired matrix of WINDOW with a window start
13661 buffer position POS.
13663 Value is 1 if successful. It is zero if fonts were loaded during
13664 redisplay which makes re-adjusting glyph matrices necessary, and -1
13665 if point would appear in the scroll margins.
13666 (We check that only if CHECK_MARGINS is nonzero. */
13669 try_window (window, pos, check_margins)
13670 Lisp_Object window;
13671 struct text_pos pos;
13672 int check_margins;
13674 struct window *w = XWINDOW (window);
13675 struct it it;
13676 struct glyph_row *last_text_row = NULL;
13677 struct frame *f = XFRAME (w->frame);
13679 /* Make POS the new window start. */
13680 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
13682 /* Mark cursor position as unknown. No overlay arrow seen. */
13683 w->cursor.vpos = -1;
13684 overlay_arrow_seen = 0;
13686 /* Initialize iterator and info to start at POS. */
13687 start_display (&it, w, pos);
13689 /* Display all lines of W. */
13690 while (it.current_y < it.last_visible_y)
13692 if (display_line (&it))
13693 last_text_row = it.glyph_row - 1;
13694 if (fonts_changed_p)
13695 return 0;
13698 /* Don't let the cursor end in the scroll margins. */
13699 if (check_margins
13700 && !MINI_WINDOW_P (w))
13702 int this_scroll_margin;
13704 this_scroll_margin = max (0, scroll_margin);
13705 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13706 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
13708 if ((w->cursor.y >= 0 /* not vscrolled */
13709 && w->cursor.y < this_scroll_margin
13710 && CHARPOS (pos) > BEGV
13711 && IT_CHARPOS (it) < ZV)
13712 /* rms: considering make_cursor_line_fully_visible_p here
13713 seems to give wrong results. We don't want to recenter
13714 when the last line is partly visible, we want to allow
13715 that case to be handled in the usual way. */
13716 || (w->cursor.y + 1) > it.last_visible_y)
13718 w->cursor.vpos = -1;
13719 clear_glyph_matrix (w->desired_matrix);
13720 return -1;
13724 /* If bottom moved off end of frame, change mode line percentage. */
13725 if (XFASTINT (w->window_end_pos) <= 0
13726 && Z != IT_CHARPOS (it))
13727 w->update_mode_line = Qt;
13729 /* Set window_end_pos to the offset of the last character displayed
13730 on the window from the end of current_buffer. Set
13731 window_end_vpos to its row number. */
13732 if (last_text_row)
13734 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
13735 w->window_end_bytepos
13736 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13737 w->window_end_pos
13738 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13739 w->window_end_vpos
13740 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
13741 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
13742 ->displays_text_p);
13744 else
13746 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
13747 w->window_end_pos = make_number (Z - ZV);
13748 w->window_end_vpos = make_number (0);
13751 /* But that is not valid info until redisplay finishes. */
13752 w->window_end_valid = Qnil;
13753 return 1;
13758 /************************************************************************
13759 Window redisplay reusing current matrix when buffer has not changed
13760 ************************************************************************/
13762 /* Try redisplay of window W showing an unchanged buffer with a
13763 different window start than the last time it was displayed by
13764 reusing its current matrix. Value is non-zero if successful.
13765 W->start is the new window start. */
13767 static int
13768 try_window_reusing_current_matrix (w)
13769 struct window *w;
13771 struct frame *f = XFRAME (w->frame);
13772 struct glyph_row *row, *bottom_row;
13773 struct it it;
13774 struct run run;
13775 struct text_pos start, new_start;
13776 int nrows_scrolled, i;
13777 struct glyph_row *last_text_row;
13778 struct glyph_row *last_reused_text_row;
13779 struct glyph_row *start_row;
13780 int start_vpos, min_y, max_y;
13782 #if GLYPH_DEBUG
13783 if (inhibit_try_window_reusing)
13784 return 0;
13785 #endif
13787 if (/* This function doesn't handle terminal frames. */
13788 !FRAME_WINDOW_P (f)
13789 /* Don't try to reuse the display if windows have been split
13790 or such. */
13791 || windows_or_buffers_changed
13792 || cursor_type_changed)
13793 return 0;
13795 /* Can't do this if region may have changed. */
13796 if ((!NILP (Vtransient_mark_mode)
13797 && !NILP (current_buffer->mark_active))
13798 || !NILP (w->region_showing)
13799 || !NILP (Vshow_trailing_whitespace))
13800 return 0;
13802 /* If top-line visibility has changed, give up. */
13803 if (WINDOW_WANTS_HEADER_LINE_P (w)
13804 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
13805 return 0;
13807 /* Give up if old or new display is scrolled vertically. We could
13808 make this function handle this, but right now it doesn't. */
13809 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
13810 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
13811 return 0;
13813 /* The variable new_start now holds the new window start. The old
13814 start `start' can be determined from the current matrix. */
13815 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
13816 start = start_row->start.pos;
13817 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
13819 /* Clear the desired matrix for the display below. */
13820 clear_glyph_matrix (w->desired_matrix);
13822 if (CHARPOS (new_start) <= CHARPOS (start))
13824 int first_row_y;
13826 /* Don't use this method if the display starts with an ellipsis
13827 displayed for invisible text. It's not easy to handle that case
13828 below, and it's certainly not worth the effort since this is
13829 not a frequent case. */
13830 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
13831 return 0;
13833 IF_DEBUG (debug_method_add (w, "twu1"));
13835 /* Display up to a row that can be reused. The variable
13836 last_text_row is set to the last row displayed that displays
13837 text. Note that it.vpos == 0 if or if not there is a
13838 header-line; it's not the same as the MATRIX_ROW_VPOS! */
13839 start_display (&it, w, new_start);
13840 first_row_y = it.current_y;
13841 w->cursor.vpos = -1;
13842 last_text_row = last_reused_text_row = NULL;
13844 while (it.current_y < it.last_visible_y
13845 && !fonts_changed_p)
13847 /* If we have reached into the characters in the START row,
13848 that means the line boundaries have changed. So we
13849 can't start copying with the row START. Maybe it will
13850 work to start copying with the following row. */
13851 while (IT_CHARPOS (it) > CHARPOS (start))
13853 /* Advance to the next row as the "start". */
13854 start_row++;
13855 start = start_row->start.pos;
13856 /* If there are no more rows to try, or just one, give up. */
13857 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
13858 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
13859 || CHARPOS (start) == ZV)
13861 clear_glyph_matrix (w->desired_matrix);
13862 return 0;
13865 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
13867 /* If we have reached alignment,
13868 we can copy the rest of the rows. */
13869 if (IT_CHARPOS (it) == CHARPOS (start))
13870 break;
13872 if (display_line (&it))
13873 last_text_row = it.glyph_row - 1;
13876 /* A value of current_y < last_visible_y means that we stopped
13877 at the previous window start, which in turn means that we
13878 have at least one reusable row. */
13879 if (it.current_y < it.last_visible_y)
13881 /* IT.vpos always starts from 0; it counts text lines. */
13882 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
13884 /* Find PT if not already found in the lines displayed. */
13885 if (w->cursor.vpos < 0)
13887 int dy = it.current_y - start_row->y;
13889 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
13890 row = row_containing_pos (w, PT, row, NULL, dy);
13891 if (row)
13892 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
13893 dy, nrows_scrolled);
13894 else
13896 clear_glyph_matrix (w->desired_matrix);
13897 return 0;
13901 /* Scroll the display. Do it before the current matrix is
13902 changed. The problem here is that update has not yet
13903 run, i.e. part of the current matrix is not up to date.
13904 scroll_run_hook will clear the cursor, and use the
13905 current matrix to get the height of the row the cursor is
13906 in. */
13907 run.current_y = start_row->y;
13908 run.desired_y = it.current_y;
13909 run.height = it.last_visible_y - it.current_y;
13911 if (run.height > 0 && run.current_y != run.desired_y)
13913 update_begin (f);
13914 FRAME_RIF (f)->update_window_begin_hook (w);
13915 FRAME_RIF (f)->clear_window_mouse_face (w);
13916 FRAME_RIF (f)->scroll_run_hook (w, &run);
13917 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
13918 update_end (f);
13921 /* Shift current matrix down by nrows_scrolled lines. */
13922 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
13923 rotate_matrix (w->current_matrix,
13924 start_vpos,
13925 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
13926 nrows_scrolled);
13928 /* Disable lines that must be updated. */
13929 for (i = 0; i < nrows_scrolled; ++i)
13930 (start_row + i)->enabled_p = 0;
13932 /* Re-compute Y positions. */
13933 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
13934 max_y = it.last_visible_y;
13935 for (row = start_row + nrows_scrolled;
13936 row < bottom_row;
13937 ++row)
13939 row->y = it.current_y;
13940 row->visible_height = row->height;
13942 if (row->y < min_y)
13943 row->visible_height -= min_y - row->y;
13944 if (row->y + row->height > max_y)
13945 row->visible_height -= row->y + row->height - max_y;
13946 row->redraw_fringe_bitmaps_p = 1;
13948 it.current_y += row->height;
13950 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
13951 last_reused_text_row = row;
13952 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
13953 break;
13956 /* Disable lines in the current matrix which are now
13957 below the window. */
13958 for (++row; row < bottom_row; ++row)
13959 row->enabled_p = row->mode_line_p = 0;
13962 /* Update window_end_pos etc.; last_reused_text_row is the last
13963 reused row from the current matrix containing text, if any.
13964 The value of last_text_row is the last displayed line
13965 containing text. */
13966 if (last_reused_text_row)
13968 w->window_end_bytepos
13969 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
13970 w->window_end_pos
13971 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
13972 w->window_end_vpos
13973 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
13974 w->current_matrix));
13976 else if (last_text_row)
13978 w->window_end_bytepos
13979 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13980 w->window_end_pos
13981 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13982 w->window_end_vpos
13983 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
13985 else
13987 /* This window must be completely empty. */
13988 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
13989 w->window_end_pos = make_number (Z - ZV);
13990 w->window_end_vpos = make_number (0);
13992 w->window_end_valid = Qnil;
13994 /* Update hint: don't try scrolling again in update_window. */
13995 w->desired_matrix->no_scrolling_p = 1;
13997 #if GLYPH_DEBUG
13998 debug_method_add (w, "try_window_reusing_current_matrix 1");
13999 #endif
14000 return 1;
14002 else if (CHARPOS (new_start) > CHARPOS (start))
14004 struct glyph_row *pt_row, *row;
14005 struct glyph_row *first_reusable_row;
14006 struct glyph_row *first_row_to_display;
14007 int dy;
14008 int yb = window_text_bottom_y (w);
14010 /* Find the row starting at new_start, if there is one. Don't
14011 reuse a partially visible line at the end. */
14012 first_reusable_row = start_row;
14013 while (first_reusable_row->enabled_p
14014 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
14015 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
14016 < CHARPOS (new_start)))
14017 ++first_reusable_row;
14019 /* Give up if there is no row to reuse. */
14020 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
14021 || !first_reusable_row->enabled_p
14022 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
14023 != CHARPOS (new_start)))
14024 return 0;
14026 /* We can reuse fully visible rows beginning with
14027 first_reusable_row to the end of the window. Set
14028 first_row_to_display to the first row that cannot be reused.
14029 Set pt_row to the row containing point, if there is any. */
14030 pt_row = NULL;
14031 for (first_row_to_display = first_reusable_row;
14032 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
14033 ++first_row_to_display)
14035 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
14036 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
14037 pt_row = first_row_to_display;
14040 /* Start displaying at the start of first_row_to_display. */
14041 xassert (first_row_to_display->y < yb);
14042 init_to_row_start (&it, w, first_row_to_display);
14044 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
14045 - start_vpos);
14046 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
14047 - nrows_scrolled);
14048 it.current_y = (first_row_to_display->y - first_reusable_row->y
14049 + WINDOW_HEADER_LINE_HEIGHT (w));
14051 /* Display lines beginning with first_row_to_display in the
14052 desired matrix. Set last_text_row to the last row displayed
14053 that displays text. */
14054 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
14055 if (pt_row == NULL)
14056 w->cursor.vpos = -1;
14057 last_text_row = NULL;
14058 while (it.current_y < it.last_visible_y && !fonts_changed_p)
14059 if (display_line (&it))
14060 last_text_row = it.glyph_row - 1;
14062 /* Give up If point isn't in a row displayed or reused. */
14063 if (w->cursor.vpos < 0)
14065 clear_glyph_matrix (w->desired_matrix);
14066 return 0;
14069 /* If point is in a reused row, adjust y and vpos of the cursor
14070 position. */
14071 if (pt_row)
14073 w->cursor.vpos -= nrows_scrolled;
14074 w->cursor.y -= first_reusable_row->y - start_row->y;
14077 /* Scroll the display. */
14078 run.current_y = first_reusable_row->y;
14079 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
14080 run.height = it.last_visible_y - run.current_y;
14081 dy = run.current_y - run.desired_y;
14083 if (run.height)
14085 update_begin (f);
14086 FRAME_RIF (f)->update_window_begin_hook (w);
14087 FRAME_RIF (f)->clear_window_mouse_face (w);
14088 FRAME_RIF (f)->scroll_run_hook (w, &run);
14089 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
14090 update_end (f);
14093 /* Adjust Y positions of reused rows. */
14094 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
14095 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
14096 max_y = it.last_visible_y;
14097 for (row = first_reusable_row; row < first_row_to_display; ++row)
14099 row->y -= dy;
14100 row->visible_height = row->height;
14101 if (row->y < min_y)
14102 row->visible_height -= min_y - row->y;
14103 if (row->y + row->height > max_y)
14104 row->visible_height -= row->y + row->height - max_y;
14105 row->redraw_fringe_bitmaps_p = 1;
14108 /* Scroll the current matrix. */
14109 xassert (nrows_scrolled > 0);
14110 rotate_matrix (w->current_matrix,
14111 start_vpos,
14112 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
14113 -nrows_scrolled);
14115 /* Disable rows not reused. */
14116 for (row -= nrows_scrolled; row < bottom_row; ++row)
14117 row->enabled_p = 0;
14119 /* Point may have moved to a different line, so we cannot assume that
14120 the previous cursor position is valid; locate the correct row. */
14121 if (pt_row)
14123 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
14124 row < bottom_row && PT >= MATRIX_ROW_END_CHARPOS (row);
14125 row++)
14127 w->cursor.vpos++;
14128 w->cursor.y = row->y;
14130 if (row < bottom_row)
14132 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
14133 while (glyph->charpos < PT)
14135 w->cursor.hpos++;
14136 w->cursor.x += glyph->pixel_width;
14137 glyph++;
14142 /* Adjust window end. A null value of last_text_row means that
14143 the window end is in reused rows which in turn means that
14144 only its vpos can have changed. */
14145 if (last_text_row)
14147 w->window_end_bytepos
14148 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
14149 w->window_end_pos
14150 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
14151 w->window_end_vpos
14152 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
14154 else
14156 w->window_end_vpos
14157 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
14160 w->window_end_valid = Qnil;
14161 w->desired_matrix->no_scrolling_p = 1;
14163 #if GLYPH_DEBUG
14164 debug_method_add (w, "try_window_reusing_current_matrix 2");
14165 #endif
14166 return 1;
14169 return 0;
14174 /************************************************************************
14175 Window redisplay reusing current matrix when buffer has changed
14176 ************************************************************************/
14178 static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *));
14179 static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *,
14180 int *, int *));
14181 static struct glyph_row *
14182 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
14183 struct glyph_row *));
14186 /* Return the last row in MATRIX displaying text. If row START is
14187 non-null, start searching with that row. IT gives the dimensions
14188 of the display. Value is null if matrix is empty; otherwise it is
14189 a pointer to the row found. */
14191 static struct glyph_row *
14192 find_last_row_displaying_text (matrix, it, start)
14193 struct glyph_matrix *matrix;
14194 struct it *it;
14195 struct glyph_row *start;
14197 struct glyph_row *row, *row_found;
14199 /* Set row_found to the last row in IT->w's current matrix
14200 displaying text. The loop looks funny but think of partially
14201 visible lines. */
14202 row_found = NULL;
14203 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
14204 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
14206 xassert (row->enabled_p);
14207 row_found = row;
14208 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
14209 break;
14210 ++row;
14213 return row_found;
14217 /* Return the last row in the current matrix of W that is not affected
14218 by changes at the start of current_buffer that occurred since W's
14219 current matrix was built. Value is null if no such row exists.
14221 BEG_UNCHANGED us the number of characters unchanged at the start of
14222 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
14223 first changed character in current_buffer. Characters at positions <
14224 BEG + BEG_UNCHANGED are at the same buffer positions as they were
14225 when the current matrix was built. */
14227 static struct glyph_row *
14228 find_last_unchanged_at_beg_row (w)
14229 struct window *w;
14231 int first_changed_pos = BEG + BEG_UNCHANGED;
14232 struct glyph_row *row;
14233 struct glyph_row *row_found = NULL;
14234 int yb = window_text_bottom_y (w);
14236 /* Find the last row displaying unchanged text. */
14237 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
14238 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
14239 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
14241 if (/* If row ends before first_changed_pos, it is unchanged,
14242 except in some case. */
14243 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
14244 /* When row ends in ZV and we write at ZV it is not
14245 unchanged. */
14246 && !row->ends_at_zv_p
14247 /* When first_changed_pos is the end of a continued line,
14248 row is not unchanged because it may be no longer
14249 continued. */
14250 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
14251 && (row->continued_p
14252 || row->exact_window_width_line_p)))
14253 row_found = row;
14255 /* Stop if last visible row. */
14256 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
14257 break;
14259 ++row;
14262 return row_found;
14266 /* Find the first glyph row in the current matrix of W that is not
14267 affected by changes at the end of current_buffer since the
14268 time W's current matrix was built.
14270 Return in *DELTA the number of chars by which buffer positions in
14271 unchanged text at the end of current_buffer must be adjusted.
14273 Return in *DELTA_BYTES the corresponding number of bytes.
14275 Value is null if no such row exists, i.e. all rows are affected by
14276 changes. */
14278 static struct glyph_row *
14279 find_first_unchanged_at_end_row (w, delta, delta_bytes)
14280 struct window *w;
14281 int *delta, *delta_bytes;
14283 struct glyph_row *row;
14284 struct glyph_row *row_found = NULL;
14286 *delta = *delta_bytes = 0;
14288 /* Display must not have been paused, otherwise the current matrix
14289 is not up to date. */
14290 if (NILP (w->window_end_valid))
14291 abort ();
14293 /* A value of window_end_pos >= END_UNCHANGED means that the window
14294 end is in the range of changed text. If so, there is no
14295 unchanged row at the end of W's current matrix. */
14296 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
14297 return NULL;
14299 /* Set row to the last row in W's current matrix displaying text. */
14300 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
14302 /* If matrix is entirely empty, no unchanged row exists. */
14303 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
14305 /* The value of row is the last glyph row in the matrix having a
14306 meaningful buffer position in it. The end position of row
14307 corresponds to window_end_pos. This allows us to translate
14308 buffer positions in the current matrix to current buffer
14309 positions for characters not in changed text. */
14310 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
14311 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
14312 int last_unchanged_pos, last_unchanged_pos_old;
14313 struct glyph_row *first_text_row
14314 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
14316 *delta = Z - Z_old;
14317 *delta_bytes = Z_BYTE - Z_BYTE_old;
14319 /* Set last_unchanged_pos to the buffer position of the last
14320 character in the buffer that has not been changed. Z is the
14321 index + 1 of the last character in current_buffer, i.e. by
14322 subtracting END_UNCHANGED we get the index of the last
14323 unchanged character, and we have to add BEG to get its buffer
14324 position. */
14325 last_unchanged_pos = Z - END_UNCHANGED + BEG;
14326 last_unchanged_pos_old = last_unchanged_pos - *delta;
14328 /* Search backward from ROW for a row displaying a line that
14329 starts at a minimum position >= last_unchanged_pos_old. */
14330 for (; row > first_text_row; --row)
14332 /* This used to abort, but it can happen.
14333 It is ok to just stop the search instead here. KFS. */
14334 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
14335 break;
14337 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
14338 row_found = row;
14342 if (row_found && !MATRIX_ROW_DISPLAYS_TEXT_P (row_found))
14343 abort ();
14345 return row_found;
14349 /* Make sure that glyph rows in the current matrix of window W
14350 reference the same glyph memory as corresponding rows in the
14351 frame's frame matrix. This function is called after scrolling W's
14352 current matrix on a terminal frame in try_window_id and
14353 try_window_reusing_current_matrix. */
14355 static void
14356 sync_frame_with_window_matrix_rows (w)
14357 struct window *w;
14359 struct frame *f = XFRAME (w->frame);
14360 struct glyph_row *window_row, *window_row_end, *frame_row;
14362 /* Preconditions: W must be a leaf window and full-width. Its frame
14363 must have a frame matrix. */
14364 xassert (NILP (w->hchild) && NILP (w->vchild));
14365 xassert (WINDOW_FULL_WIDTH_P (w));
14366 xassert (!FRAME_WINDOW_P (f));
14368 /* If W is a full-width window, glyph pointers in W's current matrix
14369 have, by definition, to be the same as glyph pointers in the
14370 corresponding frame matrix. Note that frame matrices have no
14371 marginal areas (see build_frame_matrix). */
14372 window_row = w->current_matrix->rows;
14373 window_row_end = window_row + w->current_matrix->nrows;
14374 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
14375 while (window_row < window_row_end)
14377 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
14378 struct glyph *end = window_row->glyphs[LAST_AREA];
14380 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
14381 frame_row->glyphs[TEXT_AREA] = start;
14382 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
14383 frame_row->glyphs[LAST_AREA] = end;
14385 /* Disable frame rows whose corresponding window rows have
14386 been disabled in try_window_id. */
14387 if (!window_row->enabled_p)
14388 frame_row->enabled_p = 0;
14390 ++window_row, ++frame_row;
14395 /* Find the glyph row in window W containing CHARPOS. Consider all
14396 rows between START and END (not inclusive). END null means search
14397 all rows to the end of the display area of W. Value is the row
14398 containing CHARPOS or null. */
14400 struct glyph_row *
14401 row_containing_pos (w, charpos, start, end, dy)
14402 struct window *w;
14403 int charpos;
14404 struct glyph_row *start, *end;
14405 int dy;
14407 struct glyph_row *row = start;
14408 int last_y;
14410 /* If we happen to start on a header-line, skip that. */
14411 if (row->mode_line_p)
14412 ++row;
14414 if ((end && row >= end) || !row->enabled_p)
14415 return NULL;
14417 last_y = window_text_bottom_y (w) - dy;
14419 while (1)
14421 /* Give up if we have gone too far. */
14422 if (end && row >= end)
14423 return NULL;
14424 /* This formerly returned if they were equal.
14425 I think that both quantities are of a "last plus one" type;
14426 if so, when they are equal, the row is within the screen. -- rms. */
14427 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
14428 return NULL;
14430 /* If it is in this row, return this row. */
14431 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
14432 || (MATRIX_ROW_END_CHARPOS (row) == charpos
14433 /* The end position of a row equals the start
14434 position of the next row. If CHARPOS is there, we
14435 would rather display it in the next line, except
14436 when this line ends in ZV. */
14437 && !row->ends_at_zv_p
14438 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
14439 && charpos >= MATRIX_ROW_START_CHARPOS (row))
14440 return row;
14441 ++row;
14446 /* Try to redisplay window W by reusing its existing display. W's
14447 current matrix must be up to date when this function is called,
14448 i.e. window_end_valid must not be nil.
14450 Value is
14452 1 if display has been updated
14453 0 if otherwise unsuccessful
14454 -1 if redisplay with same window start is known not to succeed
14456 The following steps are performed:
14458 1. Find the last row in the current matrix of W that is not
14459 affected by changes at the start of current_buffer. If no such row
14460 is found, give up.
14462 2. Find the first row in W's current matrix that is not affected by
14463 changes at the end of current_buffer. Maybe there is no such row.
14465 3. Display lines beginning with the row + 1 found in step 1 to the
14466 row found in step 2 or, if step 2 didn't find a row, to the end of
14467 the window.
14469 4. If cursor is not known to appear on the window, give up.
14471 5. If display stopped at the row found in step 2, scroll the
14472 display and current matrix as needed.
14474 6. Maybe display some lines at the end of W, if we must. This can
14475 happen under various circumstances, like a partially visible line
14476 becoming fully visible, or because newly displayed lines are displayed
14477 in smaller font sizes.
14479 7. Update W's window end information. */
14481 static int
14482 try_window_id (w)
14483 struct window *w;
14485 struct frame *f = XFRAME (w->frame);
14486 struct glyph_matrix *current_matrix = w->current_matrix;
14487 struct glyph_matrix *desired_matrix = w->desired_matrix;
14488 struct glyph_row *last_unchanged_at_beg_row;
14489 struct glyph_row *first_unchanged_at_end_row;
14490 struct glyph_row *row;
14491 struct glyph_row *bottom_row;
14492 int bottom_vpos;
14493 struct it it;
14494 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
14495 struct text_pos start_pos;
14496 struct run run;
14497 int first_unchanged_at_end_vpos = 0;
14498 struct glyph_row *last_text_row, *last_text_row_at_end;
14499 struct text_pos start;
14500 int first_changed_charpos, last_changed_charpos;
14502 #if GLYPH_DEBUG
14503 if (inhibit_try_window_id)
14504 return 0;
14505 #endif
14507 /* This is handy for debugging. */
14508 #if 0
14509 #define GIVE_UP(X) \
14510 do { \
14511 fprintf (stderr, "try_window_id give up %d\n", (X)); \
14512 return 0; \
14513 } while (0)
14514 #else
14515 #define GIVE_UP(X) return 0
14516 #endif
14518 SET_TEXT_POS_FROM_MARKER (start, w->start);
14520 /* Don't use this for mini-windows because these can show
14521 messages and mini-buffers, and we don't handle that here. */
14522 if (MINI_WINDOW_P (w))
14523 GIVE_UP (1);
14525 /* This flag is used to prevent redisplay optimizations. */
14526 if (windows_or_buffers_changed || cursor_type_changed)
14527 GIVE_UP (2);
14529 /* Verify that narrowing has not changed.
14530 Also verify that we were not told to prevent redisplay optimizations.
14531 It would be nice to further
14532 reduce the number of cases where this prevents try_window_id. */
14533 if (current_buffer->clip_changed
14534 || current_buffer->prevent_redisplay_optimizations_p)
14535 GIVE_UP (3);
14537 /* Window must either use window-based redisplay or be full width. */
14538 if (!FRAME_WINDOW_P (f)
14539 && (!FRAME_LINE_INS_DEL_OK (f)
14540 || !WINDOW_FULL_WIDTH_P (w)))
14541 GIVE_UP (4);
14543 /* Give up if point is not known NOT to appear in W. */
14544 if (PT < CHARPOS (start))
14545 GIVE_UP (5);
14547 /* Another way to prevent redisplay optimizations. */
14548 if (XFASTINT (w->last_modified) == 0)
14549 GIVE_UP (6);
14551 /* Verify that window is not hscrolled. */
14552 if (XFASTINT (w->hscroll) != 0)
14553 GIVE_UP (7);
14555 /* Verify that display wasn't paused. */
14556 if (NILP (w->window_end_valid))
14557 GIVE_UP (8);
14559 /* Can't use this if highlighting a region because a cursor movement
14560 will do more than just set the cursor. */
14561 if (!NILP (Vtransient_mark_mode)
14562 && !NILP (current_buffer->mark_active))
14563 GIVE_UP (9);
14565 /* Likewise if highlighting trailing whitespace. */
14566 if (!NILP (Vshow_trailing_whitespace))
14567 GIVE_UP (11);
14569 /* Likewise if showing a region. */
14570 if (!NILP (w->region_showing))
14571 GIVE_UP (10);
14573 /* Can use this if overlay arrow position and or string have changed. */
14574 if (overlay_arrows_changed_p ())
14575 GIVE_UP (12);
14578 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
14579 only if buffer has really changed. The reason is that the gap is
14580 initially at Z for freshly visited files. The code below would
14581 set end_unchanged to 0 in that case. */
14582 if (MODIFF > SAVE_MODIFF
14583 /* This seems to happen sometimes after saving a buffer. */
14584 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
14586 if (GPT - BEG < BEG_UNCHANGED)
14587 BEG_UNCHANGED = GPT - BEG;
14588 if (Z - GPT < END_UNCHANGED)
14589 END_UNCHANGED = Z - GPT;
14592 /* The position of the first and last character that has been changed. */
14593 first_changed_charpos = BEG + BEG_UNCHANGED;
14594 last_changed_charpos = Z - END_UNCHANGED;
14596 /* If window starts after a line end, and the last change is in
14597 front of that newline, then changes don't affect the display.
14598 This case happens with stealth-fontification. Note that although
14599 the display is unchanged, glyph positions in the matrix have to
14600 be adjusted, of course. */
14601 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
14602 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
14603 && ((last_changed_charpos < CHARPOS (start)
14604 && CHARPOS (start) == BEGV)
14605 || (last_changed_charpos < CHARPOS (start) - 1
14606 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
14608 int Z_old, delta, Z_BYTE_old, delta_bytes;
14609 struct glyph_row *r0;
14611 /* Compute how many chars/bytes have been added to or removed
14612 from the buffer. */
14613 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
14614 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
14615 delta = Z - Z_old;
14616 delta_bytes = Z_BYTE - Z_BYTE_old;
14618 /* Give up if PT is not in the window. Note that it already has
14619 been checked at the start of try_window_id that PT is not in
14620 front of the window start. */
14621 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
14622 GIVE_UP (13);
14624 /* If window start is unchanged, we can reuse the whole matrix
14625 as is, after adjusting glyph positions. No need to compute
14626 the window end again, since its offset from Z hasn't changed. */
14627 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
14628 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
14629 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
14630 /* PT must not be in a partially visible line. */
14631 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
14632 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
14634 /* Adjust positions in the glyph matrix. */
14635 if (delta || delta_bytes)
14637 struct glyph_row *r1
14638 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
14639 increment_matrix_positions (w->current_matrix,
14640 MATRIX_ROW_VPOS (r0, current_matrix),
14641 MATRIX_ROW_VPOS (r1, current_matrix),
14642 delta, delta_bytes);
14645 /* Set the cursor. */
14646 row = row_containing_pos (w, PT, r0, NULL, 0);
14647 if (row)
14648 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
14649 else
14650 abort ();
14651 return 1;
14655 /* Handle the case that changes are all below what is displayed in
14656 the window, and that PT is in the window. This shortcut cannot
14657 be taken if ZV is visible in the window, and text has been added
14658 there that is visible in the window. */
14659 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
14660 /* ZV is not visible in the window, or there are no
14661 changes at ZV, actually. */
14662 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
14663 || first_changed_charpos == last_changed_charpos))
14665 struct glyph_row *r0;
14667 /* Give up if PT is not in the window. Note that it already has
14668 been checked at the start of try_window_id that PT is not in
14669 front of the window start. */
14670 if (PT >= MATRIX_ROW_END_CHARPOS (row))
14671 GIVE_UP (14);
14673 /* If window start is unchanged, we can reuse the whole matrix
14674 as is, without changing glyph positions since no text has
14675 been added/removed in front of the window end. */
14676 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
14677 if (TEXT_POS_EQUAL_P (start, r0->start.pos)
14678 /* PT must not be in a partially visible line. */
14679 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
14680 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
14682 /* We have to compute the window end anew since text
14683 can have been added/removed after it. */
14684 w->window_end_pos
14685 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
14686 w->window_end_bytepos
14687 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
14689 /* Set the cursor. */
14690 row = row_containing_pos (w, PT, r0, NULL, 0);
14691 if (row)
14692 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
14693 else
14694 abort ();
14695 return 2;
14699 /* Give up if window start is in the changed area.
14701 The condition used to read
14703 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
14705 but why that was tested escapes me at the moment. */
14706 if (CHARPOS (start) >= first_changed_charpos
14707 && CHARPOS (start) <= last_changed_charpos)
14708 GIVE_UP (15);
14710 /* Check that window start agrees with the start of the first glyph
14711 row in its current matrix. Check this after we know the window
14712 start is not in changed text, otherwise positions would not be
14713 comparable. */
14714 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
14715 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
14716 GIVE_UP (16);
14718 /* Give up if the window ends in strings. Overlay strings
14719 at the end are difficult to handle, so don't try. */
14720 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
14721 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
14722 GIVE_UP (20);
14724 /* Compute the position at which we have to start displaying new
14725 lines. Some of the lines at the top of the window might be
14726 reusable because they are not displaying changed text. Find the
14727 last row in W's current matrix not affected by changes at the
14728 start of current_buffer. Value is null if changes start in the
14729 first line of window. */
14730 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
14731 if (last_unchanged_at_beg_row)
14733 /* Avoid starting to display in the moddle of a character, a TAB
14734 for instance. This is easier than to set up the iterator
14735 exactly, and it's not a frequent case, so the additional
14736 effort wouldn't really pay off. */
14737 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
14738 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
14739 && last_unchanged_at_beg_row > w->current_matrix->rows)
14740 --last_unchanged_at_beg_row;
14742 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
14743 GIVE_UP (17);
14745 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
14746 GIVE_UP (18);
14747 start_pos = it.current.pos;
14749 /* Start displaying new lines in the desired matrix at the same
14750 vpos we would use in the current matrix, i.e. below
14751 last_unchanged_at_beg_row. */
14752 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
14753 current_matrix);
14754 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
14755 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
14757 xassert (it.hpos == 0 && it.current_x == 0);
14759 else
14761 /* There are no reusable lines at the start of the window.
14762 Start displaying in the first text line. */
14763 start_display (&it, w, start);
14764 it.vpos = it.first_vpos;
14765 start_pos = it.current.pos;
14768 /* Find the first row that is not affected by changes at the end of
14769 the buffer. Value will be null if there is no unchanged row, in
14770 which case we must redisplay to the end of the window. delta
14771 will be set to the value by which buffer positions beginning with
14772 first_unchanged_at_end_row have to be adjusted due to text
14773 changes. */
14774 first_unchanged_at_end_row
14775 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
14776 IF_DEBUG (debug_delta = delta);
14777 IF_DEBUG (debug_delta_bytes = delta_bytes);
14779 /* Set stop_pos to the buffer position up to which we will have to
14780 display new lines. If first_unchanged_at_end_row != NULL, this
14781 is the buffer position of the start of the line displayed in that
14782 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
14783 that we don't stop at a buffer position. */
14784 stop_pos = 0;
14785 if (first_unchanged_at_end_row)
14787 xassert (last_unchanged_at_beg_row == NULL
14788 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
14790 /* If this is a continuation line, move forward to the next one
14791 that isn't. Changes in lines above affect this line.
14792 Caution: this may move first_unchanged_at_end_row to a row
14793 not displaying text. */
14794 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
14795 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
14796 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
14797 < it.last_visible_y))
14798 ++first_unchanged_at_end_row;
14800 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
14801 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
14802 >= it.last_visible_y))
14803 first_unchanged_at_end_row = NULL;
14804 else
14806 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
14807 + delta);
14808 first_unchanged_at_end_vpos
14809 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
14810 xassert (stop_pos >= Z - END_UNCHANGED);
14813 else if (last_unchanged_at_beg_row == NULL)
14814 GIVE_UP (19);
14817 #if GLYPH_DEBUG
14819 /* Either there is no unchanged row at the end, or the one we have
14820 now displays text. This is a necessary condition for the window
14821 end pos calculation at the end of this function. */
14822 xassert (first_unchanged_at_end_row == NULL
14823 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
14825 debug_last_unchanged_at_beg_vpos
14826 = (last_unchanged_at_beg_row
14827 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
14828 : -1);
14829 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
14831 #endif /* GLYPH_DEBUG != 0 */
14834 /* Display new lines. Set last_text_row to the last new line
14835 displayed which has text on it, i.e. might end up as being the
14836 line where the window_end_vpos is. */
14837 w->cursor.vpos = -1;
14838 last_text_row = NULL;
14839 overlay_arrow_seen = 0;
14840 while (it.current_y < it.last_visible_y
14841 && !fonts_changed_p
14842 && (first_unchanged_at_end_row == NULL
14843 || IT_CHARPOS (it) < stop_pos))
14845 if (display_line (&it))
14846 last_text_row = it.glyph_row - 1;
14849 if (fonts_changed_p)
14850 return -1;
14853 /* Compute differences in buffer positions, y-positions etc. for
14854 lines reused at the bottom of the window. Compute what we can
14855 scroll. */
14856 if (first_unchanged_at_end_row
14857 /* No lines reused because we displayed everything up to the
14858 bottom of the window. */
14859 && it.current_y < it.last_visible_y)
14861 dvpos = (it.vpos
14862 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
14863 current_matrix));
14864 dy = it.current_y - first_unchanged_at_end_row->y;
14865 run.current_y = first_unchanged_at_end_row->y;
14866 run.desired_y = run.current_y + dy;
14867 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
14869 else
14871 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
14872 first_unchanged_at_end_row = NULL;
14874 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
14877 /* Find the cursor if not already found. We have to decide whether
14878 PT will appear on this window (it sometimes doesn't, but this is
14879 not a very frequent case.) This decision has to be made before
14880 the current matrix is altered. A value of cursor.vpos < 0 means
14881 that PT is either in one of the lines beginning at
14882 first_unchanged_at_end_row or below the window. Don't care for
14883 lines that might be displayed later at the window end; as
14884 mentioned, this is not a frequent case. */
14885 if (w->cursor.vpos < 0)
14887 /* Cursor in unchanged rows at the top? */
14888 if (PT < CHARPOS (start_pos)
14889 && last_unchanged_at_beg_row)
14891 row = row_containing_pos (w, PT,
14892 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
14893 last_unchanged_at_beg_row + 1, 0);
14894 if (row)
14895 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
14898 /* Start from first_unchanged_at_end_row looking for PT. */
14899 else if (first_unchanged_at_end_row)
14901 row = row_containing_pos (w, PT - delta,
14902 first_unchanged_at_end_row, NULL, 0);
14903 if (row)
14904 set_cursor_from_row (w, row, w->current_matrix, delta,
14905 delta_bytes, dy, dvpos);
14908 /* Give up if cursor was not found. */
14909 if (w->cursor.vpos < 0)
14911 clear_glyph_matrix (w->desired_matrix);
14912 return -1;
14916 /* Don't let the cursor end in the scroll margins. */
14918 int this_scroll_margin, cursor_height;
14920 this_scroll_margin = max (0, scroll_margin);
14921 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
14922 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
14923 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
14925 if ((w->cursor.y < this_scroll_margin
14926 && CHARPOS (start) > BEGV)
14927 /* Old redisplay didn't take scroll margin into account at the bottom,
14928 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
14929 || (w->cursor.y + (make_cursor_line_fully_visible_p
14930 ? cursor_height + this_scroll_margin
14931 : 1)) > it.last_visible_y)
14933 w->cursor.vpos = -1;
14934 clear_glyph_matrix (w->desired_matrix);
14935 return -1;
14939 /* Scroll the display. Do it before changing the current matrix so
14940 that xterm.c doesn't get confused about where the cursor glyph is
14941 found. */
14942 if (dy && run.height)
14944 update_begin (f);
14946 if (FRAME_WINDOW_P (f))
14948 FRAME_RIF (f)->update_window_begin_hook (w);
14949 FRAME_RIF (f)->clear_window_mouse_face (w);
14950 FRAME_RIF (f)->scroll_run_hook (w, &run);
14951 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
14953 else
14955 /* Terminal frame. In this case, dvpos gives the number of
14956 lines to scroll by; dvpos < 0 means scroll up. */
14957 int first_unchanged_at_end_vpos
14958 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
14959 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
14960 int end = (WINDOW_TOP_EDGE_LINE (w)
14961 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
14962 + window_internal_height (w));
14964 /* Perform the operation on the screen. */
14965 if (dvpos > 0)
14967 /* Scroll last_unchanged_at_beg_row to the end of the
14968 window down dvpos lines. */
14969 set_terminal_window (f, end);
14971 /* On dumb terminals delete dvpos lines at the end
14972 before inserting dvpos empty lines. */
14973 if (!FRAME_SCROLL_REGION_OK (f))
14974 ins_del_lines (f, end - dvpos, -dvpos);
14976 /* Insert dvpos empty lines in front of
14977 last_unchanged_at_beg_row. */
14978 ins_del_lines (f, from, dvpos);
14980 else if (dvpos < 0)
14982 /* Scroll up last_unchanged_at_beg_vpos to the end of
14983 the window to last_unchanged_at_beg_vpos - |dvpos|. */
14984 set_terminal_window (f, end);
14986 /* Delete dvpos lines in front of
14987 last_unchanged_at_beg_vpos. ins_del_lines will set
14988 the cursor to the given vpos and emit |dvpos| delete
14989 line sequences. */
14990 ins_del_lines (f, from + dvpos, dvpos);
14992 /* On a dumb terminal insert dvpos empty lines at the
14993 end. */
14994 if (!FRAME_SCROLL_REGION_OK (f))
14995 ins_del_lines (f, end + dvpos, -dvpos);
14998 set_terminal_window (f, 0);
15001 update_end (f);
15004 /* Shift reused rows of the current matrix to the right position.
15005 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
15006 text. */
15007 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
15008 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
15009 if (dvpos < 0)
15011 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
15012 bottom_vpos, dvpos);
15013 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
15014 bottom_vpos, 0);
15016 else if (dvpos > 0)
15018 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
15019 bottom_vpos, dvpos);
15020 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
15021 first_unchanged_at_end_vpos + dvpos, 0);
15024 /* For frame-based redisplay, make sure that current frame and window
15025 matrix are in sync with respect to glyph memory. */
15026 if (!FRAME_WINDOW_P (f))
15027 sync_frame_with_window_matrix_rows (w);
15029 /* Adjust buffer positions in reused rows. */
15030 if (delta || delta_bytes)
15031 increment_matrix_positions (current_matrix,
15032 first_unchanged_at_end_vpos + dvpos,
15033 bottom_vpos, delta, delta_bytes);
15035 /* Adjust Y positions. */
15036 if (dy)
15037 shift_glyph_matrix (w, current_matrix,
15038 first_unchanged_at_end_vpos + dvpos,
15039 bottom_vpos, dy);
15041 if (first_unchanged_at_end_row)
15043 first_unchanged_at_end_row += dvpos;
15044 if (first_unchanged_at_end_row->y >= it.last_visible_y
15045 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
15046 first_unchanged_at_end_row = NULL;
15049 /* If scrolling up, there may be some lines to display at the end of
15050 the window. */
15051 last_text_row_at_end = NULL;
15052 if (dy < 0)
15054 /* Scrolling up can leave for example a partially visible line
15055 at the end of the window to be redisplayed. */
15056 /* Set last_row to the glyph row in the current matrix where the
15057 window end line is found. It has been moved up or down in
15058 the matrix by dvpos. */
15059 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
15060 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
15062 /* If last_row is the window end line, it should display text. */
15063 xassert (last_row->displays_text_p);
15065 /* If window end line was partially visible before, begin
15066 displaying at that line. Otherwise begin displaying with the
15067 line following it. */
15068 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
15070 init_to_row_start (&it, w, last_row);
15071 it.vpos = last_vpos;
15072 it.current_y = last_row->y;
15074 else
15076 init_to_row_end (&it, w, last_row);
15077 it.vpos = 1 + last_vpos;
15078 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
15079 ++last_row;
15082 /* We may start in a continuation line. If so, we have to
15083 get the right continuation_lines_width and current_x. */
15084 it.continuation_lines_width = last_row->continuation_lines_width;
15085 it.hpos = it.current_x = 0;
15087 /* Display the rest of the lines at the window end. */
15088 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
15089 while (it.current_y < it.last_visible_y
15090 && !fonts_changed_p)
15092 /* Is it always sure that the display agrees with lines in
15093 the current matrix? I don't think so, so we mark rows
15094 displayed invalid in the current matrix by setting their
15095 enabled_p flag to zero. */
15096 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
15097 if (display_line (&it))
15098 last_text_row_at_end = it.glyph_row - 1;
15102 /* Update window_end_pos and window_end_vpos. */
15103 if (first_unchanged_at_end_row
15104 && !last_text_row_at_end)
15106 /* Window end line if one of the preserved rows from the current
15107 matrix. Set row to the last row displaying text in current
15108 matrix starting at first_unchanged_at_end_row, after
15109 scrolling. */
15110 xassert (first_unchanged_at_end_row->displays_text_p);
15111 row = find_last_row_displaying_text (w->current_matrix, &it,
15112 first_unchanged_at_end_row);
15113 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
15115 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
15116 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
15117 w->window_end_vpos
15118 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
15119 xassert (w->window_end_bytepos >= 0);
15120 IF_DEBUG (debug_method_add (w, "A"));
15122 else if (last_text_row_at_end)
15124 w->window_end_pos
15125 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
15126 w->window_end_bytepos
15127 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
15128 w->window_end_vpos
15129 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
15130 xassert (w->window_end_bytepos >= 0);
15131 IF_DEBUG (debug_method_add (w, "B"));
15133 else if (last_text_row)
15135 /* We have displayed either to the end of the window or at the
15136 end of the window, i.e. the last row with text is to be found
15137 in the desired matrix. */
15138 w->window_end_pos
15139 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
15140 w->window_end_bytepos
15141 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
15142 w->window_end_vpos
15143 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
15144 xassert (w->window_end_bytepos >= 0);
15146 else if (first_unchanged_at_end_row == NULL
15147 && last_text_row == NULL
15148 && last_text_row_at_end == NULL)
15150 /* Displayed to end of window, but no line containing text was
15151 displayed. Lines were deleted at the end of the window. */
15152 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
15153 int vpos = XFASTINT (w->window_end_vpos);
15154 struct glyph_row *current_row = current_matrix->rows + vpos;
15155 struct glyph_row *desired_row = desired_matrix->rows + vpos;
15157 for (row = NULL;
15158 row == NULL && vpos >= first_vpos;
15159 --vpos, --current_row, --desired_row)
15161 if (desired_row->enabled_p)
15163 if (desired_row->displays_text_p)
15164 row = desired_row;
15166 else if (current_row->displays_text_p)
15167 row = current_row;
15170 xassert (row != NULL);
15171 w->window_end_vpos = make_number (vpos + 1);
15172 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
15173 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
15174 xassert (w->window_end_bytepos >= 0);
15175 IF_DEBUG (debug_method_add (w, "C"));
15177 else
15178 abort ();
15180 #if 0 /* This leads to problems, for instance when the cursor is
15181 at ZV, and the cursor line displays no text. */
15182 /* Disable rows below what's displayed in the window. This makes
15183 debugging easier. */
15184 enable_glyph_matrix_rows (current_matrix,
15185 XFASTINT (w->window_end_vpos) + 1,
15186 bottom_vpos, 0);
15187 #endif
15189 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
15190 debug_end_vpos = XFASTINT (w->window_end_vpos));
15192 /* Record that display has not been completed. */
15193 w->window_end_valid = Qnil;
15194 w->desired_matrix->no_scrolling_p = 1;
15195 return 3;
15197 #undef GIVE_UP
15202 /***********************************************************************
15203 More debugging support
15204 ***********************************************************************/
15206 #if GLYPH_DEBUG
15208 void dump_glyph_row P_ ((struct glyph_row *, int, int));
15209 void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
15210 void dump_glyph P_ ((struct glyph_row *, struct glyph *, int));
15213 /* Dump the contents of glyph matrix MATRIX on stderr.
15215 GLYPHS 0 means don't show glyph contents.
15216 GLYPHS 1 means show glyphs in short form
15217 GLYPHS > 1 means show glyphs in long form. */
15219 void
15220 dump_glyph_matrix (matrix, glyphs)
15221 struct glyph_matrix *matrix;
15222 int glyphs;
15224 int i;
15225 for (i = 0; i < matrix->nrows; ++i)
15226 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
15230 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
15231 the glyph row and area where the glyph comes from. */
15233 void
15234 dump_glyph (row, glyph, area)
15235 struct glyph_row *row;
15236 struct glyph *glyph;
15237 int area;
15239 if (glyph->type == CHAR_GLYPH)
15241 fprintf (stderr,
15242 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
15243 glyph - row->glyphs[TEXT_AREA],
15244 'C',
15245 glyph->charpos,
15246 (BUFFERP (glyph->object)
15247 ? 'B'
15248 : (STRINGP (glyph->object)
15249 ? 'S'
15250 : '-')),
15251 glyph->pixel_width,
15252 glyph->u.ch,
15253 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
15254 ? glyph->u.ch
15255 : '.'),
15256 glyph->face_id,
15257 glyph->left_box_line_p,
15258 glyph->right_box_line_p);
15260 else if (glyph->type == STRETCH_GLYPH)
15262 fprintf (stderr,
15263 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
15264 glyph - row->glyphs[TEXT_AREA],
15265 'S',
15266 glyph->charpos,
15267 (BUFFERP (glyph->object)
15268 ? 'B'
15269 : (STRINGP (glyph->object)
15270 ? 'S'
15271 : '-')),
15272 glyph->pixel_width,
15274 '.',
15275 glyph->face_id,
15276 glyph->left_box_line_p,
15277 glyph->right_box_line_p);
15279 else if (glyph->type == IMAGE_GLYPH)
15281 fprintf (stderr,
15282 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
15283 glyph - row->glyphs[TEXT_AREA],
15284 'I',
15285 glyph->charpos,
15286 (BUFFERP (glyph->object)
15287 ? 'B'
15288 : (STRINGP (glyph->object)
15289 ? 'S'
15290 : '-')),
15291 glyph->pixel_width,
15292 glyph->u.img_id,
15293 '.',
15294 glyph->face_id,
15295 glyph->left_box_line_p,
15296 glyph->right_box_line_p);
15298 else if (glyph->type == COMPOSITE_GLYPH)
15300 fprintf (stderr,
15301 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
15302 glyph - row->glyphs[TEXT_AREA],
15303 '+',
15304 glyph->charpos,
15305 (BUFFERP (glyph->object)
15306 ? 'B'
15307 : (STRINGP (glyph->object)
15308 ? 'S'
15309 : '-')),
15310 glyph->pixel_width,
15311 glyph->u.cmp_id,
15312 '.',
15313 glyph->face_id,
15314 glyph->left_box_line_p,
15315 glyph->right_box_line_p);
15320 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
15321 GLYPHS 0 means don't show glyph contents.
15322 GLYPHS 1 means show glyphs in short form
15323 GLYPHS > 1 means show glyphs in long form. */
15325 void
15326 dump_glyph_row (row, vpos, glyphs)
15327 struct glyph_row *row;
15328 int vpos, glyphs;
15330 if (glyphs != 1)
15332 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
15333 fprintf (stderr, "======================================================================\n");
15335 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d\
15336 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
15337 vpos,
15338 MATRIX_ROW_START_CHARPOS (row),
15339 MATRIX_ROW_END_CHARPOS (row),
15340 row->used[TEXT_AREA],
15341 row->contains_overlapping_glyphs_p,
15342 row->enabled_p,
15343 row->truncated_on_left_p,
15344 row->truncated_on_right_p,
15345 row->continued_p,
15346 MATRIX_ROW_CONTINUATION_LINE_P (row),
15347 row->displays_text_p,
15348 row->ends_at_zv_p,
15349 row->fill_line_p,
15350 row->ends_in_middle_of_char_p,
15351 row->starts_in_middle_of_char_p,
15352 row->mouse_face_p,
15353 row->x,
15354 row->y,
15355 row->pixel_width,
15356 row->height,
15357 row->visible_height,
15358 row->ascent,
15359 row->phys_ascent);
15360 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
15361 row->end.overlay_string_index,
15362 row->continuation_lines_width);
15363 fprintf (stderr, "%9d %5d\n",
15364 CHARPOS (row->start.string_pos),
15365 CHARPOS (row->end.string_pos));
15366 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
15367 row->end.dpvec_index);
15370 if (glyphs > 1)
15372 int area;
15374 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
15376 struct glyph *glyph = row->glyphs[area];
15377 struct glyph *glyph_end = glyph + row->used[area];
15379 /* Glyph for a line end in text. */
15380 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
15381 ++glyph_end;
15383 if (glyph < glyph_end)
15384 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
15386 for (; glyph < glyph_end; ++glyph)
15387 dump_glyph (row, glyph, area);
15390 else if (glyphs == 1)
15392 int area;
15394 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
15396 char *s = (char *) alloca (row->used[area] + 1);
15397 int i;
15399 for (i = 0; i < row->used[area]; ++i)
15401 struct glyph *glyph = row->glyphs[area] + i;
15402 if (glyph->type == CHAR_GLYPH
15403 && glyph->u.ch < 0x80
15404 && glyph->u.ch >= ' ')
15405 s[i] = glyph->u.ch;
15406 else
15407 s[i] = '.';
15410 s[i] = '\0';
15411 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
15417 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
15418 Sdump_glyph_matrix, 0, 1, "p",
15419 doc: /* Dump the current matrix of the selected window to stderr.
15420 Shows contents of glyph row structures. With non-nil
15421 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
15422 glyphs in short form, otherwise show glyphs in long form. */)
15423 (glyphs)
15424 Lisp_Object glyphs;
15426 struct window *w = XWINDOW (selected_window);
15427 struct buffer *buffer = XBUFFER (w->buffer);
15429 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
15430 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
15431 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
15432 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
15433 fprintf (stderr, "=============================================\n");
15434 dump_glyph_matrix (w->current_matrix,
15435 NILP (glyphs) ? 0 : XINT (glyphs));
15436 return Qnil;
15440 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
15441 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
15444 struct frame *f = XFRAME (selected_frame);
15445 dump_glyph_matrix (f->current_matrix, 1);
15446 return Qnil;
15450 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
15451 doc: /* Dump glyph row ROW to stderr.
15452 GLYPH 0 means don't dump glyphs.
15453 GLYPH 1 means dump glyphs in short form.
15454 GLYPH > 1 or omitted means dump glyphs in long form. */)
15455 (row, glyphs)
15456 Lisp_Object row, glyphs;
15458 struct glyph_matrix *matrix;
15459 int vpos;
15461 CHECK_NUMBER (row);
15462 matrix = XWINDOW (selected_window)->current_matrix;
15463 vpos = XINT (row);
15464 if (vpos >= 0 && vpos < matrix->nrows)
15465 dump_glyph_row (MATRIX_ROW (matrix, vpos),
15466 vpos,
15467 INTEGERP (glyphs) ? XINT (glyphs) : 2);
15468 return Qnil;
15472 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
15473 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
15474 GLYPH 0 means don't dump glyphs.
15475 GLYPH 1 means dump glyphs in short form.
15476 GLYPH > 1 or omitted means dump glyphs in long form. */)
15477 (row, glyphs)
15478 Lisp_Object row, glyphs;
15480 struct frame *sf = SELECTED_FRAME ();
15481 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
15482 int vpos;
15484 CHECK_NUMBER (row);
15485 vpos = XINT (row);
15486 if (vpos >= 0 && vpos < m->nrows)
15487 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
15488 INTEGERP (glyphs) ? XINT (glyphs) : 2);
15489 return Qnil;
15493 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
15494 doc: /* Toggle tracing of redisplay.
15495 With ARG, turn tracing on if and only if ARG is positive. */)
15496 (arg)
15497 Lisp_Object arg;
15499 if (NILP (arg))
15500 trace_redisplay_p = !trace_redisplay_p;
15501 else
15503 arg = Fprefix_numeric_value (arg);
15504 trace_redisplay_p = XINT (arg) > 0;
15507 return Qnil;
15511 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
15512 doc: /* Like `format', but print result to stderr.
15513 usage: (trace-to-stderr STRING &rest OBJECTS) */)
15514 (nargs, args)
15515 int nargs;
15516 Lisp_Object *args;
15518 Lisp_Object s = Fformat (nargs, args);
15519 fprintf (stderr, "%s", SDATA (s));
15520 return Qnil;
15523 #endif /* GLYPH_DEBUG */
15527 /***********************************************************************
15528 Building Desired Matrix Rows
15529 ***********************************************************************/
15531 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
15532 Used for non-window-redisplay windows, and for windows w/o left fringe. */
15534 static struct glyph_row *
15535 get_overlay_arrow_glyph_row (w, overlay_arrow_string)
15536 struct window *w;
15537 Lisp_Object overlay_arrow_string;
15539 struct frame *f = XFRAME (WINDOW_FRAME (w));
15540 struct buffer *buffer = XBUFFER (w->buffer);
15541 struct buffer *old = current_buffer;
15542 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
15543 int arrow_len = SCHARS (overlay_arrow_string);
15544 const unsigned char *arrow_end = arrow_string + arrow_len;
15545 const unsigned char *p;
15546 struct it it;
15547 int multibyte_p;
15548 int n_glyphs_before;
15550 set_buffer_temp (buffer);
15551 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
15552 it.glyph_row->used[TEXT_AREA] = 0;
15553 SET_TEXT_POS (it.position, 0, 0);
15555 multibyte_p = !NILP (buffer->enable_multibyte_characters);
15556 p = arrow_string;
15557 while (p < arrow_end)
15559 Lisp_Object face, ilisp;
15561 /* Get the next character. */
15562 if (multibyte_p)
15563 it.c = string_char_and_length (p, arrow_len, &it.len);
15564 else
15565 it.c = *p, it.len = 1;
15566 p += it.len;
15568 /* Get its face. */
15569 ilisp = make_number (p - arrow_string);
15570 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
15571 it.face_id = compute_char_face (f, it.c, face);
15573 /* Compute its width, get its glyphs. */
15574 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
15575 SET_TEXT_POS (it.position, -1, -1);
15576 PRODUCE_GLYPHS (&it);
15578 /* If this character doesn't fit any more in the line, we have
15579 to remove some glyphs. */
15580 if (it.current_x > it.last_visible_x)
15582 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
15583 break;
15587 set_buffer_temp (old);
15588 return it.glyph_row;
15592 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
15593 glyphs are only inserted for terminal frames since we can't really
15594 win with truncation glyphs when partially visible glyphs are
15595 involved. Which glyphs to insert is determined by
15596 produce_special_glyphs. */
15598 static void
15599 insert_left_trunc_glyphs (it)
15600 struct it *it;
15602 struct it truncate_it;
15603 struct glyph *from, *end, *to, *toend;
15605 xassert (!FRAME_WINDOW_P (it->f));
15607 /* Get the truncation glyphs. */
15608 truncate_it = *it;
15609 truncate_it.current_x = 0;
15610 truncate_it.face_id = DEFAULT_FACE_ID;
15611 truncate_it.glyph_row = &scratch_glyph_row;
15612 truncate_it.glyph_row->used[TEXT_AREA] = 0;
15613 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
15614 truncate_it.object = make_number (0);
15615 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
15617 /* Overwrite glyphs from IT with truncation glyphs. */
15618 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
15619 end = from + truncate_it.glyph_row->used[TEXT_AREA];
15620 to = it->glyph_row->glyphs[TEXT_AREA];
15621 toend = to + it->glyph_row->used[TEXT_AREA];
15623 while (from < end)
15624 *to++ = *from++;
15626 /* There may be padding glyphs left over. Overwrite them too. */
15627 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
15629 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
15630 while (from < end)
15631 *to++ = *from++;
15634 if (to > toend)
15635 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
15639 /* Compute the pixel height and width of IT->glyph_row.
15641 Most of the time, ascent and height of a display line will be equal
15642 to the max_ascent and max_height values of the display iterator
15643 structure. This is not the case if
15645 1. We hit ZV without displaying anything. In this case, max_ascent
15646 and max_height will be zero.
15648 2. We have some glyphs that don't contribute to the line height.
15649 (The glyph row flag contributes_to_line_height_p is for future
15650 pixmap extensions).
15652 The first case is easily covered by using default values because in
15653 these cases, the line height does not really matter, except that it
15654 must not be zero. */
15656 static void
15657 compute_line_metrics (it)
15658 struct it *it;
15660 struct glyph_row *row = it->glyph_row;
15661 int area, i;
15663 if (FRAME_WINDOW_P (it->f))
15665 int i, min_y, max_y;
15667 /* The line may consist of one space only, that was added to
15668 place the cursor on it. If so, the row's height hasn't been
15669 computed yet. */
15670 if (row->height == 0)
15672 if (it->max_ascent + it->max_descent == 0)
15673 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
15674 row->ascent = it->max_ascent;
15675 row->height = it->max_ascent + it->max_descent;
15676 row->phys_ascent = it->max_phys_ascent;
15677 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
15678 row->extra_line_spacing = it->max_extra_line_spacing;
15681 /* Compute the width of this line. */
15682 row->pixel_width = row->x;
15683 for (i = 0; i < row->used[TEXT_AREA]; ++i)
15684 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
15686 xassert (row->pixel_width >= 0);
15687 xassert (row->ascent >= 0 && row->height > 0);
15689 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
15690 || MATRIX_ROW_OVERLAPS_PRED_P (row));
15692 /* If first line's physical ascent is larger than its logical
15693 ascent, use the physical ascent, and make the row taller.
15694 This makes accented characters fully visible. */
15695 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
15696 && row->phys_ascent > row->ascent)
15698 row->height += row->phys_ascent - row->ascent;
15699 row->ascent = row->phys_ascent;
15702 /* Compute how much of the line is visible. */
15703 row->visible_height = row->height;
15705 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
15706 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
15708 if (row->y < min_y)
15709 row->visible_height -= min_y - row->y;
15710 if (row->y + row->height > max_y)
15711 row->visible_height -= row->y + row->height - max_y;
15713 else
15715 row->pixel_width = row->used[TEXT_AREA];
15716 if (row->continued_p)
15717 row->pixel_width -= it->continuation_pixel_width;
15718 else if (row->truncated_on_right_p)
15719 row->pixel_width -= it->truncation_pixel_width;
15720 row->ascent = row->phys_ascent = 0;
15721 row->height = row->phys_height = row->visible_height = 1;
15722 row->extra_line_spacing = 0;
15725 /* Compute a hash code for this row. */
15726 row->hash = 0;
15727 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
15728 for (i = 0; i < row->used[area]; ++i)
15729 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
15730 + row->glyphs[area][i].u.val
15731 + row->glyphs[area][i].face_id
15732 + row->glyphs[area][i].padding_p
15733 + (row->glyphs[area][i].type << 2));
15735 it->max_ascent = it->max_descent = 0;
15736 it->max_phys_ascent = it->max_phys_descent = 0;
15740 /* Append one space to the glyph row of iterator IT if doing a
15741 window-based redisplay. The space has the same face as
15742 IT->face_id. Value is non-zero if a space was added.
15744 This function is called to make sure that there is always one glyph
15745 at the end of a glyph row that the cursor can be set on under
15746 window-systems. (If there weren't such a glyph we would not know
15747 how wide and tall a box cursor should be displayed).
15749 At the same time this space let's a nicely handle clearing to the
15750 end of the line if the row ends in italic text. */
15752 static int
15753 append_space_for_newline (it, default_face_p)
15754 struct it *it;
15755 int default_face_p;
15757 if (FRAME_WINDOW_P (it->f))
15759 int n = it->glyph_row->used[TEXT_AREA];
15761 if (it->glyph_row->glyphs[TEXT_AREA] + n
15762 < it->glyph_row->glyphs[1 + TEXT_AREA])
15764 /* Save some values that must not be changed.
15765 Must save IT->c and IT->len because otherwise
15766 ITERATOR_AT_END_P wouldn't work anymore after
15767 append_space_for_newline has been called. */
15768 enum display_element_type saved_what = it->what;
15769 int saved_c = it->c, saved_len = it->len;
15770 int saved_x = it->current_x;
15771 int saved_face_id = it->face_id;
15772 struct text_pos saved_pos;
15773 Lisp_Object saved_object;
15774 struct face *face;
15776 saved_object = it->object;
15777 saved_pos = it->position;
15779 it->what = IT_CHARACTER;
15780 bzero (&it->position, sizeof it->position);
15781 it->object = make_number (0);
15782 it->c = ' ';
15783 it->len = 1;
15785 if (default_face_p)
15786 it->face_id = DEFAULT_FACE_ID;
15787 else if (it->face_before_selective_p)
15788 it->face_id = it->saved_face_id;
15789 face = FACE_FROM_ID (it->f, it->face_id);
15790 it->face_id = FACE_FOR_CHAR (it->f, face, 0);
15792 PRODUCE_GLYPHS (it);
15794 it->override_ascent = -1;
15795 it->constrain_row_ascent_descent_p = 0;
15796 it->current_x = saved_x;
15797 it->object = saved_object;
15798 it->position = saved_pos;
15799 it->what = saved_what;
15800 it->face_id = saved_face_id;
15801 it->len = saved_len;
15802 it->c = saved_c;
15803 return 1;
15807 return 0;
15811 /* Extend the face of the last glyph in the text area of IT->glyph_row
15812 to the end of the display line. Called from display_line.
15813 If the glyph row is empty, add a space glyph to it so that we
15814 know the face to draw. Set the glyph row flag fill_line_p. */
15816 static void
15817 extend_face_to_end_of_line (it)
15818 struct it *it;
15820 struct face *face;
15821 struct frame *f = it->f;
15823 /* If line is already filled, do nothing. */
15824 if (it->current_x >= it->last_visible_x)
15825 return;
15827 /* Face extension extends the background and box of IT->face_id
15828 to the end of the line. If the background equals the background
15829 of the frame, we don't have to do anything. */
15830 if (it->face_before_selective_p)
15831 face = FACE_FROM_ID (it->f, it->saved_face_id);
15832 else
15833 face = FACE_FROM_ID (f, it->face_id);
15835 if (FRAME_WINDOW_P (f)
15836 && it->glyph_row->displays_text_p
15837 && face->box == FACE_NO_BOX
15838 && face->background == FRAME_BACKGROUND_PIXEL (f)
15839 && !face->stipple)
15840 return;
15842 /* Set the glyph row flag indicating that the face of the last glyph
15843 in the text area has to be drawn to the end of the text area. */
15844 it->glyph_row->fill_line_p = 1;
15846 /* If current character of IT is not ASCII, make sure we have the
15847 ASCII face. This will be automatically undone the next time
15848 get_next_display_element returns a multibyte character. Note
15849 that the character will always be single byte in unibyte text. */
15850 if (!SINGLE_BYTE_CHAR_P (it->c))
15852 it->face_id = FACE_FOR_CHAR (f, face, 0);
15855 if (FRAME_WINDOW_P (f))
15857 /* If the row is empty, add a space with the current face of IT,
15858 so that we know which face to draw. */
15859 if (it->glyph_row->used[TEXT_AREA] == 0)
15861 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
15862 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
15863 it->glyph_row->used[TEXT_AREA] = 1;
15866 else
15868 /* Save some values that must not be changed. */
15869 int saved_x = it->current_x;
15870 struct text_pos saved_pos;
15871 Lisp_Object saved_object;
15872 enum display_element_type saved_what = it->what;
15873 int saved_face_id = it->face_id;
15875 saved_object = it->object;
15876 saved_pos = it->position;
15878 it->what = IT_CHARACTER;
15879 bzero (&it->position, sizeof it->position);
15880 it->object = make_number (0);
15881 it->c = ' ';
15882 it->len = 1;
15883 it->face_id = face->id;
15885 PRODUCE_GLYPHS (it);
15887 while (it->current_x <= it->last_visible_x)
15888 PRODUCE_GLYPHS (it);
15890 /* Don't count these blanks really. It would let us insert a left
15891 truncation glyph below and make us set the cursor on them, maybe. */
15892 it->current_x = saved_x;
15893 it->object = saved_object;
15894 it->position = saved_pos;
15895 it->what = saved_what;
15896 it->face_id = saved_face_id;
15901 /* Value is non-zero if text starting at CHARPOS in current_buffer is
15902 trailing whitespace. */
15904 static int
15905 trailing_whitespace_p (charpos)
15906 int charpos;
15908 int bytepos = CHAR_TO_BYTE (charpos);
15909 int c = 0;
15911 while (bytepos < ZV_BYTE
15912 && (c = FETCH_CHAR (bytepos),
15913 c == ' ' || c == '\t'))
15914 ++bytepos;
15916 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
15918 if (bytepos != PT_BYTE)
15919 return 1;
15921 return 0;
15925 /* Highlight trailing whitespace, if any, in ROW. */
15927 void
15928 highlight_trailing_whitespace (f, row)
15929 struct frame *f;
15930 struct glyph_row *row;
15932 int used = row->used[TEXT_AREA];
15934 if (used)
15936 struct glyph *start = row->glyphs[TEXT_AREA];
15937 struct glyph *glyph = start + used - 1;
15939 /* Skip over glyphs inserted to display the cursor at the
15940 end of a line, for extending the face of the last glyph
15941 to the end of the line on terminals, and for truncation
15942 and continuation glyphs. */
15943 while (glyph >= start
15944 && glyph->type == CHAR_GLYPH
15945 && INTEGERP (glyph->object))
15946 --glyph;
15948 /* If last glyph is a space or stretch, and it's trailing
15949 whitespace, set the face of all trailing whitespace glyphs in
15950 IT->glyph_row to `trailing-whitespace'. */
15951 if (glyph >= start
15952 && BUFFERP (glyph->object)
15953 && (glyph->type == STRETCH_GLYPH
15954 || (glyph->type == CHAR_GLYPH
15955 && glyph->u.ch == ' '))
15956 && trailing_whitespace_p (glyph->charpos))
15958 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0, 0);
15959 if (face_id < 0)
15960 return;
15962 while (glyph >= start
15963 && BUFFERP (glyph->object)
15964 && (glyph->type == STRETCH_GLYPH
15965 || (glyph->type == CHAR_GLYPH
15966 && glyph->u.ch == ' ')))
15967 (glyph--)->face_id = face_id;
15973 /* Value is non-zero if glyph row ROW in window W should be
15974 used to hold the cursor. */
15976 static int
15977 cursor_row_p (w, row)
15978 struct window *w;
15979 struct glyph_row *row;
15981 int cursor_row_p = 1;
15983 if (PT == MATRIX_ROW_END_CHARPOS (row))
15985 /* Suppose the row ends on a string.
15986 Unless the row is continued, that means it ends on a newline
15987 in the string. If it's anything other than a display string
15988 (e.g. a before-string from an overlay), we don't want the
15989 cursor there. (This heuristic seems to give the optimal
15990 behavior for the various types of multi-line strings.) */
15991 if (CHARPOS (row->end.string_pos) >= 0)
15993 if (row->continued_p)
15994 cursor_row_p = 1;
15995 else
15997 /* Check for `display' property. */
15998 struct glyph *beg = row->glyphs[TEXT_AREA];
15999 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
16000 struct glyph *glyph;
16002 cursor_row_p = 0;
16003 for (glyph = end; glyph >= beg; --glyph)
16004 if (STRINGP (glyph->object))
16006 Lisp_Object prop
16007 = Fget_char_property (make_number (PT),
16008 Qdisplay, Qnil);
16009 cursor_row_p =
16010 (!NILP (prop)
16011 && display_prop_string_p (prop, glyph->object));
16012 break;
16016 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
16018 /* If the row ends in middle of a real character,
16019 and the line is continued, we want the cursor here.
16020 That's because MATRIX_ROW_END_CHARPOS would equal
16021 PT if PT is before the character. */
16022 if (!row->ends_in_ellipsis_p)
16023 cursor_row_p = row->continued_p;
16024 else
16025 /* If the row ends in an ellipsis, then
16026 MATRIX_ROW_END_CHARPOS will equal point after the invisible text.
16027 We want that position to be displayed after the ellipsis. */
16028 cursor_row_p = 0;
16030 /* If the row ends at ZV, display the cursor at the end of that
16031 row instead of at the start of the row below. */
16032 else if (row->ends_at_zv_p)
16033 cursor_row_p = 1;
16034 else
16035 cursor_row_p = 0;
16038 return cursor_row_p;
16042 /* Construct the glyph row IT->glyph_row in the desired matrix of
16043 IT->w from text at the current position of IT. See dispextern.h
16044 for an overview of struct it. Value is non-zero if
16045 IT->glyph_row displays text, as opposed to a line displaying ZV
16046 only. */
16048 static int
16049 display_line (it)
16050 struct it *it;
16052 struct glyph_row *row = it->glyph_row;
16053 Lisp_Object overlay_arrow_string;
16055 /* We always start displaying at hpos zero even if hscrolled. */
16056 xassert (it->hpos == 0 && it->current_x == 0);
16058 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
16059 >= it->w->desired_matrix->nrows)
16061 it->w->nrows_scale_factor++;
16062 fonts_changed_p = 1;
16063 return 0;
16066 /* Is IT->w showing the region? */
16067 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
16069 /* Clear the result glyph row and enable it. */
16070 prepare_desired_row (row);
16072 row->y = it->current_y;
16073 row->start = it->start;
16074 row->continuation_lines_width = it->continuation_lines_width;
16075 row->displays_text_p = 1;
16076 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
16077 it->starts_in_middle_of_char_p = 0;
16079 /* Arrange the overlays nicely for our purposes. Usually, we call
16080 display_line on only one line at a time, in which case this
16081 can't really hurt too much, or we call it on lines which appear
16082 one after another in the buffer, in which case all calls to
16083 recenter_overlay_lists but the first will be pretty cheap. */
16084 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
16086 /* Move over display elements that are not visible because we are
16087 hscrolled. This may stop at an x-position < IT->first_visible_x
16088 if the first glyph is partially visible or if we hit a line end. */
16089 if (it->current_x < it->first_visible_x)
16091 move_it_in_display_line_to (it, ZV, it->first_visible_x,
16092 MOVE_TO_POS | MOVE_TO_X);
16095 /* Get the initial row height. This is either the height of the
16096 text hscrolled, if there is any, or zero. */
16097 row->ascent = it->max_ascent;
16098 row->height = it->max_ascent + it->max_descent;
16099 row->phys_ascent = it->max_phys_ascent;
16100 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
16101 row->extra_line_spacing = it->max_extra_line_spacing;
16103 /* Loop generating characters. The loop is left with IT on the next
16104 character to display. */
16105 while (1)
16107 int n_glyphs_before, hpos_before, x_before;
16108 int x, i, nglyphs;
16109 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
16111 /* Retrieve the next thing to display. Value is zero if end of
16112 buffer reached. */
16113 if (!get_next_display_element (it))
16115 /* Maybe add a space at the end of this line that is used to
16116 display the cursor there under X. Set the charpos of the
16117 first glyph of blank lines not corresponding to any text
16118 to -1. */
16119 #ifdef HAVE_WINDOW_SYSTEM
16120 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
16121 row->exact_window_width_line_p = 1;
16122 else
16123 #endif /* HAVE_WINDOW_SYSTEM */
16124 if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
16125 || row->used[TEXT_AREA] == 0)
16127 row->glyphs[TEXT_AREA]->charpos = -1;
16128 row->displays_text_p = 0;
16130 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
16131 && (!MINI_WINDOW_P (it->w)
16132 || (minibuf_level && EQ (it->window, minibuf_window))))
16133 row->indicate_empty_line_p = 1;
16136 it->continuation_lines_width = 0;
16137 row->ends_at_zv_p = 1;
16138 break;
16141 /* Now, get the metrics of what we want to display. This also
16142 generates glyphs in `row' (which is IT->glyph_row). */
16143 n_glyphs_before = row->used[TEXT_AREA];
16144 x = it->current_x;
16146 /* Remember the line height so far in case the next element doesn't
16147 fit on the line. */
16148 if (!it->truncate_lines_p)
16150 ascent = it->max_ascent;
16151 descent = it->max_descent;
16152 phys_ascent = it->max_phys_ascent;
16153 phys_descent = it->max_phys_descent;
16156 PRODUCE_GLYPHS (it);
16158 /* If this display element was in marginal areas, continue with
16159 the next one. */
16160 if (it->area != TEXT_AREA)
16162 row->ascent = max (row->ascent, it->max_ascent);
16163 row->height = max (row->height, it->max_ascent + it->max_descent);
16164 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16165 row->phys_height = max (row->phys_height,
16166 it->max_phys_ascent + it->max_phys_descent);
16167 row->extra_line_spacing = max (row->extra_line_spacing,
16168 it->max_extra_line_spacing);
16169 set_iterator_to_next (it, 1);
16170 continue;
16173 /* Does the display element fit on the line? If we truncate
16174 lines, we should draw past the right edge of the window. If
16175 we don't truncate, we want to stop so that we can display the
16176 continuation glyph before the right margin. If lines are
16177 continued, there are two possible strategies for characters
16178 resulting in more than 1 glyph (e.g. tabs): Display as many
16179 glyphs as possible in this line and leave the rest for the
16180 continuation line, or display the whole element in the next
16181 line. Original redisplay did the former, so we do it also. */
16182 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
16183 hpos_before = it->hpos;
16184 x_before = x;
16186 if (/* Not a newline. */
16187 nglyphs > 0
16188 /* Glyphs produced fit entirely in the line. */
16189 && it->current_x < it->last_visible_x)
16191 it->hpos += nglyphs;
16192 row->ascent = max (row->ascent, it->max_ascent);
16193 row->height = max (row->height, it->max_ascent + it->max_descent);
16194 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16195 row->phys_height = max (row->phys_height,
16196 it->max_phys_ascent + it->max_phys_descent);
16197 row->extra_line_spacing = max (row->extra_line_spacing,
16198 it->max_extra_line_spacing);
16199 if (it->current_x - it->pixel_width < it->first_visible_x)
16200 row->x = x - it->first_visible_x;
16202 else
16204 int new_x;
16205 struct glyph *glyph;
16207 for (i = 0; i < nglyphs; ++i, x = new_x)
16209 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
16210 new_x = x + glyph->pixel_width;
16212 if (/* Lines are continued. */
16213 !it->truncate_lines_p
16214 && (/* Glyph doesn't fit on the line. */
16215 new_x > it->last_visible_x
16216 /* Or it fits exactly on a window system frame. */
16217 || (new_x == it->last_visible_x
16218 && FRAME_WINDOW_P (it->f))))
16220 /* End of a continued line. */
16222 if (it->hpos == 0
16223 || (new_x == it->last_visible_x
16224 && FRAME_WINDOW_P (it->f)))
16226 /* Current glyph is the only one on the line or
16227 fits exactly on the line. We must continue
16228 the line because we can't draw the cursor
16229 after the glyph. */
16230 row->continued_p = 1;
16231 it->current_x = new_x;
16232 it->continuation_lines_width += new_x;
16233 ++it->hpos;
16234 if (i == nglyphs - 1)
16236 set_iterator_to_next (it, 1);
16237 #ifdef HAVE_WINDOW_SYSTEM
16238 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
16240 if (!get_next_display_element (it))
16242 row->exact_window_width_line_p = 1;
16243 it->continuation_lines_width = 0;
16244 row->continued_p = 0;
16245 row->ends_at_zv_p = 1;
16247 else if (ITERATOR_AT_END_OF_LINE_P (it))
16249 row->continued_p = 0;
16250 row->exact_window_width_line_p = 1;
16253 #endif /* HAVE_WINDOW_SYSTEM */
16256 else if (CHAR_GLYPH_PADDING_P (*glyph)
16257 && !FRAME_WINDOW_P (it->f))
16259 /* A padding glyph that doesn't fit on this line.
16260 This means the whole character doesn't fit
16261 on the line. */
16262 row->used[TEXT_AREA] = n_glyphs_before;
16264 /* Fill the rest of the row with continuation
16265 glyphs like in 20.x. */
16266 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
16267 < row->glyphs[1 + TEXT_AREA])
16268 produce_special_glyphs (it, IT_CONTINUATION);
16270 row->continued_p = 1;
16271 it->current_x = x_before;
16272 it->continuation_lines_width += x_before;
16274 /* Restore the height to what it was before the
16275 element not fitting on the line. */
16276 it->max_ascent = ascent;
16277 it->max_descent = descent;
16278 it->max_phys_ascent = phys_ascent;
16279 it->max_phys_descent = phys_descent;
16281 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
16283 /* A TAB that extends past the right edge of the
16284 window. This produces a single glyph on
16285 window system frames. We leave the glyph in
16286 this row and let it fill the row, but don't
16287 consume the TAB. */
16288 it->continuation_lines_width += it->last_visible_x;
16289 row->ends_in_middle_of_char_p = 1;
16290 row->continued_p = 1;
16291 glyph->pixel_width = it->last_visible_x - x;
16292 it->starts_in_middle_of_char_p = 1;
16294 else
16296 /* Something other than a TAB that draws past
16297 the right edge of the window. Restore
16298 positions to values before the element. */
16299 row->used[TEXT_AREA] = n_glyphs_before + i;
16301 /* Display continuation glyphs. */
16302 if (!FRAME_WINDOW_P (it->f))
16303 produce_special_glyphs (it, IT_CONTINUATION);
16304 row->continued_p = 1;
16306 it->current_x = x_before;
16307 it->continuation_lines_width += x;
16308 extend_face_to_end_of_line (it);
16310 if (nglyphs > 1 && i > 0)
16312 row->ends_in_middle_of_char_p = 1;
16313 it->starts_in_middle_of_char_p = 1;
16316 /* Restore the height to what it was before the
16317 element not fitting on the line. */
16318 it->max_ascent = ascent;
16319 it->max_descent = descent;
16320 it->max_phys_ascent = phys_ascent;
16321 it->max_phys_descent = phys_descent;
16324 break;
16326 else if (new_x > it->first_visible_x)
16328 /* Increment number of glyphs actually displayed. */
16329 ++it->hpos;
16331 if (x < it->first_visible_x)
16332 /* Glyph is partially visible, i.e. row starts at
16333 negative X position. */
16334 row->x = x - it->first_visible_x;
16336 else
16338 /* Glyph is completely off the left margin of the
16339 window. This should not happen because of the
16340 move_it_in_display_line at the start of this
16341 function, unless the text display area of the
16342 window is empty. */
16343 xassert (it->first_visible_x <= it->last_visible_x);
16347 row->ascent = max (row->ascent, it->max_ascent);
16348 row->height = max (row->height, it->max_ascent + it->max_descent);
16349 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16350 row->phys_height = max (row->phys_height,
16351 it->max_phys_ascent + it->max_phys_descent);
16352 row->extra_line_spacing = max (row->extra_line_spacing,
16353 it->max_extra_line_spacing);
16355 /* End of this display line if row is continued. */
16356 if (row->continued_p || row->ends_at_zv_p)
16357 break;
16360 at_end_of_line:
16361 /* Is this a line end? If yes, we're also done, after making
16362 sure that a non-default face is extended up to the right
16363 margin of the window. */
16364 if (ITERATOR_AT_END_OF_LINE_P (it))
16366 int used_before = row->used[TEXT_AREA];
16368 row->ends_in_newline_from_string_p = STRINGP (it->object);
16370 #ifdef HAVE_WINDOW_SYSTEM
16371 /* Add a space at the end of the line that is used to
16372 display the cursor there. */
16373 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
16374 append_space_for_newline (it, 0);
16375 #endif /* HAVE_WINDOW_SYSTEM */
16377 /* Extend the face to the end of the line. */
16378 extend_face_to_end_of_line (it);
16380 /* Make sure we have the position. */
16381 if (used_before == 0)
16382 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
16384 /* Consume the line end. This skips over invisible lines. */
16385 set_iterator_to_next (it, 1);
16386 it->continuation_lines_width = 0;
16387 break;
16390 /* Proceed with next display element. Note that this skips
16391 over lines invisible because of selective display. */
16392 set_iterator_to_next (it, 1);
16394 /* If we truncate lines, we are done when the last displayed
16395 glyphs reach past the right margin of the window. */
16396 if (it->truncate_lines_p
16397 && (FRAME_WINDOW_P (it->f)
16398 ? (it->current_x >= it->last_visible_x)
16399 : (it->current_x > it->last_visible_x)))
16401 /* Maybe add truncation glyphs. */
16402 if (!FRAME_WINDOW_P (it->f))
16404 int i, n;
16406 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
16407 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
16408 break;
16410 for (n = row->used[TEXT_AREA]; i < n; ++i)
16412 row->used[TEXT_AREA] = i;
16413 produce_special_glyphs (it, IT_TRUNCATION);
16416 #ifdef HAVE_WINDOW_SYSTEM
16417 else
16419 /* Don't truncate if we can overflow newline into fringe. */
16420 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
16422 if (!get_next_display_element (it))
16424 it->continuation_lines_width = 0;
16425 row->ends_at_zv_p = 1;
16426 row->exact_window_width_line_p = 1;
16427 break;
16429 if (ITERATOR_AT_END_OF_LINE_P (it))
16431 row->exact_window_width_line_p = 1;
16432 goto at_end_of_line;
16436 #endif /* HAVE_WINDOW_SYSTEM */
16438 row->truncated_on_right_p = 1;
16439 it->continuation_lines_width = 0;
16440 reseat_at_next_visible_line_start (it, 0);
16441 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
16442 it->hpos = hpos_before;
16443 it->current_x = x_before;
16444 break;
16448 /* If line is not empty and hscrolled, maybe insert truncation glyphs
16449 at the left window margin. */
16450 if (it->first_visible_x
16451 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
16453 if (!FRAME_WINDOW_P (it->f))
16454 insert_left_trunc_glyphs (it);
16455 row->truncated_on_left_p = 1;
16458 /* If the start of this line is the overlay arrow-position, then
16459 mark this glyph row as the one containing the overlay arrow.
16460 This is clearly a mess with variable size fonts. It would be
16461 better to let it be displayed like cursors under X. */
16462 if ((row->displays_text_p || !overlay_arrow_seen)
16463 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
16464 !NILP (overlay_arrow_string)))
16466 /* Overlay arrow in window redisplay is a fringe bitmap. */
16467 if (STRINGP (overlay_arrow_string))
16469 struct glyph_row *arrow_row
16470 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
16471 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
16472 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
16473 struct glyph *p = row->glyphs[TEXT_AREA];
16474 struct glyph *p2, *end;
16476 /* Copy the arrow glyphs. */
16477 while (glyph < arrow_end)
16478 *p++ = *glyph++;
16480 /* Throw away padding glyphs. */
16481 p2 = p;
16482 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
16483 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
16484 ++p2;
16485 if (p2 > p)
16487 while (p2 < end)
16488 *p++ = *p2++;
16489 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
16492 else
16494 xassert (INTEGERP (overlay_arrow_string));
16495 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
16497 overlay_arrow_seen = 1;
16500 /* Compute pixel dimensions of this line. */
16501 compute_line_metrics (it);
16503 /* Remember the position at which this line ends. */
16504 row->end = it->current;
16506 /* Record whether this row ends inside an ellipsis. */
16507 row->ends_in_ellipsis_p
16508 = (it->method == GET_FROM_DISPLAY_VECTOR
16509 && it->ellipsis_p);
16511 /* Save fringe bitmaps in this row. */
16512 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
16513 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
16514 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
16515 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
16517 it->left_user_fringe_bitmap = 0;
16518 it->left_user_fringe_face_id = 0;
16519 it->right_user_fringe_bitmap = 0;
16520 it->right_user_fringe_face_id = 0;
16522 /* Maybe set the cursor. */
16523 if (it->w->cursor.vpos < 0
16524 && PT >= MATRIX_ROW_START_CHARPOS (row)
16525 && PT <= MATRIX_ROW_END_CHARPOS (row)
16526 && cursor_row_p (it->w, row))
16527 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
16529 /* Highlight trailing whitespace. */
16530 if (!NILP (Vshow_trailing_whitespace))
16531 highlight_trailing_whitespace (it->f, it->glyph_row);
16533 /* Prepare for the next line. This line starts horizontally at (X
16534 HPOS) = (0 0). Vertical positions are incremented. As a
16535 convenience for the caller, IT->glyph_row is set to the next
16536 row to be used. */
16537 it->current_x = it->hpos = 0;
16538 it->current_y += row->height;
16539 ++it->vpos;
16540 ++it->glyph_row;
16541 it->start = it->current;
16542 return row->displays_text_p;
16547 /***********************************************************************
16548 Menu Bar
16549 ***********************************************************************/
16551 /* Redisplay the menu bar in the frame for window W.
16553 The menu bar of X frames that don't have X toolkit support is
16554 displayed in a special window W->frame->menu_bar_window.
16556 The menu bar of terminal frames is treated specially as far as
16557 glyph matrices are concerned. Menu bar lines are not part of
16558 windows, so the update is done directly on the frame matrix rows
16559 for the menu bar. */
16561 static void
16562 display_menu_bar (w)
16563 struct window *w;
16565 struct frame *f = XFRAME (WINDOW_FRAME (w));
16566 struct it it;
16567 Lisp_Object items;
16568 int i;
16570 /* Don't do all this for graphical frames. */
16571 #ifdef HAVE_NTGUI
16572 if (FRAME_W32_P (f))
16573 return;
16574 #endif
16575 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
16576 if (FRAME_X_P (f))
16577 return;
16578 #endif
16579 #ifdef MAC_OS
16580 if (FRAME_MAC_P (f))
16581 return;
16582 #endif
16584 #ifdef USE_X_TOOLKIT
16585 xassert (!FRAME_WINDOW_P (f));
16586 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
16587 it.first_visible_x = 0;
16588 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
16589 #else /* not USE_X_TOOLKIT */
16590 if (FRAME_WINDOW_P (f))
16592 /* Menu bar lines are displayed in the desired matrix of the
16593 dummy window menu_bar_window. */
16594 struct window *menu_w;
16595 xassert (WINDOWP (f->menu_bar_window));
16596 menu_w = XWINDOW (f->menu_bar_window);
16597 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
16598 MENU_FACE_ID);
16599 it.first_visible_x = 0;
16600 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
16602 else
16604 /* This is a TTY frame, i.e. character hpos/vpos are used as
16605 pixel x/y. */
16606 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
16607 MENU_FACE_ID);
16608 it.first_visible_x = 0;
16609 it.last_visible_x = FRAME_COLS (f);
16611 #endif /* not USE_X_TOOLKIT */
16613 if (! mode_line_inverse_video)
16614 /* Force the menu-bar to be displayed in the default face. */
16615 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
16617 /* Clear all rows of the menu bar. */
16618 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
16620 struct glyph_row *row = it.glyph_row + i;
16621 clear_glyph_row (row);
16622 row->enabled_p = 1;
16623 row->full_width_p = 1;
16626 /* Display all items of the menu bar. */
16627 items = FRAME_MENU_BAR_ITEMS (it.f);
16628 for (i = 0; i < XVECTOR (items)->size; i += 4)
16630 Lisp_Object string;
16632 /* Stop at nil string. */
16633 string = AREF (items, i + 1);
16634 if (NILP (string))
16635 break;
16637 /* Remember where item was displayed. */
16638 AREF (items, i + 3) = make_number (it.hpos);
16640 /* Display the item, pad with one space. */
16641 if (it.current_x < it.last_visible_x)
16642 display_string (NULL, string, Qnil, 0, 0, &it,
16643 SCHARS (string) + 1, 0, 0, -1);
16646 /* Fill out the line with spaces. */
16647 if (it.current_x < it.last_visible_x)
16648 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
16650 /* Compute the total height of the lines. */
16651 compute_line_metrics (&it);
16656 /***********************************************************************
16657 Mode Line
16658 ***********************************************************************/
16660 /* Redisplay mode lines in the window tree whose root is WINDOW. If
16661 FORCE is non-zero, redisplay mode lines unconditionally.
16662 Otherwise, redisplay only mode lines that are garbaged. Value is
16663 the number of windows whose mode lines were redisplayed. */
16665 static int
16666 redisplay_mode_lines (window, force)
16667 Lisp_Object window;
16668 int force;
16670 int nwindows = 0;
16672 while (!NILP (window))
16674 struct window *w = XWINDOW (window);
16676 if (WINDOWP (w->hchild))
16677 nwindows += redisplay_mode_lines (w->hchild, force);
16678 else if (WINDOWP (w->vchild))
16679 nwindows += redisplay_mode_lines (w->vchild, force);
16680 else if (force
16681 || FRAME_GARBAGED_P (XFRAME (w->frame))
16682 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
16684 struct text_pos lpoint;
16685 struct buffer *old = current_buffer;
16687 /* Set the window's buffer for the mode line display. */
16688 SET_TEXT_POS (lpoint, PT, PT_BYTE);
16689 set_buffer_internal_1 (XBUFFER (w->buffer));
16691 /* Point refers normally to the selected window. For any
16692 other window, set up appropriate value. */
16693 if (!EQ (window, selected_window))
16695 struct text_pos pt;
16697 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
16698 if (CHARPOS (pt) < BEGV)
16699 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
16700 else if (CHARPOS (pt) > (ZV - 1))
16701 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
16702 else
16703 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
16706 /* Display mode lines. */
16707 clear_glyph_matrix (w->desired_matrix);
16708 if (display_mode_lines (w))
16710 ++nwindows;
16711 w->must_be_updated_p = 1;
16714 /* Restore old settings. */
16715 set_buffer_internal_1 (old);
16716 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
16719 window = w->next;
16722 return nwindows;
16726 /* Display the mode and/or top line of window W. Value is the number
16727 of mode lines displayed. */
16729 static int
16730 display_mode_lines (w)
16731 struct window *w;
16733 Lisp_Object old_selected_window, old_selected_frame;
16734 int n = 0;
16736 old_selected_frame = selected_frame;
16737 selected_frame = w->frame;
16738 old_selected_window = selected_window;
16739 XSETWINDOW (selected_window, w);
16741 /* These will be set while the mode line specs are processed. */
16742 line_number_displayed = 0;
16743 w->column_number_displayed = Qnil;
16745 if (WINDOW_WANTS_MODELINE_P (w))
16747 struct window *sel_w = XWINDOW (old_selected_window);
16749 /* Select mode line face based on the real selected window. */
16750 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
16751 current_buffer->mode_line_format);
16752 ++n;
16755 if (WINDOW_WANTS_HEADER_LINE_P (w))
16757 display_mode_line (w, HEADER_LINE_FACE_ID,
16758 current_buffer->header_line_format);
16759 ++n;
16762 selected_frame = old_selected_frame;
16763 selected_window = old_selected_window;
16764 return n;
16768 /* Display mode or top line of window W. FACE_ID specifies which line
16769 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
16770 FORMAT is the mode line format to display. Value is the pixel
16771 height of the mode line displayed. */
16773 static int
16774 display_mode_line (w, face_id, format)
16775 struct window *w;
16776 enum face_id face_id;
16777 Lisp_Object format;
16779 struct it it;
16780 struct face *face;
16781 int count = SPECPDL_INDEX ();
16783 init_iterator (&it, w, -1, -1, NULL, face_id);
16784 /* Don't extend on a previously drawn mode-line.
16785 This may happen if called from pos_visible_p. */
16786 it.glyph_row->enabled_p = 0;
16787 prepare_desired_row (it.glyph_row);
16789 it.glyph_row->mode_line_p = 1;
16791 if (! mode_line_inverse_video)
16792 /* Force the mode-line to be displayed in the default face. */
16793 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
16795 record_unwind_protect (unwind_format_mode_line,
16796 format_mode_line_unwind_data (NULL, 0));
16798 mode_line_target = MODE_LINE_DISPLAY;
16800 /* Temporarily make frame's keyboard the current kboard so that
16801 kboard-local variables in the mode_line_format will get the right
16802 values. */
16803 push_kboard (FRAME_KBOARD (it.f));
16804 record_unwind_save_match_data ();
16805 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
16806 pop_kboard ();
16808 unbind_to (count, Qnil);
16810 /* Fill up with spaces. */
16811 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
16813 compute_line_metrics (&it);
16814 it.glyph_row->full_width_p = 1;
16815 it.glyph_row->continued_p = 0;
16816 it.glyph_row->truncated_on_left_p = 0;
16817 it.glyph_row->truncated_on_right_p = 0;
16819 /* Make a 3D mode-line have a shadow at its right end. */
16820 face = FACE_FROM_ID (it.f, face_id);
16821 extend_face_to_end_of_line (&it);
16822 if (face->box != FACE_NO_BOX)
16824 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
16825 + it.glyph_row->used[TEXT_AREA] - 1);
16826 last->right_box_line_p = 1;
16829 return it.glyph_row->height;
16832 /* Move element ELT in LIST to the front of LIST.
16833 Return the updated list. */
16835 static Lisp_Object
16836 move_elt_to_front (elt, list)
16837 Lisp_Object elt, list;
16839 register Lisp_Object tail, prev;
16840 register Lisp_Object tem;
16842 tail = list;
16843 prev = Qnil;
16844 while (CONSP (tail))
16846 tem = XCAR (tail);
16848 if (EQ (elt, tem))
16850 /* Splice out the link TAIL. */
16851 if (NILP (prev))
16852 list = XCDR (tail);
16853 else
16854 Fsetcdr (prev, XCDR (tail));
16856 /* Now make it the first. */
16857 Fsetcdr (tail, list);
16858 return tail;
16860 else
16861 prev = tail;
16862 tail = XCDR (tail);
16863 QUIT;
16866 /* Not found--return unchanged LIST. */
16867 return list;
16870 /* Contribute ELT to the mode line for window IT->w. How it
16871 translates into text depends on its data type.
16873 IT describes the display environment in which we display, as usual.
16875 DEPTH is the depth in recursion. It is used to prevent
16876 infinite recursion here.
16878 FIELD_WIDTH is the number of characters the display of ELT should
16879 occupy in the mode line, and PRECISION is the maximum number of
16880 characters to display from ELT's representation. See
16881 display_string for details.
16883 Returns the hpos of the end of the text generated by ELT.
16885 PROPS is a property list to add to any string we encounter.
16887 If RISKY is nonzero, remove (disregard) any properties in any string
16888 we encounter, and ignore :eval and :propertize.
16890 The global variable `mode_line_target' determines whether the
16891 output is passed to `store_mode_line_noprop',
16892 `store_mode_line_string', or `display_string'. */
16894 static int
16895 display_mode_element (it, depth, field_width, precision, elt, props, risky)
16896 struct it *it;
16897 int depth;
16898 int field_width, precision;
16899 Lisp_Object elt, props;
16900 int risky;
16902 int n = 0, field, prec;
16903 int literal = 0;
16905 tail_recurse:
16906 if (depth > 100)
16907 elt = build_string ("*too-deep*");
16909 depth++;
16911 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
16913 case Lisp_String:
16915 /* A string: output it and check for %-constructs within it. */
16916 unsigned char c;
16917 int offset = 0;
16919 if (SCHARS (elt) > 0
16920 && (!NILP (props) || risky))
16922 Lisp_Object oprops, aelt;
16923 oprops = Ftext_properties_at (make_number (0), elt);
16925 /* If the starting string's properties are not what
16926 we want, translate the string. Also, if the string
16927 is risky, do that anyway. */
16929 if (NILP (Fequal (props, oprops)) || risky)
16931 /* If the starting string has properties,
16932 merge the specified ones onto the existing ones. */
16933 if (! NILP (oprops) && !risky)
16935 Lisp_Object tem;
16937 oprops = Fcopy_sequence (oprops);
16938 tem = props;
16939 while (CONSP (tem))
16941 oprops = Fplist_put (oprops, XCAR (tem),
16942 XCAR (XCDR (tem)));
16943 tem = XCDR (XCDR (tem));
16945 props = oprops;
16948 aelt = Fassoc (elt, mode_line_proptrans_alist);
16949 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
16951 /* AELT is what we want. Move it to the front
16952 without consing. */
16953 elt = XCAR (aelt);
16954 mode_line_proptrans_alist
16955 = move_elt_to_front (aelt, mode_line_proptrans_alist);
16957 else
16959 Lisp_Object tem;
16961 /* If AELT has the wrong props, it is useless.
16962 so get rid of it. */
16963 if (! NILP (aelt))
16964 mode_line_proptrans_alist
16965 = Fdelq (aelt, mode_line_proptrans_alist);
16967 elt = Fcopy_sequence (elt);
16968 Fset_text_properties (make_number (0), Flength (elt),
16969 props, elt);
16970 /* Add this item to mode_line_proptrans_alist. */
16971 mode_line_proptrans_alist
16972 = Fcons (Fcons (elt, props),
16973 mode_line_proptrans_alist);
16974 /* Truncate mode_line_proptrans_alist
16975 to at most 50 elements. */
16976 tem = Fnthcdr (make_number (50),
16977 mode_line_proptrans_alist);
16978 if (! NILP (tem))
16979 XSETCDR (tem, Qnil);
16984 offset = 0;
16986 if (literal)
16988 prec = precision - n;
16989 switch (mode_line_target)
16991 case MODE_LINE_NOPROP:
16992 case MODE_LINE_TITLE:
16993 n += store_mode_line_noprop (SDATA (elt), -1, prec);
16994 break;
16995 case MODE_LINE_STRING:
16996 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
16997 break;
16998 case MODE_LINE_DISPLAY:
16999 n += display_string (NULL, elt, Qnil, 0, 0, it,
17000 0, prec, 0, STRING_MULTIBYTE (elt));
17001 break;
17004 break;
17007 /* Handle the non-literal case. */
17009 while ((precision <= 0 || n < precision)
17010 && SREF (elt, offset) != 0
17011 && (mode_line_target != MODE_LINE_DISPLAY
17012 || it->current_x < it->last_visible_x))
17014 int last_offset = offset;
17016 /* Advance to end of string or next format specifier. */
17017 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
17020 if (offset - 1 != last_offset)
17022 int nchars, nbytes;
17024 /* Output to end of string or up to '%'. Field width
17025 is length of string. Don't output more than
17026 PRECISION allows us. */
17027 offset--;
17029 prec = c_string_width (SDATA (elt) + last_offset,
17030 offset - last_offset, precision - n,
17031 &nchars, &nbytes);
17033 switch (mode_line_target)
17035 case MODE_LINE_NOPROP:
17036 case MODE_LINE_TITLE:
17037 n += store_mode_line_noprop (SDATA (elt) + last_offset, 0, prec);
17038 break;
17039 case MODE_LINE_STRING:
17041 int bytepos = last_offset;
17042 int charpos = string_byte_to_char (elt, bytepos);
17043 int endpos = (precision <= 0
17044 ? string_byte_to_char (elt, offset)
17045 : charpos + nchars);
17047 n += store_mode_line_string (NULL,
17048 Fsubstring (elt, make_number (charpos),
17049 make_number (endpos)),
17050 0, 0, 0, Qnil);
17052 break;
17053 case MODE_LINE_DISPLAY:
17055 int bytepos = last_offset;
17056 int charpos = string_byte_to_char (elt, bytepos);
17058 if (precision <= 0)
17059 nchars = string_byte_to_char (elt, offset) - charpos;
17060 n += display_string (NULL, elt, Qnil, 0, charpos,
17061 it, 0, nchars, 0,
17062 STRING_MULTIBYTE (elt));
17064 break;
17067 else /* c == '%' */
17069 int percent_position = offset;
17071 /* Get the specified minimum width. Zero means
17072 don't pad. */
17073 field = 0;
17074 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
17075 field = field * 10 + c - '0';
17077 /* Don't pad beyond the total padding allowed. */
17078 if (field_width - n > 0 && field > field_width - n)
17079 field = field_width - n;
17081 /* Note that either PRECISION <= 0 or N < PRECISION. */
17082 prec = precision - n;
17084 if (c == 'M')
17085 n += display_mode_element (it, depth, field, prec,
17086 Vglobal_mode_string, props,
17087 risky);
17088 else if (c != 0)
17090 int multibyte;
17091 int bytepos, charpos;
17092 unsigned char *spec;
17094 bytepos = percent_position;
17095 charpos = (STRING_MULTIBYTE (elt)
17096 ? string_byte_to_char (elt, bytepos)
17097 : bytepos);
17099 spec
17100 = decode_mode_spec (it->w, c, field, prec, &multibyte);
17102 switch (mode_line_target)
17104 case MODE_LINE_NOPROP:
17105 case MODE_LINE_TITLE:
17106 n += store_mode_line_noprop (spec, field, prec);
17107 break;
17108 case MODE_LINE_STRING:
17110 int len = strlen (spec);
17111 Lisp_Object tem = make_string (spec, len);
17112 props = Ftext_properties_at (make_number (charpos), elt);
17113 /* Should only keep face property in props */
17114 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
17116 break;
17117 case MODE_LINE_DISPLAY:
17119 int nglyphs_before, nwritten;
17121 nglyphs_before = it->glyph_row->used[TEXT_AREA];
17122 nwritten = display_string (spec, Qnil, elt,
17123 charpos, 0, it,
17124 field, prec, 0,
17125 multibyte);
17127 /* Assign to the glyphs written above the
17128 string where the `%x' came from, position
17129 of the `%'. */
17130 if (nwritten > 0)
17132 struct glyph *glyph
17133 = (it->glyph_row->glyphs[TEXT_AREA]
17134 + nglyphs_before);
17135 int i;
17137 for (i = 0; i < nwritten; ++i)
17139 glyph[i].object = elt;
17140 glyph[i].charpos = charpos;
17143 n += nwritten;
17146 break;
17149 else /* c == 0 */
17150 break;
17154 break;
17156 case Lisp_Symbol:
17157 /* A symbol: process the value of the symbol recursively
17158 as if it appeared here directly. Avoid error if symbol void.
17159 Special case: if value of symbol is a string, output the string
17160 literally. */
17162 register Lisp_Object tem;
17164 /* If the variable is not marked as risky to set
17165 then its contents are risky to use. */
17166 if (NILP (Fget (elt, Qrisky_local_variable)))
17167 risky = 1;
17169 tem = Fboundp (elt);
17170 if (!NILP (tem))
17172 tem = Fsymbol_value (elt);
17173 /* If value is a string, output that string literally:
17174 don't check for % within it. */
17175 if (STRINGP (tem))
17176 literal = 1;
17178 if (!EQ (tem, elt))
17180 /* Give up right away for nil or t. */
17181 elt = tem;
17182 goto tail_recurse;
17186 break;
17188 case Lisp_Cons:
17190 register Lisp_Object car, tem;
17192 /* A cons cell: five distinct cases.
17193 If first element is :eval or :propertize, do something special.
17194 If first element is a string or a cons, process all the elements
17195 and effectively concatenate them.
17196 If first element is a negative number, truncate displaying cdr to
17197 at most that many characters. If positive, pad (with spaces)
17198 to at least that many characters.
17199 If first element is a symbol, process the cadr or caddr recursively
17200 according to whether the symbol's value is non-nil or nil. */
17201 car = XCAR (elt);
17202 if (EQ (car, QCeval))
17204 /* An element of the form (:eval FORM) means evaluate FORM
17205 and use the result as mode line elements. */
17207 if (risky)
17208 break;
17210 if (CONSP (XCDR (elt)))
17212 Lisp_Object spec;
17213 spec = safe_eval (XCAR (XCDR (elt)));
17214 n += display_mode_element (it, depth, field_width - n,
17215 precision - n, spec, props,
17216 risky);
17219 else if (EQ (car, QCpropertize))
17221 /* An element of the form (:propertize ELT PROPS...)
17222 means display ELT but applying properties PROPS. */
17224 if (risky)
17225 break;
17227 if (CONSP (XCDR (elt)))
17228 n += display_mode_element (it, depth, field_width - n,
17229 precision - n, XCAR (XCDR (elt)),
17230 XCDR (XCDR (elt)), risky);
17232 else if (SYMBOLP (car))
17234 tem = Fboundp (car);
17235 elt = XCDR (elt);
17236 if (!CONSP (elt))
17237 goto invalid;
17238 /* elt is now the cdr, and we know it is a cons cell.
17239 Use its car if CAR has a non-nil value. */
17240 if (!NILP (tem))
17242 tem = Fsymbol_value (car);
17243 if (!NILP (tem))
17245 elt = XCAR (elt);
17246 goto tail_recurse;
17249 /* Symbol's value is nil (or symbol is unbound)
17250 Get the cddr of the original list
17251 and if possible find the caddr and use that. */
17252 elt = XCDR (elt);
17253 if (NILP (elt))
17254 break;
17255 else if (!CONSP (elt))
17256 goto invalid;
17257 elt = XCAR (elt);
17258 goto tail_recurse;
17260 else if (INTEGERP (car))
17262 register int lim = XINT (car);
17263 elt = XCDR (elt);
17264 if (lim < 0)
17266 /* Negative int means reduce maximum width. */
17267 if (precision <= 0)
17268 precision = -lim;
17269 else
17270 precision = min (precision, -lim);
17272 else if (lim > 0)
17274 /* Padding specified. Don't let it be more than
17275 current maximum. */
17276 if (precision > 0)
17277 lim = min (precision, lim);
17279 /* If that's more padding than already wanted, queue it.
17280 But don't reduce padding already specified even if
17281 that is beyond the current truncation point. */
17282 field_width = max (lim, field_width);
17284 goto tail_recurse;
17286 else if (STRINGP (car) || CONSP (car))
17288 register int limit = 50;
17289 /* Limit is to protect against circular lists. */
17290 while (CONSP (elt)
17291 && --limit > 0
17292 && (precision <= 0 || n < precision))
17294 n += display_mode_element (it, depth,
17295 /* Do padding only after the last
17296 element in the list. */
17297 (! CONSP (XCDR (elt))
17298 ? field_width - n
17299 : 0),
17300 precision - n, XCAR (elt),
17301 props, risky);
17302 elt = XCDR (elt);
17306 break;
17308 default:
17309 invalid:
17310 elt = build_string ("*invalid*");
17311 goto tail_recurse;
17314 /* Pad to FIELD_WIDTH. */
17315 if (field_width > 0 && n < field_width)
17317 switch (mode_line_target)
17319 case MODE_LINE_NOPROP:
17320 case MODE_LINE_TITLE:
17321 n += store_mode_line_noprop ("", field_width - n, 0);
17322 break;
17323 case MODE_LINE_STRING:
17324 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
17325 break;
17326 case MODE_LINE_DISPLAY:
17327 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
17328 0, 0, 0);
17329 break;
17333 return n;
17336 /* Store a mode-line string element in mode_line_string_list.
17338 If STRING is non-null, display that C string. Otherwise, the Lisp
17339 string LISP_STRING is displayed.
17341 FIELD_WIDTH is the minimum number of output glyphs to produce.
17342 If STRING has fewer characters than FIELD_WIDTH, pad to the right
17343 with spaces. FIELD_WIDTH <= 0 means don't pad.
17345 PRECISION is the maximum number of characters to output from
17346 STRING. PRECISION <= 0 means don't truncate the string.
17348 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
17349 properties to the string.
17351 PROPS are the properties to add to the string.
17352 The mode_line_string_face face property is always added to the string.
17355 static int
17356 store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
17357 char *string;
17358 Lisp_Object lisp_string;
17359 int copy_string;
17360 int field_width;
17361 int precision;
17362 Lisp_Object props;
17364 int len;
17365 int n = 0;
17367 if (string != NULL)
17369 len = strlen (string);
17370 if (precision > 0 && len > precision)
17371 len = precision;
17372 lisp_string = make_string (string, len);
17373 if (NILP (props))
17374 props = mode_line_string_face_prop;
17375 else if (!NILP (mode_line_string_face))
17377 Lisp_Object face = Fplist_get (props, Qface);
17378 props = Fcopy_sequence (props);
17379 if (NILP (face))
17380 face = mode_line_string_face;
17381 else
17382 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
17383 props = Fplist_put (props, Qface, face);
17385 Fadd_text_properties (make_number (0), make_number (len),
17386 props, lisp_string);
17388 else
17390 len = XFASTINT (Flength (lisp_string));
17391 if (precision > 0 && len > precision)
17393 len = precision;
17394 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
17395 precision = -1;
17397 if (!NILP (mode_line_string_face))
17399 Lisp_Object face;
17400 if (NILP (props))
17401 props = Ftext_properties_at (make_number (0), lisp_string);
17402 face = Fplist_get (props, Qface);
17403 if (NILP (face))
17404 face = mode_line_string_face;
17405 else
17406 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
17407 props = Fcons (Qface, Fcons (face, Qnil));
17408 if (copy_string)
17409 lisp_string = Fcopy_sequence (lisp_string);
17411 if (!NILP (props))
17412 Fadd_text_properties (make_number (0), make_number (len),
17413 props, lisp_string);
17416 if (len > 0)
17418 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
17419 n += len;
17422 if (field_width > len)
17424 field_width -= len;
17425 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
17426 if (!NILP (props))
17427 Fadd_text_properties (make_number (0), make_number (field_width),
17428 props, lisp_string);
17429 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
17430 n += field_width;
17433 return n;
17437 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
17438 1, 4, 0,
17439 doc: /* Format a string out of a mode line format specification.
17440 First arg FORMAT specifies the mode line format (see `mode-line-format'
17441 for details) to use.
17443 Optional second arg FACE specifies the face property to put
17444 on all characters for which no face is specified.
17445 The value t means whatever face the window's mode line currently uses
17446 \(either `mode-line' or `mode-line-inactive', depending).
17447 A value of nil means the default is no face property.
17448 If FACE is an integer, the value string has no text properties.
17450 Optional third and fourth args WINDOW and BUFFER specify the window
17451 and buffer to use as the context for the formatting (defaults
17452 are the selected window and the window's buffer). */)
17453 (format, face, window, buffer)
17454 Lisp_Object format, face, window, buffer;
17456 struct it it;
17457 int len;
17458 struct window *w;
17459 struct buffer *old_buffer = NULL;
17460 int face_id = -1;
17461 int no_props = INTEGERP (face);
17462 int count = SPECPDL_INDEX ();
17463 Lisp_Object str;
17464 int string_start = 0;
17466 if (NILP (window))
17467 window = selected_window;
17468 CHECK_WINDOW (window);
17469 w = XWINDOW (window);
17471 if (NILP (buffer))
17472 buffer = w->buffer;
17473 CHECK_BUFFER (buffer);
17475 /* Make formatting the modeline a non-op when noninteractive, otherwise
17476 there will be problems later caused by a partially initialized frame. */
17477 if (NILP (format) || noninteractive)
17478 return empty_unibyte_string;
17480 if (no_props)
17481 face = Qnil;
17483 if (!NILP (face))
17485 if (EQ (face, Qt))
17486 face = (EQ (window, selected_window) ? Qmode_line : Qmode_line_inactive);
17487 face_id = lookup_named_face (XFRAME (WINDOW_FRAME (w)), face, 0, 0);
17490 if (face_id < 0)
17491 face_id = DEFAULT_FACE_ID;
17493 if (XBUFFER (buffer) != current_buffer)
17494 old_buffer = current_buffer;
17496 /* Save things including mode_line_proptrans_alist,
17497 and set that to nil so that we don't alter the outer value. */
17498 record_unwind_protect (unwind_format_mode_line,
17499 format_mode_line_unwind_data (old_buffer, 1));
17500 mode_line_proptrans_alist = Qnil;
17502 if (old_buffer)
17503 set_buffer_internal_1 (XBUFFER (buffer));
17505 init_iterator (&it, w, -1, -1, NULL, face_id);
17507 if (no_props)
17509 mode_line_target = MODE_LINE_NOPROP;
17510 mode_line_string_face_prop = Qnil;
17511 mode_line_string_list = Qnil;
17512 string_start = MODE_LINE_NOPROP_LEN (0);
17514 else
17516 mode_line_target = MODE_LINE_STRING;
17517 mode_line_string_list = Qnil;
17518 mode_line_string_face = face;
17519 mode_line_string_face_prop
17520 = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil)));
17523 push_kboard (FRAME_KBOARD (it.f));
17524 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
17525 pop_kboard ();
17527 if (no_props)
17529 len = MODE_LINE_NOPROP_LEN (string_start);
17530 str = make_string (mode_line_noprop_buf + string_start, len);
17532 else
17534 mode_line_string_list = Fnreverse (mode_line_string_list);
17535 str = Fmapconcat (intern ("identity"), mode_line_string_list,
17536 empty_unibyte_string);
17539 unbind_to (count, Qnil);
17540 return str;
17543 /* Write a null-terminated, right justified decimal representation of
17544 the positive integer D to BUF using a minimal field width WIDTH. */
17546 static void
17547 pint2str (buf, width, d)
17548 register char *buf;
17549 register int width;
17550 register int d;
17552 register char *p = buf;
17554 if (d <= 0)
17555 *p++ = '0';
17556 else
17558 while (d > 0)
17560 *p++ = d % 10 + '0';
17561 d /= 10;
17565 for (width -= (int) (p - buf); width > 0; --width)
17566 *p++ = ' ';
17567 *p-- = '\0';
17568 while (p > buf)
17570 d = *buf;
17571 *buf++ = *p;
17572 *p-- = d;
17576 /* Write a null-terminated, right justified decimal and "human
17577 readable" representation of the nonnegative integer D to BUF using
17578 a minimal field width WIDTH. D should be smaller than 999.5e24. */
17580 static const char power_letter[] =
17582 0, /* not used */
17583 'k', /* kilo */
17584 'M', /* mega */
17585 'G', /* giga */
17586 'T', /* tera */
17587 'P', /* peta */
17588 'E', /* exa */
17589 'Z', /* zetta */
17590 'Y' /* yotta */
17593 static void
17594 pint2hrstr (buf, width, d)
17595 char *buf;
17596 int width;
17597 int d;
17599 /* We aim to represent the nonnegative integer D as
17600 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
17601 int quotient = d;
17602 int remainder = 0;
17603 /* -1 means: do not use TENTHS. */
17604 int tenths = -1;
17605 int exponent = 0;
17607 /* Length of QUOTIENT.TENTHS as a string. */
17608 int length;
17610 char * psuffix;
17611 char * p;
17613 if (1000 <= quotient)
17615 /* Scale to the appropriate EXPONENT. */
17618 remainder = quotient % 1000;
17619 quotient /= 1000;
17620 exponent++;
17622 while (1000 <= quotient);
17624 /* Round to nearest and decide whether to use TENTHS or not. */
17625 if (quotient <= 9)
17627 tenths = remainder / 100;
17628 if (50 <= remainder % 100)
17630 if (tenths < 9)
17631 tenths++;
17632 else
17634 quotient++;
17635 if (quotient == 10)
17636 tenths = -1;
17637 else
17638 tenths = 0;
17642 else
17643 if (500 <= remainder)
17645 if (quotient < 999)
17646 quotient++;
17647 else
17649 quotient = 1;
17650 exponent++;
17651 tenths = 0;
17656 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
17657 if (tenths == -1 && quotient <= 99)
17658 if (quotient <= 9)
17659 length = 1;
17660 else
17661 length = 2;
17662 else
17663 length = 3;
17664 p = psuffix = buf + max (width, length);
17666 /* Print EXPONENT. */
17667 if (exponent)
17668 *psuffix++ = power_letter[exponent];
17669 *psuffix = '\0';
17671 /* Print TENTHS. */
17672 if (tenths >= 0)
17674 *--p = '0' + tenths;
17675 *--p = '.';
17678 /* Print QUOTIENT. */
17681 int digit = quotient % 10;
17682 *--p = '0' + digit;
17684 while ((quotient /= 10) != 0);
17686 /* Print leading spaces. */
17687 while (buf < p)
17688 *--p = ' ';
17691 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
17692 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
17693 type of CODING_SYSTEM. Return updated pointer into BUF. */
17695 static unsigned char invalid_eol_type[] = "(*invalid*)";
17697 static char *
17698 decode_mode_spec_coding (coding_system, buf, eol_flag)
17699 Lisp_Object coding_system;
17700 register char *buf;
17701 int eol_flag;
17703 Lisp_Object val;
17704 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
17705 const unsigned char *eol_str;
17706 int eol_str_len;
17707 /* The EOL conversion we are using. */
17708 Lisp_Object eoltype;
17710 val = Fget (coding_system, Qcoding_system);
17711 eoltype = Qnil;
17713 if (!VECTORP (val)) /* Not yet decided. */
17715 if (multibyte)
17716 *buf++ = '-';
17717 if (eol_flag)
17718 eoltype = eol_mnemonic_undecided;
17719 /* Don't mention EOL conversion if it isn't decided. */
17721 else
17723 Lisp_Object eolvalue;
17725 eolvalue = Fget (coding_system, Qeol_type);
17727 if (multibyte)
17728 *buf++ = XFASTINT (AREF (val, 1));
17730 if (eol_flag)
17732 /* The EOL conversion that is normal on this system. */
17734 if (NILP (eolvalue)) /* Not yet decided. */
17735 eoltype = eol_mnemonic_undecided;
17736 else if (VECTORP (eolvalue)) /* Not yet decided. */
17737 eoltype = eol_mnemonic_undecided;
17738 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
17739 eoltype = (XFASTINT (eolvalue) == 0
17740 ? eol_mnemonic_unix
17741 : (XFASTINT (eolvalue) == 1
17742 ? eol_mnemonic_dos : eol_mnemonic_mac));
17746 if (eol_flag)
17748 /* Mention the EOL conversion if it is not the usual one. */
17749 if (STRINGP (eoltype))
17751 eol_str = SDATA (eoltype);
17752 eol_str_len = SBYTES (eoltype);
17754 else if (INTEGERP (eoltype)
17755 && CHAR_VALID_P (XINT (eoltype), 0))
17757 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
17758 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
17759 eol_str = tmp;
17761 else
17763 eol_str = invalid_eol_type;
17764 eol_str_len = sizeof (invalid_eol_type) - 1;
17766 bcopy (eol_str, buf, eol_str_len);
17767 buf += eol_str_len;
17770 return buf;
17773 /* Return a string for the output of a mode line %-spec for window W,
17774 generated by character C. PRECISION >= 0 means don't return a
17775 string longer than that value. FIELD_WIDTH > 0 means pad the
17776 string returned with spaces to that value. Return 1 in *MULTIBYTE
17777 if the result is multibyte text.
17779 Note we operate on the current buffer for most purposes,
17780 the exception being w->base_line_pos. */
17782 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
17784 static char *
17785 decode_mode_spec (w, c, field_width, precision, multibyte)
17786 struct window *w;
17787 register int c;
17788 int field_width, precision;
17789 int *multibyte;
17791 Lisp_Object obj;
17792 struct frame *f = XFRAME (WINDOW_FRAME (w));
17793 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
17794 struct buffer *b = current_buffer;
17796 obj = Qnil;
17797 *multibyte = 0;
17799 switch (c)
17801 case '*':
17802 if (!NILP (b->read_only))
17803 return "%";
17804 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
17805 return "*";
17806 return "-";
17808 case '+':
17809 /* This differs from %* only for a modified read-only buffer. */
17810 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
17811 return "*";
17812 if (!NILP (b->read_only))
17813 return "%";
17814 return "-";
17816 case '&':
17817 /* This differs from %* in ignoring read-only-ness. */
17818 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
17819 return "*";
17820 return "-";
17822 case '%':
17823 return "%";
17825 case '[':
17827 int i;
17828 char *p;
17830 if (command_loop_level > 5)
17831 return "[[[... ";
17832 p = decode_mode_spec_buf;
17833 for (i = 0; i < command_loop_level; i++)
17834 *p++ = '[';
17835 *p = 0;
17836 return decode_mode_spec_buf;
17839 case ']':
17841 int i;
17842 char *p;
17844 if (command_loop_level > 5)
17845 return " ...]]]";
17846 p = decode_mode_spec_buf;
17847 for (i = 0; i < command_loop_level; i++)
17848 *p++ = ']';
17849 *p = 0;
17850 return decode_mode_spec_buf;
17853 case '-':
17855 register int i;
17857 /* Let lots_of_dashes be a string of infinite length. */
17858 if (mode_line_target == MODE_LINE_NOPROP ||
17859 mode_line_target == MODE_LINE_STRING)
17860 return "--";
17861 if (field_width <= 0
17862 || field_width > sizeof (lots_of_dashes))
17864 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
17865 decode_mode_spec_buf[i] = '-';
17866 decode_mode_spec_buf[i] = '\0';
17867 return decode_mode_spec_buf;
17869 else
17870 return lots_of_dashes;
17873 case 'b':
17874 obj = b->name;
17875 break;
17877 case 'c':
17878 /* %c and %l are ignored in `frame-title-format'.
17879 (In redisplay_internal, the frame title is drawn _before_ the
17880 windows are updated, so the stuff which depends on actual
17881 window contents (such as %l) may fail to render properly, or
17882 even crash emacs.) */
17883 if (mode_line_target == MODE_LINE_TITLE)
17884 return "";
17885 else
17887 int col = (int) current_column (); /* iftc */
17888 w->column_number_displayed = make_number (col);
17889 pint2str (decode_mode_spec_buf, field_width, col);
17890 return decode_mode_spec_buf;
17893 case 'e':
17894 #ifndef SYSTEM_MALLOC
17896 if (NILP (Vmemory_full))
17897 return "";
17898 else
17899 return "!MEM FULL! ";
17901 #else
17902 return "";
17903 #endif
17905 case 'F':
17906 /* %F displays the frame name. */
17907 if (!NILP (f->title))
17908 return (char *) SDATA (f->title);
17909 if (f->explicit_name || ! FRAME_WINDOW_P (f))
17910 return (char *) SDATA (f->name);
17911 return "Emacs";
17913 case 'f':
17914 obj = b->filename;
17915 break;
17917 case 'i':
17919 int size = ZV - BEGV;
17920 pint2str (decode_mode_spec_buf, field_width, size);
17921 return decode_mode_spec_buf;
17924 case 'I':
17926 int size = ZV - BEGV;
17927 pint2hrstr (decode_mode_spec_buf, field_width, size);
17928 return decode_mode_spec_buf;
17931 case 'l':
17933 int startpos, startpos_byte, line, linepos, linepos_byte;
17934 int topline, nlines, junk, height;
17936 /* %c and %l are ignored in `frame-title-format'. */
17937 if (mode_line_target == MODE_LINE_TITLE)
17938 return "";
17940 startpos = XMARKER (w->start)->charpos;
17941 startpos_byte = marker_byte_position (w->start);
17942 height = WINDOW_TOTAL_LINES (w);
17944 /* If we decided that this buffer isn't suitable for line numbers,
17945 don't forget that too fast. */
17946 if (EQ (w->base_line_pos, w->buffer))
17947 goto no_value;
17948 /* But do forget it, if the window shows a different buffer now. */
17949 else if (BUFFERP (w->base_line_pos))
17950 w->base_line_pos = Qnil;
17952 /* If the buffer is very big, don't waste time. */
17953 if (INTEGERP (Vline_number_display_limit)
17954 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
17956 w->base_line_pos = Qnil;
17957 w->base_line_number = Qnil;
17958 goto no_value;
17961 if (!NILP (w->base_line_number)
17962 && !NILP (w->base_line_pos)
17963 && XFASTINT (w->base_line_pos) <= startpos)
17965 line = XFASTINT (w->base_line_number);
17966 linepos = XFASTINT (w->base_line_pos);
17967 linepos_byte = buf_charpos_to_bytepos (b, linepos);
17969 else
17971 line = 1;
17972 linepos = BUF_BEGV (b);
17973 linepos_byte = BUF_BEGV_BYTE (b);
17976 /* Count lines from base line to window start position. */
17977 nlines = display_count_lines (linepos, linepos_byte,
17978 startpos_byte,
17979 startpos, &junk);
17981 topline = nlines + line;
17983 /* Determine a new base line, if the old one is too close
17984 or too far away, or if we did not have one.
17985 "Too close" means it's plausible a scroll-down would
17986 go back past it. */
17987 if (startpos == BUF_BEGV (b))
17989 w->base_line_number = make_number (topline);
17990 w->base_line_pos = make_number (BUF_BEGV (b));
17992 else if (nlines < height + 25 || nlines > height * 3 + 50
17993 || linepos == BUF_BEGV (b))
17995 int limit = BUF_BEGV (b);
17996 int limit_byte = BUF_BEGV_BYTE (b);
17997 int position;
17998 int distance = (height * 2 + 30) * line_number_display_limit_width;
18000 if (startpos - distance > limit)
18002 limit = startpos - distance;
18003 limit_byte = CHAR_TO_BYTE (limit);
18006 nlines = display_count_lines (startpos, startpos_byte,
18007 limit_byte,
18008 - (height * 2 + 30),
18009 &position);
18010 /* If we couldn't find the lines we wanted within
18011 line_number_display_limit_width chars per line,
18012 give up on line numbers for this window. */
18013 if (position == limit_byte && limit == startpos - distance)
18015 w->base_line_pos = w->buffer;
18016 w->base_line_number = Qnil;
18017 goto no_value;
18020 w->base_line_number = make_number (topline - nlines);
18021 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
18024 /* Now count lines from the start pos to point. */
18025 nlines = display_count_lines (startpos, startpos_byte,
18026 PT_BYTE, PT, &junk);
18028 /* Record that we did display the line number. */
18029 line_number_displayed = 1;
18031 /* Make the string to show. */
18032 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
18033 return decode_mode_spec_buf;
18034 no_value:
18036 char* p = decode_mode_spec_buf;
18037 int pad = field_width - 2;
18038 while (pad-- > 0)
18039 *p++ = ' ';
18040 *p++ = '?';
18041 *p++ = '?';
18042 *p = '\0';
18043 return decode_mode_spec_buf;
18046 break;
18048 case 'm':
18049 obj = b->mode_name;
18050 break;
18052 case 'n':
18053 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
18054 return " Narrow";
18055 break;
18057 case 'p':
18059 int pos = marker_position (w->start);
18060 int total = BUF_ZV (b) - BUF_BEGV (b);
18062 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
18064 if (pos <= BUF_BEGV (b))
18065 return "All";
18066 else
18067 return "Bottom";
18069 else if (pos <= BUF_BEGV (b))
18070 return "Top";
18071 else
18073 if (total > 1000000)
18074 /* Do it differently for a large value, to avoid overflow. */
18075 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
18076 else
18077 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
18078 /* We can't normally display a 3-digit number,
18079 so get us a 2-digit number that is close. */
18080 if (total == 100)
18081 total = 99;
18082 sprintf (decode_mode_spec_buf, "%2d%%", total);
18083 return decode_mode_spec_buf;
18087 /* Display percentage of size above the bottom of the screen. */
18088 case 'P':
18090 int toppos = marker_position (w->start);
18091 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
18092 int total = BUF_ZV (b) - BUF_BEGV (b);
18094 if (botpos >= BUF_ZV (b))
18096 if (toppos <= BUF_BEGV (b))
18097 return "All";
18098 else
18099 return "Bottom";
18101 else
18103 if (total > 1000000)
18104 /* Do it differently for a large value, to avoid overflow. */
18105 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
18106 else
18107 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
18108 /* We can't normally display a 3-digit number,
18109 so get us a 2-digit number that is close. */
18110 if (total == 100)
18111 total = 99;
18112 if (toppos <= BUF_BEGV (b))
18113 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
18114 else
18115 sprintf (decode_mode_spec_buf, "%2d%%", total);
18116 return decode_mode_spec_buf;
18120 case 's':
18121 /* status of process */
18122 obj = Fget_buffer_process (Fcurrent_buffer ());
18123 if (NILP (obj))
18124 return "no process";
18125 #ifdef subprocesses
18126 obj = Fsymbol_name (Fprocess_status (obj));
18127 #endif
18128 break;
18130 case '@':
18132 Lisp_Object val;
18133 val = call1 (intern ("file-remote-p"), current_buffer->directory);
18134 if (NILP (val))
18135 return "-";
18136 else
18137 return "@";
18140 case 't': /* indicate TEXT or BINARY */
18141 #ifdef MODE_LINE_BINARY_TEXT
18142 return MODE_LINE_BINARY_TEXT (b);
18143 #else
18144 return "T";
18145 #endif
18147 case 'z':
18148 /* coding-system (not including end-of-line format) */
18149 case 'Z':
18150 /* coding-system (including end-of-line type) */
18152 int eol_flag = (c == 'Z');
18153 char *p = decode_mode_spec_buf;
18155 if (! FRAME_WINDOW_P (f))
18157 /* No need to mention EOL here--the terminal never needs
18158 to do EOL conversion. */
18159 p = decode_mode_spec_coding (FRAME_KEYBOARD_CODING (f)->symbol, p, 0);
18160 p = decode_mode_spec_coding (FRAME_TERMINAL_CODING (f)->symbol, p, 0);
18162 p = decode_mode_spec_coding (b->buffer_file_coding_system,
18163 p, eol_flag);
18165 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
18166 #ifdef subprocesses
18167 obj = Fget_buffer_process (Fcurrent_buffer ());
18168 if (PROCESSP (obj))
18170 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
18171 p, eol_flag);
18172 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
18173 p, eol_flag);
18175 #endif /* subprocesses */
18176 #endif /* 0 */
18177 *p = 0;
18178 return decode_mode_spec_buf;
18182 if (STRINGP (obj))
18184 *multibyte = STRING_MULTIBYTE (obj);
18185 return (char *) SDATA (obj);
18187 else
18188 return "";
18192 /* Count up to COUNT lines starting from START / START_BYTE.
18193 But don't go beyond LIMIT_BYTE.
18194 Return the number of lines thus found (always nonnegative).
18196 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
18198 static int
18199 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
18200 int start, start_byte, limit_byte, count;
18201 int *byte_pos_ptr;
18203 register unsigned char *cursor;
18204 unsigned char *base;
18206 register int ceiling;
18207 register unsigned char *ceiling_addr;
18208 int orig_count = count;
18210 /* If we are not in selective display mode,
18211 check only for newlines. */
18212 int selective_display = (!NILP (current_buffer->selective_display)
18213 && !INTEGERP (current_buffer->selective_display));
18215 if (count > 0)
18217 while (start_byte < limit_byte)
18219 ceiling = BUFFER_CEILING_OF (start_byte);
18220 ceiling = min (limit_byte - 1, ceiling);
18221 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
18222 base = (cursor = BYTE_POS_ADDR (start_byte));
18223 while (1)
18225 if (selective_display)
18226 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
18228 else
18229 while (*cursor != '\n' && ++cursor != ceiling_addr)
18232 if (cursor != ceiling_addr)
18234 if (--count == 0)
18236 start_byte += cursor - base + 1;
18237 *byte_pos_ptr = start_byte;
18238 return orig_count;
18240 else
18241 if (++cursor == ceiling_addr)
18242 break;
18244 else
18245 break;
18247 start_byte += cursor - base;
18250 else
18252 while (start_byte > limit_byte)
18254 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
18255 ceiling = max (limit_byte, ceiling);
18256 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
18257 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
18258 while (1)
18260 if (selective_display)
18261 while (--cursor != ceiling_addr
18262 && *cursor != '\n' && *cursor != 015)
18264 else
18265 while (--cursor != ceiling_addr && *cursor != '\n')
18268 if (cursor != ceiling_addr)
18270 if (++count == 0)
18272 start_byte += cursor - base + 1;
18273 *byte_pos_ptr = start_byte;
18274 /* When scanning backwards, we should
18275 not count the newline posterior to which we stop. */
18276 return - orig_count - 1;
18279 else
18280 break;
18282 /* Here we add 1 to compensate for the last decrement
18283 of CURSOR, which took it past the valid range. */
18284 start_byte += cursor - base + 1;
18288 *byte_pos_ptr = limit_byte;
18290 if (count < 0)
18291 return - orig_count + count;
18292 return orig_count - count;
18298 /***********************************************************************
18299 Displaying strings
18300 ***********************************************************************/
18302 /* Display a NUL-terminated string, starting with index START.
18304 If STRING is non-null, display that C string. Otherwise, the Lisp
18305 string LISP_STRING is displayed.
18307 If FACE_STRING is not nil, FACE_STRING_POS is a position in
18308 FACE_STRING. Display STRING or LISP_STRING with the face at
18309 FACE_STRING_POS in FACE_STRING:
18311 Display the string in the environment given by IT, but use the
18312 standard display table, temporarily.
18314 FIELD_WIDTH is the minimum number of output glyphs to produce.
18315 If STRING has fewer characters than FIELD_WIDTH, pad to the right
18316 with spaces. If STRING has more characters, more than FIELD_WIDTH
18317 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
18319 PRECISION is the maximum number of characters to output from
18320 STRING. PRECISION < 0 means don't truncate the string.
18322 This is roughly equivalent to printf format specifiers:
18324 FIELD_WIDTH PRECISION PRINTF
18325 ----------------------------------------
18326 -1 -1 %s
18327 -1 10 %.10s
18328 10 -1 %10s
18329 20 10 %20.10s
18331 MULTIBYTE zero means do not display multibyte chars, > 0 means do
18332 display them, and < 0 means obey the current buffer's value of
18333 enable_multibyte_characters.
18335 Value is the number of columns displayed. */
18337 static int
18338 display_string (string, lisp_string, face_string, face_string_pos,
18339 start, it, field_width, precision, max_x, multibyte)
18340 unsigned char *string;
18341 Lisp_Object lisp_string;
18342 Lisp_Object face_string;
18343 int face_string_pos;
18344 int start;
18345 struct it *it;
18346 int field_width, precision, max_x;
18347 int multibyte;
18349 int hpos_at_start = it->hpos;
18350 int saved_face_id = it->face_id;
18351 struct glyph_row *row = it->glyph_row;
18353 /* Initialize the iterator IT for iteration over STRING beginning
18354 with index START. */
18355 reseat_to_string (it, string, lisp_string, start,
18356 precision, field_width, multibyte);
18358 /* If displaying STRING, set up the face of the iterator
18359 from LISP_STRING, if that's given. */
18360 if (STRINGP (face_string))
18362 int endptr;
18363 struct face *face;
18365 it->face_id
18366 = face_at_string_position (it->w, face_string, face_string_pos,
18367 0, it->region_beg_charpos,
18368 it->region_end_charpos,
18369 &endptr, it->base_face_id, 0);
18370 face = FACE_FROM_ID (it->f, it->face_id);
18371 it->face_box_p = face->box != FACE_NO_BOX;
18374 /* Set max_x to the maximum allowed X position. Don't let it go
18375 beyond the right edge of the window. */
18376 if (max_x <= 0)
18377 max_x = it->last_visible_x;
18378 else
18379 max_x = min (max_x, it->last_visible_x);
18381 /* Skip over display elements that are not visible. because IT->w is
18382 hscrolled. */
18383 if (it->current_x < it->first_visible_x)
18384 move_it_in_display_line_to (it, 100000, it->first_visible_x,
18385 MOVE_TO_POS | MOVE_TO_X);
18387 row->ascent = it->max_ascent;
18388 row->height = it->max_ascent + it->max_descent;
18389 row->phys_ascent = it->max_phys_ascent;
18390 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
18391 row->extra_line_spacing = it->max_extra_line_spacing;
18393 /* This condition is for the case that we are called with current_x
18394 past last_visible_x. */
18395 while (it->current_x < max_x)
18397 int x_before, x, n_glyphs_before, i, nglyphs;
18399 /* Get the next display element. */
18400 if (!get_next_display_element (it))
18401 break;
18403 /* Produce glyphs. */
18404 x_before = it->current_x;
18405 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
18406 PRODUCE_GLYPHS (it);
18408 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
18409 i = 0;
18410 x = x_before;
18411 while (i < nglyphs)
18413 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
18415 if (!it->truncate_lines_p
18416 && x + glyph->pixel_width > max_x)
18418 /* End of continued line or max_x reached. */
18419 if (CHAR_GLYPH_PADDING_P (*glyph))
18421 /* A wide character is unbreakable. */
18422 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
18423 it->current_x = x_before;
18425 else
18427 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
18428 it->current_x = x;
18430 break;
18432 else if (x + glyph->pixel_width > it->first_visible_x)
18434 /* Glyph is at least partially visible. */
18435 ++it->hpos;
18436 if (x < it->first_visible_x)
18437 it->glyph_row->x = x - it->first_visible_x;
18439 else
18441 /* Glyph is off the left margin of the display area.
18442 Should not happen. */
18443 abort ();
18446 row->ascent = max (row->ascent, it->max_ascent);
18447 row->height = max (row->height, it->max_ascent + it->max_descent);
18448 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
18449 row->phys_height = max (row->phys_height,
18450 it->max_phys_ascent + it->max_phys_descent);
18451 row->extra_line_spacing = max (row->extra_line_spacing,
18452 it->max_extra_line_spacing);
18453 x += glyph->pixel_width;
18454 ++i;
18457 /* Stop if max_x reached. */
18458 if (i < nglyphs)
18459 break;
18461 /* Stop at line ends. */
18462 if (ITERATOR_AT_END_OF_LINE_P (it))
18464 it->continuation_lines_width = 0;
18465 break;
18468 set_iterator_to_next (it, 1);
18470 /* Stop if truncating at the right edge. */
18471 if (it->truncate_lines_p
18472 && it->current_x >= it->last_visible_x)
18474 /* Add truncation mark, but don't do it if the line is
18475 truncated at a padding space. */
18476 if (IT_CHARPOS (*it) < it->string_nchars)
18478 if (!FRAME_WINDOW_P (it->f))
18480 int i, n;
18482 if (it->current_x > it->last_visible_x)
18484 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
18485 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
18486 break;
18487 for (n = row->used[TEXT_AREA]; i < n; ++i)
18489 row->used[TEXT_AREA] = i;
18490 produce_special_glyphs (it, IT_TRUNCATION);
18493 produce_special_glyphs (it, IT_TRUNCATION);
18495 it->glyph_row->truncated_on_right_p = 1;
18497 break;
18501 /* Maybe insert a truncation at the left. */
18502 if (it->first_visible_x
18503 && IT_CHARPOS (*it) > 0)
18505 if (!FRAME_WINDOW_P (it->f))
18506 insert_left_trunc_glyphs (it);
18507 it->glyph_row->truncated_on_left_p = 1;
18510 it->face_id = saved_face_id;
18512 /* Value is number of columns displayed. */
18513 return it->hpos - hpos_at_start;
18518 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
18519 appears as an element of LIST or as the car of an element of LIST.
18520 If PROPVAL is a list, compare each element against LIST in that
18521 way, and return 1/2 if any element of PROPVAL is found in LIST.
18522 Otherwise return 0. This function cannot quit.
18523 The return value is 2 if the text is invisible but with an ellipsis
18524 and 1 if it's invisible and without an ellipsis. */
18527 invisible_p (propval, list)
18528 register Lisp_Object propval;
18529 Lisp_Object list;
18531 register Lisp_Object tail, proptail;
18533 for (tail = list; CONSP (tail); tail = XCDR (tail))
18535 register Lisp_Object tem;
18536 tem = XCAR (tail);
18537 if (EQ (propval, tem))
18538 return 1;
18539 if (CONSP (tem) && EQ (propval, XCAR (tem)))
18540 return NILP (XCDR (tem)) ? 1 : 2;
18543 if (CONSP (propval))
18545 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
18547 Lisp_Object propelt;
18548 propelt = XCAR (proptail);
18549 for (tail = list; CONSP (tail); tail = XCDR (tail))
18551 register Lisp_Object tem;
18552 tem = XCAR (tail);
18553 if (EQ (propelt, tem))
18554 return 1;
18555 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
18556 return NILP (XCDR (tem)) ? 1 : 2;
18561 return 0;
18564 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
18565 doc: /* Non-nil if the property makes the text invisible.
18566 POS-OR-PROP can be a marker or number, in which case it is taken to be
18567 a position in the current buffer and the value of the `invisible' property
18568 is checked; or it can be some other value, which is then presumed to be the
18569 value of the `invisible' property of the text of interest.
18570 The non-nil value returned can be t for truly invisible text or something
18571 else if the text is replaced by an ellipsis. */)
18572 (pos_or_prop)
18573 Lisp_Object pos_or_prop;
18575 Lisp_Object prop
18576 = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
18577 ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
18578 : pos_or_prop);
18579 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
18580 return (invis == 0 ? Qnil
18581 : invis == 1 ? Qt
18582 : make_number (invis));
18585 /* Calculate a width or height in pixels from a specification using
18586 the following elements:
18588 SPEC ::=
18589 NUM - a (fractional) multiple of the default font width/height
18590 (NUM) - specifies exactly NUM pixels
18591 UNIT - a fixed number of pixels, see below.
18592 ELEMENT - size of a display element in pixels, see below.
18593 (NUM . SPEC) - equals NUM * SPEC
18594 (+ SPEC SPEC ...) - add pixel values
18595 (- SPEC SPEC ...) - subtract pixel values
18596 (- SPEC) - negate pixel value
18598 NUM ::=
18599 INT or FLOAT - a number constant
18600 SYMBOL - use symbol's (buffer local) variable binding.
18602 UNIT ::=
18603 in - pixels per inch *)
18604 mm - pixels per 1/1000 meter *)
18605 cm - pixels per 1/100 meter *)
18606 width - width of current font in pixels.
18607 height - height of current font in pixels.
18609 *) using the ratio(s) defined in display-pixels-per-inch.
18611 ELEMENT ::=
18613 left-fringe - left fringe width in pixels
18614 right-fringe - right fringe width in pixels
18616 left-margin - left margin width in pixels
18617 right-margin - right margin width in pixels
18619 scroll-bar - scroll-bar area width in pixels
18621 Examples:
18623 Pixels corresponding to 5 inches:
18624 (5 . in)
18626 Total width of non-text areas on left side of window (if scroll-bar is on left):
18627 '(space :width (+ left-fringe left-margin scroll-bar))
18629 Align to first text column (in header line):
18630 '(space :align-to 0)
18632 Align to middle of text area minus half the width of variable `my-image'
18633 containing a loaded image:
18634 '(space :align-to (0.5 . (- text my-image)))
18636 Width of left margin minus width of 1 character in the default font:
18637 '(space :width (- left-margin 1))
18639 Width of left margin minus width of 2 characters in the current font:
18640 '(space :width (- left-margin (2 . width)))
18642 Center 1 character over left-margin (in header line):
18643 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
18645 Different ways to express width of left fringe plus left margin minus one pixel:
18646 '(space :width (- (+ left-fringe left-margin) (1)))
18647 '(space :width (+ left-fringe left-margin (- (1))))
18648 '(space :width (+ left-fringe left-margin (-1)))
18652 #define NUMVAL(X) \
18653 ((INTEGERP (X) || FLOATP (X)) \
18654 ? XFLOATINT (X) \
18655 : - 1)
18658 calc_pixel_width_or_height (res, it, prop, font, width_p, align_to)
18659 double *res;
18660 struct it *it;
18661 Lisp_Object prop;
18662 void *font;
18663 int width_p, *align_to;
18665 double pixels;
18667 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
18668 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
18670 if (NILP (prop))
18671 return OK_PIXELS (0);
18673 xassert (FRAME_LIVE_P (it->f));
18675 if (SYMBOLP (prop))
18677 if (SCHARS (SYMBOL_NAME (prop)) == 2)
18679 char *unit = SDATA (SYMBOL_NAME (prop));
18681 if (unit[0] == 'i' && unit[1] == 'n')
18682 pixels = 1.0;
18683 else if (unit[0] == 'm' && unit[1] == 'm')
18684 pixels = 25.4;
18685 else if (unit[0] == 'c' && unit[1] == 'm')
18686 pixels = 2.54;
18687 else
18688 pixels = 0;
18689 if (pixels > 0)
18691 double ppi;
18692 #ifdef HAVE_WINDOW_SYSTEM
18693 if (FRAME_WINDOW_P (it->f)
18694 && (ppi = (width_p
18695 ? FRAME_X_DISPLAY_INFO (it->f)->resx
18696 : FRAME_X_DISPLAY_INFO (it->f)->resy),
18697 ppi > 0))
18698 return OK_PIXELS (ppi / pixels);
18699 #endif
18701 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
18702 || (CONSP (Vdisplay_pixels_per_inch)
18703 && (ppi = (width_p
18704 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
18705 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
18706 ppi > 0)))
18707 return OK_PIXELS (ppi / pixels);
18709 return 0;
18713 #ifdef HAVE_WINDOW_SYSTEM
18714 if (EQ (prop, Qheight))
18715 return OK_PIXELS (font ? FONT_HEIGHT ((XFontStruct *)font) : FRAME_LINE_HEIGHT (it->f));
18716 if (EQ (prop, Qwidth))
18717 return OK_PIXELS (font ? FONT_WIDTH ((XFontStruct *)font) : FRAME_COLUMN_WIDTH (it->f));
18718 #else
18719 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
18720 return OK_PIXELS (1);
18721 #endif
18723 if (EQ (prop, Qtext))
18724 return OK_PIXELS (width_p
18725 ? window_box_width (it->w, TEXT_AREA)
18726 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
18728 if (align_to && *align_to < 0)
18730 *res = 0;
18731 if (EQ (prop, Qleft))
18732 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
18733 if (EQ (prop, Qright))
18734 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
18735 if (EQ (prop, Qcenter))
18736 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
18737 + window_box_width (it->w, TEXT_AREA) / 2);
18738 if (EQ (prop, Qleft_fringe))
18739 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
18740 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
18741 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
18742 if (EQ (prop, Qright_fringe))
18743 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
18744 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
18745 : window_box_right_offset (it->w, TEXT_AREA));
18746 if (EQ (prop, Qleft_margin))
18747 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
18748 if (EQ (prop, Qright_margin))
18749 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
18750 if (EQ (prop, Qscroll_bar))
18751 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
18753 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
18754 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
18755 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
18756 : 0)));
18758 else
18760 if (EQ (prop, Qleft_fringe))
18761 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
18762 if (EQ (prop, Qright_fringe))
18763 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
18764 if (EQ (prop, Qleft_margin))
18765 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
18766 if (EQ (prop, Qright_margin))
18767 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
18768 if (EQ (prop, Qscroll_bar))
18769 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
18772 prop = Fbuffer_local_value (prop, it->w->buffer);
18775 if (INTEGERP (prop) || FLOATP (prop))
18777 int base_unit = (width_p
18778 ? FRAME_COLUMN_WIDTH (it->f)
18779 : FRAME_LINE_HEIGHT (it->f));
18780 return OK_PIXELS (XFLOATINT (prop) * base_unit);
18783 if (CONSP (prop))
18785 Lisp_Object car = XCAR (prop);
18786 Lisp_Object cdr = XCDR (prop);
18788 if (SYMBOLP (car))
18790 #ifdef HAVE_WINDOW_SYSTEM
18791 if (FRAME_WINDOW_P (it->f)
18792 && valid_image_p (prop))
18794 int id = lookup_image (it->f, prop);
18795 struct image *img = IMAGE_FROM_ID (it->f, id);
18797 return OK_PIXELS (width_p ? img->width : img->height);
18799 #endif
18800 if (EQ (car, Qplus) || EQ (car, Qminus))
18802 int first = 1;
18803 double px;
18805 pixels = 0;
18806 while (CONSP (cdr))
18808 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
18809 font, width_p, align_to))
18810 return 0;
18811 if (first)
18812 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
18813 else
18814 pixels += px;
18815 cdr = XCDR (cdr);
18817 if (EQ (car, Qminus))
18818 pixels = -pixels;
18819 return OK_PIXELS (pixels);
18822 car = Fbuffer_local_value (car, it->w->buffer);
18825 if (INTEGERP (car) || FLOATP (car))
18827 double fact;
18828 pixels = XFLOATINT (car);
18829 if (NILP (cdr))
18830 return OK_PIXELS (pixels);
18831 if (calc_pixel_width_or_height (&fact, it, cdr,
18832 font, width_p, align_to))
18833 return OK_PIXELS (pixels * fact);
18834 return 0;
18837 return 0;
18840 return 0;
18844 /***********************************************************************
18845 Glyph Display
18846 ***********************************************************************/
18848 #ifdef HAVE_WINDOW_SYSTEM
18850 #if GLYPH_DEBUG
18852 void
18853 dump_glyph_string (s)
18854 struct glyph_string *s;
18856 fprintf (stderr, "glyph string\n");
18857 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
18858 s->x, s->y, s->width, s->height);
18859 fprintf (stderr, " ybase = %d\n", s->ybase);
18860 fprintf (stderr, " hl = %d\n", s->hl);
18861 fprintf (stderr, " left overhang = %d, right = %d\n",
18862 s->left_overhang, s->right_overhang);
18863 fprintf (stderr, " nchars = %d\n", s->nchars);
18864 fprintf (stderr, " extends to end of line = %d\n",
18865 s->extends_to_end_of_line_p);
18866 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
18867 fprintf (stderr, " bg width = %d\n", s->background_width);
18870 #endif /* GLYPH_DEBUG */
18872 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
18873 of XChar2b structures for S; it can't be allocated in
18874 init_glyph_string because it must be allocated via `alloca'. W
18875 is the window on which S is drawn. ROW and AREA are the glyph row
18876 and area within the row from which S is constructed. START is the
18877 index of the first glyph structure covered by S. HL is a
18878 face-override for drawing S. */
18880 #ifdef HAVE_NTGUI
18881 #define OPTIONAL_HDC(hdc) hdc,
18882 #define DECLARE_HDC(hdc) HDC hdc;
18883 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
18884 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
18885 #endif
18887 #ifndef OPTIONAL_HDC
18888 #define OPTIONAL_HDC(hdc)
18889 #define DECLARE_HDC(hdc)
18890 #define ALLOCATE_HDC(hdc, f)
18891 #define RELEASE_HDC(hdc, f)
18892 #endif
18894 static void
18895 init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
18896 struct glyph_string *s;
18897 DECLARE_HDC (hdc)
18898 XChar2b *char2b;
18899 struct window *w;
18900 struct glyph_row *row;
18901 enum glyph_row_area area;
18902 int start;
18903 enum draw_glyphs_face hl;
18905 bzero (s, sizeof *s);
18906 s->w = w;
18907 s->f = XFRAME (w->frame);
18908 #ifdef HAVE_NTGUI
18909 s->hdc = hdc;
18910 #endif
18911 s->display = FRAME_X_DISPLAY (s->f);
18912 s->window = FRAME_X_WINDOW (s->f);
18913 s->char2b = char2b;
18914 s->hl = hl;
18915 s->row = row;
18916 s->area = area;
18917 s->first_glyph = row->glyphs[area] + start;
18918 s->height = row->height;
18919 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
18921 /* Display the internal border below the tool-bar window. */
18922 if (WINDOWP (s->f->tool_bar_window)
18923 && s->w == XWINDOW (s->f->tool_bar_window))
18924 s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
18926 s->ybase = s->y + row->ascent;
18930 /* Append the list of glyph strings with head H and tail T to the list
18931 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
18933 static INLINE void
18934 append_glyph_string_lists (head, tail, h, t)
18935 struct glyph_string **head, **tail;
18936 struct glyph_string *h, *t;
18938 if (h)
18940 if (*head)
18941 (*tail)->next = h;
18942 else
18943 *head = h;
18944 h->prev = *tail;
18945 *tail = t;
18950 /* Prepend the list of glyph strings with head H and tail T to the
18951 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
18952 result. */
18954 static INLINE void
18955 prepend_glyph_string_lists (head, tail, h, t)
18956 struct glyph_string **head, **tail;
18957 struct glyph_string *h, *t;
18959 if (h)
18961 if (*head)
18962 (*head)->prev = t;
18963 else
18964 *tail = t;
18965 t->next = *head;
18966 *head = h;
18971 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
18972 Set *HEAD and *TAIL to the resulting list. */
18974 static INLINE void
18975 append_glyph_string (head, tail, s)
18976 struct glyph_string **head, **tail;
18977 struct glyph_string *s;
18979 s->next = s->prev = NULL;
18980 append_glyph_string_lists (head, tail, s, s);
18984 /* Get face and two-byte form of character glyph GLYPH on frame F.
18985 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
18986 a pointer to a realized face that is ready for display. */
18988 static INLINE struct face *
18989 get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
18990 struct frame *f;
18991 struct glyph *glyph;
18992 XChar2b *char2b;
18993 int *two_byte_p;
18995 struct face *face;
18997 xassert (glyph->type == CHAR_GLYPH);
18998 face = FACE_FROM_ID (f, glyph->face_id);
19000 if (two_byte_p)
19001 *two_byte_p = 0;
19003 if (!glyph->multibyte_p)
19005 /* Unibyte case. We don't have to encode, but we have to make
19006 sure to use a face suitable for unibyte. */
19007 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
19009 else if (glyph->u.ch < 128)
19011 /* Case of ASCII in a face known to fit ASCII. */
19012 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
19014 else
19016 int c1, c2, charset;
19018 /* Split characters into bytes. If c2 is -1 afterwards, C is
19019 really a one-byte character so that byte1 is zero. */
19020 SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
19021 if (c2 > 0)
19022 STORE_XCHAR2B (char2b, c1, c2);
19023 else
19024 STORE_XCHAR2B (char2b, 0, c1);
19026 /* Maybe encode the character in *CHAR2B. */
19027 if (charset != CHARSET_ASCII)
19029 struct font_info *font_info
19030 = FONT_INFO_FROM_ID (f, face->font_info_id);
19031 if (font_info)
19032 glyph->font_type
19033 = FRAME_RIF (f)->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
19037 /* Make sure X resources of the face are allocated. */
19038 xassert (face != NULL);
19039 PREPARE_FACE_FOR_DISPLAY (f, face);
19040 return face;
19044 /* Fill glyph string S with composition components specified by S->cmp.
19046 FACES is an array of faces for all components of this composition.
19047 S->gidx is the index of the first component for S.
19049 OVERLAPS non-zero means S should draw the foreground only, and use
19050 its physical height for clipping. See also draw_glyphs.
19052 Value is the index of a component not in S. */
19054 static int
19055 fill_composite_glyph_string (s, faces, overlaps)
19056 struct glyph_string *s;
19057 struct face **faces;
19058 int overlaps;
19060 int i;
19062 xassert (s);
19064 s->for_overlaps = overlaps;
19066 s->face = faces[s->gidx];
19067 s->font = s->face->font;
19068 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
19070 /* For all glyphs of this composition, starting at the offset
19071 S->gidx, until we reach the end of the definition or encounter a
19072 glyph that requires the different face, add it to S. */
19073 ++s->nchars;
19074 for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
19075 ++s->nchars;
19077 /* All glyph strings for the same composition has the same width,
19078 i.e. the width set for the first component of the composition. */
19080 s->width = s->first_glyph->pixel_width;
19082 /* If the specified font could not be loaded, use the frame's
19083 default font, but record the fact that we couldn't load it in
19084 the glyph string so that we can draw rectangles for the
19085 characters of the glyph string. */
19086 if (s->font == NULL)
19088 s->font_not_found_p = 1;
19089 s->font = FRAME_FONT (s->f);
19092 /* Adjust base line for subscript/superscript text. */
19093 s->ybase += s->first_glyph->voffset;
19095 xassert (s->face && s->face->gc);
19097 /* This glyph string must always be drawn with 16-bit functions. */
19098 s->two_byte_p = 1;
19100 return s->gidx + s->nchars;
19104 /* Fill glyph string S from a sequence of character glyphs.
19106 FACE_ID is the face id of the string. START is the index of the
19107 first glyph to consider, END is the index of the last + 1.
19108 OVERLAPS non-zero means S should draw the foreground only, and use
19109 its physical height for clipping. See also draw_glyphs.
19111 Value is the index of the first glyph not in S. */
19113 static int
19114 fill_glyph_string (s, face_id, start, end, overlaps)
19115 struct glyph_string *s;
19116 int face_id;
19117 int start, end, overlaps;
19119 struct glyph *glyph, *last;
19120 int voffset;
19121 int glyph_not_available_p;
19123 xassert (s->f == XFRAME (s->w->frame));
19124 xassert (s->nchars == 0);
19125 xassert (start >= 0 && end > start);
19127 s->for_overlaps = overlaps,
19128 glyph = s->row->glyphs[s->area] + start;
19129 last = s->row->glyphs[s->area] + end;
19130 voffset = glyph->voffset;
19132 glyph_not_available_p = glyph->glyph_not_available_p;
19134 while (glyph < last
19135 && glyph->type == CHAR_GLYPH
19136 && glyph->voffset == voffset
19137 /* Same face id implies same font, nowadays. */
19138 && glyph->face_id == face_id
19139 && glyph->glyph_not_available_p == glyph_not_available_p)
19141 int two_byte_p;
19143 s->face = get_glyph_face_and_encoding (s->f, glyph,
19144 s->char2b + s->nchars,
19145 &two_byte_p);
19146 s->two_byte_p = two_byte_p;
19147 ++s->nchars;
19148 xassert (s->nchars <= end - start);
19149 s->width += glyph->pixel_width;
19150 ++glyph;
19153 s->font = s->face->font;
19154 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
19156 /* If the specified font could not be loaded, use the frame's font,
19157 but record the fact that we couldn't load it in
19158 S->font_not_found_p so that we can draw rectangles for the
19159 characters of the glyph string. */
19160 if (s->font == NULL || glyph_not_available_p)
19162 s->font_not_found_p = 1;
19163 s->font = FRAME_FONT (s->f);
19166 /* Adjust base line for subscript/superscript text. */
19167 s->ybase += voffset;
19169 xassert (s->face && s->face->gc);
19170 return glyph - s->row->glyphs[s->area];
19174 /* Fill glyph string S from image glyph S->first_glyph. */
19176 static void
19177 fill_image_glyph_string (s)
19178 struct glyph_string *s;
19180 xassert (s->first_glyph->type == IMAGE_GLYPH);
19181 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
19182 xassert (s->img);
19183 s->slice = s->first_glyph->slice;
19184 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
19185 s->font = s->face->font;
19186 s->width = s->first_glyph->pixel_width;
19188 /* Adjust base line for subscript/superscript text. */
19189 s->ybase += s->first_glyph->voffset;
19193 /* Fill glyph string S from a sequence of stretch glyphs.
19195 ROW is the glyph row in which the glyphs are found, AREA is the
19196 area within the row. START is the index of the first glyph to
19197 consider, END is the index of the last + 1.
19199 Value is the index of the first glyph not in S. */
19201 static int
19202 fill_stretch_glyph_string (s, row, area, start, end)
19203 struct glyph_string *s;
19204 struct glyph_row *row;
19205 enum glyph_row_area area;
19206 int start, end;
19208 struct glyph *glyph, *last;
19209 int voffset, face_id;
19211 xassert (s->first_glyph->type == STRETCH_GLYPH);
19213 glyph = s->row->glyphs[s->area] + start;
19214 last = s->row->glyphs[s->area] + end;
19215 face_id = glyph->face_id;
19216 s->face = FACE_FROM_ID (s->f, face_id);
19217 s->font = s->face->font;
19218 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
19219 s->width = glyph->pixel_width;
19220 s->nchars = 1;
19221 voffset = glyph->voffset;
19223 for (++glyph;
19224 (glyph < last
19225 && glyph->type == STRETCH_GLYPH
19226 && glyph->voffset == voffset
19227 && glyph->face_id == face_id);
19228 ++glyph)
19229 s->width += glyph->pixel_width;
19231 /* Adjust base line for subscript/superscript text. */
19232 s->ybase += voffset;
19234 /* The case that face->gc == 0 is handled when drawing the glyph
19235 string by calling PREPARE_FACE_FOR_DISPLAY. */
19236 xassert (s->face);
19237 return glyph - s->row->glyphs[s->area];
19241 /* EXPORT for RIF:
19242 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
19243 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
19244 assumed to be zero. */
19246 void
19247 x_get_glyph_overhangs (glyph, f, left, right)
19248 struct glyph *glyph;
19249 struct frame *f;
19250 int *left, *right;
19252 *left = *right = 0;
19254 if (glyph->type == CHAR_GLYPH)
19256 XFontStruct *font;
19257 struct face *face;
19258 struct font_info *font_info;
19259 XChar2b char2b;
19260 XCharStruct *pcm;
19262 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
19263 font = face->font;
19264 font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
19265 if (font /* ++KFS: Should this be font_info ? */
19266 && (pcm = FRAME_RIF (f)->per_char_metric (font, &char2b, glyph->font_type)))
19268 if (pcm->rbearing > pcm->width)
19269 *right = pcm->rbearing - pcm->width;
19270 if (pcm->lbearing < 0)
19271 *left = -pcm->lbearing;
19277 /* Return the index of the first glyph preceding glyph string S that
19278 is overwritten by S because of S's left overhang. Value is -1
19279 if no glyphs are overwritten. */
19281 static int
19282 left_overwritten (s)
19283 struct glyph_string *s;
19285 int k;
19287 if (s->left_overhang)
19289 int x = 0, i;
19290 struct glyph *glyphs = s->row->glyphs[s->area];
19291 int first = s->first_glyph - glyphs;
19293 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
19294 x -= glyphs[i].pixel_width;
19296 k = i + 1;
19298 else
19299 k = -1;
19301 return k;
19305 /* Return the index of the first glyph preceding glyph string S that
19306 is overwriting S because of its right overhang. Value is -1 if no
19307 glyph in front of S overwrites S. */
19309 static int
19310 left_overwriting (s)
19311 struct glyph_string *s;
19313 int i, k, x;
19314 struct glyph *glyphs = s->row->glyphs[s->area];
19315 int first = s->first_glyph - glyphs;
19317 k = -1;
19318 x = 0;
19319 for (i = first - 1; i >= 0; --i)
19321 int left, right;
19322 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
19323 if (x + right > 0)
19324 k = i;
19325 x -= glyphs[i].pixel_width;
19328 return k;
19332 /* Return the index of the last glyph following glyph string S that is
19333 not overwritten by S because of S's right overhang. Value is -1 if
19334 no such glyph is found. */
19336 static int
19337 right_overwritten (s)
19338 struct glyph_string *s;
19340 int k = -1;
19342 if (s->right_overhang)
19344 int x = 0, i;
19345 struct glyph *glyphs = s->row->glyphs[s->area];
19346 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
19347 int end = s->row->used[s->area];
19349 for (i = first; i < end && s->right_overhang > x; ++i)
19350 x += glyphs[i].pixel_width;
19352 k = i;
19355 return k;
19359 /* Return the index of the last glyph following glyph string S that
19360 overwrites S because of its left overhang. Value is negative
19361 if no such glyph is found. */
19363 static int
19364 right_overwriting (s)
19365 struct glyph_string *s;
19367 int i, k, x;
19368 int end = s->row->used[s->area];
19369 struct glyph *glyphs = s->row->glyphs[s->area];
19370 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
19372 k = -1;
19373 x = 0;
19374 for (i = first; i < end; ++i)
19376 int left, right;
19377 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
19378 if (x - left < 0)
19379 k = i;
19380 x += glyphs[i].pixel_width;
19383 return k;
19387 /* Get face and two-byte form of character C in face FACE_ID on frame
19388 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
19389 means we want to display multibyte text. DISPLAY_P non-zero means
19390 make sure that X resources for the face returned are allocated.
19391 Value is a pointer to a realized face that is ready for display if
19392 DISPLAY_P is non-zero. */
19394 static INLINE struct face *
19395 get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
19396 struct frame *f;
19397 int c, face_id;
19398 XChar2b *char2b;
19399 int multibyte_p, display_p;
19401 struct face *face = FACE_FROM_ID (f, face_id);
19403 if (!multibyte_p)
19405 /* Unibyte case. We don't have to encode, but we have to make
19406 sure to use a face suitable for unibyte. */
19407 STORE_XCHAR2B (char2b, 0, c);
19408 face_id = FACE_FOR_CHAR (f, face, c);
19409 face = FACE_FROM_ID (f, face_id);
19411 else if (c < 128)
19413 /* Case of ASCII in a face known to fit ASCII. */
19414 STORE_XCHAR2B (char2b, 0, c);
19416 else
19418 int c1, c2, charset;
19420 /* Split characters into bytes. If c2 is -1 afterwards, C is
19421 really a one-byte character so that byte1 is zero. */
19422 SPLIT_CHAR (c, charset, c1, c2);
19423 if (c2 > 0)
19424 STORE_XCHAR2B (char2b, c1, c2);
19425 else
19426 STORE_XCHAR2B (char2b, 0, c1);
19428 /* Maybe encode the character in *CHAR2B. */
19429 if (face->font != NULL)
19431 struct font_info *font_info
19432 = FONT_INFO_FROM_ID (f, face->font_info_id);
19433 if (font_info)
19434 FRAME_RIF (f)->encode_char (c, char2b, font_info, 0);
19438 /* Make sure X resources of the face are allocated. */
19439 #ifdef HAVE_X_WINDOWS
19440 if (display_p)
19441 #endif
19443 xassert (face != NULL);
19444 PREPARE_FACE_FOR_DISPLAY (f, face);
19447 return face;
19451 /* Set background width of glyph string S. START is the index of the
19452 first glyph following S. LAST_X is the right-most x-position + 1
19453 in the drawing area. */
19455 static INLINE void
19456 set_glyph_string_background_width (s, start, last_x)
19457 struct glyph_string *s;
19458 int start;
19459 int last_x;
19461 /* If the face of this glyph string has to be drawn to the end of
19462 the drawing area, set S->extends_to_end_of_line_p. */
19464 if (start == s->row->used[s->area]
19465 && s->area == TEXT_AREA
19466 && ((s->row->fill_line_p
19467 && (s->hl == DRAW_NORMAL_TEXT
19468 || s->hl == DRAW_IMAGE_RAISED
19469 || s->hl == DRAW_IMAGE_SUNKEN))
19470 || s->hl == DRAW_MOUSE_FACE))
19471 s->extends_to_end_of_line_p = 1;
19473 /* If S extends its face to the end of the line, set its
19474 background_width to the distance to the right edge of the drawing
19475 area. */
19476 if (s->extends_to_end_of_line_p)
19477 s->background_width = last_x - s->x + 1;
19478 else
19479 s->background_width = s->width;
19483 /* Compute overhangs and x-positions for glyph string S and its
19484 predecessors, or successors. X is the starting x-position for S.
19485 BACKWARD_P non-zero means process predecessors. */
19487 static void
19488 compute_overhangs_and_x (s, x, backward_p)
19489 struct glyph_string *s;
19490 int x;
19491 int backward_p;
19493 if (backward_p)
19495 while (s)
19497 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
19498 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
19499 x -= s->width;
19500 s->x = x;
19501 s = s->prev;
19504 else
19506 while (s)
19508 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
19509 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
19510 s->x = x;
19511 x += s->width;
19512 s = s->next;
19519 /* The following macros are only called from draw_glyphs below.
19520 They reference the following parameters of that function directly:
19521 `w', `row', `area', and `overlap_p'
19522 as well as the following local variables:
19523 `s', `f', and `hdc' (in W32) */
19525 #ifdef HAVE_NTGUI
19526 /* On W32, silently add local `hdc' variable to argument list of
19527 init_glyph_string. */
19528 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
19529 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
19530 #else
19531 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
19532 init_glyph_string (s, char2b, w, row, area, start, hl)
19533 #endif
19535 /* Add a glyph string for a stretch glyph to the list of strings
19536 between HEAD and TAIL. START is the index of the stretch glyph in
19537 row area AREA of glyph row ROW. END is the index of the last glyph
19538 in that glyph row area. X is the current output position assigned
19539 to the new glyph string constructed. HL overrides that face of the
19540 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
19541 is the right-most x-position of the drawing area. */
19543 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
19544 and below -- keep them on one line. */
19545 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
19546 do \
19548 s = (struct glyph_string *) alloca (sizeof *s); \
19549 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
19550 START = fill_stretch_glyph_string (s, row, area, START, END); \
19551 append_glyph_string (&HEAD, &TAIL, s); \
19552 s->x = (X); \
19554 while (0)
19557 /* Add a glyph string for an image glyph to the list of strings
19558 between HEAD and TAIL. START is the index of the image glyph in
19559 row area AREA of glyph row ROW. END is the index of the last glyph
19560 in that glyph row area. X is the current output position assigned
19561 to the new glyph string constructed. HL overrides that face of the
19562 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
19563 is the right-most x-position of the drawing area. */
19565 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
19566 do \
19568 s = (struct glyph_string *) alloca (sizeof *s); \
19569 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
19570 fill_image_glyph_string (s); \
19571 append_glyph_string (&HEAD, &TAIL, s); \
19572 ++START; \
19573 s->x = (X); \
19575 while (0)
19578 /* Add a glyph string for a sequence of character glyphs to the list
19579 of strings between HEAD and TAIL. START is the index of the first
19580 glyph in row area AREA of glyph row ROW that is part of the new
19581 glyph string. END is the index of the last glyph in that glyph row
19582 area. X is the current output position assigned to the new glyph
19583 string constructed. HL overrides that face of the glyph; e.g. it
19584 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
19585 right-most x-position of the drawing area. */
19587 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
19588 do \
19590 int c, face_id; \
19591 XChar2b *char2b; \
19593 c = (row)->glyphs[area][START].u.ch; \
19594 face_id = (row)->glyphs[area][START].face_id; \
19596 s = (struct glyph_string *) alloca (sizeof *s); \
19597 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
19598 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
19599 append_glyph_string (&HEAD, &TAIL, s); \
19600 s->x = (X); \
19601 START = fill_glyph_string (s, face_id, START, END, overlaps); \
19603 while (0)
19606 /* Add a glyph string for a composite sequence to the list of strings
19607 between HEAD and TAIL. START is the index of the first glyph in
19608 row area AREA of glyph row ROW that is part of the new glyph
19609 string. END is the index of the last glyph in that glyph row area.
19610 X is the current output position assigned to the new glyph string
19611 constructed. HL overrides that face of the glyph; e.g. it is
19612 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
19613 x-position of the drawing area. */
19615 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
19616 do { \
19617 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
19618 int face_id = (row)->glyphs[area][START].face_id; \
19619 struct face *base_face = FACE_FROM_ID (f, face_id); \
19620 struct composition *cmp = composition_table[cmp_id]; \
19621 int glyph_len = cmp->glyph_len; \
19622 XChar2b *char2b; \
19623 struct face **faces; \
19624 struct glyph_string *first_s = NULL; \
19625 int n; \
19627 base_face = base_face->ascii_face; \
19628 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
19629 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
19630 /* At first, fill in `char2b' and `faces'. */ \
19631 for (n = 0; n < glyph_len; n++) \
19633 int c = COMPOSITION_GLYPH (cmp, n); \
19634 int this_face_id = FACE_FOR_CHAR (f, base_face, c); \
19635 faces[n] = FACE_FROM_ID (f, this_face_id); \
19636 get_char_face_and_encoding (f, c, this_face_id, \
19637 char2b + n, 1, 1); \
19640 /* Make glyph_strings for each glyph sequence that is drawable by \
19641 the same face, and append them to HEAD/TAIL. */ \
19642 for (n = 0; n < cmp->glyph_len;) \
19644 s = (struct glyph_string *) alloca (sizeof *s); \
19645 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \
19646 append_glyph_string (&(HEAD), &(TAIL), s); \
19647 s->cmp = cmp; \
19648 s->gidx = n; \
19649 s->x = (X); \
19651 if (n == 0) \
19652 first_s = s; \
19654 n = fill_composite_glyph_string (s, faces, overlaps); \
19657 ++START; \
19658 s = first_s; \
19659 } while (0)
19662 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
19663 of AREA of glyph row ROW on window W between indices START and END.
19664 HL overrides the face for drawing glyph strings, e.g. it is
19665 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
19666 x-positions of the drawing area.
19668 This is an ugly monster macro construct because we must use alloca
19669 to allocate glyph strings (because draw_glyphs can be called
19670 asynchronously). */
19672 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
19673 do \
19675 HEAD = TAIL = NULL; \
19676 while (START < END) \
19678 struct glyph *first_glyph = (row)->glyphs[area] + START; \
19679 switch (first_glyph->type) \
19681 case CHAR_GLYPH: \
19682 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
19683 HL, X, LAST_X); \
19684 break; \
19686 case COMPOSITE_GLYPH: \
19687 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
19688 HL, X, LAST_X); \
19689 break; \
19691 case STRETCH_GLYPH: \
19692 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
19693 HL, X, LAST_X); \
19694 break; \
19696 case IMAGE_GLYPH: \
19697 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
19698 HL, X, LAST_X); \
19699 break; \
19701 default: \
19702 abort (); \
19705 set_glyph_string_background_width (s, START, LAST_X); \
19706 (X) += s->width; \
19709 while (0)
19712 /* Draw glyphs between START and END in AREA of ROW on window W,
19713 starting at x-position X. X is relative to AREA in W. HL is a
19714 face-override with the following meaning:
19716 DRAW_NORMAL_TEXT draw normally
19717 DRAW_CURSOR draw in cursor face
19718 DRAW_MOUSE_FACE draw in mouse face.
19719 DRAW_INVERSE_VIDEO draw in mode line face
19720 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
19721 DRAW_IMAGE_RAISED draw an image with a raised relief around it
19723 If OVERLAPS is non-zero, draw only the foreground of characters and
19724 clip to the physical height of ROW. Non-zero value also defines
19725 the overlapping part to be drawn:
19727 OVERLAPS_PRED overlap with preceding rows
19728 OVERLAPS_SUCC overlap with succeeding rows
19729 OVERLAPS_BOTH overlap with both preceding/succeeding rows
19730 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
19732 Value is the x-position reached, relative to AREA of W. */
19734 static int
19735 draw_glyphs (w, x, row, area, start, end, hl, overlaps)
19736 struct window *w;
19737 int x;
19738 struct glyph_row *row;
19739 enum glyph_row_area area;
19740 int start, end;
19741 enum draw_glyphs_face hl;
19742 int overlaps;
19744 struct glyph_string *head, *tail;
19745 struct glyph_string *s;
19746 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
19747 int last_x, area_width;
19748 int x_reached;
19749 int i, j;
19750 struct frame *f = XFRAME (WINDOW_FRAME (w));
19751 DECLARE_HDC (hdc);
19753 ALLOCATE_HDC (hdc, f);
19755 /* Let's rather be paranoid than getting a SEGV. */
19756 end = min (end, row->used[area]);
19757 start = max (0, start);
19758 start = min (end, start);
19760 /* Translate X to frame coordinates. Set last_x to the right
19761 end of the drawing area. */
19762 if (row->full_width_p)
19764 /* X is relative to the left edge of W, without scroll bars
19765 or fringes. */
19766 x += WINDOW_LEFT_EDGE_X (w);
19767 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
19769 else
19771 int area_left = window_box_left (w, area);
19772 x += area_left;
19773 area_width = window_box_width (w, area);
19774 last_x = area_left + area_width;
19777 /* Build a doubly-linked list of glyph_string structures between
19778 head and tail from what we have to draw. Note that the macro
19779 BUILD_GLYPH_STRINGS will modify its start parameter. That's
19780 the reason we use a separate variable `i'. */
19781 i = start;
19782 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
19783 if (tail)
19784 x_reached = tail->x + tail->background_width;
19785 else
19786 x_reached = x;
19788 /* If there are any glyphs with lbearing < 0 or rbearing > width in
19789 the row, redraw some glyphs in front or following the glyph
19790 strings built above. */
19791 if (head && !overlaps && row->contains_overlapping_glyphs_p)
19793 int dummy_x = 0;
19794 struct glyph_string *h, *t;
19796 /* Compute overhangs for all glyph strings. */
19797 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
19798 for (s = head; s; s = s->next)
19799 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
19801 /* Prepend glyph strings for glyphs in front of the first glyph
19802 string that are overwritten because of the first glyph
19803 string's left overhang. The background of all strings
19804 prepended must be drawn because the first glyph string
19805 draws over it. */
19806 i = left_overwritten (head);
19807 if (i >= 0)
19809 j = i;
19810 BUILD_GLYPH_STRINGS (j, start, h, t,
19811 DRAW_NORMAL_TEXT, dummy_x, last_x);
19812 start = i;
19813 compute_overhangs_and_x (t, head->x, 1);
19814 prepend_glyph_string_lists (&head, &tail, h, t);
19815 clip_head = head;
19818 /* Prepend glyph strings for glyphs in front of the first glyph
19819 string that overwrite that glyph string because of their
19820 right overhang. For these strings, only the foreground must
19821 be drawn, because it draws over the glyph string at `head'.
19822 The background must not be drawn because this would overwrite
19823 right overhangs of preceding glyphs for which no glyph
19824 strings exist. */
19825 i = left_overwriting (head);
19826 if (i >= 0)
19828 clip_head = head;
19829 BUILD_GLYPH_STRINGS (i, start, h, t,
19830 DRAW_NORMAL_TEXT, dummy_x, last_x);
19831 for (s = h; s; s = s->next)
19832 s->background_filled_p = 1;
19833 compute_overhangs_and_x (t, head->x, 1);
19834 prepend_glyph_string_lists (&head, &tail, h, t);
19837 /* Append glyphs strings for glyphs following the last glyph
19838 string tail that are overwritten by tail. The background of
19839 these strings has to be drawn because tail's foreground draws
19840 over it. */
19841 i = right_overwritten (tail);
19842 if (i >= 0)
19844 BUILD_GLYPH_STRINGS (end, i, h, t,
19845 DRAW_NORMAL_TEXT, x, last_x);
19846 compute_overhangs_and_x (h, tail->x + tail->width, 0);
19847 append_glyph_string_lists (&head, &tail, h, t);
19848 clip_tail = tail;
19851 /* Append glyph strings for glyphs following the last glyph
19852 string tail that overwrite tail. The foreground of such
19853 glyphs has to be drawn because it writes into the background
19854 of tail. The background must not be drawn because it could
19855 paint over the foreground of following glyphs. */
19856 i = right_overwriting (tail);
19857 if (i >= 0)
19859 clip_tail = tail;
19860 BUILD_GLYPH_STRINGS (end, i, h, t,
19861 DRAW_NORMAL_TEXT, x, last_x);
19862 for (s = h; s; s = s->next)
19863 s->background_filled_p = 1;
19864 compute_overhangs_and_x (h, tail->x + tail->width, 0);
19865 append_glyph_string_lists (&head, &tail, h, t);
19867 if (clip_head || clip_tail)
19868 for (s = head; s; s = s->next)
19870 s->clip_head = clip_head;
19871 s->clip_tail = clip_tail;
19875 /* Draw all strings. */
19876 for (s = head; s; s = s->next)
19877 FRAME_RIF (f)->draw_glyph_string (s);
19879 if (area == TEXT_AREA
19880 && !row->full_width_p
19881 /* When drawing overlapping rows, only the glyph strings'
19882 foreground is drawn, which doesn't erase a cursor
19883 completely. */
19884 && !overlaps)
19886 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
19887 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
19888 : (tail ? tail->x + tail->background_width : x));
19890 int text_left = window_box_left (w, TEXT_AREA);
19891 x0 -= text_left;
19892 x1 -= text_left;
19894 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
19895 row->y, MATRIX_ROW_BOTTOM_Y (row));
19898 /* Value is the x-position up to which drawn, relative to AREA of W.
19899 This doesn't include parts drawn because of overhangs. */
19900 if (row->full_width_p)
19901 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
19902 else
19903 x_reached -= window_box_left (w, area);
19905 RELEASE_HDC (hdc, f);
19907 return x_reached;
19910 /* Expand row matrix if too narrow. Don't expand if area
19911 is not present. */
19913 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
19915 if (!fonts_changed_p \
19916 && (it->glyph_row->glyphs[area] \
19917 < it->glyph_row->glyphs[area + 1])) \
19919 it->w->ncols_scale_factor++; \
19920 fonts_changed_p = 1; \
19924 /* Store one glyph for IT->char_to_display in IT->glyph_row.
19925 Called from x_produce_glyphs when IT->glyph_row is non-null. */
19927 static INLINE void
19928 append_glyph (it)
19929 struct it *it;
19931 struct glyph *glyph;
19932 enum glyph_row_area area = it->area;
19934 xassert (it->glyph_row);
19935 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
19937 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
19938 if (glyph < it->glyph_row->glyphs[area + 1])
19940 glyph->charpos = CHARPOS (it->position);
19941 glyph->object = it->object;
19942 glyph->pixel_width = it->pixel_width;
19943 glyph->ascent = it->ascent;
19944 glyph->descent = it->descent;
19945 glyph->voffset = it->voffset;
19946 glyph->type = CHAR_GLYPH;
19947 glyph->multibyte_p = it->multibyte_p;
19948 glyph->left_box_line_p = it->start_of_box_run_p;
19949 glyph->right_box_line_p = it->end_of_box_run_p;
19950 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
19951 || it->phys_descent > it->descent);
19952 glyph->padding_p = 0;
19953 glyph->glyph_not_available_p = it->glyph_not_available_p;
19954 glyph->face_id = it->face_id;
19955 glyph->u.ch = it->char_to_display;
19956 glyph->slice = null_glyph_slice;
19957 glyph->font_type = FONT_TYPE_UNKNOWN;
19958 ++it->glyph_row->used[area];
19960 else
19961 IT_EXPAND_MATRIX_WIDTH (it, area);
19964 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
19965 Called from x_produce_glyphs when IT->glyph_row is non-null. */
19967 static INLINE void
19968 append_composite_glyph (it)
19969 struct it *it;
19971 struct glyph *glyph;
19972 enum glyph_row_area area = it->area;
19974 xassert (it->glyph_row);
19976 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
19977 if (glyph < it->glyph_row->glyphs[area + 1])
19979 glyph->charpos = CHARPOS (it->position);
19980 glyph->object = it->object;
19981 glyph->pixel_width = it->pixel_width;
19982 glyph->ascent = it->ascent;
19983 glyph->descent = it->descent;
19984 glyph->voffset = it->voffset;
19985 glyph->type = COMPOSITE_GLYPH;
19986 glyph->multibyte_p = it->multibyte_p;
19987 glyph->left_box_line_p = it->start_of_box_run_p;
19988 glyph->right_box_line_p = it->end_of_box_run_p;
19989 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
19990 || it->phys_descent > it->descent);
19991 glyph->padding_p = 0;
19992 glyph->glyph_not_available_p = 0;
19993 glyph->face_id = it->face_id;
19994 glyph->u.cmp_id = it->cmp_id;
19995 glyph->slice = null_glyph_slice;
19996 glyph->font_type = FONT_TYPE_UNKNOWN;
19997 ++it->glyph_row->used[area];
19999 else
20000 IT_EXPAND_MATRIX_WIDTH (it, area);
20004 /* Change IT->ascent and IT->height according to the setting of
20005 IT->voffset. */
20007 static INLINE void
20008 take_vertical_position_into_account (it)
20009 struct it *it;
20011 if (it->voffset)
20013 if (it->voffset < 0)
20014 /* Increase the ascent so that we can display the text higher
20015 in the line. */
20016 it->ascent -= it->voffset;
20017 else
20018 /* Increase the descent so that we can display the text lower
20019 in the line. */
20020 it->descent += it->voffset;
20025 /* Produce glyphs/get display metrics for the image IT is loaded with.
20026 See the description of struct display_iterator in dispextern.h for
20027 an overview of struct display_iterator. */
20029 static void
20030 produce_image_glyph (it)
20031 struct it *it;
20033 struct image *img;
20034 struct face *face;
20035 int glyph_ascent, crop;
20036 struct glyph_slice slice;
20038 xassert (it->what == IT_IMAGE);
20040 face = FACE_FROM_ID (it->f, it->face_id);
20041 xassert (face);
20042 /* Make sure X resources of the face is loaded. */
20043 PREPARE_FACE_FOR_DISPLAY (it->f, face);
20045 if (it->image_id < 0)
20047 /* Fringe bitmap. */
20048 it->ascent = it->phys_ascent = 0;
20049 it->descent = it->phys_descent = 0;
20050 it->pixel_width = 0;
20051 it->nglyphs = 0;
20052 return;
20055 img = IMAGE_FROM_ID (it->f, it->image_id);
20056 xassert (img);
20057 /* Make sure X resources of the image is loaded. */
20058 prepare_image_for_display (it->f, img);
20060 slice.x = slice.y = 0;
20061 slice.width = img->width;
20062 slice.height = img->height;
20064 if (INTEGERP (it->slice.x))
20065 slice.x = XINT (it->slice.x);
20066 else if (FLOATP (it->slice.x))
20067 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
20069 if (INTEGERP (it->slice.y))
20070 slice.y = XINT (it->slice.y);
20071 else if (FLOATP (it->slice.y))
20072 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
20074 if (INTEGERP (it->slice.width))
20075 slice.width = XINT (it->slice.width);
20076 else if (FLOATP (it->slice.width))
20077 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
20079 if (INTEGERP (it->slice.height))
20080 slice.height = XINT (it->slice.height);
20081 else if (FLOATP (it->slice.height))
20082 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
20084 if (slice.x >= img->width)
20085 slice.x = img->width;
20086 if (slice.y >= img->height)
20087 slice.y = img->height;
20088 if (slice.x + slice.width >= img->width)
20089 slice.width = img->width - slice.x;
20090 if (slice.y + slice.height > img->height)
20091 slice.height = img->height - slice.y;
20093 if (slice.width == 0 || slice.height == 0)
20094 return;
20096 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
20098 it->descent = slice.height - glyph_ascent;
20099 if (slice.y == 0)
20100 it->descent += img->vmargin;
20101 if (slice.y + slice.height == img->height)
20102 it->descent += img->vmargin;
20103 it->phys_descent = it->descent;
20105 it->pixel_width = slice.width;
20106 if (slice.x == 0)
20107 it->pixel_width += img->hmargin;
20108 if (slice.x + slice.width == img->width)
20109 it->pixel_width += img->hmargin;
20111 /* It's quite possible for images to have an ascent greater than
20112 their height, so don't get confused in that case. */
20113 if (it->descent < 0)
20114 it->descent = 0;
20116 #if 0 /* this breaks image tiling */
20117 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
20118 int face_ascent = face->font ? FONT_BASE (face->font) : FRAME_BASELINE_OFFSET (it->f);
20119 if (face_ascent > it->ascent)
20120 it->ascent = it->phys_ascent = face_ascent;
20121 #endif
20123 it->nglyphs = 1;
20125 if (face->box != FACE_NO_BOX)
20127 if (face->box_line_width > 0)
20129 if (slice.y == 0)
20130 it->ascent += face->box_line_width;
20131 if (slice.y + slice.height == img->height)
20132 it->descent += face->box_line_width;
20135 if (it->start_of_box_run_p && slice.x == 0)
20136 it->pixel_width += eabs (face->box_line_width);
20137 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
20138 it->pixel_width += eabs (face->box_line_width);
20141 take_vertical_position_into_account (it);
20143 /* Automatically crop wide image glyphs at right edge so we can
20144 draw the cursor on same display row. */
20145 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
20146 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
20148 it->pixel_width -= crop;
20149 slice.width -= crop;
20152 if (it->glyph_row)
20154 struct glyph *glyph;
20155 enum glyph_row_area area = it->area;
20157 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
20158 if (glyph < it->glyph_row->glyphs[area + 1])
20160 glyph->charpos = CHARPOS (it->position);
20161 glyph->object = it->object;
20162 glyph->pixel_width = it->pixel_width;
20163 glyph->ascent = glyph_ascent;
20164 glyph->descent = it->descent;
20165 glyph->voffset = it->voffset;
20166 glyph->type = IMAGE_GLYPH;
20167 glyph->multibyte_p = it->multibyte_p;
20168 glyph->left_box_line_p = it->start_of_box_run_p;
20169 glyph->right_box_line_p = it->end_of_box_run_p;
20170 glyph->overlaps_vertically_p = 0;
20171 glyph->padding_p = 0;
20172 glyph->glyph_not_available_p = 0;
20173 glyph->face_id = it->face_id;
20174 glyph->u.img_id = img->id;
20175 glyph->slice = slice;
20176 glyph->font_type = FONT_TYPE_UNKNOWN;
20177 ++it->glyph_row->used[area];
20179 else
20180 IT_EXPAND_MATRIX_WIDTH (it, area);
20185 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
20186 of the glyph, WIDTH and HEIGHT are the width and height of the
20187 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
20189 static void
20190 append_stretch_glyph (it, object, width, height, ascent)
20191 struct it *it;
20192 Lisp_Object object;
20193 int width, height;
20194 int ascent;
20196 struct glyph *glyph;
20197 enum glyph_row_area area = it->area;
20199 xassert (ascent >= 0 && ascent <= height);
20201 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
20202 if (glyph < it->glyph_row->glyphs[area + 1])
20204 glyph->charpos = CHARPOS (it->position);
20205 glyph->object = object;
20206 glyph->pixel_width = width;
20207 glyph->ascent = ascent;
20208 glyph->descent = height - ascent;
20209 glyph->voffset = it->voffset;
20210 glyph->type = STRETCH_GLYPH;
20211 glyph->multibyte_p = it->multibyte_p;
20212 glyph->left_box_line_p = it->start_of_box_run_p;
20213 glyph->right_box_line_p = it->end_of_box_run_p;
20214 glyph->overlaps_vertically_p = 0;
20215 glyph->padding_p = 0;
20216 glyph->glyph_not_available_p = 0;
20217 glyph->face_id = it->face_id;
20218 glyph->u.stretch.ascent = ascent;
20219 glyph->u.stretch.height = height;
20220 glyph->slice = null_glyph_slice;
20221 glyph->font_type = FONT_TYPE_UNKNOWN;
20222 ++it->glyph_row->used[area];
20224 else
20225 IT_EXPAND_MATRIX_WIDTH (it, area);
20229 /* Produce a stretch glyph for iterator IT. IT->object is the value
20230 of the glyph property displayed. The value must be a list
20231 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
20232 being recognized:
20234 1. `:width WIDTH' specifies that the space should be WIDTH *
20235 canonical char width wide. WIDTH may be an integer or floating
20236 point number.
20238 2. `:relative-width FACTOR' specifies that the width of the stretch
20239 should be computed from the width of the first character having the
20240 `glyph' property, and should be FACTOR times that width.
20242 3. `:align-to HPOS' specifies that the space should be wide enough
20243 to reach HPOS, a value in canonical character units.
20245 Exactly one of the above pairs must be present.
20247 4. `:height HEIGHT' specifies that the height of the stretch produced
20248 should be HEIGHT, measured in canonical character units.
20250 5. `:relative-height FACTOR' specifies that the height of the
20251 stretch should be FACTOR times the height of the characters having
20252 the glyph property.
20254 Either none or exactly one of 4 or 5 must be present.
20256 6. `:ascent ASCENT' specifies that ASCENT percent of the height
20257 of the stretch should be used for the ascent of the stretch.
20258 ASCENT must be in the range 0 <= ASCENT <= 100. */
20260 static void
20261 produce_stretch_glyph (it)
20262 struct it *it;
20264 /* (space :width WIDTH :height HEIGHT ...) */
20265 Lisp_Object prop, plist;
20266 int width = 0, height = 0, align_to = -1;
20267 int zero_width_ok_p = 0, zero_height_ok_p = 0;
20268 int ascent = 0;
20269 double tem;
20270 struct face *face = FACE_FROM_ID (it->f, it->face_id);
20271 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
20273 PREPARE_FACE_FOR_DISPLAY (it->f, face);
20275 /* List should start with `space'. */
20276 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
20277 plist = XCDR (it->object);
20279 /* Compute the width of the stretch. */
20280 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
20281 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
20283 /* Absolute width `:width WIDTH' specified and valid. */
20284 zero_width_ok_p = 1;
20285 width = (int)tem;
20287 else if (prop = Fplist_get (plist, QCrelative_width),
20288 NUMVAL (prop) > 0)
20290 /* Relative width `:relative-width FACTOR' specified and valid.
20291 Compute the width of the characters having the `glyph'
20292 property. */
20293 struct it it2;
20294 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
20296 it2 = *it;
20297 if (it->multibyte_p)
20299 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
20300 - IT_BYTEPOS (*it));
20301 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
20303 else
20304 it2.c = *p, it2.len = 1;
20306 it2.glyph_row = NULL;
20307 it2.what = IT_CHARACTER;
20308 x_produce_glyphs (&it2);
20309 width = NUMVAL (prop) * it2.pixel_width;
20311 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
20312 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
20314 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
20315 align_to = (align_to < 0
20317 : align_to - window_box_left_offset (it->w, TEXT_AREA));
20318 else if (align_to < 0)
20319 align_to = window_box_left_offset (it->w, TEXT_AREA);
20320 width = max (0, (int)tem + align_to - it->current_x);
20321 zero_width_ok_p = 1;
20323 else
20324 /* Nothing specified -> width defaults to canonical char width. */
20325 width = FRAME_COLUMN_WIDTH (it->f);
20327 if (width <= 0 && (width < 0 || !zero_width_ok_p))
20328 width = 1;
20330 /* Compute height. */
20331 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
20332 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
20334 height = (int)tem;
20335 zero_height_ok_p = 1;
20337 else if (prop = Fplist_get (plist, QCrelative_height),
20338 NUMVAL (prop) > 0)
20339 height = FONT_HEIGHT (font) * NUMVAL (prop);
20340 else
20341 height = FONT_HEIGHT (font);
20343 if (height <= 0 && (height < 0 || !zero_height_ok_p))
20344 height = 1;
20346 /* Compute percentage of height used for ascent. If
20347 `:ascent ASCENT' is present and valid, use that. Otherwise,
20348 derive the ascent from the font in use. */
20349 if (prop = Fplist_get (plist, QCascent),
20350 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
20351 ascent = height * NUMVAL (prop) / 100.0;
20352 else if (!NILP (prop)
20353 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
20354 ascent = min (max (0, (int)tem), height);
20355 else
20356 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
20358 if (width > 0 && !it->truncate_lines_p
20359 && it->current_x + width > it->last_visible_x)
20360 width = it->last_visible_x - it->current_x - 1;
20362 if (width > 0 && height > 0 && it->glyph_row)
20364 Lisp_Object object = it->stack[it->sp - 1].string;
20365 if (!STRINGP (object))
20366 object = it->w->buffer;
20367 append_stretch_glyph (it, object, width, height, ascent);
20370 it->pixel_width = width;
20371 it->ascent = it->phys_ascent = ascent;
20372 it->descent = it->phys_descent = height - it->ascent;
20373 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
20375 take_vertical_position_into_account (it);
20378 /* Get line-height and line-spacing property at point.
20379 If line-height has format (HEIGHT TOTAL), return TOTAL
20380 in TOTAL_HEIGHT. */
20382 static Lisp_Object
20383 get_line_height_property (it, prop)
20384 struct it *it;
20385 Lisp_Object prop;
20387 Lisp_Object position;
20389 if (STRINGP (it->object))
20390 position = make_number (IT_STRING_CHARPOS (*it));
20391 else if (BUFFERP (it->object))
20392 position = make_number (IT_CHARPOS (*it));
20393 else
20394 return Qnil;
20396 return Fget_char_property (position, prop, it->object);
20399 /* Calculate line-height and line-spacing properties.
20400 An integer value specifies explicit pixel value.
20401 A float value specifies relative value to current face height.
20402 A cons (float . face-name) specifies relative value to
20403 height of specified face font.
20405 Returns height in pixels, or nil. */
20408 static Lisp_Object
20409 calc_line_height_property (it, val, font, boff, override)
20410 struct it *it;
20411 Lisp_Object val;
20412 XFontStruct *font;
20413 int boff, override;
20415 Lisp_Object face_name = Qnil;
20416 int ascent, descent, height;
20418 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
20419 return val;
20421 if (CONSP (val))
20423 face_name = XCAR (val);
20424 val = XCDR (val);
20425 if (!NUMBERP (val))
20426 val = make_number (1);
20427 if (NILP (face_name))
20429 height = it->ascent + it->descent;
20430 goto scale;
20434 if (NILP (face_name))
20436 font = FRAME_FONT (it->f);
20437 boff = FRAME_BASELINE_OFFSET (it->f);
20439 else if (EQ (face_name, Qt))
20441 override = 0;
20443 else
20445 int face_id;
20446 struct face *face;
20447 struct font_info *font_info;
20449 face_id = lookup_named_face (it->f, face_name, ' ', 0);
20450 if (face_id < 0)
20451 return make_number (-1);
20453 face = FACE_FROM_ID (it->f, face_id);
20454 font = face->font;
20455 if (font == NULL)
20456 return make_number (-1);
20458 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
20459 boff = font_info->baseline_offset;
20460 if (font_info->vertical_centering)
20461 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
20464 ascent = FONT_BASE (font) + boff;
20465 descent = FONT_DESCENT (font) - boff;
20467 if (override)
20469 it->override_ascent = ascent;
20470 it->override_descent = descent;
20471 it->override_boff = boff;
20474 height = ascent + descent;
20476 scale:
20477 if (FLOATP (val))
20478 height = (int)(XFLOAT_DATA (val) * height);
20479 else if (INTEGERP (val))
20480 height *= XINT (val);
20482 return make_number (height);
20486 /* RIF:
20487 Produce glyphs/get display metrics for the display element IT is
20488 loaded with. See the description of struct it in dispextern.h
20489 for an overview of struct it. */
20491 void
20492 x_produce_glyphs (it)
20493 struct it *it;
20495 int extra_line_spacing = it->extra_line_spacing;
20497 it->glyph_not_available_p = 0;
20499 if (it->what == IT_CHARACTER)
20501 XChar2b char2b;
20502 XFontStruct *font;
20503 struct face *face = FACE_FROM_ID (it->f, it->face_id);
20504 XCharStruct *pcm;
20505 int font_not_found_p;
20506 struct font_info *font_info;
20507 int boff; /* baseline offset */
20508 /* We may change it->multibyte_p upon unibyte<->multibyte
20509 conversion. So, save the current value now and restore it
20510 later.
20512 Note: It seems that we don't have to record multibyte_p in
20513 struct glyph because the character code itself tells if or
20514 not the character is multibyte. Thus, in the future, we must
20515 consider eliminating the field `multibyte_p' in the struct
20516 glyph. */
20517 int saved_multibyte_p = it->multibyte_p;
20519 /* Maybe translate single-byte characters to multibyte, or the
20520 other way. */
20521 it->char_to_display = it->c;
20522 if (!ASCII_BYTE_P (it->c))
20524 if (unibyte_display_via_language_environment
20525 && SINGLE_BYTE_CHAR_P (it->c)
20526 && (it->c >= 0240
20527 || !NILP (Vnonascii_translation_table)))
20529 it->char_to_display = unibyte_char_to_multibyte (it->c);
20530 it->multibyte_p = 1;
20531 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
20532 face = FACE_FROM_ID (it->f, it->face_id);
20534 else if (!SINGLE_BYTE_CHAR_P (it->c)
20535 && !it->multibyte_p)
20537 it->multibyte_p = 1;
20538 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
20539 face = FACE_FROM_ID (it->f, it->face_id);
20543 /* Get font to use. Encode IT->char_to_display. */
20544 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
20545 &char2b, it->multibyte_p, 0);
20546 font = face->font;
20548 /* When no suitable font found, use the default font. */
20549 font_not_found_p = font == NULL;
20550 if (font_not_found_p)
20552 font = FRAME_FONT (it->f);
20553 boff = FRAME_BASELINE_OFFSET (it->f);
20554 font_info = NULL;
20556 else
20558 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
20559 boff = font_info->baseline_offset;
20560 if (font_info->vertical_centering)
20561 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
20564 if (it->char_to_display >= ' '
20565 && (!it->multibyte_p || it->char_to_display < 128))
20567 /* Either unibyte or ASCII. */
20568 int stretched_p;
20570 it->nglyphs = 1;
20572 pcm = FRAME_RIF (it->f)->per_char_metric
20573 (font, &char2b, FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
20575 if (it->override_ascent >= 0)
20577 it->ascent = it->override_ascent;
20578 it->descent = it->override_descent;
20579 boff = it->override_boff;
20581 else
20583 it->ascent = FONT_BASE (font) + boff;
20584 it->descent = FONT_DESCENT (font) - boff;
20587 if (pcm)
20589 it->phys_ascent = pcm->ascent + boff;
20590 it->phys_descent = pcm->descent - boff;
20591 it->pixel_width = pcm->width;
20593 else
20595 it->glyph_not_available_p = 1;
20596 it->phys_ascent = it->ascent;
20597 it->phys_descent = it->descent;
20598 it->pixel_width = FONT_WIDTH (font);
20601 if (it->constrain_row_ascent_descent_p)
20603 if (it->descent > it->max_descent)
20605 it->ascent += it->descent - it->max_descent;
20606 it->descent = it->max_descent;
20608 if (it->ascent > it->max_ascent)
20610 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
20611 it->ascent = it->max_ascent;
20613 it->phys_ascent = min (it->phys_ascent, it->ascent);
20614 it->phys_descent = min (it->phys_descent, it->descent);
20615 extra_line_spacing = 0;
20618 /* If this is a space inside a region of text with
20619 `space-width' property, change its width. */
20620 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
20621 if (stretched_p)
20622 it->pixel_width *= XFLOATINT (it->space_width);
20624 /* If face has a box, add the box thickness to the character
20625 height. If character has a box line to the left and/or
20626 right, add the box line width to the character's width. */
20627 if (face->box != FACE_NO_BOX)
20629 int thick = face->box_line_width;
20631 if (thick > 0)
20633 it->ascent += thick;
20634 it->descent += thick;
20636 else
20637 thick = -thick;
20639 if (it->start_of_box_run_p)
20640 it->pixel_width += thick;
20641 if (it->end_of_box_run_p)
20642 it->pixel_width += thick;
20645 /* If face has an overline, add the height of the overline
20646 (1 pixel) and a 1 pixel margin to the character height. */
20647 if (face->overline_p)
20648 it->ascent += overline_margin;
20650 if (it->constrain_row_ascent_descent_p)
20652 if (it->ascent > it->max_ascent)
20653 it->ascent = it->max_ascent;
20654 if (it->descent > it->max_descent)
20655 it->descent = it->max_descent;
20658 take_vertical_position_into_account (it);
20660 /* If we have to actually produce glyphs, do it. */
20661 if (it->glyph_row)
20663 if (stretched_p)
20665 /* Translate a space with a `space-width' property
20666 into a stretch glyph. */
20667 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
20668 / FONT_HEIGHT (font));
20669 append_stretch_glyph (it, it->object, it->pixel_width,
20670 it->ascent + it->descent, ascent);
20672 else
20673 append_glyph (it);
20675 /* If characters with lbearing or rbearing are displayed
20676 in this line, record that fact in a flag of the
20677 glyph row. This is used to optimize X output code. */
20678 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
20679 it->glyph_row->contains_overlapping_glyphs_p = 1;
20682 else if (it->char_to_display == '\n')
20684 /* A newline has no width but we need the height of the line.
20685 But if previous part of the line set a height, don't
20686 increase that height */
20688 Lisp_Object height;
20689 Lisp_Object total_height = Qnil;
20691 it->override_ascent = -1;
20692 it->pixel_width = 0;
20693 it->nglyphs = 0;
20695 height = get_line_height_property(it, Qline_height);
20696 /* Split (line-height total-height) list */
20697 if (CONSP (height)
20698 && CONSP (XCDR (height))
20699 && NILP (XCDR (XCDR (height))))
20701 total_height = XCAR (XCDR (height));
20702 height = XCAR (height);
20704 height = calc_line_height_property(it, height, font, boff, 1);
20706 if (it->override_ascent >= 0)
20708 it->ascent = it->override_ascent;
20709 it->descent = it->override_descent;
20710 boff = it->override_boff;
20712 else
20714 it->ascent = FONT_BASE (font) + boff;
20715 it->descent = FONT_DESCENT (font) - boff;
20718 if (EQ (height, Qt))
20720 if (it->descent > it->max_descent)
20722 it->ascent += it->descent - it->max_descent;
20723 it->descent = it->max_descent;
20725 if (it->ascent > it->max_ascent)
20727 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
20728 it->ascent = it->max_ascent;
20730 it->phys_ascent = min (it->phys_ascent, it->ascent);
20731 it->phys_descent = min (it->phys_descent, it->descent);
20732 it->constrain_row_ascent_descent_p = 1;
20733 extra_line_spacing = 0;
20735 else
20737 Lisp_Object spacing;
20739 it->phys_ascent = it->ascent;
20740 it->phys_descent = it->descent;
20742 if ((it->max_ascent > 0 || it->max_descent > 0)
20743 && face->box != FACE_NO_BOX
20744 && face->box_line_width > 0)
20746 it->ascent += face->box_line_width;
20747 it->descent += face->box_line_width;
20749 if (!NILP (height)
20750 && XINT (height) > it->ascent + it->descent)
20751 it->ascent = XINT (height) - it->descent;
20753 if (!NILP (total_height))
20754 spacing = calc_line_height_property(it, total_height, font, boff, 0);
20755 else
20757 spacing = get_line_height_property(it, Qline_spacing);
20758 spacing = calc_line_height_property(it, spacing, font, boff, 0);
20760 if (INTEGERP (spacing))
20762 extra_line_spacing = XINT (spacing);
20763 if (!NILP (total_height))
20764 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
20768 else if (it->char_to_display == '\t')
20770 int tab_width = it->tab_width * FRAME_SPACE_WIDTH (it->f);
20771 int x = it->current_x + it->continuation_lines_width;
20772 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
20774 /* If the distance from the current position to the next tab
20775 stop is less than a space character width, use the
20776 tab stop after that. */
20777 if (next_tab_x - x < FRAME_SPACE_WIDTH (it->f))
20778 next_tab_x += tab_width;
20780 it->pixel_width = next_tab_x - x;
20781 it->nglyphs = 1;
20782 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
20783 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
20785 if (it->glyph_row)
20787 append_stretch_glyph (it, it->object, it->pixel_width,
20788 it->ascent + it->descent, it->ascent);
20791 else
20793 /* A multi-byte character. Assume that the display width of the
20794 character is the width of the character multiplied by the
20795 width of the font. */
20797 /* If we found a font, this font should give us the right
20798 metrics. If we didn't find a font, use the frame's
20799 default font and calculate the width of the character
20800 from the charset width; this is what old redisplay code
20801 did. */
20803 pcm = FRAME_RIF (it->f)->per_char_metric (font, &char2b,
20804 FONT_TYPE_FOR_MULTIBYTE (font, it->c));
20806 if (font_not_found_p || !pcm)
20808 int charset = CHAR_CHARSET (it->char_to_display);
20810 it->glyph_not_available_p = 1;
20811 it->pixel_width = (FRAME_COLUMN_WIDTH (it->f)
20812 * CHARSET_WIDTH (charset));
20813 it->phys_ascent = FONT_BASE (font) + boff;
20814 it->phys_descent = FONT_DESCENT (font) - boff;
20816 else
20818 it->pixel_width = pcm->width;
20819 it->phys_ascent = pcm->ascent + boff;
20820 it->phys_descent = pcm->descent - boff;
20821 if (it->glyph_row
20822 && (pcm->lbearing < 0
20823 || pcm->rbearing > pcm->width))
20824 it->glyph_row->contains_overlapping_glyphs_p = 1;
20826 it->nglyphs = 1;
20827 it->ascent = FONT_BASE (font) + boff;
20828 it->descent = FONT_DESCENT (font) - boff;
20829 if (face->box != FACE_NO_BOX)
20831 int thick = face->box_line_width;
20833 if (thick > 0)
20835 it->ascent += thick;
20836 it->descent += thick;
20838 else
20839 thick = - thick;
20841 if (it->start_of_box_run_p)
20842 it->pixel_width += thick;
20843 if (it->end_of_box_run_p)
20844 it->pixel_width += thick;
20847 /* If face has an overline, add the height of the overline
20848 (1 pixel) and a 1 pixel margin to the character height. */
20849 if (face->overline_p)
20850 it->ascent += overline_margin;
20852 take_vertical_position_into_account (it);
20854 if (it->glyph_row)
20855 append_glyph (it);
20857 it->multibyte_p = saved_multibyte_p;
20859 else if (it->what == IT_COMPOSITION)
20861 /* Note: A composition is represented as one glyph in the
20862 glyph matrix. There are no padding glyphs. */
20863 XChar2b char2b;
20864 XFontStruct *font;
20865 struct face *face = FACE_FROM_ID (it->f, it->face_id);
20866 XCharStruct *pcm;
20867 int font_not_found_p;
20868 struct font_info *font_info;
20869 int boff; /* baseline offset */
20870 struct composition *cmp = composition_table[it->cmp_id];
20872 /* Maybe translate single-byte characters to multibyte. */
20873 it->char_to_display = it->c;
20874 if (unibyte_display_via_language_environment
20875 && SINGLE_BYTE_CHAR_P (it->c)
20876 && (it->c >= 0240
20877 || (it->c >= 0200
20878 && !NILP (Vnonascii_translation_table))))
20880 it->char_to_display = unibyte_char_to_multibyte (it->c);
20883 /* Get face and font to use. Encode IT->char_to_display. */
20884 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
20885 face = FACE_FROM_ID (it->f, it->face_id);
20886 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
20887 &char2b, it->multibyte_p, 0);
20888 font = face->font;
20890 /* When no suitable font found, use the default font. */
20891 font_not_found_p = font == NULL;
20892 if (font_not_found_p)
20894 font = FRAME_FONT (it->f);
20895 boff = FRAME_BASELINE_OFFSET (it->f);
20896 font_info = NULL;
20898 else
20900 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
20901 boff = font_info->baseline_offset;
20902 if (font_info->vertical_centering)
20903 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
20906 /* There are no padding glyphs, so there is only one glyph to
20907 produce for the composition. Important is that pixel_width,
20908 ascent and descent are the values of what is drawn by
20909 draw_glyphs (i.e. the values of the overall glyphs composed). */
20910 it->nglyphs = 1;
20912 /* If we have not yet calculated pixel size data of glyphs of
20913 the composition for the current face font, calculate them
20914 now. Theoretically, we have to check all fonts for the
20915 glyphs, but that requires much time and memory space. So,
20916 here we check only the font of the first glyph. This leads
20917 to incorrect display very rarely, and C-l (recenter) can
20918 correct the display anyway. */
20919 if (cmp->font != (void *) font)
20921 /* Ascent and descent of the font of the first character of
20922 this composition (adjusted by baseline offset). Ascent
20923 and descent of overall glyphs should not be less than
20924 them respectively. */
20925 int font_ascent = FONT_BASE (font) + boff;
20926 int font_descent = FONT_DESCENT (font) - boff;
20927 /* Bounding box of the overall glyphs. */
20928 int leftmost, rightmost, lowest, highest;
20929 int i, width, ascent, descent;
20931 cmp->font = (void *) font;
20933 /* Initialize the bounding box. */
20934 if (font_info
20935 && (pcm = FRAME_RIF (it->f)->per_char_metric (font, &char2b,
20936 FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
20938 width = pcm->width;
20939 ascent = pcm->ascent;
20940 descent = pcm->descent;
20942 else
20944 width = FONT_WIDTH (font);
20945 ascent = FONT_BASE (font);
20946 descent = FONT_DESCENT (font);
20949 rightmost = width;
20950 lowest = - descent + boff;
20951 highest = ascent + boff;
20952 leftmost = 0;
20954 if (font_info
20955 && font_info->default_ascent
20956 && CHAR_TABLE_P (Vuse_default_ascent)
20957 && !NILP (Faref (Vuse_default_ascent,
20958 make_number (it->char_to_display))))
20959 highest = font_info->default_ascent + boff;
20961 /* Draw the first glyph at the normal position. It may be
20962 shifted to right later if some other glyphs are drawn at
20963 the left. */
20964 cmp->offsets[0] = 0;
20965 cmp->offsets[1] = boff;
20967 /* Set cmp->offsets for the remaining glyphs. */
20968 for (i = 1; i < cmp->glyph_len; i++)
20970 int left, right, btm, top;
20971 int ch = COMPOSITION_GLYPH (cmp, i);
20972 int face_id = FACE_FOR_CHAR (it->f, face, ch);
20974 face = FACE_FROM_ID (it->f, face_id);
20975 get_char_face_and_encoding (it->f, ch, face->id,
20976 &char2b, it->multibyte_p, 0);
20977 font = face->font;
20978 if (font == NULL)
20980 font = FRAME_FONT (it->f);
20981 boff = FRAME_BASELINE_OFFSET (it->f);
20982 font_info = NULL;
20984 else
20986 font_info
20987 = FONT_INFO_FROM_ID (it->f, face->font_info_id);
20988 boff = font_info->baseline_offset;
20989 if (font_info->vertical_centering)
20990 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
20993 if (font_info
20994 && (pcm = FRAME_RIF (it->f)->per_char_metric (font, &char2b,
20995 FONT_TYPE_FOR_MULTIBYTE (font, ch))))
20997 width = pcm->width;
20998 ascent = pcm->ascent;
20999 descent = pcm->descent;
21001 else
21003 width = FONT_WIDTH (font);
21004 ascent = 1;
21005 descent = 0;
21008 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
21010 /* Relative composition with or without
21011 alternate chars. */
21012 left = (leftmost + rightmost - width) / 2;
21013 btm = - descent + boff;
21014 if (font_info && font_info->relative_compose
21015 && (! CHAR_TABLE_P (Vignore_relative_composition)
21016 || NILP (Faref (Vignore_relative_composition,
21017 make_number (ch)))))
21020 if (- descent >= font_info->relative_compose)
21021 /* One extra pixel between two glyphs. */
21022 btm = highest + 1;
21023 else if (ascent <= 0)
21024 /* One extra pixel between two glyphs. */
21025 btm = lowest - 1 - ascent - descent;
21028 else
21030 /* A composition rule is specified by an integer
21031 value that encodes global and new reference
21032 points (GREF and NREF). GREF and NREF are
21033 specified by numbers as below:
21035 0---1---2 -- ascent
21039 9--10--11 -- center
21041 ---3---4---5--- baseline
21043 6---7---8 -- descent
21045 int rule = COMPOSITION_RULE (cmp, i);
21046 int gref, nref, grefx, grefy, nrefx, nrefy;
21048 COMPOSITION_DECODE_RULE (rule, gref, nref);
21049 grefx = gref % 3, nrefx = nref % 3;
21050 grefy = gref / 3, nrefy = nref / 3;
21052 left = (leftmost
21053 + grefx * (rightmost - leftmost) / 2
21054 - nrefx * width / 2);
21055 btm = ((grefy == 0 ? highest
21056 : grefy == 1 ? 0
21057 : grefy == 2 ? lowest
21058 : (highest + lowest) / 2)
21059 - (nrefy == 0 ? ascent + descent
21060 : nrefy == 1 ? descent - boff
21061 : nrefy == 2 ? 0
21062 : (ascent + descent) / 2));
21065 cmp->offsets[i * 2] = left;
21066 cmp->offsets[i * 2 + 1] = btm + descent;
21068 /* Update the bounding box of the overall glyphs. */
21069 right = left + width;
21070 top = btm + descent + ascent;
21071 if (left < leftmost)
21072 leftmost = left;
21073 if (right > rightmost)
21074 rightmost = right;
21075 if (top > highest)
21076 highest = top;
21077 if (btm < lowest)
21078 lowest = btm;
21081 /* If there are glyphs whose x-offsets are negative,
21082 shift all glyphs to the right and make all x-offsets
21083 non-negative. */
21084 if (leftmost < 0)
21086 for (i = 0; i < cmp->glyph_len; i++)
21087 cmp->offsets[i * 2] -= leftmost;
21088 rightmost -= leftmost;
21091 cmp->pixel_width = rightmost;
21092 cmp->ascent = highest;
21093 cmp->descent = - lowest;
21094 if (cmp->ascent < font_ascent)
21095 cmp->ascent = font_ascent;
21096 if (cmp->descent < font_descent)
21097 cmp->descent = font_descent;
21100 it->pixel_width = cmp->pixel_width;
21101 it->ascent = it->phys_ascent = cmp->ascent;
21102 it->descent = it->phys_descent = cmp->descent;
21104 if (face->box != FACE_NO_BOX)
21106 int thick = face->box_line_width;
21108 if (thick > 0)
21110 it->ascent += thick;
21111 it->descent += thick;
21113 else
21114 thick = - thick;
21116 if (it->start_of_box_run_p)
21117 it->pixel_width += thick;
21118 if (it->end_of_box_run_p)
21119 it->pixel_width += thick;
21122 /* If face has an overline, add the height of the overline
21123 (1 pixel) and a 1 pixel margin to the character height. */
21124 if (face->overline_p)
21125 it->ascent += overline_margin;
21127 take_vertical_position_into_account (it);
21129 if (it->glyph_row)
21130 append_composite_glyph (it);
21132 else if (it->what == IT_IMAGE)
21133 produce_image_glyph (it);
21134 else if (it->what == IT_STRETCH)
21135 produce_stretch_glyph (it);
21137 /* Accumulate dimensions. Note: can't assume that it->descent > 0
21138 because this isn't true for images with `:ascent 100'. */
21139 xassert (it->ascent >= 0 && it->descent >= 0);
21140 if (it->area == TEXT_AREA)
21141 it->current_x += it->pixel_width;
21143 if (extra_line_spacing > 0)
21145 it->descent += extra_line_spacing;
21146 if (extra_line_spacing > it->max_extra_line_spacing)
21147 it->max_extra_line_spacing = extra_line_spacing;
21150 it->max_ascent = max (it->max_ascent, it->ascent);
21151 it->max_descent = max (it->max_descent, it->descent);
21152 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
21153 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
21156 /* EXPORT for RIF:
21157 Output LEN glyphs starting at START at the nominal cursor position.
21158 Advance the nominal cursor over the text. The global variable
21159 updated_window contains the window being updated, updated_row is
21160 the glyph row being updated, and updated_area is the area of that
21161 row being updated. */
21163 void
21164 x_write_glyphs (start, len)
21165 struct glyph *start;
21166 int len;
21168 int x, hpos;
21170 xassert (updated_window && updated_row);
21171 BLOCK_INPUT;
21173 /* Write glyphs. */
21175 hpos = start - updated_row->glyphs[updated_area];
21176 x = draw_glyphs (updated_window, output_cursor.x,
21177 updated_row, updated_area,
21178 hpos, hpos + len,
21179 DRAW_NORMAL_TEXT, 0);
21181 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
21182 if (updated_area == TEXT_AREA
21183 && updated_window->phys_cursor_on_p
21184 && updated_window->phys_cursor.vpos == output_cursor.vpos
21185 && updated_window->phys_cursor.hpos >= hpos
21186 && updated_window->phys_cursor.hpos < hpos + len)
21187 updated_window->phys_cursor_on_p = 0;
21189 UNBLOCK_INPUT;
21191 /* Advance the output cursor. */
21192 output_cursor.hpos += len;
21193 output_cursor.x = x;
21197 /* EXPORT for RIF:
21198 Insert LEN glyphs from START at the nominal cursor position. */
21200 void
21201 x_insert_glyphs (start, len)
21202 struct glyph *start;
21203 int len;
21205 struct frame *f;
21206 struct window *w;
21207 int line_height, shift_by_width, shifted_region_width;
21208 struct glyph_row *row;
21209 struct glyph *glyph;
21210 int frame_x, frame_y, hpos;
21212 xassert (updated_window && updated_row);
21213 BLOCK_INPUT;
21214 w = updated_window;
21215 f = XFRAME (WINDOW_FRAME (w));
21217 /* Get the height of the line we are in. */
21218 row = updated_row;
21219 line_height = row->height;
21221 /* Get the width of the glyphs to insert. */
21222 shift_by_width = 0;
21223 for (glyph = start; glyph < start + len; ++glyph)
21224 shift_by_width += glyph->pixel_width;
21226 /* Get the width of the region to shift right. */
21227 shifted_region_width = (window_box_width (w, updated_area)
21228 - output_cursor.x
21229 - shift_by_width);
21231 /* Shift right. */
21232 frame_x = window_box_left (w, updated_area) + output_cursor.x;
21233 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
21235 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
21236 line_height, shift_by_width);
21238 /* Write the glyphs. */
21239 hpos = start - row->glyphs[updated_area];
21240 draw_glyphs (w, output_cursor.x, row, updated_area,
21241 hpos, hpos + len,
21242 DRAW_NORMAL_TEXT, 0);
21244 /* Advance the output cursor. */
21245 output_cursor.hpos += len;
21246 output_cursor.x += shift_by_width;
21247 UNBLOCK_INPUT;
21251 /* EXPORT for RIF:
21252 Erase the current text line from the nominal cursor position
21253 (inclusive) to pixel column TO_X (exclusive). The idea is that
21254 everything from TO_X onward is already erased.
21256 TO_X is a pixel position relative to updated_area of
21257 updated_window. TO_X == -1 means clear to the end of this area. */
21259 void
21260 x_clear_end_of_line (to_x)
21261 int to_x;
21263 struct frame *f;
21264 struct window *w = updated_window;
21265 int max_x, min_y, max_y;
21266 int from_x, from_y, to_y;
21268 xassert (updated_window && updated_row);
21269 f = XFRAME (w->frame);
21271 if (updated_row->full_width_p)
21272 max_x = WINDOW_TOTAL_WIDTH (w);
21273 else
21274 max_x = window_box_width (w, updated_area);
21275 max_y = window_text_bottom_y (w);
21277 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
21278 of window. For TO_X > 0, truncate to end of drawing area. */
21279 if (to_x == 0)
21280 return;
21281 else if (to_x < 0)
21282 to_x = max_x;
21283 else
21284 to_x = min (to_x, max_x);
21286 to_y = min (max_y, output_cursor.y + updated_row->height);
21288 /* Notice if the cursor will be cleared by this operation. */
21289 if (!updated_row->full_width_p)
21290 notice_overwritten_cursor (w, updated_area,
21291 output_cursor.x, -1,
21292 updated_row->y,
21293 MATRIX_ROW_BOTTOM_Y (updated_row));
21295 from_x = output_cursor.x;
21297 /* Translate to frame coordinates. */
21298 if (updated_row->full_width_p)
21300 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
21301 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
21303 else
21305 int area_left = window_box_left (w, updated_area);
21306 from_x += area_left;
21307 to_x += area_left;
21310 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
21311 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
21312 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
21314 /* Prevent inadvertently clearing to end of the X window. */
21315 if (to_x > from_x && to_y > from_y)
21317 BLOCK_INPUT;
21318 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
21319 to_x - from_x, to_y - from_y);
21320 UNBLOCK_INPUT;
21324 #endif /* HAVE_WINDOW_SYSTEM */
21328 /***********************************************************************
21329 Cursor types
21330 ***********************************************************************/
21332 /* Value is the internal representation of the specified cursor type
21333 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
21334 of the bar cursor. */
21336 static enum text_cursor_kinds
21337 get_specified_cursor_type (arg, width)
21338 Lisp_Object arg;
21339 int *width;
21341 enum text_cursor_kinds type;
21343 if (NILP (arg))
21344 return NO_CURSOR;
21346 if (EQ (arg, Qbox))
21347 return FILLED_BOX_CURSOR;
21349 if (EQ (arg, Qhollow))
21350 return HOLLOW_BOX_CURSOR;
21352 if (EQ (arg, Qbar))
21354 *width = 2;
21355 return BAR_CURSOR;
21358 if (CONSP (arg)
21359 && EQ (XCAR (arg), Qbar)
21360 && INTEGERP (XCDR (arg))
21361 && XINT (XCDR (arg)) >= 0)
21363 *width = XINT (XCDR (arg));
21364 return BAR_CURSOR;
21367 if (EQ (arg, Qhbar))
21369 *width = 2;
21370 return HBAR_CURSOR;
21373 if (CONSP (arg)
21374 && EQ (XCAR (arg), Qhbar)
21375 && INTEGERP (XCDR (arg))
21376 && XINT (XCDR (arg)) >= 0)
21378 *width = XINT (XCDR (arg));
21379 return HBAR_CURSOR;
21382 /* Treat anything unknown as "hollow box cursor".
21383 It was bad to signal an error; people have trouble fixing
21384 .Xdefaults with Emacs, when it has something bad in it. */
21385 type = HOLLOW_BOX_CURSOR;
21387 return type;
21390 /* Set the default cursor types for specified frame. */
21391 void
21392 set_frame_cursor_types (f, arg)
21393 struct frame *f;
21394 Lisp_Object arg;
21396 int width;
21397 Lisp_Object tem;
21399 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
21400 FRAME_CURSOR_WIDTH (f) = width;
21402 /* By default, set up the blink-off state depending on the on-state. */
21404 tem = Fassoc (arg, Vblink_cursor_alist);
21405 if (!NILP (tem))
21407 FRAME_BLINK_OFF_CURSOR (f)
21408 = get_specified_cursor_type (XCDR (tem), &width);
21409 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
21411 else
21412 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
21416 /* Return the cursor we want to be displayed in window W. Return
21417 width of bar/hbar cursor through WIDTH arg. Return with
21418 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
21419 (i.e. if the `system caret' should track this cursor).
21421 In a mini-buffer window, we want the cursor only to appear if we
21422 are reading input from this window. For the selected window, we
21423 want the cursor type given by the frame parameter or buffer local
21424 setting of cursor-type. If explicitly marked off, draw no cursor.
21425 In all other cases, we want a hollow box cursor. */
21427 static enum text_cursor_kinds
21428 get_window_cursor_type (w, glyph, width, active_cursor)
21429 struct window *w;
21430 struct glyph *glyph;
21431 int *width;
21432 int *active_cursor;
21434 struct frame *f = XFRAME (w->frame);
21435 struct buffer *b = XBUFFER (w->buffer);
21436 int cursor_type = DEFAULT_CURSOR;
21437 Lisp_Object alt_cursor;
21438 int non_selected = 0;
21440 *active_cursor = 1;
21442 /* Echo area */
21443 if (cursor_in_echo_area
21444 && FRAME_HAS_MINIBUF_P (f)
21445 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
21447 if (w == XWINDOW (echo_area_window))
21449 if (EQ (b->cursor_type, Qt) || NILP (b->cursor_type))
21451 *width = FRAME_CURSOR_WIDTH (f);
21452 return FRAME_DESIRED_CURSOR (f);
21454 else
21455 return get_specified_cursor_type (b->cursor_type, width);
21458 *active_cursor = 0;
21459 non_selected = 1;
21462 /* Detect a nonselected window or nonselected frame. */
21463 else if (w != XWINDOW (f->selected_window)
21464 #ifdef HAVE_WINDOW_SYSTEM
21465 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
21466 #endif
21469 *active_cursor = 0;
21471 if (MINI_WINDOW_P (w) && minibuf_level == 0)
21472 return NO_CURSOR;
21474 non_selected = 1;
21477 /* Never display a cursor in a window in which cursor-type is nil. */
21478 if (NILP (b->cursor_type))
21479 return NO_CURSOR;
21481 /* Get the normal cursor type for this window. */
21482 if (EQ (b->cursor_type, Qt))
21484 cursor_type = FRAME_DESIRED_CURSOR (f);
21485 *width = FRAME_CURSOR_WIDTH (f);
21487 else
21488 cursor_type = get_specified_cursor_type (b->cursor_type, width);
21490 /* Use cursor-in-non-selected-windows instead
21491 for non-selected window or frame. */
21492 if (non_selected)
21494 alt_cursor = b->cursor_in_non_selected_windows;
21495 if (!EQ (Qt, alt_cursor))
21496 return get_specified_cursor_type (alt_cursor, width);
21497 /* t means modify the normal cursor type. */
21498 if (cursor_type == FILLED_BOX_CURSOR)
21499 cursor_type = HOLLOW_BOX_CURSOR;
21500 else if (cursor_type == BAR_CURSOR && *width > 1)
21501 --*width;
21502 return cursor_type;
21505 /* Use normal cursor if not blinked off. */
21506 if (!w->cursor_off_p)
21508 #ifdef HAVE_WINDOW_SYSTEM
21509 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
21511 if (cursor_type == FILLED_BOX_CURSOR)
21513 /* Using a block cursor on large images can be very annoying.
21514 So use a hollow cursor for "large" images.
21515 If image is not transparent (no mask), also use hollow cursor. */
21516 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
21517 if (img != NULL && IMAGEP (img->spec))
21519 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
21520 where N = size of default frame font size.
21521 This should cover most of the "tiny" icons people may use. */
21522 if (!img->mask
21523 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
21524 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
21525 cursor_type = HOLLOW_BOX_CURSOR;
21528 else if (cursor_type != NO_CURSOR)
21530 /* Display current only supports BOX and HOLLOW cursors for images.
21531 So for now, unconditionally use a HOLLOW cursor when cursor is
21532 not a solid box cursor. */
21533 cursor_type = HOLLOW_BOX_CURSOR;
21536 #endif
21537 return cursor_type;
21540 /* Cursor is blinked off, so determine how to "toggle" it. */
21542 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
21543 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
21544 return get_specified_cursor_type (XCDR (alt_cursor), width);
21546 /* Then see if frame has specified a specific blink off cursor type. */
21547 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
21549 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
21550 return FRAME_BLINK_OFF_CURSOR (f);
21553 #if 0
21554 /* Some people liked having a permanently visible blinking cursor,
21555 while others had very strong opinions against it. So it was
21556 decided to remove it. KFS 2003-09-03 */
21558 /* Finally perform built-in cursor blinking:
21559 filled box <-> hollow box
21560 wide [h]bar <-> narrow [h]bar
21561 narrow [h]bar <-> no cursor
21562 other type <-> no cursor */
21564 if (cursor_type == FILLED_BOX_CURSOR)
21565 return HOLLOW_BOX_CURSOR;
21567 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
21569 *width = 1;
21570 return cursor_type;
21572 #endif
21574 return NO_CURSOR;
21578 #ifdef HAVE_WINDOW_SYSTEM
21580 /* Notice when the text cursor of window W has been completely
21581 overwritten by a drawing operation that outputs glyphs in AREA
21582 starting at X0 and ending at X1 in the line starting at Y0 and
21583 ending at Y1. X coordinates are area-relative. X1 < 0 means all
21584 the rest of the line after X0 has been written. Y coordinates
21585 are window-relative. */
21587 static void
21588 notice_overwritten_cursor (w, area, x0, x1, y0, y1)
21589 struct window *w;
21590 enum glyph_row_area area;
21591 int x0, y0, x1, y1;
21593 int cx0, cx1, cy0, cy1;
21594 struct glyph_row *row;
21596 if (!w->phys_cursor_on_p)
21597 return;
21598 if (area != TEXT_AREA)
21599 return;
21601 if (w->phys_cursor.vpos < 0
21602 || w->phys_cursor.vpos >= w->current_matrix->nrows
21603 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
21604 !(row->enabled_p && row->displays_text_p)))
21605 return;
21607 if (row->cursor_in_fringe_p)
21609 row->cursor_in_fringe_p = 0;
21610 draw_fringe_bitmap (w, row, 0);
21611 w->phys_cursor_on_p = 0;
21612 return;
21615 cx0 = w->phys_cursor.x;
21616 cx1 = cx0 + w->phys_cursor_width;
21617 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
21618 return;
21620 /* The cursor image will be completely removed from the
21621 screen if the output area intersects the cursor area in
21622 y-direction. When we draw in [y0 y1[, and some part of
21623 the cursor is at y < y0, that part must have been drawn
21624 before. When scrolling, the cursor is erased before
21625 actually scrolling, so we don't come here. When not
21626 scrolling, the rows above the old cursor row must have
21627 changed, and in this case these rows must have written
21628 over the cursor image.
21630 Likewise if part of the cursor is below y1, with the
21631 exception of the cursor being in the first blank row at
21632 the buffer and window end because update_text_area
21633 doesn't draw that row. (Except when it does, but
21634 that's handled in update_text_area.) */
21636 cy0 = w->phys_cursor.y;
21637 cy1 = cy0 + w->phys_cursor_height;
21638 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
21639 return;
21641 w->phys_cursor_on_p = 0;
21644 #endif /* HAVE_WINDOW_SYSTEM */
21647 /************************************************************************
21648 Mouse Face
21649 ************************************************************************/
21651 #ifdef HAVE_WINDOW_SYSTEM
21653 /* EXPORT for RIF:
21654 Fix the display of area AREA of overlapping row ROW in window W
21655 with respect to the overlapping part OVERLAPS. */
21657 void
21658 x_fix_overlapping_area (w, row, area, overlaps)
21659 struct window *w;
21660 struct glyph_row *row;
21661 enum glyph_row_area area;
21662 int overlaps;
21664 int i, x;
21666 BLOCK_INPUT;
21668 x = 0;
21669 for (i = 0; i < row->used[area];)
21671 if (row->glyphs[area][i].overlaps_vertically_p)
21673 int start = i, start_x = x;
21677 x += row->glyphs[area][i].pixel_width;
21678 ++i;
21680 while (i < row->used[area]
21681 && row->glyphs[area][i].overlaps_vertically_p);
21683 draw_glyphs (w, start_x, row, area,
21684 start, i,
21685 DRAW_NORMAL_TEXT, overlaps);
21687 else
21689 x += row->glyphs[area][i].pixel_width;
21690 ++i;
21694 UNBLOCK_INPUT;
21698 /* EXPORT:
21699 Draw the cursor glyph of window W in glyph row ROW. See the
21700 comment of draw_glyphs for the meaning of HL. */
21702 void
21703 draw_phys_cursor_glyph (w, row, hl)
21704 struct window *w;
21705 struct glyph_row *row;
21706 enum draw_glyphs_face hl;
21708 /* If cursor hpos is out of bounds, don't draw garbage. This can
21709 happen in mini-buffer windows when switching between echo area
21710 glyphs and mini-buffer. */
21711 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
21713 int on_p = w->phys_cursor_on_p;
21714 int x1;
21715 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
21716 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
21717 hl, 0);
21718 w->phys_cursor_on_p = on_p;
21720 if (hl == DRAW_CURSOR)
21721 w->phys_cursor_width = x1 - w->phys_cursor.x;
21722 /* When we erase the cursor, and ROW is overlapped by other
21723 rows, make sure that these overlapping parts of other rows
21724 are redrawn. */
21725 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
21727 w->phys_cursor_width = x1 - w->phys_cursor.x;
21729 if (row > w->current_matrix->rows
21730 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
21731 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
21732 OVERLAPS_ERASED_CURSOR);
21734 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
21735 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
21736 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
21737 OVERLAPS_ERASED_CURSOR);
21743 /* EXPORT:
21744 Erase the image of a cursor of window W from the screen. */
21746 void
21747 erase_phys_cursor (w)
21748 struct window *w;
21750 struct frame *f = XFRAME (w->frame);
21751 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21752 int hpos = w->phys_cursor.hpos;
21753 int vpos = w->phys_cursor.vpos;
21754 int mouse_face_here_p = 0;
21755 struct glyph_matrix *active_glyphs = w->current_matrix;
21756 struct glyph_row *cursor_row;
21757 struct glyph *cursor_glyph;
21758 enum draw_glyphs_face hl;
21760 /* No cursor displayed or row invalidated => nothing to do on the
21761 screen. */
21762 if (w->phys_cursor_type == NO_CURSOR)
21763 goto mark_cursor_off;
21765 /* VPOS >= active_glyphs->nrows means that window has been resized.
21766 Don't bother to erase the cursor. */
21767 if (vpos >= active_glyphs->nrows)
21768 goto mark_cursor_off;
21770 /* If row containing cursor is marked invalid, there is nothing we
21771 can do. */
21772 cursor_row = MATRIX_ROW (active_glyphs, vpos);
21773 if (!cursor_row->enabled_p)
21774 goto mark_cursor_off;
21776 /* If line spacing is > 0, old cursor may only be partially visible in
21777 window after split-window. So adjust visible height. */
21778 cursor_row->visible_height = min (cursor_row->visible_height,
21779 window_text_bottom_y (w) - cursor_row->y);
21781 /* If row is completely invisible, don't attempt to delete a cursor which
21782 isn't there. This can happen if cursor is at top of a window, and
21783 we switch to a buffer with a header line in that window. */
21784 if (cursor_row->visible_height <= 0)
21785 goto mark_cursor_off;
21787 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
21788 if (cursor_row->cursor_in_fringe_p)
21790 cursor_row->cursor_in_fringe_p = 0;
21791 draw_fringe_bitmap (w, cursor_row, 0);
21792 goto mark_cursor_off;
21795 /* This can happen when the new row is shorter than the old one.
21796 In this case, either draw_glyphs or clear_end_of_line
21797 should have cleared the cursor. Note that we wouldn't be
21798 able to erase the cursor in this case because we don't have a
21799 cursor glyph at hand. */
21800 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
21801 goto mark_cursor_off;
21803 /* If the cursor is in the mouse face area, redisplay that when
21804 we clear the cursor. */
21805 if (! NILP (dpyinfo->mouse_face_window)
21806 && w == XWINDOW (dpyinfo->mouse_face_window)
21807 && (vpos > dpyinfo->mouse_face_beg_row
21808 || (vpos == dpyinfo->mouse_face_beg_row
21809 && hpos >= dpyinfo->mouse_face_beg_col))
21810 && (vpos < dpyinfo->mouse_face_end_row
21811 || (vpos == dpyinfo->mouse_face_end_row
21812 && hpos < dpyinfo->mouse_face_end_col))
21813 /* Don't redraw the cursor's spot in mouse face if it is at the
21814 end of a line (on a newline). The cursor appears there, but
21815 mouse highlighting does not. */
21816 && cursor_row->used[TEXT_AREA] > hpos)
21817 mouse_face_here_p = 1;
21819 /* Maybe clear the display under the cursor. */
21820 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
21822 int x, y, left_x;
21823 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
21824 int width;
21826 cursor_glyph = get_phys_cursor_glyph (w);
21827 if (cursor_glyph == NULL)
21828 goto mark_cursor_off;
21830 width = cursor_glyph->pixel_width;
21831 left_x = window_box_left_offset (w, TEXT_AREA);
21832 x = w->phys_cursor.x;
21833 if (x < left_x)
21834 width -= left_x - x;
21835 width = min (width, window_box_width (w, TEXT_AREA) - x);
21836 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
21837 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
21839 if (width > 0)
21840 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
21843 /* Erase the cursor by redrawing the character underneath it. */
21844 if (mouse_face_here_p)
21845 hl = DRAW_MOUSE_FACE;
21846 else
21847 hl = DRAW_NORMAL_TEXT;
21848 draw_phys_cursor_glyph (w, cursor_row, hl);
21850 mark_cursor_off:
21851 w->phys_cursor_on_p = 0;
21852 w->phys_cursor_type = NO_CURSOR;
21856 /* EXPORT:
21857 Display or clear cursor of window W. If ON is zero, clear the
21858 cursor. If it is non-zero, display the cursor. If ON is nonzero,
21859 where to put the cursor is specified by HPOS, VPOS, X and Y. */
21861 void
21862 display_and_set_cursor (w, on, hpos, vpos, x, y)
21863 struct window *w;
21864 int on, hpos, vpos, x, y;
21866 struct frame *f = XFRAME (w->frame);
21867 int new_cursor_type;
21868 int new_cursor_width;
21869 int active_cursor;
21870 struct glyph_row *glyph_row;
21871 struct glyph *glyph;
21873 /* This is pointless on invisible frames, and dangerous on garbaged
21874 windows and frames; in the latter case, the frame or window may
21875 be in the midst of changing its size, and x and y may be off the
21876 window. */
21877 if (! FRAME_VISIBLE_P (f)
21878 || FRAME_GARBAGED_P (f)
21879 || vpos >= w->current_matrix->nrows
21880 || hpos >= w->current_matrix->matrix_w)
21881 return;
21883 /* If cursor is off and we want it off, return quickly. */
21884 if (!on && !w->phys_cursor_on_p)
21885 return;
21887 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
21888 /* If cursor row is not enabled, we don't really know where to
21889 display the cursor. */
21890 if (!glyph_row->enabled_p)
21892 w->phys_cursor_on_p = 0;
21893 return;
21896 glyph = NULL;
21897 if (!glyph_row->exact_window_width_line_p
21898 || hpos < glyph_row->used[TEXT_AREA])
21899 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
21901 xassert (interrupt_input_blocked);
21903 /* Set new_cursor_type to the cursor we want to be displayed. */
21904 new_cursor_type = get_window_cursor_type (w, glyph,
21905 &new_cursor_width, &active_cursor);
21907 /* If cursor is currently being shown and we don't want it to be or
21908 it is in the wrong place, or the cursor type is not what we want,
21909 erase it. */
21910 if (w->phys_cursor_on_p
21911 && (!on
21912 || w->phys_cursor.x != x
21913 || w->phys_cursor.y != y
21914 || new_cursor_type != w->phys_cursor_type
21915 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
21916 && new_cursor_width != w->phys_cursor_width)))
21917 erase_phys_cursor (w);
21919 /* Don't check phys_cursor_on_p here because that flag is only set
21920 to zero in some cases where we know that the cursor has been
21921 completely erased, to avoid the extra work of erasing the cursor
21922 twice. In other words, phys_cursor_on_p can be 1 and the cursor
21923 still not be visible, or it has only been partly erased. */
21924 if (on)
21926 w->phys_cursor_ascent = glyph_row->ascent;
21927 w->phys_cursor_height = glyph_row->height;
21929 /* Set phys_cursor_.* before x_draw_.* is called because some
21930 of them may need the information. */
21931 w->phys_cursor.x = x;
21932 w->phys_cursor.y = glyph_row->y;
21933 w->phys_cursor.hpos = hpos;
21934 w->phys_cursor.vpos = vpos;
21937 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
21938 new_cursor_type, new_cursor_width,
21939 on, active_cursor);
21943 /* Switch the display of W's cursor on or off, according to the value
21944 of ON. */
21946 static void
21947 update_window_cursor (w, on)
21948 struct window *w;
21949 int on;
21951 /* Don't update cursor in windows whose frame is in the process
21952 of being deleted. */
21953 if (w->current_matrix)
21955 BLOCK_INPUT;
21956 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
21957 w->phys_cursor.x, w->phys_cursor.y);
21958 UNBLOCK_INPUT;
21963 /* Call update_window_cursor with parameter ON_P on all leaf windows
21964 in the window tree rooted at W. */
21966 static void
21967 update_cursor_in_window_tree (w, on_p)
21968 struct window *w;
21969 int on_p;
21971 while (w)
21973 if (!NILP (w->hchild))
21974 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
21975 else if (!NILP (w->vchild))
21976 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
21977 else
21978 update_window_cursor (w, on_p);
21980 w = NILP (w->next) ? 0 : XWINDOW (w->next);
21985 /* EXPORT:
21986 Display the cursor on window W, or clear it, according to ON_P.
21987 Don't change the cursor's position. */
21989 void
21990 x_update_cursor (f, on_p)
21991 struct frame *f;
21992 int on_p;
21994 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
21998 /* EXPORT:
21999 Clear the cursor of window W to background color, and mark the
22000 cursor as not shown. This is used when the text where the cursor
22001 is is about to be rewritten. */
22003 void
22004 x_clear_cursor (w)
22005 struct window *w;
22007 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
22008 update_window_cursor (w, 0);
22012 /* EXPORT:
22013 Display the active region described by mouse_face_* according to DRAW. */
22015 void
22016 show_mouse_face (dpyinfo, draw)
22017 Display_Info *dpyinfo;
22018 enum draw_glyphs_face draw;
22020 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
22021 struct frame *f = XFRAME (WINDOW_FRAME (w));
22023 if (/* If window is in the process of being destroyed, don't bother
22024 to do anything. */
22025 w->current_matrix != NULL
22026 /* Don't update mouse highlight if hidden */
22027 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
22028 /* Recognize when we are called to operate on rows that don't exist
22029 anymore. This can happen when a window is split. */
22030 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
22032 int phys_cursor_on_p = w->phys_cursor_on_p;
22033 struct glyph_row *row, *first, *last;
22035 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
22036 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
22038 for (row = first; row <= last && row->enabled_p; ++row)
22040 int start_hpos, end_hpos, start_x;
22042 /* For all but the first row, the highlight starts at column 0. */
22043 if (row == first)
22045 start_hpos = dpyinfo->mouse_face_beg_col;
22046 start_x = dpyinfo->mouse_face_beg_x;
22048 else
22050 start_hpos = 0;
22051 start_x = 0;
22054 if (row == last)
22055 end_hpos = dpyinfo->mouse_face_end_col;
22056 else
22058 end_hpos = row->used[TEXT_AREA];
22059 if (draw == DRAW_NORMAL_TEXT)
22060 row->fill_line_p = 1; /* Clear to end of line */
22063 if (end_hpos > start_hpos)
22065 draw_glyphs (w, start_x, row, TEXT_AREA,
22066 start_hpos, end_hpos,
22067 draw, 0);
22069 row->mouse_face_p
22070 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
22074 /* When we've written over the cursor, arrange for it to
22075 be displayed again. */
22076 if (phys_cursor_on_p && !w->phys_cursor_on_p)
22078 BLOCK_INPUT;
22079 display_and_set_cursor (w, 1,
22080 w->phys_cursor.hpos, w->phys_cursor.vpos,
22081 w->phys_cursor.x, w->phys_cursor.y);
22082 UNBLOCK_INPUT;
22086 /* Change the mouse cursor. */
22087 if (draw == DRAW_NORMAL_TEXT && !EQ (dpyinfo->mouse_face_window, f->tool_bar_window))
22088 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
22089 else if (draw == DRAW_MOUSE_FACE)
22090 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
22091 else
22092 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
22095 /* EXPORT:
22096 Clear out the mouse-highlighted active region.
22097 Redraw it un-highlighted first. Value is non-zero if mouse
22098 face was actually drawn unhighlighted. */
22101 clear_mouse_face (dpyinfo)
22102 Display_Info *dpyinfo;
22104 int cleared = 0;
22106 if (!dpyinfo->mouse_face_hidden && !NILP (dpyinfo->mouse_face_window))
22108 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
22109 cleared = 1;
22112 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
22113 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
22114 dpyinfo->mouse_face_window = Qnil;
22115 dpyinfo->mouse_face_overlay = Qnil;
22116 return cleared;
22120 /* EXPORT:
22121 Non-zero if physical cursor of window W is within mouse face. */
22124 cursor_in_mouse_face_p (w)
22125 struct window *w;
22127 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
22128 int in_mouse_face = 0;
22130 if (WINDOWP (dpyinfo->mouse_face_window)
22131 && XWINDOW (dpyinfo->mouse_face_window) == w)
22133 int hpos = w->phys_cursor.hpos;
22134 int vpos = w->phys_cursor.vpos;
22136 if (vpos >= dpyinfo->mouse_face_beg_row
22137 && vpos <= dpyinfo->mouse_face_end_row
22138 && (vpos > dpyinfo->mouse_face_beg_row
22139 || hpos >= dpyinfo->mouse_face_beg_col)
22140 && (vpos < dpyinfo->mouse_face_end_row
22141 || hpos < dpyinfo->mouse_face_end_col
22142 || dpyinfo->mouse_face_past_end))
22143 in_mouse_face = 1;
22146 return in_mouse_face;
22152 /* Find the glyph matrix position of buffer position CHARPOS in window
22153 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
22154 current glyphs must be up to date. If CHARPOS is above window
22155 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
22156 of last line in W. In the row containing CHARPOS, stop before glyphs
22157 having STOP as object. */
22159 #if 1 /* This is a version of fast_find_position that's more correct
22160 in the presence of hscrolling, for example. I didn't install
22161 it right away because the problem fixed is minor, it failed
22162 in 20.x as well, and I think it's too risky to install
22163 so near the release of 21.1. 2001-09-25 gerd. */
22165 static int
22166 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
22167 struct window *w;
22168 int charpos;
22169 int *hpos, *vpos, *x, *y;
22170 Lisp_Object stop;
22172 struct glyph_row *row, *first;
22173 struct glyph *glyph, *end;
22174 int past_end = 0;
22176 first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
22177 if (charpos < MATRIX_ROW_START_CHARPOS (first))
22179 *x = first->x;
22180 *y = first->y;
22181 *hpos = 0;
22182 *vpos = MATRIX_ROW_VPOS (first, w->current_matrix);
22183 return 1;
22186 row = row_containing_pos (w, charpos, first, NULL, 0);
22187 if (row == NULL)
22189 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
22190 past_end = 1;
22193 /* If whole rows or last part of a row came from a display overlay,
22194 row_containing_pos will skip over such rows because their end pos
22195 equals the start pos of the overlay or interval.
22197 Move back if we have a STOP object and previous row's
22198 end glyph came from STOP. */
22199 if (!NILP (stop))
22201 struct glyph_row *prev;
22202 while ((prev = row - 1, prev >= first)
22203 && MATRIX_ROW_END_CHARPOS (prev) == charpos
22204 && prev->used[TEXT_AREA] > 0)
22206 struct glyph *beg = prev->glyphs[TEXT_AREA];
22207 glyph = beg + prev->used[TEXT_AREA];
22208 while (--glyph >= beg
22209 && INTEGERP (glyph->object));
22210 if (glyph < beg
22211 || !EQ (stop, glyph->object))
22212 break;
22213 row = prev;
22217 *x = row->x;
22218 *y = row->y;
22219 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
22221 glyph = row->glyphs[TEXT_AREA];
22222 end = glyph + row->used[TEXT_AREA];
22224 /* Skip over glyphs not having an object at the start of the row.
22225 These are special glyphs like truncation marks on terminal
22226 frames. */
22227 if (row->displays_text_p)
22228 while (glyph < end
22229 && INTEGERP (glyph->object)
22230 && !EQ (stop, glyph->object)
22231 && glyph->charpos < 0)
22233 *x += glyph->pixel_width;
22234 ++glyph;
22237 while (glyph < end
22238 && !INTEGERP (glyph->object)
22239 && !EQ (stop, glyph->object)
22240 && (!BUFFERP (glyph->object)
22241 || glyph->charpos < charpos))
22243 *x += glyph->pixel_width;
22244 ++glyph;
22247 *hpos = glyph - row->glyphs[TEXT_AREA];
22248 return !past_end;
22251 #else /* not 1 */
22253 static int
22254 fast_find_position (w, pos, hpos, vpos, x, y, stop)
22255 struct window *w;
22256 int pos;
22257 int *hpos, *vpos, *x, *y;
22258 Lisp_Object stop;
22260 int i;
22261 int lastcol;
22262 int maybe_next_line_p = 0;
22263 int line_start_position;
22264 int yb = window_text_bottom_y (w);
22265 struct glyph_row *row, *best_row;
22266 int row_vpos, best_row_vpos;
22267 int current_x;
22269 row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
22270 row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
22272 while (row->y < yb)
22274 if (row->used[TEXT_AREA])
22275 line_start_position = row->glyphs[TEXT_AREA]->charpos;
22276 else
22277 line_start_position = 0;
22279 if (line_start_position > pos)
22280 break;
22281 /* If the position sought is the end of the buffer,
22282 don't include the blank lines at the bottom of the window. */
22283 else if (line_start_position == pos
22284 && pos == BUF_ZV (XBUFFER (w->buffer)))
22286 maybe_next_line_p = 1;
22287 break;
22289 else if (line_start_position > 0)
22291 best_row = row;
22292 best_row_vpos = row_vpos;
22295 if (row->y + row->height >= yb)
22296 break;
22298 ++row;
22299 ++row_vpos;
22302 /* Find the right column within BEST_ROW. */
22303 lastcol = 0;
22304 current_x = best_row->x;
22305 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
22307 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
22308 int charpos = glyph->charpos;
22310 if (BUFFERP (glyph->object))
22312 if (charpos == pos)
22314 *hpos = i;
22315 *vpos = best_row_vpos;
22316 *x = current_x;
22317 *y = best_row->y;
22318 return 1;
22320 else if (charpos > pos)
22321 break;
22323 else if (EQ (glyph->object, stop))
22324 break;
22326 if (charpos > 0)
22327 lastcol = i;
22328 current_x += glyph->pixel_width;
22331 /* If we're looking for the end of the buffer,
22332 and we didn't find it in the line we scanned,
22333 use the start of the following line. */
22334 if (maybe_next_line_p)
22336 ++best_row;
22337 ++best_row_vpos;
22338 lastcol = 0;
22339 current_x = best_row->x;
22342 *vpos = best_row_vpos;
22343 *hpos = lastcol + 1;
22344 *x = current_x;
22345 *y = best_row->y;
22346 return 0;
22349 #endif /* not 1 */
22352 /* Find the position of the glyph for position POS in OBJECT in
22353 window W's current matrix, and return in *X, *Y the pixel
22354 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
22356 RIGHT_P non-zero means return the position of the right edge of the
22357 glyph, RIGHT_P zero means return the left edge position.
22359 If no glyph for POS exists in the matrix, return the position of
22360 the glyph with the next smaller position that is in the matrix, if
22361 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
22362 exists in the matrix, return the position of the glyph with the
22363 next larger position in OBJECT.
22365 Value is non-zero if a glyph was found. */
22367 static int
22368 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
22369 struct window *w;
22370 int pos;
22371 Lisp_Object object;
22372 int *hpos, *vpos, *x, *y;
22373 int right_p;
22375 int yb = window_text_bottom_y (w);
22376 struct glyph_row *r;
22377 struct glyph *best_glyph = NULL;
22378 struct glyph_row *best_row = NULL;
22379 int best_x = 0;
22381 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
22382 r->enabled_p && r->y < yb;
22383 ++r)
22385 struct glyph *g = r->glyphs[TEXT_AREA];
22386 struct glyph *e = g + r->used[TEXT_AREA];
22387 int gx;
22389 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
22390 if (EQ (g->object, object))
22392 if (g->charpos == pos)
22394 best_glyph = g;
22395 best_x = gx;
22396 best_row = r;
22397 goto found;
22399 else if (best_glyph == NULL
22400 || ((eabs (g->charpos - pos)
22401 < eabs (best_glyph->charpos - pos))
22402 && (right_p
22403 ? g->charpos < pos
22404 : g->charpos > pos)))
22406 best_glyph = g;
22407 best_x = gx;
22408 best_row = r;
22413 found:
22415 if (best_glyph)
22417 *x = best_x;
22418 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
22420 if (right_p)
22422 *x += best_glyph->pixel_width;
22423 ++*hpos;
22426 *y = best_row->y;
22427 *vpos = best_row - w->current_matrix->rows;
22430 return best_glyph != NULL;
22434 /* See if position X, Y is within a hot-spot of an image. */
22436 static int
22437 on_hot_spot_p (hot_spot, x, y)
22438 Lisp_Object hot_spot;
22439 int x, y;
22441 if (!CONSP (hot_spot))
22442 return 0;
22444 if (EQ (XCAR (hot_spot), Qrect))
22446 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
22447 Lisp_Object rect = XCDR (hot_spot);
22448 Lisp_Object tem;
22449 if (!CONSP (rect))
22450 return 0;
22451 if (!CONSP (XCAR (rect)))
22452 return 0;
22453 if (!CONSP (XCDR (rect)))
22454 return 0;
22455 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
22456 return 0;
22457 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
22458 return 0;
22459 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
22460 return 0;
22461 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
22462 return 0;
22463 return 1;
22465 else if (EQ (XCAR (hot_spot), Qcircle))
22467 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
22468 Lisp_Object circ = XCDR (hot_spot);
22469 Lisp_Object lr, lx0, ly0;
22470 if (CONSP (circ)
22471 && CONSP (XCAR (circ))
22472 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
22473 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
22474 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
22476 double r = XFLOATINT (lr);
22477 double dx = XINT (lx0) - x;
22478 double dy = XINT (ly0) - y;
22479 return (dx * dx + dy * dy <= r * r);
22482 else if (EQ (XCAR (hot_spot), Qpoly))
22484 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
22485 if (VECTORP (XCDR (hot_spot)))
22487 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
22488 Lisp_Object *poly = v->contents;
22489 int n = v->size;
22490 int i;
22491 int inside = 0;
22492 Lisp_Object lx, ly;
22493 int x0, y0;
22495 /* Need an even number of coordinates, and at least 3 edges. */
22496 if (n < 6 || n & 1)
22497 return 0;
22499 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
22500 If count is odd, we are inside polygon. Pixels on edges
22501 may or may not be included depending on actual geometry of the
22502 polygon. */
22503 if ((lx = poly[n-2], !INTEGERP (lx))
22504 || (ly = poly[n-1], !INTEGERP (lx)))
22505 return 0;
22506 x0 = XINT (lx), y0 = XINT (ly);
22507 for (i = 0; i < n; i += 2)
22509 int x1 = x0, y1 = y0;
22510 if ((lx = poly[i], !INTEGERP (lx))
22511 || (ly = poly[i+1], !INTEGERP (ly)))
22512 return 0;
22513 x0 = XINT (lx), y0 = XINT (ly);
22515 /* Does this segment cross the X line? */
22516 if (x0 >= x)
22518 if (x1 >= x)
22519 continue;
22521 else if (x1 < x)
22522 continue;
22523 if (y > y0 && y > y1)
22524 continue;
22525 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
22526 inside = !inside;
22528 return inside;
22531 return 0;
22534 Lisp_Object
22535 find_hot_spot (map, x, y)
22536 Lisp_Object map;
22537 int x, y;
22539 while (CONSP (map))
22541 if (CONSP (XCAR (map))
22542 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
22543 return XCAR (map);
22544 map = XCDR (map);
22547 return Qnil;
22550 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
22551 3, 3, 0,
22552 doc: /* Lookup in image map MAP coordinates X and Y.
22553 An image map is an alist where each element has the format (AREA ID PLIST).
22554 An AREA is specified as either a rectangle, a circle, or a polygon:
22555 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
22556 pixel coordinates of the upper left and bottom right corners.
22557 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
22558 and the radius of the circle; r may be a float or integer.
22559 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
22560 vector describes one corner in the polygon.
22561 Returns the alist element for the first matching AREA in MAP. */)
22562 (map, x, y)
22563 Lisp_Object map;
22564 Lisp_Object x, y;
22566 if (NILP (map))
22567 return Qnil;
22569 CHECK_NUMBER (x);
22570 CHECK_NUMBER (y);
22572 return find_hot_spot (map, XINT (x), XINT (y));
22576 /* Display frame CURSOR, optionally using shape defined by POINTER. */
22577 static void
22578 define_frame_cursor1 (f, cursor, pointer)
22579 struct frame *f;
22580 Cursor cursor;
22581 Lisp_Object pointer;
22583 /* Do not change cursor shape while dragging mouse. */
22584 if (!NILP (do_mouse_tracking))
22585 return;
22587 if (!NILP (pointer))
22589 if (EQ (pointer, Qarrow))
22590 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
22591 else if (EQ (pointer, Qhand))
22592 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
22593 else if (EQ (pointer, Qtext))
22594 cursor = FRAME_X_OUTPUT (f)->text_cursor;
22595 else if (EQ (pointer, intern ("hdrag")))
22596 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
22597 #ifdef HAVE_X_WINDOWS
22598 else if (EQ (pointer, intern ("vdrag")))
22599 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
22600 #endif
22601 else if (EQ (pointer, intern ("hourglass")))
22602 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
22603 else if (EQ (pointer, Qmodeline))
22604 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
22605 else
22606 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
22609 if (cursor != No_Cursor)
22610 FRAME_RIF (f)->define_frame_cursor (f, cursor);
22613 /* Take proper action when mouse has moved to the mode or header line
22614 or marginal area AREA of window W, x-position X and y-position Y.
22615 X is relative to the start of the text display area of W, so the
22616 width of bitmap areas and scroll bars must be subtracted to get a
22617 position relative to the start of the mode line. */
22619 static void
22620 note_mode_line_or_margin_highlight (window, x, y, area)
22621 Lisp_Object window;
22622 int x, y;
22623 enum window_part area;
22625 struct window *w = XWINDOW (window);
22626 struct frame *f = XFRAME (w->frame);
22627 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
22628 Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
22629 Lisp_Object pointer = Qnil;
22630 int charpos, dx, dy, width, height;
22631 Lisp_Object string, object = Qnil;
22632 Lisp_Object pos, help;
22634 Lisp_Object mouse_face;
22635 int original_x_pixel = x;
22636 struct glyph * glyph = NULL, * row_start_glyph = NULL;
22637 struct glyph_row *row;
22639 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
22641 int x0;
22642 struct glyph *end;
22644 string = mode_line_string (w, area, &x, &y, &charpos,
22645 &object, &dx, &dy, &width, &height);
22647 row = (area == ON_MODE_LINE
22648 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
22649 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
22651 /* Find glyph */
22652 if (row->mode_line_p && row->enabled_p)
22654 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
22655 end = glyph + row->used[TEXT_AREA];
22657 for (x0 = original_x_pixel;
22658 glyph < end && x0 >= glyph->pixel_width;
22659 ++glyph)
22660 x0 -= glyph->pixel_width;
22662 if (glyph >= end)
22663 glyph = NULL;
22666 else
22668 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
22669 string = marginal_area_string (w, area, &x, &y, &charpos,
22670 &object, &dx, &dy, &width, &height);
22673 help = Qnil;
22675 if (IMAGEP (object))
22677 Lisp_Object image_map, hotspot;
22678 if ((image_map = Fplist_get (XCDR (object), QCmap),
22679 !NILP (image_map))
22680 && (hotspot = find_hot_spot (image_map, dx, dy),
22681 CONSP (hotspot))
22682 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
22684 Lisp_Object area_id, plist;
22686 area_id = XCAR (hotspot);
22687 /* Could check AREA_ID to see if we enter/leave this hot-spot.
22688 If so, we could look for mouse-enter, mouse-leave
22689 properties in PLIST (and do something...). */
22690 hotspot = XCDR (hotspot);
22691 if (CONSP (hotspot)
22692 && (plist = XCAR (hotspot), CONSP (plist)))
22694 pointer = Fplist_get (plist, Qpointer);
22695 if (NILP (pointer))
22696 pointer = Qhand;
22697 help = Fplist_get (plist, Qhelp_echo);
22698 if (!NILP (help))
22700 help_echo_string = help;
22701 /* Is this correct? ++kfs */
22702 XSETWINDOW (help_echo_window, w);
22703 help_echo_object = w->buffer;
22704 help_echo_pos = charpos;
22708 if (NILP (pointer))
22709 pointer = Fplist_get (XCDR (object), QCpointer);
22712 if (STRINGP (string))
22714 pos = make_number (charpos);
22715 /* If we're on a string with `help-echo' text property, arrange
22716 for the help to be displayed. This is done by setting the
22717 global variable help_echo_string to the help string. */
22718 if (NILP (help))
22720 help = Fget_text_property (pos, Qhelp_echo, string);
22721 if (!NILP (help))
22723 help_echo_string = help;
22724 XSETWINDOW (help_echo_window, w);
22725 help_echo_object = string;
22726 help_echo_pos = charpos;
22730 if (NILP (pointer))
22731 pointer = Fget_text_property (pos, Qpointer, string);
22733 /* Change the mouse pointer according to what is under X/Y. */
22734 if (NILP (pointer) && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
22736 Lisp_Object map;
22737 map = Fget_text_property (pos, Qlocal_map, string);
22738 if (!KEYMAPP (map))
22739 map = Fget_text_property (pos, Qkeymap, string);
22740 if (!KEYMAPP (map))
22741 cursor = dpyinfo->vertical_scroll_bar_cursor;
22744 /* Change the mouse face according to what is under X/Y. */
22745 mouse_face = Fget_text_property (pos, Qmouse_face, string);
22746 if (!NILP (mouse_face)
22747 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
22748 && glyph)
22750 Lisp_Object b, e;
22752 struct glyph * tmp_glyph;
22754 int gpos;
22755 int gseq_length;
22756 int total_pixel_width;
22757 int ignore;
22759 int vpos, hpos;
22761 b = Fprevious_single_property_change (make_number (charpos + 1),
22762 Qmouse_face, string, Qnil);
22763 if (NILP (b))
22764 b = make_number (0);
22766 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
22767 if (NILP (e))
22768 e = make_number (SCHARS (string));
22770 /* Calculate the position(glyph position: GPOS) of GLYPH in
22771 displayed string. GPOS is different from CHARPOS.
22773 CHARPOS is the position of glyph in internal string
22774 object. A mode line string format has structures which
22775 is converted to a flatten by emacs lisp interpreter.
22776 The internal string is an element of the structures.
22777 The displayed string is the flatten string. */
22778 gpos = 0;
22779 if (glyph > row_start_glyph)
22781 tmp_glyph = glyph - 1;
22782 while (tmp_glyph >= row_start_glyph
22783 && tmp_glyph->charpos >= XINT (b)
22784 && EQ (tmp_glyph->object, glyph->object))
22786 tmp_glyph--;
22787 gpos++;
22791 /* Calculate the lenght(glyph sequence length: GSEQ_LENGTH) of
22792 displayed string holding GLYPH.
22794 GSEQ_LENGTH is different from SCHARS (STRING).
22795 SCHARS (STRING) returns the length of the internal string. */
22796 for (tmp_glyph = glyph, gseq_length = gpos;
22797 tmp_glyph->charpos < XINT (e);
22798 tmp_glyph++, gseq_length++)
22800 if (!EQ (tmp_glyph->object, glyph->object))
22801 break;
22804 total_pixel_width = 0;
22805 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
22806 total_pixel_width += tmp_glyph->pixel_width;
22808 /* Pre calculation of re-rendering position */
22809 vpos = (x - gpos);
22810 hpos = (area == ON_MODE_LINE
22811 ? (w->current_matrix)->nrows - 1
22812 : 0);
22814 /* If the re-rendering position is included in the last
22815 re-rendering area, we should do nothing. */
22816 if ( EQ (window, dpyinfo->mouse_face_window)
22817 && dpyinfo->mouse_face_beg_col <= vpos
22818 && vpos < dpyinfo->mouse_face_end_col
22819 && dpyinfo->mouse_face_beg_row == hpos )
22820 return;
22822 if (clear_mouse_face (dpyinfo))
22823 cursor = No_Cursor;
22825 dpyinfo->mouse_face_beg_col = vpos;
22826 dpyinfo->mouse_face_beg_row = hpos;
22828 dpyinfo->mouse_face_beg_x = original_x_pixel - (total_pixel_width + dx);
22829 dpyinfo->mouse_face_beg_y = 0;
22831 dpyinfo->mouse_face_end_col = vpos + gseq_length;
22832 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_beg_row;
22834 dpyinfo->mouse_face_end_x = 0;
22835 dpyinfo->mouse_face_end_y = 0;
22837 dpyinfo->mouse_face_past_end = 0;
22838 dpyinfo->mouse_face_window = window;
22840 dpyinfo->mouse_face_face_id = face_at_string_position (w, string,
22841 charpos,
22842 0, 0, 0, &ignore,
22843 glyph->face_id, 1);
22844 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
22846 if (NILP (pointer))
22847 pointer = Qhand;
22849 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
22850 clear_mouse_face (dpyinfo);
22852 define_frame_cursor1 (f, cursor, pointer);
22856 /* EXPORT:
22857 Take proper action when the mouse has moved to position X, Y on
22858 frame F as regards highlighting characters that have mouse-face
22859 properties. Also de-highlighting chars where the mouse was before.
22860 X and Y can be negative or out of range. */
22862 void
22863 note_mouse_highlight (f, x, y)
22864 struct frame *f;
22865 int x, y;
22867 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
22868 enum window_part part;
22869 Lisp_Object window;
22870 struct window *w;
22871 Cursor cursor = No_Cursor;
22872 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
22873 struct buffer *b;
22875 /* When a menu is active, don't highlight because this looks odd. */
22876 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (MAC_OS)
22877 if (popup_activated ())
22878 return;
22879 #endif
22881 if (NILP (Vmouse_highlight)
22882 || !f->glyphs_initialized_p)
22883 return;
22885 dpyinfo->mouse_face_mouse_x = x;
22886 dpyinfo->mouse_face_mouse_y = y;
22887 dpyinfo->mouse_face_mouse_frame = f;
22889 if (dpyinfo->mouse_face_defer)
22890 return;
22892 if (gc_in_progress)
22894 dpyinfo->mouse_face_deferred_gc = 1;
22895 return;
22898 /* Which window is that in? */
22899 window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
22901 /* If we were displaying active text in another window, clear that.
22902 Also clear if we move out of text area in same window. */
22903 if (! EQ (window, dpyinfo->mouse_face_window)
22904 || (part != ON_TEXT && part != ON_MODE_LINE && part != ON_HEADER_LINE
22905 && !NILP (dpyinfo->mouse_face_window)))
22906 clear_mouse_face (dpyinfo);
22908 /* Not on a window -> return. */
22909 if (!WINDOWP (window))
22910 return;
22912 /* Reset help_echo_string. It will get recomputed below. */
22913 help_echo_string = Qnil;
22915 /* Convert to window-relative pixel coordinates. */
22916 w = XWINDOW (window);
22917 frame_to_window_pixel_xy (w, &x, &y);
22919 /* Handle tool-bar window differently since it doesn't display a
22920 buffer. */
22921 if (EQ (window, f->tool_bar_window))
22923 note_tool_bar_highlight (f, x, y);
22924 return;
22927 /* Mouse is on the mode, header line or margin? */
22928 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
22929 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
22931 note_mode_line_or_margin_highlight (window, x, y, part);
22932 return;
22935 if (part == ON_VERTICAL_BORDER)
22937 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
22938 help_echo_string = build_string ("drag-mouse-1: resize");
22940 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
22941 || part == ON_SCROLL_BAR)
22942 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
22943 else
22944 cursor = FRAME_X_OUTPUT (f)->text_cursor;
22946 /* Are we in a window whose display is up to date?
22947 And verify the buffer's text has not changed. */
22948 b = XBUFFER (w->buffer);
22949 if (part == ON_TEXT
22950 && EQ (w->window_end_valid, w->buffer)
22951 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
22952 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
22954 int hpos, vpos, pos, i, dx, dy, area;
22955 struct glyph *glyph;
22956 Lisp_Object object;
22957 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
22958 Lisp_Object *overlay_vec = NULL;
22959 int noverlays;
22960 struct buffer *obuf;
22961 int obegv, ozv, same_region;
22963 /* Find the glyph under X/Y. */
22964 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
22966 /* Look for :pointer property on image. */
22967 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
22969 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
22970 if (img != NULL && IMAGEP (img->spec))
22972 Lisp_Object image_map, hotspot;
22973 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
22974 !NILP (image_map))
22975 && (hotspot = find_hot_spot (image_map,
22976 glyph->slice.x + dx,
22977 glyph->slice.y + dy),
22978 CONSP (hotspot))
22979 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
22981 Lisp_Object area_id, plist;
22983 area_id = XCAR (hotspot);
22984 /* Could check AREA_ID to see if we enter/leave this hot-spot.
22985 If so, we could look for mouse-enter, mouse-leave
22986 properties in PLIST (and do something...). */
22987 hotspot = XCDR (hotspot);
22988 if (CONSP (hotspot)
22989 && (plist = XCAR (hotspot), CONSP (plist)))
22991 pointer = Fplist_get (plist, Qpointer);
22992 if (NILP (pointer))
22993 pointer = Qhand;
22994 help_echo_string = Fplist_get (plist, Qhelp_echo);
22995 if (!NILP (help_echo_string))
22997 help_echo_window = window;
22998 help_echo_object = glyph->object;
22999 help_echo_pos = glyph->charpos;
23003 if (NILP (pointer))
23004 pointer = Fplist_get (XCDR (img->spec), QCpointer);
23008 /* Clear mouse face if X/Y not over text. */
23009 if (glyph == NULL
23010 || area != TEXT_AREA
23011 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
23013 if (clear_mouse_face (dpyinfo))
23014 cursor = No_Cursor;
23015 if (NILP (pointer))
23017 if (area != TEXT_AREA)
23018 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
23019 else
23020 pointer = Vvoid_text_area_pointer;
23022 goto set_cursor;
23025 pos = glyph->charpos;
23026 object = glyph->object;
23027 if (!STRINGP (object) && !BUFFERP (object))
23028 goto set_cursor;
23030 /* If we get an out-of-range value, return now; avoid an error. */
23031 if (BUFFERP (object) && pos > BUF_Z (b))
23032 goto set_cursor;
23034 /* Make the window's buffer temporarily current for
23035 overlays_at and compute_char_face. */
23036 obuf = current_buffer;
23037 current_buffer = b;
23038 obegv = BEGV;
23039 ozv = ZV;
23040 BEGV = BEG;
23041 ZV = Z;
23043 /* Is this char mouse-active or does it have help-echo? */
23044 position = make_number (pos);
23046 if (BUFFERP (object))
23048 /* Put all the overlays we want in a vector in overlay_vec. */
23049 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
23050 /* Sort overlays into increasing priority order. */
23051 noverlays = sort_overlays (overlay_vec, noverlays, w);
23053 else
23054 noverlays = 0;
23056 same_region = (EQ (window, dpyinfo->mouse_face_window)
23057 && vpos >= dpyinfo->mouse_face_beg_row
23058 && vpos <= dpyinfo->mouse_face_end_row
23059 && (vpos > dpyinfo->mouse_face_beg_row
23060 || hpos >= dpyinfo->mouse_face_beg_col)
23061 && (vpos < dpyinfo->mouse_face_end_row
23062 || hpos < dpyinfo->mouse_face_end_col
23063 || dpyinfo->mouse_face_past_end));
23065 if (same_region)
23066 cursor = No_Cursor;
23068 /* Check mouse-face highlighting. */
23069 if (! same_region
23070 /* If there exists an overlay with mouse-face overlapping
23071 the one we are currently highlighting, we have to
23072 check if we enter the overlapping overlay, and then
23073 highlight only that. */
23074 || (OVERLAYP (dpyinfo->mouse_face_overlay)
23075 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
23077 /* Find the highest priority overlay that has a mouse-face
23078 property. */
23079 overlay = Qnil;
23080 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
23082 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
23083 if (!NILP (mouse_face))
23084 overlay = overlay_vec[i];
23087 /* If we're actually highlighting the same overlay as
23088 before, there's no need to do that again. */
23089 if (!NILP (overlay)
23090 && EQ (overlay, dpyinfo->mouse_face_overlay))
23091 goto check_help_echo;
23093 dpyinfo->mouse_face_overlay = overlay;
23095 /* Clear the display of the old active region, if any. */
23096 if (clear_mouse_face (dpyinfo))
23097 cursor = No_Cursor;
23099 /* If no overlay applies, get a text property. */
23100 if (NILP (overlay))
23101 mouse_face = Fget_text_property (position, Qmouse_face, object);
23103 /* Handle the overlay case. */
23104 if (!NILP (overlay))
23106 /* Find the range of text around this char that
23107 should be active. */
23108 Lisp_Object before, after;
23109 int ignore;
23111 before = Foverlay_start (overlay);
23112 after = Foverlay_end (overlay);
23113 /* Record this as the current active region. */
23114 fast_find_position (w, XFASTINT (before),
23115 &dpyinfo->mouse_face_beg_col,
23116 &dpyinfo->mouse_face_beg_row,
23117 &dpyinfo->mouse_face_beg_x,
23118 &dpyinfo->mouse_face_beg_y, Qnil);
23120 dpyinfo->mouse_face_past_end
23121 = !fast_find_position (w, XFASTINT (after),
23122 &dpyinfo->mouse_face_end_col,
23123 &dpyinfo->mouse_face_end_row,
23124 &dpyinfo->mouse_face_end_x,
23125 &dpyinfo->mouse_face_end_y, Qnil);
23126 dpyinfo->mouse_face_window = window;
23128 dpyinfo->mouse_face_face_id
23129 = face_at_buffer_position (w, pos, 0, 0,
23130 &ignore, pos + 1,
23131 !dpyinfo->mouse_face_hidden);
23133 /* Display it as active. */
23134 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
23135 cursor = No_Cursor;
23137 /* Handle the text property case. */
23138 else if (!NILP (mouse_face) && BUFFERP (object))
23140 /* Find the range of text around this char that
23141 should be active. */
23142 Lisp_Object before, after, beginning, end;
23143 int ignore;
23145 beginning = Fmarker_position (w->start);
23146 end = make_number (BUF_Z (XBUFFER (object))
23147 - XFASTINT (w->window_end_pos));
23148 before
23149 = Fprevious_single_property_change (make_number (pos + 1),
23150 Qmouse_face,
23151 object, beginning);
23152 after
23153 = Fnext_single_property_change (position, Qmouse_face,
23154 object, end);
23156 /* Record this as the current active region. */
23157 fast_find_position (w, XFASTINT (before),
23158 &dpyinfo->mouse_face_beg_col,
23159 &dpyinfo->mouse_face_beg_row,
23160 &dpyinfo->mouse_face_beg_x,
23161 &dpyinfo->mouse_face_beg_y, Qnil);
23162 dpyinfo->mouse_face_past_end
23163 = !fast_find_position (w, XFASTINT (after),
23164 &dpyinfo->mouse_face_end_col,
23165 &dpyinfo->mouse_face_end_row,
23166 &dpyinfo->mouse_face_end_x,
23167 &dpyinfo->mouse_face_end_y, Qnil);
23168 dpyinfo->mouse_face_window = window;
23170 if (BUFFERP (object))
23171 dpyinfo->mouse_face_face_id
23172 = face_at_buffer_position (w, pos, 0, 0,
23173 &ignore, pos + 1,
23174 !dpyinfo->mouse_face_hidden);
23176 /* Display it as active. */
23177 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
23178 cursor = No_Cursor;
23180 else if (!NILP (mouse_face) && STRINGP (object))
23182 Lisp_Object b, e;
23183 int ignore;
23185 b = Fprevious_single_property_change (make_number (pos + 1),
23186 Qmouse_face,
23187 object, Qnil);
23188 e = Fnext_single_property_change (position, Qmouse_face,
23189 object, Qnil);
23190 if (NILP (b))
23191 b = make_number (0);
23192 if (NILP (e))
23193 e = make_number (SCHARS (object) - 1);
23195 fast_find_string_pos (w, XINT (b), object,
23196 &dpyinfo->mouse_face_beg_col,
23197 &dpyinfo->mouse_face_beg_row,
23198 &dpyinfo->mouse_face_beg_x,
23199 &dpyinfo->mouse_face_beg_y, 0);
23200 fast_find_string_pos (w, XINT (e), object,
23201 &dpyinfo->mouse_face_end_col,
23202 &dpyinfo->mouse_face_end_row,
23203 &dpyinfo->mouse_face_end_x,
23204 &dpyinfo->mouse_face_end_y, 1);
23205 dpyinfo->mouse_face_past_end = 0;
23206 dpyinfo->mouse_face_window = window;
23207 dpyinfo->mouse_face_face_id
23208 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
23209 glyph->face_id, 1);
23210 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
23211 cursor = No_Cursor;
23213 else if (STRINGP (object) && NILP (mouse_face))
23215 /* A string which doesn't have mouse-face, but
23216 the text ``under'' it might have. */
23217 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
23218 int start = MATRIX_ROW_START_CHARPOS (r);
23220 pos = string_buffer_position (w, object, start);
23221 if (pos > 0)
23222 mouse_face = get_char_property_and_overlay (make_number (pos),
23223 Qmouse_face,
23224 w->buffer,
23225 &overlay);
23226 if (!NILP (mouse_face) && !NILP (overlay))
23228 Lisp_Object before = Foverlay_start (overlay);
23229 Lisp_Object after = Foverlay_end (overlay);
23230 int ignore;
23232 /* Note that we might not be able to find position
23233 BEFORE in the glyph matrix if the overlay is
23234 entirely covered by a `display' property. In
23235 this case, we overshoot. So let's stop in
23236 the glyph matrix before glyphs for OBJECT. */
23237 fast_find_position (w, XFASTINT (before),
23238 &dpyinfo->mouse_face_beg_col,
23239 &dpyinfo->mouse_face_beg_row,
23240 &dpyinfo->mouse_face_beg_x,
23241 &dpyinfo->mouse_face_beg_y,
23242 object);
23244 dpyinfo->mouse_face_past_end
23245 = !fast_find_position (w, XFASTINT (after),
23246 &dpyinfo->mouse_face_end_col,
23247 &dpyinfo->mouse_face_end_row,
23248 &dpyinfo->mouse_face_end_x,
23249 &dpyinfo->mouse_face_end_y,
23250 Qnil);
23251 dpyinfo->mouse_face_window = window;
23252 dpyinfo->mouse_face_face_id
23253 = face_at_buffer_position (w, pos, 0, 0,
23254 &ignore, pos + 1,
23255 !dpyinfo->mouse_face_hidden);
23257 /* Display it as active. */
23258 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
23259 cursor = No_Cursor;
23264 check_help_echo:
23266 /* Look for a `help-echo' property. */
23267 if (NILP (help_echo_string)) {
23268 Lisp_Object help, overlay;
23270 /* Check overlays first. */
23271 help = overlay = Qnil;
23272 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
23274 overlay = overlay_vec[i];
23275 help = Foverlay_get (overlay, Qhelp_echo);
23278 if (!NILP (help))
23280 help_echo_string = help;
23281 help_echo_window = window;
23282 help_echo_object = overlay;
23283 help_echo_pos = pos;
23285 else
23287 Lisp_Object object = glyph->object;
23288 int charpos = glyph->charpos;
23290 /* Try text properties. */
23291 if (STRINGP (object)
23292 && charpos >= 0
23293 && charpos < SCHARS (object))
23295 help = Fget_text_property (make_number (charpos),
23296 Qhelp_echo, object);
23297 if (NILP (help))
23299 /* If the string itself doesn't specify a help-echo,
23300 see if the buffer text ``under'' it does. */
23301 struct glyph_row *r
23302 = MATRIX_ROW (w->current_matrix, vpos);
23303 int start = MATRIX_ROW_START_CHARPOS (r);
23304 int pos = string_buffer_position (w, object, start);
23305 if (pos > 0)
23307 help = Fget_char_property (make_number (pos),
23308 Qhelp_echo, w->buffer);
23309 if (!NILP (help))
23311 charpos = pos;
23312 object = w->buffer;
23317 else if (BUFFERP (object)
23318 && charpos >= BEGV
23319 && charpos < ZV)
23320 help = Fget_text_property (make_number (charpos), Qhelp_echo,
23321 object);
23323 if (!NILP (help))
23325 help_echo_string = help;
23326 help_echo_window = window;
23327 help_echo_object = object;
23328 help_echo_pos = charpos;
23333 /* Look for a `pointer' property. */
23334 if (NILP (pointer))
23336 /* Check overlays first. */
23337 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
23338 pointer = Foverlay_get (overlay_vec[i], Qpointer);
23340 if (NILP (pointer))
23342 Lisp_Object object = glyph->object;
23343 int charpos = glyph->charpos;
23345 /* Try text properties. */
23346 if (STRINGP (object)
23347 && charpos >= 0
23348 && charpos < SCHARS (object))
23350 pointer = Fget_text_property (make_number (charpos),
23351 Qpointer, object);
23352 if (NILP (pointer))
23354 /* If the string itself doesn't specify a pointer,
23355 see if the buffer text ``under'' it does. */
23356 struct glyph_row *r
23357 = MATRIX_ROW (w->current_matrix, vpos);
23358 int start = MATRIX_ROW_START_CHARPOS (r);
23359 int pos = string_buffer_position (w, object, start);
23360 if (pos > 0)
23361 pointer = Fget_char_property (make_number (pos),
23362 Qpointer, w->buffer);
23365 else if (BUFFERP (object)
23366 && charpos >= BEGV
23367 && charpos < ZV)
23368 pointer = Fget_text_property (make_number (charpos),
23369 Qpointer, object);
23373 BEGV = obegv;
23374 ZV = ozv;
23375 current_buffer = obuf;
23378 set_cursor:
23380 define_frame_cursor1 (f, cursor, pointer);
23384 /* EXPORT for RIF:
23385 Clear any mouse-face on window W. This function is part of the
23386 redisplay interface, and is called from try_window_id and similar
23387 functions to ensure the mouse-highlight is off. */
23389 void
23390 x_clear_window_mouse_face (w)
23391 struct window *w;
23393 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
23394 Lisp_Object window;
23396 BLOCK_INPUT;
23397 XSETWINDOW (window, w);
23398 if (EQ (window, dpyinfo->mouse_face_window))
23399 clear_mouse_face (dpyinfo);
23400 UNBLOCK_INPUT;
23404 /* EXPORT:
23405 Just discard the mouse face information for frame F, if any.
23406 This is used when the size of F is changed. */
23408 void
23409 cancel_mouse_face (f)
23410 struct frame *f;
23412 Lisp_Object window;
23413 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
23415 window = dpyinfo->mouse_face_window;
23416 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
23418 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
23419 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
23420 dpyinfo->mouse_face_window = Qnil;
23425 #endif /* HAVE_WINDOW_SYSTEM */
23428 /***********************************************************************
23429 Exposure Events
23430 ***********************************************************************/
23432 #ifdef HAVE_WINDOW_SYSTEM
23434 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
23435 which intersects rectangle R. R is in window-relative coordinates. */
23437 static void
23438 expose_area (w, row, r, area)
23439 struct window *w;
23440 struct glyph_row *row;
23441 XRectangle *r;
23442 enum glyph_row_area area;
23444 struct glyph *first = row->glyphs[area];
23445 struct glyph *end = row->glyphs[area] + row->used[area];
23446 struct glyph *last;
23447 int first_x, start_x, x;
23449 if (area == TEXT_AREA && row->fill_line_p)
23450 /* If row extends face to end of line write the whole line. */
23451 draw_glyphs (w, 0, row, area,
23452 0, row->used[area],
23453 DRAW_NORMAL_TEXT, 0);
23454 else
23456 /* Set START_X to the window-relative start position for drawing glyphs of
23457 AREA. The first glyph of the text area can be partially visible.
23458 The first glyphs of other areas cannot. */
23459 start_x = window_box_left_offset (w, area);
23460 x = start_x;
23461 if (area == TEXT_AREA)
23462 x += row->x;
23464 /* Find the first glyph that must be redrawn. */
23465 while (first < end
23466 && x + first->pixel_width < r->x)
23468 x += first->pixel_width;
23469 ++first;
23472 /* Find the last one. */
23473 last = first;
23474 first_x = x;
23475 while (last < end
23476 && x < r->x + r->width)
23478 x += last->pixel_width;
23479 ++last;
23482 /* Repaint. */
23483 if (last > first)
23484 draw_glyphs (w, first_x - start_x, row, area,
23485 first - row->glyphs[area], last - row->glyphs[area],
23486 DRAW_NORMAL_TEXT, 0);
23491 /* Redraw the parts of the glyph row ROW on window W intersecting
23492 rectangle R. R is in window-relative coordinates. Value is
23493 non-zero if mouse-face was overwritten. */
23495 static int
23496 expose_line (w, row, r)
23497 struct window *w;
23498 struct glyph_row *row;
23499 XRectangle *r;
23501 xassert (row->enabled_p);
23503 if (row->mode_line_p || w->pseudo_window_p)
23504 draw_glyphs (w, 0, row, TEXT_AREA,
23505 0, row->used[TEXT_AREA],
23506 DRAW_NORMAL_TEXT, 0);
23507 else
23509 if (row->used[LEFT_MARGIN_AREA])
23510 expose_area (w, row, r, LEFT_MARGIN_AREA);
23511 if (row->used[TEXT_AREA])
23512 expose_area (w, row, r, TEXT_AREA);
23513 if (row->used[RIGHT_MARGIN_AREA])
23514 expose_area (w, row, r, RIGHT_MARGIN_AREA);
23515 draw_row_fringe_bitmaps (w, row);
23518 return row->mouse_face_p;
23522 /* Redraw those parts of glyphs rows during expose event handling that
23523 overlap other rows. Redrawing of an exposed line writes over parts
23524 of lines overlapping that exposed line; this function fixes that.
23526 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
23527 row in W's current matrix that is exposed and overlaps other rows.
23528 LAST_OVERLAPPING_ROW is the last such row. */
23530 static void
23531 expose_overlaps (w, first_overlapping_row, last_overlapping_row)
23532 struct window *w;
23533 struct glyph_row *first_overlapping_row;
23534 struct glyph_row *last_overlapping_row;
23536 struct glyph_row *row;
23538 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
23539 if (row->overlapping_p)
23541 xassert (row->enabled_p && !row->mode_line_p);
23543 if (row->used[LEFT_MARGIN_AREA])
23544 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
23546 if (row->used[TEXT_AREA])
23547 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
23549 if (row->used[RIGHT_MARGIN_AREA])
23550 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
23555 /* Return non-zero if W's cursor intersects rectangle R. */
23557 static int
23558 phys_cursor_in_rect_p (w, r)
23559 struct window *w;
23560 XRectangle *r;
23562 XRectangle cr, result;
23563 struct glyph *cursor_glyph;
23564 struct glyph_row *row;
23566 if (w->phys_cursor.vpos >= 0
23567 && w->phys_cursor.vpos < w->current_matrix->nrows
23568 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
23569 row->enabled_p)
23570 && row->cursor_in_fringe_p)
23572 /* Cursor is in the fringe. */
23573 cr.x = window_box_right_offset (w,
23574 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
23575 ? RIGHT_MARGIN_AREA
23576 : TEXT_AREA));
23577 cr.y = row->y;
23578 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
23579 cr.height = row->height;
23580 return x_intersect_rectangles (&cr, r, &result);
23583 cursor_glyph = get_phys_cursor_glyph (w);
23584 if (cursor_glyph)
23586 /* r is relative to W's box, but w->phys_cursor.x is relative
23587 to left edge of W's TEXT area. Adjust it. */
23588 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
23589 cr.y = w->phys_cursor.y;
23590 cr.width = cursor_glyph->pixel_width;
23591 cr.height = w->phys_cursor_height;
23592 /* ++KFS: W32 version used W32-specific IntersectRect here, but
23593 I assume the effect is the same -- and this is portable. */
23594 return x_intersect_rectangles (&cr, r, &result);
23596 /* If we don't understand the format, pretend we're not in the hot-spot. */
23597 return 0;
23601 /* EXPORT:
23602 Draw a vertical window border to the right of window W if W doesn't
23603 have vertical scroll bars. */
23605 void
23606 x_draw_vertical_border (w)
23607 struct window *w;
23609 struct frame *f = XFRAME (WINDOW_FRAME (w));
23611 /* We could do better, if we knew what type of scroll-bar the adjacent
23612 windows (on either side) have... But we don't :-(
23613 However, I think this works ok. ++KFS 2003-04-25 */
23615 /* Redraw borders between horizontally adjacent windows. Don't
23616 do it for frames with vertical scroll bars because either the
23617 right scroll bar of a window, or the left scroll bar of its
23618 neighbor will suffice as a border. */
23619 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
23620 return;
23622 if (!WINDOW_RIGHTMOST_P (w)
23623 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
23625 int x0, x1, y0, y1;
23627 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
23628 y1 -= 1;
23630 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
23631 x1 -= 1;
23633 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
23635 else if (!WINDOW_LEFTMOST_P (w)
23636 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
23638 int x0, x1, y0, y1;
23640 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
23641 y1 -= 1;
23643 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
23644 x0 -= 1;
23646 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
23651 /* Redraw the part of window W intersection rectangle FR. Pixel
23652 coordinates in FR are frame-relative. Call this function with
23653 input blocked. Value is non-zero if the exposure overwrites
23654 mouse-face. */
23656 static int
23657 expose_window (w, fr)
23658 struct window *w;
23659 XRectangle *fr;
23661 struct frame *f = XFRAME (w->frame);
23662 XRectangle wr, r;
23663 int mouse_face_overwritten_p = 0;
23665 /* If window is not yet fully initialized, do nothing. This can
23666 happen when toolkit scroll bars are used and a window is split.
23667 Reconfiguring the scroll bar will generate an expose for a newly
23668 created window. */
23669 if (w->current_matrix == NULL)
23670 return 0;
23672 /* When we're currently updating the window, display and current
23673 matrix usually don't agree. Arrange for a thorough display
23674 later. */
23675 if (w == updated_window)
23677 SET_FRAME_GARBAGED (f);
23678 return 0;
23681 /* Frame-relative pixel rectangle of W. */
23682 wr.x = WINDOW_LEFT_EDGE_X (w);
23683 wr.y = WINDOW_TOP_EDGE_Y (w);
23684 wr.width = WINDOW_TOTAL_WIDTH (w);
23685 wr.height = WINDOW_TOTAL_HEIGHT (w);
23687 if (x_intersect_rectangles (fr, &wr, &r))
23689 int yb = window_text_bottom_y (w);
23690 struct glyph_row *row;
23691 int cursor_cleared_p;
23692 struct glyph_row *first_overlapping_row, *last_overlapping_row;
23694 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
23695 r.x, r.y, r.width, r.height));
23697 /* Convert to window coordinates. */
23698 r.x -= WINDOW_LEFT_EDGE_X (w);
23699 r.y -= WINDOW_TOP_EDGE_Y (w);
23701 /* Turn off the cursor. */
23702 if (!w->pseudo_window_p
23703 && phys_cursor_in_rect_p (w, &r))
23705 x_clear_cursor (w);
23706 cursor_cleared_p = 1;
23708 else
23709 cursor_cleared_p = 0;
23711 /* Update lines intersecting rectangle R. */
23712 first_overlapping_row = last_overlapping_row = NULL;
23713 for (row = w->current_matrix->rows;
23714 row->enabled_p;
23715 ++row)
23717 int y0 = row->y;
23718 int y1 = MATRIX_ROW_BOTTOM_Y (row);
23720 if ((y0 >= r.y && y0 < r.y + r.height)
23721 || (y1 > r.y && y1 < r.y + r.height)
23722 || (r.y >= y0 && r.y < y1)
23723 || (r.y + r.height > y0 && r.y + r.height < y1))
23725 /* A header line may be overlapping, but there is no need
23726 to fix overlapping areas for them. KFS 2005-02-12 */
23727 if (row->overlapping_p && !row->mode_line_p)
23729 if (first_overlapping_row == NULL)
23730 first_overlapping_row = row;
23731 last_overlapping_row = row;
23734 if (expose_line (w, row, &r))
23735 mouse_face_overwritten_p = 1;
23738 if (y1 >= yb)
23739 break;
23742 /* Display the mode line if there is one. */
23743 if (WINDOW_WANTS_MODELINE_P (w)
23744 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
23745 row->enabled_p)
23746 && row->y < r.y + r.height)
23748 if (expose_line (w, row, &r))
23749 mouse_face_overwritten_p = 1;
23752 if (!w->pseudo_window_p)
23754 /* Fix the display of overlapping rows. */
23755 if (first_overlapping_row)
23756 expose_overlaps (w, first_overlapping_row, last_overlapping_row);
23758 /* Draw border between windows. */
23759 x_draw_vertical_border (w);
23761 /* Turn the cursor on again. */
23762 if (cursor_cleared_p)
23763 update_window_cursor (w, 1);
23767 return mouse_face_overwritten_p;
23772 /* Redraw (parts) of all windows in the window tree rooted at W that
23773 intersect R. R contains frame pixel coordinates. Value is
23774 non-zero if the exposure overwrites mouse-face. */
23776 static int
23777 expose_window_tree (w, r)
23778 struct window *w;
23779 XRectangle *r;
23781 struct frame *f = XFRAME (w->frame);
23782 int mouse_face_overwritten_p = 0;
23784 while (w && !FRAME_GARBAGED_P (f))
23786 if (!NILP (w->hchild))
23787 mouse_face_overwritten_p
23788 |= expose_window_tree (XWINDOW (w->hchild), r);
23789 else if (!NILP (w->vchild))
23790 mouse_face_overwritten_p
23791 |= expose_window_tree (XWINDOW (w->vchild), r);
23792 else
23793 mouse_face_overwritten_p |= expose_window (w, r);
23795 w = NILP (w->next) ? NULL : XWINDOW (w->next);
23798 return mouse_face_overwritten_p;
23802 /* EXPORT:
23803 Redisplay an exposed area of frame F. X and Y are the upper-left
23804 corner of the exposed rectangle. W and H are width and height of
23805 the exposed area. All are pixel values. W or H zero means redraw
23806 the entire frame. */
23808 void
23809 expose_frame (f, x, y, w, h)
23810 struct frame *f;
23811 int x, y, w, h;
23813 XRectangle r;
23814 int mouse_face_overwritten_p = 0;
23816 TRACE ((stderr, "expose_frame "));
23818 /* No need to redraw if frame will be redrawn soon. */
23819 if (FRAME_GARBAGED_P (f))
23821 TRACE ((stderr, " garbaged\n"));
23822 return;
23825 /* If basic faces haven't been realized yet, there is no point in
23826 trying to redraw anything. This can happen when we get an expose
23827 event while Emacs is starting, e.g. by moving another window. */
23828 if (FRAME_FACE_CACHE (f) == NULL
23829 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
23831 TRACE ((stderr, " no faces\n"));
23832 return;
23835 if (w == 0 || h == 0)
23837 r.x = r.y = 0;
23838 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
23839 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
23841 else
23843 r.x = x;
23844 r.y = y;
23845 r.width = w;
23846 r.height = h;
23849 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
23850 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
23852 if (WINDOWP (f->tool_bar_window))
23853 mouse_face_overwritten_p
23854 |= expose_window (XWINDOW (f->tool_bar_window), &r);
23856 #ifdef HAVE_X_WINDOWS
23857 #ifndef MSDOS
23858 #ifndef USE_X_TOOLKIT
23859 if (WINDOWP (f->menu_bar_window))
23860 mouse_face_overwritten_p
23861 |= expose_window (XWINDOW (f->menu_bar_window), &r);
23862 #endif /* not USE_X_TOOLKIT */
23863 #endif
23864 #endif
23866 /* Some window managers support a focus-follows-mouse style with
23867 delayed raising of frames. Imagine a partially obscured frame,
23868 and moving the mouse into partially obscured mouse-face on that
23869 frame. The visible part of the mouse-face will be highlighted,
23870 then the WM raises the obscured frame. With at least one WM, KDE
23871 2.1, Emacs is not getting any event for the raising of the frame
23872 (even tried with SubstructureRedirectMask), only Expose events.
23873 These expose events will draw text normally, i.e. not
23874 highlighted. Which means we must redo the highlight here.
23875 Subsume it under ``we love X''. --gerd 2001-08-15 */
23876 /* Included in Windows version because Windows most likely does not
23877 do the right thing if any third party tool offers
23878 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
23879 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
23881 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
23882 if (f == dpyinfo->mouse_face_mouse_frame)
23884 int x = dpyinfo->mouse_face_mouse_x;
23885 int y = dpyinfo->mouse_face_mouse_y;
23886 clear_mouse_face (dpyinfo);
23887 note_mouse_highlight (f, x, y);
23893 /* EXPORT:
23894 Determine the intersection of two rectangles R1 and R2. Return
23895 the intersection in *RESULT. Value is non-zero if RESULT is not
23896 empty. */
23899 x_intersect_rectangles (r1, r2, result)
23900 XRectangle *r1, *r2, *result;
23902 XRectangle *left, *right;
23903 XRectangle *upper, *lower;
23904 int intersection_p = 0;
23906 /* Rearrange so that R1 is the left-most rectangle. */
23907 if (r1->x < r2->x)
23908 left = r1, right = r2;
23909 else
23910 left = r2, right = r1;
23912 /* X0 of the intersection is right.x0, if this is inside R1,
23913 otherwise there is no intersection. */
23914 if (right->x <= left->x + left->width)
23916 result->x = right->x;
23918 /* The right end of the intersection is the minimum of the
23919 the right ends of left and right. */
23920 result->width = (min (left->x + left->width, right->x + right->width)
23921 - result->x);
23923 /* Same game for Y. */
23924 if (r1->y < r2->y)
23925 upper = r1, lower = r2;
23926 else
23927 upper = r2, lower = r1;
23929 /* The upper end of the intersection is lower.y0, if this is inside
23930 of upper. Otherwise, there is no intersection. */
23931 if (lower->y <= upper->y + upper->height)
23933 result->y = lower->y;
23935 /* The lower end of the intersection is the minimum of the lower
23936 ends of upper and lower. */
23937 result->height = (min (lower->y + lower->height,
23938 upper->y + upper->height)
23939 - result->y);
23940 intersection_p = 1;
23944 return intersection_p;
23947 #endif /* HAVE_WINDOW_SYSTEM */
23950 /***********************************************************************
23951 Initialization
23952 ***********************************************************************/
23954 void
23955 syms_of_xdisp ()
23957 Vwith_echo_area_save_vector = Qnil;
23958 staticpro (&Vwith_echo_area_save_vector);
23960 Vmessage_stack = Qnil;
23961 staticpro (&Vmessage_stack);
23963 Qinhibit_redisplay = intern ("inhibit-redisplay");
23964 staticpro (&Qinhibit_redisplay);
23966 message_dolog_marker1 = Fmake_marker ();
23967 staticpro (&message_dolog_marker1);
23968 message_dolog_marker2 = Fmake_marker ();
23969 staticpro (&message_dolog_marker2);
23970 message_dolog_marker3 = Fmake_marker ();
23971 staticpro (&message_dolog_marker3);
23973 #if GLYPH_DEBUG
23974 defsubr (&Sdump_frame_glyph_matrix);
23975 defsubr (&Sdump_glyph_matrix);
23976 defsubr (&Sdump_glyph_row);
23977 defsubr (&Sdump_tool_bar_row);
23978 defsubr (&Strace_redisplay);
23979 defsubr (&Strace_to_stderr);
23980 #endif
23981 #ifdef HAVE_WINDOW_SYSTEM
23982 defsubr (&Stool_bar_lines_needed);
23983 defsubr (&Slookup_image_map);
23984 #endif
23985 defsubr (&Sformat_mode_line);
23986 defsubr (&Sinvisible_p);
23988 staticpro (&Qmenu_bar_update_hook);
23989 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
23991 staticpro (&Qoverriding_terminal_local_map);
23992 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
23994 staticpro (&Qoverriding_local_map);
23995 Qoverriding_local_map = intern ("overriding-local-map");
23997 staticpro (&Qwindow_scroll_functions);
23998 Qwindow_scroll_functions = intern ("window-scroll-functions");
24000 staticpro (&Qwindow_text_change_functions);
24001 Qwindow_text_change_functions = intern ("window-text-change-functions");
24003 staticpro (&Qredisplay_end_trigger_functions);
24004 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
24006 staticpro (&Qinhibit_point_motion_hooks);
24007 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
24009 QCdata = intern (":data");
24010 staticpro (&QCdata);
24011 Qdisplay = intern ("display");
24012 staticpro (&Qdisplay);
24013 Qspace_width = intern ("space-width");
24014 staticpro (&Qspace_width);
24015 Qraise = intern ("raise");
24016 staticpro (&Qraise);
24017 Qslice = intern ("slice");
24018 staticpro (&Qslice);
24019 Qspace = intern ("space");
24020 staticpro (&Qspace);
24021 Qmargin = intern ("margin");
24022 staticpro (&Qmargin);
24023 Qpointer = intern ("pointer");
24024 staticpro (&Qpointer);
24025 Qleft_margin = intern ("left-margin");
24026 staticpro (&Qleft_margin);
24027 Qright_margin = intern ("right-margin");
24028 staticpro (&Qright_margin);
24029 Qcenter = intern ("center");
24030 staticpro (&Qcenter);
24031 Qline_height = intern ("line-height");
24032 staticpro (&Qline_height);
24033 QCalign_to = intern (":align-to");
24034 staticpro (&QCalign_to);
24035 QCrelative_width = intern (":relative-width");
24036 staticpro (&QCrelative_width);
24037 QCrelative_height = intern (":relative-height");
24038 staticpro (&QCrelative_height);
24039 QCeval = intern (":eval");
24040 staticpro (&QCeval);
24041 QCpropertize = intern (":propertize");
24042 staticpro (&QCpropertize);
24043 QCfile = intern (":file");
24044 staticpro (&QCfile);
24045 Qfontified = intern ("fontified");
24046 staticpro (&Qfontified);
24047 Qfontification_functions = intern ("fontification-functions");
24048 staticpro (&Qfontification_functions);
24049 Qtrailing_whitespace = intern ("trailing-whitespace");
24050 staticpro (&Qtrailing_whitespace);
24051 Qescape_glyph = intern ("escape-glyph");
24052 staticpro (&Qescape_glyph);
24053 Qnobreak_space = intern ("nobreak-space");
24054 staticpro (&Qnobreak_space);
24055 Qimage = intern ("image");
24056 staticpro (&Qimage);
24057 QCmap = intern (":map");
24058 staticpro (&QCmap);
24059 QCpointer = intern (":pointer");
24060 staticpro (&QCpointer);
24061 Qrect = intern ("rect");
24062 staticpro (&Qrect);
24063 Qcircle = intern ("circle");
24064 staticpro (&Qcircle);
24065 Qpoly = intern ("poly");
24066 staticpro (&Qpoly);
24067 Qmessage_truncate_lines = intern ("message-truncate-lines");
24068 staticpro (&Qmessage_truncate_lines);
24069 Qgrow_only = intern ("grow-only");
24070 staticpro (&Qgrow_only);
24071 Qinhibit_menubar_update = intern ("inhibit-menubar-update");
24072 staticpro (&Qinhibit_menubar_update);
24073 Qinhibit_eval_during_redisplay = intern ("inhibit-eval-during-redisplay");
24074 staticpro (&Qinhibit_eval_during_redisplay);
24075 Qposition = intern ("position");
24076 staticpro (&Qposition);
24077 Qbuffer_position = intern ("buffer-position");
24078 staticpro (&Qbuffer_position);
24079 Qobject = intern ("object");
24080 staticpro (&Qobject);
24081 Qbar = intern ("bar");
24082 staticpro (&Qbar);
24083 Qhbar = intern ("hbar");
24084 staticpro (&Qhbar);
24085 Qbox = intern ("box");
24086 staticpro (&Qbox);
24087 Qhollow = intern ("hollow");
24088 staticpro (&Qhollow);
24089 Qhand = intern ("hand");
24090 staticpro (&Qhand);
24091 Qarrow = intern ("arrow");
24092 staticpro (&Qarrow);
24093 Qtext = intern ("text");
24094 staticpro (&Qtext);
24095 Qrisky_local_variable = intern ("risky-local-variable");
24096 staticpro (&Qrisky_local_variable);
24097 Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
24098 staticpro (&Qinhibit_free_realized_faces);
24100 list_of_error = Fcons (Fcons (intern ("error"),
24101 Fcons (intern ("void-variable"), Qnil)),
24102 Qnil);
24103 staticpro (&list_of_error);
24105 Qlast_arrow_position = intern ("last-arrow-position");
24106 staticpro (&Qlast_arrow_position);
24107 Qlast_arrow_string = intern ("last-arrow-string");
24108 staticpro (&Qlast_arrow_string);
24110 Qoverlay_arrow_string = intern ("overlay-arrow-string");
24111 staticpro (&Qoverlay_arrow_string);
24112 Qoverlay_arrow_bitmap = intern ("overlay-arrow-bitmap");
24113 staticpro (&Qoverlay_arrow_bitmap);
24115 echo_buffer[0] = echo_buffer[1] = Qnil;
24116 staticpro (&echo_buffer[0]);
24117 staticpro (&echo_buffer[1]);
24119 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
24120 staticpro (&echo_area_buffer[0]);
24121 staticpro (&echo_area_buffer[1]);
24123 Vmessages_buffer_name = build_string ("*Messages*");
24124 staticpro (&Vmessages_buffer_name);
24126 mode_line_proptrans_alist = Qnil;
24127 staticpro (&mode_line_proptrans_alist);
24128 mode_line_string_list = Qnil;
24129 staticpro (&mode_line_string_list);
24130 mode_line_string_face = Qnil;
24131 staticpro (&mode_line_string_face);
24132 mode_line_string_face_prop = Qnil;
24133 staticpro (&mode_line_string_face_prop);
24134 Vmode_line_unwind_vector = Qnil;
24135 staticpro (&Vmode_line_unwind_vector);
24137 help_echo_string = Qnil;
24138 staticpro (&help_echo_string);
24139 help_echo_object = Qnil;
24140 staticpro (&help_echo_object);
24141 help_echo_window = Qnil;
24142 staticpro (&help_echo_window);
24143 previous_help_echo_string = Qnil;
24144 staticpro (&previous_help_echo_string);
24145 help_echo_pos = -1;
24147 #ifdef HAVE_WINDOW_SYSTEM
24148 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
24149 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
24150 For example, if a block cursor is over a tab, it will be drawn as
24151 wide as that tab on the display. */);
24152 x_stretch_cursor_p = 0;
24153 #endif
24155 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
24156 doc: /* *Non-nil means highlight trailing whitespace.
24157 The face used for trailing whitespace is `trailing-whitespace'. */);
24158 Vshow_trailing_whitespace = Qnil;
24160 DEFVAR_LISP ("nobreak-char-display", &Vnobreak_char_display,
24161 doc: /* *Control highlighting of nobreak space and soft hyphen.
24162 A value of t means highlight the character itself (for nobreak space,
24163 use face `nobreak-space').
24164 A value of nil means no highlighting.
24165 Other values mean display the escape glyph followed by an ordinary
24166 space or ordinary hyphen. */);
24167 Vnobreak_char_display = Qt;
24169 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
24170 doc: /* *The pointer shape to show in void text areas.
24171 A value of nil means to show the text pointer. Other options are `arrow',
24172 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
24173 Vvoid_text_area_pointer = Qarrow;
24175 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
24176 doc: /* Non-nil means don't actually do any redisplay.
24177 This is used for internal purposes. */);
24178 Vinhibit_redisplay = Qnil;
24180 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
24181 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
24182 Vglobal_mode_string = Qnil;
24184 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
24185 doc: /* Marker for where to display an arrow on top of the buffer text.
24186 This must be the beginning of a line in order to work.
24187 See also `overlay-arrow-string'. */);
24188 Voverlay_arrow_position = Qnil;
24190 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
24191 doc: /* String to display as an arrow in non-window frames.
24192 See also `overlay-arrow-position'. */);
24193 Voverlay_arrow_string = build_string ("=>");
24195 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list,
24196 doc: /* List of variables (symbols) which hold markers for overlay arrows.
24197 The symbols on this list are examined during redisplay to determine
24198 where to display overlay arrows. */);
24199 Voverlay_arrow_variable_list
24200 = Fcons (intern ("overlay-arrow-position"), Qnil);
24202 DEFVAR_INT ("scroll-step", &scroll_step,
24203 doc: /* *The number of lines to try scrolling a window by when point moves out.
24204 If that fails to bring point back on frame, point is centered instead.
24205 If this is zero, point is always centered after it moves off frame.
24206 If you want scrolling to always be a line at a time, you should set
24207 `scroll-conservatively' to a large value rather than set this to 1. */);
24209 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
24210 doc: /* *Scroll up to this many lines, to bring point back on screen.
24211 If point moves off-screen, redisplay will scroll by up to
24212 `scroll-conservatively' lines in order to bring point just barely
24213 onto the screen again. If that cannot be done, then redisplay
24214 recenters point as usual.
24216 A value of zero means always recenter point if it moves off screen. */);
24217 scroll_conservatively = 0;
24219 DEFVAR_INT ("scroll-margin", &scroll_margin,
24220 doc: /* *Number of lines of margin at the top and bottom of a window.
24221 Recenter the window whenever point gets within this many lines
24222 of the top or bottom of the window. */);
24223 scroll_margin = 0;
24225 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch,
24226 doc: /* Pixels per inch value for non-window system displays.
24227 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
24228 Vdisplay_pixels_per_inch = make_float (72.0);
24230 #if GLYPH_DEBUG
24231 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
24232 #endif
24234 DEFVAR_BOOL ("truncate-partial-width-windows",
24235 &truncate_partial_width_windows,
24236 doc: /* *Non-nil means truncate lines in all windows less than full frame wide. */);
24237 truncate_partial_width_windows = 1;
24239 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
24240 doc: /* When nil, display the mode-line/header-line/menu-bar in the default face.
24241 Any other value means to use the appropriate face, `mode-line',
24242 `header-line', or `menu' respectively. */);
24243 mode_line_inverse_video = 1;
24245 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
24246 doc: /* *Maximum buffer size for which line number should be displayed.
24247 If the buffer is bigger than this, the line number does not appear
24248 in the mode line. A value of nil means no limit. */);
24249 Vline_number_display_limit = Qnil;
24251 DEFVAR_INT ("line-number-display-limit-width",
24252 &line_number_display_limit_width,
24253 doc: /* *Maximum line width (in characters) for line number display.
24254 If the average length of the lines near point is bigger than this, then the
24255 line number may be omitted from the mode line. */);
24256 line_number_display_limit_width = 200;
24258 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
24259 doc: /* *Non-nil means highlight region even in nonselected windows. */);
24260 highlight_nonselected_windows = 0;
24262 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
24263 doc: /* Non-nil if more than one frame is visible on this display.
24264 Minibuffer-only frames don't count, but iconified frames do.
24265 This variable is not guaranteed to be accurate except while processing
24266 `frame-title-format' and `icon-title-format'. */);
24268 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
24269 doc: /* Template for displaying the title bar of visible frames.
24270 \(Assuming the window manager supports this feature.)
24272 This variable has the same structure as `mode-line-format', except that
24273 the %c and %l constructs are ignored. It is used only on frames for
24274 which no explicit name has been set \(see `modify-frame-parameters'). */);
24276 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
24277 doc: /* Template for displaying the title bar of an iconified frame.
24278 \(Assuming the window manager supports this feature.)
24279 This variable has the same structure as `mode-line-format' (which see),
24280 and is used only on frames for which no explicit name has been set
24281 \(see `modify-frame-parameters'). */);
24282 Vicon_title_format
24283 = Vframe_title_format
24284 = Fcons (intern ("multiple-frames"),
24285 Fcons (build_string ("%b"),
24286 Fcons (Fcons (empty_unibyte_string,
24287 Fcons (intern ("invocation-name"),
24288 Fcons (build_string ("@"),
24289 Fcons (intern ("system-name"),
24290 Qnil)))),
24291 Qnil)));
24293 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
24294 doc: /* Maximum number of lines to keep in the message log buffer.
24295 If nil, disable message logging. If t, log messages but don't truncate
24296 the buffer when it becomes large. */);
24297 Vmessage_log_max = make_number (100);
24299 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
24300 doc: /* Functions called before redisplay, if window sizes have changed.
24301 The value should be a list of functions that take one argument.
24302 Just before redisplay, for each frame, if any of its windows have changed
24303 size since the last redisplay, or have been split or deleted,
24304 all the functions in the list are called, with the frame as argument. */);
24305 Vwindow_size_change_functions = Qnil;
24307 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
24308 doc: /* List of functions to call before redisplaying a window with scrolling.
24309 Each function is called with two arguments, the window
24310 and its new display-start position. Note that the value of `window-end'
24311 is not valid when these functions are called. */);
24312 Vwindow_scroll_functions = Qnil;
24314 DEFVAR_LISP ("window-text-change-functions",
24315 &Vwindow_text_change_functions,
24316 doc: /* Functions to call in redisplay when text in the window might change. */);
24317 Vwindow_text_change_functions = Qnil;
24319 DEFVAR_LISP ("redisplay-end-trigger-functions", &Vredisplay_end_trigger_functions,
24320 doc: /* Functions called when redisplay of a window reaches the end trigger.
24321 Each function is called with two arguments, the window and the end trigger value.
24322 See `set-window-redisplay-end-trigger'. */);
24323 Vredisplay_end_trigger_functions = Qnil;
24325 DEFVAR_LISP ("mouse-autoselect-window", &Vmouse_autoselect_window,
24326 doc: /* *Non-nil means autoselect window with mouse pointer.
24327 If nil, do not autoselect windows.
24328 A positive number means delay autoselection by that many seconds: a
24329 window is autoselected only after the mouse has remained in that
24330 window for the duration of the delay.
24331 A negative number has a similar effect, but causes windows to be
24332 autoselected only after the mouse has stopped moving. \(Because of
24333 the way Emacs compares mouse events, you will occasionally wait twice
24334 that time before the window gets selected.\)
24335 Any other value means to autoselect window instantaneously when the
24336 mouse pointer enters it.
24338 Autoselection selects the minibuffer only if it is active, and never
24339 unselects the minibuffer if it is active.
24341 When customizing this variable make sure that the actual value of
24342 `focus-follows-mouse' matches the behavior of your window manager. */);
24343 Vmouse_autoselect_window = Qnil;
24345 DEFVAR_LISP ("auto-resize-tool-bars", &Vauto_resize_tool_bars,
24346 doc: /* *Non-nil means automatically resize tool-bars.
24347 This dynamically changes the tool-bar's height to the minimum height
24348 that is needed to make all tool-bar items visible.
24349 If value is `grow-only', the tool-bar's height is only increased
24350 automatically; to decrease the tool-bar height, use \\[recenter]. */);
24351 Vauto_resize_tool_bars = Qt;
24353 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
24354 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
24355 auto_raise_tool_bar_buttons_p = 1;
24357 DEFVAR_BOOL ("make-cursor-line-fully-visible", &make_cursor_line_fully_visible_p,
24358 doc: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
24359 make_cursor_line_fully_visible_p = 1;
24361 DEFVAR_LISP ("tool-bar-border", &Vtool_bar_border,
24362 doc: /* *Border below tool-bar in pixels.
24363 If an integer, use it as the height of the border.
24364 If it is one of `internal-border-width' or `border-width', use the
24365 value of the corresponding frame parameter.
24366 Otherwise, no border is added below the tool-bar. */);
24367 Vtool_bar_border = Qinternal_border_width;
24369 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
24370 doc: /* *Margin around tool-bar buttons in pixels.
24371 If an integer, use that for both horizontal and vertical margins.
24372 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
24373 HORZ specifying the horizontal margin, and VERT specifying the
24374 vertical margin. */);
24375 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
24377 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
24378 doc: /* *Relief thickness of tool-bar buttons. */);
24379 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
24381 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
24382 doc: /* List of functions to call to fontify regions of text.
24383 Each function is called with one argument POS. Functions must
24384 fontify a region starting at POS in the current buffer, and give
24385 fontified regions the property `fontified'. */);
24386 Vfontification_functions = Qnil;
24387 Fmake_variable_buffer_local (Qfontification_functions);
24389 DEFVAR_BOOL ("unibyte-display-via-language-environment",
24390 &unibyte_display_via_language_environment,
24391 doc: /* *Non-nil means display unibyte text according to language environment.
24392 Specifically this means that unibyte non-ASCII characters
24393 are displayed by converting them to the equivalent multibyte characters
24394 according to the current language environment. As a result, they are
24395 displayed according to the current fontset. */);
24396 unibyte_display_via_language_environment = 0;
24398 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
24399 doc: /* *Maximum height for resizing mini-windows.
24400 If a float, it specifies a fraction of the mini-window frame's height.
24401 If an integer, it specifies a number of lines. */);
24402 Vmax_mini_window_height = make_float (0.25);
24404 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
24405 doc: /* *How to resize mini-windows.
24406 A value of nil means don't automatically resize mini-windows.
24407 A value of t means resize them to fit the text displayed in them.
24408 A value of `grow-only', the default, means let mini-windows grow
24409 only, until their display becomes empty, at which point the windows
24410 go back to their normal size. */);
24411 Vresize_mini_windows = Qgrow_only;
24413 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
24414 doc: /* Alist specifying how to blink the cursor off.
24415 Each element has the form (ON-STATE . OFF-STATE). Whenever the
24416 `cursor-type' frame-parameter or variable equals ON-STATE,
24417 comparing using `equal', Emacs uses OFF-STATE to specify
24418 how to blink it off. ON-STATE and OFF-STATE are values for
24419 the `cursor-type' frame parameter.
24421 If a frame's ON-STATE has no entry in this list,
24422 the frame's other specifications determine how to blink the cursor off. */);
24423 Vblink_cursor_alist = Qnil;
24425 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
24426 doc: /* *Non-nil means scroll the display automatically to make point visible. */);
24427 automatic_hscrolling_p = 1;
24428 Qauto_hscroll_mode = intern ("auto-hscroll-mode");
24429 staticpro (&Qauto_hscroll_mode);
24431 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
24432 doc: /* *How many columns away from the window edge point is allowed to get
24433 before automatic hscrolling will horizontally scroll the window. */);
24434 hscroll_margin = 5;
24436 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
24437 doc: /* *How many columns to scroll the window when point gets too close to the edge.
24438 When point is less than `hscroll-margin' columns from the window
24439 edge, automatic hscrolling will scroll the window by the amount of columns
24440 determined by this variable. If its value is a positive integer, scroll that
24441 many columns. If it's a positive floating-point number, it specifies the
24442 fraction of the window's width to scroll. If it's nil or zero, point will be
24443 centered horizontally after the scroll. Any other value, including negative
24444 numbers, are treated as if the value were zero.
24446 Automatic hscrolling always moves point outside the scroll margin, so if
24447 point was more than scroll step columns inside the margin, the window will
24448 scroll more than the value given by the scroll step.
24450 Note that the lower bound for automatic hscrolling specified by `scroll-left'
24451 and `scroll-right' overrides this variable's effect. */);
24452 Vhscroll_step = make_number (0);
24454 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
24455 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
24456 Bind this around calls to `message' to let it take effect. */);
24457 message_truncate_lines = 0;
24459 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
24460 doc: /* Normal hook run to update the menu bar definitions.
24461 Redisplay runs this hook before it redisplays the menu bar.
24462 This is used to update submenus such as Buffers,
24463 whose contents depend on various data. */);
24464 Vmenu_bar_update_hook = Qnil;
24466 DEFVAR_LISP ("menu-updating-frame", &Vmenu_updating_frame,
24467 doc: /* Frame for which we are updating a menu.
24468 The enable predicate for a menu binding should check this variable. */);
24469 Vmenu_updating_frame = Qnil;
24471 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
24472 doc: /* Non-nil means don't update menu bars. Internal use only. */);
24473 inhibit_menubar_update = 0;
24475 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
24476 doc: /* Non-nil means don't eval Lisp during redisplay. */);
24477 inhibit_eval_during_redisplay = 0;
24479 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
24480 doc: /* Non-nil means don't free realized faces. Internal use only. */);
24481 inhibit_free_realized_faces = 0;
24483 #if GLYPH_DEBUG
24484 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
24485 doc: /* Inhibit try_window_id display optimization. */);
24486 inhibit_try_window_id = 0;
24488 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
24489 doc: /* Inhibit try_window_reusing display optimization. */);
24490 inhibit_try_window_reusing = 0;
24492 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
24493 doc: /* Inhibit try_cursor_movement display optimization. */);
24494 inhibit_try_cursor_movement = 0;
24495 #endif /* GLYPH_DEBUG */
24497 DEFVAR_INT ("overline-margin", &overline_margin,
24498 doc: /* *Space between overline and text, in pixels.
24499 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
24500 margin to the caracter height. */);
24501 overline_margin = 2;
24505 /* Initialize this module when Emacs starts. */
24507 void
24508 init_xdisp ()
24510 Lisp_Object root_window;
24511 struct window *mini_w;
24513 current_header_line_height = current_mode_line_height = -1;
24515 CHARPOS (this_line_start_pos) = 0;
24517 mini_w = XWINDOW (minibuf_window);
24518 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
24520 if (!noninteractive)
24522 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
24523 int i;
24525 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
24526 set_window_height (root_window,
24527 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
24529 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
24530 set_window_height (minibuf_window, 1, 0);
24532 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
24533 mini_w->total_cols = make_number (FRAME_COLS (f));
24535 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
24536 scratch_glyph_row.glyphs[TEXT_AREA + 1]
24537 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
24539 /* The default ellipsis glyphs `...'. */
24540 for (i = 0; i < 3; ++i)
24541 default_invis_vector[i] = make_number ('.');
24545 /* Allocate the buffer for frame titles.
24546 Also used for `format-mode-line'. */
24547 int size = 100;
24548 mode_line_noprop_buf = (char *) xmalloc (size);
24549 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
24550 mode_line_noprop_ptr = mode_line_noprop_buf;
24551 mode_line_target = MODE_LINE_DISPLAY;
24554 help_echo_showing_p = 0;
24558 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
24559 (do not change this comment) */