*** empty log message ***
[emacs.git] / src / xdisp.c
blob7bccdc105203866b765cd88cb53e32f9a8ce1ff3
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 "character.h"
181 #include "charset.h"
182 #include "indent.h"
183 #include "commands.h"
184 #include "keymap.h"
185 #include "macros.h"
186 #include "disptab.h"
187 #include "termhooks.h"
188 #include "intervals.h"
189 #include "coding.h"
190 #include "process.h"
191 #include "region-cache.h"
192 #include "fontset.h"
193 #include "blockinput.h"
195 #ifdef HAVE_X_WINDOWS
196 #include "xterm.h"
197 #endif
198 #ifdef WINDOWSNT
199 #include "w32term.h"
200 #endif
201 #ifdef MAC_OS
202 #include "macterm.h"
203 #endif
205 #ifdef HAVE_WINDOW_SYSTEM
206 #include "font.h"
207 #endif /* HAVE_WINDOW_SYSTEM */
209 #ifndef FRAME_X_OUTPUT
210 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
211 #endif
213 #define INFINITY 10000000
215 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
216 || defined (USE_GTK)
217 extern void set_frame_menubar P_ ((struct frame *f, int, int));
218 extern int pending_menu_activation;
219 #endif
221 extern int interrupt_input;
222 extern int command_loop_level;
224 extern Lisp_Object do_mouse_tracking;
226 extern int minibuffer_auto_raise;
227 extern Lisp_Object Vminibuffer_list;
229 extern Lisp_Object Qface;
230 extern Lisp_Object Qmode_line, Qmode_line_inactive, Qheader_line;
232 extern Lisp_Object Voverriding_local_map;
233 extern Lisp_Object Voverriding_local_map_menu_flag;
234 extern Lisp_Object Qmenu_item;
235 extern Lisp_Object Qwhen;
236 extern Lisp_Object Qhelp_echo;
238 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
239 Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
240 Lisp_Object Qwindow_text_change_functions, Vwindow_text_change_functions;
241 Lisp_Object Qredisplay_end_trigger_functions, Vredisplay_end_trigger_functions;
242 Lisp_Object Qinhibit_point_motion_hooks;
243 Lisp_Object QCeval, QCfile, QCdata, QCpropertize;
244 Lisp_Object Qfontified;
245 Lisp_Object Qgrow_only;
246 Lisp_Object Qinhibit_eval_during_redisplay;
247 Lisp_Object Qbuffer_position, Qposition, Qobject;
249 /* Cursor shapes */
250 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
252 /* Pointer shapes */
253 Lisp_Object Qarrow, Qhand, Qtext;
255 Lisp_Object Qrisky_local_variable;
257 /* Holds the list (error). */
258 Lisp_Object list_of_error;
260 /* Functions called to fontify regions of text. */
262 Lisp_Object Vfontification_functions;
263 Lisp_Object Qfontification_functions;
265 /* Non-nil means automatically select any window when the mouse
266 cursor moves into it. */
267 Lisp_Object Vmouse_autoselect_window;
269 /* Non-zero means draw tool bar buttons raised when the mouse moves
270 over them. */
272 int auto_raise_tool_bar_buttons_p;
274 /* Non-zero means to reposition window if cursor line is only partially visible. */
276 int make_cursor_line_fully_visible_p;
278 /* Margin below tool bar in pixels. 0 or nil means no margin.
279 If value is `internal-border-width' or `border-width',
280 the corresponding frame parameter is used. */
282 Lisp_Object Vtool_bar_border;
284 /* Margin around tool bar buttons in pixels. */
286 Lisp_Object Vtool_bar_button_margin;
288 /* Thickness of shadow to draw around tool bar buttons. */
290 EMACS_INT tool_bar_button_relief;
292 /* Non-nil means automatically resize tool-bars so that all tool-bar
293 items are visible, and no blank lines remain.
295 If value is `grow-only', only make tool-bar bigger. */
297 Lisp_Object Vauto_resize_tool_bars;
299 /* Non-zero means draw block and hollow cursor as wide as the glyph
300 under it. For example, if a block cursor is over a tab, it will be
301 drawn as wide as that tab on the display. */
303 int x_stretch_cursor_p;
305 /* Non-nil means don't actually do any redisplay. */
307 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
309 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
311 int inhibit_eval_during_redisplay;
313 /* Names of text properties relevant for redisplay. */
315 Lisp_Object Qdisplay;
316 extern Lisp_Object Qface, Qinvisible, Qwidth;
318 /* Symbols used in text property values. */
320 Lisp_Object Vdisplay_pixels_per_inch;
321 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
322 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
323 Lisp_Object Qslice;
324 Lisp_Object Qcenter;
325 Lisp_Object Qmargin, Qpointer;
326 Lisp_Object Qline_height;
327 extern Lisp_Object Qheight;
328 extern Lisp_Object QCwidth, QCheight, QCascent;
329 extern Lisp_Object Qscroll_bar;
330 extern Lisp_Object Qcursor;
332 /* Non-nil means highlight trailing whitespace. */
334 Lisp_Object Vshow_trailing_whitespace;
336 /* Non-nil means escape non-break space and hyphens. */
338 Lisp_Object Vnobreak_char_display;
340 #ifdef HAVE_WINDOW_SYSTEM
341 extern Lisp_Object Voverflow_newline_into_fringe;
343 /* Test if overflow newline into fringe. Called with iterator IT
344 at or past right window margin, and with IT->current_x set. */
346 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) \
347 (!NILP (Voverflow_newline_into_fringe) \
348 && FRAME_WINDOW_P (it->f) \
349 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
350 && it->current_x == it->last_visible_x)
352 #endif /* HAVE_WINDOW_SYSTEM */
354 /* Non-nil means show the text cursor in void text areas
355 i.e. in blank areas after eol and eob. This used to be
356 the default in 21.3. */
358 Lisp_Object Vvoid_text_area_pointer;
360 /* Name of the face used to highlight trailing whitespace. */
362 Lisp_Object Qtrailing_whitespace;
364 /* Name and number of the face used to highlight escape glyphs. */
366 Lisp_Object Qescape_glyph;
368 /* Name and number of the face used to highlight non-breaking spaces. */
370 Lisp_Object Qnobreak_space;
372 /* The symbol `image' which is the car of the lists used to represent
373 images in Lisp. */
375 Lisp_Object Qimage;
377 /* The image map types. */
378 Lisp_Object QCmap, QCpointer;
379 Lisp_Object Qrect, Qcircle, Qpoly;
381 /* Non-zero means print newline to stdout before next mini-buffer
382 message. */
384 int noninteractive_need_newline;
386 /* Non-zero means print newline to message log before next message. */
388 static int message_log_need_newline;
390 /* Three markers that message_dolog uses.
391 It could allocate them itself, but that causes trouble
392 in handling memory-full errors. */
393 static Lisp_Object message_dolog_marker1;
394 static Lisp_Object message_dolog_marker2;
395 static Lisp_Object message_dolog_marker3;
397 /* The buffer position of the first character appearing entirely or
398 partially on the line of the selected window which contains the
399 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
400 redisplay optimization in redisplay_internal. */
402 static struct text_pos this_line_start_pos;
404 /* Number of characters past the end of the line above, including the
405 terminating newline. */
407 static struct text_pos this_line_end_pos;
409 /* The vertical positions and the height of this line. */
411 static int this_line_vpos;
412 static int this_line_y;
413 static int this_line_pixel_height;
415 /* X position at which this display line starts. Usually zero;
416 negative if first character is partially visible. */
418 static int this_line_start_x;
420 /* Buffer that this_line_.* variables are referring to. */
422 static struct buffer *this_line_buffer;
424 /* Nonzero means truncate lines in all windows less wide than the
425 frame. */
427 int truncate_partial_width_windows;
429 /* A flag to control how to display unibyte 8-bit character. */
431 int unibyte_display_via_language_environment;
433 /* Nonzero means we have more than one non-mini-buffer-only frame.
434 Not guaranteed to be accurate except while parsing
435 frame-title-format. */
437 int multiple_frames;
439 Lisp_Object Vglobal_mode_string;
442 /* List of variables (symbols) which hold markers for overlay arrows.
443 The symbols on this list are examined during redisplay to determine
444 where to display overlay arrows. */
446 Lisp_Object Voverlay_arrow_variable_list;
448 /* Marker for where to display an arrow on top of the buffer text. */
450 Lisp_Object Voverlay_arrow_position;
452 /* String to display for the arrow. Only used on terminal frames. */
454 Lisp_Object Voverlay_arrow_string;
456 /* Values of those variables at last redisplay are stored as
457 properties on `overlay-arrow-position' symbol. However, if
458 Voverlay_arrow_position is a marker, last-arrow-position is its
459 numerical position. */
461 Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
463 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
464 properties on a symbol in overlay-arrow-variable-list. */
466 Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
468 /* Like mode-line-format, but for the title bar on a visible frame. */
470 Lisp_Object Vframe_title_format;
472 /* Like mode-line-format, but for the title bar on an iconified frame. */
474 Lisp_Object Vicon_title_format;
476 /* List of functions to call when a window's size changes. These
477 functions get one arg, a frame on which one or more windows' sizes
478 have changed. */
480 static Lisp_Object Vwindow_size_change_functions;
482 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
484 /* Nonzero if an overlay arrow has been displayed in this window. */
486 static int overlay_arrow_seen;
488 /* Nonzero means highlight the region even in nonselected windows. */
490 int highlight_nonselected_windows;
492 /* If cursor motion alone moves point off frame, try scrolling this
493 many lines up or down if that will bring it back. */
495 static EMACS_INT scroll_step;
497 /* Nonzero means scroll just far enough to bring point back on the
498 screen, when appropriate. */
500 static EMACS_INT scroll_conservatively;
502 /* Recenter the window whenever point gets within this many lines of
503 the top or bottom of the window. This value is translated into a
504 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
505 that there is really a fixed pixel height scroll margin. */
507 EMACS_INT scroll_margin;
509 /* Number of windows showing the buffer of the selected window (or
510 another buffer with the same base buffer). keyboard.c refers to
511 this. */
513 int buffer_shared;
515 /* Vector containing glyphs for an ellipsis `...'. */
517 static Lisp_Object default_invis_vector[3];
519 /* Zero means display the mode-line/header-line/menu-bar in the default face
520 (this slightly odd definition is for compatibility with previous versions
521 of emacs), non-zero means display them using their respective faces.
523 This variable is deprecated. */
525 int mode_line_inverse_video;
527 /* Prompt to display in front of the mini-buffer contents. */
529 Lisp_Object minibuf_prompt;
531 /* Width of current mini-buffer prompt. Only set after display_line
532 of the line that contains the prompt. */
534 int minibuf_prompt_width;
536 /* This is the window where the echo area message was displayed. It
537 is always a mini-buffer window, but it may not be the same window
538 currently active as a mini-buffer. */
540 Lisp_Object echo_area_window;
542 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
543 pushes the current message and the value of
544 message_enable_multibyte on the stack, the function restore_message
545 pops the stack and displays MESSAGE again. */
547 Lisp_Object Vmessage_stack;
549 /* Nonzero means multibyte characters were enabled when the echo area
550 message was specified. */
552 int message_enable_multibyte;
554 /* Nonzero if we should redraw the mode lines on the next redisplay. */
556 int update_mode_lines;
558 /* Nonzero if window sizes or contents have changed since last
559 redisplay that finished. */
561 int windows_or_buffers_changed;
563 /* Nonzero means a frame's cursor type has been changed. */
565 int cursor_type_changed;
567 /* Nonzero after display_mode_line if %l was used and it displayed a
568 line number. */
570 int line_number_displayed;
572 /* Maximum buffer size for which to display line numbers. */
574 Lisp_Object Vline_number_display_limit;
576 /* Line width to consider when repositioning for line number display. */
578 static EMACS_INT line_number_display_limit_width;
580 /* Number of lines to keep in the message log buffer. t means
581 infinite. nil means don't log at all. */
583 Lisp_Object Vmessage_log_max;
585 /* The name of the *Messages* buffer, a string. */
587 static Lisp_Object Vmessages_buffer_name;
589 /* Current, index 0, and last displayed echo area message. Either
590 buffers from echo_buffers, or nil to indicate no message. */
592 Lisp_Object echo_area_buffer[2];
594 /* The buffers referenced from echo_area_buffer. */
596 static Lisp_Object echo_buffer[2];
598 /* A vector saved used in with_area_buffer to reduce consing. */
600 static Lisp_Object Vwith_echo_area_save_vector;
602 /* Non-zero means display_echo_area should display the last echo area
603 message again. Set by redisplay_preserve_echo_area. */
605 static int display_last_displayed_message_p;
607 /* Nonzero if echo area is being used by print; zero if being used by
608 message. */
610 int message_buf_print;
612 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
614 Lisp_Object Qinhibit_menubar_update;
615 int inhibit_menubar_update;
617 /* When evaluating expressions from menu bar items (enable conditions,
618 for instance), this is the frame they are being processed for. */
620 Lisp_Object Vmenu_updating_frame;
622 /* Maximum height for resizing mini-windows. Either a float
623 specifying a fraction of the available height, or an integer
624 specifying a number of lines. */
626 Lisp_Object Vmax_mini_window_height;
628 /* Non-zero means messages should be displayed with truncated
629 lines instead of being continued. */
631 int message_truncate_lines;
632 Lisp_Object Qmessage_truncate_lines;
634 /* Set to 1 in clear_message to make redisplay_internal aware
635 of an emptied echo area. */
637 static int message_cleared_p;
639 /* How to blink the default frame cursor off. */
640 Lisp_Object Vblink_cursor_alist;
642 /* A scratch glyph row with contents used for generating truncation
643 glyphs. Also used in direct_output_for_insert. */
645 #define MAX_SCRATCH_GLYPHS 100
646 struct glyph_row scratch_glyph_row;
647 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
649 /* Ascent and height of the last line processed by move_it_to. */
651 static int last_max_ascent, last_height;
653 /* Non-zero if there's a help-echo in the echo area. */
655 int help_echo_showing_p;
657 /* If >= 0, computed, exact values of mode-line and header-line height
658 to use in the macros CURRENT_MODE_LINE_HEIGHT and
659 CURRENT_HEADER_LINE_HEIGHT. */
661 int current_mode_line_height, current_header_line_height;
663 /* The maximum distance to look ahead for text properties. Values
664 that are too small let us call compute_char_face and similar
665 functions too often which is expensive. Values that are too large
666 let us call compute_char_face and alike too often because we
667 might not be interested in text properties that far away. */
669 #define TEXT_PROP_DISTANCE_LIMIT 100
671 #if GLYPH_DEBUG
673 /* Variables to turn off display optimizations from Lisp. */
675 int inhibit_try_window_id, inhibit_try_window_reusing;
676 int inhibit_try_cursor_movement;
678 /* Non-zero means print traces of redisplay if compiled with
679 GLYPH_DEBUG != 0. */
681 int trace_redisplay_p;
683 #endif /* GLYPH_DEBUG */
685 #ifdef DEBUG_TRACE_MOVE
686 /* Non-zero means trace with TRACE_MOVE to stderr. */
687 int trace_move;
689 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
690 #else
691 #define TRACE_MOVE(x) (void) 0
692 #endif
694 /* Non-zero means automatically scroll windows horizontally to make
695 point visible. */
697 int automatic_hscrolling_p;
698 Lisp_Object Qauto_hscroll_mode;
700 /* How close to the margin can point get before the window is scrolled
701 horizontally. */
702 EMACS_INT hscroll_margin;
704 /* How much to scroll horizontally when point is inside the above margin. */
705 Lisp_Object Vhscroll_step;
707 /* The variable `resize-mini-windows'. If nil, don't resize
708 mini-windows. If t, always resize them to fit the text they
709 display. If `grow-only', let mini-windows grow only until they
710 become empty. */
712 Lisp_Object Vresize_mini_windows;
714 /* Buffer being redisplayed -- for redisplay_window_error. */
716 struct buffer *displayed_buffer;
718 /* Space between overline and text. */
720 EMACS_INT overline_margin;
722 /* Value returned from text property handlers (see below). */
724 enum prop_handled
726 HANDLED_NORMALLY,
727 HANDLED_RECOMPUTE_PROPS,
728 HANDLED_OVERLAY_STRING_CONSUMED,
729 HANDLED_RETURN
732 /* A description of text properties that redisplay is interested
733 in. */
735 struct props
737 /* The name of the property. */
738 Lisp_Object *name;
740 /* A unique index for the property. */
741 enum prop_idx idx;
743 /* A handler function called to set up iterator IT from the property
744 at IT's current position. Value is used to steer handle_stop. */
745 enum prop_handled (*handler) P_ ((struct it *it));
748 static enum prop_handled handle_face_prop P_ ((struct it *));
749 static enum prop_handled handle_invisible_prop P_ ((struct it *));
750 static enum prop_handled handle_display_prop P_ ((struct it *));
751 static enum prop_handled handle_composition_prop P_ ((struct it *));
752 static enum prop_handled handle_overlay_change P_ ((struct it *));
753 static enum prop_handled handle_fontified_prop P_ ((struct it *));
754 static enum prop_handled handle_auto_composed_prop P_ ((struct it *));
756 /* Properties handled by iterators. */
758 static struct props it_props[] =
760 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
761 /* Handle `face' before `display' because some sub-properties of
762 `display' need to know the face. */
763 {&Qface, FACE_PROP_IDX, handle_face_prop},
764 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
765 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
766 {&Qauto_composed, AUTO_COMPOSED_PROP_IDX, handle_auto_composed_prop},
767 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
768 {NULL, 0, NULL}
771 /* Value is the position described by X. If X is a marker, value is
772 the marker_position of X. Otherwise, value is X. */
774 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
776 /* Enumeration returned by some move_it_.* functions internally. */
778 enum move_it_result
780 /* Not used. Undefined value. */
781 MOVE_UNDEFINED,
783 /* Move ended at the requested buffer position or ZV. */
784 MOVE_POS_MATCH_OR_ZV,
786 /* Move ended at the requested X pixel position. */
787 MOVE_X_REACHED,
789 /* Move within a line ended at the end of a line that must be
790 continued. */
791 MOVE_LINE_CONTINUED,
793 /* Move within a line ended at the end of a line that would
794 be displayed truncated. */
795 MOVE_LINE_TRUNCATED,
797 /* Move within a line ended at a line end. */
798 MOVE_NEWLINE_OR_CR
801 /* This counter is used to clear the face cache every once in a while
802 in redisplay_internal. It is incremented for each redisplay.
803 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
804 cleared. */
806 #define CLEAR_FACE_CACHE_COUNT 500
807 static int clear_face_cache_count;
809 /* Similarly for the image cache. */
811 #ifdef HAVE_WINDOW_SYSTEM
812 #define CLEAR_IMAGE_CACHE_COUNT 101
813 static int clear_image_cache_count;
814 #endif
816 /* Non-zero while redisplay_internal is in progress. */
818 int redisplaying_p;
820 /* Non-zero means don't free realized faces. Bound while freeing
821 realized faces is dangerous because glyph matrices might still
822 reference them. */
824 int inhibit_free_realized_faces;
825 Lisp_Object Qinhibit_free_realized_faces;
827 /* If a string, XTread_socket generates an event to display that string.
828 (The display is done in read_char.) */
830 Lisp_Object help_echo_string;
831 Lisp_Object help_echo_window;
832 Lisp_Object help_echo_object;
833 int help_echo_pos;
835 /* Temporary variable for XTread_socket. */
837 Lisp_Object previous_help_echo_string;
839 /* Null glyph slice */
841 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
844 /* Function prototypes. */
846 static void setup_for_ellipsis P_ ((struct it *, int));
847 static void mark_window_display_accurate_1 P_ ((struct window *, int));
848 static int single_display_spec_string_p P_ ((Lisp_Object, Lisp_Object));
849 static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
850 static int cursor_row_p P_ ((struct window *, struct glyph_row *));
851 static int redisplay_mode_lines P_ ((Lisp_Object, int));
852 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
854 #if 0
855 static int invisible_text_between_p P_ ((struct it *, int, int));
856 #endif
858 static void pint2str P_ ((char *, int, int));
859 static void pint2hrstr P_ ((char *, int, int));
860 static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
861 struct text_pos));
862 static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
863 static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
864 static void store_mode_line_noprop_char P_ ((char));
865 static int store_mode_line_noprop P_ ((const unsigned char *, int, int));
866 static void x_consider_frame_title P_ ((Lisp_Object));
867 static void handle_stop P_ ((struct it *));
868 static int tool_bar_lines_needed P_ ((struct frame *, int *));
869 static int single_display_spec_intangible_p P_ ((Lisp_Object));
870 static void ensure_echo_area_buffers P_ ((void));
871 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
872 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
873 static int with_echo_area_buffer P_ ((struct window *, int,
874 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
875 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
876 static void clear_garbaged_frames P_ ((void));
877 static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
878 static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
879 static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
880 static int display_echo_area P_ ((struct window *));
881 static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
882 static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
883 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
884 static int string_char_and_length P_ ((const unsigned char *, int, int *));
885 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
886 struct text_pos));
887 static int compute_window_start_on_continuation_line P_ ((struct window *));
888 static Lisp_Object safe_eval_handler P_ ((Lisp_Object));
889 static void insert_left_trunc_glyphs P_ ((struct it *));
890 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *,
891 Lisp_Object));
892 static void extend_face_to_end_of_line P_ ((struct it *));
893 static int append_space_for_newline P_ ((struct it *, int));
894 static int cursor_row_fully_visible_p P_ ((struct window *, int, int));
895 static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
896 static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
897 static int trailing_whitespace_p P_ ((int));
898 static int message_log_check_duplicate P_ ((int, int, int, int));
899 static void push_it P_ ((struct it *));
900 static void pop_it P_ ((struct it *));
901 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
902 static void select_frame_for_redisplay P_ ((Lisp_Object));
903 static void redisplay_internal P_ ((int));
904 static int echo_area_display P_ ((int));
905 static void redisplay_windows P_ ((Lisp_Object));
906 static void redisplay_window P_ ((Lisp_Object, int));
907 static Lisp_Object redisplay_window_error ();
908 static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
909 static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
910 static int update_menu_bar P_ ((struct frame *, int, int));
911 static int try_window_reusing_current_matrix P_ ((struct window *));
912 static int try_window_id P_ ((struct window *));
913 static int display_line P_ ((struct it *));
914 static int display_mode_lines P_ ((struct window *));
915 static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
916 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
917 static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
918 static char *decode_mode_spec P_ ((struct window *, int, int, int, int *));
919 static void display_menu_bar P_ ((struct window *));
920 static int display_count_lines P_ ((int, int, int, int, int *));
921 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
922 EMACS_INT, EMACS_INT, struct it *, int, int, int, int));
923 static void compute_line_metrics P_ ((struct it *));
924 static void run_redisplay_end_trigger_hook P_ ((struct it *));
925 static int get_overlay_strings P_ ((struct it *, int));
926 static int get_overlay_strings_1 P_ ((struct it *, int, int));
927 static void next_overlay_string P_ ((struct it *));
928 static void reseat P_ ((struct it *, struct text_pos, int));
929 static void reseat_1 P_ ((struct it *, struct text_pos, int));
930 static void back_to_previous_visible_line_start P_ ((struct it *));
931 void reseat_at_previous_visible_line_start P_ ((struct it *));
932 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
933 static int next_element_from_ellipsis P_ ((struct it *));
934 static int next_element_from_display_vector P_ ((struct it *));
935 static int next_element_from_string P_ ((struct it *));
936 static int next_element_from_c_string P_ ((struct it *));
937 static int next_element_from_buffer P_ ((struct it *));
938 static int next_element_from_composition P_ ((struct it *));
939 static int next_element_from_image P_ ((struct it *));
940 static int next_element_from_stretch P_ ((struct it *));
941 static void load_overlay_strings P_ ((struct it *, int));
942 static int init_from_display_pos P_ ((struct it *, struct window *,
943 struct display_pos *));
944 static void reseat_to_string P_ ((struct it *, unsigned char *,
945 Lisp_Object, int, int, int, int));
946 static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
947 int, int, int));
948 void move_it_vertically_backward P_ ((struct it *, int));
949 static void init_to_row_start P_ ((struct it *, struct window *,
950 struct glyph_row *));
951 static int init_to_row_end P_ ((struct it *, struct window *,
952 struct glyph_row *));
953 static void back_to_previous_line_start P_ ((struct it *));
954 static int forward_to_next_line_start P_ ((struct it *, int *));
955 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
956 Lisp_Object, int));
957 static struct text_pos string_pos P_ ((int, Lisp_Object));
958 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
959 static int number_of_chars P_ ((unsigned char *, int));
960 static void compute_stop_pos P_ ((struct it *));
961 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
962 Lisp_Object));
963 static int face_before_or_after_it_pos P_ ((struct it *, int));
964 static EMACS_INT next_overlay_change P_ ((EMACS_INT));
965 static int handle_single_display_spec P_ ((struct it *, Lisp_Object,
966 Lisp_Object, Lisp_Object,
967 struct text_pos *, int));
968 static int underlying_face_id P_ ((struct it *));
969 static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
970 struct window *));
972 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
973 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
975 #ifdef HAVE_WINDOW_SYSTEM
977 static void update_tool_bar P_ ((struct frame *, int));
978 static void build_desired_tool_bar_string P_ ((struct frame *f));
979 static int redisplay_tool_bar P_ ((struct frame *));
980 static void display_tool_bar_line P_ ((struct it *, int));
981 static void notice_overwritten_cursor P_ ((struct window *,
982 enum glyph_row_area,
983 int, int, int, int));
987 #endif /* HAVE_WINDOW_SYSTEM */
990 /***********************************************************************
991 Window display dimensions
992 ***********************************************************************/
994 /* Return the bottom boundary y-position for text lines in window W.
995 This is the first y position at which a line cannot start.
996 It is relative to the top of the window.
998 This is the height of W minus the height of a mode line, if any. */
1000 INLINE int
1001 window_text_bottom_y (w)
1002 struct window *w;
1004 int height = WINDOW_TOTAL_HEIGHT (w);
1006 if (WINDOW_WANTS_MODELINE_P (w))
1007 height -= CURRENT_MODE_LINE_HEIGHT (w);
1008 return height;
1011 /* Return the pixel width of display area AREA of window W. AREA < 0
1012 means return the total width of W, not including fringes to
1013 the left and right of the window. */
1015 INLINE int
1016 window_box_width (w, area)
1017 struct window *w;
1018 int area;
1020 int cols = XFASTINT (w->total_cols);
1021 int pixels = 0;
1023 if (!w->pseudo_window_p)
1025 cols -= WINDOW_SCROLL_BAR_COLS (w);
1027 if (area == TEXT_AREA)
1029 if (INTEGERP (w->left_margin_cols))
1030 cols -= XFASTINT (w->left_margin_cols);
1031 if (INTEGERP (w->right_margin_cols))
1032 cols -= XFASTINT (w->right_margin_cols);
1033 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
1035 else if (area == LEFT_MARGIN_AREA)
1037 cols = (INTEGERP (w->left_margin_cols)
1038 ? XFASTINT (w->left_margin_cols) : 0);
1039 pixels = 0;
1041 else if (area == RIGHT_MARGIN_AREA)
1043 cols = (INTEGERP (w->right_margin_cols)
1044 ? XFASTINT (w->right_margin_cols) : 0);
1045 pixels = 0;
1049 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1053 /* Return the pixel height of the display area of window W, not
1054 including mode lines of W, if any. */
1056 INLINE int
1057 window_box_height (w)
1058 struct window *w;
1060 struct frame *f = XFRAME (w->frame);
1061 int height = WINDOW_TOTAL_HEIGHT (w);
1063 xassert (height >= 0);
1065 /* Note: the code below that determines the mode-line/header-line
1066 height is essentially the same as that contained in the macro
1067 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1068 the appropriate glyph row has its `mode_line_p' flag set,
1069 and if it doesn't, uses estimate_mode_line_height instead. */
1071 if (WINDOW_WANTS_MODELINE_P (w))
1073 struct glyph_row *ml_row
1074 = (w->current_matrix && w->current_matrix->rows
1075 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1076 : 0);
1077 if (ml_row && ml_row->mode_line_p)
1078 height -= ml_row->height;
1079 else
1080 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1083 if (WINDOW_WANTS_HEADER_LINE_P (w))
1085 struct glyph_row *hl_row
1086 = (w->current_matrix && w->current_matrix->rows
1087 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1088 : 0);
1089 if (hl_row && hl_row->mode_line_p)
1090 height -= hl_row->height;
1091 else
1092 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1095 /* With a very small font and a mode-line that's taller than
1096 default, we might end up with a negative height. */
1097 return max (0, height);
1100 /* Return the window-relative coordinate of the left edge of display
1101 area AREA of window W. AREA < 0 means return the left edge of the
1102 whole window, to the right of the left fringe of W. */
1104 INLINE int
1105 window_box_left_offset (w, area)
1106 struct window *w;
1107 int area;
1109 int x;
1111 if (w->pseudo_window_p)
1112 return 0;
1114 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1116 if (area == TEXT_AREA)
1117 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1118 + window_box_width (w, LEFT_MARGIN_AREA));
1119 else if (area == RIGHT_MARGIN_AREA)
1120 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1121 + window_box_width (w, LEFT_MARGIN_AREA)
1122 + window_box_width (w, TEXT_AREA)
1123 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1125 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1126 else if (area == LEFT_MARGIN_AREA
1127 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1128 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1130 return x;
1134 /* Return the window-relative coordinate of the right edge of display
1135 area AREA of window W. AREA < 0 means return the left edge of the
1136 whole window, to the left of the right fringe of W. */
1138 INLINE int
1139 window_box_right_offset (w, area)
1140 struct window *w;
1141 int area;
1143 return window_box_left_offset (w, area) + window_box_width (w, area);
1146 /* Return the frame-relative coordinate of the left edge of display
1147 area AREA of window W. AREA < 0 means return the left edge of the
1148 whole window, to the right of the left fringe of W. */
1150 INLINE int
1151 window_box_left (w, area)
1152 struct window *w;
1153 int area;
1155 struct frame *f = XFRAME (w->frame);
1156 int x;
1158 if (w->pseudo_window_p)
1159 return FRAME_INTERNAL_BORDER_WIDTH (f);
1161 x = (WINDOW_LEFT_EDGE_X (w)
1162 + window_box_left_offset (w, area));
1164 return x;
1168 /* Return the frame-relative coordinate of the right edge of display
1169 area AREA of window W. AREA < 0 means return the left edge of the
1170 whole window, to the left of the right fringe of W. */
1172 INLINE int
1173 window_box_right (w, area)
1174 struct window *w;
1175 int area;
1177 return window_box_left (w, area) + window_box_width (w, area);
1180 /* Get the bounding box of the display area AREA of window W, without
1181 mode lines, in frame-relative coordinates. AREA < 0 means the
1182 whole window, not including the left and right fringes of
1183 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1184 coordinates of the upper-left corner of the box. Return in
1185 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1187 INLINE void
1188 window_box (w, area, box_x, box_y, box_width, box_height)
1189 struct window *w;
1190 int area;
1191 int *box_x, *box_y, *box_width, *box_height;
1193 if (box_width)
1194 *box_width = window_box_width (w, area);
1195 if (box_height)
1196 *box_height = window_box_height (w);
1197 if (box_x)
1198 *box_x = window_box_left (w, area);
1199 if (box_y)
1201 *box_y = WINDOW_TOP_EDGE_Y (w);
1202 if (WINDOW_WANTS_HEADER_LINE_P (w))
1203 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1208 /* Get the bounding box of the display area AREA of window W, without
1209 mode lines. AREA < 0 means the whole window, not including the
1210 left and right fringe of the window. Return in *TOP_LEFT_X
1211 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1212 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1213 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1214 box. */
1216 INLINE void
1217 window_box_edges (w, area, top_left_x, top_left_y,
1218 bottom_right_x, bottom_right_y)
1219 struct window *w;
1220 int area;
1221 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
1223 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1224 bottom_right_y);
1225 *bottom_right_x += *top_left_x;
1226 *bottom_right_y += *top_left_y;
1231 /***********************************************************************
1232 Utilities
1233 ***********************************************************************/
1235 /* Return the bottom y-position of the line the iterator IT is in.
1236 This can modify IT's settings. */
1239 line_bottom_y (it)
1240 struct it *it;
1242 int line_height = it->max_ascent + it->max_descent;
1243 int line_top_y = it->current_y;
1245 if (line_height == 0)
1247 if (last_height)
1248 line_height = last_height;
1249 else if (IT_CHARPOS (*it) < ZV)
1251 move_it_by_lines (it, 1, 1);
1252 line_height = (it->max_ascent || it->max_descent
1253 ? it->max_ascent + it->max_descent
1254 : last_height);
1256 else
1258 struct glyph_row *row = it->glyph_row;
1260 /* Use the default character height. */
1261 it->glyph_row = NULL;
1262 it->what = IT_CHARACTER;
1263 it->c = ' ';
1264 it->len = 1;
1265 PRODUCE_GLYPHS (it);
1266 line_height = it->ascent + it->descent;
1267 it->glyph_row = row;
1271 return line_top_y + line_height;
1275 /* Return 1 if position CHARPOS is visible in window W.
1276 CHARPOS < 0 means return info about WINDOW_END position.
1277 If visible, set *X and *Y to pixel coordinates of top left corner.
1278 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1279 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1282 pos_visible_p (w, charpos, x, y, rtop, rbot, rowh, vpos)
1283 struct window *w;
1284 int charpos, *x, *y, *rtop, *rbot, *rowh, *vpos;
1286 struct it it;
1287 struct text_pos top;
1288 int visible_p = 0;
1289 struct buffer *old_buffer = NULL;
1291 if (noninteractive)
1292 return visible_p;
1294 if (XBUFFER (w->buffer) != current_buffer)
1296 old_buffer = current_buffer;
1297 set_buffer_internal_1 (XBUFFER (w->buffer));
1300 SET_TEXT_POS_FROM_MARKER (top, w->start);
1302 /* Compute exact mode line heights. */
1303 if (WINDOW_WANTS_MODELINE_P (w))
1304 current_mode_line_height
1305 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1306 current_buffer->mode_line_format);
1308 if (WINDOW_WANTS_HEADER_LINE_P (w))
1309 current_header_line_height
1310 = display_mode_line (w, HEADER_LINE_FACE_ID,
1311 current_buffer->header_line_format);
1313 start_display (&it, w, top);
1314 move_it_to (&it, charpos, -1, it.last_visible_y-1, -1,
1315 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
1317 /* Note that we may overshoot because of invisible text. */
1318 if (charpos >= 0 && IT_CHARPOS (it) >= charpos)
1320 int top_x = it.current_x;
1321 int top_y = it.current_y;
1322 int bottom_y = (last_height = 0, line_bottom_y (&it));
1323 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1325 if (top_y < window_top_y)
1326 visible_p = bottom_y > window_top_y;
1327 else if (top_y < it.last_visible_y)
1328 visible_p = 1;
1329 if (visible_p)
1331 if (it.method == GET_FROM_BUFFER)
1333 Lisp_Object window, prop;
1335 XSETWINDOW (window, w);
1336 prop = Fget_char_property (make_number (it.position.charpos),
1337 Qinvisible, window);
1339 /* If charpos coincides with invisible text covered with an
1340 ellipsis, use the first glyph of the ellipsis to compute
1341 the pixel positions. */
1342 if (TEXT_PROP_MEANS_INVISIBLE (prop) == 2)
1344 struct glyph_row *row = it.glyph_row;
1345 struct glyph *glyph = row->glyphs[TEXT_AREA];
1346 struct glyph *end = glyph + row->used[TEXT_AREA];
1347 int x = row->x;
1349 for (; glyph < end && glyph->charpos < charpos; glyph++)
1350 x += glyph->pixel_width;
1352 top_x = x;
1356 *x = top_x;
1357 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1358 *rtop = max (0, window_top_y - top_y);
1359 *rbot = max (0, bottom_y - it.last_visible_y);
1360 *rowh = max (0, (min (bottom_y, it.last_visible_y)
1361 - max (top_y, window_top_y)));
1362 *vpos = it.vpos;
1365 else
1367 struct it it2;
1369 it2 = it;
1370 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1371 move_it_by_lines (&it, 1, 0);
1372 if (charpos < IT_CHARPOS (it)
1373 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1375 visible_p = 1;
1376 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1377 *x = it2.current_x;
1378 *y = it2.current_y + it2.max_ascent - it2.ascent;
1379 *rtop = max (0, -it2.current_y);
1380 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1381 - it.last_visible_y));
1382 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
1383 it.last_visible_y)
1384 - max (it2.current_y,
1385 WINDOW_HEADER_LINE_HEIGHT (w))));
1386 *vpos = it2.vpos;
1390 if (old_buffer)
1391 set_buffer_internal_1 (old_buffer);
1393 current_header_line_height = current_mode_line_height = -1;
1395 if (visible_p && XFASTINT (w->hscroll) > 0)
1396 *x -= XFASTINT (w->hscroll) * WINDOW_FRAME_COLUMN_WIDTH (w);
1398 #if 0
1399 /* Debugging code. */
1400 if (visible_p)
1401 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1402 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
1403 else
1404 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
1405 #endif
1407 return visible_p;
1411 /* Return the next character from STR which is MAXLEN bytes long.
1412 Return in *LEN the length of the character. This is like
1413 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1414 we find one, we return a `?', but with the length of the invalid
1415 character. */
1417 static INLINE int
1418 string_char_and_length (str, maxlen, len)
1419 const unsigned char *str;
1420 int maxlen, *len;
1422 int c;
1424 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
1425 if (!CHAR_VALID_P (c, 1))
1426 /* We may not change the length here because other places in Emacs
1427 don't use this function, i.e. they silently accept invalid
1428 characters. */
1429 c = '?';
1431 return c;
1436 /* Given a position POS containing a valid character and byte position
1437 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1439 static struct text_pos
1440 string_pos_nchars_ahead (pos, string, nchars)
1441 struct text_pos pos;
1442 Lisp_Object string;
1443 int nchars;
1445 xassert (STRINGP (string) && nchars >= 0);
1447 if (STRING_MULTIBYTE (string))
1449 int rest = SBYTES (string) - BYTEPOS (pos);
1450 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1451 int len;
1453 while (nchars--)
1455 string_char_and_length (p, rest, &len);
1456 p += len, rest -= len;
1457 xassert (rest >= 0);
1458 CHARPOS (pos) += 1;
1459 BYTEPOS (pos) += len;
1462 else
1463 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1465 return pos;
1469 /* Value is the text position, i.e. character and byte position,
1470 for character position CHARPOS in STRING. */
1472 static INLINE struct text_pos
1473 string_pos (charpos, string)
1474 int charpos;
1475 Lisp_Object string;
1477 struct text_pos pos;
1478 xassert (STRINGP (string));
1479 xassert (charpos >= 0);
1480 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1481 return pos;
1485 /* Value is a text position, i.e. character and byte position, for
1486 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1487 means recognize multibyte characters. */
1489 static struct text_pos
1490 c_string_pos (charpos, s, multibyte_p)
1491 int charpos;
1492 unsigned char *s;
1493 int multibyte_p;
1495 struct text_pos pos;
1497 xassert (s != NULL);
1498 xassert (charpos >= 0);
1500 if (multibyte_p)
1502 int rest = strlen (s), len;
1504 SET_TEXT_POS (pos, 0, 0);
1505 while (charpos--)
1507 string_char_and_length (s, rest, &len);
1508 s += len, rest -= len;
1509 xassert (rest >= 0);
1510 CHARPOS (pos) += 1;
1511 BYTEPOS (pos) += len;
1514 else
1515 SET_TEXT_POS (pos, charpos, charpos);
1517 return pos;
1521 /* Value is the number of characters in C string S. MULTIBYTE_P
1522 non-zero means recognize multibyte characters. */
1524 static int
1525 number_of_chars (s, multibyte_p)
1526 unsigned char *s;
1527 int multibyte_p;
1529 int nchars;
1531 if (multibyte_p)
1533 int rest = strlen (s), len;
1534 unsigned char *p = (unsigned char *) s;
1536 for (nchars = 0; rest > 0; ++nchars)
1538 string_char_and_length (p, rest, &len);
1539 rest -= len, p += len;
1542 else
1543 nchars = strlen (s);
1545 return nchars;
1549 /* Compute byte position NEWPOS->bytepos corresponding to
1550 NEWPOS->charpos. POS is a known position in string STRING.
1551 NEWPOS->charpos must be >= POS.charpos. */
1553 static void
1554 compute_string_pos (newpos, pos, string)
1555 struct text_pos *newpos, pos;
1556 Lisp_Object string;
1558 xassert (STRINGP (string));
1559 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1561 if (STRING_MULTIBYTE (string))
1562 *newpos = string_pos_nchars_ahead (pos, string,
1563 CHARPOS (*newpos) - CHARPOS (pos));
1564 else
1565 BYTEPOS (*newpos) = CHARPOS (*newpos);
1568 /* EXPORT:
1569 Return an estimation of the pixel height of mode or top lines on
1570 frame F. FACE_ID specifies what line's height to estimate. */
1573 estimate_mode_line_height (f, face_id)
1574 struct frame *f;
1575 enum face_id face_id;
1577 #ifdef HAVE_WINDOW_SYSTEM
1578 if (FRAME_WINDOW_P (f))
1580 int height = FONT_HEIGHT (FRAME_FONT (f));
1582 /* This function is called so early when Emacs starts that the face
1583 cache and mode line face are not yet initialized. */
1584 if (FRAME_FACE_CACHE (f))
1586 struct face *face = FACE_FROM_ID (f, face_id);
1587 if (face)
1589 if (face->font)
1590 height = FONT_HEIGHT (face->font);
1591 if (face->box_line_width > 0)
1592 height += 2 * face->box_line_width;
1596 return height;
1598 #endif
1600 return 1;
1603 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1604 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1605 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1606 not force the value into range. */
1608 void
1609 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
1610 FRAME_PTR f;
1611 register int pix_x, pix_y;
1612 int *x, *y;
1613 NativeRectangle *bounds;
1614 int noclip;
1617 #ifdef HAVE_WINDOW_SYSTEM
1618 if (FRAME_WINDOW_P (f))
1620 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1621 even for negative values. */
1622 if (pix_x < 0)
1623 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1624 if (pix_y < 0)
1625 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1627 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1628 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1630 if (bounds)
1631 STORE_NATIVE_RECT (*bounds,
1632 FRAME_COL_TO_PIXEL_X (f, pix_x),
1633 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1634 FRAME_COLUMN_WIDTH (f) - 1,
1635 FRAME_LINE_HEIGHT (f) - 1);
1637 if (!noclip)
1639 if (pix_x < 0)
1640 pix_x = 0;
1641 else if (pix_x > FRAME_TOTAL_COLS (f))
1642 pix_x = FRAME_TOTAL_COLS (f);
1644 if (pix_y < 0)
1645 pix_y = 0;
1646 else if (pix_y > FRAME_LINES (f))
1647 pix_y = FRAME_LINES (f);
1650 #endif
1652 *x = pix_x;
1653 *y = pix_y;
1657 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1658 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1659 can't tell the positions because W's display is not up to date,
1660 return 0. */
1663 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
1664 struct window *w;
1665 int hpos, vpos;
1666 int *frame_x, *frame_y;
1668 #ifdef HAVE_WINDOW_SYSTEM
1669 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1671 int success_p;
1673 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1674 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1676 if (display_completed)
1678 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1679 struct glyph *glyph = row->glyphs[TEXT_AREA];
1680 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1682 hpos = row->x;
1683 vpos = row->y;
1684 while (glyph < end)
1686 hpos += glyph->pixel_width;
1687 ++glyph;
1690 /* If first glyph is partially visible, its first visible position is still 0. */
1691 if (hpos < 0)
1692 hpos = 0;
1694 success_p = 1;
1696 else
1698 hpos = vpos = 0;
1699 success_p = 0;
1702 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1703 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1704 return success_p;
1706 #endif
1708 *frame_x = hpos;
1709 *frame_y = vpos;
1710 return 1;
1714 #ifdef HAVE_WINDOW_SYSTEM
1716 /* Find the glyph under window-relative coordinates X/Y in window W.
1717 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1718 strings. Return in *HPOS and *VPOS the row and column number of
1719 the glyph found. Return in *AREA the glyph area containing X.
1720 Value is a pointer to the glyph found or null if X/Y is not on
1721 text, or we can't tell because W's current matrix is not up to
1722 date. */
1724 #ifndef HAVE_CARBON
1725 static
1726 #endif
1727 struct glyph *
1728 x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
1729 struct window *w;
1730 int x, y;
1731 int *hpos, *vpos, *dx, *dy, *area;
1733 struct glyph *glyph, *end;
1734 struct glyph_row *row = NULL;
1735 int x0, i;
1737 /* Find row containing Y. Give up if some row is not enabled. */
1738 for (i = 0; i < w->current_matrix->nrows; ++i)
1740 row = MATRIX_ROW (w->current_matrix, i);
1741 if (!row->enabled_p)
1742 return NULL;
1743 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1744 break;
1747 *vpos = i;
1748 *hpos = 0;
1750 /* Give up if Y is not in the window. */
1751 if (i == w->current_matrix->nrows)
1752 return NULL;
1754 /* Get the glyph area containing X. */
1755 if (w->pseudo_window_p)
1757 *area = TEXT_AREA;
1758 x0 = 0;
1760 else
1762 if (x < window_box_left_offset (w, TEXT_AREA))
1764 *area = LEFT_MARGIN_AREA;
1765 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1767 else if (x < window_box_right_offset (w, TEXT_AREA))
1769 *area = TEXT_AREA;
1770 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1772 else
1774 *area = RIGHT_MARGIN_AREA;
1775 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1779 /* Find glyph containing X. */
1780 glyph = row->glyphs[*area];
1781 end = glyph + row->used[*area];
1782 x -= x0;
1783 while (glyph < end && x >= glyph->pixel_width)
1785 x -= glyph->pixel_width;
1786 ++glyph;
1789 if (glyph == end)
1790 return NULL;
1792 if (dx)
1794 *dx = x;
1795 *dy = y - (row->y + row->ascent - glyph->ascent);
1798 *hpos = glyph - row->glyphs[*area];
1799 return glyph;
1803 /* EXPORT:
1804 Convert frame-relative x/y to coordinates relative to window W.
1805 Takes pseudo-windows into account. */
1807 void
1808 frame_to_window_pixel_xy (w, x, y)
1809 struct window *w;
1810 int *x, *y;
1812 if (w->pseudo_window_p)
1814 /* A pseudo-window is always full-width, and starts at the
1815 left edge of the frame, plus a frame border. */
1816 struct frame *f = XFRAME (w->frame);
1817 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1818 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1820 else
1822 *x -= WINDOW_LEFT_EDGE_X (w);
1823 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1827 /* EXPORT:
1828 Return in RECTS[] at most N clipping rectangles for glyph string S.
1829 Return the number of stored rectangles. */
1832 get_glyph_string_clip_rects (s, rects, n)
1833 struct glyph_string *s;
1834 NativeRectangle *rects;
1835 int n;
1837 XRectangle r;
1839 if (n <= 0)
1840 return 0;
1842 if (s->row->full_width_p)
1844 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1845 r.x = WINDOW_LEFT_EDGE_X (s->w);
1846 r.width = WINDOW_TOTAL_WIDTH (s->w);
1848 /* Unless displaying a mode or menu bar line, which are always
1849 fully visible, clip to the visible part of the row. */
1850 if (s->w->pseudo_window_p)
1851 r.height = s->row->visible_height;
1852 else
1853 r.height = s->height;
1855 else
1857 /* This is a text line that may be partially visible. */
1858 r.x = window_box_left (s->w, s->area);
1859 r.width = window_box_width (s->w, s->area);
1860 r.height = s->row->visible_height;
1863 if (s->clip_head)
1864 if (r.x < s->clip_head->x)
1866 if (r.width >= s->clip_head->x - r.x)
1867 r.width -= s->clip_head->x - r.x;
1868 else
1869 r.width = 0;
1870 r.x = s->clip_head->x;
1872 if (s->clip_tail)
1873 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
1875 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
1876 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
1877 else
1878 r.width = 0;
1881 /* If S draws overlapping rows, it's sufficient to use the top and
1882 bottom of the window for clipping because this glyph string
1883 intentionally draws over other lines. */
1884 if (s->for_overlaps)
1886 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1887 r.height = window_text_bottom_y (s->w) - r.y;
1889 /* Alas, the above simple strategy does not work for the
1890 environments with anti-aliased text: if the same text is
1891 drawn onto the same place multiple times, it gets thicker.
1892 If the overlap we are processing is for the erased cursor, we
1893 take the intersection with the rectagle of the cursor. */
1894 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
1896 XRectangle rc, r_save = r;
1898 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
1899 rc.y = s->w->phys_cursor.y;
1900 rc.width = s->w->phys_cursor_width;
1901 rc.height = s->w->phys_cursor_height;
1903 x_intersect_rectangles (&r_save, &rc, &r);
1906 else
1908 /* Don't use S->y for clipping because it doesn't take partially
1909 visible lines into account. For example, it can be negative for
1910 partially visible lines at the top of a window. */
1911 if (!s->row->full_width_p
1912 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1913 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1914 else
1915 r.y = max (0, s->row->y);
1917 /* If drawing a tool-bar window, draw it over the internal border
1918 at the top of the window. */
1919 if (WINDOWP (s->f->tool_bar_window)
1920 && s->w == XWINDOW (s->f->tool_bar_window))
1921 r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
1924 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1926 /* If drawing the cursor, don't let glyph draw outside its
1927 advertised boundaries. Cleartype does this under some circumstances. */
1928 if (s->hl == DRAW_CURSOR)
1930 struct glyph *glyph = s->first_glyph;
1931 int height, max_y;
1933 if (s->x > r.x)
1935 r.width -= s->x - r.x;
1936 r.x = s->x;
1938 r.width = min (r.width, glyph->pixel_width);
1940 /* If r.y is below window bottom, ensure that we still see a cursor. */
1941 height = min (glyph->ascent + glyph->descent,
1942 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
1943 max_y = window_text_bottom_y (s->w) - height;
1944 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
1945 if (s->ybase - glyph->ascent > max_y)
1947 r.y = max_y;
1948 r.height = height;
1950 else
1952 /* Don't draw cursor glyph taller than our actual glyph. */
1953 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
1954 if (height < r.height)
1956 max_y = r.y + r.height;
1957 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
1958 r.height = min (max_y - r.y, height);
1963 if (s->row->clip)
1965 XRectangle r_save = r;
1967 if (! x_intersect_rectangles (&r_save, s->row->clip, &r))
1968 r.width = 0;
1971 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
1972 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
1974 #ifdef CONVERT_FROM_XRECT
1975 CONVERT_FROM_XRECT (r, *rects);
1976 #else
1977 *rects = r;
1978 #endif
1979 return 1;
1981 else
1983 /* If we are processing overlapping and allowed to return
1984 multiple clipping rectangles, we exclude the row of the glyph
1985 string from the clipping rectangle. This is to avoid drawing
1986 the same text on the environment with anti-aliasing. */
1987 #ifdef CONVERT_FROM_XRECT
1988 XRectangle rs[2];
1989 #else
1990 XRectangle *rs = rects;
1991 #endif
1992 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
1994 if (s->for_overlaps & OVERLAPS_PRED)
1996 rs[i] = r;
1997 if (r.y + r.height > row_y)
1999 if (r.y < row_y)
2000 rs[i].height = row_y - r.y;
2001 else
2002 rs[i].height = 0;
2004 i++;
2006 if (s->for_overlaps & OVERLAPS_SUCC)
2008 rs[i] = r;
2009 if (r.y < row_y + s->row->visible_height)
2011 if (r.y + r.height > row_y + s->row->visible_height)
2013 rs[i].y = row_y + s->row->visible_height;
2014 rs[i].height = r.y + r.height - rs[i].y;
2016 else
2017 rs[i].height = 0;
2019 i++;
2022 n = i;
2023 #ifdef CONVERT_FROM_XRECT
2024 for (i = 0; i < n; i++)
2025 CONVERT_FROM_XRECT (rs[i], rects[i]);
2026 #endif
2027 return n;
2031 /* EXPORT:
2032 Return in *NR the clipping rectangle for glyph string S. */
2034 void
2035 get_glyph_string_clip_rect (s, nr)
2036 struct glyph_string *s;
2037 NativeRectangle *nr;
2039 get_glyph_string_clip_rects (s, nr, 1);
2043 /* EXPORT:
2044 Return the position and height of the phys cursor in window W.
2045 Set w->phys_cursor_width to width of phys cursor.
2048 void
2049 get_phys_cursor_geometry (w, row, glyph, xp, yp, heightp)
2050 struct window *w;
2051 struct glyph_row *row;
2052 struct glyph *glyph;
2053 int *xp, *yp, *heightp;
2055 struct frame *f = XFRAME (WINDOW_FRAME (w));
2056 int x, y, wd, h, h0, y0;
2058 /* Compute the width of the rectangle to draw. If on a stretch
2059 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2060 rectangle as wide as the glyph, but use a canonical character
2061 width instead. */
2062 wd = glyph->pixel_width - 1;
2063 #ifdef HAVE_NTGUI
2064 wd++; /* Why? */
2065 #endif
2067 x = w->phys_cursor.x;
2068 if (x < 0)
2070 wd += x;
2071 x = 0;
2074 if (glyph->type == STRETCH_GLYPH
2075 && !x_stretch_cursor_p)
2076 wd = min (FRAME_COLUMN_WIDTH (f), wd);
2077 w->phys_cursor_width = wd;
2079 y = w->phys_cursor.y + row->ascent - glyph->ascent;
2081 /* If y is below window bottom, ensure that we still see a cursor. */
2082 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
2084 h = max (h0, glyph->ascent + glyph->descent);
2085 h0 = min (h0, glyph->ascent + glyph->descent);
2087 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
2088 if (y < y0)
2090 h = max (h - (y0 - y) + 1, h0);
2091 y = y0 - 1;
2093 else
2095 y0 = window_text_bottom_y (w) - h0;
2096 if (y > y0)
2098 h += y - y0;
2099 y = y0;
2103 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
2104 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
2105 *heightp = h;
2109 * Remember which glyph the mouse is over.
2112 void
2113 remember_mouse_glyph (f, gx, gy, rect)
2114 struct frame *f;
2115 int gx, gy;
2116 NativeRectangle *rect;
2118 Lisp_Object window;
2119 struct window *w;
2120 struct glyph_row *r, *gr, *end_row;
2121 enum window_part part;
2122 enum glyph_row_area area;
2123 int x, y, width, height;
2125 /* Try to determine frame pixel position and size of the glyph under
2126 frame pixel coordinates X/Y on frame F. */
2128 if (!f->glyphs_initialized_p
2129 || (window = window_from_coordinates (f, gx, gy, &part, &x, &y, 0),
2130 NILP (window)))
2132 width = FRAME_SMALLEST_CHAR_WIDTH (f);
2133 height = FRAME_SMALLEST_FONT_HEIGHT (f);
2134 goto virtual_glyph;
2137 w = XWINDOW (window);
2138 width = WINDOW_FRAME_COLUMN_WIDTH (w);
2139 height = WINDOW_FRAME_LINE_HEIGHT (w);
2141 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
2142 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
2144 if (w->pseudo_window_p)
2146 area = TEXT_AREA;
2147 part = ON_MODE_LINE; /* Don't adjust margin. */
2148 goto text_glyph;
2151 switch (part)
2153 case ON_LEFT_MARGIN:
2154 area = LEFT_MARGIN_AREA;
2155 goto text_glyph;
2157 case ON_RIGHT_MARGIN:
2158 area = RIGHT_MARGIN_AREA;
2159 goto text_glyph;
2161 case ON_HEADER_LINE:
2162 case ON_MODE_LINE:
2163 gr = (part == ON_HEADER_LINE
2164 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
2165 : MATRIX_MODE_LINE_ROW (w->current_matrix));
2166 gy = gr->y;
2167 area = TEXT_AREA;
2168 goto text_glyph_row_found;
2170 case ON_TEXT:
2171 area = TEXT_AREA;
2173 text_glyph:
2174 gr = 0; gy = 0;
2175 for (; r <= end_row && r->enabled_p; ++r)
2176 if (r->y + r->height > y)
2178 gr = r; gy = r->y;
2179 break;
2182 text_glyph_row_found:
2183 if (gr && gy <= y)
2185 struct glyph *g = gr->glyphs[area];
2186 struct glyph *end = g + gr->used[area];
2188 height = gr->height;
2189 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2190 if (gx + g->pixel_width > x)
2191 break;
2193 if (g < end)
2195 if (g->type == IMAGE_GLYPH)
2197 /* Don't remember when mouse is over image, as
2198 image may have hot-spots. */
2199 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2200 return;
2202 width = g->pixel_width;
2204 else
2206 /* Use nominal char spacing at end of line. */
2207 x -= gx;
2208 gx += (x / width) * width;
2211 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2212 gx += window_box_left_offset (w, area);
2214 else
2216 /* Use nominal line height at end of window. */
2217 gx = (x / width) * width;
2218 y -= gy;
2219 gy += (y / height) * height;
2221 break;
2223 case ON_LEFT_FRINGE:
2224 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2225 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2226 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2227 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2228 goto row_glyph;
2230 case ON_RIGHT_FRINGE:
2231 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2232 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2233 : window_box_right_offset (w, TEXT_AREA));
2234 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2235 goto row_glyph;
2237 case ON_SCROLL_BAR:
2238 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2240 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2241 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2242 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2243 : 0)));
2244 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2246 row_glyph:
2247 gr = 0, gy = 0;
2248 for (; r <= end_row && r->enabled_p; ++r)
2249 if (r->y + r->height > y)
2251 gr = r; gy = r->y;
2252 break;
2255 if (gr && gy <= y)
2256 height = gr->height;
2257 else
2259 /* Use nominal line height at end of window. */
2260 y -= gy;
2261 gy += (y / height) * height;
2263 break;
2265 default:
2267 virtual_glyph:
2268 /* If there is no glyph under the mouse, then we divide the screen
2269 into a grid of the smallest glyph in the frame, and use that
2270 as our "glyph". */
2272 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2273 round down even for negative values. */
2274 if (gx < 0)
2275 gx -= width - 1;
2276 if (gy < 0)
2277 gy -= height - 1;
2279 gx = (gx / width) * width;
2280 gy = (gy / height) * height;
2282 goto store_rect;
2285 gx += WINDOW_LEFT_EDGE_X (w);
2286 gy += WINDOW_TOP_EDGE_Y (w);
2288 store_rect:
2289 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2291 /* Visible feedback for debugging. */
2292 #if 0
2293 #if HAVE_X_WINDOWS
2294 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2295 f->output_data.x->normal_gc,
2296 gx, gy, width, height);
2297 #endif
2298 #endif
2302 #endif /* HAVE_WINDOW_SYSTEM */
2305 /***********************************************************************
2306 Lisp form evaluation
2307 ***********************************************************************/
2309 /* Error handler for safe_eval and safe_call. */
2311 static Lisp_Object
2312 safe_eval_handler (arg)
2313 Lisp_Object arg;
2315 add_to_log ("Error during redisplay: %s", arg, Qnil);
2316 return Qnil;
2320 /* Evaluate SEXPR and return the result, or nil if something went
2321 wrong. Prevent redisplay during the evaluation. */
2323 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
2324 Return the result, or nil if something went wrong. Prevent
2325 redisplay during the evaluation. */
2327 Lisp_Object
2328 safe_call (nargs, args)
2329 int nargs;
2330 Lisp_Object *args;
2332 Lisp_Object val;
2334 if (inhibit_eval_during_redisplay)
2335 val = Qnil;
2336 else
2338 int count = SPECPDL_INDEX ();
2339 struct gcpro gcpro1;
2341 GCPRO1 (args[0]);
2342 gcpro1.nvars = nargs;
2343 specbind (Qinhibit_redisplay, Qt);
2344 /* Use Qt to ensure debugger does not run,
2345 so there is no possibility of wanting to redisplay. */
2346 val = internal_condition_case_2 (Ffuncall, nargs, args, Qt,
2347 safe_eval_handler);
2348 UNGCPRO;
2349 val = unbind_to (count, val);
2352 return val;
2356 /* Call function FN with one argument ARG.
2357 Return the result, or nil if something went wrong. */
2359 Lisp_Object
2360 safe_call1 (fn, arg)
2361 Lisp_Object fn, arg;
2363 Lisp_Object args[2];
2364 args[0] = fn;
2365 args[1] = arg;
2366 return safe_call (2, args);
2369 static Lisp_Object Qeval;
2371 Lisp_Object
2372 safe_eval (Lisp_Object sexpr)
2374 return safe_call1 (Qeval, sexpr);
2377 /* Call function FN with one argument ARG.
2378 Return the result, or nil if something went wrong. */
2380 Lisp_Object
2381 safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
2383 Lisp_Object args[3];
2384 args[0] = fn;
2385 args[1] = arg1;
2386 args[2] = arg2;
2387 return safe_call (3, args);
2392 /***********************************************************************
2393 Debugging
2394 ***********************************************************************/
2396 #if 0
2398 /* Define CHECK_IT to perform sanity checks on iterators.
2399 This is for debugging. It is too slow to do unconditionally. */
2401 static void
2402 check_it (it)
2403 struct it *it;
2405 if (it->method == GET_FROM_STRING)
2407 xassert (STRINGP (it->string));
2408 xassert (IT_STRING_CHARPOS (*it) >= 0);
2410 else
2412 xassert (IT_STRING_CHARPOS (*it) < 0);
2413 if (it->method == GET_FROM_BUFFER)
2415 /* Check that character and byte positions agree. */
2416 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2420 if (it->dpvec)
2421 xassert (it->current.dpvec_index >= 0);
2422 else
2423 xassert (it->current.dpvec_index < 0);
2426 #define CHECK_IT(IT) check_it ((IT))
2428 #else /* not 0 */
2430 #define CHECK_IT(IT) (void) 0
2432 #endif /* not 0 */
2435 #if GLYPH_DEBUG
2437 /* Check that the window end of window W is what we expect it
2438 to be---the last row in the current matrix displaying text. */
2440 static void
2441 check_window_end (w)
2442 struct window *w;
2444 if (!MINI_WINDOW_P (w)
2445 && !NILP (w->window_end_valid))
2447 struct glyph_row *row;
2448 xassert ((row = MATRIX_ROW (w->current_matrix,
2449 XFASTINT (w->window_end_vpos)),
2450 !row->enabled_p
2451 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2452 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2456 #define CHECK_WINDOW_END(W) check_window_end ((W))
2458 #else /* not GLYPH_DEBUG */
2460 #define CHECK_WINDOW_END(W) (void) 0
2462 #endif /* not GLYPH_DEBUG */
2466 /***********************************************************************
2467 Iterator initialization
2468 ***********************************************************************/
2470 /* Initialize IT for displaying current_buffer in window W, starting
2471 at character position CHARPOS. CHARPOS < 0 means that no buffer
2472 position is specified which is useful when the iterator is assigned
2473 a position later. BYTEPOS is the byte position corresponding to
2474 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2476 If ROW is not null, calls to produce_glyphs with IT as parameter
2477 will produce glyphs in that row.
2479 BASE_FACE_ID is the id of a base face to use. It must be one of
2480 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2481 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2482 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2484 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2485 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2486 will be initialized to use the corresponding mode line glyph row of
2487 the desired matrix of W. */
2489 void
2490 init_iterator (it, w, charpos, bytepos, row, base_face_id)
2491 struct it *it;
2492 struct window *w;
2493 int charpos, bytepos;
2494 struct glyph_row *row;
2495 enum face_id base_face_id;
2497 int highlight_region_p;
2499 /* Some precondition checks. */
2500 xassert (w != NULL && it != NULL);
2501 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2502 && charpos <= ZV));
2504 /* If face attributes have been changed since the last redisplay,
2505 free realized faces now because they depend on face definitions
2506 that might have changed. Don't free faces while there might be
2507 desired matrices pending which reference these faces. */
2508 if (face_change_count && !inhibit_free_realized_faces)
2510 face_change_count = 0;
2511 free_all_realized_faces (Qnil);
2514 /* Use one of the mode line rows of W's desired matrix if
2515 appropriate. */
2516 if (row == NULL)
2518 if (base_face_id == MODE_LINE_FACE_ID
2519 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2520 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2521 else if (base_face_id == HEADER_LINE_FACE_ID)
2522 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2525 /* Clear IT. */
2526 bzero (it, sizeof *it);
2527 it->current.overlay_string_index = -1;
2528 it->current.dpvec_index = -1;
2529 it->base_face_id = base_face_id;
2530 it->string = Qnil;
2531 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2533 /* The window in which we iterate over current_buffer: */
2534 XSETWINDOW (it->window, w);
2535 it->w = w;
2536 it->f = XFRAME (w->frame);
2538 /* Extra space between lines (on window systems only). */
2539 if (base_face_id == DEFAULT_FACE_ID
2540 && FRAME_WINDOW_P (it->f))
2542 if (NATNUMP (current_buffer->extra_line_spacing))
2543 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
2544 else if (FLOATP (current_buffer->extra_line_spacing))
2545 it->extra_line_spacing = (XFLOAT_DATA (current_buffer->extra_line_spacing)
2546 * FRAME_LINE_HEIGHT (it->f));
2547 else if (it->f->extra_line_spacing > 0)
2548 it->extra_line_spacing = it->f->extra_line_spacing;
2549 it->max_extra_line_spacing = 0;
2552 /* If realized faces have been removed, e.g. because of face
2553 attribute changes of named faces, recompute them. When running
2554 in batch mode, the face cache of the initial frame is null. If
2555 we happen to get called, make a dummy face cache. */
2556 if (FRAME_FACE_CACHE (it->f) == NULL)
2557 init_frame_faces (it->f);
2558 if (FRAME_FACE_CACHE (it->f)->used == 0)
2559 recompute_basic_faces (it->f);
2561 /* Current value of the `slice', `space-width', and 'height' properties. */
2562 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2563 it->space_width = Qnil;
2564 it->font_height = Qnil;
2565 it->override_ascent = -1;
2567 /* Are control characters displayed as `^C'? */
2568 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
2570 /* -1 means everything between a CR and the following line end
2571 is invisible. >0 means lines indented more than this value are
2572 invisible. */
2573 it->selective = (INTEGERP (current_buffer->selective_display)
2574 ? XFASTINT (current_buffer->selective_display)
2575 : (!NILP (current_buffer->selective_display)
2576 ? -1 : 0));
2577 it->selective_display_ellipsis_p
2578 = !NILP (current_buffer->selective_display_ellipses);
2580 /* Display table to use. */
2581 it->dp = window_display_table (w);
2583 /* Are multibyte characters enabled in current_buffer? */
2584 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2586 /* Non-zero if we should highlight the region. */
2587 highlight_region_p
2588 = (!NILP (Vtransient_mark_mode)
2589 && !NILP (current_buffer->mark_active)
2590 && XMARKER (current_buffer->mark)->buffer != 0);
2592 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2593 start and end of a visible region in window IT->w. Set both to
2594 -1 to indicate no region. */
2595 if (highlight_region_p
2596 /* Maybe highlight only in selected window. */
2597 && (/* Either show region everywhere. */
2598 highlight_nonselected_windows
2599 /* Or show region in the selected window. */
2600 || w == XWINDOW (selected_window)
2601 /* Or show the region if we are in the mini-buffer and W is
2602 the window the mini-buffer refers to. */
2603 || (MINI_WINDOW_P (XWINDOW (selected_window))
2604 && WINDOWP (minibuf_selected_window)
2605 && w == XWINDOW (minibuf_selected_window))))
2607 int charpos = marker_position (current_buffer->mark);
2608 it->region_beg_charpos = min (PT, charpos);
2609 it->region_end_charpos = max (PT, charpos);
2611 else
2612 it->region_beg_charpos = it->region_end_charpos = -1;
2614 /* Get the position at which the redisplay_end_trigger hook should
2615 be run, if it is to be run at all. */
2616 if (MARKERP (w->redisplay_end_trigger)
2617 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2618 it->redisplay_end_trigger_charpos
2619 = marker_position (w->redisplay_end_trigger);
2620 else if (INTEGERP (w->redisplay_end_trigger))
2621 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2623 /* Correct bogus values of tab_width. */
2624 it->tab_width = XINT (current_buffer->tab_width);
2625 if (it->tab_width <= 0 || it->tab_width > 1000)
2626 it->tab_width = 8;
2628 /* Are lines in the display truncated? */
2629 it->truncate_lines_p
2630 = (base_face_id != DEFAULT_FACE_ID
2631 || XINT (it->w->hscroll)
2632 || (truncate_partial_width_windows
2633 && !WINDOW_FULL_WIDTH_P (it->w))
2634 || !NILP (current_buffer->truncate_lines));
2636 /* Get dimensions of truncation and continuation glyphs. These are
2637 displayed as fringe bitmaps under X, so we don't need them for such
2638 frames. */
2639 if (!FRAME_WINDOW_P (it->f))
2641 if (it->truncate_lines_p)
2643 /* We will need the truncation glyph. */
2644 xassert (it->glyph_row == NULL);
2645 produce_special_glyphs (it, IT_TRUNCATION);
2646 it->truncation_pixel_width = it->pixel_width;
2648 else
2650 /* We will need the continuation glyph. */
2651 xassert (it->glyph_row == NULL);
2652 produce_special_glyphs (it, IT_CONTINUATION);
2653 it->continuation_pixel_width = it->pixel_width;
2656 /* Reset these values to zero because the produce_special_glyphs
2657 above has changed them. */
2658 it->pixel_width = it->ascent = it->descent = 0;
2659 it->phys_ascent = it->phys_descent = 0;
2662 /* Set this after getting the dimensions of truncation and
2663 continuation glyphs, so that we don't produce glyphs when calling
2664 produce_special_glyphs, above. */
2665 it->glyph_row = row;
2666 it->area = TEXT_AREA;
2668 /* Get the dimensions of the display area. The display area
2669 consists of the visible window area plus a horizontally scrolled
2670 part to the left of the window. All x-values are relative to the
2671 start of this total display area. */
2672 if (base_face_id != DEFAULT_FACE_ID)
2674 /* Mode lines, menu bar in terminal frames. */
2675 it->first_visible_x = 0;
2676 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2678 else
2680 it->first_visible_x
2681 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2682 it->last_visible_x = (it->first_visible_x
2683 + window_box_width (w, TEXT_AREA));
2685 /* If we truncate lines, leave room for the truncator glyph(s) at
2686 the right margin. Otherwise, leave room for the continuation
2687 glyph(s). Truncation and continuation glyphs are not inserted
2688 for window-based redisplay. */
2689 if (!FRAME_WINDOW_P (it->f))
2691 if (it->truncate_lines_p)
2692 it->last_visible_x -= it->truncation_pixel_width;
2693 else
2694 it->last_visible_x -= it->continuation_pixel_width;
2697 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2698 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2701 /* Leave room for a border glyph. */
2702 if (!FRAME_WINDOW_P (it->f)
2703 && !WINDOW_RIGHTMOST_P (it->w))
2704 it->last_visible_x -= 1;
2706 it->last_visible_y = window_text_bottom_y (w);
2708 /* For mode lines and alike, arrange for the first glyph having a
2709 left box line if the face specifies a box. */
2710 if (base_face_id != DEFAULT_FACE_ID)
2712 struct face *face;
2714 it->face_id = base_face_id;
2716 /* If we have a boxed mode line, make the first character appear
2717 with a left box line. */
2718 face = FACE_FROM_ID (it->f, base_face_id);
2719 if (face->box != FACE_NO_BOX)
2720 it->start_of_box_run_p = 1;
2723 /* If a buffer position was specified, set the iterator there,
2724 getting overlays and face properties from that position. */
2725 if (charpos >= BUF_BEG (current_buffer))
2727 it->end_charpos = ZV;
2728 it->face_id = -1;
2729 IT_CHARPOS (*it) = charpos;
2731 /* Compute byte position if not specified. */
2732 if (bytepos < charpos)
2733 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2734 else
2735 IT_BYTEPOS (*it) = bytepos;
2737 it->start = it->current;
2739 /* Compute faces etc. */
2740 reseat (it, it->current.pos, 1);
2743 CHECK_IT (it);
2747 /* Initialize IT for the display of window W with window start POS. */
2749 void
2750 start_display (it, w, pos)
2751 struct it *it;
2752 struct window *w;
2753 struct text_pos pos;
2755 struct glyph_row *row;
2756 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2758 row = w->desired_matrix->rows + first_vpos;
2759 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2760 it->first_vpos = first_vpos;
2762 /* Don't reseat to previous visible line start if current start
2763 position is in a string or image. */
2764 if (it->method == GET_FROM_BUFFER && !it->truncate_lines_p)
2766 int start_at_line_beg_p;
2767 int first_y = it->current_y;
2769 /* If window start is not at a line start, skip forward to POS to
2770 get the correct continuation lines width. */
2771 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2772 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2773 if (!start_at_line_beg_p)
2775 int new_x;
2777 reseat_at_previous_visible_line_start (it);
2778 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2780 new_x = it->current_x + it->pixel_width;
2782 /* If lines are continued, this line may end in the middle
2783 of a multi-glyph character (e.g. a control character
2784 displayed as \003, or in the middle of an overlay
2785 string). In this case move_it_to above will not have
2786 taken us to the start of the continuation line but to the
2787 end of the continued line. */
2788 if (it->current_x > 0
2789 && !it->truncate_lines_p /* Lines are continued. */
2790 && (/* And glyph doesn't fit on the line. */
2791 new_x > it->last_visible_x
2792 /* Or it fits exactly and we're on a window
2793 system frame. */
2794 || (new_x == it->last_visible_x
2795 && FRAME_WINDOW_P (it->f))))
2797 if (it->current.dpvec_index >= 0
2798 || it->current.overlay_string_index >= 0)
2800 set_iterator_to_next (it, 1);
2801 move_it_in_display_line_to (it, -1, -1, 0);
2804 it->continuation_lines_width += it->current_x;
2807 /* We're starting a new display line, not affected by the
2808 height of the continued line, so clear the appropriate
2809 fields in the iterator structure. */
2810 it->max_ascent = it->max_descent = 0;
2811 it->max_phys_ascent = it->max_phys_descent = 0;
2813 it->current_y = first_y;
2814 it->vpos = 0;
2815 it->current_x = it->hpos = 0;
2819 #if 0 /* Don't assert the following because start_display is sometimes
2820 called intentionally with a window start that is not at a
2821 line start. Please leave this code in as a comment. */
2823 /* Window start should be on a line start, now. */
2824 xassert (it->continuation_lines_width
2825 || IT_CHARPOS (it) == BEGV
2826 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
2827 #endif /* 0 */
2831 /* Return 1 if POS is a position in ellipses displayed for invisible
2832 text. W is the window we display, for text property lookup. */
2834 static int
2835 in_ellipses_for_invisible_text_p (pos, w)
2836 struct display_pos *pos;
2837 struct window *w;
2839 Lisp_Object prop, window;
2840 int ellipses_p = 0;
2841 int charpos = CHARPOS (pos->pos);
2843 /* If POS specifies a position in a display vector, this might
2844 be for an ellipsis displayed for invisible text. We won't
2845 get the iterator set up for delivering that ellipsis unless
2846 we make sure that it gets aware of the invisible text. */
2847 if (pos->dpvec_index >= 0
2848 && pos->overlay_string_index < 0
2849 && CHARPOS (pos->string_pos) < 0
2850 && charpos > BEGV
2851 && (XSETWINDOW (window, w),
2852 prop = Fget_char_property (make_number (charpos),
2853 Qinvisible, window),
2854 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2856 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2857 window);
2858 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2861 return ellipses_p;
2865 /* Initialize IT for stepping through current_buffer in window W,
2866 starting at position POS that includes overlay string and display
2867 vector/ control character translation position information. Value
2868 is zero if there are overlay strings with newlines at POS. */
2870 static int
2871 init_from_display_pos (it, w, pos)
2872 struct it *it;
2873 struct window *w;
2874 struct display_pos *pos;
2876 int charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2877 int i, overlay_strings_with_newlines = 0;
2879 /* If POS specifies a position in a display vector, this might
2880 be for an ellipsis displayed for invisible text. We won't
2881 get the iterator set up for delivering that ellipsis unless
2882 we make sure that it gets aware of the invisible text. */
2883 if (in_ellipses_for_invisible_text_p (pos, w))
2885 --charpos;
2886 bytepos = 0;
2889 /* Keep in mind: the call to reseat in init_iterator skips invisible
2890 text, so we might end up at a position different from POS. This
2891 is only a problem when POS is a row start after a newline and an
2892 overlay starts there with an after-string, and the overlay has an
2893 invisible property. Since we don't skip invisible text in
2894 display_line and elsewhere immediately after consuming the
2895 newline before the row start, such a POS will not be in a string,
2896 but the call to init_iterator below will move us to the
2897 after-string. */
2898 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2900 /* This only scans the current chunk -- it should scan all chunks.
2901 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
2902 to 16 in 22.1 to make this a lesser problem. */
2903 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
2905 const char *s = SDATA (it->overlay_strings[i]);
2906 const char *e = s + SBYTES (it->overlay_strings[i]);
2908 while (s < e && *s != '\n')
2909 ++s;
2911 if (s < e)
2913 overlay_strings_with_newlines = 1;
2914 break;
2918 /* If position is within an overlay string, set up IT to the right
2919 overlay string. */
2920 if (pos->overlay_string_index >= 0)
2922 int relative_index;
2924 /* If the first overlay string happens to have a `display'
2925 property for an image, the iterator will be set up for that
2926 image, and we have to undo that setup first before we can
2927 correct the overlay string index. */
2928 if (it->method == GET_FROM_IMAGE)
2929 pop_it (it);
2931 /* We already have the first chunk of overlay strings in
2932 IT->overlay_strings. Load more until the one for
2933 pos->overlay_string_index is in IT->overlay_strings. */
2934 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
2936 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
2937 it->current.overlay_string_index = 0;
2938 while (n--)
2940 load_overlay_strings (it, 0);
2941 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
2945 it->current.overlay_string_index = pos->overlay_string_index;
2946 relative_index = (it->current.overlay_string_index
2947 % OVERLAY_STRING_CHUNK_SIZE);
2948 it->string = it->overlay_strings[relative_index];
2949 xassert (STRINGP (it->string));
2950 it->current.string_pos = pos->string_pos;
2951 it->method = GET_FROM_STRING;
2954 #if 0 /* This is bogus because POS not having an overlay string
2955 position does not mean it's after the string. Example: A
2956 line starting with a before-string and initialization of IT
2957 to the previous row's end position. */
2958 else if (it->current.overlay_string_index >= 0)
2960 /* If POS says we're already after an overlay string ending at
2961 POS, make sure to pop the iterator because it will be in
2962 front of that overlay string. When POS is ZV, we've thereby
2963 also ``processed'' overlay strings at ZV. */
2964 while (it->sp)
2965 pop_it (it);
2966 xassert (it->current.overlay_string_index == -1);
2967 xassert (it->method == GET_FROM_BUFFER);
2968 if (CHARPOS (pos->pos) == ZV)
2969 it->overlay_strings_at_end_processed_p = 1;
2971 #endif /* 0 */
2973 if (CHARPOS (pos->string_pos) >= 0)
2975 /* Recorded position is not in an overlay string, but in another
2976 string. This can only be a string from a `display' property.
2977 IT should already be filled with that string. */
2978 it->current.string_pos = pos->string_pos;
2979 xassert (STRINGP (it->string));
2982 /* Restore position in display vector translations, control
2983 character translations or ellipses. */
2984 if (pos->dpvec_index >= 0)
2986 if (it->dpvec == NULL)
2987 get_next_display_element (it);
2988 xassert (it->dpvec && it->current.dpvec_index == 0);
2989 it->current.dpvec_index = pos->dpvec_index;
2992 CHECK_IT (it);
2993 return !overlay_strings_with_newlines;
2997 /* Initialize IT for stepping through current_buffer in window W
2998 starting at ROW->start. */
3000 static void
3001 init_to_row_start (it, w, row)
3002 struct it *it;
3003 struct window *w;
3004 struct glyph_row *row;
3006 init_from_display_pos (it, w, &row->start);
3007 it->start = row->start;
3008 it->continuation_lines_width = row->continuation_lines_width;
3009 CHECK_IT (it);
3013 /* Initialize IT for stepping through current_buffer in window W
3014 starting in the line following ROW, i.e. starting at ROW->end.
3015 Value is zero if there are overlay strings with newlines at ROW's
3016 end position. */
3018 static int
3019 init_to_row_end (it, w, row)
3020 struct it *it;
3021 struct window *w;
3022 struct glyph_row *row;
3024 int success = 0;
3026 if (init_from_display_pos (it, w, &row->end))
3028 if (row->continued_p)
3029 it->continuation_lines_width
3030 = row->continuation_lines_width + row->pixel_width;
3031 CHECK_IT (it);
3032 success = 1;
3035 return success;
3041 /***********************************************************************
3042 Text properties
3043 ***********************************************************************/
3045 /* Called when IT reaches IT->stop_charpos. Handle text property and
3046 overlay changes. Set IT->stop_charpos to the next position where
3047 to stop. */
3049 static void
3050 handle_stop (it)
3051 struct it *it;
3053 enum prop_handled handled;
3054 int handle_overlay_change_p;
3055 struct props *p;
3057 it->dpvec = NULL;
3058 it->current.dpvec_index = -1;
3059 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
3060 it->ignore_overlay_strings_at_pos_p = 0;
3062 /* Use face of preceding text for ellipsis (if invisible) */
3063 if (it->selective_display_ellipsis_p)
3064 it->saved_face_id = it->face_id;
3068 handled = HANDLED_NORMALLY;
3070 /* Call text property handlers. */
3071 for (p = it_props; p->handler; ++p)
3073 handled = p->handler (it);
3075 if (handled == HANDLED_RECOMPUTE_PROPS)
3076 break;
3077 else if (handled == HANDLED_RETURN)
3079 /* We still want to show before and after strings from
3080 overlays even if the actual buffer text is replaced. */
3081 if (!handle_overlay_change_p || it->sp > 1)
3082 return;
3083 if (!get_overlay_strings_1 (it, 0, 0))
3084 return;
3085 it->ignore_overlay_strings_at_pos_p = 1;
3086 it->string_from_display_prop_p = 0;
3087 handle_overlay_change_p = 0;
3088 handled = HANDLED_RECOMPUTE_PROPS;
3089 break;
3091 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
3092 handle_overlay_change_p = 0;
3095 if (handled != HANDLED_RECOMPUTE_PROPS)
3097 /* Don't check for overlay strings below when set to deliver
3098 characters from a display vector. */
3099 if (it->method == GET_FROM_DISPLAY_VECTOR)
3100 handle_overlay_change_p = 0;
3102 /* Handle overlay changes.
3103 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
3104 if it finds overlays. */
3105 if (handle_overlay_change_p)
3106 handled = handle_overlay_change (it);
3109 while (handled == HANDLED_RECOMPUTE_PROPS);
3111 /* Determine where to stop next. */
3112 if (handled == HANDLED_NORMALLY)
3113 compute_stop_pos (it);
3117 /* Compute IT->stop_charpos from text property and overlay change
3118 information for IT's current position. */
3120 static void
3121 compute_stop_pos (it)
3122 struct it *it;
3124 register INTERVAL iv, next_iv;
3125 Lisp_Object object, limit, position;
3127 /* If nowhere else, stop at the end. */
3128 it->stop_charpos = it->end_charpos;
3130 if (STRINGP (it->string))
3132 /* Strings are usually short, so don't limit the search for
3133 properties. */
3134 object = it->string;
3135 limit = Qnil;
3136 position = make_number (IT_STRING_CHARPOS (*it));
3138 else
3140 int charpos;
3142 /* If next overlay change is in front of the current stop pos
3143 (which is IT->end_charpos), stop there. Note: value of
3144 next_overlay_change is point-max if no overlay change
3145 follows. */
3146 charpos = next_overlay_change (IT_CHARPOS (*it));
3147 if (charpos < it->stop_charpos)
3148 it->stop_charpos = charpos;
3150 /* If showing the region, we have to stop at the region
3151 start or end because the face might change there. */
3152 if (it->region_beg_charpos > 0)
3154 if (IT_CHARPOS (*it) < it->region_beg_charpos)
3155 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
3156 else if (IT_CHARPOS (*it) < it->region_end_charpos)
3157 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
3160 /* Set up variables for computing the stop position from text
3161 property changes. */
3162 XSETBUFFER (object, current_buffer);
3163 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3164 position = make_number (IT_CHARPOS (*it));
3168 /* Get the interval containing IT's position. Value is a null
3169 interval if there isn't such an interval. */
3170 iv = validate_interval_range (object, &position, &position, 0);
3171 if (!NULL_INTERVAL_P (iv))
3173 Lisp_Object values_here[LAST_PROP_IDX];
3174 struct props *p;
3176 /* Get properties here. */
3177 for (p = it_props; p->handler; ++p)
3178 values_here[p->idx] = textget (iv->plist, *p->name);
3180 /* Look for an interval following iv that has different
3181 properties. */
3182 for (next_iv = next_interval (iv);
3183 (!NULL_INTERVAL_P (next_iv)
3184 && (NILP (limit)
3185 || XFASTINT (limit) > next_iv->position));
3186 next_iv = next_interval (next_iv))
3188 for (p = it_props; p->handler; ++p)
3190 Lisp_Object new_value;
3192 new_value = textget (next_iv->plist, *p->name);
3193 if (!EQ (values_here[p->idx], new_value))
3194 break;
3197 if (p->handler)
3198 break;
3201 if (!NULL_INTERVAL_P (next_iv))
3203 if (INTEGERP (limit)
3204 && next_iv->position >= XFASTINT (limit))
3205 /* No text property change up to limit. */
3206 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3207 else
3208 /* Text properties change in next_iv. */
3209 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3213 xassert (STRINGP (it->string)
3214 || (it->stop_charpos >= BEGV
3215 && it->stop_charpos >= IT_CHARPOS (*it)));
3219 /* Return the position of the next overlay change after POS in
3220 current_buffer. Value is point-max if no overlay change
3221 follows. This is like `next-overlay-change' but doesn't use
3222 xmalloc. */
3224 static EMACS_INT
3225 next_overlay_change (pos)
3226 EMACS_INT pos;
3228 int noverlays;
3229 EMACS_INT endpos;
3230 Lisp_Object *overlays;
3231 int i;
3233 /* Get all overlays at the given position. */
3234 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
3236 /* If any of these overlays ends before endpos,
3237 use its ending point instead. */
3238 for (i = 0; i < noverlays; ++i)
3240 Lisp_Object oend;
3241 EMACS_INT oendpos;
3243 oend = OVERLAY_END (overlays[i]);
3244 oendpos = OVERLAY_POSITION (oend);
3245 endpos = min (endpos, oendpos);
3248 return endpos;
3253 /***********************************************************************
3254 Fontification
3255 ***********************************************************************/
3257 /* Handle changes in the `fontified' property of the current buffer by
3258 calling hook functions from Qfontification_functions to fontify
3259 regions of text. */
3261 static enum prop_handled
3262 handle_fontified_prop (it)
3263 struct it *it;
3265 Lisp_Object prop, pos;
3266 enum prop_handled handled = HANDLED_NORMALLY;
3268 if (!NILP (Vmemory_full))
3269 return handled;
3271 /* Get the value of the `fontified' property at IT's current buffer
3272 position. (The `fontified' property doesn't have a special
3273 meaning in strings.) If the value is nil, call functions from
3274 Qfontification_functions. */
3275 if (!STRINGP (it->string)
3276 && it->s == NULL
3277 && !NILP (Vfontification_functions)
3278 && !NILP (Vrun_hooks)
3279 && (pos = make_number (IT_CHARPOS (*it)),
3280 prop = Fget_char_property (pos, Qfontified, Qnil),
3281 /* Ignore the special cased nil value always present at EOB since
3282 no amount of fontifying will be able to change it. */
3283 NILP (prop) && IT_CHARPOS (*it) < Z))
3285 int count = SPECPDL_INDEX ();
3286 Lisp_Object val;
3288 val = Vfontification_functions;
3289 specbind (Qfontification_functions, Qnil);
3291 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3292 safe_call1 (val, pos);
3293 else
3295 Lisp_Object globals, fn;
3296 struct gcpro gcpro1, gcpro2;
3298 globals = Qnil;
3299 GCPRO2 (val, globals);
3301 for (; CONSP (val); val = XCDR (val))
3303 fn = XCAR (val);
3305 if (EQ (fn, Qt))
3307 /* A value of t indicates this hook has a local
3308 binding; it means to run the global binding too.
3309 In a global value, t should not occur. If it
3310 does, we must ignore it to avoid an endless
3311 loop. */
3312 for (globals = Fdefault_value (Qfontification_functions);
3313 CONSP (globals);
3314 globals = XCDR (globals))
3316 fn = XCAR (globals);
3317 if (!EQ (fn, Qt))
3318 safe_call1 (fn, pos);
3321 else
3322 safe_call1 (fn, pos);
3325 UNGCPRO;
3328 unbind_to (count, Qnil);
3330 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3331 something. This avoids an endless loop if they failed to
3332 fontify the text for which reason ever. */
3333 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3334 handled = HANDLED_RECOMPUTE_PROPS;
3337 return handled;
3342 /***********************************************************************
3343 Faces
3344 ***********************************************************************/
3346 /* Set up iterator IT from face properties at its current position.
3347 Called from handle_stop. */
3349 static enum prop_handled
3350 handle_face_prop (it)
3351 struct it *it;
3353 int new_face_id;
3354 EMACS_INT next_stop;
3356 if (!STRINGP (it->string))
3358 new_face_id
3359 = face_at_buffer_position (it->w,
3360 IT_CHARPOS (*it),
3361 it->region_beg_charpos,
3362 it->region_end_charpos,
3363 &next_stop,
3364 (IT_CHARPOS (*it)
3365 + TEXT_PROP_DISTANCE_LIMIT),
3368 /* Is this a start of a run of characters with box face?
3369 Caveat: this can be called for a freshly initialized
3370 iterator; face_id is -1 in this case. We know that the new
3371 face will not change until limit, i.e. if the new face has a
3372 box, all characters up to limit will have one. But, as
3373 usual, we don't know whether limit is really the end. */
3374 if (new_face_id != it->face_id)
3376 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3378 /* If new face has a box but old face has not, this is
3379 the start of a run of characters with box, i.e. it has
3380 a shadow on the left side. The value of face_id of the
3381 iterator will be -1 if this is the initial call that gets
3382 the face. In this case, we have to look in front of IT's
3383 position and see whether there is a face != new_face_id. */
3384 it->start_of_box_run_p
3385 = (new_face->box != FACE_NO_BOX
3386 && (it->face_id >= 0
3387 || IT_CHARPOS (*it) == BEG
3388 || new_face_id != face_before_it_pos (it)));
3389 it->face_box_p = new_face->box != FACE_NO_BOX;
3392 else
3394 int base_face_id, bufpos;
3395 int i;
3396 Lisp_Object from_overlay
3397 = (it->current.overlay_string_index >= 0
3398 ? it->string_overlays[it->current.overlay_string_index]
3399 : Qnil);
3401 /* See if we got to this string directly or indirectly from
3402 an overlay property. That includes the before-string or
3403 after-string of an overlay, strings in display properties
3404 provided by an overlay, their text properties, etc.
3406 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
3407 if (! NILP (from_overlay))
3408 for (i = it->sp - 1; i >= 0; i--)
3410 if (it->stack[i].current.overlay_string_index >= 0)
3411 from_overlay
3412 = it->string_overlays[it->stack[i].current.overlay_string_index];
3413 else if (! NILP (it->stack[i].from_overlay))
3414 from_overlay = it->stack[i].from_overlay;
3416 if (!NILP (from_overlay))
3417 break;
3420 if (! NILP (from_overlay))
3422 bufpos = IT_CHARPOS (*it);
3423 /* For a string from an overlay, the base face depends
3424 only on text properties and ignores overlays. */
3425 base_face_id
3426 = face_for_overlay_string (it->w,
3427 IT_CHARPOS (*it),
3428 it->region_beg_charpos,
3429 it->region_end_charpos,
3430 &next_stop,
3431 (IT_CHARPOS (*it)
3432 + TEXT_PROP_DISTANCE_LIMIT),
3434 from_overlay);
3436 else
3438 bufpos = 0;
3440 /* For strings from a `display' property, use the face at
3441 IT's current buffer position as the base face to merge
3442 with, so that overlay strings appear in the same face as
3443 surrounding text, unless they specify their own
3444 faces. */
3445 base_face_id = underlying_face_id (it);
3448 new_face_id = face_at_string_position (it->w,
3449 it->string,
3450 IT_STRING_CHARPOS (*it),
3451 bufpos,
3452 it->region_beg_charpos,
3453 it->region_end_charpos,
3454 &next_stop,
3455 base_face_id, 0);
3457 #if 0 /* This shouldn't be neccessary. Let's check it. */
3458 /* If IT is used to display a mode line we would really like to
3459 use the mode line face instead of the frame's default face. */
3460 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
3461 && new_face_id == DEFAULT_FACE_ID)
3462 new_face_id = CURRENT_MODE_LINE_FACE_ID (it->w);
3463 #endif
3465 /* Is this a start of a run of characters with box? Caveat:
3466 this can be called for a freshly allocated iterator; face_id
3467 is -1 is this case. We know that the new face will not
3468 change until the next check pos, i.e. if the new face has a
3469 box, all characters up to that position will have a
3470 box. But, as usual, we don't know whether that position
3471 is really the end. */
3472 if (new_face_id != it->face_id)
3474 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3475 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3477 /* If new face has a box but old face hasn't, this is the
3478 start of a run of characters with box, i.e. it has a
3479 shadow on the left side. */
3480 it->start_of_box_run_p
3481 = new_face->box && (old_face == NULL || !old_face->box);
3482 it->face_box_p = new_face->box != FACE_NO_BOX;
3486 it->face_id = new_face_id;
3487 return HANDLED_NORMALLY;
3491 /* Return the ID of the face ``underlying'' IT's current position,
3492 which is in a string. If the iterator is associated with a
3493 buffer, return the face at IT's current buffer position.
3494 Otherwise, use the iterator's base_face_id. */
3496 static int
3497 underlying_face_id (it)
3498 struct it *it;
3500 int face_id = it->base_face_id, i;
3502 xassert (STRINGP (it->string));
3504 for (i = it->sp - 1; i >= 0; --i)
3505 if (NILP (it->stack[i].string))
3506 face_id = it->stack[i].face_id;
3508 return face_id;
3512 /* Compute the face one character before or after the current position
3513 of IT. BEFORE_P non-zero means get the face in front of IT's
3514 position. Value is the id of the face. */
3516 static int
3517 face_before_or_after_it_pos (it, before_p)
3518 struct it *it;
3519 int before_p;
3521 int face_id, limit;
3522 EMACS_INT next_check_charpos;
3523 struct text_pos pos;
3525 xassert (it->s == NULL);
3527 if (STRINGP (it->string))
3529 int bufpos, base_face_id;
3531 /* No face change past the end of the string (for the case
3532 we are padding with spaces). No face change before the
3533 string start. */
3534 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
3535 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
3536 return it->face_id;
3538 /* Set pos to the position before or after IT's current position. */
3539 if (before_p)
3540 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
3541 else
3542 /* For composition, we must check the character after the
3543 composition. */
3544 pos = (it->what == IT_COMPOSITION
3545 ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string)
3546 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
3548 if (it->current.overlay_string_index >= 0)
3549 bufpos = IT_CHARPOS (*it);
3550 else
3551 bufpos = 0;
3553 base_face_id = underlying_face_id (it);
3555 /* Get the face for ASCII, or unibyte. */
3556 face_id = face_at_string_position (it->w,
3557 it->string,
3558 CHARPOS (pos),
3559 bufpos,
3560 it->region_beg_charpos,
3561 it->region_end_charpos,
3562 &next_check_charpos,
3563 base_face_id, 0);
3565 /* Correct the face for charsets different from ASCII. Do it
3566 for the multibyte case only. The face returned above is
3567 suitable for unibyte text if IT->string is unibyte. */
3568 if (STRING_MULTIBYTE (it->string))
3570 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
3571 int rest = SBYTES (it->string) - BYTEPOS (pos);
3572 int c, len;
3573 struct face *face = FACE_FROM_ID (it->f, face_id);
3575 c = string_char_and_length (p, rest, &len);
3576 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), it->string);
3579 else
3581 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3582 || (IT_CHARPOS (*it) <= BEGV && before_p))
3583 return it->face_id;
3585 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3586 pos = it->current.pos;
3588 if (before_p)
3589 DEC_TEXT_POS (pos, it->multibyte_p);
3590 else
3592 if (it->what == IT_COMPOSITION)
3593 /* For composition, we must check the position after the
3594 composition. */
3595 pos.charpos += it->cmp_len, pos.bytepos += it->len;
3596 else
3597 INC_TEXT_POS (pos, it->multibyte_p);
3600 /* Determine face for CHARSET_ASCII, or unibyte. */
3601 face_id = face_at_buffer_position (it->w,
3602 CHARPOS (pos),
3603 it->region_beg_charpos,
3604 it->region_end_charpos,
3605 &next_check_charpos,
3606 limit, 0);
3608 /* Correct the face for charsets different from ASCII. Do it
3609 for the multibyte case only. The face returned above is
3610 suitable for unibyte text if current_buffer is unibyte. */
3611 if (it->multibyte_p)
3613 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3614 struct face *face = FACE_FROM_ID (it->f, face_id);
3615 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
3619 return face_id;
3624 /***********************************************************************
3625 Invisible text
3626 ***********************************************************************/
3628 /* Set up iterator IT from invisible properties at its current
3629 position. Called from handle_stop. */
3631 static enum prop_handled
3632 handle_invisible_prop (it)
3633 struct it *it;
3635 enum prop_handled handled = HANDLED_NORMALLY;
3637 if (STRINGP (it->string))
3639 extern Lisp_Object Qinvisible;
3640 Lisp_Object prop, end_charpos, limit, charpos;
3642 /* Get the value of the invisible text property at the
3643 current position. Value will be nil if there is no such
3644 property. */
3645 charpos = make_number (IT_STRING_CHARPOS (*it));
3646 prop = Fget_text_property (charpos, Qinvisible, it->string);
3648 if (!NILP (prop)
3649 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3651 handled = HANDLED_RECOMPUTE_PROPS;
3653 /* Get the position at which the next change of the
3654 invisible text property can be found in IT->string.
3655 Value will be nil if the property value is the same for
3656 all the rest of IT->string. */
3657 XSETINT (limit, SCHARS (it->string));
3658 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3659 it->string, limit);
3661 /* Text at current position is invisible. The next
3662 change in the property is at position end_charpos.
3663 Move IT's current position to that position. */
3664 if (INTEGERP (end_charpos)
3665 && XFASTINT (end_charpos) < XFASTINT (limit))
3667 struct text_pos old;
3668 old = it->current.string_pos;
3669 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3670 compute_string_pos (&it->current.string_pos, old, it->string);
3672 else
3674 /* The rest of the string is invisible. If this is an
3675 overlay string, proceed with the next overlay string
3676 or whatever comes and return a character from there. */
3677 if (it->current.overlay_string_index >= 0)
3679 next_overlay_string (it);
3680 /* Don't check for overlay strings when we just
3681 finished processing them. */
3682 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3684 else
3686 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3687 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3692 else
3694 int invis_p;
3695 EMACS_INT newpos, next_stop, start_charpos;
3696 Lisp_Object pos, prop, overlay;
3698 /* First of all, is there invisible text at this position? */
3699 start_charpos = IT_CHARPOS (*it);
3700 pos = make_number (IT_CHARPOS (*it));
3701 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3702 &overlay);
3703 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3705 /* If we are on invisible text, skip over it. */
3706 if (invis_p && IT_CHARPOS (*it) < it->end_charpos)
3708 /* Record whether we have to display an ellipsis for the
3709 invisible text. */
3710 int display_ellipsis_p = invis_p == 2;
3712 handled = HANDLED_RECOMPUTE_PROPS;
3714 /* Loop skipping over invisible text. The loop is left at
3715 ZV or with IT on the first char being visible again. */
3718 /* Try to skip some invisible text. Return value is the
3719 position reached which can be equal to IT's position
3720 if there is nothing invisible here. This skips both
3721 over invisible text properties and overlays with
3722 invisible property. */
3723 newpos = skip_invisible (IT_CHARPOS (*it),
3724 &next_stop, ZV, it->window);
3726 /* If we skipped nothing at all we weren't at invisible
3727 text in the first place. If everything to the end of
3728 the buffer was skipped, end the loop. */
3729 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
3730 invis_p = 0;
3731 else
3733 /* We skipped some characters but not necessarily
3734 all there are. Check if we ended up on visible
3735 text. Fget_char_property returns the property of
3736 the char before the given position, i.e. if we
3737 get invis_p = 0, this means that the char at
3738 newpos is visible. */
3739 pos = make_number (newpos);
3740 prop = Fget_char_property (pos, Qinvisible, it->window);
3741 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3744 /* If we ended up on invisible text, proceed to
3745 skip starting with next_stop. */
3746 if (invis_p)
3747 IT_CHARPOS (*it) = next_stop;
3749 /* If there are adjacent invisible texts, don't lose the
3750 second one's ellipsis. */
3751 if (invis_p == 2)
3752 display_ellipsis_p = 1;
3754 while (invis_p);
3756 /* The position newpos is now either ZV or on visible text. */
3757 IT_CHARPOS (*it) = newpos;
3758 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3760 /* If there are before-strings at the start of invisible
3761 text, and the text is invisible because of a text
3762 property, arrange to show before-strings because 20.x did
3763 it that way. (If the text is invisible because of an
3764 overlay property instead of a text property, this is
3765 already handled in the overlay code.) */
3766 if (NILP (overlay)
3767 && get_overlay_strings (it, start_charpos))
3769 handled = HANDLED_RECOMPUTE_PROPS;
3770 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3772 else if (display_ellipsis_p)
3774 /* Make sure that the glyphs of the ellipsis will get
3775 correct `charpos' values. If we would not update
3776 it->position here, the glyphs would belong to the
3777 last visible character _before_ the invisible
3778 text, which confuses `set_cursor_from_row'.
3780 We use the last invisible position instead of the
3781 first because this way the cursor is always drawn on
3782 the first "." of the ellipsis, whenever PT is inside
3783 the invisible text. Otherwise the cursor would be
3784 placed _after_ the ellipsis when the point is after the
3785 first invisible character. */
3786 if (!STRINGP (it->object))
3788 it->position.charpos = IT_CHARPOS (*it) - 1;
3789 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
3791 setup_for_ellipsis (it, 0);
3792 /* Let the ellipsis display before
3793 considering any properties of the following char.
3794 Fixes jasonr@gnu.org 01 Oct 07 bug. */
3795 handled = HANDLED_RETURN;
3800 return handled;
3804 /* Make iterator IT return `...' next.
3805 Replaces LEN characters from buffer. */
3807 static void
3808 setup_for_ellipsis (it, len)
3809 struct it *it;
3810 int len;
3812 /* Use the display table definition for `...'. Invalid glyphs
3813 will be handled by the method returning elements from dpvec. */
3814 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3816 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3817 it->dpvec = v->contents;
3818 it->dpend = v->contents + v->size;
3820 else
3822 /* Default `...'. */
3823 it->dpvec = default_invis_vector;
3824 it->dpend = default_invis_vector + 3;
3827 it->dpvec_char_len = len;
3828 it->current.dpvec_index = 0;
3829 it->dpvec_face_id = -1;
3831 /* Remember the current face id in case glyphs specify faces.
3832 IT's face is restored in set_iterator_to_next.
3833 saved_face_id was set to preceding char's face in handle_stop. */
3834 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
3835 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
3837 it->method = GET_FROM_DISPLAY_VECTOR;
3838 it->ellipsis_p = 1;
3843 /***********************************************************************
3844 'display' property
3845 ***********************************************************************/
3847 /* Set up iterator IT from `display' property at its current position.
3848 Called from handle_stop.
3849 We return HANDLED_RETURN if some part of the display property
3850 overrides the display of the buffer text itself.
3851 Otherwise we return HANDLED_NORMALLY. */
3853 static enum prop_handled
3854 handle_display_prop (it)
3855 struct it *it;
3857 Lisp_Object prop, object, overlay;
3858 struct text_pos *position;
3859 /* Nonzero if some property replaces the display of the text itself. */
3860 int display_replaced_p = 0;
3862 if (STRINGP (it->string))
3864 object = it->string;
3865 position = &it->current.string_pos;
3867 else
3869 XSETWINDOW (object, it->w);
3870 position = &it->current.pos;
3873 /* Reset those iterator values set from display property values. */
3874 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
3875 it->space_width = Qnil;
3876 it->font_height = Qnil;
3877 it->voffset = 0;
3879 /* We don't support recursive `display' properties, i.e. string
3880 values that have a string `display' property, that have a string
3881 `display' property etc. */
3882 if (!it->string_from_display_prop_p)
3883 it->area = TEXT_AREA;
3885 prop = get_char_property_and_overlay (make_number (position->charpos),
3886 Qdisplay, object, &overlay);
3887 if (NILP (prop))
3888 return HANDLED_NORMALLY;
3889 /* Now OVERLAY is the overlay that gave us this property, or nil
3890 if it was a text property. */
3892 if (!STRINGP (it->string))
3893 object = it->w->buffer;
3895 if (CONSP (prop)
3896 /* Simple properties. */
3897 && !EQ (XCAR (prop), Qimage)
3898 && !EQ (XCAR (prop), Qspace)
3899 && !EQ (XCAR (prop), Qwhen)
3900 && !EQ (XCAR (prop), Qslice)
3901 && !EQ (XCAR (prop), Qspace_width)
3902 && !EQ (XCAR (prop), Qheight)
3903 && !EQ (XCAR (prop), Qraise)
3904 /* Marginal area specifications. */
3905 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
3906 && !EQ (XCAR (prop), Qleft_fringe)
3907 && !EQ (XCAR (prop), Qright_fringe)
3908 && !NILP (XCAR (prop)))
3910 for (; CONSP (prop); prop = XCDR (prop))
3912 if (handle_single_display_spec (it, XCAR (prop), object, overlay,
3913 position, display_replaced_p))
3915 display_replaced_p = 1;
3916 /* If some text in a string is replaced, `position' no
3917 longer points to the position of `object'. */
3918 if (STRINGP (object))
3919 break;
3923 else if (VECTORP (prop))
3925 int i;
3926 for (i = 0; i < ASIZE (prop); ++i)
3927 if (handle_single_display_spec (it, AREF (prop, i), object, overlay,
3928 position, display_replaced_p))
3930 display_replaced_p = 1;
3931 /* If some text in a string is replaced, `position' no
3932 longer points to the position of `object'. */
3933 if (STRINGP (object))
3934 break;
3937 else
3939 int ret = handle_single_display_spec (it, prop, object, overlay,
3940 position, 0);
3941 if (ret < 0) /* Replaced by "", i.e. nothing. */
3942 return HANDLED_RECOMPUTE_PROPS;
3943 if (ret)
3944 display_replaced_p = 1;
3947 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
3951 /* Value is the position of the end of the `display' property starting
3952 at START_POS in OBJECT. */
3954 static struct text_pos
3955 display_prop_end (it, object, start_pos)
3956 struct it *it;
3957 Lisp_Object object;
3958 struct text_pos start_pos;
3960 Lisp_Object end;
3961 struct text_pos end_pos;
3963 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
3964 Qdisplay, object, Qnil);
3965 CHARPOS (end_pos) = XFASTINT (end);
3966 if (STRINGP (object))
3967 compute_string_pos (&end_pos, start_pos, it->string);
3968 else
3969 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
3971 return end_pos;
3975 /* Set up IT from a single `display' specification PROP. OBJECT
3976 is the object in which the `display' property was found. *POSITION
3977 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3978 means that we previously saw a display specification which already
3979 replaced text display with something else, for example an image;
3980 we ignore such properties after the first one has been processed.
3982 OVERLAY is the overlay this `display' property came from,
3983 or nil if it was a text property.
3985 If PROP is a `space' or `image' specification, and in some other
3986 cases too, set *POSITION to the position where the `display'
3987 property ends.
3989 Value is non-zero if something was found which replaces the display
3990 of buffer or string text. Specifically, the value is -1 if that
3991 "something" is "nothing". */
3993 static int
3994 handle_single_display_spec (it, spec, object, overlay, position,
3995 display_replaced_before_p)
3996 struct it *it;
3997 Lisp_Object spec;
3998 Lisp_Object object;
3999 Lisp_Object overlay;
4000 struct text_pos *position;
4001 int display_replaced_before_p;
4003 Lisp_Object form;
4004 Lisp_Object location, value;
4005 struct text_pos start_pos, save_pos;
4006 int valid_p;
4008 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4009 If the result is non-nil, use VALUE instead of SPEC. */
4010 form = Qt;
4011 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
4013 spec = XCDR (spec);
4014 if (!CONSP (spec))
4015 return 0;
4016 form = XCAR (spec);
4017 spec = XCDR (spec);
4020 if (!NILP (form) && !EQ (form, Qt))
4022 int count = SPECPDL_INDEX ();
4023 struct gcpro gcpro1;
4025 /* Bind `object' to the object having the `display' property, a
4026 buffer or string. Bind `position' to the position in the
4027 object where the property was found, and `buffer-position'
4028 to the current position in the buffer. */
4029 specbind (Qobject, object);
4030 specbind (Qposition, make_number (CHARPOS (*position)));
4031 specbind (Qbuffer_position,
4032 make_number (STRINGP (object)
4033 ? IT_CHARPOS (*it) : CHARPOS (*position)));
4034 GCPRO1 (form);
4035 form = safe_eval (form);
4036 UNGCPRO;
4037 unbind_to (count, Qnil);
4040 if (NILP (form))
4041 return 0;
4043 /* Handle `(height HEIGHT)' specifications. */
4044 if (CONSP (spec)
4045 && EQ (XCAR (spec), Qheight)
4046 && CONSP (XCDR (spec)))
4048 if (!FRAME_WINDOW_P (it->f))
4049 return 0;
4051 it->font_height = XCAR (XCDR (spec));
4052 if (!NILP (it->font_height))
4054 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4055 int new_height = -1;
4057 if (CONSP (it->font_height)
4058 && (EQ (XCAR (it->font_height), Qplus)
4059 || EQ (XCAR (it->font_height), Qminus))
4060 && CONSP (XCDR (it->font_height))
4061 && INTEGERP (XCAR (XCDR (it->font_height))))
4063 /* `(+ N)' or `(- N)' where N is an integer. */
4064 int steps = XINT (XCAR (XCDR (it->font_height)));
4065 if (EQ (XCAR (it->font_height), Qplus))
4066 steps = - steps;
4067 it->face_id = smaller_face (it->f, it->face_id, steps);
4069 else if (FUNCTIONP (it->font_height))
4071 /* Call function with current height as argument.
4072 Value is the new height. */
4073 Lisp_Object height;
4074 height = safe_call1 (it->font_height,
4075 face->lface[LFACE_HEIGHT_INDEX]);
4076 if (NUMBERP (height))
4077 new_height = XFLOATINT (height);
4079 else if (NUMBERP (it->font_height))
4081 /* Value is a multiple of the canonical char height. */
4082 struct face *face;
4084 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
4085 new_height = (XFLOATINT (it->font_height)
4086 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
4088 else
4090 /* Evaluate IT->font_height with `height' bound to the
4091 current specified height to get the new height. */
4092 int count = SPECPDL_INDEX ();
4094 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
4095 value = safe_eval (it->font_height);
4096 unbind_to (count, Qnil);
4098 if (NUMBERP (value))
4099 new_height = XFLOATINT (value);
4102 if (new_height > 0)
4103 it->face_id = face_with_height (it->f, it->face_id, new_height);
4106 return 0;
4109 /* Handle `(space-width WIDTH)'. */
4110 if (CONSP (spec)
4111 && EQ (XCAR (spec), Qspace_width)
4112 && CONSP (XCDR (spec)))
4114 if (!FRAME_WINDOW_P (it->f))
4115 return 0;
4117 value = XCAR (XCDR (spec));
4118 if (NUMBERP (value) && XFLOATINT (value) > 0)
4119 it->space_width = value;
4121 return 0;
4124 /* Handle `(slice X Y WIDTH HEIGHT)'. */
4125 if (CONSP (spec)
4126 && EQ (XCAR (spec), Qslice))
4128 Lisp_Object tem;
4130 if (!FRAME_WINDOW_P (it->f))
4131 return 0;
4133 if (tem = XCDR (spec), CONSP (tem))
4135 it->slice.x = XCAR (tem);
4136 if (tem = XCDR (tem), CONSP (tem))
4138 it->slice.y = XCAR (tem);
4139 if (tem = XCDR (tem), CONSP (tem))
4141 it->slice.width = XCAR (tem);
4142 if (tem = XCDR (tem), CONSP (tem))
4143 it->slice.height = XCAR (tem);
4148 return 0;
4151 /* Handle `(raise FACTOR)'. */
4152 if (CONSP (spec)
4153 && EQ (XCAR (spec), Qraise)
4154 && CONSP (XCDR (spec)))
4156 if (!FRAME_WINDOW_P (it->f))
4157 return 0;
4159 #ifdef HAVE_WINDOW_SYSTEM
4160 value = XCAR (XCDR (spec));
4161 if (NUMBERP (value))
4163 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4164 it->voffset = - (XFLOATINT (value)
4165 * (FONT_HEIGHT (face->font)));
4167 #endif /* HAVE_WINDOW_SYSTEM */
4169 return 0;
4172 /* Don't handle the other kinds of display specifications
4173 inside a string that we got from a `display' property. */
4174 if (it->string_from_display_prop_p)
4175 return 0;
4177 /* Characters having this form of property are not displayed, so
4178 we have to find the end of the property. */
4179 start_pos = *position;
4180 *position = display_prop_end (it, object, start_pos);
4181 value = Qnil;
4183 /* Stop the scan at that end position--we assume that all
4184 text properties change there. */
4185 it->stop_charpos = position->charpos;
4187 /* Handle `(left-fringe BITMAP [FACE])'
4188 and `(right-fringe BITMAP [FACE])'. */
4189 if (CONSP (spec)
4190 && (EQ (XCAR (spec), Qleft_fringe)
4191 || EQ (XCAR (spec), Qright_fringe))
4192 && CONSP (XCDR (spec)))
4194 int face_id = DEFAULT_FACE_ID;
4195 int fringe_bitmap;
4197 if (!FRAME_WINDOW_P (it->f))
4198 /* If we return here, POSITION has been advanced
4199 across the text with this property. */
4200 return 0;
4202 #ifdef HAVE_WINDOW_SYSTEM
4203 value = XCAR (XCDR (spec));
4204 if (!SYMBOLP (value)
4205 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
4206 /* If we return here, POSITION has been advanced
4207 across the text with this property. */
4208 return 0;
4210 if (CONSP (XCDR (XCDR (spec))))
4212 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
4213 int face_id2 = lookup_derived_face (it->f, face_name,
4214 FRINGE_FACE_ID, 0);
4215 if (face_id2 >= 0)
4216 face_id = face_id2;
4219 /* Save current settings of IT so that we can restore them
4220 when we are finished with the glyph property value. */
4222 save_pos = it->position;
4223 it->position = *position;
4224 push_it (it);
4225 it->position = save_pos;
4227 it->area = TEXT_AREA;
4228 it->what = IT_IMAGE;
4229 it->image_id = -1; /* no image */
4230 it->position = start_pos;
4231 it->object = NILP (object) ? it->w->buffer : object;
4232 it->method = GET_FROM_IMAGE;
4233 it->from_overlay = Qnil;
4234 it->face_id = face_id;
4236 /* Say that we haven't consumed the characters with
4237 `display' property yet. The call to pop_it in
4238 set_iterator_to_next will clean this up. */
4239 *position = start_pos;
4241 if (EQ (XCAR (spec), Qleft_fringe))
4243 it->left_user_fringe_bitmap = fringe_bitmap;
4244 it->left_user_fringe_face_id = face_id;
4246 else
4248 it->right_user_fringe_bitmap = fringe_bitmap;
4249 it->right_user_fringe_face_id = face_id;
4251 #endif /* HAVE_WINDOW_SYSTEM */
4252 return 1;
4255 /* Prepare to handle `((margin left-margin) ...)',
4256 `((margin right-margin) ...)' and `((margin nil) ...)'
4257 prefixes for display specifications. */
4258 location = Qunbound;
4259 if (CONSP (spec) && CONSP (XCAR (spec)))
4261 Lisp_Object tem;
4263 value = XCDR (spec);
4264 if (CONSP (value))
4265 value = XCAR (value);
4267 tem = XCAR (spec);
4268 if (EQ (XCAR (tem), Qmargin)
4269 && (tem = XCDR (tem),
4270 tem = CONSP (tem) ? XCAR (tem) : Qnil,
4271 (NILP (tem)
4272 || EQ (tem, Qleft_margin)
4273 || EQ (tem, Qright_margin))))
4274 location = tem;
4277 if (EQ (location, Qunbound))
4279 location = Qnil;
4280 value = spec;
4283 /* After this point, VALUE is the property after any
4284 margin prefix has been stripped. It must be a string,
4285 an image specification, or `(space ...)'.
4287 LOCATION specifies where to display: `left-margin',
4288 `right-margin' or nil. */
4290 valid_p = (STRINGP (value)
4291 #ifdef HAVE_WINDOW_SYSTEM
4292 || (FRAME_WINDOW_P (it->f) && valid_image_p (value))
4293 #endif /* not HAVE_WINDOW_SYSTEM */
4294 || (CONSP (value) && EQ (XCAR (value), Qspace)));
4296 if (valid_p && !display_replaced_before_p)
4298 /* Save current settings of IT so that we can restore them
4299 when we are finished with the glyph property value. */
4300 save_pos = it->position;
4301 it->position = *position;
4302 push_it (it);
4303 it->position = save_pos;
4304 it->from_overlay = overlay;
4306 if (NILP (location))
4307 it->area = TEXT_AREA;
4308 else if (EQ (location, Qleft_margin))
4309 it->area = LEFT_MARGIN_AREA;
4310 else
4311 it->area = RIGHT_MARGIN_AREA;
4313 if (STRINGP (value))
4315 if (SCHARS (value) == 0)
4317 pop_it (it);
4318 return -1; /* Replaced by "", i.e. nothing. */
4320 it->string = value;
4321 it->multibyte_p = STRING_MULTIBYTE (it->string);
4322 it->current.overlay_string_index = -1;
4323 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4324 it->end_charpos = it->string_nchars = SCHARS (it->string);
4325 it->method = GET_FROM_STRING;
4326 it->stop_charpos = 0;
4327 it->string_from_display_prop_p = 1;
4328 /* Say that we haven't consumed the characters with
4329 `display' property yet. The call to pop_it in
4330 set_iterator_to_next will clean this up. */
4331 if (BUFFERP (object))
4332 *position = start_pos;
4334 else if (CONSP (value) && EQ (XCAR (value), Qspace))
4336 it->method = GET_FROM_STRETCH;
4337 it->object = value;
4338 *position = it->position = start_pos;
4340 #ifdef HAVE_WINDOW_SYSTEM
4341 else
4343 it->what = IT_IMAGE;
4344 it->image_id = lookup_image (it->f, value);
4345 it->position = start_pos;
4346 it->object = NILP (object) ? it->w->buffer : object;
4347 it->method = GET_FROM_IMAGE;
4349 /* Say that we haven't consumed the characters with
4350 `display' property yet. The call to pop_it in
4351 set_iterator_to_next will clean this up. */
4352 *position = start_pos;
4354 #endif /* HAVE_WINDOW_SYSTEM */
4356 return 1;
4359 /* Invalid property or property not supported. Restore
4360 POSITION to what it was before. */
4361 *position = start_pos;
4362 return 0;
4366 /* Check if SPEC is a display sub-property value whose text should be
4367 treated as intangible. */
4369 static int
4370 single_display_spec_intangible_p (prop)
4371 Lisp_Object prop;
4373 /* Skip over `when FORM'. */
4374 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
4376 prop = XCDR (prop);
4377 if (!CONSP (prop))
4378 return 0;
4379 prop = XCDR (prop);
4382 if (STRINGP (prop))
4383 return 1;
4385 if (!CONSP (prop))
4386 return 0;
4388 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
4389 we don't need to treat text as intangible. */
4390 if (EQ (XCAR (prop), Qmargin))
4392 prop = XCDR (prop);
4393 if (!CONSP (prop))
4394 return 0;
4396 prop = XCDR (prop);
4397 if (!CONSP (prop)
4398 || EQ (XCAR (prop), Qleft_margin)
4399 || EQ (XCAR (prop), Qright_margin))
4400 return 0;
4403 return (CONSP (prop)
4404 && (EQ (XCAR (prop), Qimage)
4405 || EQ (XCAR (prop), Qspace)));
4409 /* Check if PROP is a display property value whose text should be
4410 treated as intangible. */
4413 display_prop_intangible_p (prop)
4414 Lisp_Object prop;
4416 if (CONSP (prop)
4417 && CONSP (XCAR (prop))
4418 && !EQ (Qmargin, XCAR (XCAR (prop))))
4420 /* A list of sub-properties. */
4421 while (CONSP (prop))
4423 if (single_display_spec_intangible_p (XCAR (prop)))
4424 return 1;
4425 prop = XCDR (prop);
4428 else if (VECTORP (prop))
4430 /* A vector of sub-properties. */
4431 int i;
4432 for (i = 0; i < ASIZE (prop); ++i)
4433 if (single_display_spec_intangible_p (AREF (prop, i)))
4434 return 1;
4436 else
4437 return single_display_spec_intangible_p (prop);
4439 return 0;
4443 /* Return 1 if PROP is a display sub-property value containing STRING. */
4445 static int
4446 single_display_spec_string_p (prop, string)
4447 Lisp_Object prop, string;
4449 if (EQ (string, prop))
4450 return 1;
4452 /* Skip over `when FORM'. */
4453 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
4455 prop = XCDR (prop);
4456 if (!CONSP (prop))
4457 return 0;
4458 prop = XCDR (prop);
4461 if (CONSP (prop))
4462 /* Skip over `margin LOCATION'. */
4463 if (EQ (XCAR (prop), Qmargin))
4465 prop = XCDR (prop);
4466 if (!CONSP (prop))
4467 return 0;
4469 prop = XCDR (prop);
4470 if (!CONSP (prop))
4471 return 0;
4474 return CONSP (prop) && EQ (XCAR (prop), string);
4478 /* Return 1 if STRING appears in the `display' property PROP. */
4480 static int
4481 display_prop_string_p (prop, string)
4482 Lisp_Object prop, string;
4484 if (CONSP (prop)
4485 && CONSP (XCAR (prop))
4486 && !EQ (Qmargin, XCAR (XCAR (prop))))
4488 /* A list of sub-properties. */
4489 while (CONSP (prop))
4491 if (single_display_spec_string_p (XCAR (prop), string))
4492 return 1;
4493 prop = XCDR (prop);
4496 else if (VECTORP (prop))
4498 /* A vector of sub-properties. */
4499 int i;
4500 for (i = 0; i < ASIZE (prop); ++i)
4501 if (single_display_spec_string_p (AREF (prop, i), string))
4502 return 1;
4504 else
4505 return single_display_spec_string_p (prop, string);
4507 return 0;
4511 /* Determine from which buffer position in W's buffer STRING comes
4512 from. AROUND_CHARPOS is an approximate position where it could
4513 be from. Value is the buffer position or 0 if it couldn't be
4514 determined.
4516 W's buffer must be current.
4518 This function is necessary because we don't record buffer positions
4519 in glyphs generated from strings (to keep struct glyph small).
4520 This function may only use code that doesn't eval because it is
4521 called asynchronously from note_mouse_highlight. */
4524 string_buffer_position (w, string, around_charpos)
4525 struct window *w;
4526 Lisp_Object string;
4527 int around_charpos;
4529 Lisp_Object limit, prop, pos;
4530 const int MAX_DISTANCE = 1000;
4531 int found = 0;
4533 pos = make_number (around_charpos);
4534 limit = make_number (min (XINT (pos) + MAX_DISTANCE, ZV));
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 = Fnext_single_char_property_change (pos, Qdisplay, Qnil, limit);
4544 if (!found)
4546 pos = make_number (around_charpos);
4547 limit = make_number (max (XINT (pos) - MAX_DISTANCE, BEGV));
4548 while (!found && !EQ (pos, limit))
4550 prop = Fget_char_property (pos, Qdisplay, Qnil);
4551 if (!NILP (prop) && display_prop_string_p (prop, string))
4552 found = 1;
4553 else
4554 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
4555 limit);
4559 return found ? XINT (pos) : 0;
4564 /***********************************************************************
4565 `composition' property
4566 ***********************************************************************/
4568 static enum prop_handled
4569 handle_auto_composed_prop (it)
4570 struct it *it;
4572 enum prop_handled handled = HANDLED_NORMALLY;
4574 if (FRAME_WINDOW_P (it->f) && FUNCTIONP (Vauto_composition_function))
4576 Lisp_Object val = Qnil;
4577 EMACS_INT pos, limit = -1;
4579 if (STRINGP (it->string))
4580 pos = IT_STRING_CHARPOS (*it);
4581 else
4582 pos = IT_CHARPOS (*it);
4584 val = Fget_text_property (make_number (pos), Qauto_composed, it->string);
4585 if (! NILP (val))
4587 Lisp_Object cmp_prop;
4588 EMACS_INT cmp_start, cmp_end;
4590 if (get_property_and_range (pos, Qcomposition, &cmp_prop,
4591 &cmp_start, &cmp_end, it->string)
4592 && cmp_start == pos
4593 && COMPOSITION_METHOD (cmp_prop) == COMPOSITION_WITH_GLYPH_STRING)
4595 Lisp_Object gstring = COMPOSITION_COMPONENTS (cmp_prop);
4596 Lisp_Object font_object = LGSTRING_FONT (gstring);
4598 if (! EQ (font_object,
4599 font_at (-1, pos, FACE_FROM_ID (it->f, it->face_id),
4600 it->w, it->string)))
4601 /* We must re-compute the composition for the
4602 different font. */
4603 val = Qnil;
4606 if (! NILP (val))
4608 Lisp_Object end;
4610 /* As Fnext_single_char_property_change is very slow, we
4611 limit the search to the current line. */
4612 if (STRINGP (it->string))
4613 limit = SCHARS (it->string);
4614 else
4615 limit = find_next_newline_no_quit (pos, 1);
4616 end = Fnext_single_char_property_change (make_number (pos),
4617 Qauto_composed,
4618 it->string,
4619 make_number (limit));
4621 if (XINT (end) < limit)
4622 /* The current point is auto-composed, but there exist
4623 characters not yet composed beyond the
4624 auto-composed region. There's a possiblity that
4625 the last characters in the region may be newly
4626 composed. */
4627 val = Qnil;
4630 if (NILP (val) && ! STRINGP (it->string))
4632 if (limit < 0)
4633 limit = (STRINGP (it->string) ? SCHARS (it->string)
4634 : find_next_newline_no_quit (pos, 1));
4635 if (pos < limit)
4637 int count = SPECPDL_INDEX ();
4638 Lisp_Object args[5];
4640 limit = font_range (pos, limit, FACE_FROM_ID (it->f, it->face_id),
4641 it->f, it->string);
4642 args[0] = Vauto_composition_function;
4643 specbind (Qauto_composition_function, Qnil);
4644 args[1] = make_number (pos);
4645 args[2] = make_number (limit);
4646 args[3] = it->window;
4647 args[4] = it->string;
4648 safe_call (5, args);
4649 unbind_to (count, Qnil);
4654 return handled;
4657 /* Set up iterator IT from `composition' property at its current
4658 position. Called from handle_stop. */
4660 static enum prop_handled
4661 handle_composition_prop (it)
4662 struct it *it;
4664 Lisp_Object prop, string;
4665 EMACS_INT pos, pos_byte, start, end;
4666 enum prop_handled handled = HANDLED_NORMALLY;
4668 if (STRINGP (it->string))
4670 unsigned char *s;
4672 pos = IT_STRING_CHARPOS (*it);
4673 pos_byte = IT_STRING_BYTEPOS (*it);
4674 string = it->string;
4675 s = SDATA (string) + pos_byte;
4676 it->c = STRING_CHAR (s, 0);
4678 else
4680 pos = IT_CHARPOS (*it);
4681 pos_byte = IT_BYTEPOS (*it);
4682 string = Qnil;
4683 it->c = FETCH_CHAR (pos_byte);
4686 /* If there's a valid composition and point is not inside of the
4687 composition (in the case that the composition is from the current
4688 buffer), draw a glyph composed from the composition components. */
4689 if (find_composition (pos, -1, &start, &end, &prop, string)
4690 && COMPOSITION_VALID_P (start, end, prop)
4691 && (STRINGP (it->string) || (PT <= start || PT >= end)))
4693 int id;
4695 if (start != pos)
4697 if (STRINGP (it->string))
4698 pos_byte = string_char_to_byte (it->string, start);
4699 else
4700 pos_byte = CHAR_TO_BYTE (start);
4702 id = get_composition_id (start, pos_byte, end - start, prop, string);
4704 if (id >= 0)
4706 struct composition *cmp = composition_table[id];
4708 if (cmp->glyph_len == 0)
4710 /* No glyph. */
4711 if (STRINGP (it->string))
4713 IT_STRING_CHARPOS (*it) = end;
4714 IT_STRING_BYTEPOS (*it) = string_char_to_byte (it->string,
4715 end);
4717 else
4719 IT_CHARPOS (*it) = end;
4720 IT_BYTEPOS (*it) = CHAR_TO_BYTE (end);
4722 return HANDLED_RECOMPUTE_PROPS;
4725 it->stop_charpos = end;
4726 push_it (it);
4728 it->method = GET_FROM_COMPOSITION;
4729 it->cmp_id = id;
4730 it->cmp_len = COMPOSITION_LENGTH (prop);
4731 /* For a terminal, draw only the first (non-TAB) character
4732 of the components. */
4733 if (composition_table[id]->method == COMPOSITION_WITH_GLYPH_STRING)
4735 /* FIXME: This doesn't do anything!?! */
4736 Lisp_Object lgstring = AREF (XHASH_TABLE (composition_hash_table)
4737 ->key_and_value,
4738 cmp->hash_index * 2);
4740 else
4742 int i;
4744 for (i = 0; i < cmp->glyph_len; i++)
4745 if ((it->c = COMPOSITION_GLYPH (composition_table[id], i))
4746 != '\t')
4747 break;
4749 if (it->c == '\t')
4750 it->c = ' ';
4751 it->len = (STRINGP (it->string)
4752 ? string_char_to_byte (it->string, end)
4753 : CHAR_TO_BYTE (end)) - pos_byte;
4754 handled = HANDLED_RETURN;
4758 return handled;
4763 /***********************************************************************
4764 Overlay strings
4765 ***********************************************************************/
4767 /* The following structure is used to record overlay strings for
4768 later sorting in load_overlay_strings. */
4770 struct overlay_entry
4772 Lisp_Object overlay;
4773 Lisp_Object string;
4774 int priority;
4775 int after_string_p;
4779 /* Set up iterator IT from overlay strings at its current position.
4780 Called from handle_stop. */
4782 static enum prop_handled
4783 handle_overlay_change (it)
4784 struct it *it;
4786 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
4787 return HANDLED_RECOMPUTE_PROPS;
4788 else
4789 return HANDLED_NORMALLY;
4793 /* Set up the next overlay string for delivery by IT, if there is an
4794 overlay string to deliver. Called by set_iterator_to_next when the
4795 end of the current overlay string is reached. If there are more
4796 overlay strings to display, IT->string and
4797 IT->current.overlay_string_index are set appropriately here.
4798 Otherwise IT->string is set to nil. */
4800 static void
4801 next_overlay_string (it)
4802 struct it *it;
4804 ++it->current.overlay_string_index;
4805 if (it->current.overlay_string_index == it->n_overlay_strings)
4807 /* No more overlay strings. Restore IT's settings to what
4808 they were before overlay strings were processed, and
4809 continue to deliver from current_buffer. */
4810 int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
4812 pop_it (it);
4813 xassert (it->sp > 0
4814 || it->method == GET_FROM_COMPOSITION
4815 || (NILP (it->string)
4816 && it->method == GET_FROM_BUFFER
4817 && it->stop_charpos >= BEGV
4818 && it->stop_charpos <= it->end_charpos));
4819 it->current.overlay_string_index = -1;
4820 it->n_overlay_strings = 0;
4822 /* If we're at the end of the buffer, record that we have
4823 processed the overlay strings there already, so that
4824 next_element_from_buffer doesn't try it again. */
4825 if (NILP (it->string) && IT_CHARPOS (*it) >= it->end_charpos)
4826 it->overlay_strings_at_end_processed_p = 1;
4828 /* If we have to display `...' for invisible text, set
4829 the iterator up for that. */
4830 if (display_ellipsis_p)
4831 setup_for_ellipsis (it, 0);
4833 else
4835 /* There are more overlay strings to process. If
4836 IT->current.overlay_string_index has advanced to a position
4837 where we must load IT->overlay_strings with more strings, do
4838 it. */
4839 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
4841 if (it->current.overlay_string_index && i == 0)
4842 load_overlay_strings (it, 0);
4844 /* Initialize IT to deliver display elements from the overlay
4845 string. */
4846 it->string = it->overlay_strings[i];
4847 it->multibyte_p = STRING_MULTIBYTE (it->string);
4848 SET_TEXT_POS (it->current.string_pos, 0, 0);
4849 it->method = GET_FROM_STRING;
4850 it->stop_charpos = 0;
4853 CHECK_IT (it);
4857 /* Compare two overlay_entry structures E1 and E2. Used as a
4858 comparison function for qsort in load_overlay_strings. Overlay
4859 strings for the same position are sorted so that
4861 1. All after-strings come in front of before-strings, except
4862 when they come from the same overlay.
4864 2. Within after-strings, strings are sorted so that overlay strings
4865 from overlays with higher priorities come first.
4867 2. Within before-strings, strings are sorted so that overlay
4868 strings from overlays with higher priorities come last.
4870 Value is analogous to strcmp. */
4873 static int
4874 compare_overlay_entries (e1, e2)
4875 void *e1, *e2;
4877 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4878 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4879 int result;
4881 if (entry1->after_string_p != entry2->after_string_p)
4883 /* Let after-strings appear in front of before-strings if
4884 they come from different overlays. */
4885 if (EQ (entry1->overlay, entry2->overlay))
4886 result = entry1->after_string_p ? 1 : -1;
4887 else
4888 result = entry1->after_string_p ? -1 : 1;
4890 else if (entry1->after_string_p)
4891 /* After-strings sorted in order of decreasing priority. */
4892 result = entry2->priority - entry1->priority;
4893 else
4894 /* Before-strings sorted in order of increasing priority. */
4895 result = entry1->priority - entry2->priority;
4897 return result;
4901 /* Load the vector IT->overlay_strings with overlay strings from IT's
4902 current buffer position, or from CHARPOS if that is > 0. Set
4903 IT->n_overlays to the total number of overlay strings found.
4905 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4906 a time. On entry into load_overlay_strings,
4907 IT->current.overlay_string_index gives the number of overlay
4908 strings that have already been loaded by previous calls to this
4909 function.
4911 IT->add_overlay_start contains an additional overlay start
4912 position to consider for taking overlay strings from, if non-zero.
4913 This position comes into play when the overlay has an `invisible'
4914 property, and both before and after-strings. When we've skipped to
4915 the end of the overlay, because of its `invisible' property, we
4916 nevertheless want its before-string to appear.
4917 IT->add_overlay_start will contain the overlay start position
4918 in this case.
4920 Overlay strings are sorted so that after-string strings come in
4921 front of before-string strings. Within before and after-strings,
4922 strings are sorted by overlay priority. See also function
4923 compare_overlay_entries. */
4925 static void
4926 load_overlay_strings (it, charpos)
4927 struct it *it;
4928 int charpos;
4930 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
4931 Lisp_Object overlay, window, str, invisible;
4932 struct Lisp_Overlay *ov;
4933 int start, end;
4934 int size = 20;
4935 int n = 0, i, j, invis_p;
4936 struct overlay_entry *entries
4937 = (struct overlay_entry *) alloca (size * sizeof *entries);
4939 if (charpos <= 0)
4940 charpos = IT_CHARPOS (*it);
4942 /* Append the overlay string STRING of overlay OVERLAY to vector
4943 `entries' which has size `size' and currently contains `n'
4944 elements. AFTER_P non-zero means STRING is an after-string of
4945 OVERLAY. */
4946 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4947 do \
4949 Lisp_Object priority; \
4951 if (n == size) \
4953 int new_size = 2 * size; \
4954 struct overlay_entry *old = entries; \
4955 entries = \
4956 (struct overlay_entry *) alloca (new_size \
4957 * sizeof *entries); \
4958 bcopy (old, entries, size * sizeof *entries); \
4959 size = new_size; \
4962 entries[n].string = (STRING); \
4963 entries[n].overlay = (OVERLAY); \
4964 priority = Foverlay_get ((OVERLAY), Qpriority); \
4965 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4966 entries[n].after_string_p = (AFTER_P); \
4967 ++n; \
4969 while (0)
4971 /* Process overlay before the overlay center. */
4972 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4974 XSETMISC (overlay, ov);
4975 xassert (OVERLAYP (overlay));
4976 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4977 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4979 if (end < charpos)
4980 break;
4982 /* Skip this overlay if it doesn't start or end at IT's current
4983 position. */
4984 if (end != charpos && start != charpos)
4985 continue;
4987 /* Skip this overlay if it doesn't apply to IT->w. */
4988 window = Foverlay_get (overlay, Qwindow);
4989 if (WINDOWP (window) && XWINDOW (window) != it->w)
4990 continue;
4992 /* If the text ``under'' the overlay is invisible, both before-
4993 and after-strings from this overlay are visible; start and
4994 end position are indistinguishable. */
4995 invisible = Foverlay_get (overlay, Qinvisible);
4996 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4998 /* If overlay has a non-empty before-string, record it. */
4999 if ((start == charpos || (end == charpos && invis_p))
5000 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5001 && SCHARS (str))
5002 RECORD_OVERLAY_STRING (overlay, str, 0);
5004 /* If overlay has a non-empty after-string, record it. */
5005 if ((end == charpos || (start == charpos && invis_p))
5006 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5007 && SCHARS (str))
5008 RECORD_OVERLAY_STRING (overlay, str, 1);
5011 /* Process overlays after the overlay center. */
5012 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
5014 XSETMISC (overlay, ov);
5015 xassert (OVERLAYP (overlay));
5016 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5017 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5019 if (start > charpos)
5020 break;
5022 /* Skip this overlay if it doesn't start or end at IT's current
5023 position. */
5024 if (end != charpos && start != charpos)
5025 continue;
5027 /* Skip this overlay if it doesn't apply to IT->w. */
5028 window = Foverlay_get (overlay, Qwindow);
5029 if (WINDOWP (window) && XWINDOW (window) != it->w)
5030 continue;
5032 /* If the text ``under'' the overlay is invisible, it has a zero
5033 dimension, and both before- and after-strings apply. */
5034 invisible = Foverlay_get (overlay, Qinvisible);
5035 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5037 /* If overlay has a non-empty before-string, record it. */
5038 if ((start == charpos || (end == charpos && invis_p))
5039 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5040 && SCHARS (str))
5041 RECORD_OVERLAY_STRING (overlay, str, 0);
5043 /* If overlay has a non-empty after-string, record it. */
5044 if ((end == charpos || (start == charpos && invis_p))
5045 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5046 && SCHARS (str))
5047 RECORD_OVERLAY_STRING (overlay, str, 1);
5050 #undef RECORD_OVERLAY_STRING
5052 /* Sort entries. */
5053 if (n > 1)
5054 qsort (entries, n, sizeof *entries, compare_overlay_entries);
5056 /* Record the total number of strings to process. */
5057 it->n_overlay_strings = n;
5059 /* IT->current.overlay_string_index is the number of overlay strings
5060 that have already been consumed by IT. Copy some of the
5061 remaining overlay strings to IT->overlay_strings. */
5062 i = 0;
5063 j = it->current.overlay_string_index;
5064 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
5066 it->overlay_strings[i] = entries[j].string;
5067 it->string_overlays[i++] = entries[j++].overlay;
5070 CHECK_IT (it);
5074 /* Get the first chunk of overlay strings at IT's current buffer
5075 position, or at CHARPOS if that is > 0. Value is non-zero if at
5076 least one overlay string was found. */
5078 static int
5079 get_overlay_strings_1 (it, charpos, compute_stop_p)
5080 struct it *it;
5081 int charpos;
5082 int compute_stop_p;
5084 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
5085 process. This fills IT->overlay_strings with strings, and sets
5086 IT->n_overlay_strings to the total number of strings to process.
5087 IT->pos.overlay_string_index has to be set temporarily to zero
5088 because load_overlay_strings needs this; it must be set to -1
5089 when no overlay strings are found because a zero value would
5090 indicate a position in the first overlay string. */
5091 it->current.overlay_string_index = 0;
5092 load_overlay_strings (it, charpos);
5094 /* If we found overlay strings, set up IT to deliver display
5095 elements from the first one. Otherwise set up IT to deliver
5096 from current_buffer. */
5097 if (it->n_overlay_strings)
5099 /* Make sure we know settings in current_buffer, so that we can
5100 restore meaningful values when we're done with the overlay
5101 strings. */
5102 if (compute_stop_p)
5103 compute_stop_pos (it);
5104 xassert (it->face_id >= 0);
5106 /* Save IT's settings. They are restored after all overlay
5107 strings have been processed. */
5108 xassert (!compute_stop_p || it->sp == 0);
5109 push_it (it);
5111 /* Set up IT to deliver display elements from the first overlay
5112 string. */
5113 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5114 it->string = it->overlay_strings[0];
5115 it->from_overlay = Qnil;
5116 it->stop_charpos = 0;
5117 xassert (STRINGP (it->string));
5118 it->end_charpos = SCHARS (it->string);
5119 it->multibyte_p = STRING_MULTIBYTE (it->string);
5120 it->method = GET_FROM_STRING;
5121 return 1;
5124 it->current.overlay_string_index = -1;
5125 return 0;
5128 static int
5129 get_overlay_strings (it, charpos)
5130 struct it *it;
5131 int charpos;
5133 it->string = Qnil;
5134 it->method = GET_FROM_BUFFER;
5136 (void) get_overlay_strings_1 (it, charpos, 1);
5138 CHECK_IT (it);
5140 /* Value is non-zero if we found at least one overlay string. */
5141 return STRINGP (it->string);
5146 /***********************************************************************
5147 Saving and restoring state
5148 ***********************************************************************/
5150 /* Save current settings of IT on IT->stack. Called, for example,
5151 before setting up IT for an overlay string, to be able to restore
5152 IT's settings to what they were after the overlay string has been
5153 processed. */
5155 static void
5156 push_it (it)
5157 struct it *it;
5159 struct iterator_stack_entry *p;
5161 xassert (it->sp < IT_STACK_SIZE);
5162 p = it->stack + it->sp;
5164 p->stop_charpos = it->stop_charpos;
5165 xassert (it->face_id >= 0);
5166 p->face_id = it->face_id;
5167 p->string = it->string;
5168 p->method = it->method;
5169 p->from_overlay = it->from_overlay;
5170 switch (p->method)
5172 case GET_FROM_IMAGE:
5173 p->u.image.object = it->object;
5174 p->u.image.image_id = it->image_id;
5175 p->u.image.slice = it->slice;
5176 break;
5177 case GET_FROM_COMPOSITION:
5178 p->u.comp.object = it->object;
5179 p->u.comp.c = it->c;
5180 p->u.comp.len = it->len;
5181 p->u.comp.cmp_id = it->cmp_id;
5182 p->u.comp.cmp_len = it->cmp_len;
5183 break;
5184 case GET_FROM_STRETCH:
5185 p->u.stretch.object = it->object;
5186 break;
5188 p->position = it->position;
5189 p->current = it->current;
5190 p->end_charpos = it->end_charpos;
5191 p->string_nchars = it->string_nchars;
5192 p->area = it->area;
5193 p->multibyte_p = it->multibyte_p;
5194 p->space_width = it->space_width;
5195 p->font_height = it->font_height;
5196 p->voffset = it->voffset;
5197 p->string_from_display_prop_p = it->string_from_display_prop_p;
5198 p->display_ellipsis_p = 0;
5199 ++it->sp;
5203 /* Restore IT's settings from IT->stack. Called, for example, when no
5204 more overlay strings must be processed, and we return to delivering
5205 display elements from a buffer, or when the end of a string from a
5206 `display' property is reached and we return to delivering display
5207 elements from an overlay string, or from a buffer. */
5209 static void
5210 pop_it (it)
5211 struct it *it;
5213 struct iterator_stack_entry *p;
5215 xassert (it->sp > 0);
5216 --it->sp;
5217 p = it->stack + it->sp;
5218 it->stop_charpos = p->stop_charpos;
5219 it->face_id = p->face_id;
5220 it->current = p->current;
5221 it->position = p->position;
5222 it->string = p->string;
5223 it->from_overlay = p->from_overlay;
5224 if (NILP (it->string))
5225 SET_TEXT_POS (it->current.string_pos, -1, -1);
5226 it->method = p->method;
5227 switch (it->method)
5229 case GET_FROM_IMAGE:
5230 it->image_id = p->u.image.image_id;
5231 it->object = p->u.image.object;
5232 it->slice = p->u.image.slice;
5233 break;
5234 case GET_FROM_COMPOSITION:
5235 it->object = p->u.comp.object;
5236 it->c = p->u.comp.c;
5237 it->len = p->u.comp.len;
5238 it->cmp_id = p->u.comp.cmp_id;
5239 it->cmp_len = p->u.comp.cmp_len;
5240 break;
5241 case GET_FROM_STRETCH:
5242 it->object = p->u.comp.object;
5243 break;
5244 case GET_FROM_BUFFER:
5245 it->object = it->w->buffer;
5246 break;
5247 case GET_FROM_STRING:
5248 it->object = it->string;
5249 break;
5251 it->end_charpos = p->end_charpos;
5252 it->string_nchars = p->string_nchars;
5253 it->area = p->area;
5254 it->multibyte_p = p->multibyte_p;
5255 it->space_width = p->space_width;
5256 it->font_height = p->font_height;
5257 it->voffset = p->voffset;
5258 it->string_from_display_prop_p = p->string_from_display_prop_p;
5263 /***********************************************************************
5264 Moving over lines
5265 ***********************************************************************/
5267 /* Set IT's current position to the previous line start. */
5269 static void
5270 back_to_previous_line_start (it)
5271 struct it *it;
5273 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
5274 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
5278 /* Move IT to the next line start.
5280 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
5281 we skipped over part of the text (as opposed to moving the iterator
5282 continuously over the text). Otherwise, don't change the value
5283 of *SKIPPED_P.
5285 Newlines may come from buffer text, overlay strings, or strings
5286 displayed via the `display' property. That's the reason we can't
5287 simply use find_next_newline_no_quit.
5289 Note that this function may not skip over invisible text that is so
5290 because of text properties and immediately follows a newline. If
5291 it would, function reseat_at_next_visible_line_start, when called
5292 from set_iterator_to_next, would effectively make invisible
5293 characters following a newline part of the wrong glyph row, which
5294 leads to wrong cursor motion. */
5296 static int
5297 forward_to_next_line_start (it, skipped_p)
5298 struct it *it;
5299 int *skipped_p;
5301 int old_selective, newline_found_p, n;
5302 const int MAX_NEWLINE_DISTANCE = 500;
5304 /* If already on a newline, just consume it to avoid unintended
5305 skipping over invisible text below. */
5306 if (it->what == IT_CHARACTER
5307 && it->c == '\n'
5308 && CHARPOS (it->position) == IT_CHARPOS (*it))
5310 set_iterator_to_next (it, 0);
5311 it->c = 0;
5312 return 1;
5315 /* Don't handle selective display in the following. It's (a)
5316 unnecessary because it's done by the caller, and (b) leads to an
5317 infinite recursion because next_element_from_ellipsis indirectly
5318 calls this function. */
5319 old_selective = it->selective;
5320 it->selective = 0;
5322 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
5323 from buffer text. */
5324 for (n = newline_found_p = 0;
5325 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
5326 n += STRINGP (it->string) ? 0 : 1)
5328 if (!get_next_display_element (it))
5329 return 0;
5330 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
5331 set_iterator_to_next (it, 0);
5334 /* If we didn't find a newline near enough, see if we can use a
5335 short-cut. */
5336 if (!newline_found_p)
5338 int start = IT_CHARPOS (*it);
5339 int limit = find_next_newline_no_quit (start, 1);
5340 Lisp_Object pos;
5342 xassert (!STRINGP (it->string));
5344 /* If there isn't any `display' property in sight, and no
5345 overlays, we can just use the position of the newline in
5346 buffer text. */
5347 if (it->stop_charpos >= limit
5348 || ((pos = Fnext_single_property_change (make_number (start),
5349 Qdisplay,
5350 Qnil, make_number (limit)),
5351 NILP (pos))
5352 && next_overlay_change (start) == ZV))
5354 IT_CHARPOS (*it) = limit;
5355 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
5356 *skipped_p = newline_found_p = 1;
5358 else
5360 while (get_next_display_element (it)
5361 && !newline_found_p)
5363 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
5364 set_iterator_to_next (it, 0);
5369 it->selective = old_selective;
5370 return newline_found_p;
5374 /* Set IT's current position to the previous visible line start. Skip
5375 invisible text that is so either due to text properties or due to
5376 selective display. Caution: this does not change IT->current_x and
5377 IT->hpos. */
5379 static void
5380 back_to_previous_visible_line_start (it)
5381 struct it *it;
5383 while (IT_CHARPOS (*it) > BEGV)
5385 back_to_previous_line_start (it);
5387 if (IT_CHARPOS (*it) <= BEGV)
5388 break;
5390 /* If selective > 0, then lines indented more than that values
5391 are invisible. */
5392 if (it->selective > 0
5393 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5394 (double) it->selective)) /* iftc */
5395 continue;
5397 /* Check the newline before point for invisibility. */
5399 Lisp_Object prop;
5400 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
5401 Qinvisible, it->window);
5402 if (TEXT_PROP_MEANS_INVISIBLE (prop))
5403 continue;
5406 if (IT_CHARPOS (*it) <= BEGV)
5407 break;
5410 struct it it2;
5411 int pos;
5412 EMACS_INT beg, end;
5413 Lisp_Object val, overlay;
5415 /* If newline is part of a composition, continue from start of composition */
5416 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
5417 && beg < IT_CHARPOS (*it))
5418 goto replaced;
5420 /* If newline is replaced by a display property, find start of overlay
5421 or interval and continue search from that point. */
5422 it2 = *it;
5423 pos = --IT_CHARPOS (it2);
5424 --IT_BYTEPOS (it2);
5425 it2.sp = 0;
5426 if (handle_display_prop (&it2) == HANDLED_RETURN
5427 && !NILP (val = get_char_property_and_overlay
5428 (make_number (pos), Qdisplay, Qnil, &overlay))
5429 && (OVERLAYP (overlay)
5430 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
5431 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
5432 goto replaced;
5434 /* Newline is not replaced by anything -- so we are done. */
5435 break;
5437 replaced:
5438 if (beg < BEGV)
5439 beg = BEGV;
5440 IT_CHARPOS (*it) = beg;
5441 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
5445 it->continuation_lines_width = 0;
5447 xassert (IT_CHARPOS (*it) >= BEGV);
5448 xassert (IT_CHARPOS (*it) == BEGV
5449 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5450 CHECK_IT (it);
5454 /* Reseat iterator IT at the previous visible line start. Skip
5455 invisible text that is so either due to text properties or due to
5456 selective display. At the end, update IT's overlay information,
5457 face information etc. */
5459 void
5460 reseat_at_previous_visible_line_start (it)
5461 struct it *it;
5463 back_to_previous_visible_line_start (it);
5464 reseat (it, it->current.pos, 1);
5465 CHECK_IT (it);
5469 /* Reseat iterator IT on the next visible line start in the current
5470 buffer. ON_NEWLINE_P non-zero means position IT on the newline
5471 preceding the line start. Skip over invisible text that is so
5472 because of selective display. Compute faces, overlays etc at the
5473 new position. Note that this function does not skip over text that
5474 is invisible because of text properties. */
5476 static void
5477 reseat_at_next_visible_line_start (it, on_newline_p)
5478 struct it *it;
5479 int on_newline_p;
5481 int newline_found_p, skipped_p = 0;
5483 newline_found_p = forward_to_next_line_start (it, &skipped_p);
5485 /* Skip over lines that are invisible because they are indented
5486 more than the value of IT->selective. */
5487 if (it->selective > 0)
5488 while (IT_CHARPOS (*it) < ZV
5489 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5490 (double) it->selective)) /* iftc */
5492 xassert (IT_BYTEPOS (*it) == BEGV
5493 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5494 newline_found_p = forward_to_next_line_start (it, &skipped_p);
5497 /* Position on the newline if that's what's requested. */
5498 if (on_newline_p && newline_found_p)
5500 if (STRINGP (it->string))
5502 if (IT_STRING_CHARPOS (*it) > 0)
5504 --IT_STRING_CHARPOS (*it);
5505 --IT_STRING_BYTEPOS (*it);
5508 else if (IT_CHARPOS (*it) > BEGV)
5510 --IT_CHARPOS (*it);
5511 --IT_BYTEPOS (*it);
5512 reseat (it, it->current.pos, 0);
5515 else if (skipped_p)
5516 reseat (it, it->current.pos, 0);
5518 CHECK_IT (it);
5523 /***********************************************************************
5524 Changing an iterator's position
5525 ***********************************************************************/
5527 /* Change IT's current position to POS in current_buffer. If FORCE_P
5528 is non-zero, always check for text properties at the new position.
5529 Otherwise, text properties are only looked up if POS >=
5530 IT->check_charpos of a property. */
5532 static void
5533 reseat (it, pos, force_p)
5534 struct it *it;
5535 struct text_pos pos;
5536 int force_p;
5538 int original_pos = IT_CHARPOS (*it);
5540 reseat_1 (it, pos, 0);
5542 /* Determine where to check text properties. Avoid doing it
5543 where possible because text property lookup is very expensive. */
5544 if (force_p
5545 || CHARPOS (pos) > it->stop_charpos
5546 || CHARPOS (pos) < original_pos)
5547 handle_stop (it);
5549 CHECK_IT (it);
5553 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
5554 IT->stop_pos to POS, also. */
5556 static void
5557 reseat_1 (it, pos, set_stop_p)
5558 struct it *it;
5559 struct text_pos pos;
5560 int set_stop_p;
5562 /* Don't call this function when scanning a C string. */
5563 xassert (it->s == NULL);
5565 /* POS must be a reasonable value. */
5566 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
5568 it->current.pos = it->position = pos;
5569 it->end_charpos = ZV;
5570 it->dpvec = NULL;
5571 it->current.dpvec_index = -1;
5572 it->current.overlay_string_index = -1;
5573 IT_STRING_CHARPOS (*it) = -1;
5574 IT_STRING_BYTEPOS (*it) = -1;
5575 it->string = Qnil;
5576 it->method = GET_FROM_BUFFER;
5577 it->object = it->w->buffer;
5578 it->area = TEXT_AREA;
5579 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
5580 it->sp = 0;
5581 it->string_from_display_prop_p = 0;
5582 it->face_before_selective_p = 0;
5584 if (set_stop_p)
5585 it->stop_charpos = CHARPOS (pos);
5589 /* Set up IT for displaying a string, starting at CHARPOS in window W.
5590 If S is non-null, it is a C string to iterate over. Otherwise,
5591 STRING gives a Lisp string to iterate over.
5593 If PRECISION > 0, don't return more then PRECISION number of
5594 characters from the string.
5596 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
5597 characters have been returned. FIELD_WIDTH < 0 means an infinite
5598 field width.
5600 MULTIBYTE = 0 means disable processing of multibyte characters,
5601 MULTIBYTE > 0 means enable it,
5602 MULTIBYTE < 0 means use IT->multibyte_p.
5604 IT must be initialized via a prior call to init_iterator before
5605 calling this function. */
5607 static void
5608 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
5609 struct it *it;
5610 unsigned char *s;
5611 Lisp_Object string;
5612 int charpos;
5613 int precision, field_width, multibyte;
5615 /* No region in strings. */
5616 it->region_beg_charpos = it->region_end_charpos = -1;
5618 /* No text property checks performed by default, but see below. */
5619 it->stop_charpos = -1;
5621 /* Set iterator position and end position. */
5622 bzero (&it->current, sizeof it->current);
5623 it->current.overlay_string_index = -1;
5624 it->current.dpvec_index = -1;
5625 xassert (charpos >= 0);
5627 /* If STRING is specified, use its multibyteness, otherwise use the
5628 setting of MULTIBYTE, if specified. */
5629 if (multibyte >= 0)
5630 it->multibyte_p = multibyte > 0;
5632 if (s == NULL)
5634 xassert (STRINGP (string));
5635 it->string = string;
5636 it->s = NULL;
5637 it->end_charpos = it->string_nchars = SCHARS (string);
5638 it->method = GET_FROM_STRING;
5639 it->current.string_pos = string_pos (charpos, string);
5641 else
5643 it->s = s;
5644 it->string = Qnil;
5646 /* Note that we use IT->current.pos, not it->current.string_pos,
5647 for displaying C strings. */
5648 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
5649 if (it->multibyte_p)
5651 it->current.pos = c_string_pos (charpos, s, 1);
5652 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
5654 else
5656 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
5657 it->end_charpos = it->string_nchars = strlen (s);
5660 it->method = GET_FROM_C_STRING;
5663 /* PRECISION > 0 means don't return more than PRECISION characters
5664 from the string. */
5665 if (precision > 0 && it->end_charpos - charpos > precision)
5666 it->end_charpos = it->string_nchars = charpos + precision;
5668 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
5669 characters have been returned. FIELD_WIDTH == 0 means don't pad,
5670 FIELD_WIDTH < 0 means infinite field width. This is useful for
5671 padding with `-' at the end of a mode line. */
5672 if (field_width < 0)
5673 field_width = INFINITY;
5674 if (field_width > it->end_charpos - charpos)
5675 it->end_charpos = charpos + field_width;
5677 /* Use the standard display table for displaying strings. */
5678 if (DISP_TABLE_P (Vstandard_display_table))
5679 it->dp = XCHAR_TABLE (Vstandard_display_table);
5681 it->stop_charpos = charpos;
5682 CHECK_IT (it);
5687 /***********************************************************************
5688 Iteration
5689 ***********************************************************************/
5691 /* Map enum it_method value to corresponding next_element_from_* function. */
5693 static int (* get_next_element[NUM_IT_METHODS]) P_ ((struct it *it)) =
5695 next_element_from_buffer,
5696 next_element_from_display_vector,
5697 next_element_from_composition,
5698 next_element_from_string,
5699 next_element_from_c_string,
5700 next_element_from_image,
5701 next_element_from_stretch
5704 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
5706 /* Load IT's display element fields with information about the next
5707 display element from the current position of IT. Value is zero if
5708 end of buffer (or C string) is reached. */
5710 static struct frame *last_escape_glyph_frame = NULL;
5711 static unsigned last_escape_glyph_face_id = (1 << FACE_ID_BITS);
5712 static int last_escape_glyph_merged_face_id = 0;
5715 get_next_display_element (it)
5716 struct it *it;
5718 /* Non-zero means that we found a display element. Zero means that
5719 we hit the end of what we iterate over. Performance note: the
5720 function pointer `method' used here turns out to be faster than
5721 using a sequence of if-statements. */
5722 int success_p;
5724 get_next:
5725 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
5727 if (it->what == IT_CHARACTER)
5729 /* Map via display table or translate control characters.
5730 IT->c, IT->len etc. have been set to the next character by
5731 the function call above. If we have a display table, and it
5732 contains an entry for IT->c, translate it. Don't do this if
5733 IT->c itself comes from a display table, otherwise we could
5734 end up in an infinite recursion. (An alternative could be to
5735 count the recursion depth of this function and signal an
5736 error when a certain maximum depth is reached.) Is it worth
5737 it? */
5738 if (success_p && it->dpvec == NULL)
5740 Lisp_Object dv;
5742 if (it->dp
5743 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
5744 VECTORP (dv)))
5746 struct Lisp_Vector *v = XVECTOR (dv);
5748 /* Return the first character from the display table
5749 entry, if not empty. If empty, don't display the
5750 current character. */
5751 if (v->size)
5753 it->dpvec_char_len = it->len;
5754 it->dpvec = v->contents;
5755 it->dpend = v->contents + v->size;
5756 it->current.dpvec_index = 0;
5757 it->dpvec_face_id = -1;
5758 it->saved_face_id = it->face_id;
5759 it->method = GET_FROM_DISPLAY_VECTOR;
5760 it->ellipsis_p = 0;
5762 else
5764 set_iterator_to_next (it, 0);
5766 goto get_next;
5769 /* Translate control characters into `\003' or `^C' form.
5770 Control characters coming from a display table entry are
5771 currently not translated because we use IT->dpvec to hold
5772 the translation. This could easily be changed but I
5773 don't believe that it is worth doing.
5775 If it->multibyte_p is nonzero, non-printable non-ASCII
5776 characters are also translated to octal form.
5778 If it->multibyte_p is zero, eight-bit characters that
5779 don't have corresponding multibyte char code are also
5780 translated to octal form. */
5781 else if ((it->c < ' '
5782 ? (it->area != TEXT_AREA
5783 /* In mode line, treat \n, \t like other crl chars. */
5784 || (it->c != '\t'
5785 && it->glyph_row && it->glyph_row->mode_line_p)
5786 || (it->c != '\n' && it->c != '\t'))
5787 : (it->multibyte_p
5788 ? (!CHAR_PRINTABLE_P (it->c)
5789 || (!NILP (Vnobreak_char_display)
5790 && (it->c == 0xA0 /* NO-BREAK SPACE */
5791 || it->c == 0xAD /* SOFT HYPHEN */)))
5792 : (it->c >= 127
5793 && (! unibyte_display_via_language_environment
5794 || (UNIBYTE_CHAR_HAS_MULTIBYTE_P (it->c)))))))
5796 /* IT->c is a control character which must be displayed
5797 either as '\003' or as `^C' where the '\\' and '^'
5798 can be defined in the display table. Fill
5799 IT->ctl_chars with glyphs for what we have to
5800 display. Then, set IT->dpvec to these glyphs. */
5801 Lisp_Object gc;
5802 int ctl_len;
5803 int face_id, lface_id = 0 ;
5804 int escape_glyph;
5806 /* Handle control characters with ^. */
5808 if (it->c < 128 && it->ctl_arrow_p)
5810 int g;
5812 g = '^'; /* default glyph for Control */
5813 /* Set IT->ctl_chars[0] to the glyph for `^'. */
5814 if (it->dp
5815 && (gc = DISP_CTRL_GLYPH (it->dp), GLYPH_CODE_P (gc))
5816 && GLYPH_CODE_CHAR_VALID_P (gc))
5818 g = GLYPH_CODE_CHAR (gc);
5819 lface_id = GLYPH_CODE_FACE (gc);
5821 if (lface_id)
5823 face_id = merge_faces (it->f, Qt, lface_id, it->face_id);
5825 else if (it->f == last_escape_glyph_frame
5826 && it->face_id == last_escape_glyph_face_id)
5828 face_id = last_escape_glyph_merged_face_id;
5830 else
5832 /* Merge the escape-glyph face into the current face. */
5833 face_id = merge_faces (it->f, Qescape_glyph, 0,
5834 it->face_id);
5835 last_escape_glyph_frame = it->f;
5836 last_escape_glyph_face_id = it->face_id;
5837 last_escape_glyph_merged_face_id = face_id;
5840 XSETINT (it->ctl_chars[0], g);
5841 XSETINT (it->ctl_chars[1], it->c ^ 0100);
5842 ctl_len = 2;
5843 goto display_control;
5846 /* Handle non-break space in the mode where it only gets
5847 highlighting. */
5849 if (EQ (Vnobreak_char_display, Qt)
5850 && it->c == 0xA0)
5852 /* Merge the no-break-space face into the current face. */
5853 face_id = merge_faces (it->f, Qnobreak_space, 0,
5854 it->face_id);
5856 it->c = ' ';
5857 XSETINT (it->ctl_chars[0], ' ');
5858 ctl_len = 1;
5859 goto display_control;
5862 /* Handle sequences that start with the "escape glyph". */
5864 /* the default escape glyph is \. */
5865 escape_glyph = '\\';
5867 if (it->dp
5868 && (gc = DISP_ESCAPE_GLYPH (it->dp), GLYPH_CODE_P (gc))
5869 && GLYPH_CODE_CHAR_VALID_P (gc))
5871 escape_glyph = GLYPH_CODE_CHAR (gc);
5872 lface_id = GLYPH_CODE_FACE (gc);
5874 if (lface_id)
5876 /* The display table specified a face.
5877 Merge it into face_id and also into escape_glyph. */
5878 face_id = merge_faces (it->f, Qt, lface_id,
5879 it->face_id);
5881 else if (it->f == last_escape_glyph_frame
5882 && it->face_id == last_escape_glyph_face_id)
5884 face_id = last_escape_glyph_merged_face_id;
5886 else
5888 /* Merge the escape-glyph face into the current face. */
5889 face_id = merge_faces (it->f, Qescape_glyph, 0,
5890 it->face_id);
5891 last_escape_glyph_frame = it->f;
5892 last_escape_glyph_face_id = it->face_id;
5893 last_escape_glyph_merged_face_id = face_id;
5896 /* Handle soft hyphens in the mode where they only get
5897 highlighting. */
5899 if (EQ (Vnobreak_char_display, Qt)
5900 && it->c == 0xAD)
5902 it->c = '-';
5903 XSETINT (it->ctl_chars[0], '-');
5904 ctl_len = 1;
5905 goto display_control;
5908 /* Handle non-break space and soft hyphen
5909 with the escape glyph. */
5911 if (it->c == 0xA0 || it->c == 0xAD)
5913 XSETINT (it->ctl_chars[0], escape_glyph);
5914 it->c = (it->c == 0xA0 ? ' ' : '-');
5915 XSETINT (it->ctl_chars[1], it->c);
5916 ctl_len = 2;
5917 goto display_control;
5921 unsigned char str[MAX_MULTIBYTE_LENGTH];
5922 int len;
5923 int i;
5925 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
5926 if (CHAR_BYTE8_P (it->c))
5928 str[0] = CHAR_TO_BYTE8 (it->c);
5929 len = 1;
5931 else if (it->c < 256)
5933 str[0] = it->c;
5934 len = 1;
5936 else
5938 /* It's an invalid character, which shouldn't
5939 happen actually, but due to bugs it may
5940 happen. Let's print the char as is, there's
5941 not much meaningful we can do with it. */
5942 str[0] = it->c;
5943 str[1] = it->c >> 8;
5944 str[2] = it->c >> 16;
5945 str[3] = it->c >> 24;
5946 len = 4;
5949 for (i = 0; i < len; i++)
5951 int g;
5952 XSETINT (it->ctl_chars[i * 4], escape_glyph);
5953 /* Insert three more glyphs into IT->ctl_chars for
5954 the octal display of the character. */
5955 g = ((str[i] >> 6) & 7) + '0';
5956 XSETINT (it->ctl_chars[i * 4 + 1], g);
5957 g = ((str[i] >> 3) & 7) + '0';
5958 XSETINT (it->ctl_chars[i * 4 + 2], g);
5959 g = (str[i] & 7) + '0';
5960 XSETINT (it->ctl_chars[i * 4 + 3], g);
5962 ctl_len = len * 4;
5965 display_control:
5966 /* Set up IT->dpvec and return first character from it. */
5967 it->dpvec_char_len = it->len;
5968 it->dpvec = it->ctl_chars;
5969 it->dpend = it->dpvec + ctl_len;
5970 it->current.dpvec_index = 0;
5971 it->dpvec_face_id = face_id;
5972 it->saved_face_id = it->face_id;
5973 it->method = GET_FROM_DISPLAY_VECTOR;
5974 it->ellipsis_p = 0;
5975 goto get_next;
5980 /* Adjust face id for a multibyte character. There are no multibyte
5981 character in unibyte text. */
5982 if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
5983 && it->multibyte_p
5984 && success_p
5985 && FRAME_WINDOW_P (it->f))
5987 struct face *face = FACE_FROM_ID (it->f, it->face_id);
5988 int pos = (it->s ? -1
5989 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
5990 : IT_CHARPOS (*it));
5992 it->face_id = FACE_FOR_CHAR (it->f, face, it->c, pos, it->string);
5995 /* Is this character the last one of a run of characters with
5996 box? If yes, set IT->end_of_box_run_p to 1. */
5997 if (it->face_box_p
5998 && it->s == NULL)
6000 int face_id;
6001 struct face *face;
6003 it->end_of_box_run_p
6004 = ((face_id = face_after_it_pos (it),
6005 face_id != it->face_id)
6006 && (face = FACE_FROM_ID (it->f, face_id),
6007 face->box == FACE_NO_BOX));
6010 /* Value is 0 if end of buffer or string reached. */
6011 return success_p;
6015 /* Move IT to the next display element.
6017 RESEAT_P non-zero means if called on a newline in buffer text,
6018 skip to the next visible line start.
6020 Functions get_next_display_element and set_iterator_to_next are
6021 separate because I find this arrangement easier to handle than a
6022 get_next_display_element function that also increments IT's
6023 position. The way it is we can first look at an iterator's current
6024 display element, decide whether it fits on a line, and if it does,
6025 increment the iterator position. The other way around we probably
6026 would either need a flag indicating whether the iterator has to be
6027 incremented the next time, or we would have to implement a
6028 decrement position function which would not be easy to write. */
6030 void
6031 set_iterator_to_next (it, reseat_p)
6032 struct it *it;
6033 int reseat_p;
6035 /* Reset flags indicating start and end of a sequence of characters
6036 with box. Reset them at the start of this function because
6037 moving the iterator to a new position might set them. */
6038 it->start_of_box_run_p = it->end_of_box_run_p = 0;
6040 switch (it->method)
6042 case GET_FROM_BUFFER:
6043 /* The current display element of IT is a character from
6044 current_buffer. Advance in the buffer, and maybe skip over
6045 invisible lines that are so because of selective display. */
6046 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
6047 reseat_at_next_visible_line_start (it, 0);
6048 else
6050 xassert (it->len != 0);
6051 IT_BYTEPOS (*it) += it->len;
6052 IT_CHARPOS (*it) += 1;
6053 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
6055 break;
6057 case GET_FROM_COMPOSITION:
6058 xassert (it->cmp_id >= 0 && it->cmp_id < n_compositions);
6059 xassert (it->sp > 0);
6060 pop_it (it);
6061 if (it->method == GET_FROM_STRING)
6063 IT_STRING_BYTEPOS (*it) += it->len;
6064 IT_STRING_CHARPOS (*it) += it->cmp_len;
6065 goto consider_string_end;
6067 else if (it->method == GET_FROM_BUFFER)
6069 IT_BYTEPOS (*it) += it->len;
6070 IT_CHARPOS (*it) += it->cmp_len;
6072 break;
6074 case GET_FROM_C_STRING:
6075 /* Current display element of IT is from a C string. */
6076 IT_BYTEPOS (*it) += it->len;
6077 IT_CHARPOS (*it) += 1;
6078 break;
6080 case GET_FROM_DISPLAY_VECTOR:
6081 /* Current display element of IT is from a display table entry.
6082 Advance in the display table definition. Reset it to null if
6083 end reached, and continue with characters from buffers/
6084 strings. */
6085 ++it->current.dpvec_index;
6087 /* Restore face of the iterator to what they were before the
6088 display vector entry (these entries may contain faces). */
6089 it->face_id = it->saved_face_id;
6091 if (it->dpvec + it->current.dpvec_index == it->dpend)
6093 int recheck_faces = it->ellipsis_p;
6095 if (it->s)
6096 it->method = GET_FROM_C_STRING;
6097 else if (STRINGP (it->string))
6098 it->method = GET_FROM_STRING;
6099 else
6101 it->method = GET_FROM_BUFFER;
6102 it->object = it->w->buffer;
6105 it->dpvec = NULL;
6106 it->current.dpvec_index = -1;
6108 /* Skip over characters which were displayed via IT->dpvec. */
6109 if (it->dpvec_char_len < 0)
6110 reseat_at_next_visible_line_start (it, 1);
6111 else if (it->dpvec_char_len > 0)
6113 if (it->method == GET_FROM_STRING
6114 && it->n_overlay_strings > 0)
6115 it->ignore_overlay_strings_at_pos_p = 1;
6116 it->len = it->dpvec_char_len;
6117 set_iterator_to_next (it, reseat_p);
6120 /* Maybe recheck faces after display vector */
6121 if (recheck_faces)
6122 it->stop_charpos = IT_CHARPOS (*it);
6124 break;
6126 case GET_FROM_STRING:
6127 /* Current display element is a character from a Lisp string. */
6128 xassert (it->s == NULL && STRINGP (it->string));
6129 IT_STRING_BYTEPOS (*it) += it->len;
6130 IT_STRING_CHARPOS (*it) += 1;
6132 consider_string_end:
6134 if (it->current.overlay_string_index >= 0)
6136 /* IT->string is an overlay string. Advance to the
6137 next, if there is one. */
6138 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
6139 next_overlay_string (it);
6141 else
6143 /* IT->string is not an overlay string. If we reached
6144 its end, and there is something on IT->stack, proceed
6145 with what is on the stack. This can be either another
6146 string, this time an overlay string, or a buffer. */
6147 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
6148 && it->sp > 0)
6150 pop_it (it);
6151 if (it->method == GET_FROM_STRING)
6152 goto consider_string_end;
6155 break;
6157 case GET_FROM_IMAGE:
6158 case GET_FROM_STRETCH:
6159 /* The position etc with which we have to proceed are on
6160 the stack. The position may be at the end of a string,
6161 if the `display' property takes up the whole string. */
6162 xassert (it->sp > 0);
6163 pop_it (it);
6164 if (it->method == GET_FROM_STRING)
6165 goto consider_string_end;
6166 break;
6168 default:
6169 /* There are no other methods defined, so this should be a bug. */
6170 abort ();
6173 xassert (it->method != GET_FROM_STRING
6174 || (STRINGP (it->string)
6175 && IT_STRING_CHARPOS (*it) >= 0));
6178 /* Load IT's display element fields with information about the next
6179 display element which comes from a display table entry or from the
6180 result of translating a control character to one of the forms `^C'
6181 or `\003'.
6183 IT->dpvec holds the glyphs to return as characters.
6184 IT->saved_face_id holds the face id before the display vector--
6185 it is restored into IT->face_idin set_iterator_to_next. */
6187 static int
6188 next_element_from_display_vector (it)
6189 struct it *it;
6191 Lisp_Object gc;
6193 /* Precondition. */
6194 xassert (it->dpvec && it->current.dpvec_index >= 0);
6196 it->face_id = it->saved_face_id;
6198 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
6199 That seemed totally bogus - so I changed it... */
6201 if ((gc = it->dpvec[it->current.dpvec_index], GLYPH_CODE_P (gc))
6202 && GLYPH_CODE_CHAR_VALID_P (gc))
6204 it->c = GLYPH_CODE_CHAR (gc);
6205 it->len = CHAR_BYTES (it->c);
6207 /* The entry may contain a face id to use. Such a face id is
6208 the id of a Lisp face, not a realized face. A face id of
6209 zero means no face is specified. */
6210 if (it->dpvec_face_id >= 0)
6211 it->face_id = it->dpvec_face_id;
6212 else
6214 int lface_id = GLYPH_CODE_FACE (gc);
6215 if (lface_id > 0)
6216 it->face_id = merge_faces (it->f, Qt, lface_id,
6217 it->saved_face_id);
6220 else
6221 /* Display table entry is invalid. Return a space. */
6222 it->c = ' ', it->len = 1;
6224 /* Don't change position and object of the iterator here. They are
6225 still the values of the character that had this display table
6226 entry or was translated, and that's what we want. */
6227 it->what = IT_CHARACTER;
6228 return 1;
6232 /* Load IT with the next display element from Lisp string IT->string.
6233 IT->current.string_pos is the current position within the string.
6234 If IT->current.overlay_string_index >= 0, the Lisp string is an
6235 overlay string. */
6237 static int
6238 next_element_from_string (it)
6239 struct it *it;
6241 struct text_pos position;
6243 xassert (STRINGP (it->string));
6244 xassert (IT_STRING_CHARPOS (*it) >= 0);
6245 position = it->current.string_pos;
6247 /* Time to check for invisible text? */
6248 if (IT_STRING_CHARPOS (*it) < it->end_charpos
6249 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
6251 handle_stop (it);
6253 /* Since a handler may have changed IT->method, we must
6254 recurse here. */
6255 return GET_NEXT_DISPLAY_ELEMENT (it);
6258 if (it->current.overlay_string_index >= 0)
6260 /* Get the next character from an overlay string. In overlay
6261 strings, There is no field width or padding with spaces to
6262 do. */
6263 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
6265 it->what = IT_EOB;
6266 return 0;
6268 else if (STRING_MULTIBYTE (it->string))
6270 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
6271 const unsigned char *s = (SDATA (it->string)
6272 + IT_STRING_BYTEPOS (*it));
6273 it->c = string_char_and_length (s, remaining, &it->len);
6275 else
6277 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
6278 it->len = 1;
6281 else
6283 /* Get the next character from a Lisp string that is not an
6284 overlay string. Such strings come from the mode line, for
6285 example. We may have to pad with spaces, or truncate the
6286 string. See also next_element_from_c_string. */
6287 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
6289 it->what = IT_EOB;
6290 return 0;
6292 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
6294 /* Pad with spaces. */
6295 it->c = ' ', it->len = 1;
6296 CHARPOS (position) = BYTEPOS (position) = -1;
6298 else if (STRING_MULTIBYTE (it->string))
6300 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
6301 const unsigned char *s = (SDATA (it->string)
6302 + IT_STRING_BYTEPOS (*it));
6303 it->c = string_char_and_length (s, maxlen, &it->len);
6305 else
6307 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
6308 it->len = 1;
6312 /* Record what we have and where it came from. */
6313 it->what = IT_CHARACTER;
6314 it->object = it->string;
6315 it->position = position;
6316 return 1;
6320 /* Load IT with next display element from C string IT->s.
6321 IT->string_nchars is the maximum number of characters to return
6322 from the string. IT->end_charpos may be greater than
6323 IT->string_nchars when this function is called, in which case we
6324 may have to return padding spaces. Value is zero if end of string
6325 reached, including padding spaces. */
6327 static int
6328 next_element_from_c_string (it)
6329 struct it *it;
6331 int success_p = 1;
6333 xassert (it->s);
6334 it->what = IT_CHARACTER;
6335 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
6336 it->object = Qnil;
6338 /* IT's position can be greater IT->string_nchars in case a field
6339 width or precision has been specified when the iterator was
6340 initialized. */
6341 if (IT_CHARPOS (*it) >= it->end_charpos)
6343 /* End of the game. */
6344 it->what = IT_EOB;
6345 success_p = 0;
6347 else if (IT_CHARPOS (*it) >= it->string_nchars)
6349 /* Pad with spaces. */
6350 it->c = ' ', it->len = 1;
6351 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
6353 else if (it->multibyte_p)
6355 /* Implementation note: The calls to strlen apparently aren't a
6356 performance problem because there is no noticeable performance
6357 difference between Emacs running in unibyte or multibyte mode. */
6358 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
6359 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
6360 maxlen, &it->len);
6362 else
6363 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
6365 return success_p;
6369 /* Set up IT to return characters from an ellipsis, if appropriate.
6370 The definition of the ellipsis glyphs may come from a display table
6371 entry. This function Fills IT with the first glyph from the
6372 ellipsis if an ellipsis is to be displayed. */
6374 static int
6375 next_element_from_ellipsis (it)
6376 struct it *it;
6378 if (it->selective_display_ellipsis_p)
6379 setup_for_ellipsis (it, it->len);
6380 else
6382 /* The face at the current position may be different from the
6383 face we find after the invisible text. Remember what it
6384 was in IT->saved_face_id, and signal that it's there by
6385 setting face_before_selective_p. */
6386 it->saved_face_id = it->face_id;
6387 it->method = GET_FROM_BUFFER;
6388 it->object = it->w->buffer;
6389 reseat_at_next_visible_line_start (it, 1);
6390 it->face_before_selective_p = 1;
6393 return GET_NEXT_DISPLAY_ELEMENT (it);
6397 /* Deliver an image display element. The iterator IT is already
6398 filled with image information (done in handle_display_prop). Value
6399 is always 1. */
6402 static int
6403 next_element_from_image (it)
6404 struct it *it;
6406 it->what = IT_IMAGE;
6407 return 1;
6411 /* Fill iterator IT with next display element from a stretch glyph
6412 property. IT->object is the value of the text property. Value is
6413 always 1. */
6415 static int
6416 next_element_from_stretch (it)
6417 struct it *it;
6419 it->what = IT_STRETCH;
6420 return 1;
6424 /* Load IT with the next display element from current_buffer. Value
6425 is zero if end of buffer reached. IT->stop_charpos is the next
6426 position at which to stop and check for text properties or buffer
6427 end. */
6429 static int
6430 next_element_from_buffer (it)
6431 struct it *it;
6433 int success_p = 1;
6435 /* Check this assumption, otherwise, we would never enter the
6436 if-statement, below. */
6437 xassert (IT_CHARPOS (*it) >= BEGV
6438 && IT_CHARPOS (*it) <= it->stop_charpos);
6440 if (IT_CHARPOS (*it) >= it->stop_charpos)
6442 if (IT_CHARPOS (*it) >= it->end_charpos)
6444 int overlay_strings_follow_p;
6446 /* End of the game, except when overlay strings follow that
6447 haven't been returned yet. */
6448 if (it->overlay_strings_at_end_processed_p)
6449 overlay_strings_follow_p = 0;
6450 else
6452 it->overlay_strings_at_end_processed_p = 1;
6453 overlay_strings_follow_p = get_overlay_strings (it, 0);
6456 if (overlay_strings_follow_p)
6457 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
6458 else
6460 it->what = IT_EOB;
6461 it->position = it->current.pos;
6462 success_p = 0;
6465 else
6467 handle_stop (it);
6468 return GET_NEXT_DISPLAY_ELEMENT (it);
6471 else
6473 /* No face changes, overlays etc. in sight, so just return a
6474 character from current_buffer. */
6475 unsigned char *p;
6477 /* Maybe run the redisplay end trigger hook. Performance note:
6478 This doesn't seem to cost measurable time. */
6479 if (it->redisplay_end_trigger_charpos
6480 && it->glyph_row
6481 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
6482 run_redisplay_end_trigger_hook (it);
6484 /* Get the next character, maybe multibyte. */
6485 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
6486 if (it->multibyte_p && !ASCII_BYTE_P (*p))
6488 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
6489 - IT_BYTEPOS (*it));
6490 it->c = string_char_and_length (p, maxlen, &it->len);
6492 else
6493 it->c = *p, it->len = 1;
6495 /* Record what we have and where it came from. */
6496 it->what = IT_CHARACTER;
6497 it->object = it->w->buffer;
6498 it->position = it->current.pos;
6500 /* Normally we return the character found above, except when we
6501 really want to return an ellipsis for selective display. */
6502 if (it->selective)
6504 if (it->c == '\n')
6506 /* A value of selective > 0 means hide lines indented more
6507 than that number of columns. */
6508 if (it->selective > 0
6509 && IT_CHARPOS (*it) + 1 < ZV
6510 && indented_beyond_p (IT_CHARPOS (*it) + 1,
6511 IT_BYTEPOS (*it) + 1,
6512 (double) it->selective)) /* iftc */
6514 success_p = next_element_from_ellipsis (it);
6515 it->dpvec_char_len = -1;
6518 else if (it->c == '\r' && it->selective == -1)
6520 /* A value of selective == -1 means that everything from the
6521 CR to the end of the line is invisible, with maybe an
6522 ellipsis displayed for it. */
6523 success_p = next_element_from_ellipsis (it);
6524 it->dpvec_char_len = -1;
6529 /* Value is zero if end of buffer reached. */
6530 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
6531 return success_p;
6535 /* Run the redisplay end trigger hook for IT. */
6537 static void
6538 run_redisplay_end_trigger_hook (it)
6539 struct it *it;
6541 Lisp_Object args[3];
6543 /* IT->glyph_row should be non-null, i.e. we should be actually
6544 displaying something, or otherwise we should not run the hook. */
6545 xassert (it->glyph_row);
6547 /* Set up hook arguments. */
6548 args[0] = Qredisplay_end_trigger_functions;
6549 args[1] = it->window;
6550 XSETINT (args[2], it->redisplay_end_trigger_charpos);
6551 it->redisplay_end_trigger_charpos = 0;
6553 /* Since we are *trying* to run these functions, don't try to run
6554 them again, even if they get an error. */
6555 it->w->redisplay_end_trigger = Qnil;
6556 Frun_hook_with_args (3, args);
6558 /* Notice if it changed the face of the character we are on. */
6559 handle_face_prop (it);
6563 /* Deliver a composition display element. The iterator IT is already
6564 filled with composition information (done in
6565 handle_composition_prop). Value is always 1. */
6567 static int
6568 next_element_from_composition (it)
6569 struct it *it;
6571 it->what = IT_COMPOSITION;
6572 it->position = (STRINGP (it->string)
6573 ? it->current.string_pos
6574 : it->current.pos);
6575 if (STRINGP (it->string))
6576 it->object = it->string;
6577 else
6578 it->object = it->w->buffer;
6579 return 1;
6584 /***********************************************************************
6585 Moving an iterator without producing glyphs
6586 ***********************************************************************/
6588 /* Check if iterator is at a position corresponding to a valid buffer
6589 position after some move_it_ call. */
6591 #define IT_POS_VALID_AFTER_MOVE_P(it) \
6592 ((it)->method == GET_FROM_STRING \
6593 ? IT_STRING_CHARPOS (*it) == 0 \
6594 : 1)
6597 /* Move iterator IT to a specified buffer or X position within one
6598 line on the display without producing glyphs.
6600 OP should be a bit mask including some or all of these bits:
6601 MOVE_TO_X: Stop on reaching x-position TO_X.
6602 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
6603 Regardless of OP's value, stop in reaching the end of the display line.
6605 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
6606 This means, in particular, that TO_X includes window's horizontal
6607 scroll amount.
6609 The return value has several possible values that
6610 say what condition caused the scan to stop:
6612 MOVE_POS_MATCH_OR_ZV
6613 - when TO_POS or ZV was reached.
6615 MOVE_X_REACHED
6616 -when TO_X was reached before TO_POS or ZV were reached.
6618 MOVE_LINE_CONTINUED
6619 - when we reached the end of the display area and the line must
6620 be continued.
6622 MOVE_LINE_TRUNCATED
6623 - when we reached the end of the display area and the line is
6624 truncated.
6626 MOVE_NEWLINE_OR_CR
6627 - when we stopped at a line end, i.e. a newline or a CR and selective
6628 display is on. */
6630 static enum move_it_result
6631 move_it_in_display_line_to (it, to_charpos, to_x, op)
6632 struct it *it;
6633 int to_charpos, to_x, op;
6635 enum move_it_result result = MOVE_UNDEFINED;
6636 struct glyph_row *saved_glyph_row;
6638 /* Don't produce glyphs in produce_glyphs. */
6639 saved_glyph_row = it->glyph_row;
6640 it->glyph_row = NULL;
6642 #define BUFFER_POS_REACHED_P() \
6643 ((op & MOVE_TO_POS) != 0 \
6644 && BUFFERP (it->object) \
6645 && IT_CHARPOS (*it) >= to_charpos \
6646 && (it->method == GET_FROM_BUFFER \
6647 || (it->method == GET_FROM_DISPLAY_VECTOR \
6648 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
6651 while (1)
6653 int x, i, ascent = 0, descent = 0;
6655 /* Stop if we move beyond TO_CHARPOS (after an image or stretch glyph). */
6656 if ((op & MOVE_TO_POS) != 0
6657 && BUFFERP (it->object)
6658 && it->method == GET_FROM_BUFFER
6659 && IT_CHARPOS (*it) > to_charpos)
6661 result = MOVE_POS_MATCH_OR_ZV;
6662 break;
6665 /* Stop when ZV reached.
6666 We used to stop here when TO_CHARPOS reached as well, but that is
6667 too soon if this glyph does not fit on this line. So we handle it
6668 explicitly below. */
6669 if (!get_next_display_element (it)
6670 || (it->truncate_lines_p
6671 && BUFFER_POS_REACHED_P ()))
6673 result = MOVE_POS_MATCH_OR_ZV;
6674 break;
6677 /* The call to produce_glyphs will get the metrics of the
6678 display element IT is loaded with. We record in x the
6679 x-position before this display element in case it does not
6680 fit on the line. */
6681 x = it->current_x;
6683 /* Remember the line height so far in case the next element doesn't
6684 fit on the line. */
6685 if (!it->truncate_lines_p)
6687 ascent = it->max_ascent;
6688 descent = it->max_descent;
6691 PRODUCE_GLYPHS (it);
6693 if (it->area != TEXT_AREA)
6695 set_iterator_to_next (it, 1);
6696 continue;
6699 /* The number of glyphs we get back in IT->nglyphs will normally
6700 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
6701 character on a terminal frame, or (iii) a line end. For the
6702 second case, IT->nglyphs - 1 padding glyphs will be present
6703 (on X frames, there is only one glyph produced for a
6704 composite character.
6706 The behavior implemented below means, for continuation lines,
6707 that as many spaces of a TAB as fit on the current line are
6708 displayed there. For terminal frames, as many glyphs of a
6709 multi-glyph character are displayed in the current line, too.
6710 This is what the old redisplay code did, and we keep it that
6711 way. Under X, the whole shape of a complex character must
6712 fit on the line or it will be completely displayed in the
6713 next line.
6715 Note that both for tabs and padding glyphs, all glyphs have
6716 the same width. */
6717 if (it->nglyphs)
6719 /* More than one glyph or glyph doesn't fit on line. All
6720 glyphs have the same width. */
6721 int single_glyph_width = it->pixel_width / it->nglyphs;
6722 int new_x;
6723 int x_before_this_char = x;
6724 int hpos_before_this_char = it->hpos;
6726 for (i = 0; i < it->nglyphs; ++i, x = new_x)
6728 new_x = x + single_glyph_width;
6730 /* We want to leave anything reaching TO_X to the caller. */
6731 if ((op & MOVE_TO_X) && new_x > to_x)
6733 if (BUFFER_POS_REACHED_P ())
6734 goto buffer_pos_reached;
6735 it->current_x = x;
6736 result = MOVE_X_REACHED;
6737 break;
6739 else if (/* Lines are continued. */
6740 !it->truncate_lines_p
6741 && (/* And glyph doesn't fit on the line. */
6742 new_x > it->last_visible_x
6743 /* Or it fits exactly and we're on a window
6744 system frame. */
6745 || (new_x == it->last_visible_x
6746 && FRAME_WINDOW_P (it->f))))
6748 if (/* IT->hpos == 0 means the very first glyph
6749 doesn't fit on the line, e.g. a wide image. */
6750 it->hpos == 0
6751 || (new_x == it->last_visible_x
6752 && FRAME_WINDOW_P (it->f)))
6754 ++it->hpos;
6755 it->current_x = new_x;
6757 /* The character's last glyph just barely fits
6758 in this row. */
6759 if (i == it->nglyphs - 1)
6761 /* If this is the destination position,
6762 return a position *before* it in this row,
6763 now that we know it fits in this row. */
6764 if (BUFFER_POS_REACHED_P ())
6766 it->hpos = hpos_before_this_char;
6767 it->current_x = x_before_this_char;
6768 result = MOVE_POS_MATCH_OR_ZV;
6769 break;
6772 set_iterator_to_next (it, 1);
6773 #ifdef HAVE_WINDOW_SYSTEM
6774 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
6776 if (!get_next_display_element (it))
6778 result = MOVE_POS_MATCH_OR_ZV;
6779 break;
6781 if (BUFFER_POS_REACHED_P ())
6783 if (ITERATOR_AT_END_OF_LINE_P (it))
6784 result = MOVE_POS_MATCH_OR_ZV;
6785 else
6786 result = MOVE_LINE_CONTINUED;
6787 break;
6789 if (ITERATOR_AT_END_OF_LINE_P (it))
6791 result = MOVE_NEWLINE_OR_CR;
6792 break;
6795 #endif /* HAVE_WINDOW_SYSTEM */
6798 else
6800 it->current_x = x;
6801 it->max_ascent = ascent;
6802 it->max_descent = descent;
6805 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
6806 IT_CHARPOS (*it)));
6807 result = MOVE_LINE_CONTINUED;
6808 break;
6810 else if (BUFFER_POS_REACHED_P ())
6811 goto buffer_pos_reached;
6812 else if (new_x > it->first_visible_x)
6814 /* Glyph is visible. Increment number of glyphs that
6815 would be displayed. */
6816 ++it->hpos;
6818 else
6820 /* Glyph is completely off the left margin of the display
6821 area. Nothing to do. */
6825 if (result != MOVE_UNDEFINED)
6826 break;
6828 else if (BUFFER_POS_REACHED_P ())
6830 buffer_pos_reached:
6831 it->current_x = x;
6832 it->max_ascent = ascent;
6833 it->max_descent = descent;
6834 result = MOVE_POS_MATCH_OR_ZV;
6835 break;
6837 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
6839 /* Stop when TO_X specified and reached. This check is
6840 necessary here because of lines consisting of a line end,
6841 only. The line end will not produce any glyphs and we
6842 would never get MOVE_X_REACHED. */
6843 xassert (it->nglyphs == 0);
6844 result = MOVE_X_REACHED;
6845 break;
6848 /* Is this a line end? If yes, we're done. */
6849 if (ITERATOR_AT_END_OF_LINE_P (it))
6851 result = MOVE_NEWLINE_OR_CR;
6852 break;
6855 /* The current display element has been consumed. Advance
6856 to the next. */
6857 set_iterator_to_next (it, 1);
6859 /* Stop if lines are truncated and IT's current x-position is
6860 past the right edge of the window now. */
6861 if (it->truncate_lines_p
6862 && it->current_x >= it->last_visible_x)
6864 #ifdef HAVE_WINDOW_SYSTEM
6865 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
6867 if (!get_next_display_element (it)
6868 || BUFFER_POS_REACHED_P ())
6870 result = MOVE_POS_MATCH_OR_ZV;
6871 break;
6873 if (ITERATOR_AT_END_OF_LINE_P (it))
6875 result = MOVE_NEWLINE_OR_CR;
6876 break;
6879 #endif /* HAVE_WINDOW_SYSTEM */
6880 result = MOVE_LINE_TRUNCATED;
6881 break;
6885 #undef BUFFER_POS_REACHED_P
6887 /* Restore the iterator settings altered at the beginning of this
6888 function. */
6889 it->glyph_row = saved_glyph_row;
6890 return result;
6894 /* Move IT forward until it satisfies one or more of the criteria in
6895 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
6897 OP is a bit-mask that specifies where to stop, and in particular,
6898 which of those four position arguments makes a difference. See the
6899 description of enum move_operation_enum.
6901 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
6902 screen line, this function will set IT to the next position >
6903 TO_CHARPOS. */
6905 void
6906 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
6907 struct it *it;
6908 int to_charpos, to_x, to_y, to_vpos;
6909 int op;
6911 enum move_it_result skip, skip2 = MOVE_X_REACHED;
6912 int line_height;
6913 int reached = 0;
6915 for (;;)
6917 if (op & MOVE_TO_VPOS)
6919 /* If no TO_CHARPOS and no TO_X specified, stop at the
6920 start of the line TO_VPOS. */
6921 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
6923 if (it->vpos == to_vpos)
6925 reached = 1;
6926 break;
6928 else
6929 skip = move_it_in_display_line_to (it, -1, -1, 0);
6931 else
6933 /* TO_VPOS >= 0 means stop at TO_X in the line at
6934 TO_VPOS, or at TO_POS, whichever comes first. */
6935 if (it->vpos == to_vpos)
6937 reached = 2;
6938 break;
6941 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
6943 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
6945 reached = 3;
6946 break;
6948 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
6950 /* We have reached TO_X but not in the line we want. */
6951 skip = move_it_in_display_line_to (it, to_charpos,
6952 -1, MOVE_TO_POS);
6953 if (skip == MOVE_POS_MATCH_OR_ZV)
6955 reached = 4;
6956 break;
6961 else if (op & MOVE_TO_Y)
6963 struct it it_backup;
6965 /* TO_Y specified means stop at TO_X in the line containing
6966 TO_Y---or at TO_CHARPOS if this is reached first. The
6967 problem is that we can't really tell whether the line
6968 contains TO_Y before we have completely scanned it, and
6969 this may skip past TO_X. What we do is to first scan to
6970 TO_X.
6972 If TO_X is not specified, use a TO_X of zero. The reason
6973 is to make the outcome of this function more predictable.
6974 If we didn't use TO_X == 0, we would stop at the end of
6975 the line which is probably not what a caller would expect
6976 to happen. */
6977 skip = move_it_in_display_line_to (it, to_charpos,
6978 ((op & MOVE_TO_X)
6979 ? to_x : 0),
6980 (MOVE_TO_X
6981 | (op & MOVE_TO_POS)));
6983 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
6984 if (skip == MOVE_POS_MATCH_OR_ZV)
6986 reached = 5;
6987 break;
6990 /* If TO_X was reached, we would like to know whether TO_Y
6991 is in the line. This can only be said if we know the
6992 total line height which requires us to scan the rest of
6993 the line. */
6994 if (skip == MOVE_X_REACHED)
6996 /* Wait! We can conclude that TO_Y is in the line if
6997 the already scanned glyphs make the line tall enough
6998 because further scanning doesn't make it shorter. */
6999 line_height = it->max_ascent + it->max_descent;
7000 if (to_y >= it->current_y
7001 && to_y < it->current_y + line_height)
7003 reached = 6;
7004 break;
7006 it_backup = *it;
7007 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
7008 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
7009 op & MOVE_TO_POS);
7010 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
7013 /* Now, decide whether TO_Y is in this line. */
7014 line_height = it->max_ascent + it->max_descent;
7015 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
7017 if (to_y >= it->current_y
7018 && to_y < it->current_y + line_height)
7020 if (skip == MOVE_X_REACHED)
7021 /* If TO_Y is in this line and TO_X was reached above,
7022 we scanned too far. We have to restore IT's settings
7023 to the ones before skipping. */
7024 *it = it_backup;
7025 reached = 6;
7027 else if (skip == MOVE_X_REACHED)
7029 skip = skip2;
7030 if (skip == MOVE_POS_MATCH_OR_ZV)
7031 reached = 7;
7034 if (reached)
7035 break;
7037 else if (BUFFERP (it->object)
7038 && it->method == GET_FROM_BUFFER
7039 && IT_CHARPOS (*it) >= to_charpos)
7040 skip = MOVE_POS_MATCH_OR_ZV;
7041 else
7042 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
7044 switch (skip)
7046 case MOVE_POS_MATCH_OR_ZV:
7047 reached = 8;
7048 goto out;
7050 case MOVE_NEWLINE_OR_CR:
7051 set_iterator_to_next (it, 1);
7052 it->continuation_lines_width = 0;
7053 break;
7055 case MOVE_LINE_TRUNCATED:
7056 it->continuation_lines_width = 0;
7057 reseat_at_next_visible_line_start (it, 0);
7058 if ((op & MOVE_TO_POS) != 0
7059 && IT_CHARPOS (*it) > to_charpos)
7061 reached = 9;
7062 goto out;
7064 break;
7066 case MOVE_LINE_CONTINUED:
7067 /* For continued lines ending in a tab, some of the glyphs
7068 associated with the tab are displayed on the current
7069 line. Since it->current_x does not include these glyphs,
7070 we use it->last_visible_x instead. */
7071 it->continuation_lines_width +=
7072 (it->c == '\t') ? it->last_visible_x : it->current_x;
7073 break;
7075 default:
7076 abort ();
7079 /* Reset/increment for the next run. */
7080 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
7081 it->current_x = it->hpos = 0;
7082 it->current_y += it->max_ascent + it->max_descent;
7083 ++it->vpos;
7084 last_height = it->max_ascent + it->max_descent;
7085 last_max_ascent = it->max_ascent;
7086 it->max_ascent = it->max_descent = 0;
7089 out:
7091 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
7095 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
7097 If DY > 0, move IT backward at least that many pixels. DY = 0
7098 means move IT backward to the preceding line start or BEGV. This
7099 function may move over more than DY pixels if IT->current_y - DY
7100 ends up in the middle of a line; in this case IT->current_y will be
7101 set to the top of the line moved to. */
7103 void
7104 move_it_vertically_backward (it, dy)
7105 struct it *it;
7106 int dy;
7108 int nlines, h;
7109 struct it it2, it3;
7110 int start_pos;
7112 move_further_back:
7113 xassert (dy >= 0);
7115 start_pos = IT_CHARPOS (*it);
7117 /* Estimate how many newlines we must move back. */
7118 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
7120 /* Set the iterator's position that many lines back. */
7121 while (nlines-- && IT_CHARPOS (*it) > BEGV)
7122 back_to_previous_visible_line_start (it);
7124 /* Reseat the iterator here. When moving backward, we don't want
7125 reseat to skip forward over invisible text, set up the iterator
7126 to deliver from overlay strings at the new position etc. So,
7127 use reseat_1 here. */
7128 reseat_1 (it, it->current.pos, 1);
7130 /* We are now surely at a line start. */
7131 it->current_x = it->hpos = 0;
7132 it->continuation_lines_width = 0;
7134 /* Move forward and see what y-distance we moved. First move to the
7135 start of the next line so that we get its height. We need this
7136 height to be able to tell whether we reached the specified
7137 y-distance. */
7138 it2 = *it;
7139 it2.max_ascent = it2.max_descent = 0;
7142 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
7143 MOVE_TO_POS | MOVE_TO_VPOS);
7145 while (!IT_POS_VALID_AFTER_MOVE_P (&it2));
7146 xassert (IT_CHARPOS (*it) >= BEGV);
7147 it3 = it2;
7149 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
7150 xassert (IT_CHARPOS (*it) >= BEGV);
7151 /* H is the actual vertical distance from the position in *IT
7152 and the starting position. */
7153 h = it2.current_y - it->current_y;
7154 /* NLINES is the distance in number of lines. */
7155 nlines = it2.vpos - it->vpos;
7157 /* Correct IT's y and vpos position
7158 so that they are relative to the starting point. */
7159 it->vpos -= nlines;
7160 it->current_y -= h;
7162 if (dy == 0)
7164 /* DY == 0 means move to the start of the screen line. The
7165 value of nlines is > 0 if continuation lines were involved. */
7166 if (nlines > 0)
7167 move_it_by_lines (it, nlines, 1);
7168 #if 0
7169 /* I think this assert is bogus if buffer contains
7170 invisible text or images. KFS. */
7171 xassert (IT_CHARPOS (*it) <= start_pos);
7172 #endif
7174 else
7176 /* The y-position we try to reach, relative to *IT.
7177 Note that H has been subtracted in front of the if-statement. */
7178 int target_y = it->current_y + h - dy;
7179 int y0 = it3.current_y;
7180 int y1 = line_bottom_y (&it3);
7181 int line_height = y1 - y0;
7183 /* If we did not reach target_y, try to move further backward if
7184 we can. If we moved too far backward, try to move forward. */
7185 if (target_y < it->current_y
7186 /* This is heuristic. In a window that's 3 lines high, with
7187 a line height of 13 pixels each, recentering with point
7188 on the bottom line will try to move -39/2 = 19 pixels
7189 backward. Try to avoid moving into the first line. */
7190 && (it->current_y - target_y
7191 > min (window_box_height (it->w), line_height * 2 / 3))
7192 && IT_CHARPOS (*it) > BEGV)
7194 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
7195 target_y - it->current_y));
7196 dy = it->current_y - target_y;
7197 goto move_further_back;
7199 else if (target_y >= it->current_y + line_height
7200 && IT_CHARPOS (*it) < ZV)
7202 /* Should move forward by at least one line, maybe more.
7204 Note: Calling move_it_by_lines can be expensive on
7205 terminal frames, where compute_motion is used (via
7206 vmotion) to do the job, when there are very long lines
7207 and truncate-lines is nil. That's the reason for
7208 treating terminal frames specially here. */
7210 if (!FRAME_WINDOW_P (it->f))
7211 move_it_vertically (it, target_y - (it->current_y + line_height));
7212 else
7216 move_it_by_lines (it, 1, 1);
7218 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
7221 #if 0
7222 /* I think this assert is bogus if buffer contains
7223 invisible text or images. KFS. */
7224 xassert (IT_CHARPOS (*it) >= BEGV);
7225 #endif
7231 /* Move IT by a specified amount of pixel lines DY. DY negative means
7232 move backwards. DY = 0 means move to start of screen line. At the
7233 end, IT will be on the start of a screen line. */
7235 void
7236 move_it_vertically (it, dy)
7237 struct it *it;
7238 int dy;
7240 if (dy <= 0)
7241 move_it_vertically_backward (it, -dy);
7242 else
7244 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
7245 move_it_to (it, ZV, -1, it->current_y + dy, -1,
7246 MOVE_TO_POS | MOVE_TO_Y);
7247 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
7249 /* If buffer ends in ZV without a newline, move to the start of
7250 the line to satisfy the post-condition. */
7251 if (IT_CHARPOS (*it) == ZV
7252 && ZV > BEGV
7253 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
7254 move_it_by_lines (it, 0, 0);
7259 /* Move iterator IT past the end of the text line it is in. */
7261 void
7262 move_it_past_eol (it)
7263 struct it *it;
7265 enum move_it_result rc;
7267 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
7268 if (rc == MOVE_NEWLINE_OR_CR)
7269 set_iterator_to_next (it, 0);
7273 #if 0 /* Currently not used. */
7275 /* Return non-zero if some text between buffer positions START_CHARPOS
7276 and END_CHARPOS is invisible. IT->window is the window for text
7277 property lookup. */
7279 static int
7280 invisible_text_between_p (it, start_charpos, end_charpos)
7281 struct it *it;
7282 int start_charpos, end_charpos;
7284 Lisp_Object prop, limit;
7285 int invisible_found_p;
7287 xassert (it != NULL && start_charpos <= end_charpos);
7289 /* Is text at START invisible? */
7290 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
7291 it->window);
7292 if (TEXT_PROP_MEANS_INVISIBLE (prop))
7293 invisible_found_p = 1;
7294 else
7296 limit = Fnext_single_char_property_change (make_number (start_charpos),
7297 Qinvisible, Qnil,
7298 make_number (end_charpos));
7299 invisible_found_p = XFASTINT (limit) < end_charpos;
7302 return invisible_found_p;
7305 #endif /* 0 */
7308 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
7309 negative means move up. DVPOS == 0 means move to the start of the
7310 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
7311 NEED_Y_P is zero, IT->current_y will be left unchanged.
7313 Further optimization ideas: If we would know that IT->f doesn't use
7314 a face with proportional font, we could be faster for
7315 truncate-lines nil. */
7317 void
7318 move_it_by_lines (it, dvpos, need_y_p)
7319 struct it *it;
7320 int dvpos, need_y_p;
7322 struct position pos;
7324 /* The commented-out optimization uses vmotion on terminals. This
7325 gives bad results, because elements like it->what, on which
7326 callers such as pos_visible_p rely, aren't updated. */
7327 /* if (!FRAME_WINDOW_P (it->f))
7329 struct text_pos textpos;
7331 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
7332 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
7333 reseat (it, textpos, 1);
7334 it->vpos += pos.vpos;
7335 it->current_y += pos.vpos;
7337 else */
7339 if (dvpos == 0)
7341 /* DVPOS == 0 means move to the start of the screen line. */
7342 move_it_vertically_backward (it, 0);
7343 xassert (it->current_x == 0 && it->hpos == 0);
7344 /* Let next call to line_bottom_y calculate real line height */
7345 last_height = 0;
7347 else if (dvpos > 0)
7349 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
7350 if (!IT_POS_VALID_AFTER_MOVE_P (it))
7351 move_it_to (it, IT_CHARPOS (*it) + 1, -1, -1, -1, MOVE_TO_POS);
7353 else
7355 struct it it2;
7356 int start_charpos, i;
7358 /* Start at the beginning of the screen line containing IT's
7359 position. This may actually move vertically backwards,
7360 in case of overlays, so adjust dvpos accordingly. */
7361 dvpos += it->vpos;
7362 move_it_vertically_backward (it, 0);
7363 dvpos -= it->vpos;
7365 /* Go back -DVPOS visible lines and reseat the iterator there. */
7366 start_charpos = IT_CHARPOS (*it);
7367 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > BEGV; --i)
7368 back_to_previous_visible_line_start (it);
7369 reseat (it, it->current.pos, 1);
7371 /* Move further back if we end up in a string or an image. */
7372 while (!IT_POS_VALID_AFTER_MOVE_P (it))
7374 /* First try to move to start of display line. */
7375 dvpos += it->vpos;
7376 move_it_vertically_backward (it, 0);
7377 dvpos -= it->vpos;
7378 if (IT_POS_VALID_AFTER_MOVE_P (it))
7379 break;
7380 /* If start of line is still in string or image,
7381 move further back. */
7382 back_to_previous_visible_line_start (it);
7383 reseat (it, it->current.pos, 1);
7384 dvpos--;
7387 it->current_x = it->hpos = 0;
7389 /* Above call may have moved too far if continuation lines
7390 are involved. Scan forward and see if it did. */
7391 it2 = *it;
7392 it2.vpos = it2.current_y = 0;
7393 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
7394 it->vpos -= it2.vpos;
7395 it->current_y -= it2.current_y;
7396 it->current_x = it->hpos = 0;
7398 /* If we moved too far back, move IT some lines forward. */
7399 if (it2.vpos > -dvpos)
7401 int delta = it2.vpos + dvpos;
7402 it2 = *it;
7403 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
7404 /* Move back again if we got too far ahead. */
7405 if (IT_CHARPOS (*it) >= start_charpos)
7406 *it = it2;
7411 /* Return 1 if IT points into the middle of a display vector. */
7414 in_display_vector_p (it)
7415 struct it *it;
7417 return (it->method == GET_FROM_DISPLAY_VECTOR
7418 && it->current.dpvec_index > 0
7419 && it->dpvec + it->current.dpvec_index != it->dpend);
7423 /***********************************************************************
7424 Messages
7425 ***********************************************************************/
7428 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
7429 to *Messages*. */
7431 void
7432 add_to_log (format, arg1, arg2)
7433 char *format;
7434 Lisp_Object arg1, arg2;
7436 Lisp_Object args[3];
7437 Lisp_Object msg, fmt;
7438 char *buffer;
7439 int len;
7440 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
7441 USE_SAFE_ALLOCA;
7443 /* Do nothing if called asynchronously. Inserting text into
7444 a buffer may call after-change-functions and alike and
7445 that would means running Lisp asynchronously. */
7446 if (handling_signal)
7447 return;
7449 fmt = msg = Qnil;
7450 GCPRO4 (fmt, msg, arg1, arg2);
7452 args[0] = fmt = build_string (format);
7453 args[1] = arg1;
7454 args[2] = arg2;
7455 msg = Fformat (3, args);
7457 len = SBYTES (msg) + 1;
7458 SAFE_ALLOCA (buffer, char *, len);
7459 bcopy (SDATA (msg), buffer, len);
7461 message_dolog (buffer, len - 1, 1, 0);
7462 SAFE_FREE ();
7464 UNGCPRO;
7468 /* Output a newline in the *Messages* buffer if "needs" one. */
7470 void
7471 message_log_maybe_newline ()
7473 if (message_log_need_newline)
7474 message_dolog ("", 0, 1, 0);
7478 /* Add a string M of length NBYTES to the message log, optionally
7479 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
7480 nonzero, means interpret the contents of M as multibyte. This
7481 function calls low-level routines in order to bypass text property
7482 hooks, etc. which might not be safe to run.
7484 This may GC (insert may run before/after change hooks),
7485 so the buffer M must NOT point to a Lisp string. */
7487 void
7488 message_dolog (m, nbytes, nlflag, multibyte)
7489 const char *m;
7490 int nbytes, nlflag, multibyte;
7492 if (!NILP (Vmemory_full))
7493 return;
7495 if (!NILP (Vmessage_log_max))
7497 struct buffer *oldbuf;
7498 Lisp_Object oldpoint, oldbegv, oldzv;
7499 int old_windows_or_buffers_changed = windows_or_buffers_changed;
7500 int point_at_end = 0;
7501 int zv_at_end = 0;
7502 Lisp_Object old_deactivate_mark, tem;
7503 struct gcpro gcpro1;
7505 old_deactivate_mark = Vdeactivate_mark;
7506 oldbuf = current_buffer;
7507 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
7508 current_buffer->undo_list = Qt;
7510 oldpoint = message_dolog_marker1;
7511 set_marker_restricted (oldpoint, make_number (PT), Qnil);
7512 oldbegv = message_dolog_marker2;
7513 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
7514 oldzv = message_dolog_marker3;
7515 set_marker_restricted (oldzv, make_number (ZV), Qnil);
7516 GCPRO1 (old_deactivate_mark);
7518 if (PT == Z)
7519 point_at_end = 1;
7520 if (ZV == Z)
7521 zv_at_end = 1;
7523 BEGV = BEG;
7524 BEGV_BYTE = BEG_BYTE;
7525 ZV = Z;
7526 ZV_BYTE = Z_BYTE;
7527 TEMP_SET_PT_BOTH (Z, Z_BYTE);
7529 /* Insert the string--maybe converting multibyte to single byte
7530 or vice versa, so that all the text fits the buffer. */
7531 if (multibyte
7532 && NILP (current_buffer->enable_multibyte_characters))
7534 int i, c, char_bytes;
7535 unsigned char work[1];
7537 /* Convert a multibyte string to single-byte
7538 for the *Message* buffer. */
7539 for (i = 0; i < nbytes; i += char_bytes)
7541 c = string_char_and_length (m + i, nbytes - i, &char_bytes);
7542 work[0] = (ASCII_CHAR_P (c)
7544 : multibyte_char_to_unibyte (c, Qnil));
7545 insert_1_both (work, 1, 1, 1, 0, 0);
7548 else if (! multibyte
7549 && ! NILP (current_buffer->enable_multibyte_characters))
7551 int i, c, char_bytes;
7552 unsigned char *msg = (unsigned char *) m;
7553 unsigned char str[MAX_MULTIBYTE_LENGTH];
7554 /* Convert a single-byte string to multibyte
7555 for the *Message* buffer. */
7556 for (i = 0; i < nbytes; i++)
7558 c = msg[i];
7559 c = unibyte_char_to_multibyte (c);
7560 char_bytes = CHAR_STRING (c, str);
7561 insert_1_both (str, 1, char_bytes, 1, 0, 0);
7564 else if (nbytes)
7565 insert_1 (m, nbytes, 1, 0, 0);
7567 if (nlflag)
7569 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
7570 insert_1 ("\n", 1, 1, 0, 0);
7572 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
7573 this_bol = PT;
7574 this_bol_byte = PT_BYTE;
7576 /* See if this line duplicates the previous one.
7577 If so, combine duplicates. */
7578 if (this_bol > BEG)
7580 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
7581 prev_bol = PT;
7582 prev_bol_byte = PT_BYTE;
7584 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
7585 this_bol, this_bol_byte);
7586 if (dup)
7588 del_range_both (prev_bol, prev_bol_byte,
7589 this_bol, this_bol_byte, 0);
7590 if (dup > 1)
7592 char dupstr[40];
7593 int duplen;
7595 /* If you change this format, don't forget to also
7596 change message_log_check_duplicate. */
7597 sprintf (dupstr, " [%d times]", dup);
7598 duplen = strlen (dupstr);
7599 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
7600 insert_1 (dupstr, duplen, 1, 0, 1);
7605 /* If we have more than the desired maximum number of lines
7606 in the *Messages* buffer now, delete the oldest ones.
7607 This is safe because we don't have undo in this buffer. */
7609 if (NATNUMP (Vmessage_log_max))
7611 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
7612 -XFASTINT (Vmessage_log_max) - 1, 0);
7613 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
7616 BEGV = XMARKER (oldbegv)->charpos;
7617 BEGV_BYTE = marker_byte_position (oldbegv);
7619 if (zv_at_end)
7621 ZV = Z;
7622 ZV_BYTE = Z_BYTE;
7624 else
7626 ZV = XMARKER (oldzv)->charpos;
7627 ZV_BYTE = marker_byte_position (oldzv);
7630 if (point_at_end)
7631 TEMP_SET_PT_BOTH (Z, Z_BYTE);
7632 else
7633 /* We can't do Fgoto_char (oldpoint) because it will run some
7634 Lisp code. */
7635 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
7636 XMARKER (oldpoint)->bytepos);
7638 UNGCPRO;
7639 unchain_marker (XMARKER (oldpoint));
7640 unchain_marker (XMARKER (oldbegv));
7641 unchain_marker (XMARKER (oldzv));
7643 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
7644 set_buffer_internal (oldbuf);
7645 if (NILP (tem))
7646 windows_or_buffers_changed = old_windows_or_buffers_changed;
7647 message_log_need_newline = !nlflag;
7648 Vdeactivate_mark = old_deactivate_mark;
7653 /* We are at the end of the buffer after just having inserted a newline.
7654 (Note: We depend on the fact we won't be crossing the gap.)
7655 Check to see if the most recent message looks a lot like the previous one.
7656 Return 0 if different, 1 if the new one should just replace it, or a
7657 value N > 1 if we should also append " [N times]". */
7659 static int
7660 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
7661 int prev_bol, this_bol;
7662 int prev_bol_byte, this_bol_byte;
7664 int i;
7665 int len = Z_BYTE - 1 - this_bol_byte;
7666 int seen_dots = 0;
7667 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
7668 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
7670 for (i = 0; i < len; i++)
7672 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
7673 seen_dots = 1;
7674 if (p1[i] != p2[i])
7675 return seen_dots;
7677 p1 += len;
7678 if (*p1 == '\n')
7679 return 2;
7680 if (*p1++ == ' ' && *p1++ == '[')
7682 int n = 0;
7683 while (*p1 >= '0' && *p1 <= '9')
7684 n = n * 10 + *p1++ - '0';
7685 if (strncmp (p1, " times]\n", 8) == 0)
7686 return n+1;
7688 return 0;
7692 /* Display an echo area message M with a specified length of NBYTES
7693 bytes. The string may include null characters. If M is 0, clear
7694 out any existing message, and let the mini-buffer text show
7695 through.
7697 This may GC, so the buffer M must NOT point to a Lisp string. */
7699 void
7700 message2 (m, nbytes, multibyte)
7701 const char *m;
7702 int nbytes;
7703 int multibyte;
7705 /* First flush out any partial line written with print. */
7706 message_log_maybe_newline ();
7707 if (m)
7708 message_dolog (m, nbytes, 1, multibyte);
7709 message2_nolog (m, nbytes, multibyte);
7713 /* The non-logging counterpart of message2. */
7715 void
7716 message2_nolog (m, nbytes, multibyte)
7717 const char *m;
7718 int nbytes, multibyte;
7720 struct frame *sf = SELECTED_FRAME ();
7721 message_enable_multibyte = multibyte;
7723 if (noninteractive)
7725 if (noninteractive_need_newline)
7726 putc ('\n', stderr);
7727 noninteractive_need_newline = 0;
7728 if (m)
7729 fwrite (m, nbytes, 1, stderr);
7730 if (cursor_in_echo_area == 0)
7731 fprintf (stderr, "\n");
7732 fflush (stderr);
7734 /* A null message buffer means that the frame hasn't really been
7735 initialized yet. Error messages get reported properly by
7736 cmd_error, so this must be just an informative message; toss it. */
7737 else if (INTERACTIVE
7738 && sf->glyphs_initialized_p
7739 && FRAME_MESSAGE_BUF (sf))
7741 Lisp_Object mini_window;
7742 struct frame *f;
7744 /* Get the frame containing the mini-buffer
7745 that the selected frame is using. */
7746 mini_window = FRAME_MINIBUF_WINDOW (sf);
7747 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
7749 FRAME_SAMPLE_VISIBILITY (f);
7750 if (FRAME_VISIBLE_P (sf)
7751 && ! FRAME_VISIBLE_P (f))
7752 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
7754 if (m)
7756 set_message (m, Qnil, nbytes, multibyte);
7757 if (minibuffer_auto_raise)
7758 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
7760 else
7761 clear_message (1, 1);
7763 do_pending_window_change (0);
7764 echo_area_display (1);
7765 do_pending_window_change (0);
7766 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
7767 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
7772 /* Display an echo area message M with a specified length of NBYTES
7773 bytes. The string may include null characters. If M is not a
7774 string, clear out any existing message, and let the mini-buffer
7775 text show through.
7777 This function cancels echoing. */
7779 void
7780 message3 (m, nbytes, multibyte)
7781 Lisp_Object m;
7782 int nbytes;
7783 int multibyte;
7785 struct gcpro gcpro1;
7787 GCPRO1 (m);
7788 clear_message (1,1);
7789 cancel_echoing ();
7791 /* First flush out any partial line written with print. */
7792 message_log_maybe_newline ();
7793 if (STRINGP (m))
7795 char *buffer;
7796 USE_SAFE_ALLOCA;
7798 SAFE_ALLOCA (buffer, char *, nbytes);
7799 bcopy (SDATA (m), buffer, nbytes);
7800 message_dolog (buffer, nbytes, 1, multibyte);
7801 SAFE_FREE ();
7803 message3_nolog (m, nbytes, multibyte);
7805 UNGCPRO;
7809 /* The non-logging version of message3.
7810 This does not cancel echoing, because it is used for echoing.
7811 Perhaps we need to make a separate function for echoing
7812 and make this cancel echoing. */
7814 void
7815 message3_nolog (m, nbytes, multibyte)
7816 Lisp_Object m;
7817 int nbytes, multibyte;
7819 struct frame *sf = SELECTED_FRAME ();
7820 message_enable_multibyte = multibyte;
7822 if (noninteractive)
7824 if (noninteractive_need_newline)
7825 putc ('\n', stderr);
7826 noninteractive_need_newline = 0;
7827 if (STRINGP (m))
7828 fwrite (SDATA (m), nbytes, 1, stderr);
7829 if (cursor_in_echo_area == 0)
7830 fprintf (stderr, "\n");
7831 fflush (stderr);
7833 /* A null message buffer means that the frame hasn't really been
7834 initialized yet. Error messages get reported properly by
7835 cmd_error, so this must be just an informative message; toss it. */
7836 else if (INTERACTIVE
7837 && sf->glyphs_initialized_p
7838 && FRAME_MESSAGE_BUF (sf))
7840 Lisp_Object mini_window;
7841 Lisp_Object frame;
7842 struct frame *f;
7844 /* Get the frame containing the mini-buffer
7845 that the selected frame is using. */
7846 mini_window = FRAME_MINIBUF_WINDOW (sf);
7847 frame = XWINDOW (mini_window)->frame;
7848 f = XFRAME (frame);
7850 FRAME_SAMPLE_VISIBILITY (f);
7851 if (FRAME_VISIBLE_P (sf)
7852 && !FRAME_VISIBLE_P (f))
7853 Fmake_frame_visible (frame);
7855 if (STRINGP (m) && SCHARS (m) > 0)
7857 set_message (NULL, m, nbytes, multibyte);
7858 if (minibuffer_auto_raise)
7859 Fraise_frame (frame);
7860 /* Assume we are not echoing.
7861 (If we are, echo_now will override this.) */
7862 echo_message_buffer = Qnil;
7864 else
7865 clear_message (1, 1);
7867 do_pending_window_change (0);
7868 echo_area_display (1);
7869 do_pending_window_change (0);
7870 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
7871 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
7876 /* Display a null-terminated echo area message M. If M is 0, clear
7877 out any existing message, and let the mini-buffer text show through.
7879 The buffer M must continue to exist until after the echo area gets
7880 cleared or some other message gets displayed there. Do not pass
7881 text that is stored in a Lisp string. Do not pass text in a buffer
7882 that was alloca'd. */
7884 void
7885 message1 (m)
7886 char *m;
7888 message2 (m, (m ? strlen (m) : 0), 0);
7892 /* The non-logging counterpart of message1. */
7894 void
7895 message1_nolog (m)
7896 char *m;
7898 message2_nolog (m, (m ? strlen (m) : 0), 0);
7901 /* Display a message M which contains a single %s
7902 which gets replaced with STRING. */
7904 void
7905 message_with_string (m, string, log)
7906 char *m;
7907 Lisp_Object string;
7908 int log;
7910 CHECK_STRING (string);
7912 if (noninteractive)
7914 if (m)
7916 if (noninteractive_need_newline)
7917 putc ('\n', stderr);
7918 noninteractive_need_newline = 0;
7919 fprintf (stderr, m, SDATA (string));
7920 if (cursor_in_echo_area == 0)
7921 fprintf (stderr, "\n");
7922 fflush (stderr);
7925 else if (INTERACTIVE)
7927 /* The frame whose minibuffer we're going to display the message on.
7928 It may be larger than the selected frame, so we need
7929 to use its buffer, not the selected frame's buffer. */
7930 Lisp_Object mini_window;
7931 struct frame *f, *sf = SELECTED_FRAME ();
7933 /* Get the frame containing the minibuffer
7934 that the selected frame is using. */
7935 mini_window = FRAME_MINIBUF_WINDOW (sf);
7936 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
7938 /* A null message buffer means that the frame hasn't really been
7939 initialized yet. Error messages get reported properly by
7940 cmd_error, so this must be just an informative message; toss it. */
7941 if (FRAME_MESSAGE_BUF (f))
7943 Lisp_Object args[2], message;
7944 struct gcpro gcpro1, gcpro2;
7946 args[0] = build_string (m);
7947 args[1] = message = string;
7948 GCPRO2 (args[0], message);
7949 gcpro1.nvars = 2;
7951 message = Fformat (2, args);
7953 if (log)
7954 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
7955 else
7956 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
7958 UNGCPRO;
7960 /* Print should start at the beginning of the message
7961 buffer next time. */
7962 message_buf_print = 0;
7968 /* Dump an informative message to the minibuf. If M is 0, clear out
7969 any existing message, and let the mini-buffer text show through. */
7971 /* VARARGS 1 */
7972 void
7973 message (m, a1, a2, a3)
7974 char *m;
7975 EMACS_INT a1, a2, a3;
7977 if (noninteractive)
7979 if (m)
7981 if (noninteractive_need_newline)
7982 putc ('\n', stderr);
7983 noninteractive_need_newline = 0;
7984 fprintf (stderr, m, a1, a2, a3);
7985 if (cursor_in_echo_area == 0)
7986 fprintf (stderr, "\n");
7987 fflush (stderr);
7990 else if (INTERACTIVE)
7992 /* The frame whose mini-buffer we're going to display the message
7993 on. It may be larger than the selected frame, so we need to
7994 use its buffer, not the selected frame's buffer. */
7995 Lisp_Object mini_window;
7996 struct frame *f, *sf = SELECTED_FRAME ();
7998 /* Get the frame containing the mini-buffer
7999 that the selected frame is using. */
8000 mini_window = FRAME_MINIBUF_WINDOW (sf);
8001 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
8003 /* A null message buffer means that the frame hasn't really been
8004 initialized yet. Error messages get reported properly by
8005 cmd_error, so this must be just an informative message; toss
8006 it. */
8007 if (FRAME_MESSAGE_BUF (f))
8009 if (m)
8011 int len;
8012 #ifdef NO_ARG_ARRAY
8013 char *a[3];
8014 a[0] = (char *) a1;
8015 a[1] = (char *) a2;
8016 a[2] = (char *) a3;
8018 len = doprnt (FRAME_MESSAGE_BUF (f),
8019 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
8020 #else
8021 len = doprnt (FRAME_MESSAGE_BUF (f),
8022 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
8023 (char **) &a1);
8024 #endif /* NO_ARG_ARRAY */
8026 message2 (FRAME_MESSAGE_BUF (f), len, 0);
8028 else
8029 message1 (0);
8031 /* Print should start at the beginning of the message
8032 buffer next time. */
8033 message_buf_print = 0;
8039 /* The non-logging version of message. */
8041 void
8042 message_nolog (m, a1, a2, a3)
8043 char *m;
8044 EMACS_INT a1, a2, a3;
8046 Lisp_Object old_log_max;
8047 old_log_max = Vmessage_log_max;
8048 Vmessage_log_max = Qnil;
8049 message (m, a1, a2, a3);
8050 Vmessage_log_max = old_log_max;
8054 /* Display the current message in the current mini-buffer. This is
8055 only called from error handlers in process.c, and is not time
8056 critical. */
8058 void
8059 update_echo_area ()
8061 if (!NILP (echo_area_buffer[0]))
8063 Lisp_Object string;
8064 string = Fcurrent_message ();
8065 message3 (string, SBYTES (string),
8066 !NILP (current_buffer->enable_multibyte_characters));
8071 /* Make sure echo area buffers in `echo_buffers' are live.
8072 If they aren't, make new ones. */
8074 static void
8075 ensure_echo_area_buffers ()
8077 int i;
8079 for (i = 0; i < 2; ++i)
8080 if (!BUFFERP (echo_buffer[i])
8081 || NILP (XBUFFER (echo_buffer[i])->name))
8083 char name[30];
8084 Lisp_Object old_buffer;
8085 int j;
8087 old_buffer = echo_buffer[i];
8088 sprintf (name, " *Echo Area %d*", i);
8089 echo_buffer[i] = Fget_buffer_create (build_string (name));
8090 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
8092 for (j = 0; j < 2; ++j)
8093 if (EQ (old_buffer, echo_area_buffer[j]))
8094 echo_area_buffer[j] = echo_buffer[i];
8099 /* Call FN with args A1..A4 with either the current or last displayed
8100 echo_area_buffer as current buffer.
8102 WHICH zero means use the current message buffer
8103 echo_area_buffer[0]. If that is nil, choose a suitable buffer
8104 from echo_buffer[] and clear it.
8106 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
8107 suitable buffer from echo_buffer[] and clear it.
8109 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
8110 that the current message becomes the last displayed one, make
8111 choose a suitable buffer for echo_area_buffer[0], and clear it.
8113 Value is what FN returns. */
8115 static int
8116 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
8117 struct window *w;
8118 int which;
8119 int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
8120 EMACS_INT a1;
8121 Lisp_Object a2;
8122 EMACS_INT a3, a4;
8124 Lisp_Object buffer;
8125 int this_one, the_other, clear_buffer_p, rc;
8126 int count = SPECPDL_INDEX ();
8128 /* If buffers aren't live, make new ones. */
8129 ensure_echo_area_buffers ();
8131 clear_buffer_p = 0;
8133 if (which == 0)
8134 this_one = 0, the_other = 1;
8135 else if (which > 0)
8136 this_one = 1, the_other = 0;
8137 else
8139 this_one = 0, the_other = 1;
8140 clear_buffer_p = 1;
8142 /* We need a fresh one in case the current echo buffer equals
8143 the one containing the last displayed echo area message. */
8144 if (!NILP (echo_area_buffer[this_one])
8145 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
8146 echo_area_buffer[this_one] = Qnil;
8149 /* Choose a suitable buffer from echo_buffer[] is we don't
8150 have one. */
8151 if (NILP (echo_area_buffer[this_one]))
8153 echo_area_buffer[this_one]
8154 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
8155 ? echo_buffer[the_other]
8156 : echo_buffer[this_one]);
8157 clear_buffer_p = 1;
8160 buffer = echo_area_buffer[this_one];
8162 /* Don't get confused by reusing the buffer used for echoing
8163 for a different purpose. */
8164 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
8165 cancel_echoing ();
8167 record_unwind_protect (unwind_with_echo_area_buffer,
8168 with_echo_area_buffer_unwind_data (w));
8170 /* Make the echo area buffer current. Note that for display
8171 purposes, it is not necessary that the displayed window's buffer
8172 == current_buffer, except for text property lookup. So, let's
8173 only set that buffer temporarily here without doing a full
8174 Fset_window_buffer. We must also change w->pointm, though,
8175 because otherwise an assertions in unshow_buffer fails, and Emacs
8176 aborts. */
8177 set_buffer_internal_1 (XBUFFER (buffer));
8178 if (w)
8180 w->buffer = buffer;
8181 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
8184 current_buffer->undo_list = Qt;
8185 current_buffer->read_only = Qnil;
8186 specbind (Qinhibit_read_only, Qt);
8187 specbind (Qinhibit_modification_hooks, Qt);
8189 if (clear_buffer_p && Z > BEG)
8190 del_range (BEG, Z);
8192 xassert (BEGV >= BEG);
8193 xassert (ZV <= Z && ZV >= BEGV);
8195 rc = fn (a1, a2, a3, a4);
8197 xassert (BEGV >= BEG);
8198 xassert (ZV <= Z && ZV >= BEGV);
8200 unbind_to (count, Qnil);
8201 return rc;
8205 /* Save state that should be preserved around the call to the function
8206 FN called in with_echo_area_buffer. */
8208 static Lisp_Object
8209 with_echo_area_buffer_unwind_data (w)
8210 struct window *w;
8212 int i = 0;
8213 Lisp_Object vector, tmp;
8215 /* Reduce consing by keeping one vector in
8216 Vwith_echo_area_save_vector. */
8217 vector = Vwith_echo_area_save_vector;
8218 Vwith_echo_area_save_vector = Qnil;
8220 if (NILP (vector))
8221 vector = Fmake_vector (make_number (7), Qnil);
8223 XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
8224 ASET (vector, i, Vdeactivate_mark); ++i;
8225 ASET (vector, i, make_number (windows_or_buffers_changed)); ++i;
8227 if (w)
8229 XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i;
8230 ASET (vector, i, w->buffer); ++i;
8231 ASET (vector, i, make_number (XMARKER (w->pointm)->charpos)); ++i;
8232 ASET (vector, i, make_number (XMARKER (w->pointm)->bytepos)); ++i;
8234 else
8236 int end = i + 4;
8237 for (; i < end; ++i)
8238 ASET (vector, i, Qnil);
8241 xassert (i == ASIZE (vector));
8242 return vector;
8246 /* Restore global state from VECTOR which was created by
8247 with_echo_area_buffer_unwind_data. */
8249 static Lisp_Object
8250 unwind_with_echo_area_buffer (vector)
8251 Lisp_Object vector;
8253 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
8254 Vdeactivate_mark = AREF (vector, 1);
8255 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
8257 if (WINDOWP (AREF (vector, 3)))
8259 struct window *w;
8260 Lisp_Object buffer, charpos, bytepos;
8262 w = XWINDOW (AREF (vector, 3));
8263 buffer = AREF (vector, 4);
8264 charpos = AREF (vector, 5);
8265 bytepos = AREF (vector, 6);
8267 w->buffer = buffer;
8268 set_marker_both (w->pointm, buffer,
8269 XFASTINT (charpos), XFASTINT (bytepos));
8272 Vwith_echo_area_save_vector = vector;
8273 return Qnil;
8277 /* Set up the echo area for use by print functions. MULTIBYTE_P
8278 non-zero means we will print multibyte. */
8280 void
8281 setup_echo_area_for_printing (multibyte_p)
8282 int multibyte_p;
8284 /* If we can't find an echo area any more, exit. */
8285 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
8286 Fkill_emacs (Qnil);
8288 ensure_echo_area_buffers ();
8290 if (!message_buf_print)
8292 /* A message has been output since the last time we printed.
8293 Choose a fresh echo area buffer. */
8294 if (EQ (echo_area_buffer[1], echo_buffer[0]))
8295 echo_area_buffer[0] = echo_buffer[1];
8296 else
8297 echo_area_buffer[0] = echo_buffer[0];
8299 /* Switch to that buffer and clear it. */
8300 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
8301 current_buffer->truncate_lines = Qnil;
8303 if (Z > BEG)
8305 int count = SPECPDL_INDEX ();
8306 specbind (Qinhibit_read_only, Qt);
8307 /* Note that undo recording is always disabled. */
8308 del_range (BEG, Z);
8309 unbind_to (count, Qnil);
8311 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
8313 /* Set up the buffer for the multibyteness we need. */
8314 if (multibyte_p
8315 != !NILP (current_buffer->enable_multibyte_characters))
8316 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
8318 /* Raise the frame containing the echo area. */
8319 if (minibuffer_auto_raise)
8321 struct frame *sf = SELECTED_FRAME ();
8322 Lisp_Object mini_window;
8323 mini_window = FRAME_MINIBUF_WINDOW (sf);
8324 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
8327 message_log_maybe_newline ();
8328 message_buf_print = 1;
8330 else
8332 if (NILP (echo_area_buffer[0]))
8334 if (EQ (echo_area_buffer[1], echo_buffer[0]))
8335 echo_area_buffer[0] = echo_buffer[1];
8336 else
8337 echo_area_buffer[0] = echo_buffer[0];
8340 if (current_buffer != XBUFFER (echo_area_buffer[0]))
8342 /* Someone switched buffers between print requests. */
8343 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
8344 current_buffer->truncate_lines = Qnil;
8350 /* Display an echo area message in window W. Value is non-zero if W's
8351 height is changed. If display_last_displayed_message_p is
8352 non-zero, display the message that was last displayed, otherwise
8353 display the current message. */
8355 static int
8356 display_echo_area (w)
8357 struct window *w;
8359 int i, no_message_p, window_height_changed_p, count;
8361 /* Temporarily disable garbage collections while displaying the echo
8362 area. This is done because a GC can print a message itself.
8363 That message would modify the echo area buffer's contents while a
8364 redisplay of the buffer is going on, and seriously confuse
8365 redisplay. */
8366 count = inhibit_garbage_collection ();
8368 /* If there is no message, we must call display_echo_area_1
8369 nevertheless because it resizes the window. But we will have to
8370 reset the echo_area_buffer in question to nil at the end because
8371 with_echo_area_buffer will sets it to an empty buffer. */
8372 i = display_last_displayed_message_p ? 1 : 0;
8373 no_message_p = NILP (echo_area_buffer[i]);
8375 window_height_changed_p
8376 = with_echo_area_buffer (w, display_last_displayed_message_p,
8377 display_echo_area_1,
8378 (EMACS_INT) w, Qnil, 0, 0);
8380 if (no_message_p)
8381 echo_area_buffer[i] = Qnil;
8383 unbind_to (count, Qnil);
8384 return window_height_changed_p;
8388 /* Helper for display_echo_area. Display the current buffer which
8389 contains the current echo area message in window W, a mini-window,
8390 a pointer to which is passed in A1. A2..A4 are currently not used.
8391 Change the height of W so that all of the message is displayed.
8392 Value is non-zero if height of W was changed. */
8394 static int
8395 display_echo_area_1 (a1, a2, a3, a4)
8396 EMACS_INT a1;
8397 Lisp_Object a2;
8398 EMACS_INT a3, a4;
8400 struct window *w = (struct window *) a1;
8401 Lisp_Object window;
8402 struct text_pos start;
8403 int window_height_changed_p = 0;
8405 /* Do this before displaying, so that we have a large enough glyph
8406 matrix for the display. If we can't get enough space for the
8407 whole text, display the last N lines. That works by setting w->start. */
8408 window_height_changed_p = resize_mini_window (w, 0);
8410 /* Use the starting position chosen by resize_mini_window. */
8411 SET_TEXT_POS_FROM_MARKER (start, w->start);
8413 /* Display. */
8414 clear_glyph_matrix (w->desired_matrix);
8415 XSETWINDOW (window, w);
8416 try_window (window, start, 0);
8418 return window_height_changed_p;
8422 /* Resize the echo area window to exactly the size needed for the
8423 currently displayed message, if there is one. If a mini-buffer
8424 is active, don't shrink it. */
8426 void
8427 resize_echo_area_exactly ()
8429 if (BUFFERP (echo_area_buffer[0])
8430 && WINDOWP (echo_area_window))
8432 struct window *w = XWINDOW (echo_area_window);
8433 int resized_p;
8434 Lisp_Object resize_exactly;
8436 if (minibuf_level == 0)
8437 resize_exactly = Qt;
8438 else
8439 resize_exactly = Qnil;
8441 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
8442 (EMACS_INT) w, resize_exactly, 0, 0);
8443 if (resized_p)
8445 ++windows_or_buffers_changed;
8446 ++update_mode_lines;
8447 redisplay_internal (0);
8453 /* Callback function for with_echo_area_buffer, when used from
8454 resize_echo_area_exactly. A1 contains a pointer to the window to
8455 resize, EXACTLY non-nil means resize the mini-window exactly to the
8456 size of the text displayed. A3 and A4 are not used. Value is what
8457 resize_mini_window returns. */
8459 static int
8460 resize_mini_window_1 (a1, exactly, a3, a4)
8461 EMACS_INT a1;
8462 Lisp_Object exactly;
8463 EMACS_INT a3, a4;
8465 return resize_mini_window ((struct window *) a1, !NILP (exactly));
8469 /* Resize mini-window W to fit the size of its contents. EXACT_P
8470 means size the window exactly to the size needed. Otherwise, it's
8471 only enlarged until W's buffer is empty.
8473 Set W->start to the right place to begin display. If the whole
8474 contents fit, start at the beginning. Otherwise, start so as
8475 to make the end of the contents appear. This is particularly
8476 important for y-or-n-p, but seems desirable generally.
8478 Value is non-zero if the window height has been changed. */
8481 resize_mini_window (w, exact_p)
8482 struct window *w;
8483 int exact_p;
8485 struct frame *f = XFRAME (w->frame);
8486 int window_height_changed_p = 0;
8488 xassert (MINI_WINDOW_P (w));
8490 /* By default, start display at the beginning. */
8491 set_marker_both (w->start, w->buffer,
8492 BUF_BEGV (XBUFFER (w->buffer)),
8493 BUF_BEGV_BYTE (XBUFFER (w->buffer)));
8495 /* Don't resize windows while redisplaying a window; it would
8496 confuse redisplay functions when the size of the window they are
8497 displaying changes from under them. Such a resizing can happen,
8498 for instance, when which-func prints a long message while
8499 we are running fontification-functions. We're running these
8500 functions with safe_call which binds inhibit-redisplay to t. */
8501 if (!NILP (Vinhibit_redisplay))
8502 return 0;
8504 /* Nil means don't try to resize. */
8505 if (NILP (Vresize_mini_windows)
8506 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
8507 return 0;
8509 if (!FRAME_MINIBUF_ONLY_P (f))
8511 struct it it;
8512 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
8513 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
8514 int height, max_height;
8515 int unit = FRAME_LINE_HEIGHT (f);
8516 struct text_pos start;
8517 struct buffer *old_current_buffer = NULL;
8519 if (current_buffer != XBUFFER (w->buffer))
8521 old_current_buffer = current_buffer;
8522 set_buffer_internal (XBUFFER (w->buffer));
8525 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
8527 /* Compute the max. number of lines specified by the user. */
8528 if (FLOATP (Vmax_mini_window_height))
8529 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
8530 else if (INTEGERP (Vmax_mini_window_height))
8531 max_height = XINT (Vmax_mini_window_height);
8532 else
8533 max_height = total_height / 4;
8535 /* Correct that max. height if it's bogus. */
8536 max_height = max (1, max_height);
8537 max_height = min (total_height, max_height);
8539 /* Find out the height of the text in the window. */
8540 if (it.truncate_lines_p)
8541 height = 1;
8542 else
8544 last_height = 0;
8545 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
8546 if (it.max_ascent == 0 && it.max_descent == 0)
8547 height = it.current_y + last_height;
8548 else
8549 height = it.current_y + it.max_ascent + it.max_descent;
8550 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
8551 height = (height + unit - 1) / unit;
8554 /* Compute a suitable window start. */
8555 if (height > max_height)
8557 height = max_height;
8558 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
8559 move_it_vertically_backward (&it, (height - 1) * unit);
8560 start = it.current.pos;
8562 else
8563 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
8564 SET_MARKER_FROM_TEXT_POS (w->start, start);
8566 if (EQ (Vresize_mini_windows, Qgrow_only))
8568 /* Let it grow only, until we display an empty message, in which
8569 case the window shrinks again. */
8570 if (height > WINDOW_TOTAL_LINES (w))
8572 int old_height = WINDOW_TOTAL_LINES (w);
8573 freeze_window_starts (f, 1);
8574 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
8575 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8577 else if (height < WINDOW_TOTAL_LINES (w)
8578 && (exact_p || BEGV == ZV))
8580 int old_height = WINDOW_TOTAL_LINES (w);
8581 freeze_window_starts (f, 0);
8582 shrink_mini_window (w);
8583 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8586 else
8588 /* Always resize to exact size needed. */
8589 if (height > WINDOW_TOTAL_LINES (w))
8591 int old_height = WINDOW_TOTAL_LINES (w);
8592 freeze_window_starts (f, 1);
8593 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
8594 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8596 else if (height < WINDOW_TOTAL_LINES (w))
8598 int old_height = WINDOW_TOTAL_LINES (w);
8599 freeze_window_starts (f, 0);
8600 shrink_mini_window (w);
8602 if (height)
8604 freeze_window_starts (f, 1);
8605 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
8608 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8612 if (old_current_buffer)
8613 set_buffer_internal (old_current_buffer);
8616 return window_height_changed_p;
8620 /* Value is the current message, a string, or nil if there is no
8621 current message. */
8623 Lisp_Object
8624 current_message ()
8626 Lisp_Object msg;
8628 if (!BUFFERP (echo_area_buffer[0]))
8629 msg = Qnil;
8630 else
8632 with_echo_area_buffer (0, 0, current_message_1,
8633 (EMACS_INT) &msg, Qnil, 0, 0);
8634 if (NILP (msg))
8635 echo_area_buffer[0] = Qnil;
8638 return msg;
8642 static int
8643 current_message_1 (a1, a2, a3, a4)
8644 EMACS_INT a1;
8645 Lisp_Object a2;
8646 EMACS_INT a3, a4;
8648 Lisp_Object *msg = (Lisp_Object *) a1;
8650 if (Z > BEG)
8651 *msg = make_buffer_string (BEG, Z, 1);
8652 else
8653 *msg = Qnil;
8654 return 0;
8658 /* Push the current message on Vmessage_stack for later restauration
8659 by restore_message. Value is non-zero if the current message isn't
8660 empty. This is a relatively infrequent operation, so it's not
8661 worth optimizing. */
8664 push_message ()
8666 Lisp_Object msg;
8667 msg = current_message ();
8668 Vmessage_stack = Fcons (msg, Vmessage_stack);
8669 return STRINGP (msg);
8673 /* Restore message display from the top of Vmessage_stack. */
8675 void
8676 restore_message ()
8678 Lisp_Object msg;
8680 xassert (CONSP (Vmessage_stack));
8681 msg = XCAR (Vmessage_stack);
8682 if (STRINGP (msg))
8683 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
8684 else
8685 message3_nolog (msg, 0, 0);
8689 /* Handler for record_unwind_protect calling pop_message. */
8691 Lisp_Object
8692 pop_message_unwind (dummy)
8693 Lisp_Object dummy;
8695 pop_message ();
8696 return Qnil;
8699 /* Pop the top-most entry off Vmessage_stack. */
8701 void
8702 pop_message ()
8704 xassert (CONSP (Vmessage_stack));
8705 Vmessage_stack = XCDR (Vmessage_stack);
8709 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
8710 exits. If the stack is not empty, we have a missing pop_message
8711 somewhere. */
8713 void
8714 check_message_stack ()
8716 if (!NILP (Vmessage_stack))
8717 abort ();
8721 /* Truncate to NCHARS what will be displayed in the echo area the next
8722 time we display it---but don't redisplay it now. */
8724 void
8725 truncate_echo_area (nchars)
8726 int nchars;
8728 if (nchars == 0)
8729 echo_area_buffer[0] = Qnil;
8730 /* A null message buffer means that the frame hasn't really been
8731 initialized yet. Error messages get reported properly by
8732 cmd_error, so this must be just an informative message; toss it. */
8733 else if (!noninteractive
8734 && INTERACTIVE
8735 && !NILP (echo_area_buffer[0]))
8737 struct frame *sf = SELECTED_FRAME ();
8738 if (FRAME_MESSAGE_BUF (sf))
8739 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
8744 /* Helper function for truncate_echo_area. Truncate the current
8745 message to at most NCHARS characters. */
8747 static int
8748 truncate_message_1 (nchars, a2, a3, a4)
8749 EMACS_INT nchars;
8750 Lisp_Object a2;
8751 EMACS_INT a3, a4;
8753 if (BEG + nchars < Z)
8754 del_range (BEG + nchars, Z);
8755 if (Z == BEG)
8756 echo_area_buffer[0] = Qnil;
8757 return 0;
8761 /* Set the current message to a substring of S or STRING.
8763 If STRING is a Lisp string, set the message to the first NBYTES
8764 bytes from STRING. NBYTES zero means use the whole string. If
8765 STRING is multibyte, the message will be displayed multibyte.
8767 If S is not null, set the message to the first LEN bytes of S. LEN
8768 zero means use the whole string. MULTIBYTE_P non-zero means S is
8769 multibyte. Display the message multibyte in that case.
8771 Doesn't GC, as with_echo_area_buffer binds Qinhibit_modification_hooks
8772 to t before calling set_message_1 (which calls insert).
8775 void
8776 set_message (s, string, nbytes, multibyte_p)
8777 const char *s;
8778 Lisp_Object string;
8779 int nbytes, multibyte_p;
8781 message_enable_multibyte
8782 = ((s && multibyte_p)
8783 || (STRINGP (string) && STRING_MULTIBYTE (string)));
8785 with_echo_area_buffer (0, -1, set_message_1,
8786 (EMACS_INT) s, string, nbytes, multibyte_p);
8787 message_buf_print = 0;
8788 help_echo_showing_p = 0;
8792 /* Helper function for set_message. Arguments have the same meaning
8793 as there, with A1 corresponding to S and A2 corresponding to STRING
8794 This function is called with the echo area buffer being
8795 current. */
8797 static int
8798 set_message_1 (a1, a2, nbytes, multibyte_p)
8799 EMACS_INT a1;
8800 Lisp_Object a2;
8801 EMACS_INT nbytes, multibyte_p;
8803 const char *s = (const char *) a1;
8804 Lisp_Object string = a2;
8806 /* Change multibyteness of the echo buffer appropriately. */
8807 if (message_enable_multibyte
8808 != !NILP (current_buffer->enable_multibyte_characters))
8809 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
8811 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
8813 /* Insert new message at BEG. */
8814 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
8816 if (STRINGP (string))
8818 int nchars;
8820 if (nbytes == 0)
8821 nbytes = SBYTES (string);
8822 nchars = string_byte_to_char (string, nbytes);
8824 /* This function takes care of single/multibyte conversion. We
8825 just have to ensure that the echo area buffer has the right
8826 setting of enable_multibyte_characters. */
8827 insert_from_string (string, 0, 0, nchars, nbytes, 1);
8829 else if (s)
8831 if (nbytes == 0)
8832 nbytes = strlen (s);
8834 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
8836 /* Convert from multi-byte to single-byte. */
8837 int i, c, n;
8838 unsigned char work[1];
8840 /* Convert a multibyte string to single-byte. */
8841 for (i = 0; i < nbytes; i += n)
8843 c = string_char_and_length (s + i, nbytes - i, &n);
8844 work[0] = (ASCII_CHAR_P (c)
8846 : multibyte_char_to_unibyte (c, Qnil));
8847 insert_1_both (work, 1, 1, 1, 0, 0);
8850 else if (!multibyte_p
8851 && !NILP (current_buffer->enable_multibyte_characters))
8853 /* Convert from single-byte to multi-byte. */
8854 int i, c, n;
8855 const unsigned char *msg = (const unsigned char *) s;
8856 unsigned char str[MAX_MULTIBYTE_LENGTH];
8858 /* Convert a single-byte string to multibyte. */
8859 for (i = 0; i < nbytes; i++)
8861 c = msg[i];
8862 c = unibyte_char_to_multibyte (c);
8863 n = CHAR_STRING (c, str);
8864 insert_1_both (str, 1, n, 1, 0, 0);
8867 else
8868 insert_1 (s, nbytes, 1, 0, 0);
8871 return 0;
8875 /* Clear messages. CURRENT_P non-zero means clear the current
8876 message. LAST_DISPLAYED_P non-zero means clear the message
8877 last displayed. */
8879 void
8880 clear_message (current_p, last_displayed_p)
8881 int current_p, last_displayed_p;
8883 if (current_p)
8885 echo_area_buffer[0] = Qnil;
8886 message_cleared_p = 1;
8889 if (last_displayed_p)
8890 echo_area_buffer[1] = Qnil;
8892 message_buf_print = 0;
8895 /* Clear garbaged frames.
8897 This function is used where the old redisplay called
8898 redraw_garbaged_frames which in turn called redraw_frame which in
8899 turn called clear_frame. The call to clear_frame was a source of
8900 flickering. I believe a clear_frame is not necessary. It should
8901 suffice in the new redisplay to invalidate all current matrices,
8902 and ensure a complete redisplay of all windows. */
8904 static void
8905 clear_garbaged_frames ()
8907 if (frame_garbaged)
8909 Lisp_Object tail, frame;
8910 int changed_count = 0;
8912 FOR_EACH_FRAME (tail, frame)
8914 struct frame *f = XFRAME (frame);
8916 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
8918 if (f->resized_p)
8920 Fredraw_frame (frame);
8921 f->force_flush_display_p = 1;
8923 clear_current_matrices (f);
8924 changed_count++;
8925 f->garbaged = 0;
8926 f->resized_p = 0;
8930 frame_garbaged = 0;
8931 if (changed_count)
8932 ++windows_or_buffers_changed;
8937 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
8938 is non-zero update selected_frame. Value is non-zero if the
8939 mini-windows height has been changed. */
8941 static int
8942 echo_area_display (update_frame_p)
8943 int update_frame_p;
8945 Lisp_Object mini_window;
8946 struct window *w;
8947 struct frame *f;
8948 int window_height_changed_p = 0;
8949 struct frame *sf = SELECTED_FRAME ();
8951 mini_window = FRAME_MINIBUF_WINDOW (sf);
8952 w = XWINDOW (mini_window);
8953 f = XFRAME (WINDOW_FRAME (w));
8955 /* Don't display if frame is invisible or not yet initialized. */
8956 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
8957 return 0;
8959 #ifdef HAVE_WINDOW_SYSTEM
8960 /* When Emacs starts, selected_frame may be the initial terminal
8961 frame. If we let this through, a message would be displayed on
8962 the terminal. */
8963 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
8964 return 0;
8965 #endif /* HAVE_WINDOW_SYSTEM */
8967 /* Redraw garbaged frames. */
8968 if (frame_garbaged)
8969 clear_garbaged_frames ();
8971 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
8973 echo_area_window = mini_window;
8974 window_height_changed_p = display_echo_area (w);
8975 w->must_be_updated_p = 1;
8977 /* Update the display, unless called from redisplay_internal.
8978 Also don't update the screen during redisplay itself. The
8979 update will happen at the end of redisplay, and an update
8980 here could cause confusion. */
8981 if (update_frame_p && !redisplaying_p)
8983 int n = 0;
8985 /* If the display update has been interrupted by pending
8986 input, update mode lines in the frame. Due to the
8987 pending input, it might have been that redisplay hasn't
8988 been called, so that mode lines above the echo area are
8989 garbaged. This looks odd, so we prevent it here. */
8990 if (!display_completed)
8991 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
8993 if (window_height_changed_p
8994 /* Don't do this if Emacs is shutting down. Redisplay
8995 needs to run hooks. */
8996 && !NILP (Vrun_hooks))
8998 /* Must update other windows. Likewise as in other
8999 cases, don't let this update be interrupted by
9000 pending input. */
9001 int count = SPECPDL_INDEX ();
9002 specbind (Qredisplay_dont_pause, Qt);
9003 windows_or_buffers_changed = 1;
9004 redisplay_internal (0);
9005 unbind_to (count, Qnil);
9007 else if (FRAME_WINDOW_P (f) && n == 0)
9009 /* Window configuration is the same as before.
9010 Can do with a display update of the echo area,
9011 unless we displayed some mode lines. */
9012 update_single_window (w, 1);
9013 FRAME_RIF (f)->flush_display (f);
9015 else
9016 update_frame (f, 1, 1);
9018 /* If cursor is in the echo area, make sure that the next
9019 redisplay displays the minibuffer, so that the cursor will
9020 be replaced with what the minibuffer wants. */
9021 if (cursor_in_echo_area)
9022 ++windows_or_buffers_changed;
9025 else if (!EQ (mini_window, selected_window))
9026 windows_or_buffers_changed++;
9028 /* Last displayed message is now the current message. */
9029 echo_area_buffer[1] = echo_area_buffer[0];
9030 /* Inform read_char that we're not echoing. */
9031 echo_message_buffer = Qnil;
9033 /* Prevent redisplay optimization in redisplay_internal by resetting
9034 this_line_start_pos. This is done because the mini-buffer now
9035 displays the message instead of its buffer text. */
9036 if (EQ (mini_window, selected_window))
9037 CHARPOS (this_line_start_pos) = 0;
9039 return window_height_changed_p;
9044 /***********************************************************************
9045 Mode Lines and Frame Titles
9046 ***********************************************************************/
9048 /* A buffer for constructing non-propertized mode-line strings and
9049 frame titles in it; allocated from the heap in init_xdisp and
9050 resized as needed in store_mode_line_noprop_char. */
9052 static char *mode_line_noprop_buf;
9054 /* The buffer's end, and a current output position in it. */
9056 static char *mode_line_noprop_buf_end;
9057 static char *mode_line_noprop_ptr;
9059 #define MODE_LINE_NOPROP_LEN(start) \
9060 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
9062 static enum {
9063 MODE_LINE_DISPLAY = 0,
9064 MODE_LINE_TITLE,
9065 MODE_LINE_NOPROP,
9066 MODE_LINE_STRING
9067 } mode_line_target;
9069 /* Alist that caches the results of :propertize.
9070 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
9071 static Lisp_Object mode_line_proptrans_alist;
9073 /* List of strings making up the mode-line. */
9074 static Lisp_Object mode_line_string_list;
9076 /* Base face property when building propertized mode line string. */
9077 static Lisp_Object mode_line_string_face;
9078 static Lisp_Object mode_line_string_face_prop;
9081 /* Unwind data for mode line strings */
9083 static Lisp_Object Vmode_line_unwind_vector;
9085 static Lisp_Object
9086 format_mode_line_unwind_data (struct buffer *obuf,
9087 Lisp_Object owin,
9088 int save_proptrans)
9090 Lisp_Object vector, tmp;
9092 /* Reduce consing by keeping one vector in
9093 Vwith_echo_area_save_vector. */
9094 vector = Vmode_line_unwind_vector;
9095 Vmode_line_unwind_vector = Qnil;
9097 if (NILP (vector))
9098 vector = Fmake_vector (make_number (8), Qnil);
9100 ASET (vector, 0, make_number (mode_line_target));
9101 ASET (vector, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
9102 ASET (vector, 2, mode_line_string_list);
9103 ASET (vector, 3, save_proptrans ? mode_line_proptrans_alist : Qt);
9104 ASET (vector, 4, mode_line_string_face);
9105 ASET (vector, 5, mode_line_string_face_prop);
9107 if (obuf)
9108 XSETBUFFER (tmp, obuf);
9109 else
9110 tmp = Qnil;
9111 ASET (vector, 6, tmp);
9112 ASET (vector, 7, owin);
9114 return vector;
9117 static Lisp_Object
9118 unwind_format_mode_line (vector)
9119 Lisp_Object vector;
9121 mode_line_target = XINT (AREF (vector, 0));
9122 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
9123 mode_line_string_list = AREF (vector, 2);
9124 if (! EQ (AREF (vector, 3), Qt))
9125 mode_line_proptrans_alist = AREF (vector, 3);
9126 mode_line_string_face = AREF (vector, 4);
9127 mode_line_string_face_prop = AREF (vector, 5);
9129 if (!NILP (AREF (vector, 7)))
9130 /* Select window before buffer, since it may change the buffer. */
9131 Fselect_window (AREF (vector, 7), Qt);
9133 if (!NILP (AREF (vector, 6)))
9135 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
9136 ASET (vector, 6, Qnil);
9139 Vmode_line_unwind_vector = vector;
9140 return Qnil;
9144 /* Store a single character C for the frame title in mode_line_noprop_buf.
9145 Re-allocate mode_line_noprop_buf if necessary. */
9147 static void
9148 #ifdef PROTOTYPES
9149 store_mode_line_noprop_char (char c)
9150 #else
9151 store_mode_line_noprop_char (c)
9152 char c;
9153 #endif
9155 /* If output position has reached the end of the allocated buffer,
9156 double the buffer's size. */
9157 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
9159 int len = MODE_LINE_NOPROP_LEN (0);
9160 int new_size = 2 * len * sizeof *mode_line_noprop_buf;
9161 mode_line_noprop_buf = (char *) xrealloc (mode_line_noprop_buf, new_size);
9162 mode_line_noprop_buf_end = mode_line_noprop_buf + new_size;
9163 mode_line_noprop_ptr = mode_line_noprop_buf + len;
9166 *mode_line_noprop_ptr++ = c;
9170 /* Store part of a frame title in mode_line_noprop_buf, beginning at
9171 mode_line_noprop_ptr. STR is the string to store. Do not copy
9172 characters that yield more columns than PRECISION; PRECISION <= 0
9173 means copy the whole string. Pad with spaces until FIELD_WIDTH
9174 number of characters have been copied; FIELD_WIDTH <= 0 means don't
9175 pad. Called from display_mode_element when it is used to build a
9176 frame title. */
9178 static int
9179 store_mode_line_noprop (str, field_width, precision)
9180 const unsigned char *str;
9181 int field_width, precision;
9183 int n = 0;
9184 int dummy, nbytes;
9186 /* Copy at most PRECISION chars from STR. */
9187 nbytes = strlen (str);
9188 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
9189 while (nbytes--)
9190 store_mode_line_noprop_char (*str++);
9192 /* Fill up with spaces until FIELD_WIDTH reached. */
9193 while (field_width > 0
9194 && n < field_width)
9196 store_mode_line_noprop_char (' ');
9197 ++n;
9200 return n;
9203 /***********************************************************************
9204 Frame Titles
9205 ***********************************************************************/
9207 #ifdef HAVE_WINDOW_SYSTEM
9209 /* Set the title of FRAME, if it has changed. The title format is
9210 Vicon_title_format if FRAME is iconified, otherwise it is
9211 frame_title_format. */
9213 static void
9214 x_consider_frame_title (frame)
9215 Lisp_Object frame;
9217 struct frame *f = XFRAME (frame);
9219 if (FRAME_WINDOW_P (f)
9220 || FRAME_MINIBUF_ONLY_P (f)
9221 || f->explicit_name)
9223 /* Do we have more than one visible frame on this X display? */
9224 Lisp_Object tail;
9225 Lisp_Object fmt;
9226 int title_start;
9227 char *title;
9228 int len;
9229 struct it it;
9230 int count = SPECPDL_INDEX ();
9232 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
9234 Lisp_Object other_frame = XCAR (tail);
9235 struct frame *tf = XFRAME (other_frame);
9237 if (tf != f
9238 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
9239 && !FRAME_MINIBUF_ONLY_P (tf)
9240 && !EQ (other_frame, tip_frame)
9241 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
9242 break;
9245 /* Set global variable indicating that multiple frames exist. */
9246 multiple_frames = CONSP (tail);
9248 /* Switch to the buffer of selected window of the frame. Set up
9249 mode_line_target so that display_mode_element will output into
9250 mode_line_noprop_buf; then display the title. */
9251 record_unwind_protect (unwind_format_mode_line,
9252 format_mode_line_unwind_data
9253 (current_buffer, selected_window, 0));
9255 Fselect_window (f->selected_window, Qt);
9256 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
9257 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
9259 mode_line_target = MODE_LINE_TITLE;
9260 title_start = MODE_LINE_NOPROP_LEN (0);
9261 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
9262 NULL, DEFAULT_FACE_ID);
9263 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
9264 len = MODE_LINE_NOPROP_LEN (title_start);
9265 title = mode_line_noprop_buf + title_start;
9266 unbind_to (count, Qnil);
9268 /* Set the title only if it's changed. This avoids consing in
9269 the common case where it hasn't. (If it turns out that we've
9270 already wasted too much time by walking through the list with
9271 display_mode_element, then we might need to optimize at a
9272 higher level than this.) */
9273 if (! STRINGP (f->name)
9274 || SBYTES (f->name) != len
9275 || bcmp (title, SDATA (f->name), len) != 0)
9276 x_implicitly_set_name (f, make_string (title, len), Qnil);
9280 #endif /* not HAVE_WINDOW_SYSTEM */
9285 /***********************************************************************
9286 Menu Bars
9287 ***********************************************************************/
9290 /* Prepare for redisplay by updating menu-bar item lists when
9291 appropriate. This can call eval. */
9293 void
9294 prepare_menu_bars ()
9296 int all_windows;
9297 struct gcpro gcpro1, gcpro2;
9298 struct frame *f;
9299 Lisp_Object tooltip_frame;
9301 #ifdef HAVE_WINDOW_SYSTEM
9302 tooltip_frame = tip_frame;
9303 #else
9304 tooltip_frame = Qnil;
9305 #endif
9307 /* Update all frame titles based on their buffer names, etc. We do
9308 this before the menu bars so that the buffer-menu will show the
9309 up-to-date frame titles. */
9310 #ifdef HAVE_WINDOW_SYSTEM
9311 if (windows_or_buffers_changed || update_mode_lines)
9313 Lisp_Object tail, frame;
9315 FOR_EACH_FRAME (tail, frame)
9317 f = XFRAME (frame);
9318 if (!EQ (frame, tooltip_frame)
9319 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
9320 x_consider_frame_title (frame);
9323 #endif /* HAVE_WINDOW_SYSTEM */
9325 /* Update the menu bar item lists, if appropriate. This has to be
9326 done before any actual redisplay or generation of display lines. */
9327 all_windows = (update_mode_lines
9328 || buffer_shared > 1
9329 || windows_or_buffers_changed);
9330 if (all_windows)
9332 Lisp_Object tail, frame;
9333 int count = SPECPDL_INDEX ();
9334 /* 1 means that update_menu_bar has run its hooks
9335 so any further calls to update_menu_bar shouldn't do so again. */
9336 int menu_bar_hooks_run = 0;
9338 record_unwind_save_match_data ();
9340 FOR_EACH_FRAME (tail, frame)
9342 f = XFRAME (frame);
9344 /* Ignore tooltip frame. */
9345 if (EQ (frame, tooltip_frame))
9346 continue;
9348 /* If a window on this frame changed size, report that to
9349 the user and clear the size-change flag. */
9350 if (FRAME_WINDOW_SIZES_CHANGED (f))
9352 Lisp_Object functions;
9354 /* Clear flag first in case we get an error below. */
9355 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
9356 functions = Vwindow_size_change_functions;
9357 GCPRO2 (tail, functions);
9359 while (CONSP (functions))
9361 call1 (XCAR (functions), frame);
9362 functions = XCDR (functions);
9364 UNGCPRO;
9367 GCPRO1 (tail);
9368 menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
9369 #ifdef HAVE_WINDOW_SYSTEM
9370 update_tool_bar (f, 0);
9371 #ifdef MAC_OS
9372 mac_update_title_bar (f, 0);
9373 #endif
9374 #endif
9375 UNGCPRO;
9378 unbind_to (count, Qnil);
9380 else
9382 struct frame *sf = SELECTED_FRAME ();
9383 update_menu_bar (sf, 1, 0);
9384 #ifdef HAVE_WINDOW_SYSTEM
9385 update_tool_bar (sf, 1);
9386 #ifdef MAC_OS
9387 mac_update_title_bar (sf, 1);
9388 #endif
9389 #endif
9392 /* Motif needs this. See comment in xmenu.c. Turn it off when
9393 pending_menu_activation is not defined. */
9394 #ifdef USE_X_TOOLKIT
9395 pending_menu_activation = 0;
9396 #endif
9400 /* Update the menu bar item list for frame F. This has to be done
9401 before we start to fill in any display lines, because it can call
9402 eval.
9404 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
9406 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
9407 already ran the menu bar hooks for this redisplay, so there
9408 is no need to run them again. The return value is the
9409 updated value of this flag, to pass to the next call. */
9411 static int
9412 update_menu_bar (f, save_match_data, hooks_run)
9413 struct frame *f;
9414 int save_match_data;
9415 int hooks_run;
9417 Lisp_Object window;
9418 register struct window *w;
9420 /* If called recursively during a menu update, do nothing. This can
9421 happen when, for instance, an activate-menubar-hook causes a
9422 redisplay. */
9423 if (inhibit_menubar_update)
9424 return hooks_run;
9426 window = FRAME_SELECTED_WINDOW (f);
9427 w = XWINDOW (window);
9429 #if 0 /* The if statement below this if statement used to include the
9430 condition !NILP (w->update_mode_line), rather than using
9431 update_mode_lines directly, and this if statement may have
9432 been added to make that condition work. Now the if
9433 statement below matches its comment, this isn't needed. */
9434 if (update_mode_lines)
9435 w->update_mode_line = Qt;
9436 #endif
9438 if (FRAME_WINDOW_P (f)
9440 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
9441 || defined (USE_GTK)
9442 FRAME_EXTERNAL_MENU_BAR (f)
9443 #else
9444 FRAME_MENU_BAR_LINES (f) > 0
9445 #endif
9446 : FRAME_MENU_BAR_LINES (f) > 0)
9448 /* If the user has switched buffers or windows, we need to
9449 recompute to reflect the new bindings. But we'll
9450 recompute when update_mode_lines is set too; that means
9451 that people can use force-mode-line-update to request
9452 that the menu bar be recomputed. The adverse effect on
9453 the rest of the redisplay algorithm is about the same as
9454 windows_or_buffers_changed anyway. */
9455 if (windows_or_buffers_changed
9456 /* This used to test w->update_mode_line, but we believe
9457 there is no need to recompute the menu in that case. */
9458 || update_mode_lines
9459 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
9460 < BUF_MODIFF (XBUFFER (w->buffer)))
9461 != !NILP (w->last_had_star))
9462 || ((!NILP (Vtransient_mark_mode)
9463 && !NILP (XBUFFER (w->buffer)->mark_active))
9464 != !NILP (w->region_showing)))
9466 struct buffer *prev = current_buffer;
9467 int count = SPECPDL_INDEX ();
9469 specbind (Qinhibit_menubar_update, Qt);
9471 set_buffer_internal_1 (XBUFFER (w->buffer));
9472 if (save_match_data)
9473 record_unwind_save_match_data ();
9474 if (NILP (Voverriding_local_map_menu_flag))
9476 specbind (Qoverriding_terminal_local_map, Qnil);
9477 specbind (Qoverriding_local_map, Qnil);
9480 if (!hooks_run)
9482 /* Run the Lucid hook. */
9483 safe_run_hooks (Qactivate_menubar_hook);
9485 /* If it has changed current-menubar from previous value,
9486 really recompute the menu-bar from the value. */
9487 if (! NILP (Vlucid_menu_bar_dirty_flag))
9488 call0 (Qrecompute_lucid_menubar);
9490 safe_run_hooks (Qmenu_bar_update_hook);
9492 hooks_run = 1;
9495 XSETFRAME (Vmenu_updating_frame, f);
9496 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
9498 /* Redisplay the menu bar in case we changed it. */
9499 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
9500 || defined (USE_GTK)
9501 if (FRAME_WINDOW_P (f))
9503 #ifdef MAC_OS
9504 /* All frames on Mac OS share the same menubar. So only
9505 the selected frame should be allowed to set it. */
9506 if (f == SELECTED_FRAME ())
9507 #endif
9508 set_frame_menubar (f, 0, 0);
9510 else
9511 /* On a terminal screen, the menu bar is an ordinary screen
9512 line, and this makes it get updated. */
9513 w->update_mode_line = Qt;
9514 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
9515 /* In the non-toolkit version, the menu bar is an ordinary screen
9516 line, and this makes it get updated. */
9517 w->update_mode_line = Qt;
9518 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
9520 unbind_to (count, Qnil);
9521 set_buffer_internal_1 (prev);
9525 return hooks_run;
9530 /***********************************************************************
9531 Output Cursor
9532 ***********************************************************************/
9534 #ifdef HAVE_WINDOW_SYSTEM
9536 /* EXPORT:
9537 Nominal cursor position -- where to draw output.
9538 HPOS and VPOS are window relative glyph matrix coordinates.
9539 X and Y are window relative pixel coordinates. */
9541 struct cursor_pos output_cursor;
9544 /* EXPORT:
9545 Set the global variable output_cursor to CURSOR. All cursor
9546 positions are relative to updated_window. */
9548 void
9549 set_output_cursor (cursor)
9550 struct cursor_pos *cursor;
9552 output_cursor.hpos = cursor->hpos;
9553 output_cursor.vpos = cursor->vpos;
9554 output_cursor.x = cursor->x;
9555 output_cursor.y = cursor->y;
9559 /* EXPORT for RIF:
9560 Set a nominal cursor position.
9562 HPOS and VPOS are column/row positions in a window glyph matrix. X
9563 and Y are window text area relative pixel positions.
9565 If this is done during an update, updated_window will contain the
9566 window that is being updated and the position is the future output
9567 cursor position for that window. If updated_window is null, use
9568 selected_window and display the cursor at the given position. */
9570 void
9571 x_cursor_to (vpos, hpos, y, x)
9572 int vpos, hpos, y, x;
9574 struct window *w;
9576 /* If updated_window is not set, work on selected_window. */
9577 if (updated_window)
9578 w = updated_window;
9579 else
9580 w = XWINDOW (selected_window);
9582 /* Set the output cursor. */
9583 output_cursor.hpos = hpos;
9584 output_cursor.vpos = vpos;
9585 output_cursor.x = x;
9586 output_cursor.y = y;
9588 /* If not called as part of an update, really display the cursor.
9589 This will also set the cursor position of W. */
9590 if (updated_window == NULL)
9592 BLOCK_INPUT;
9593 display_and_set_cursor (w, 1, hpos, vpos, x, y);
9594 if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
9595 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
9596 UNBLOCK_INPUT;
9600 #endif /* HAVE_WINDOW_SYSTEM */
9603 /***********************************************************************
9604 Tool-bars
9605 ***********************************************************************/
9607 #ifdef HAVE_WINDOW_SYSTEM
9609 /* Where the mouse was last time we reported a mouse event. */
9611 FRAME_PTR last_mouse_frame;
9613 /* Tool-bar item index of the item on which a mouse button was pressed
9614 or -1. */
9616 int last_tool_bar_item;
9619 /* Update the tool-bar item list for frame F. This has to be done
9620 before we start to fill in any display lines. Called from
9621 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
9622 and restore it here. */
9624 static void
9625 update_tool_bar (f, save_match_data)
9626 struct frame *f;
9627 int save_match_data;
9629 #if defined (USE_GTK) || USE_MAC_TOOLBAR
9630 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
9631 #else
9632 int do_update = WINDOWP (f->tool_bar_window)
9633 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
9634 #endif
9636 if (do_update)
9638 Lisp_Object window;
9639 struct window *w;
9641 window = FRAME_SELECTED_WINDOW (f);
9642 w = XWINDOW (window);
9644 /* If the user has switched buffers or windows, we need to
9645 recompute to reflect the new bindings. But we'll
9646 recompute when update_mode_lines is set too; that means
9647 that people can use force-mode-line-update to request
9648 that the menu bar be recomputed. The adverse effect on
9649 the rest of the redisplay algorithm is about the same as
9650 windows_or_buffers_changed anyway. */
9651 if (windows_or_buffers_changed
9652 || !NILP (w->update_mode_line)
9653 || update_mode_lines
9654 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
9655 < BUF_MODIFF (XBUFFER (w->buffer)))
9656 != !NILP (w->last_had_star))
9657 || ((!NILP (Vtransient_mark_mode)
9658 && !NILP (XBUFFER (w->buffer)->mark_active))
9659 != !NILP (w->region_showing)))
9661 struct buffer *prev = current_buffer;
9662 int count = SPECPDL_INDEX ();
9663 Lisp_Object new_tool_bar;
9664 int new_n_tool_bar;
9665 struct gcpro gcpro1;
9667 /* Set current_buffer to the buffer of the selected
9668 window of the frame, so that we get the right local
9669 keymaps. */
9670 set_buffer_internal_1 (XBUFFER (w->buffer));
9672 /* Save match data, if we must. */
9673 if (save_match_data)
9674 record_unwind_save_match_data ();
9676 /* Make sure that we don't accidentally use bogus keymaps. */
9677 if (NILP (Voverriding_local_map_menu_flag))
9679 specbind (Qoverriding_terminal_local_map, Qnil);
9680 specbind (Qoverriding_local_map, Qnil);
9683 GCPRO1 (new_tool_bar);
9685 /* Build desired tool-bar items from keymaps. */
9686 new_tool_bar = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
9687 &new_n_tool_bar);
9689 /* Redisplay the tool-bar if we changed it. */
9690 if (new_n_tool_bar != f->n_tool_bar_items
9691 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
9693 /* Redisplay that happens asynchronously due to an expose event
9694 may access f->tool_bar_items. Make sure we update both
9695 variables within BLOCK_INPUT so no such event interrupts. */
9696 BLOCK_INPUT;
9697 f->tool_bar_items = new_tool_bar;
9698 f->n_tool_bar_items = new_n_tool_bar;
9699 w->update_mode_line = Qt;
9700 UNBLOCK_INPUT;
9703 UNGCPRO;
9705 unbind_to (count, Qnil);
9706 set_buffer_internal_1 (prev);
9712 /* Set F->desired_tool_bar_string to a Lisp string representing frame
9713 F's desired tool-bar contents. F->tool_bar_items must have
9714 been set up previously by calling prepare_menu_bars. */
9716 static void
9717 build_desired_tool_bar_string (f)
9718 struct frame *f;
9720 int i, size, size_needed;
9721 struct gcpro gcpro1, gcpro2, gcpro3;
9722 Lisp_Object image, plist, props;
9724 image = plist = props = Qnil;
9725 GCPRO3 (image, plist, props);
9727 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
9728 Otherwise, make a new string. */
9730 /* The size of the string we might be able to reuse. */
9731 size = (STRINGP (f->desired_tool_bar_string)
9732 ? SCHARS (f->desired_tool_bar_string)
9733 : 0);
9735 /* We need one space in the string for each image. */
9736 size_needed = f->n_tool_bar_items;
9738 /* Reuse f->desired_tool_bar_string, if possible. */
9739 if (size < size_needed || NILP (f->desired_tool_bar_string))
9740 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
9741 make_number (' '));
9742 else
9744 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
9745 Fremove_text_properties (make_number (0), make_number (size),
9746 props, f->desired_tool_bar_string);
9749 /* Put a `display' property on the string for the images to display,
9750 put a `menu_item' property on tool-bar items with a value that
9751 is the index of the item in F's tool-bar item vector. */
9752 for (i = 0; i < f->n_tool_bar_items; ++i)
9754 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
9756 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
9757 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
9758 int hmargin, vmargin, relief, idx, end;
9759 extern Lisp_Object QCrelief, QCmargin, QCconversion;
9761 /* If image is a vector, choose the image according to the
9762 button state. */
9763 image = PROP (TOOL_BAR_ITEM_IMAGES);
9764 if (VECTORP (image))
9766 if (enabled_p)
9767 idx = (selected_p
9768 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
9769 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
9770 else
9771 idx = (selected_p
9772 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
9773 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
9775 xassert (ASIZE (image) >= idx);
9776 image = AREF (image, idx);
9778 else
9779 idx = -1;
9781 /* Ignore invalid image specifications. */
9782 if (!valid_image_p (image))
9783 continue;
9785 /* Display the tool-bar button pressed, or depressed. */
9786 plist = Fcopy_sequence (XCDR (image));
9788 /* Compute margin and relief to draw. */
9789 relief = (tool_bar_button_relief >= 0
9790 ? tool_bar_button_relief
9791 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
9792 hmargin = vmargin = relief;
9794 if (INTEGERP (Vtool_bar_button_margin)
9795 && XINT (Vtool_bar_button_margin) > 0)
9797 hmargin += XFASTINT (Vtool_bar_button_margin);
9798 vmargin += XFASTINT (Vtool_bar_button_margin);
9800 else if (CONSP (Vtool_bar_button_margin))
9802 if (INTEGERP (XCAR (Vtool_bar_button_margin))
9803 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
9804 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
9806 if (INTEGERP (XCDR (Vtool_bar_button_margin))
9807 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
9808 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
9811 if (auto_raise_tool_bar_buttons_p)
9813 /* Add a `:relief' property to the image spec if the item is
9814 selected. */
9815 if (selected_p)
9817 plist = Fplist_put (plist, QCrelief, make_number (-relief));
9818 hmargin -= relief;
9819 vmargin -= relief;
9822 else
9824 /* If image is selected, display it pressed, i.e. with a
9825 negative relief. If it's not selected, display it with a
9826 raised relief. */
9827 plist = Fplist_put (plist, QCrelief,
9828 (selected_p
9829 ? make_number (-relief)
9830 : make_number (relief)));
9831 hmargin -= relief;
9832 vmargin -= relief;
9835 /* Put a margin around the image. */
9836 if (hmargin || vmargin)
9838 if (hmargin == vmargin)
9839 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
9840 else
9841 plist = Fplist_put (plist, QCmargin,
9842 Fcons (make_number (hmargin),
9843 make_number (vmargin)));
9846 /* If button is not enabled, and we don't have special images
9847 for the disabled state, make the image appear disabled by
9848 applying an appropriate algorithm to it. */
9849 if (!enabled_p && idx < 0)
9850 plist = Fplist_put (plist, QCconversion, Qdisabled);
9852 /* Put a `display' text property on the string for the image to
9853 display. Put a `menu-item' property on the string that gives
9854 the start of this item's properties in the tool-bar items
9855 vector. */
9856 image = Fcons (Qimage, plist);
9857 props = list4 (Qdisplay, image,
9858 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
9860 /* Let the last image hide all remaining spaces in the tool bar
9861 string. The string can be longer than needed when we reuse a
9862 previous string. */
9863 if (i + 1 == f->n_tool_bar_items)
9864 end = SCHARS (f->desired_tool_bar_string);
9865 else
9866 end = i + 1;
9867 Fadd_text_properties (make_number (i), make_number (end),
9868 props, f->desired_tool_bar_string);
9869 #undef PROP
9872 UNGCPRO;
9876 /* Display one line of the tool-bar of frame IT->f.
9878 HEIGHT specifies the desired height of the tool-bar line.
9879 If the actual height of the glyph row is less than HEIGHT, the
9880 row's height is increased to HEIGHT, and the icons are centered
9881 vertically in the new height.
9883 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
9884 count a final empty row in case the tool-bar width exactly matches
9885 the window width.
9888 static void
9889 display_tool_bar_line (it, height)
9890 struct it *it;
9891 int height;
9893 struct glyph_row *row = it->glyph_row;
9894 int max_x = it->last_visible_x;
9895 struct glyph *last;
9897 prepare_desired_row (row);
9898 row->y = it->current_y;
9900 /* Note that this isn't made use of if the face hasn't a box,
9901 so there's no need to check the face here. */
9902 it->start_of_box_run_p = 1;
9904 while (it->current_x < max_x)
9906 int x, n_glyphs_before, i, nglyphs;
9907 struct it it_before;
9909 /* Get the next display element. */
9910 if (!get_next_display_element (it))
9912 /* Don't count empty row if we are counting needed tool-bar lines. */
9913 if (height < 0 && !it->hpos)
9914 return;
9915 break;
9918 /* Produce glyphs. */
9919 n_glyphs_before = row->used[TEXT_AREA];
9920 it_before = *it;
9922 PRODUCE_GLYPHS (it);
9924 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
9925 i = 0;
9926 x = it_before.current_x;
9927 while (i < nglyphs)
9929 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
9931 if (x + glyph->pixel_width > max_x)
9933 /* Glyph doesn't fit on line. Backtrack. */
9934 row->used[TEXT_AREA] = n_glyphs_before;
9935 *it = it_before;
9936 /* If this is the only glyph on this line, it will never fit on the
9937 toolbar, so skip it. But ensure there is at least one glyph,
9938 so we don't accidentally disable the tool-bar. */
9939 if (n_glyphs_before == 0
9940 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
9941 break;
9942 goto out;
9945 ++it->hpos;
9946 x += glyph->pixel_width;
9947 ++i;
9950 /* Stop at line ends. */
9951 if (ITERATOR_AT_END_OF_LINE_P (it))
9952 break;
9954 set_iterator_to_next (it, 1);
9957 out:;
9959 row->displays_text_p = row->used[TEXT_AREA] != 0;
9961 /* Use default face for the border below the tool bar.
9963 FIXME: When auto-resize-tool-bars is grow-only, there is
9964 no additional border below the possibly empty tool-bar lines.
9965 So to make the extra empty lines look "normal", we have to
9966 use the tool-bar face for the border too. */
9967 if (!row->displays_text_p && !EQ (Vauto_resize_tool_bars, Qgrow_only))
9968 it->face_id = DEFAULT_FACE_ID;
9970 extend_face_to_end_of_line (it);
9971 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
9972 last->right_box_line_p = 1;
9973 if (last == row->glyphs[TEXT_AREA])
9974 last->left_box_line_p = 1;
9976 /* Make line the desired height and center it vertically. */
9977 if ((height -= it->max_ascent + it->max_descent) > 0)
9979 /* Don't add more than one line height. */
9980 height %= FRAME_LINE_HEIGHT (it->f);
9981 it->max_ascent += height / 2;
9982 it->max_descent += (height + 1) / 2;
9985 compute_line_metrics (it);
9987 /* If line is empty, make it occupy the rest of the tool-bar. */
9988 if (!row->displays_text_p)
9990 row->height = row->phys_height = it->last_visible_y - row->y;
9991 row->visible_height = row->height;
9992 row->ascent = row->phys_ascent = 0;
9993 row->extra_line_spacing = 0;
9996 row->full_width_p = 1;
9997 row->continued_p = 0;
9998 row->truncated_on_left_p = 0;
9999 row->truncated_on_right_p = 0;
10001 it->current_x = it->hpos = 0;
10002 it->current_y += row->height;
10003 ++it->vpos;
10004 ++it->glyph_row;
10008 /* Max tool-bar height. */
10010 #define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
10011 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
10013 /* Value is the number of screen lines needed to make all tool-bar
10014 items of frame F visible. The number of actual rows needed is
10015 returned in *N_ROWS if non-NULL. */
10017 static int
10018 tool_bar_lines_needed (f, n_rows)
10019 struct frame *f;
10020 int *n_rows;
10022 struct window *w = XWINDOW (f->tool_bar_window);
10023 struct it it;
10024 /* tool_bar_lines_needed is called from redisplay_tool_bar after building
10025 the desired matrix, so use (unused) mode-line row as temporary row to
10026 avoid destroying the first tool-bar row. */
10027 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
10029 /* Initialize an iterator for iteration over
10030 F->desired_tool_bar_string in the tool-bar window of frame F. */
10031 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
10032 it.first_visible_x = 0;
10033 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
10034 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
10036 while (!ITERATOR_AT_END_P (&it))
10038 clear_glyph_row (temp_row);
10039 it.glyph_row = temp_row;
10040 display_tool_bar_line (&it, -1);
10042 clear_glyph_row (temp_row);
10044 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
10045 if (n_rows)
10046 *n_rows = it.vpos > 0 ? it.vpos : -1;
10048 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
10052 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
10053 0, 1, 0,
10054 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
10055 (frame)
10056 Lisp_Object frame;
10058 struct frame *f;
10059 struct window *w;
10060 int nlines = 0;
10062 if (NILP (frame))
10063 frame = selected_frame;
10064 else
10065 CHECK_FRAME (frame);
10066 f = XFRAME (frame);
10068 if (WINDOWP (f->tool_bar_window)
10069 || (w = XWINDOW (f->tool_bar_window),
10070 WINDOW_TOTAL_LINES (w) > 0))
10072 update_tool_bar (f, 1);
10073 if (f->n_tool_bar_items)
10075 build_desired_tool_bar_string (f);
10076 nlines = tool_bar_lines_needed (f, NULL);
10080 return make_number (nlines);
10084 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
10085 height should be changed. */
10087 static int
10088 redisplay_tool_bar (f)
10089 struct frame *f;
10091 struct window *w;
10092 struct it it;
10093 struct glyph_row *row;
10095 #if defined (USE_GTK) || USE_MAC_TOOLBAR
10096 if (FRAME_EXTERNAL_TOOL_BAR (f))
10097 update_frame_tool_bar (f);
10098 return 0;
10099 #endif
10101 /* If frame hasn't a tool-bar window or if it is zero-height, don't
10102 do anything. This means you must start with tool-bar-lines
10103 non-zero to get the auto-sizing effect. Or in other words, you
10104 can turn off tool-bars by specifying tool-bar-lines zero. */
10105 if (!WINDOWP (f->tool_bar_window)
10106 || (w = XWINDOW (f->tool_bar_window),
10107 WINDOW_TOTAL_LINES (w) == 0))
10108 return 0;
10110 /* Set up an iterator for the tool-bar window. */
10111 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
10112 it.first_visible_x = 0;
10113 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
10114 row = it.glyph_row;
10116 /* Build a string that represents the contents of the tool-bar. */
10117 build_desired_tool_bar_string (f);
10118 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
10120 if (f->n_tool_bar_rows == 0)
10122 int nlines;
10124 if ((nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
10125 nlines != WINDOW_TOTAL_LINES (w)))
10127 extern Lisp_Object Qtool_bar_lines;
10128 Lisp_Object frame;
10129 int old_height = WINDOW_TOTAL_LINES (w);
10131 XSETFRAME (frame, f);
10132 Fmodify_frame_parameters (frame,
10133 Fcons (Fcons (Qtool_bar_lines,
10134 make_number (nlines)),
10135 Qnil));
10136 if (WINDOW_TOTAL_LINES (w) != old_height)
10138 clear_glyph_matrix (w->desired_matrix);
10139 fonts_changed_p = 1;
10140 return 1;
10145 /* Display as many lines as needed to display all tool-bar items. */
10147 if (f->n_tool_bar_rows > 0)
10149 int border, rows, height, extra;
10151 if (INTEGERP (Vtool_bar_border))
10152 border = XINT (Vtool_bar_border);
10153 else if (EQ (Vtool_bar_border, Qinternal_border_width))
10154 border = FRAME_INTERNAL_BORDER_WIDTH (f);
10155 else if (EQ (Vtool_bar_border, Qborder_width))
10156 border = f->border_width;
10157 else
10158 border = 0;
10159 if (border < 0)
10160 border = 0;
10162 rows = f->n_tool_bar_rows;
10163 height = max (1, (it.last_visible_y - border) / rows);
10164 extra = it.last_visible_y - border - height * rows;
10166 while (it.current_y < it.last_visible_y)
10168 int h = 0;
10169 if (extra > 0 && rows-- > 0)
10171 h = (extra + rows - 1) / rows;
10172 extra -= h;
10174 display_tool_bar_line (&it, height + h);
10177 else
10179 while (it.current_y < it.last_visible_y)
10180 display_tool_bar_line (&it, 0);
10183 /* It doesn't make much sense to try scrolling in the tool-bar
10184 window, so don't do it. */
10185 w->desired_matrix->no_scrolling_p = 1;
10186 w->must_be_updated_p = 1;
10188 if (!NILP (Vauto_resize_tool_bars))
10190 int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
10191 int change_height_p = 0;
10193 /* If we couldn't display everything, change the tool-bar's
10194 height if there is room for more. */
10195 if (IT_STRING_CHARPOS (it) < it.end_charpos
10196 && it.current_y < max_tool_bar_height)
10197 change_height_p = 1;
10199 row = it.glyph_row - 1;
10201 /* If there are blank lines at the end, except for a partially
10202 visible blank line at the end that is smaller than
10203 FRAME_LINE_HEIGHT, change the tool-bar's height. */
10204 if (!row->displays_text_p
10205 && row->height >= FRAME_LINE_HEIGHT (f))
10206 change_height_p = 1;
10208 /* If row displays tool-bar items, but is partially visible,
10209 change the tool-bar's height. */
10210 if (row->displays_text_p
10211 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y
10212 && MATRIX_ROW_BOTTOM_Y (row) < max_tool_bar_height)
10213 change_height_p = 1;
10215 /* Resize windows as needed by changing the `tool-bar-lines'
10216 frame parameter. */
10217 if (change_height_p)
10219 extern Lisp_Object Qtool_bar_lines;
10220 Lisp_Object frame;
10221 int old_height = WINDOW_TOTAL_LINES (w);
10222 int nrows;
10223 int nlines = tool_bar_lines_needed (f, &nrows);
10225 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
10226 && !f->minimize_tool_bar_window_p)
10227 ? (nlines > old_height)
10228 : (nlines != old_height));
10229 f->minimize_tool_bar_window_p = 0;
10231 if (change_height_p)
10233 XSETFRAME (frame, f);
10234 Fmodify_frame_parameters (frame,
10235 Fcons (Fcons (Qtool_bar_lines,
10236 make_number (nlines)),
10237 Qnil));
10238 if (WINDOW_TOTAL_LINES (w) != old_height)
10240 clear_glyph_matrix (w->desired_matrix);
10241 f->n_tool_bar_rows = nrows;
10242 fonts_changed_p = 1;
10243 return 1;
10249 f->minimize_tool_bar_window_p = 0;
10250 return 0;
10254 /* Get information about the tool-bar item which is displayed in GLYPH
10255 on frame F. Return in *PROP_IDX the index where tool-bar item
10256 properties start in F->tool_bar_items. Value is zero if
10257 GLYPH doesn't display a tool-bar item. */
10259 static int
10260 tool_bar_item_info (f, glyph, prop_idx)
10261 struct frame *f;
10262 struct glyph *glyph;
10263 int *prop_idx;
10265 Lisp_Object prop;
10266 int success_p;
10267 int charpos;
10269 /* This function can be called asynchronously, which means we must
10270 exclude any possibility that Fget_text_property signals an
10271 error. */
10272 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
10273 charpos = max (0, charpos);
10275 /* Get the text property `menu-item' at pos. The value of that
10276 property is the start index of this item's properties in
10277 F->tool_bar_items. */
10278 prop = Fget_text_property (make_number (charpos),
10279 Qmenu_item, f->current_tool_bar_string);
10280 if (INTEGERP (prop))
10282 *prop_idx = XINT (prop);
10283 success_p = 1;
10285 else
10286 success_p = 0;
10288 return success_p;
10292 /* Get information about the tool-bar item at position X/Y on frame F.
10293 Return in *GLYPH a pointer to the glyph of the tool-bar item in
10294 the current matrix of the tool-bar window of F, or NULL if not
10295 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
10296 item in F->tool_bar_items. Value is
10298 -1 if X/Y is not on a tool-bar item
10299 0 if X/Y is on the same item that was highlighted before.
10300 1 otherwise. */
10302 static int
10303 get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
10304 struct frame *f;
10305 int x, y;
10306 struct glyph **glyph;
10307 int *hpos, *vpos, *prop_idx;
10309 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10310 struct window *w = XWINDOW (f->tool_bar_window);
10311 int area;
10313 /* Find the glyph under X/Y. */
10314 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
10315 if (*glyph == NULL)
10316 return -1;
10318 /* Get the start of this tool-bar item's properties in
10319 f->tool_bar_items. */
10320 if (!tool_bar_item_info (f, *glyph, prop_idx))
10321 return -1;
10323 /* Is mouse on the highlighted item? */
10324 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
10325 && *vpos >= dpyinfo->mouse_face_beg_row
10326 && *vpos <= dpyinfo->mouse_face_end_row
10327 && (*vpos > dpyinfo->mouse_face_beg_row
10328 || *hpos >= dpyinfo->mouse_face_beg_col)
10329 && (*vpos < dpyinfo->mouse_face_end_row
10330 || *hpos < dpyinfo->mouse_face_end_col
10331 || dpyinfo->mouse_face_past_end))
10332 return 0;
10334 return 1;
10338 /* EXPORT:
10339 Handle mouse button event on the tool-bar of frame F, at
10340 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
10341 0 for button release. MODIFIERS is event modifiers for button
10342 release. */
10344 void
10345 handle_tool_bar_click (f, x, y, down_p, modifiers)
10346 struct frame *f;
10347 int x, y, down_p;
10348 unsigned int modifiers;
10350 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10351 struct window *w = XWINDOW (f->tool_bar_window);
10352 int hpos, vpos, prop_idx;
10353 struct glyph *glyph;
10354 Lisp_Object enabled_p;
10356 /* If not on the highlighted tool-bar item, return. */
10357 frame_to_window_pixel_xy (w, &x, &y);
10358 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
10359 return;
10361 /* If item is disabled, do nothing. */
10362 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
10363 if (NILP (enabled_p))
10364 return;
10366 if (down_p)
10368 /* Show item in pressed state. */
10369 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
10370 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
10371 last_tool_bar_item = prop_idx;
10373 else
10375 Lisp_Object key, frame;
10376 struct input_event event;
10377 EVENT_INIT (event);
10379 /* Show item in released state. */
10380 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
10381 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
10383 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
10385 XSETFRAME (frame, f);
10386 event.kind = TOOL_BAR_EVENT;
10387 event.frame_or_window = frame;
10388 event.arg = frame;
10389 kbd_buffer_store_event (&event);
10391 event.kind = TOOL_BAR_EVENT;
10392 event.frame_or_window = frame;
10393 event.arg = key;
10394 event.modifiers = modifiers;
10395 kbd_buffer_store_event (&event);
10396 last_tool_bar_item = -1;
10401 /* Possibly highlight a tool-bar item on frame F when mouse moves to
10402 tool-bar window-relative coordinates X/Y. Called from
10403 note_mouse_highlight. */
10405 static void
10406 note_tool_bar_highlight (f, x, y)
10407 struct frame *f;
10408 int x, y;
10410 Lisp_Object window = f->tool_bar_window;
10411 struct window *w = XWINDOW (window);
10412 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10413 int hpos, vpos;
10414 struct glyph *glyph;
10415 struct glyph_row *row;
10416 int i;
10417 Lisp_Object enabled_p;
10418 int prop_idx;
10419 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
10420 int mouse_down_p, rc;
10422 /* Function note_mouse_highlight is called with negative x(y
10423 values when mouse moves outside of the frame. */
10424 if (x <= 0 || y <= 0)
10426 clear_mouse_face (dpyinfo);
10427 return;
10430 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
10431 if (rc < 0)
10433 /* Not on tool-bar item. */
10434 clear_mouse_face (dpyinfo);
10435 return;
10437 else if (rc == 0)
10438 /* On same tool-bar item as before. */
10439 goto set_help_echo;
10441 clear_mouse_face (dpyinfo);
10443 /* Mouse is down, but on different tool-bar item? */
10444 mouse_down_p = (dpyinfo->grabbed
10445 && f == last_mouse_frame
10446 && FRAME_LIVE_P (f));
10447 if (mouse_down_p
10448 && last_tool_bar_item != prop_idx)
10449 return;
10451 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
10452 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
10454 /* If tool-bar item is not enabled, don't highlight it. */
10455 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
10456 if (!NILP (enabled_p))
10458 /* Compute the x-position of the glyph. In front and past the
10459 image is a space. We include this in the highlighted area. */
10460 row = MATRIX_ROW (w->current_matrix, vpos);
10461 for (i = x = 0; i < hpos; ++i)
10462 x += row->glyphs[TEXT_AREA][i].pixel_width;
10464 /* Record this as the current active region. */
10465 dpyinfo->mouse_face_beg_col = hpos;
10466 dpyinfo->mouse_face_beg_row = vpos;
10467 dpyinfo->mouse_face_beg_x = x;
10468 dpyinfo->mouse_face_beg_y = row->y;
10469 dpyinfo->mouse_face_past_end = 0;
10471 dpyinfo->mouse_face_end_col = hpos + 1;
10472 dpyinfo->mouse_face_end_row = vpos;
10473 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
10474 dpyinfo->mouse_face_end_y = row->y;
10475 dpyinfo->mouse_face_window = window;
10476 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
10478 /* Display it as active. */
10479 show_mouse_face (dpyinfo, draw);
10480 dpyinfo->mouse_face_image_state = draw;
10483 set_help_echo:
10485 /* Set help_echo_string to a help string to display for this tool-bar item.
10486 XTread_socket does the rest. */
10487 help_echo_object = help_echo_window = Qnil;
10488 help_echo_pos = -1;
10489 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
10490 if (NILP (help_echo_string))
10491 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
10494 #endif /* HAVE_WINDOW_SYSTEM */
10498 /************************************************************************
10499 Horizontal scrolling
10500 ************************************************************************/
10502 static int hscroll_window_tree P_ ((Lisp_Object));
10503 static int hscroll_windows P_ ((Lisp_Object));
10505 /* For all leaf windows in the window tree rooted at WINDOW, set their
10506 hscroll value so that PT is (i) visible in the window, and (ii) so
10507 that it is not within a certain margin at the window's left and
10508 right border. Value is non-zero if any window's hscroll has been
10509 changed. */
10511 static int
10512 hscroll_window_tree (window)
10513 Lisp_Object window;
10515 int hscrolled_p = 0;
10516 int hscroll_relative_p = FLOATP (Vhscroll_step);
10517 int hscroll_step_abs = 0;
10518 double hscroll_step_rel = 0;
10520 if (hscroll_relative_p)
10522 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
10523 if (hscroll_step_rel < 0)
10525 hscroll_relative_p = 0;
10526 hscroll_step_abs = 0;
10529 else if (INTEGERP (Vhscroll_step))
10531 hscroll_step_abs = XINT (Vhscroll_step);
10532 if (hscroll_step_abs < 0)
10533 hscroll_step_abs = 0;
10535 else
10536 hscroll_step_abs = 0;
10538 while (WINDOWP (window))
10540 struct window *w = XWINDOW (window);
10542 if (WINDOWP (w->hchild))
10543 hscrolled_p |= hscroll_window_tree (w->hchild);
10544 else if (WINDOWP (w->vchild))
10545 hscrolled_p |= hscroll_window_tree (w->vchild);
10546 else if (w->cursor.vpos >= 0)
10548 int h_margin;
10549 int text_area_width;
10550 struct glyph_row *current_cursor_row
10551 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
10552 struct glyph_row *desired_cursor_row
10553 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
10554 struct glyph_row *cursor_row
10555 = (desired_cursor_row->enabled_p
10556 ? desired_cursor_row
10557 : current_cursor_row);
10559 text_area_width = window_box_width (w, TEXT_AREA);
10561 /* Scroll when cursor is inside this scroll margin. */
10562 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
10564 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->buffer))
10565 && ((XFASTINT (w->hscroll)
10566 && w->cursor.x <= h_margin)
10567 || (cursor_row->enabled_p
10568 && cursor_row->truncated_on_right_p
10569 && (w->cursor.x >= text_area_width - h_margin))))
10571 struct it it;
10572 int hscroll;
10573 struct buffer *saved_current_buffer;
10574 int pt;
10575 int wanted_x;
10577 /* Find point in a display of infinite width. */
10578 saved_current_buffer = current_buffer;
10579 current_buffer = XBUFFER (w->buffer);
10581 if (w == XWINDOW (selected_window))
10582 pt = BUF_PT (current_buffer);
10583 else
10585 pt = marker_position (w->pointm);
10586 pt = max (BEGV, pt);
10587 pt = min (ZV, pt);
10590 /* Move iterator to pt starting at cursor_row->start in
10591 a line with infinite width. */
10592 init_to_row_start (&it, w, cursor_row);
10593 it.last_visible_x = INFINITY;
10594 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
10595 current_buffer = saved_current_buffer;
10597 /* Position cursor in window. */
10598 if (!hscroll_relative_p && hscroll_step_abs == 0)
10599 hscroll = max (0, (it.current_x
10600 - (ITERATOR_AT_END_OF_LINE_P (&it)
10601 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
10602 : (text_area_width / 2))))
10603 / FRAME_COLUMN_WIDTH (it.f);
10604 else if (w->cursor.x >= text_area_width - h_margin)
10606 if (hscroll_relative_p)
10607 wanted_x = text_area_width * (1 - hscroll_step_rel)
10608 - h_margin;
10609 else
10610 wanted_x = text_area_width
10611 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
10612 - h_margin;
10613 hscroll
10614 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
10616 else
10618 if (hscroll_relative_p)
10619 wanted_x = text_area_width * hscroll_step_rel
10620 + h_margin;
10621 else
10622 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
10623 + h_margin;
10624 hscroll
10625 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
10627 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
10629 /* Don't call Fset_window_hscroll if value hasn't
10630 changed because it will prevent redisplay
10631 optimizations. */
10632 if (XFASTINT (w->hscroll) != hscroll)
10634 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
10635 w->hscroll = make_number (hscroll);
10636 hscrolled_p = 1;
10641 window = w->next;
10644 /* Value is non-zero if hscroll of any leaf window has been changed. */
10645 return hscrolled_p;
10649 /* Set hscroll so that cursor is visible and not inside horizontal
10650 scroll margins for all windows in the tree rooted at WINDOW. See
10651 also hscroll_window_tree above. Value is non-zero if any window's
10652 hscroll has been changed. If it has, desired matrices on the frame
10653 of WINDOW are cleared. */
10655 static int
10656 hscroll_windows (window)
10657 Lisp_Object window;
10659 int hscrolled_p = hscroll_window_tree (window);
10660 if (hscrolled_p)
10661 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
10662 return hscrolled_p;
10667 /************************************************************************
10668 Redisplay
10669 ************************************************************************/
10671 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
10672 to a non-zero value. This is sometimes handy to have in a debugger
10673 session. */
10675 #if GLYPH_DEBUG
10677 /* First and last unchanged row for try_window_id. */
10679 int debug_first_unchanged_at_end_vpos;
10680 int debug_last_unchanged_at_beg_vpos;
10682 /* Delta vpos and y. */
10684 int debug_dvpos, debug_dy;
10686 /* Delta in characters and bytes for try_window_id. */
10688 int debug_delta, debug_delta_bytes;
10690 /* Values of window_end_pos and window_end_vpos at the end of
10691 try_window_id. */
10693 EMACS_INT debug_end_pos, debug_end_vpos;
10695 /* Append a string to W->desired_matrix->method. FMT is a printf
10696 format string. A1...A9 are a supplement for a variable-length
10697 argument list. If trace_redisplay_p is non-zero also printf the
10698 resulting string to stderr. */
10700 static void
10701 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
10702 struct window *w;
10703 char *fmt;
10704 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
10706 char buffer[512];
10707 char *method = w->desired_matrix->method;
10708 int len = strlen (method);
10709 int size = sizeof w->desired_matrix->method;
10710 int remaining = size - len - 1;
10712 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
10713 if (len && remaining)
10715 method[len] = '|';
10716 --remaining, ++len;
10719 strncpy (method + len, buffer, remaining);
10721 if (trace_redisplay_p)
10722 fprintf (stderr, "%p (%s): %s\n",
10724 ((BUFFERP (w->buffer)
10725 && STRINGP (XBUFFER (w->buffer)->name))
10726 ? (char *) SDATA (XBUFFER (w->buffer)->name)
10727 : "no buffer"),
10728 buffer);
10731 #endif /* GLYPH_DEBUG */
10734 /* Value is non-zero if all changes in window W, which displays
10735 current_buffer, are in the text between START and END. START is a
10736 buffer position, END is given as a distance from Z. Used in
10737 redisplay_internal for display optimization. */
10739 static INLINE int
10740 text_outside_line_unchanged_p (w, start, end)
10741 struct window *w;
10742 int start, end;
10744 int unchanged_p = 1;
10746 /* If text or overlays have changed, see where. */
10747 if (XFASTINT (w->last_modified) < MODIFF
10748 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
10750 /* Gap in the line? */
10751 if (GPT < start || Z - GPT < end)
10752 unchanged_p = 0;
10754 /* Changes start in front of the line, or end after it? */
10755 if (unchanged_p
10756 && (BEG_UNCHANGED < start - 1
10757 || END_UNCHANGED < end))
10758 unchanged_p = 0;
10760 /* If selective display, can't optimize if changes start at the
10761 beginning of the line. */
10762 if (unchanged_p
10763 && INTEGERP (current_buffer->selective_display)
10764 && XINT (current_buffer->selective_display) > 0
10765 && (BEG_UNCHANGED < start || GPT <= start))
10766 unchanged_p = 0;
10768 /* If there are overlays at the start or end of the line, these
10769 may have overlay strings with newlines in them. A change at
10770 START, for instance, may actually concern the display of such
10771 overlay strings as well, and they are displayed on different
10772 lines. So, quickly rule out this case. (For the future, it
10773 might be desirable to implement something more telling than
10774 just BEG/END_UNCHANGED.) */
10775 if (unchanged_p)
10777 if (BEG + BEG_UNCHANGED == start
10778 && overlay_touches_p (start))
10779 unchanged_p = 0;
10780 if (END_UNCHANGED == end
10781 && overlay_touches_p (Z - end))
10782 unchanged_p = 0;
10786 return unchanged_p;
10790 /* Do a frame update, taking possible shortcuts into account. This is
10791 the main external entry point for redisplay.
10793 If the last redisplay displayed an echo area message and that message
10794 is no longer requested, we clear the echo area or bring back the
10795 mini-buffer if that is in use. */
10797 void
10798 redisplay ()
10800 redisplay_internal (0);
10804 static Lisp_Object
10805 overlay_arrow_string_or_property (var)
10806 Lisp_Object var;
10808 Lisp_Object val;
10810 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
10811 return val;
10813 return Voverlay_arrow_string;
10816 /* Return 1 if there are any overlay-arrows in current_buffer. */
10817 static int
10818 overlay_arrow_in_current_buffer_p ()
10820 Lisp_Object vlist;
10822 for (vlist = Voverlay_arrow_variable_list;
10823 CONSP (vlist);
10824 vlist = XCDR (vlist))
10826 Lisp_Object var = XCAR (vlist);
10827 Lisp_Object val;
10829 if (!SYMBOLP (var))
10830 continue;
10831 val = find_symbol_value (var);
10832 if (MARKERP (val)
10833 && current_buffer == XMARKER (val)->buffer)
10834 return 1;
10836 return 0;
10840 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
10841 has changed. */
10843 static int
10844 overlay_arrows_changed_p ()
10846 Lisp_Object vlist;
10848 for (vlist = Voverlay_arrow_variable_list;
10849 CONSP (vlist);
10850 vlist = XCDR (vlist))
10852 Lisp_Object var = XCAR (vlist);
10853 Lisp_Object val, pstr;
10855 if (!SYMBOLP (var))
10856 continue;
10857 val = find_symbol_value (var);
10858 if (!MARKERP (val))
10859 continue;
10860 if (! EQ (COERCE_MARKER (val),
10861 Fget (var, Qlast_arrow_position))
10862 || ! (pstr = overlay_arrow_string_or_property (var),
10863 EQ (pstr, Fget (var, Qlast_arrow_string))))
10864 return 1;
10866 return 0;
10869 /* Mark overlay arrows to be updated on next redisplay. */
10871 static void
10872 update_overlay_arrows (up_to_date)
10873 int up_to_date;
10875 Lisp_Object vlist;
10877 for (vlist = Voverlay_arrow_variable_list;
10878 CONSP (vlist);
10879 vlist = XCDR (vlist))
10881 Lisp_Object var = XCAR (vlist);
10883 if (!SYMBOLP (var))
10884 continue;
10886 if (up_to_date > 0)
10888 Lisp_Object val = find_symbol_value (var);
10889 Fput (var, Qlast_arrow_position,
10890 COERCE_MARKER (val));
10891 Fput (var, Qlast_arrow_string,
10892 overlay_arrow_string_or_property (var));
10894 else if (up_to_date < 0
10895 || !NILP (Fget (var, Qlast_arrow_position)))
10897 Fput (var, Qlast_arrow_position, Qt);
10898 Fput (var, Qlast_arrow_string, Qt);
10904 /* Return overlay arrow string to display at row.
10905 Return integer (bitmap number) for arrow bitmap in left fringe.
10906 Return nil if no overlay arrow. */
10908 static Lisp_Object
10909 overlay_arrow_at_row (it, row)
10910 struct it *it;
10911 struct glyph_row *row;
10913 Lisp_Object vlist;
10915 for (vlist = Voverlay_arrow_variable_list;
10916 CONSP (vlist);
10917 vlist = XCDR (vlist))
10919 Lisp_Object var = XCAR (vlist);
10920 Lisp_Object val;
10922 if (!SYMBOLP (var))
10923 continue;
10925 val = find_symbol_value (var);
10927 if (MARKERP (val)
10928 && current_buffer == XMARKER (val)->buffer
10929 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
10931 if (FRAME_WINDOW_P (it->f)
10932 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
10934 #ifdef HAVE_WINDOW_SYSTEM
10935 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
10937 int fringe_bitmap;
10938 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
10939 return make_number (fringe_bitmap);
10941 #endif
10942 return make_number (-1); /* Use default arrow bitmap */
10944 return overlay_arrow_string_or_property (var);
10948 return Qnil;
10951 /* Return 1 if point moved out of or into a composition. Otherwise
10952 return 0. PREV_BUF and PREV_PT are the last point buffer and
10953 position. BUF and PT are the current point buffer and position. */
10956 check_point_in_composition (prev_buf, prev_pt, buf, pt)
10957 struct buffer *prev_buf, *buf;
10958 int prev_pt, pt;
10960 EMACS_INT start, end;
10961 Lisp_Object prop;
10962 Lisp_Object buffer;
10964 XSETBUFFER (buffer, buf);
10965 /* Check a composition at the last point if point moved within the
10966 same buffer. */
10967 if (prev_buf == buf)
10969 if (prev_pt == pt)
10970 /* Point didn't move. */
10971 return 0;
10973 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
10974 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
10975 && COMPOSITION_VALID_P (start, end, prop)
10976 && start < prev_pt && end > prev_pt)
10977 /* The last point was within the composition. Return 1 iff
10978 point moved out of the composition. */
10979 return (pt <= start || pt >= end);
10982 /* Check a composition at the current point. */
10983 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
10984 && find_composition (pt, -1, &start, &end, &prop, buffer)
10985 && COMPOSITION_VALID_P (start, end, prop)
10986 && start < pt && end > pt);
10990 /* Reconsider the setting of B->clip_changed which is displayed
10991 in window W. */
10993 static INLINE void
10994 reconsider_clip_changes (w, b)
10995 struct window *w;
10996 struct buffer *b;
10998 if (b->clip_changed
10999 && !NILP (w->window_end_valid)
11000 && w->current_matrix->buffer == b
11001 && w->current_matrix->zv == BUF_ZV (b)
11002 && w->current_matrix->begv == BUF_BEGV (b))
11003 b->clip_changed = 0;
11005 /* If display wasn't paused, and W is not a tool bar window, see if
11006 point has been moved into or out of a composition. In that case,
11007 we set b->clip_changed to 1 to force updating the screen. If
11008 b->clip_changed has already been set to 1, we can skip this
11009 check. */
11010 if (!b->clip_changed
11011 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
11013 int pt;
11015 if (w == XWINDOW (selected_window))
11016 pt = BUF_PT (current_buffer);
11017 else
11018 pt = marker_position (w->pointm);
11020 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
11021 || pt != XINT (w->last_point))
11022 && check_point_in_composition (w->current_matrix->buffer,
11023 XINT (w->last_point),
11024 XBUFFER (w->buffer), pt))
11025 b->clip_changed = 1;
11030 /* Select FRAME to forward the values of frame-local variables into C
11031 variables so that the redisplay routines can access those values
11032 directly. */
11034 static void
11035 select_frame_for_redisplay (frame)
11036 Lisp_Object frame;
11038 Lisp_Object tail, sym, val;
11039 Lisp_Object old = selected_frame;
11041 xassert (FRAMEP (frame) && FRAME_LIVE_P (XFRAME (frame)));
11043 selected_frame = frame;
11047 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
11048 if (CONSP (XCAR (tail))
11049 && (sym = XCAR (XCAR (tail)),
11050 SYMBOLP (sym))
11051 && (sym = indirect_variable (sym),
11052 val = SYMBOL_VALUE (sym),
11053 (BUFFER_LOCAL_VALUEP (val)))
11054 && XBUFFER_LOCAL_VALUE (val)->check_frame)
11055 /* Use find_symbol_value rather than Fsymbol_value
11056 to avoid an error if it is void. */
11057 find_symbol_value (sym);
11058 } while (!EQ (frame, old) && (frame = old, 1));
11062 #define STOP_POLLING \
11063 do { if (! polling_stopped_here) stop_polling (); \
11064 polling_stopped_here = 1; } while (0)
11066 #define RESUME_POLLING \
11067 do { if (polling_stopped_here) start_polling (); \
11068 polling_stopped_here = 0; } while (0)
11071 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
11072 response to any user action; therefore, we should preserve the echo
11073 area. (Actually, our caller does that job.) Perhaps in the future
11074 avoid recentering windows if it is not necessary; currently that
11075 causes some problems. */
11077 static void
11078 redisplay_internal (preserve_echo_area)
11079 int preserve_echo_area;
11081 struct window *w = XWINDOW (selected_window);
11082 struct frame *f;
11083 int pause;
11084 int must_finish = 0;
11085 struct text_pos tlbufpos, tlendpos;
11086 int number_of_visible_frames;
11087 int count, count1;
11088 struct frame *sf;
11089 int polling_stopped_here = 0;
11090 Lisp_Object old_frame = selected_frame;
11092 /* Non-zero means redisplay has to consider all windows on all
11093 frames. Zero means, only selected_window is considered. */
11094 int consider_all_windows_p;
11096 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
11098 /* No redisplay if running in batch mode or frame is not yet fully
11099 initialized, or redisplay is explicitly turned off by setting
11100 Vinhibit_redisplay. */
11101 if (noninteractive
11102 || !NILP (Vinhibit_redisplay))
11103 return;
11105 /* Don't examine these until after testing Vinhibit_redisplay.
11106 When Emacs is shutting down, perhaps because its connection to
11107 X has dropped, we should not look at them at all. */
11108 f = XFRAME (w->frame);
11109 sf = SELECTED_FRAME ();
11111 if (!f->glyphs_initialized_p)
11112 return;
11114 /* The flag redisplay_performed_directly_p is set by
11115 direct_output_for_insert when it already did the whole screen
11116 update necessary. */
11117 if (redisplay_performed_directly_p)
11119 redisplay_performed_directly_p = 0;
11120 if (!hscroll_windows (selected_window))
11121 return;
11124 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (MAC_OS)
11125 if (popup_activated ())
11126 return;
11127 #endif
11129 /* I don't think this happens but let's be paranoid. */
11130 if (redisplaying_p)
11131 return;
11133 /* Record a function that resets redisplaying_p to its old value
11134 when we leave this function. */
11135 count = SPECPDL_INDEX ();
11136 record_unwind_protect (unwind_redisplay,
11137 Fcons (make_number (redisplaying_p), selected_frame));
11138 ++redisplaying_p;
11139 specbind (Qinhibit_free_realized_faces, Qnil);
11142 Lisp_Object tail, frame;
11144 FOR_EACH_FRAME (tail, frame)
11146 struct frame *f = XFRAME (frame);
11147 f->already_hscrolled_p = 0;
11151 retry:
11152 if (!EQ (old_frame, selected_frame)
11153 && FRAME_LIVE_P (XFRAME (old_frame)))
11154 /* When running redisplay, we play a bit fast-and-loose and allow e.g.
11155 selected_frame and selected_window to be temporarily out-of-sync so
11156 when we come back here via `goto retry', we need to resync because we
11157 may need to run Elisp code (via prepare_menu_bars). */
11158 select_frame_for_redisplay (old_frame);
11160 pause = 0;
11161 reconsider_clip_changes (w, current_buffer);
11162 last_escape_glyph_frame = NULL;
11163 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
11165 /* If new fonts have been loaded that make a glyph matrix adjustment
11166 necessary, do it. */
11167 if (fonts_changed_p)
11169 adjust_glyphs (NULL);
11170 ++windows_or_buffers_changed;
11171 fonts_changed_p = 0;
11174 /* If face_change_count is non-zero, init_iterator will free all
11175 realized faces, which includes the faces referenced from current
11176 matrices. So, we can't reuse current matrices in this case. */
11177 if (face_change_count)
11178 ++windows_or_buffers_changed;
11180 if (FRAME_TERMCAP_P (sf)
11181 && FRAME_TTY (sf)->previous_frame != sf)
11183 /* Since frames on a single ASCII terminal share the same
11184 display area, displaying a different frame means redisplay
11185 the whole thing. */
11186 windows_or_buffers_changed++;
11187 SET_FRAME_GARBAGED (sf);
11188 #ifndef WINDOWSNT
11189 set_tty_color_mode (FRAME_TTY (sf), sf);
11190 #endif
11191 FRAME_TTY (sf)->previous_frame = sf;
11194 /* Set the visible flags for all frames. Do this before checking
11195 for resized or garbaged frames; they want to know if their frames
11196 are visible. See the comment in frame.h for
11197 FRAME_SAMPLE_VISIBILITY. */
11199 Lisp_Object tail, frame;
11201 number_of_visible_frames = 0;
11203 FOR_EACH_FRAME (tail, frame)
11205 struct frame *f = XFRAME (frame);
11207 FRAME_SAMPLE_VISIBILITY (f);
11208 if (FRAME_VISIBLE_P (f))
11209 ++number_of_visible_frames;
11210 clear_desired_matrices (f);
11215 /* Notice any pending interrupt request to change frame size. */
11216 do_pending_window_change (1);
11218 /* Clear frames marked as garbaged. */
11219 if (frame_garbaged)
11220 clear_garbaged_frames ();
11222 /* Build menubar and tool-bar items. */
11223 if (NILP (Vmemory_full))
11224 prepare_menu_bars ();
11226 if (windows_or_buffers_changed)
11227 update_mode_lines++;
11229 /* Detect case that we need to write or remove a star in the mode line. */
11230 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
11232 w->update_mode_line = Qt;
11233 if (buffer_shared > 1)
11234 update_mode_lines++;
11237 /* Avoid invocation of point motion hooks by `current_column' below. */
11238 count1 = SPECPDL_INDEX ();
11239 specbind (Qinhibit_point_motion_hooks, Qt);
11241 /* If %c is in the mode line, update it if needed. */
11242 if (!NILP (w->column_number_displayed)
11243 /* This alternative quickly identifies a common case
11244 where no change is needed. */
11245 && !(PT == XFASTINT (w->last_point)
11246 && XFASTINT (w->last_modified) >= MODIFF
11247 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
11248 && (XFASTINT (w->column_number_displayed)
11249 != (int) current_column ())) /* iftc */
11250 w->update_mode_line = Qt;
11252 unbind_to (count1, Qnil);
11254 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
11256 /* The variable buffer_shared is set in redisplay_window and
11257 indicates that we redisplay a buffer in different windows. See
11258 there. */
11259 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
11260 || cursor_type_changed);
11262 /* If specs for an arrow have changed, do thorough redisplay
11263 to ensure we remove any arrow that should no longer exist. */
11264 if (overlay_arrows_changed_p ())
11265 consider_all_windows_p = windows_or_buffers_changed = 1;
11267 /* Normally the message* functions will have already displayed and
11268 updated the echo area, but the frame may have been trashed, or
11269 the update may have been preempted, so display the echo area
11270 again here. Checking message_cleared_p captures the case that
11271 the echo area should be cleared. */
11272 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
11273 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
11274 || (message_cleared_p
11275 && minibuf_level == 0
11276 /* If the mini-window is currently selected, this means the
11277 echo-area doesn't show through. */
11278 && !MINI_WINDOW_P (XWINDOW (selected_window))))
11280 int window_height_changed_p = echo_area_display (0);
11281 must_finish = 1;
11283 /* If we don't display the current message, don't clear the
11284 message_cleared_p flag, because, if we did, we wouldn't clear
11285 the echo area in the next redisplay which doesn't preserve
11286 the echo area. */
11287 if (!display_last_displayed_message_p)
11288 message_cleared_p = 0;
11290 if (fonts_changed_p)
11291 goto retry;
11292 else if (window_height_changed_p)
11294 consider_all_windows_p = 1;
11295 ++update_mode_lines;
11296 ++windows_or_buffers_changed;
11298 /* If window configuration was changed, frames may have been
11299 marked garbaged. Clear them or we will experience
11300 surprises wrt scrolling. */
11301 if (frame_garbaged)
11302 clear_garbaged_frames ();
11305 else if (EQ (selected_window, minibuf_window)
11306 && (current_buffer->clip_changed
11307 || XFASTINT (w->last_modified) < MODIFF
11308 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
11309 && resize_mini_window (w, 0))
11311 /* Resized active mini-window to fit the size of what it is
11312 showing if its contents might have changed. */
11313 must_finish = 1;
11314 consider_all_windows_p = 1;
11315 ++windows_or_buffers_changed;
11316 ++update_mode_lines;
11318 /* If window configuration was changed, frames may have been
11319 marked garbaged. Clear them or we will experience
11320 surprises wrt scrolling. */
11321 if (frame_garbaged)
11322 clear_garbaged_frames ();
11326 /* If showing the region, and mark has changed, we must redisplay
11327 the whole window. The assignment to this_line_start_pos prevents
11328 the optimization directly below this if-statement. */
11329 if (((!NILP (Vtransient_mark_mode)
11330 && !NILP (XBUFFER (w->buffer)->mark_active))
11331 != !NILP (w->region_showing))
11332 || (!NILP (w->region_showing)
11333 && !EQ (w->region_showing,
11334 Fmarker_position (XBUFFER (w->buffer)->mark))))
11335 CHARPOS (this_line_start_pos) = 0;
11337 /* Optimize the case that only the line containing the cursor in the
11338 selected window has changed. Variables starting with this_ are
11339 set in display_line and record information about the line
11340 containing the cursor. */
11341 tlbufpos = this_line_start_pos;
11342 tlendpos = this_line_end_pos;
11343 if (!consider_all_windows_p
11344 && CHARPOS (tlbufpos) > 0
11345 && NILP (w->update_mode_line)
11346 && !current_buffer->clip_changed
11347 && !current_buffer->prevent_redisplay_optimizations_p
11348 && FRAME_VISIBLE_P (XFRAME (w->frame))
11349 && !FRAME_OBSCURED_P (XFRAME (w->frame))
11350 /* Make sure recorded data applies to current buffer, etc. */
11351 && this_line_buffer == current_buffer
11352 && current_buffer == XBUFFER (w->buffer)
11353 && NILP (w->force_start)
11354 && NILP (w->optional_new_start)
11355 /* Point must be on the line that we have info recorded about. */
11356 && PT >= CHARPOS (tlbufpos)
11357 && PT <= Z - CHARPOS (tlendpos)
11358 /* All text outside that line, including its final newline,
11359 must be unchanged */
11360 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
11361 CHARPOS (tlendpos)))
11363 if (CHARPOS (tlbufpos) > BEGV
11364 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
11365 && (CHARPOS (tlbufpos) == ZV
11366 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
11367 /* Former continuation line has disappeared by becoming empty */
11368 goto cancel;
11369 else if (XFASTINT (w->last_modified) < MODIFF
11370 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
11371 || MINI_WINDOW_P (w))
11373 /* We have to handle the case of continuation around a
11374 wide-column character (See the comment in indent.c around
11375 line 885).
11377 For instance, in the following case:
11379 -------- Insert --------
11380 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
11381 J_I_ ==> J_I_ `^^' are cursors.
11382 ^^ ^^
11383 -------- --------
11385 As we have to redraw the line above, we should goto cancel. */
11387 struct it it;
11388 int line_height_before = this_line_pixel_height;
11390 /* Note that start_display will handle the case that the
11391 line starting at tlbufpos is a continuation lines. */
11392 start_display (&it, w, tlbufpos);
11394 /* Implementation note: It this still necessary? */
11395 if (it.current_x != this_line_start_x)
11396 goto cancel;
11398 TRACE ((stderr, "trying display optimization 1\n"));
11399 w->cursor.vpos = -1;
11400 overlay_arrow_seen = 0;
11401 it.vpos = this_line_vpos;
11402 it.current_y = this_line_y;
11403 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
11404 display_line (&it);
11406 /* If line contains point, is not continued,
11407 and ends at same distance from eob as before, we win */
11408 if (w->cursor.vpos >= 0
11409 /* Line is not continued, otherwise this_line_start_pos
11410 would have been set to 0 in display_line. */
11411 && CHARPOS (this_line_start_pos)
11412 /* Line ends as before. */
11413 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
11414 /* Line has same height as before. Otherwise other lines
11415 would have to be shifted up or down. */
11416 && this_line_pixel_height == line_height_before)
11418 /* If this is not the window's last line, we must adjust
11419 the charstarts of the lines below. */
11420 if (it.current_y < it.last_visible_y)
11422 struct glyph_row *row
11423 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
11424 int delta, delta_bytes;
11426 if (Z - CHARPOS (tlendpos) == ZV)
11428 /* This line ends at end of (accessible part of)
11429 buffer. There is no newline to count. */
11430 delta = (Z
11431 - CHARPOS (tlendpos)
11432 - MATRIX_ROW_START_CHARPOS (row));
11433 delta_bytes = (Z_BYTE
11434 - BYTEPOS (tlendpos)
11435 - MATRIX_ROW_START_BYTEPOS (row));
11437 else
11439 /* This line ends in a newline. Must take
11440 account of the newline and the rest of the
11441 text that follows. */
11442 delta = (Z
11443 - CHARPOS (tlendpos)
11444 - MATRIX_ROW_START_CHARPOS (row));
11445 delta_bytes = (Z_BYTE
11446 - BYTEPOS (tlendpos)
11447 - MATRIX_ROW_START_BYTEPOS (row));
11450 increment_matrix_positions (w->current_matrix,
11451 this_line_vpos + 1,
11452 w->current_matrix->nrows,
11453 delta, delta_bytes);
11456 /* If this row displays text now but previously didn't,
11457 or vice versa, w->window_end_vpos may have to be
11458 adjusted. */
11459 if ((it.glyph_row - 1)->displays_text_p)
11461 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
11462 XSETINT (w->window_end_vpos, this_line_vpos);
11464 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
11465 && this_line_vpos > 0)
11466 XSETINT (w->window_end_vpos, this_line_vpos - 1);
11467 w->window_end_valid = Qnil;
11469 /* Update hint: No need to try to scroll in update_window. */
11470 w->desired_matrix->no_scrolling_p = 1;
11472 #if GLYPH_DEBUG
11473 *w->desired_matrix->method = 0;
11474 debug_method_add (w, "optimization 1");
11475 #endif
11476 #ifdef HAVE_WINDOW_SYSTEM
11477 update_window_fringes (w, 0);
11478 #endif
11479 goto update;
11481 else
11482 goto cancel;
11484 else if (/* Cursor position hasn't changed. */
11485 PT == XFASTINT (w->last_point)
11486 /* Make sure the cursor was last displayed
11487 in this window. Otherwise we have to reposition it. */
11488 && 0 <= w->cursor.vpos
11489 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
11491 if (!must_finish)
11493 do_pending_window_change (1);
11495 /* We used to always goto end_of_redisplay here, but this
11496 isn't enough if we have a blinking cursor. */
11497 if (w->cursor_off_p == w->last_cursor_off_p)
11498 goto end_of_redisplay;
11500 goto update;
11502 /* If highlighting the region, or if the cursor is in the echo area,
11503 then we can't just move the cursor. */
11504 else if (! (!NILP (Vtransient_mark_mode)
11505 && !NILP (current_buffer->mark_active))
11506 && (EQ (selected_window, current_buffer->last_selected_window)
11507 || highlight_nonselected_windows)
11508 && NILP (w->region_showing)
11509 && NILP (Vshow_trailing_whitespace)
11510 && !cursor_in_echo_area)
11512 struct it it;
11513 struct glyph_row *row;
11515 /* Skip from tlbufpos to PT and see where it is. Note that
11516 PT may be in invisible text. If so, we will end at the
11517 next visible position. */
11518 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
11519 NULL, DEFAULT_FACE_ID);
11520 it.current_x = this_line_start_x;
11521 it.current_y = this_line_y;
11522 it.vpos = this_line_vpos;
11524 /* The call to move_it_to stops in front of PT, but
11525 moves over before-strings. */
11526 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
11528 if (it.vpos == this_line_vpos
11529 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
11530 row->enabled_p))
11532 xassert (this_line_vpos == it.vpos);
11533 xassert (this_line_y == it.current_y);
11534 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11535 #if GLYPH_DEBUG
11536 *w->desired_matrix->method = 0;
11537 debug_method_add (w, "optimization 3");
11538 #endif
11539 goto update;
11541 else
11542 goto cancel;
11545 cancel:
11546 /* Text changed drastically or point moved off of line. */
11547 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
11550 CHARPOS (this_line_start_pos) = 0;
11551 consider_all_windows_p |= buffer_shared > 1;
11552 ++clear_face_cache_count;
11553 #ifdef HAVE_WINDOW_SYSTEM
11554 ++clear_image_cache_count;
11555 #endif
11557 /* Build desired matrices, and update the display. If
11558 consider_all_windows_p is non-zero, do it for all windows on all
11559 frames. Otherwise do it for selected_window, only. */
11561 if (consider_all_windows_p)
11563 Lisp_Object tail, frame;
11565 FOR_EACH_FRAME (tail, frame)
11566 XFRAME (frame)->updated_p = 0;
11568 /* Recompute # windows showing selected buffer. This will be
11569 incremented each time such a window is displayed. */
11570 buffer_shared = 0;
11572 FOR_EACH_FRAME (tail, frame)
11574 struct frame *f = XFRAME (frame);
11576 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
11578 if (! EQ (frame, selected_frame))
11579 /* Select the frame, for the sake of frame-local
11580 variables. */
11581 select_frame_for_redisplay (frame);
11583 /* Mark all the scroll bars to be removed; we'll redeem
11584 the ones we want when we redisplay their windows. */
11585 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
11586 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
11588 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
11589 redisplay_windows (FRAME_ROOT_WINDOW (f));
11591 /* Any scroll bars which redisplay_windows should have
11592 nuked should now go away. */
11593 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
11594 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
11596 /* If fonts changed, display again. */
11597 /* ??? rms: I suspect it is a mistake to jump all the way
11598 back to retry here. It should just retry this frame. */
11599 if (fonts_changed_p)
11600 goto retry;
11602 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
11604 /* See if we have to hscroll. */
11605 if (!f->already_hscrolled_p)
11607 f->already_hscrolled_p = 1;
11608 if (hscroll_windows (f->root_window))
11609 goto retry;
11612 /* Prevent various kinds of signals during display
11613 update. stdio is not robust about handling
11614 signals, which can cause an apparent I/O
11615 error. */
11616 if (interrupt_input)
11617 unrequest_sigio ();
11618 STOP_POLLING;
11620 /* Update the display. */
11621 set_window_update_flags (XWINDOW (f->root_window), 1);
11622 pause |= update_frame (f, 0, 0);
11623 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
11624 if (pause)
11625 break;
11626 #endif
11628 f->updated_p = 1;
11633 if (!EQ (old_frame, selected_frame)
11634 && FRAME_LIVE_P (XFRAME (old_frame)))
11635 /* We played a bit fast-and-loose above and allowed selected_frame
11636 and selected_window to be temporarily out-of-sync but let's make
11637 sure this stays contained. */
11638 select_frame_for_redisplay (old_frame);
11639 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
11641 if (!pause)
11643 /* Do the mark_window_display_accurate after all windows have
11644 been redisplayed because this call resets flags in buffers
11645 which are needed for proper redisplay. */
11646 FOR_EACH_FRAME (tail, frame)
11648 struct frame *f = XFRAME (frame);
11649 if (f->updated_p)
11651 mark_window_display_accurate (f->root_window, 1);
11652 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
11653 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
11658 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
11660 Lisp_Object mini_window;
11661 struct frame *mini_frame;
11663 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
11664 /* Use list_of_error, not Qerror, so that
11665 we catch only errors and don't run the debugger. */
11666 internal_condition_case_1 (redisplay_window_1, selected_window,
11667 list_of_error,
11668 redisplay_window_error);
11670 /* Compare desired and current matrices, perform output. */
11672 update:
11673 /* If fonts changed, display again. */
11674 if (fonts_changed_p)
11675 goto retry;
11677 /* Prevent various kinds of signals during display update.
11678 stdio is not robust about handling signals,
11679 which can cause an apparent I/O error. */
11680 if (interrupt_input)
11681 unrequest_sigio ();
11682 STOP_POLLING;
11684 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
11686 if (hscroll_windows (selected_window))
11687 goto retry;
11689 XWINDOW (selected_window)->must_be_updated_p = 1;
11690 pause = update_frame (sf, 0, 0);
11693 /* We may have called echo_area_display at the top of this
11694 function. If the echo area is on another frame, that may
11695 have put text on a frame other than the selected one, so the
11696 above call to update_frame would not have caught it. Catch
11697 it here. */
11698 mini_window = FRAME_MINIBUF_WINDOW (sf);
11699 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
11701 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
11703 XWINDOW (mini_window)->must_be_updated_p = 1;
11704 pause |= update_frame (mini_frame, 0, 0);
11705 if (!pause && hscroll_windows (mini_window))
11706 goto retry;
11710 /* If display was paused because of pending input, make sure we do a
11711 thorough update the next time. */
11712 if (pause)
11714 /* Prevent the optimization at the beginning of
11715 redisplay_internal that tries a single-line update of the
11716 line containing the cursor in the selected window. */
11717 CHARPOS (this_line_start_pos) = 0;
11719 /* Let the overlay arrow be updated the next time. */
11720 update_overlay_arrows (0);
11722 /* If we pause after scrolling, some rows in the current
11723 matrices of some windows are not valid. */
11724 if (!WINDOW_FULL_WIDTH_P (w)
11725 && !FRAME_WINDOW_P (XFRAME (w->frame)))
11726 update_mode_lines = 1;
11728 else
11730 if (!consider_all_windows_p)
11732 /* This has already been done above if
11733 consider_all_windows_p is set. */
11734 mark_window_display_accurate_1 (w, 1);
11736 /* Say overlay arrows are up to date. */
11737 update_overlay_arrows (1);
11739 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
11740 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
11743 update_mode_lines = 0;
11744 windows_or_buffers_changed = 0;
11745 cursor_type_changed = 0;
11748 /* Start SIGIO interrupts coming again. Having them off during the
11749 code above makes it less likely one will discard output, but not
11750 impossible, since there might be stuff in the system buffer here.
11751 But it is much hairier to try to do anything about that. */
11752 if (interrupt_input)
11753 request_sigio ();
11754 RESUME_POLLING;
11756 /* If a frame has become visible which was not before, redisplay
11757 again, so that we display it. Expose events for such a frame
11758 (which it gets when becoming visible) don't call the parts of
11759 redisplay constructing glyphs, so simply exposing a frame won't
11760 display anything in this case. So, we have to display these
11761 frames here explicitly. */
11762 if (!pause)
11764 Lisp_Object tail, frame;
11765 int new_count = 0;
11767 FOR_EACH_FRAME (tail, frame)
11769 int this_is_visible = 0;
11771 if (XFRAME (frame)->visible)
11772 this_is_visible = 1;
11773 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
11774 if (XFRAME (frame)->visible)
11775 this_is_visible = 1;
11777 if (this_is_visible)
11778 new_count++;
11781 if (new_count != number_of_visible_frames)
11782 windows_or_buffers_changed++;
11785 /* Change frame size now if a change is pending. */
11786 do_pending_window_change (1);
11788 /* If we just did a pending size change, or have additional
11789 visible frames, redisplay again. */
11790 if (windows_or_buffers_changed && !pause)
11791 goto retry;
11793 /* Clear the face cache eventually. */
11794 if (consider_all_windows_p)
11796 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
11798 clear_face_cache (0);
11799 clear_face_cache_count = 0;
11801 #ifdef HAVE_WINDOW_SYSTEM
11802 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
11804 clear_image_caches (Qnil);
11805 clear_image_cache_count = 0;
11807 #endif /* HAVE_WINDOW_SYSTEM */
11810 end_of_redisplay:
11811 unbind_to (count, Qnil);
11812 RESUME_POLLING;
11816 /* Redisplay, but leave alone any recent echo area message unless
11817 another message has been requested in its place.
11819 This is useful in situations where you need to redisplay but no
11820 user action has occurred, making it inappropriate for the message
11821 area to be cleared. See tracking_off and
11822 wait_reading_process_output for examples of these situations.
11824 FROM_WHERE is an integer saying from where this function was
11825 called. This is useful for debugging. */
11827 void
11828 redisplay_preserve_echo_area (from_where)
11829 int from_where;
11831 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
11833 if (!NILP (echo_area_buffer[1]))
11835 /* We have a previously displayed message, but no current
11836 message. Redisplay the previous message. */
11837 display_last_displayed_message_p = 1;
11838 redisplay_internal (1);
11839 display_last_displayed_message_p = 0;
11841 else
11842 redisplay_internal (1);
11844 if (FRAME_RIF (SELECTED_FRAME ()) != NULL
11845 && FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
11846 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (NULL);
11850 /* Function registered with record_unwind_protect in
11851 redisplay_internal. Reset redisplaying_p to the value it had
11852 before redisplay_internal was called, and clear
11853 prevent_freeing_realized_faces_p. It also selects the previously
11854 selected frame, unless it has been deleted (by an X connection
11855 failure during redisplay, for example). */
11857 static Lisp_Object
11858 unwind_redisplay (val)
11859 Lisp_Object val;
11861 Lisp_Object old_redisplaying_p, old_frame;
11863 old_redisplaying_p = XCAR (val);
11864 redisplaying_p = XFASTINT (old_redisplaying_p);
11865 old_frame = XCDR (val);
11866 if (! EQ (old_frame, selected_frame)
11867 && FRAME_LIVE_P (XFRAME (old_frame)))
11868 select_frame_for_redisplay (old_frame);
11869 return Qnil;
11873 /* Mark the display of window W as accurate or inaccurate. If
11874 ACCURATE_P is non-zero mark display of W as accurate. If
11875 ACCURATE_P is zero, arrange for W to be redisplayed the next time
11876 redisplay_internal is called. */
11878 static void
11879 mark_window_display_accurate_1 (w, accurate_p)
11880 struct window *w;
11881 int accurate_p;
11883 if (BUFFERP (w->buffer))
11885 struct buffer *b = XBUFFER (w->buffer);
11887 w->last_modified
11888 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
11889 w->last_overlay_modified
11890 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
11891 w->last_had_star
11892 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
11894 if (accurate_p)
11896 b->clip_changed = 0;
11897 b->prevent_redisplay_optimizations_p = 0;
11899 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
11900 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
11901 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
11902 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
11904 w->current_matrix->buffer = b;
11905 w->current_matrix->begv = BUF_BEGV (b);
11906 w->current_matrix->zv = BUF_ZV (b);
11908 w->last_cursor = w->cursor;
11909 w->last_cursor_off_p = w->cursor_off_p;
11911 if (w == XWINDOW (selected_window))
11912 w->last_point = make_number (BUF_PT (b));
11913 else
11914 w->last_point = make_number (XMARKER (w->pointm)->charpos);
11918 if (accurate_p)
11920 w->window_end_valid = w->buffer;
11921 #if 0 /* This is incorrect with variable-height lines. */
11922 xassert (XINT (w->window_end_vpos)
11923 < (WINDOW_TOTAL_LINES (w)
11924 - (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
11925 #endif
11926 w->update_mode_line = Qnil;
11931 /* Mark the display of windows in the window tree rooted at WINDOW as
11932 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
11933 windows as accurate. If ACCURATE_P is zero, arrange for windows to
11934 be redisplayed the next time redisplay_internal is called. */
11936 void
11937 mark_window_display_accurate (window, accurate_p)
11938 Lisp_Object window;
11939 int accurate_p;
11941 struct window *w;
11943 for (; !NILP (window); window = w->next)
11945 w = XWINDOW (window);
11946 mark_window_display_accurate_1 (w, accurate_p);
11948 if (!NILP (w->vchild))
11949 mark_window_display_accurate (w->vchild, accurate_p);
11950 if (!NILP (w->hchild))
11951 mark_window_display_accurate (w->hchild, accurate_p);
11954 if (accurate_p)
11956 update_overlay_arrows (1);
11958 else
11960 /* Force a thorough redisplay the next time by setting
11961 last_arrow_position and last_arrow_string to t, which is
11962 unequal to any useful value of Voverlay_arrow_... */
11963 update_overlay_arrows (-1);
11968 /* Return value in display table DP (Lisp_Char_Table *) for character
11969 C. Since a display table doesn't have any parent, we don't have to
11970 follow parent. Do not call this function directly but use the
11971 macro DISP_CHAR_VECTOR. */
11973 Lisp_Object
11974 disp_char_vector (dp, c)
11975 struct Lisp_Char_Table *dp;
11976 int c;
11978 Lisp_Object val;
11980 if (ASCII_CHAR_P (c))
11982 val = dp->ascii;
11983 if (SUB_CHAR_TABLE_P (val))
11984 val = XSUB_CHAR_TABLE (val)->contents[c];
11986 else
11988 Lisp_Object table;
11990 XSETCHAR_TABLE (table, dp);
11991 val = char_table_ref (table, c);
11993 if (NILP (val))
11994 val = dp->defalt;
11995 return val;
12000 /***********************************************************************
12001 Window Redisplay
12002 ***********************************************************************/
12004 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
12006 static void
12007 redisplay_windows (window)
12008 Lisp_Object window;
12010 while (!NILP (window))
12012 struct window *w = XWINDOW (window);
12014 if (!NILP (w->hchild))
12015 redisplay_windows (w->hchild);
12016 else if (!NILP (w->vchild))
12017 redisplay_windows (w->vchild);
12018 else
12020 displayed_buffer = XBUFFER (w->buffer);
12021 /* Use list_of_error, not Qerror, so that
12022 we catch only errors and don't run the debugger. */
12023 internal_condition_case_1 (redisplay_window_0, window,
12024 list_of_error,
12025 redisplay_window_error);
12028 window = w->next;
12032 static Lisp_Object
12033 redisplay_window_error ()
12035 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
12036 return Qnil;
12039 static Lisp_Object
12040 redisplay_window_0 (window)
12041 Lisp_Object window;
12043 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
12044 redisplay_window (window, 0);
12045 return Qnil;
12048 static Lisp_Object
12049 redisplay_window_1 (window)
12050 Lisp_Object window;
12052 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
12053 redisplay_window (window, 1);
12054 return Qnil;
12058 /* Increment GLYPH until it reaches END or CONDITION fails while
12059 adding (GLYPH)->pixel_width to X. */
12061 #define SKIP_GLYPHS(glyph, end, x, condition) \
12062 do \
12064 (x) += (glyph)->pixel_width; \
12065 ++(glyph); \
12067 while ((glyph) < (end) && (condition))
12070 /* Set cursor position of W. PT is assumed to be displayed in ROW.
12071 DELTA is the number of bytes by which positions recorded in ROW
12072 differ from current buffer positions.
12074 Return 0 if cursor is not on this row. 1 otherwise. */
12077 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
12078 struct window *w;
12079 struct glyph_row *row;
12080 struct glyph_matrix *matrix;
12081 int delta, delta_bytes, dy, dvpos;
12083 struct glyph *glyph = row->glyphs[TEXT_AREA];
12084 struct glyph *end = glyph + row->used[TEXT_AREA];
12085 struct glyph *cursor = NULL;
12086 /* The first glyph that starts a sequence of glyphs from string. */
12087 struct glyph *string_start;
12088 /* The X coordinate of string_start. */
12089 int string_start_x;
12090 /* The last known character position. */
12091 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
12092 /* The last known character position before string_start. */
12093 int string_before_pos;
12094 int x = row->x;
12095 int cursor_x = x;
12096 int cursor_from_overlay_pos = 0;
12097 int pt_old = PT - delta;
12099 /* Skip over glyphs not having an object at the start of the row.
12100 These are special glyphs like truncation marks on terminal
12101 frames. */
12102 if (row->displays_text_p)
12103 while (glyph < end
12104 && INTEGERP (glyph->object)
12105 && glyph->charpos < 0)
12107 x += glyph->pixel_width;
12108 ++glyph;
12111 string_start = NULL;
12112 while (glyph < end
12113 && !INTEGERP (glyph->object)
12114 && (!BUFFERP (glyph->object)
12115 || (last_pos = glyph->charpos) < pt_old))
12117 if (! STRINGP (glyph->object))
12119 string_start = NULL;
12120 x += glyph->pixel_width;
12121 ++glyph;
12122 if (cursor_from_overlay_pos
12123 && last_pos >= cursor_from_overlay_pos)
12125 cursor_from_overlay_pos = 0;
12126 cursor = 0;
12129 else
12131 if (string_start == NULL)
12133 string_before_pos = last_pos;
12134 string_start = glyph;
12135 string_start_x = x;
12137 /* Skip all glyphs from string. */
12140 Lisp_Object cprop;
12141 int pos;
12142 if ((cursor == NULL || glyph > cursor)
12143 && (cprop = Fget_char_property (make_number ((glyph)->charpos),
12144 Qcursor, (glyph)->object),
12145 !NILP (cprop))
12146 && (pos = string_buffer_position (w, glyph->object,
12147 string_before_pos),
12148 (pos == 0 /* From overlay */
12149 || pos == pt_old)))
12151 /* Estimate overlay buffer position from the buffer
12152 positions of the glyphs before and after the overlay.
12153 Add 1 to last_pos so that if point corresponds to the
12154 glyph right after the overlay, we still use a 'cursor'
12155 property found in that overlay. */
12156 cursor_from_overlay_pos = (pos ? 0 : last_pos
12157 + (INTEGERP (cprop) ? XINT (cprop) : 0));
12158 cursor = glyph;
12159 cursor_x = x;
12161 x += glyph->pixel_width;
12162 ++glyph;
12164 while (glyph < end && EQ (glyph->object, string_start->object));
12168 if (cursor != NULL)
12170 glyph = cursor;
12171 x = cursor_x;
12173 else if (row->ends_in_ellipsis_p && glyph == end)
12175 /* Scan back over the ellipsis glyphs, decrementing positions. */
12176 while (glyph > row->glyphs[TEXT_AREA]
12177 && (glyph - 1)->charpos == last_pos)
12178 glyph--, x -= glyph->pixel_width;
12179 /* That loop always goes one position too far,
12180 including the glyph before the ellipsis.
12181 So scan forward over that one. */
12182 x += glyph->pixel_width;
12183 glyph++;
12185 else if (string_start
12186 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
12188 /* We may have skipped over point because the previous glyphs
12189 are from string. As there's no easy way to know the
12190 character position of the current glyph, find the correct
12191 glyph on point by scanning from string_start again. */
12192 Lisp_Object limit;
12193 Lisp_Object string;
12194 struct glyph *stop = glyph;
12195 int pos;
12197 limit = make_number (pt_old + 1);
12198 glyph = string_start;
12199 x = string_start_x;
12200 string = glyph->object;
12201 pos = string_buffer_position (w, string, string_before_pos);
12202 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
12203 because we always put cursor after overlay strings. */
12204 while (pos == 0 && glyph < stop)
12206 string = glyph->object;
12207 SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string));
12208 if (glyph < stop)
12209 pos = string_buffer_position (w, glyph->object, string_before_pos);
12212 while (glyph < stop)
12214 pos = XINT (Fnext_single_char_property_change
12215 (make_number (pos), Qdisplay, Qnil, limit));
12216 if (pos > pt_old)
12217 break;
12218 /* Skip glyphs from the same string. */
12219 string = glyph->object;
12220 SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string));
12221 /* Skip glyphs from an overlay. */
12222 while (glyph < stop
12223 && ! string_buffer_position (w, glyph->object, pos))
12225 string = glyph->object;
12226 SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string));
12230 /* If we reached the end of the line, and end was from a string,
12231 cursor is not on this line. */
12232 if (glyph == end && row->continued_p)
12233 return 0;
12236 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
12237 w->cursor.x = x;
12238 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
12239 w->cursor.y = row->y + dy;
12241 if (w == XWINDOW (selected_window))
12243 if (!row->continued_p
12244 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
12245 && row->x == 0)
12247 this_line_buffer = XBUFFER (w->buffer);
12249 CHARPOS (this_line_start_pos)
12250 = MATRIX_ROW_START_CHARPOS (row) + delta;
12251 BYTEPOS (this_line_start_pos)
12252 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
12254 CHARPOS (this_line_end_pos)
12255 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
12256 BYTEPOS (this_line_end_pos)
12257 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
12259 this_line_y = w->cursor.y;
12260 this_line_pixel_height = row->height;
12261 this_line_vpos = w->cursor.vpos;
12262 this_line_start_x = row->x;
12264 else
12265 CHARPOS (this_line_start_pos) = 0;
12268 return 1;
12272 /* Run window scroll functions, if any, for WINDOW with new window
12273 start STARTP. Sets the window start of WINDOW to that position.
12275 We assume that the window's buffer is really current. */
12277 static INLINE struct text_pos
12278 run_window_scroll_functions (window, startp)
12279 Lisp_Object window;
12280 struct text_pos startp;
12282 struct window *w = XWINDOW (window);
12283 SET_MARKER_FROM_TEXT_POS (w->start, startp);
12285 if (current_buffer != XBUFFER (w->buffer))
12286 abort ();
12288 if (!NILP (Vwindow_scroll_functions))
12290 run_hook_with_args_2 (Qwindow_scroll_functions, window,
12291 make_number (CHARPOS (startp)));
12292 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12293 /* In case the hook functions switch buffers. */
12294 if (current_buffer != XBUFFER (w->buffer))
12295 set_buffer_internal_1 (XBUFFER (w->buffer));
12298 return startp;
12302 /* Make sure the line containing the cursor is fully visible.
12303 A value of 1 means there is nothing to be done.
12304 (Either the line is fully visible, or it cannot be made so,
12305 or we cannot tell.)
12307 If FORCE_P is non-zero, return 0 even if partial visible cursor row
12308 is higher than window.
12310 A value of 0 means the caller should do scrolling
12311 as if point had gone off the screen. */
12313 static int
12314 cursor_row_fully_visible_p (w, force_p, current_matrix_p)
12315 struct window *w;
12316 int force_p;
12317 int current_matrix_p;
12319 struct glyph_matrix *matrix;
12320 struct glyph_row *row;
12321 int window_height;
12323 if (!make_cursor_line_fully_visible_p)
12324 return 1;
12326 /* It's not always possible to find the cursor, e.g, when a window
12327 is full of overlay strings. Don't do anything in that case. */
12328 if (w->cursor.vpos < 0)
12329 return 1;
12331 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
12332 row = MATRIX_ROW (matrix, w->cursor.vpos);
12334 /* If the cursor row is not partially visible, there's nothing to do. */
12335 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
12336 return 1;
12338 /* If the row the cursor is in is taller than the window's height,
12339 it's not clear what to do, so do nothing. */
12340 window_height = window_box_height (w);
12341 if (row->height >= window_height)
12343 if (!force_p || MINI_WINDOW_P (w)
12344 || w->vscroll || w->cursor.vpos == 0)
12345 return 1;
12347 return 0;
12349 #if 0
12350 /* This code used to try to scroll the window just enough to make
12351 the line visible. It returned 0 to say that the caller should
12352 allocate larger glyph matrices. */
12354 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
12356 int dy = row->height - row->visible_height;
12357 w->vscroll = 0;
12358 w->cursor.y += dy;
12359 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
12361 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
12363 int dy = - (row->height - row->visible_height);
12364 w->vscroll = dy;
12365 w->cursor.y += dy;
12366 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
12369 /* When we change the cursor y-position of the selected window,
12370 change this_line_y as well so that the display optimization for
12371 the cursor line of the selected window in redisplay_internal uses
12372 the correct y-position. */
12373 if (w == XWINDOW (selected_window))
12374 this_line_y = w->cursor.y;
12376 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
12377 redisplay with larger matrices. */
12378 if (matrix->nrows < required_matrix_height (w))
12380 fonts_changed_p = 1;
12381 return 0;
12384 return 1;
12385 #endif /* 0 */
12389 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
12390 non-zero means only WINDOW is redisplayed in redisplay_internal.
12391 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
12392 in redisplay_window to bring a partially visible line into view in
12393 the case that only the cursor has moved.
12395 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
12396 last screen line's vertical height extends past the end of the screen.
12398 Value is
12400 1 if scrolling succeeded
12402 0 if scrolling didn't find point.
12404 -1 if new fonts have been loaded so that we must interrupt
12405 redisplay, adjust glyph matrices, and try again. */
12407 enum
12409 SCROLLING_SUCCESS,
12410 SCROLLING_FAILED,
12411 SCROLLING_NEED_LARGER_MATRICES
12414 static int
12415 try_scrolling (window, just_this_one_p, scroll_conservatively,
12416 scroll_step, temp_scroll_step, last_line_misfit)
12417 Lisp_Object window;
12418 int just_this_one_p;
12419 EMACS_INT scroll_conservatively, scroll_step;
12420 int temp_scroll_step;
12421 int last_line_misfit;
12423 struct window *w = XWINDOW (window);
12424 struct frame *f = XFRAME (w->frame);
12425 struct text_pos scroll_margin_pos;
12426 struct text_pos pos;
12427 struct text_pos startp;
12428 struct it it;
12429 Lisp_Object window_end;
12430 int this_scroll_margin;
12431 int dy = 0;
12432 int scroll_max;
12433 int rc;
12434 int amount_to_scroll = 0;
12435 Lisp_Object aggressive;
12436 int height;
12437 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
12439 #if GLYPH_DEBUG
12440 debug_method_add (w, "try_scrolling");
12441 #endif
12443 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12445 /* Compute scroll margin height in pixels. We scroll when point is
12446 within this distance from the top or bottom of the window. */
12447 if (scroll_margin > 0)
12449 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
12450 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
12452 else
12453 this_scroll_margin = 0;
12455 /* Force scroll_conservatively to have a reasonable value so it doesn't
12456 cause an overflow while computing how much to scroll. */
12457 if (scroll_conservatively)
12458 scroll_conservatively = min (scroll_conservatively,
12459 MOST_POSITIVE_FIXNUM / FRAME_LINE_HEIGHT (f));
12461 /* Compute how much we should try to scroll maximally to bring point
12462 into view. */
12463 if (scroll_step || scroll_conservatively || temp_scroll_step)
12464 scroll_max = max (scroll_step,
12465 max (scroll_conservatively, temp_scroll_step));
12466 else if (NUMBERP (current_buffer->scroll_down_aggressively)
12467 || NUMBERP (current_buffer->scroll_up_aggressively))
12468 /* We're trying to scroll because of aggressive scrolling
12469 but no scroll_step is set. Choose an arbitrary one. Maybe
12470 there should be a variable for this. */
12471 scroll_max = 10;
12472 else
12473 scroll_max = 0;
12474 scroll_max *= FRAME_LINE_HEIGHT (f);
12476 /* Decide whether we have to scroll down. Start at the window end
12477 and move this_scroll_margin up to find the position of the scroll
12478 margin. */
12479 window_end = Fwindow_end (window, Qt);
12481 too_near_end:
12483 CHARPOS (scroll_margin_pos) = XINT (window_end);
12484 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
12486 if (this_scroll_margin || extra_scroll_margin_lines)
12488 start_display (&it, w, scroll_margin_pos);
12489 if (this_scroll_margin)
12490 move_it_vertically_backward (&it, this_scroll_margin);
12491 if (extra_scroll_margin_lines)
12492 move_it_by_lines (&it, - extra_scroll_margin_lines, 0);
12493 scroll_margin_pos = it.current.pos;
12496 if (PT >= CHARPOS (scroll_margin_pos))
12498 int y0;
12500 /* Point is in the scroll margin at the bottom of the window, or
12501 below. Compute a new window start that makes point visible. */
12503 /* Compute the distance from the scroll margin to PT.
12504 Give up if the distance is greater than scroll_max. */
12505 start_display (&it, w, scroll_margin_pos);
12506 y0 = it.current_y;
12507 move_it_to (&it, PT, 0, it.last_visible_y, -1,
12508 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
12510 /* To make point visible, we have to move the window start
12511 down so that the line the cursor is in is visible, which
12512 means we have to add in the height of the cursor line. */
12513 dy = line_bottom_y (&it) - y0;
12515 if (dy > scroll_max)
12516 return SCROLLING_FAILED;
12518 /* Move the window start down. If scrolling conservatively,
12519 move it just enough down to make point visible. If
12520 scroll_step is set, move it down by scroll_step. */
12521 start_display (&it, w, startp);
12523 if (scroll_conservatively)
12524 /* Set AMOUNT_TO_SCROLL to at least one line,
12525 and at most scroll_conservatively lines. */
12526 amount_to_scroll
12527 = min (max (dy, FRAME_LINE_HEIGHT (f)),
12528 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
12529 else if (scroll_step || temp_scroll_step)
12530 amount_to_scroll = scroll_max;
12531 else
12533 aggressive = current_buffer->scroll_up_aggressively;
12534 height = WINDOW_BOX_TEXT_HEIGHT (w);
12535 if (NUMBERP (aggressive))
12537 double float_amount = XFLOATINT (aggressive) * height;
12538 amount_to_scroll = float_amount;
12539 if (amount_to_scroll == 0 && float_amount > 0)
12540 amount_to_scroll = 1;
12544 if (amount_to_scroll <= 0)
12545 return SCROLLING_FAILED;
12547 /* If moving by amount_to_scroll leaves STARTP unchanged,
12548 move it down one screen line. */
12550 move_it_vertically (&it, amount_to_scroll);
12551 if (CHARPOS (it.current.pos) == CHARPOS (startp))
12552 move_it_by_lines (&it, 1, 1);
12553 startp = it.current.pos;
12555 else
12557 /* See if point is inside the scroll margin at the top of the
12558 window. */
12559 scroll_margin_pos = startp;
12560 if (this_scroll_margin)
12562 start_display (&it, w, startp);
12563 move_it_vertically (&it, this_scroll_margin);
12564 scroll_margin_pos = it.current.pos;
12567 if (PT < CHARPOS (scroll_margin_pos))
12569 /* Point is in the scroll margin at the top of the window or
12570 above what is displayed in the window. */
12571 int y0;
12573 /* Compute the vertical distance from PT to the scroll
12574 margin position. Give up if distance is greater than
12575 scroll_max. */
12576 SET_TEXT_POS (pos, PT, PT_BYTE);
12577 start_display (&it, w, pos);
12578 y0 = it.current_y;
12579 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
12580 it.last_visible_y, -1,
12581 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
12582 dy = it.current_y - y0;
12583 if (dy > scroll_max)
12584 return SCROLLING_FAILED;
12586 /* Compute new window start. */
12587 start_display (&it, w, startp);
12589 if (scroll_conservatively)
12590 amount_to_scroll
12591 = max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
12592 else if (scroll_step || temp_scroll_step)
12593 amount_to_scroll = scroll_max;
12594 else
12596 aggressive = current_buffer->scroll_down_aggressively;
12597 height = WINDOW_BOX_TEXT_HEIGHT (w);
12598 if (NUMBERP (aggressive))
12600 double float_amount = XFLOATINT (aggressive) * height;
12601 amount_to_scroll = float_amount;
12602 if (amount_to_scroll == 0 && float_amount > 0)
12603 amount_to_scroll = 1;
12607 if (amount_to_scroll <= 0)
12608 return SCROLLING_FAILED;
12610 move_it_vertically_backward (&it, amount_to_scroll);
12611 startp = it.current.pos;
12615 /* Run window scroll functions. */
12616 startp = run_window_scroll_functions (window, startp);
12618 /* Display the window. Give up if new fonts are loaded, or if point
12619 doesn't appear. */
12620 if (!try_window (window, startp, 0))
12621 rc = SCROLLING_NEED_LARGER_MATRICES;
12622 else if (w->cursor.vpos < 0)
12624 clear_glyph_matrix (w->desired_matrix);
12625 rc = SCROLLING_FAILED;
12627 else
12629 /* Maybe forget recorded base line for line number display. */
12630 if (!just_this_one_p
12631 || current_buffer->clip_changed
12632 || BEG_UNCHANGED < CHARPOS (startp))
12633 w->base_line_number = Qnil;
12635 /* If cursor ends up on a partially visible line,
12636 treat that as being off the bottom of the screen. */
12637 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0))
12639 clear_glyph_matrix (w->desired_matrix);
12640 ++extra_scroll_margin_lines;
12641 goto too_near_end;
12643 rc = SCROLLING_SUCCESS;
12646 return rc;
12650 /* Compute a suitable window start for window W if display of W starts
12651 on a continuation line. Value is non-zero if a new window start
12652 was computed.
12654 The new window start will be computed, based on W's width, starting
12655 from the start of the continued line. It is the start of the
12656 screen line with the minimum distance from the old start W->start. */
12658 static int
12659 compute_window_start_on_continuation_line (w)
12660 struct window *w;
12662 struct text_pos pos, start_pos;
12663 int window_start_changed_p = 0;
12665 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
12667 /* If window start is on a continuation line... Window start may be
12668 < BEGV in case there's invisible text at the start of the
12669 buffer (M-x rmail, for example). */
12670 if (CHARPOS (start_pos) > BEGV
12671 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
12673 struct it it;
12674 struct glyph_row *row;
12676 /* Handle the case that the window start is out of range. */
12677 if (CHARPOS (start_pos) < BEGV)
12678 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
12679 else if (CHARPOS (start_pos) > ZV)
12680 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
12682 /* Find the start of the continued line. This should be fast
12683 because scan_buffer is fast (newline cache). */
12684 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
12685 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
12686 row, DEFAULT_FACE_ID);
12687 reseat_at_previous_visible_line_start (&it);
12689 /* If the line start is "too far" away from the window start,
12690 say it takes too much time to compute a new window start. */
12691 if (CHARPOS (start_pos) - IT_CHARPOS (it)
12692 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
12694 int min_distance, distance;
12696 /* Move forward by display lines to find the new window
12697 start. If window width was enlarged, the new start can
12698 be expected to be > the old start. If window width was
12699 decreased, the new window start will be < the old start.
12700 So, we're looking for the display line start with the
12701 minimum distance from the old window start. */
12702 pos = it.current.pos;
12703 min_distance = INFINITY;
12704 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
12705 distance < min_distance)
12707 min_distance = distance;
12708 pos = it.current.pos;
12709 move_it_by_lines (&it, 1, 0);
12712 /* Set the window start there. */
12713 SET_MARKER_FROM_TEXT_POS (w->start, pos);
12714 window_start_changed_p = 1;
12718 return window_start_changed_p;
12722 /* Try cursor movement in case text has not changed in window WINDOW,
12723 with window start STARTP. Value is
12725 CURSOR_MOVEMENT_SUCCESS if successful
12727 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
12729 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
12730 display. *SCROLL_STEP is set to 1, under certain circumstances, if
12731 we want to scroll as if scroll-step were set to 1. See the code.
12733 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
12734 which case we have to abort this redisplay, and adjust matrices
12735 first. */
12737 enum
12739 CURSOR_MOVEMENT_SUCCESS,
12740 CURSOR_MOVEMENT_CANNOT_BE_USED,
12741 CURSOR_MOVEMENT_MUST_SCROLL,
12742 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
12745 static int
12746 try_cursor_movement (window, startp, scroll_step)
12747 Lisp_Object window;
12748 struct text_pos startp;
12749 int *scroll_step;
12751 struct window *w = XWINDOW (window);
12752 struct frame *f = XFRAME (w->frame);
12753 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
12755 #if GLYPH_DEBUG
12756 if (inhibit_try_cursor_movement)
12757 return rc;
12758 #endif
12760 /* Handle case where text has not changed, only point, and it has
12761 not moved off the frame. */
12762 if (/* Point may be in this window. */
12763 PT >= CHARPOS (startp)
12764 /* Selective display hasn't changed. */
12765 && !current_buffer->clip_changed
12766 /* Function force-mode-line-update is used to force a thorough
12767 redisplay. It sets either windows_or_buffers_changed or
12768 update_mode_lines. So don't take a shortcut here for these
12769 cases. */
12770 && !update_mode_lines
12771 && !windows_or_buffers_changed
12772 && !cursor_type_changed
12773 /* Can't use this case if highlighting a region. When a
12774 region exists, cursor movement has to do more than just
12775 set the cursor. */
12776 && !(!NILP (Vtransient_mark_mode)
12777 && !NILP (current_buffer->mark_active))
12778 && NILP (w->region_showing)
12779 && NILP (Vshow_trailing_whitespace)
12780 /* Right after splitting windows, last_point may be nil. */
12781 && INTEGERP (w->last_point)
12782 /* This code is not used for mini-buffer for the sake of the case
12783 of redisplaying to replace an echo area message; since in
12784 that case the mini-buffer contents per se are usually
12785 unchanged. This code is of no real use in the mini-buffer
12786 since the handling of this_line_start_pos, etc., in redisplay
12787 handles the same cases. */
12788 && !EQ (window, minibuf_window)
12789 /* When splitting windows or for new windows, it happens that
12790 redisplay is called with a nil window_end_vpos or one being
12791 larger than the window. This should really be fixed in
12792 window.c. I don't have this on my list, now, so we do
12793 approximately the same as the old redisplay code. --gerd. */
12794 && INTEGERP (w->window_end_vpos)
12795 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
12796 && (FRAME_WINDOW_P (f)
12797 || !overlay_arrow_in_current_buffer_p ()))
12799 int this_scroll_margin, top_scroll_margin;
12800 struct glyph_row *row = NULL;
12802 #if GLYPH_DEBUG
12803 debug_method_add (w, "cursor movement");
12804 #endif
12806 /* Scroll if point within this distance from the top or bottom
12807 of the window. This is a pixel value. */
12808 this_scroll_margin = max (0, scroll_margin);
12809 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
12810 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
12812 top_scroll_margin = this_scroll_margin;
12813 if (WINDOW_WANTS_HEADER_LINE_P (w))
12814 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
12816 /* Start with the row the cursor was displayed during the last
12817 not paused redisplay. Give up if that row is not valid. */
12818 if (w->last_cursor.vpos < 0
12819 || w->last_cursor.vpos >= w->current_matrix->nrows)
12820 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12821 else
12823 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
12824 if (row->mode_line_p)
12825 ++row;
12826 if (!row->enabled_p)
12827 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12830 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
12832 int scroll_p = 0;
12833 int last_y = window_text_bottom_y (w) - this_scroll_margin;
12835 if (PT > XFASTINT (w->last_point))
12837 /* Point has moved forward. */
12838 while (MATRIX_ROW_END_CHARPOS (row) < PT
12839 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
12841 xassert (row->enabled_p);
12842 ++row;
12845 /* The end position of a row equals the start position
12846 of the next row. If PT is there, we would rather
12847 display it in the next line. */
12848 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
12849 && MATRIX_ROW_END_CHARPOS (row) == PT
12850 && !cursor_row_p (w, row))
12851 ++row;
12853 /* If within the scroll margin, scroll. Note that
12854 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
12855 the next line would be drawn, and that
12856 this_scroll_margin can be zero. */
12857 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
12858 || PT > MATRIX_ROW_END_CHARPOS (row)
12859 /* Line is completely visible last line in window
12860 and PT is to be set in the next line. */
12861 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
12862 && PT == MATRIX_ROW_END_CHARPOS (row)
12863 && !row->ends_at_zv_p
12864 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
12865 scroll_p = 1;
12867 else if (PT < XFASTINT (w->last_point))
12869 /* Cursor has to be moved backward. Note that PT >=
12870 CHARPOS (startp) because of the outer if-statement. */
12871 while (!row->mode_line_p
12872 && (MATRIX_ROW_START_CHARPOS (row) > PT
12873 || (MATRIX_ROW_START_CHARPOS (row) == PT
12874 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
12875 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
12876 row > w->current_matrix->rows
12877 && (row-1)->ends_in_newline_from_string_p))))
12878 && (row->y > top_scroll_margin
12879 || CHARPOS (startp) == BEGV))
12881 xassert (row->enabled_p);
12882 --row;
12885 /* Consider the following case: Window starts at BEGV,
12886 there is invisible, intangible text at BEGV, so that
12887 display starts at some point START > BEGV. It can
12888 happen that we are called with PT somewhere between
12889 BEGV and START. Try to handle that case. */
12890 if (row < w->current_matrix->rows
12891 || row->mode_line_p)
12893 row = w->current_matrix->rows;
12894 if (row->mode_line_p)
12895 ++row;
12898 /* Due to newlines in overlay strings, we may have to
12899 skip forward over overlay strings. */
12900 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
12901 && MATRIX_ROW_END_CHARPOS (row) == PT
12902 && !cursor_row_p (w, row))
12903 ++row;
12905 /* If within the scroll margin, scroll. */
12906 if (row->y < top_scroll_margin
12907 && CHARPOS (startp) != BEGV)
12908 scroll_p = 1;
12910 else
12912 /* Cursor did not move. So don't scroll even if cursor line
12913 is partially visible, as it was so before. */
12914 rc = CURSOR_MOVEMENT_SUCCESS;
12917 if (PT < MATRIX_ROW_START_CHARPOS (row)
12918 || PT > MATRIX_ROW_END_CHARPOS (row))
12920 /* if PT is not in the glyph row, give up. */
12921 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12923 else if (rc != CURSOR_MOVEMENT_SUCCESS
12924 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
12925 && make_cursor_line_fully_visible_p)
12927 if (PT == MATRIX_ROW_END_CHARPOS (row)
12928 && !row->ends_at_zv_p
12929 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
12930 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12931 else if (row->height > window_box_height (w))
12933 /* If we end up in a partially visible line, let's
12934 make it fully visible, except when it's taller
12935 than the window, in which case we can't do much
12936 about it. */
12937 *scroll_step = 1;
12938 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12940 else
12942 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
12943 if (!cursor_row_fully_visible_p (w, 0, 1))
12944 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12945 else
12946 rc = CURSOR_MOVEMENT_SUCCESS;
12949 else if (scroll_p)
12950 rc = CURSOR_MOVEMENT_MUST_SCROLL;
12951 else
12955 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
12957 rc = CURSOR_MOVEMENT_SUCCESS;
12958 break;
12960 ++row;
12962 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
12963 && MATRIX_ROW_START_CHARPOS (row) == PT
12964 && cursor_row_p (w, row));
12969 return rc;
12972 void
12973 set_vertical_scroll_bar (w)
12974 struct window *w;
12976 int start, end, whole;
12978 /* Calculate the start and end positions for the current window.
12979 At some point, it would be nice to choose between scrollbars
12980 which reflect the whole buffer size, with special markers
12981 indicating narrowing, and scrollbars which reflect only the
12982 visible region.
12984 Note that mini-buffers sometimes aren't displaying any text. */
12985 if (!MINI_WINDOW_P (w)
12986 || (w == XWINDOW (minibuf_window)
12987 && NILP (echo_area_buffer[0])))
12989 struct buffer *buf = XBUFFER (w->buffer);
12990 whole = BUF_ZV (buf) - BUF_BEGV (buf);
12991 start = marker_position (w->start) - BUF_BEGV (buf);
12992 /* I don't think this is guaranteed to be right. For the
12993 moment, we'll pretend it is. */
12994 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
12996 if (end < start)
12997 end = start;
12998 if (whole < (end - start))
12999 whole = end - start;
13001 else
13002 start = end = whole = 0;
13004 /* Indicate what this scroll bar ought to be displaying now. */
13005 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
13006 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
13007 (w, end - start, whole, start);
13011 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
13012 selected_window is redisplayed.
13014 We can return without actually redisplaying the window if
13015 fonts_changed_p is nonzero. In that case, redisplay_internal will
13016 retry. */
13018 static void
13019 redisplay_window (window, just_this_one_p)
13020 Lisp_Object window;
13021 int just_this_one_p;
13023 struct window *w = XWINDOW (window);
13024 struct frame *f = XFRAME (w->frame);
13025 struct buffer *buffer = XBUFFER (w->buffer);
13026 struct buffer *old = current_buffer;
13027 struct text_pos lpoint, opoint, startp;
13028 int update_mode_line;
13029 int tem;
13030 struct it it;
13031 /* Record it now because it's overwritten. */
13032 int current_matrix_up_to_date_p = 0;
13033 int used_current_matrix_p = 0;
13034 /* This is less strict than current_matrix_up_to_date_p.
13035 It indictes that the buffer contents and narrowing are unchanged. */
13036 int buffer_unchanged_p = 0;
13037 int temp_scroll_step = 0;
13038 int count = SPECPDL_INDEX ();
13039 int rc;
13040 int centering_position = -1;
13041 int last_line_misfit = 0;
13042 int beg_unchanged, end_unchanged;
13044 SET_TEXT_POS (lpoint, PT, PT_BYTE);
13045 opoint = lpoint;
13047 /* W must be a leaf window here. */
13048 xassert (!NILP (w->buffer));
13049 #if GLYPH_DEBUG
13050 *w->desired_matrix->method = 0;
13051 #endif
13053 restart:
13054 reconsider_clip_changes (w, buffer);
13056 /* Has the mode line to be updated? */
13057 update_mode_line = (!NILP (w->update_mode_line)
13058 || update_mode_lines
13059 || buffer->clip_changed
13060 || buffer->prevent_redisplay_optimizations_p);
13062 if (MINI_WINDOW_P (w))
13064 if (w == XWINDOW (echo_area_window)
13065 && !NILP (echo_area_buffer[0]))
13067 if (update_mode_line)
13068 /* We may have to update a tty frame's menu bar or a
13069 tool-bar. Example `M-x C-h C-h C-g'. */
13070 goto finish_menu_bars;
13071 else
13072 /* We've already displayed the echo area glyphs in this window. */
13073 goto finish_scroll_bars;
13075 else if ((w != XWINDOW (minibuf_window)
13076 || minibuf_level == 0)
13077 /* When buffer is nonempty, redisplay window normally. */
13078 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
13079 /* Quail displays non-mini buffers in minibuffer window.
13080 In that case, redisplay the window normally. */
13081 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
13083 /* W is a mini-buffer window, but it's not active, so clear
13084 it. */
13085 int yb = window_text_bottom_y (w);
13086 struct glyph_row *row;
13087 int y;
13089 for (y = 0, row = w->desired_matrix->rows;
13090 y < yb;
13091 y += row->height, ++row)
13092 blank_row (w, row, y);
13093 goto finish_scroll_bars;
13096 clear_glyph_matrix (w->desired_matrix);
13099 /* Otherwise set up data on this window; select its buffer and point
13100 value. */
13101 /* Really select the buffer, for the sake of buffer-local
13102 variables. */
13103 set_buffer_internal_1 (XBUFFER (w->buffer));
13105 current_matrix_up_to_date_p
13106 = (!NILP (w->window_end_valid)
13107 && !current_buffer->clip_changed
13108 && !current_buffer->prevent_redisplay_optimizations_p
13109 && XFASTINT (w->last_modified) >= MODIFF
13110 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
13112 /* Run the window-bottom-change-functions
13113 if it is possible that the text on the screen has changed
13114 (either due to modification of the text, or any other reason). */
13115 if (!current_matrix_up_to_date_p
13116 && !NILP (Vwindow_text_change_functions))
13118 safe_run_hooks (Qwindow_text_change_functions);
13119 goto restart;
13122 beg_unchanged = BEG_UNCHANGED;
13123 end_unchanged = END_UNCHANGED;
13125 SET_TEXT_POS (opoint, PT, PT_BYTE);
13127 specbind (Qinhibit_point_motion_hooks, Qt);
13129 buffer_unchanged_p
13130 = (!NILP (w->window_end_valid)
13131 && !current_buffer->clip_changed
13132 && XFASTINT (w->last_modified) >= MODIFF
13133 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
13135 /* When windows_or_buffers_changed is non-zero, we can't rely on
13136 the window end being valid, so set it to nil there. */
13137 if (windows_or_buffers_changed)
13139 /* If window starts on a continuation line, maybe adjust the
13140 window start in case the window's width changed. */
13141 if (XMARKER (w->start)->buffer == current_buffer)
13142 compute_window_start_on_continuation_line (w);
13144 w->window_end_valid = Qnil;
13147 /* Some sanity checks. */
13148 CHECK_WINDOW_END (w);
13149 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
13150 abort ();
13151 if (BYTEPOS (opoint) < CHARPOS (opoint))
13152 abort ();
13154 /* If %c is in mode line, update it if needed. */
13155 if (!NILP (w->column_number_displayed)
13156 /* This alternative quickly identifies a common case
13157 where no change is needed. */
13158 && !(PT == XFASTINT (w->last_point)
13159 && XFASTINT (w->last_modified) >= MODIFF
13160 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
13161 && (XFASTINT (w->column_number_displayed)
13162 != (int) current_column ())) /* iftc */
13163 update_mode_line = 1;
13165 /* Count number of windows showing the selected buffer. An indirect
13166 buffer counts as its base buffer. */
13167 if (!just_this_one_p)
13169 struct buffer *current_base, *window_base;
13170 current_base = current_buffer;
13171 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
13172 if (current_base->base_buffer)
13173 current_base = current_base->base_buffer;
13174 if (window_base->base_buffer)
13175 window_base = window_base->base_buffer;
13176 if (current_base == window_base)
13177 buffer_shared++;
13180 /* Point refers normally to the selected window. For any other
13181 window, set up appropriate value. */
13182 if (!EQ (window, selected_window))
13184 int new_pt = XMARKER (w->pointm)->charpos;
13185 int new_pt_byte = marker_byte_position (w->pointm);
13186 if (new_pt < BEGV)
13188 new_pt = BEGV;
13189 new_pt_byte = BEGV_BYTE;
13190 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
13192 else if (new_pt > (ZV - 1))
13194 new_pt = ZV;
13195 new_pt_byte = ZV_BYTE;
13196 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
13199 /* We don't use SET_PT so that the point-motion hooks don't run. */
13200 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
13203 /* If any of the character widths specified in the display table
13204 have changed, invalidate the width run cache. It's true that
13205 this may be a bit late to catch such changes, but the rest of
13206 redisplay goes (non-fatally) haywire when the display table is
13207 changed, so why should we worry about doing any better? */
13208 if (current_buffer->width_run_cache)
13210 struct Lisp_Char_Table *disptab = buffer_display_table ();
13212 if (! disptab_matches_widthtab (disptab,
13213 XVECTOR (current_buffer->width_table)))
13215 invalidate_region_cache (current_buffer,
13216 current_buffer->width_run_cache,
13217 BEG, Z);
13218 recompute_width_table (current_buffer, disptab);
13222 /* If window-start is screwed up, choose a new one. */
13223 if (XMARKER (w->start)->buffer != current_buffer)
13224 goto recenter;
13226 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13228 /* If someone specified a new starting point but did not insist,
13229 check whether it can be used. */
13230 if (!NILP (w->optional_new_start)
13231 && CHARPOS (startp) >= BEGV
13232 && CHARPOS (startp) <= ZV)
13234 w->optional_new_start = Qnil;
13235 start_display (&it, w, startp);
13236 move_it_to (&it, PT, 0, it.last_visible_y, -1,
13237 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
13238 if (IT_CHARPOS (it) == PT)
13239 w->force_start = Qt;
13240 /* IT may overshoot PT if text at PT is invisible. */
13241 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
13242 w->force_start = Qt;
13245 force_start:
13247 /* Handle case where place to start displaying has been specified,
13248 unless the specified location is outside the accessible range. */
13249 if (!NILP (w->force_start)
13250 || w->frozen_window_start_p)
13252 /* We set this later on if we have to adjust point. */
13253 int new_vpos = -1;
13254 int val;
13256 w->force_start = Qnil;
13257 w->vscroll = 0;
13258 w->window_end_valid = Qnil;
13260 /* Forget any recorded base line for line number display. */
13261 if (!buffer_unchanged_p)
13262 w->base_line_number = Qnil;
13264 /* Redisplay the mode line. Select the buffer properly for that.
13265 Also, run the hook window-scroll-functions
13266 because we have scrolled. */
13267 /* Note, we do this after clearing force_start because
13268 if there's an error, it is better to forget about force_start
13269 than to get into an infinite loop calling the hook functions
13270 and having them get more errors. */
13271 if (!update_mode_line
13272 || ! NILP (Vwindow_scroll_functions))
13274 update_mode_line = 1;
13275 w->update_mode_line = Qt;
13276 startp = run_window_scroll_functions (window, startp);
13279 w->last_modified = make_number (0);
13280 w->last_overlay_modified = make_number (0);
13281 if (CHARPOS (startp) < BEGV)
13282 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
13283 else if (CHARPOS (startp) > ZV)
13284 SET_TEXT_POS (startp, ZV, ZV_BYTE);
13286 /* Redisplay, then check if cursor has been set during the
13287 redisplay. Give up if new fonts were loaded. */
13288 val = try_window (window, startp, 1);
13289 if (!val)
13291 w->force_start = Qt;
13292 clear_glyph_matrix (w->desired_matrix);
13293 goto need_larger_matrices;
13295 /* Point was outside the scroll margins. */
13296 if (val < 0)
13297 new_vpos = window_box_height (w) / 2;
13299 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
13301 /* If point does not appear, try to move point so it does
13302 appear. The desired matrix has been built above, so we
13303 can use it here. */
13304 new_vpos = window_box_height (w) / 2;
13307 if (!cursor_row_fully_visible_p (w, 0, 0))
13309 /* Point does appear, but on a line partly visible at end of window.
13310 Move it back to a fully-visible line. */
13311 new_vpos = window_box_height (w);
13314 /* If we need to move point for either of the above reasons,
13315 now actually do it. */
13316 if (new_vpos >= 0)
13318 struct glyph_row *row;
13320 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
13321 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
13322 ++row;
13324 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
13325 MATRIX_ROW_START_BYTEPOS (row));
13327 if (w != XWINDOW (selected_window))
13328 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
13329 else if (current_buffer == old)
13330 SET_TEXT_POS (lpoint, PT, PT_BYTE);
13332 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
13334 /* If we are highlighting the region, then we just changed
13335 the region, so redisplay to show it. */
13336 if (!NILP (Vtransient_mark_mode)
13337 && !NILP (current_buffer->mark_active))
13339 clear_glyph_matrix (w->desired_matrix);
13340 if (!try_window (window, startp, 0))
13341 goto need_larger_matrices;
13345 #if GLYPH_DEBUG
13346 debug_method_add (w, "forced window start");
13347 #endif
13348 goto done;
13351 /* Handle case where text has not changed, only point, and it has
13352 not moved off the frame, and we are not retrying after hscroll.
13353 (current_matrix_up_to_date_p is nonzero when retrying.) */
13354 if (current_matrix_up_to_date_p
13355 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
13356 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
13358 switch (rc)
13360 case CURSOR_MOVEMENT_SUCCESS:
13361 used_current_matrix_p = 1;
13362 goto done;
13364 #if 0 /* try_cursor_movement never returns this value. */
13365 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES:
13366 goto need_larger_matrices;
13367 #endif
13369 case CURSOR_MOVEMENT_MUST_SCROLL:
13370 goto try_to_scroll;
13372 default:
13373 abort ();
13376 /* If current starting point was originally the beginning of a line
13377 but no longer is, find a new starting point. */
13378 else if (!NILP (w->start_at_line_beg)
13379 && !(CHARPOS (startp) <= BEGV
13380 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
13382 #if GLYPH_DEBUG
13383 debug_method_add (w, "recenter 1");
13384 #endif
13385 goto recenter;
13388 /* Try scrolling with try_window_id. Value is > 0 if update has
13389 been done, it is -1 if we know that the same window start will
13390 not work. It is 0 if unsuccessful for some other reason. */
13391 else if ((tem = try_window_id (w)) != 0)
13393 #if GLYPH_DEBUG
13394 debug_method_add (w, "try_window_id %d", tem);
13395 #endif
13397 if (fonts_changed_p)
13398 goto need_larger_matrices;
13399 if (tem > 0)
13400 goto done;
13402 /* Otherwise try_window_id has returned -1 which means that we
13403 don't want the alternative below this comment to execute. */
13405 else if (CHARPOS (startp) >= BEGV
13406 && CHARPOS (startp) <= ZV
13407 && PT >= CHARPOS (startp)
13408 && (CHARPOS (startp) < ZV
13409 /* Avoid starting at end of buffer. */
13410 || CHARPOS (startp) == BEGV
13411 || (XFASTINT (w->last_modified) >= MODIFF
13412 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
13415 /* If first window line is a continuation line, and window start
13416 is inside the modified region, but the first change is before
13417 current window start, we must select a new window start.
13419 However, if this is the result of a down-mouse event (e.g. by
13420 extending the mouse-drag-overlay), we don't want to select a
13421 new window start, since that would change the position under
13422 the mouse, resulting in an unwanted mouse-movement rather
13423 than a simple mouse-click. */
13424 if (NILP (w->start_at_line_beg)
13425 && NILP (do_mouse_tracking)
13426 && CHARPOS (startp) > BEGV
13427 && CHARPOS (startp) > BEG + beg_unchanged
13428 && CHARPOS (startp) <= Z - end_unchanged)
13430 w->force_start = Qt;
13431 if (XMARKER (w->start)->buffer == current_buffer)
13432 compute_window_start_on_continuation_line (w);
13433 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13434 goto force_start;
13437 #if GLYPH_DEBUG
13438 debug_method_add (w, "same window start");
13439 #endif
13441 /* Try to redisplay starting at same place as before.
13442 If point has not moved off frame, accept the results. */
13443 if (!current_matrix_up_to_date_p
13444 /* Don't use try_window_reusing_current_matrix in this case
13445 because a window scroll function can have changed the
13446 buffer. */
13447 || !NILP (Vwindow_scroll_functions)
13448 || MINI_WINDOW_P (w)
13449 || !(used_current_matrix_p
13450 = try_window_reusing_current_matrix (w)))
13452 IF_DEBUG (debug_method_add (w, "1"));
13453 if (try_window (window, startp, 1) < 0)
13454 /* -1 means we need to scroll.
13455 0 means we need new matrices, but fonts_changed_p
13456 is set in that case, so we will detect it below. */
13457 goto try_to_scroll;
13460 if (fonts_changed_p)
13461 goto need_larger_matrices;
13463 if (w->cursor.vpos >= 0)
13465 if (!just_this_one_p
13466 || current_buffer->clip_changed
13467 || BEG_UNCHANGED < CHARPOS (startp))
13468 /* Forget any recorded base line for line number display. */
13469 w->base_line_number = Qnil;
13471 if (!cursor_row_fully_visible_p (w, 1, 0))
13473 clear_glyph_matrix (w->desired_matrix);
13474 last_line_misfit = 1;
13476 /* Drop through and scroll. */
13477 else
13478 goto done;
13480 else
13481 clear_glyph_matrix (w->desired_matrix);
13484 try_to_scroll:
13486 w->last_modified = make_number (0);
13487 w->last_overlay_modified = make_number (0);
13489 /* Redisplay the mode line. Select the buffer properly for that. */
13490 if (!update_mode_line)
13492 update_mode_line = 1;
13493 w->update_mode_line = Qt;
13496 /* Try to scroll by specified few lines. */
13497 if ((scroll_conservatively
13498 || scroll_step
13499 || temp_scroll_step
13500 || NUMBERP (current_buffer->scroll_up_aggressively)
13501 || NUMBERP (current_buffer->scroll_down_aggressively))
13502 && !current_buffer->clip_changed
13503 && CHARPOS (startp) >= BEGV
13504 && CHARPOS (startp) <= ZV)
13506 /* The function returns -1 if new fonts were loaded, 1 if
13507 successful, 0 if not successful. */
13508 int rc = try_scrolling (window, just_this_one_p,
13509 scroll_conservatively,
13510 scroll_step,
13511 temp_scroll_step, last_line_misfit);
13512 switch (rc)
13514 case SCROLLING_SUCCESS:
13515 goto done;
13517 case SCROLLING_NEED_LARGER_MATRICES:
13518 goto need_larger_matrices;
13520 case SCROLLING_FAILED:
13521 break;
13523 default:
13524 abort ();
13528 /* Finally, just choose place to start which centers point */
13530 recenter:
13531 if (centering_position < 0)
13532 centering_position = window_box_height (w) / 2;
13534 #if GLYPH_DEBUG
13535 debug_method_add (w, "recenter");
13536 #endif
13538 /* w->vscroll = 0; */
13540 /* Forget any previously recorded base line for line number display. */
13541 if (!buffer_unchanged_p)
13542 w->base_line_number = Qnil;
13544 /* Move backward half the height of the window. */
13545 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
13546 it.current_y = it.last_visible_y;
13547 move_it_vertically_backward (&it, centering_position);
13548 xassert (IT_CHARPOS (it) >= BEGV);
13550 /* The function move_it_vertically_backward may move over more
13551 than the specified y-distance. If it->w is small, e.g. a
13552 mini-buffer window, we may end up in front of the window's
13553 display area. Start displaying at the start of the line
13554 containing PT in this case. */
13555 if (it.current_y <= 0)
13557 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
13558 move_it_vertically_backward (&it, 0);
13559 #if 0
13560 /* I think this assert is bogus if buffer contains
13561 invisible text or images. KFS. */
13562 xassert (IT_CHARPOS (it) <= PT);
13563 #endif
13564 it.current_y = 0;
13567 it.current_x = it.hpos = 0;
13569 /* Set startp here explicitly in case that helps avoid an infinite loop
13570 in case the window-scroll-functions functions get errors. */
13571 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
13573 /* Run scroll hooks. */
13574 startp = run_window_scroll_functions (window, it.current.pos);
13576 /* Redisplay the window. */
13577 if (!current_matrix_up_to_date_p
13578 || windows_or_buffers_changed
13579 || cursor_type_changed
13580 /* Don't use try_window_reusing_current_matrix in this case
13581 because it can have changed the buffer. */
13582 || !NILP (Vwindow_scroll_functions)
13583 || !just_this_one_p
13584 || MINI_WINDOW_P (w)
13585 || !(used_current_matrix_p
13586 = try_window_reusing_current_matrix (w)))
13587 try_window (window, startp, 0);
13589 /* If new fonts have been loaded (due to fontsets), give up. We
13590 have to start a new redisplay since we need to re-adjust glyph
13591 matrices. */
13592 if (fonts_changed_p)
13593 goto need_larger_matrices;
13595 /* If cursor did not appear assume that the middle of the window is
13596 in the first line of the window. Do it again with the next line.
13597 (Imagine a window of height 100, displaying two lines of height
13598 60. Moving back 50 from it->last_visible_y will end in the first
13599 line.) */
13600 if (w->cursor.vpos < 0)
13602 if (!NILP (w->window_end_valid)
13603 && PT >= Z - XFASTINT (w->window_end_pos))
13605 clear_glyph_matrix (w->desired_matrix);
13606 move_it_by_lines (&it, 1, 0);
13607 try_window (window, it.current.pos, 0);
13609 else if (PT < IT_CHARPOS (it))
13611 clear_glyph_matrix (w->desired_matrix);
13612 move_it_by_lines (&it, -1, 0);
13613 try_window (window, it.current.pos, 0);
13615 else
13617 /* Not much we can do about it. */
13621 /* Consider the following case: Window starts at BEGV, there is
13622 invisible, intangible text at BEGV, so that display starts at
13623 some point START > BEGV. It can happen that we are called with
13624 PT somewhere between BEGV and START. Try to handle that case. */
13625 if (w->cursor.vpos < 0)
13627 struct glyph_row *row = w->current_matrix->rows;
13628 if (row->mode_line_p)
13629 ++row;
13630 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13633 if (!cursor_row_fully_visible_p (w, 0, 0))
13635 /* If vscroll is enabled, disable it and try again. */
13636 if (w->vscroll)
13638 w->vscroll = 0;
13639 clear_glyph_matrix (w->desired_matrix);
13640 goto recenter;
13643 /* If centering point failed to make the whole line visible,
13644 put point at the top instead. That has to make the whole line
13645 visible, if it can be done. */
13646 if (centering_position == 0)
13647 goto done;
13649 clear_glyph_matrix (w->desired_matrix);
13650 centering_position = 0;
13651 goto recenter;
13654 done:
13656 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13657 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
13658 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
13659 ? Qt : Qnil);
13661 /* Display the mode line, if we must. */
13662 if ((update_mode_line
13663 /* If window not full width, must redo its mode line
13664 if (a) the window to its side is being redone and
13665 (b) we do a frame-based redisplay. This is a consequence
13666 of how inverted lines are drawn in frame-based redisplay. */
13667 || (!just_this_one_p
13668 && !FRAME_WINDOW_P (f)
13669 && !WINDOW_FULL_WIDTH_P (w))
13670 /* Line number to display. */
13671 || INTEGERP (w->base_line_pos)
13672 /* Column number is displayed and different from the one displayed. */
13673 || (!NILP (w->column_number_displayed)
13674 && (XFASTINT (w->column_number_displayed)
13675 != (int) current_column ()))) /* iftc */
13676 /* This means that the window has a mode line. */
13677 && (WINDOW_WANTS_MODELINE_P (w)
13678 || WINDOW_WANTS_HEADER_LINE_P (w)))
13680 display_mode_lines (w);
13682 /* If mode line height has changed, arrange for a thorough
13683 immediate redisplay using the correct mode line height. */
13684 if (WINDOW_WANTS_MODELINE_P (w)
13685 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
13687 fonts_changed_p = 1;
13688 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
13689 = DESIRED_MODE_LINE_HEIGHT (w);
13692 /* If top line height has changed, arrange for a thorough
13693 immediate redisplay using the correct mode line height. */
13694 if (WINDOW_WANTS_HEADER_LINE_P (w)
13695 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
13697 fonts_changed_p = 1;
13698 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
13699 = DESIRED_HEADER_LINE_HEIGHT (w);
13702 if (fonts_changed_p)
13703 goto need_larger_matrices;
13706 if (!line_number_displayed
13707 && !BUFFERP (w->base_line_pos))
13709 w->base_line_pos = Qnil;
13710 w->base_line_number = Qnil;
13713 finish_menu_bars:
13715 /* When we reach a frame's selected window, redo the frame's menu bar. */
13716 if (update_mode_line
13717 && EQ (FRAME_SELECTED_WINDOW (f), window))
13719 int redisplay_menu_p = 0;
13720 int redisplay_tool_bar_p = 0;
13722 if (FRAME_WINDOW_P (f))
13724 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
13725 || defined (USE_GTK)
13726 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
13727 #else
13728 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
13729 #endif
13731 else
13732 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
13734 if (redisplay_menu_p)
13735 display_menu_bar (w);
13737 #ifdef HAVE_WINDOW_SYSTEM
13738 if (FRAME_WINDOW_P (f))
13740 #if defined (USE_GTK) || USE_MAC_TOOLBAR
13741 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
13742 #else
13743 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
13744 && (FRAME_TOOL_BAR_LINES (f) > 0
13745 || !NILP (Vauto_resize_tool_bars));
13746 #endif
13748 if (redisplay_tool_bar_p && redisplay_tool_bar (f))
13750 extern int ignore_mouse_drag_p;
13751 ignore_mouse_drag_p = 1;
13754 #endif
13757 #ifdef HAVE_WINDOW_SYSTEM
13758 if (FRAME_WINDOW_P (f)
13759 && update_window_fringes (w, (just_this_one_p
13760 || (!used_current_matrix_p && !overlay_arrow_seen)
13761 || w->pseudo_window_p)))
13763 update_begin (f);
13764 BLOCK_INPUT;
13765 if (draw_window_fringes (w, 1))
13766 x_draw_vertical_border (w);
13767 UNBLOCK_INPUT;
13768 update_end (f);
13770 #endif /* HAVE_WINDOW_SYSTEM */
13772 /* We go to this label, with fonts_changed_p nonzero,
13773 if it is necessary to try again using larger glyph matrices.
13774 We have to redeem the scroll bar even in this case,
13775 because the loop in redisplay_internal expects that. */
13776 need_larger_matrices:
13778 finish_scroll_bars:
13780 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
13782 /* Set the thumb's position and size. */
13783 set_vertical_scroll_bar (w);
13785 /* Note that we actually used the scroll bar attached to this
13786 window, so it shouldn't be deleted at the end of redisplay. */
13787 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
13788 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
13791 /* Restore current_buffer and value of point in it. */
13792 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
13793 set_buffer_internal_1 (old);
13794 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
13795 shorter. This can be caused by log truncation in *Messages*. */
13796 if (CHARPOS (lpoint) <= ZV)
13797 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
13799 unbind_to (count, Qnil);
13803 /* Build the complete desired matrix of WINDOW with a window start
13804 buffer position POS.
13806 Value is 1 if successful. It is zero if fonts were loaded during
13807 redisplay which makes re-adjusting glyph matrices necessary, and -1
13808 if point would appear in the scroll margins.
13809 (We check that only if CHECK_MARGINS is nonzero. */
13812 try_window (window, pos, check_margins)
13813 Lisp_Object window;
13814 struct text_pos pos;
13815 int check_margins;
13817 struct window *w = XWINDOW (window);
13818 struct it it;
13819 struct glyph_row *last_text_row = NULL;
13820 struct frame *f = XFRAME (w->frame);
13822 /* Make POS the new window start. */
13823 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
13825 /* Mark cursor position as unknown. No overlay arrow seen. */
13826 w->cursor.vpos = -1;
13827 overlay_arrow_seen = 0;
13829 /* Initialize iterator and info to start at POS. */
13830 start_display (&it, w, pos);
13832 /* Display all lines of W. */
13833 while (it.current_y < it.last_visible_y)
13835 if (display_line (&it))
13836 last_text_row = it.glyph_row - 1;
13837 if (fonts_changed_p)
13838 return 0;
13841 /* Don't let the cursor end in the scroll margins. */
13842 if (check_margins
13843 && !MINI_WINDOW_P (w))
13845 int this_scroll_margin;
13847 this_scroll_margin = max (0, scroll_margin);
13848 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13849 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
13851 if ((w->cursor.y >= 0 /* not vscrolled */
13852 && w->cursor.y < this_scroll_margin
13853 && CHARPOS (pos) > BEGV
13854 && IT_CHARPOS (it) < ZV)
13855 /* rms: considering make_cursor_line_fully_visible_p here
13856 seems to give wrong results. We don't want to recenter
13857 when the last line is partly visible, we want to allow
13858 that case to be handled in the usual way. */
13859 || (w->cursor.y + 1) > it.last_visible_y)
13861 w->cursor.vpos = -1;
13862 clear_glyph_matrix (w->desired_matrix);
13863 return -1;
13867 /* If bottom moved off end of frame, change mode line percentage. */
13868 if (XFASTINT (w->window_end_pos) <= 0
13869 && Z != IT_CHARPOS (it))
13870 w->update_mode_line = Qt;
13872 /* Set window_end_pos to the offset of the last character displayed
13873 on the window from the end of current_buffer. Set
13874 window_end_vpos to its row number. */
13875 if (last_text_row)
13877 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
13878 w->window_end_bytepos
13879 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13880 w->window_end_pos
13881 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13882 w->window_end_vpos
13883 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
13884 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
13885 ->displays_text_p);
13887 else
13889 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
13890 w->window_end_pos = make_number (Z - ZV);
13891 w->window_end_vpos = make_number (0);
13894 /* But that is not valid info until redisplay finishes. */
13895 w->window_end_valid = Qnil;
13896 return 1;
13901 /************************************************************************
13902 Window redisplay reusing current matrix when buffer has not changed
13903 ************************************************************************/
13905 /* Try redisplay of window W showing an unchanged buffer with a
13906 different window start than the last time it was displayed by
13907 reusing its current matrix. Value is non-zero if successful.
13908 W->start is the new window start. */
13910 static int
13911 try_window_reusing_current_matrix (w)
13912 struct window *w;
13914 struct frame *f = XFRAME (w->frame);
13915 struct glyph_row *row, *bottom_row;
13916 struct it it;
13917 struct run run;
13918 struct text_pos start, new_start;
13919 int nrows_scrolled, i;
13920 struct glyph_row *last_text_row;
13921 struct glyph_row *last_reused_text_row;
13922 struct glyph_row *start_row;
13923 int start_vpos, min_y, max_y;
13925 #if GLYPH_DEBUG
13926 if (inhibit_try_window_reusing)
13927 return 0;
13928 #endif
13930 if (/* This function doesn't handle terminal frames. */
13931 !FRAME_WINDOW_P (f)
13932 /* Don't try to reuse the display if windows have been split
13933 or such. */
13934 || windows_or_buffers_changed
13935 || cursor_type_changed)
13936 return 0;
13938 /* Can't do this if region may have changed. */
13939 if ((!NILP (Vtransient_mark_mode)
13940 && !NILP (current_buffer->mark_active))
13941 || !NILP (w->region_showing)
13942 || !NILP (Vshow_trailing_whitespace))
13943 return 0;
13945 /* If top-line visibility has changed, give up. */
13946 if (WINDOW_WANTS_HEADER_LINE_P (w)
13947 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
13948 return 0;
13950 /* Give up if old or new display is scrolled vertically. We could
13951 make this function handle this, but right now it doesn't. */
13952 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
13953 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
13954 return 0;
13956 /* The variable new_start now holds the new window start. The old
13957 start `start' can be determined from the current matrix. */
13958 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
13959 start = start_row->start.pos;
13960 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
13962 /* Clear the desired matrix for the display below. */
13963 clear_glyph_matrix (w->desired_matrix);
13965 if (CHARPOS (new_start) <= CHARPOS (start))
13967 int first_row_y;
13969 /* Don't use this method if the display starts with an ellipsis
13970 displayed for invisible text. It's not easy to handle that case
13971 below, and it's certainly not worth the effort since this is
13972 not a frequent case. */
13973 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
13974 return 0;
13976 IF_DEBUG (debug_method_add (w, "twu1"));
13978 /* Display up to a row that can be reused. The variable
13979 last_text_row is set to the last row displayed that displays
13980 text. Note that it.vpos == 0 if or if not there is a
13981 header-line; it's not the same as the MATRIX_ROW_VPOS! */
13982 start_display (&it, w, new_start);
13983 first_row_y = it.current_y;
13984 w->cursor.vpos = -1;
13985 last_text_row = last_reused_text_row = NULL;
13987 while (it.current_y < it.last_visible_y
13988 && !fonts_changed_p)
13990 /* If we have reached into the characters in the START row,
13991 that means the line boundaries have changed. So we
13992 can't start copying with the row START. Maybe it will
13993 work to start copying with the following row. */
13994 while (IT_CHARPOS (it) > CHARPOS (start))
13996 /* Advance to the next row as the "start". */
13997 start_row++;
13998 start = start_row->start.pos;
13999 /* If there are no more rows to try, or just one, give up. */
14000 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
14001 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
14002 || CHARPOS (start) == ZV)
14004 clear_glyph_matrix (w->desired_matrix);
14005 return 0;
14008 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
14010 /* If we have reached alignment,
14011 we can copy the rest of the rows. */
14012 if (IT_CHARPOS (it) == CHARPOS (start))
14013 break;
14015 if (display_line (&it))
14016 last_text_row = it.glyph_row - 1;
14019 /* A value of current_y < last_visible_y means that we stopped
14020 at the previous window start, which in turn means that we
14021 have at least one reusable row. */
14022 if (it.current_y < it.last_visible_y)
14024 /* IT.vpos always starts from 0; it counts text lines. */
14025 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
14027 /* Find PT if not already found in the lines displayed. */
14028 if (w->cursor.vpos < 0)
14030 int dy = it.current_y - start_row->y;
14032 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
14033 row = row_containing_pos (w, PT, row, NULL, dy);
14034 if (row)
14035 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
14036 dy, nrows_scrolled);
14037 else
14039 clear_glyph_matrix (w->desired_matrix);
14040 return 0;
14044 /* Scroll the display. Do it before the current matrix is
14045 changed. The problem here is that update has not yet
14046 run, i.e. part of the current matrix is not up to date.
14047 scroll_run_hook will clear the cursor, and use the
14048 current matrix to get the height of the row the cursor is
14049 in. */
14050 run.current_y = start_row->y;
14051 run.desired_y = it.current_y;
14052 run.height = it.last_visible_y - it.current_y;
14054 if (run.height > 0 && run.current_y != run.desired_y)
14056 update_begin (f);
14057 FRAME_RIF (f)->update_window_begin_hook (w);
14058 FRAME_RIF (f)->clear_window_mouse_face (w);
14059 FRAME_RIF (f)->scroll_run_hook (w, &run);
14060 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
14061 update_end (f);
14064 /* Shift current matrix down by nrows_scrolled lines. */
14065 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
14066 rotate_matrix (w->current_matrix,
14067 start_vpos,
14068 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
14069 nrows_scrolled);
14071 /* Disable lines that must be updated. */
14072 for (i = 0; i < nrows_scrolled; ++i)
14073 (start_row + i)->enabled_p = 0;
14075 /* Re-compute Y positions. */
14076 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
14077 max_y = it.last_visible_y;
14078 for (row = start_row + nrows_scrolled;
14079 row < bottom_row;
14080 ++row)
14082 row->y = it.current_y;
14083 row->visible_height = row->height;
14085 if (row->y < min_y)
14086 row->visible_height -= min_y - row->y;
14087 if (row->y + row->height > max_y)
14088 row->visible_height -= row->y + row->height - max_y;
14089 row->redraw_fringe_bitmaps_p = 1;
14091 it.current_y += row->height;
14093 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
14094 last_reused_text_row = row;
14095 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
14096 break;
14099 /* Disable lines in the current matrix which are now
14100 below the window. */
14101 for (++row; row < bottom_row; ++row)
14102 row->enabled_p = row->mode_line_p = 0;
14105 /* Update window_end_pos etc.; last_reused_text_row is the last
14106 reused row from the current matrix containing text, if any.
14107 The value of last_text_row is the last displayed line
14108 containing text. */
14109 if (last_reused_text_row)
14111 w->window_end_bytepos
14112 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
14113 w->window_end_pos
14114 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
14115 w->window_end_vpos
14116 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
14117 w->current_matrix));
14119 else if (last_text_row)
14121 w->window_end_bytepos
14122 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
14123 w->window_end_pos
14124 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
14125 w->window_end_vpos
14126 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
14128 else
14130 /* This window must be completely empty. */
14131 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
14132 w->window_end_pos = make_number (Z - ZV);
14133 w->window_end_vpos = make_number (0);
14135 w->window_end_valid = Qnil;
14137 /* Update hint: don't try scrolling again in update_window. */
14138 w->desired_matrix->no_scrolling_p = 1;
14140 #if GLYPH_DEBUG
14141 debug_method_add (w, "try_window_reusing_current_matrix 1");
14142 #endif
14143 return 1;
14145 else if (CHARPOS (new_start) > CHARPOS (start))
14147 struct glyph_row *pt_row, *row;
14148 struct glyph_row *first_reusable_row;
14149 struct glyph_row *first_row_to_display;
14150 int dy;
14151 int yb = window_text_bottom_y (w);
14153 /* Find the row starting at new_start, if there is one. Don't
14154 reuse a partially visible line at the end. */
14155 first_reusable_row = start_row;
14156 while (first_reusable_row->enabled_p
14157 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
14158 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
14159 < CHARPOS (new_start)))
14160 ++first_reusable_row;
14162 /* Give up if there is no row to reuse. */
14163 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
14164 || !first_reusable_row->enabled_p
14165 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
14166 != CHARPOS (new_start)))
14167 return 0;
14169 /* We can reuse fully visible rows beginning with
14170 first_reusable_row to the end of the window. Set
14171 first_row_to_display to the first row that cannot be reused.
14172 Set pt_row to the row containing point, if there is any. */
14173 pt_row = NULL;
14174 for (first_row_to_display = first_reusable_row;
14175 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
14176 ++first_row_to_display)
14178 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
14179 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
14180 pt_row = first_row_to_display;
14183 /* Start displaying at the start of first_row_to_display. */
14184 xassert (first_row_to_display->y < yb);
14185 init_to_row_start (&it, w, first_row_to_display);
14187 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
14188 - start_vpos);
14189 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
14190 - nrows_scrolled);
14191 it.current_y = (first_row_to_display->y - first_reusable_row->y
14192 + WINDOW_HEADER_LINE_HEIGHT (w));
14194 /* Display lines beginning with first_row_to_display in the
14195 desired matrix. Set last_text_row to the last row displayed
14196 that displays text. */
14197 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
14198 if (pt_row == NULL)
14199 w->cursor.vpos = -1;
14200 last_text_row = NULL;
14201 while (it.current_y < it.last_visible_y && !fonts_changed_p)
14202 if (display_line (&it))
14203 last_text_row = it.glyph_row - 1;
14205 /* Give up If point isn't in a row displayed or reused. */
14206 if (w->cursor.vpos < 0)
14208 clear_glyph_matrix (w->desired_matrix);
14209 return 0;
14212 /* If point is in a reused row, adjust y and vpos of the cursor
14213 position. */
14214 if (pt_row)
14216 w->cursor.vpos -= nrows_scrolled;
14217 w->cursor.y -= first_reusable_row->y - start_row->y;
14220 /* Scroll the display. */
14221 run.current_y = first_reusable_row->y;
14222 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
14223 run.height = it.last_visible_y - run.current_y;
14224 dy = run.current_y - run.desired_y;
14226 if (run.height)
14228 update_begin (f);
14229 FRAME_RIF (f)->update_window_begin_hook (w);
14230 FRAME_RIF (f)->clear_window_mouse_face (w);
14231 FRAME_RIF (f)->scroll_run_hook (w, &run);
14232 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
14233 update_end (f);
14236 /* Adjust Y positions of reused rows. */
14237 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
14238 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
14239 max_y = it.last_visible_y;
14240 for (row = first_reusable_row; row < first_row_to_display; ++row)
14242 row->y -= dy;
14243 row->visible_height = row->height;
14244 if (row->y < min_y)
14245 row->visible_height -= min_y - row->y;
14246 if (row->y + row->height > max_y)
14247 row->visible_height -= row->y + row->height - max_y;
14248 row->redraw_fringe_bitmaps_p = 1;
14251 /* Scroll the current matrix. */
14252 xassert (nrows_scrolled > 0);
14253 rotate_matrix (w->current_matrix,
14254 start_vpos,
14255 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
14256 -nrows_scrolled);
14258 /* Disable rows not reused. */
14259 for (row -= nrows_scrolled; row < bottom_row; ++row)
14260 row->enabled_p = 0;
14262 /* Point may have moved to a different line, so we cannot assume that
14263 the previous cursor position is valid; locate the correct row. */
14264 if (pt_row)
14266 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
14267 row < bottom_row && PT >= MATRIX_ROW_END_CHARPOS (row);
14268 row++)
14270 w->cursor.vpos++;
14271 w->cursor.y = row->y;
14273 if (row < bottom_row)
14275 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
14276 while (glyph->charpos < PT)
14278 w->cursor.hpos++;
14279 w->cursor.x += glyph->pixel_width;
14280 glyph++;
14285 /* Adjust window end. A null value of last_text_row means that
14286 the window end is in reused rows which in turn means that
14287 only its vpos can have changed. */
14288 if (last_text_row)
14290 w->window_end_bytepos
14291 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
14292 w->window_end_pos
14293 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
14294 w->window_end_vpos
14295 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
14297 else
14299 w->window_end_vpos
14300 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
14303 w->window_end_valid = Qnil;
14304 w->desired_matrix->no_scrolling_p = 1;
14306 #if GLYPH_DEBUG
14307 debug_method_add (w, "try_window_reusing_current_matrix 2");
14308 #endif
14309 return 1;
14312 return 0;
14317 /************************************************************************
14318 Window redisplay reusing current matrix when buffer has changed
14319 ************************************************************************/
14321 static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *));
14322 static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *,
14323 int *, int *));
14324 static struct glyph_row *
14325 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
14326 struct glyph_row *));
14329 /* Return the last row in MATRIX displaying text. If row START is
14330 non-null, start searching with that row. IT gives the dimensions
14331 of the display. Value is null if matrix is empty; otherwise it is
14332 a pointer to the row found. */
14334 static struct glyph_row *
14335 find_last_row_displaying_text (matrix, it, start)
14336 struct glyph_matrix *matrix;
14337 struct it *it;
14338 struct glyph_row *start;
14340 struct glyph_row *row, *row_found;
14342 /* Set row_found to the last row in IT->w's current matrix
14343 displaying text. The loop looks funny but think of partially
14344 visible lines. */
14345 row_found = NULL;
14346 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
14347 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
14349 xassert (row->enabled_p);
14350 row_found = row;
14351 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
14352 break;
14353 ++row;
14356 return row_found;
14360 /* Return the last row in the current matrix of W that is not affected
14361 by changes at the start of current_buffer that occurred since W's
14362 current matrix was built. Value is null if no such row exists.
14364 BEG_UNCHANGED us the number of characters unchanged at the start of
14365 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
14366 first changed character in current_buffer. Characters at positions <
14367 BEG + BEG_UNCHANGED are at the same buffer positions as they were
14368 when the current matrix was built. */
14370 static struct glyph_row *
14371 find_last_unchanged_at_beg_row (w)
14372 struct window *w;
14374 int first_changed_pos = BEG + BEG_UNCHANGED;
14375 struct glyph_row *row;
14376 struct glyph_row *row_found = NULL;
14377 int yb = window_text_bottom_y (w);
14379 /* Find the last row displaying unchanged text. */
14380 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
14381 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
14382 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
14384 if (/* If row ends before first_changed_pos, it is unchanged,
14385 except in some case. */
14386 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
14387 /* When row ends in ZV and we write at ZV it is not
14388 unchanged. */
14389 && !row->ends_at_zv_p
14390 /* When first_changed_pos is the end of a continued line,
14391 row is not unchanged because it may be no longer
14392 continued. */
14393 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
14394 && (row->continued_p
14395 || row->exact_window_width_line_p)))
14396 row_found = row;
14398 /* Stop if last visible row. */
14399 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
14400 break;
14402 ++row;
14405 return row_found;
14409 /* Find the first glyph row in the current matrix of W that is not
14410 affected by changes at the end of current_buffer since the
14411 time W's current matrix was built.
14413 Return in *DELTA the number of chars by which buffer positions in
14414 unchanged text at the end of current_buffer must be adjusted.
14416 Return in *DELTA_BYTES the corresponding number of bytes.
14418 Value is null if no such row exists, i.e. all rows are affected by
14419 changes. */
14421 static struct glyph_row *
14422 find_first_unchanged_at_end_row (w, delta, delta_bytes)
14423 struct window *w;
14424 int *delta, *delta_bytes;
14426 struct glyph_row *row;
14427 struct glyph_row *row_found = NULL;
14429 *delta = *delta_bytes = 0;
14431 /* Display must not have been paused, otherwise the current matrix
14432 is not up to date. */
14433 eassert (!NILP (w->window_end_valid));
14435 /* A value of window_end_pos >= END_UNCHANGED means that the window
14436 end is in the range of changed text. If so, there is no
14437 unchanged row at the end of W's current matrix. */
14438 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
14439 return NULL;
14441 /* Set row to the last row in W's current matrix displaying text. */
14442 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
14444 /* If matrix is entirely empty, no unchanged row exists. */
14445 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
14447 /* The value of row is the last glyph row in the matrix having a
14448 meaningful buffer position in it. The end position of row
14449 corresponds to window_end_pos. This allows us to translate
14450 buffer positions in the current matrix to current buffer
14451 positions for characters not in changed text. */
14452 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
14453 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
14454 int last_unchanged_pos, last_unchanged_pos_old;
14455 struct glyph_row *first_text_row
14456 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
14458 *delta = Z - Z_old;
14459 *delta_bytes = Z_BYTE - Z_BYTE_old;
14461 /* Set last_unchanged_pos to the buffer position of the last
14462 character in the buffer that has not been changed. Z is the
14463 index + 1 of the last character in current_buffer, i.e. by
14464 subtracting END_UNCHANGED we get the index of the last
14465 unchanged character, and we have to add BEG to get its buffer
14466 position. */
14467 last_unchanged_pos = Z - END_UNCHANGED + BEG;
14468 last_unchanged_pos_old = last_unchanged_pos - *delta;
14470 /* Search backward from ROW for a row displaying a line that
14471 starts at a minimum position >= last_unchanged_pos_old. */
14472 for (; row > first_text_row; --row)
14474 /* This used to abort, but it can happen.
14475 It is ok to just stop the search instead here. KFS. */
14476 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
14477 break;
14479 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
14480 row_found = row;
14484 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
14486 return row_found;
14490 /* Make sure that glyph rows in the current matrix of window W
14491 reference the same glyph memory as corresponding rows in the
14492 frame's frame matrix. This function is called after scrolling W's
14493 current matrix on a terminal frame in try_window_id and
14494 try_window_reusing_current_matrix. */
14496 static void
14497 sync_frame_with_window_matrix_rows (w)
14498 struct window *w;
14500 struct frame *f = XFRAME (w->frame);
14501 struct glyph_row *window_row, *window_row_end, *frame_row;
14503 /* Preconditions: W must be a leaf window and full-width. Its frame
14504 must have a frame matrix. */
14505 xassert (NILP (w->hchild) && NILP (w->vchild));
14506 xassert (WINDOW_FULL_WIDTH_P (w));
14507 xassert (!FRAME_WINDOW_P (f));
14509 /* If W is a full-width window, glyph pointers in W's current matrix
14510 have, by definition, to be the same as glyph pointers in the
14511 corresponding frame matrix. Note that frame matrices have no
14512 marginal areas (see build_frame_matrix). */
14513 window_row = w->current_matrix->rows;
14514 window_row_end = window_row + w->current_matrix->nrows;
14515 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
14516 while (window_row < window_row_end)
14518 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
14519 struct glyph *end = window_row->glyphs[LAST_AREA];
14521 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
14522 frame_row->glyphs[TEXT_AREA] = start;
14523 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
14524 frame_row->glyphs[LAST_AREA] = end;
14526 /* Disable frame rows whose corresponding window rows have
14527 been disabled in try_window_id. */
14528 if (!window_row->enabled_p)
14529 frame_row->enabled_p = 0;
14531 ++window_row, ++frame_row;
14536 /* Find the glyph row in window W containing CHARPOS. Consider all
14537 rows between START and END (not inclusive). END null means search
14538 all rows to the end of the display area of W. Value is the row
14539 containing CHARPOS or null. */
14541 struct glyph_row *
14542 row_containing_pos (w, charpos, start, end, dy)
14543 struct window *w;
14544 int charpos;
14545 struct glyph_row *start, *end;
14546 int dy;
14548 struct glyph_row *row = start;
14549 int last_y;
14551 /* If we happen to start on a header-line, skip that. */
14552 if (row->mode_line_p)
14553 ++row;
14555 if ((end && row >= end) || !row->enabled_p)
14556 return NULL;
14558 last_y = window_text_bottom_y (w) - dy;
14560 while (1)
14562 /* Give up if we have gone too far. */
14563 if (end && row >= end)
14564 return NULL;
14565 /* This formerly returned if they were equal.
14566 I think that both quantities are of a "last plus one" type;
14567 if so, when they are equal, the row is within the screen. -- rms. */
14568 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
14569 return NULL;
14571 /* If it is in this row, return this row. */
14572 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
14573 || (MATRIX_ROW_END_CHARPOS (row) == charpos
14574 /* The end position of a row equals the start
14575 position of the next row. If CHARPOS is there, we
14576 would rather display it in the next line, except
14577 when this line ends in ZV. */
14578 && !row->ends_at_zv_p
14579 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
14580 && charpos >= MATRIX_ROW_START_CHARPOS (row))
14581 return row;
14582 ++row;
14587 /* Try to redisplay window W by reusing its existing display. W's
14588 current matrix must be up to date when this function is called,
14589 i.e. window_end_valid must not be nil.
14591 Value is
14593 1 if display has been updated
14594 0 if otherwise unsuccessful
14595 -1 if redisplay with same window start is known not to succeed
14597 The following steps are performed:
14599 1. Find the last row in the current matrix of W that is not
14600 affected by changes at the start of current_buffer. If no such row
14601 is found, give up.
14603 2. Find the first row in W's current matrix that is not affected by
14604 changes at the end of current_buffer. Maybe there is no such row.
14606 3. Display lines beginning with the row + 1 found in step 1 to the
14607 row found in step 2 or, if step 2 didn't find a row, to the end of
14608 the window.
14610 4. If cursor is not known to appear on the window, give up.
14612 5. If display stopped at the row found in step 2, scroll the
14613 display and current matrix as needed.
14615 6. Maybe display some lines at the end of W, if we must. This can
14616 happen under various circumstances, like a partially visible line
14617 becoming fully visible, or because newly displayed lines are displayed
14618 in smaller font sizes.
14620 7. Update W's window end information. */
14622 static int
14623 try_window_id (w)
14624 struct window *w;
14626 struct frame *f = XFRAME (w->frame);
14627 struct glyph_matrix *current_matrix = w->current_matrix;
14628 struct glyph_matrix *desired_matrix = w->desired_matrix;
14629 struct glyph_row *last_unchanged_at_beg_row;
14630 struct glyph_row *first_unchanged_at_end_row;
14631 struct glyph_row *row;
14632 struct glyph_row *bottom_row;
14633 int bottom_vpos;
14634 struct it it;
14635 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
14636 struct text_pos start_pos;
14637 struct run run;
14638 int first_unchanged_at_end_vpos = 0;
14639 struct glyph_row *last_text_row, *last_text_row_at_end;
14640 struct text_pos start;
14641 int first_changed_charpos, last_changed_charpos;
14643 #if GLYPH_DEBUG
14644 if (inhibit_try_window_id)
14645 return 0;
14646 #endif
14648 /* This is handy for debugging. */
14649 #if 0
14650 #define GIVE_UP(X) \
14651 do { \
14652 fprintf (stderr, "try_window_id give up %d\n", (X)); \
14653 return 0; \
14654 } while (0)
14655 #else
14656 #define GIVE_UP(X) return 0
14657 #endif
14659 SET_TEXT_POS_FROM_MARKER (start, w->start);
14661 /* Don't use this for mini-windows because these can show
14662 messages and mini-buffers, and we don't handle that here. */
14663 if (MINI_WINDOW_P (w))
14664 GIVE_UP (1);
14666 /* This flag is used to prevent redisplay optimizations. */
14667 if (windows_or_buffers_changed || cursor_type_changed)
14668 GIVE_UP (2);
14670 /* Verify that narrowing has not changed.
14671 Also verify that we were not told to prevent redisplay optimizations.
14672 It would be nice to further
14673 reduce the number of cases where this prevents try_window_id. */
14674 if (current_buffer->clip_changed
14675 || current_buffer->prevent_redisplay_optimizations_p)
14676 GIVE_UP (3);
14678 /* Window must either use window-based redisplay or be full width. */
14679 if (!FRAME_WINDOW_P (f)
14680 && (!FRAME_LINE_INS_DEL_OK (f)
14681 || !WINDOW_FULL_WIDTH_P (w)))
14682 GIVE_UP (4);
14684 /* Give up if point is not known NOT to appear in W. */
14685 if (PT < CHARPOS (start))
14686 GIVE_UP (5);
14688 /* Another way to prevent redisplay optimizations. */
14689 if (XFASTINT (w->last_modified) == 0)
14690 GIVE_UP (6);
14692 /* Verify that window is not hscrolled. */
14693 if (XFASTINT (w->hscroll) != 0)
14694 GIVE_UP (7);
14696 /* Verify that display wasn't paused. */
14697 if (NILP (w->window_end_valid))
14698 GIVE_UP (8);
14700 /* Can't use this if highlighting a region because a cursor movement
14701 will do more than just set the cursor. */
14702 if (!NILP (Vtransient_mark_mode)
14703 && !NILP (current_buffer->mark_active))
14704 GIVE_UP (9);
14706 /* Likewise if highlighting trailing whitespace. */
14707 if (!NILP (Vshow_trailing_whitespace))
14708 GIVE_UP (11);
14710 /* Likewise if showing a region. */
14711 if (!NILP (w->region_showing))
14712 GIVE_UP (10);
14714 /* Can use this if overlay arrow position and or string have changed. */
14715 if (overlay_arrows_changed_p ())
14716 GIVE_UP (12);
14719 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
14720 only if buffer has really changed. The reason is that the gap is
14721 initially at Z for freshly visited files. The code below would
14722 set end_unchanged to 0 in that case. */
14723 if (MODIFF > SAVE_MODIFF
14724 /* This seems to happen sometimes after saving a buffer. */
14725 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
14727 if (GPT - BEG < BEG_UNCHANGED)
14728 BEG_UNCHANGED = GPT - BEG;
14729 if (Z - GPT < END_UNCHANGED)
14730 END_UNCHANGED = Z - GPT;
14733 /* The position of the first and last character that has been changed. */
14734 first_changed_charpos = BEG + BEG_UNCHANGED;
14735 last_changed_charpos = Z - END_UNCHANGED;
14737 /* If window starts after a line end, and the last change is in
14738 front of that newline, then changes don't affect the display.
14739 This case happens with stealth-fontification. Note that although
14740 the display is unchanged, glyph positions in the matrix have to
14741 be adjusted, of course. */
14742 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
14743 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
14744 && ((last_changed_charpos < CHARPOS (start)
14745 && CHARPOS (start) == BEGV)
14746 || (last_changed_charpos < CHARPOS (start) - 1
14747 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
14749 int Z_old, delta, Z_BYTE_old, delta_bytes;
14750 struct glyph_row *r0;
14752 /* Compute how many chars/bytes have been added to or removed
14753 from the buffer. */
14754 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
14755 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
14756 delta = Z - Z_old;
14757 delta_bytes = Z_BYTE - Z_BYTE_old;
14759 /* Give up if PT is not in the window. Note that it already has
14760 been checked at the start of try_window_id that PT is not in
14761 front of the window start. */
14762 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
14763 GIVE_UP (13);
14765 /* If window start is unchanged, we can reuse the whole matrix
14766 as is, after adjusting glyph positions. No need to compute
14767 the window end again, since its offset from Z hasn't changed. */
14768 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
14769 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
14770 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
14771 /* PT must not be in a partially visible line. */
14772 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
14773 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
14775 /* Adjust positions in the glyph matrix. */
14776 if (delta || delta_bytes)
14778 struct glyph_row *r1
14779 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
14780 increment_matrix_positions (w->current_matrix,
14781 MATRIX_ROW_VPOS (r0, current_matrix),
14782 MATRIX_ROW_VPOS (r1, current_matrix),
14783 delta, delta_bytes);
14786 /* Set the cursor. */
14787 row = row_containing_pos (w, PT, r0, NULL, 0);
14788 if (row)
14789 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
14790 else
14791 abort ();
14792 return 1;
14796 /* Handle the case that changes are all below what is displayed in
14797 the window, and that PT is in the window. This shortcut cannot
14798 be taken if ZV is visible in the window, and text has been added
14799 there that is visible in the window. */
14800 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
14801 /* ZV is not visible in the window, or there are no
14802 changes at ZV, actually. */
14803 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
14804 || first_changed_charpos == last_changed_charpos))
14806 struct glyph_row *r0;
14808 /* Give up if PT is not in the window. Note that it already has
14809 been checked at the start of try_window_id that PT is not in
14810 front of the window start. */
14811 if (PT >= MATRIX_ROW_END_CHARPOS (row))
14812 GIVE_UP (14);
14814 /* If window start is unchanged, we can reuse the whole matrix
14815 as is, without changing glyph positions since no text has
14816 been added/removed in front of the window end. */
14817 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
14818 if (TEXT_POS_EQUAL_P (start, r0->start.pos)
14819 /* PT must not be in a partially visible line. */
14820 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
14821 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
14823 /* We have to compute the window end anew since text
14824 can have been added/removed after it. */
14825 w->window_end_pos
14826 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
14827 w->window_end_bytepos
14828 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
14830 /* Set the cursor. */
14831 row = row_containing_pos (w, PT, r0, NULL, 0);
14832 if (row)
14833 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
14834 else
14835 abort ();
14836 return 2;
14840 /* Give up if window start is in the changed area.
14842 The condition used to read
14844 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
14846 but why that was tested escapes me at the moment. */
14847 if (CHARPOS (start) >= first_changed_charpos
14848 && CHARPOS (start) <= last_changed_charpos)
14849 GIVE_UP (15);
14851 /* Check that window start agrees with the start of the first glyph
14852 row in its current matrix. Check this after we know the window
14853 start is not in changed text, otherwise positions would not be
14854 comparable. */
14855 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
14856 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
14857 GIVE_UP (16);
14859 /* Give up if the window ends in strings. Overlay strings
14860 at the end are difficult to handle, so don't try. */
14861 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
14862 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
14863 GIVE_UP (20);
14865 /* Compute the position at which we have to start displaying new
14866 lines. Some of the lines at the top of the window might be
14867 reusable because they are not displaying changed text. Find the
14868 last row in W's current matrix not affected by changes at the
14869 start of current_buffer. Value is null if changes start in the
14870 first line of window. */
14871 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
14872 if (last_unchanged_at_beg_row)
14874 /* Avoid starting to display in the moddle of a character, a TAB
14875 for instance. This is easier than to set up the iterator
14876 exactly, and it's not a frequent case, so the additional
14877 effort wouldn't really pay off. */
14878 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
14879 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
14880 && last_unchanged_at_beg_row > w->current_matrix->rows)
14881 --last_unchanged_at_beg_row;
14883 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
14884 GIVE_UP (17);
14886 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
14887 GIVE_UP (18);
14888 start_pos = it.current.pos;
14890 /* Start displaying new lines in the desired matrix at the same
14891 vpos we would use in the current matrix, i.e. below
14892 last_unchanged_at_beg_row. */
14893 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
14894 current_matrix);
14895 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
14896 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
14898 xassert (it.hpos == 0 && it.current_x == 0);
14900 else
14902 /* There are no reusable lines at the start of the window.
14903 Start displaying in the first text line. */
14904 start_display (&it, w, start);
14905 it.vpos = it.first_vpos;
14906 start_pos = it.current.pos;
14909 /* Find the first row that is not affected by changes at the end of
14910 the buffer. Value will be null if there is no unchanged row, in
14911 which case we must redisplay to the end of the window. delta
14912 will be set to the value by which buffer positions beginning with
14913 first_unchanged_at_end_row have to be adjusted due to text
14914 changes. */
14915 first_unchanged_at_end_row
14916 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
14917 IF_DEBUG (debug_delta = delta);
14918 IF_DEBUG (debug_delta_bytes = delta_bytes);
14920 /* Set stop_pos to the buffer position up to which we will have to
14921 display new lines. If first_unchanged_at_end_row != NULL, this
14922 is the buffer position of the start of the line displayed in that
14923 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
14924 that we don't stop at a buffer position. */
14925 stop_pos = 0;
14926 if (first_unchanged_at_end_row)
14928 xassert (last_unchanged_at_beg_row == NULL
14929 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
14931 /* If this is a continuation line, move forward to the next one
14932 that isn't. Changes in lines above affect this line.
14933 Caution: this may move first_unchanged_at_end_row to a row
14934 not displaying text. */
14935 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
14936 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
14937 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
14938 < it.last_visible_y))
14939 ++first_unchanged_at_end_row;
14941 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
14942 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
14943 >= it.last_visible_y))
14944 first_unchanged_at_end_row = NULL;
14945 else
14947 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
14948 + delta);
14949 first_unchanged_at_end_vpos
14950 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
14951 xassert (stop_pos >= Z - END_UNCHANGED);
14954 else if (last_unchanged_at_beg_row == NULL)
14955 GIVE_UP (19);
14958 #if GLYPH_DEBUG
14960 /* Either there is no unchanged row at the end, or the one we have
14961 now displays text. This is a necessary condition for the window
14962 end pos calculation at the end of this function. */
14963 xassert (first_unchanged_at_end_row == NULL
14964 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
14966 debug_last_unchanged_at_beg_vpos
14967 = (last_unchanged_at_beg_row
14968 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
14969 : -1);
14970 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
14972 #endif /* GLYPH_DEBUG != 0 */
14975 /* Display new lines. Set last_text_row to the last new line
14976 displayed which has text on it, i.e. might end up as being the
14977 line where the window_end_vpos is. */
14978 w->cursor.vpos = -1;
14979 last_text_row = NULL;
14980 overlay_arrow_seen = 0;
14981 while (it.current_y < it.last_visible_y
14982 && !fonts_changed_p
14983 && (first_unchanged_at_end_row == NULL
14984 || IT_CHARPOS (it) < stop_pos))
14986 if (display_line (&it))
14987 last_text_row = it.glyph_row - 1;
14990 if (fonts_changed_p)
14991 return -1;
14994 /* Compute differences in buffer positions, y-positions etc. for
14995 lines reused at the bottom of the window. Compute what we can
14996 scroll. */
14997 if (first_unchanged_at_end_row
14998 /* No lines reused because we displayed everything up to the
14999 bottom of the window. */
15000 && it.current_y < it.last_visible_y)
15002 dvpos = (it.vpos
15003 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
15004 current_matrix));
15005 dy = it.current_y - first_unchanged_at_end_row->y;
15006 run.current_y = first_unchanged_at_end_row->y;
15007 run.desired_y = run.current_y + dy;
15008 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
15010 else
15012 delta = delta_bytes = dvpos = dy
15013 = run.current_y = run.desired_y = run.height = 0;
15014 first_unchanged_at_end_row = NULL;
15016 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
15019 /* Find the cursor if not already found. We have to decide whether
15020 PT will appear on this window (it sometimes doesn't, but this is
15021 not a very frequent case.) This decision has to be made before
15022 the current matrix is altered. A value of cursor.vpos < 0 means
15023 that PT is either in one of the lines beginning at
15024 first_unchanged_at_end_row or below the window. Don't care for
15025 lines that might be displayed later at the window end; as
15026 mentioned, this is not a frequent case. */
15027 if (w->cursor.vpos < 0)
15029 /* Cursor in unchanged rows at the top? */
15030 if (PT < CHARPOS (start_pos)
15031 && last_unchanged_at_beg_row)
15033 row = row_containing_pos (w, PT,
15034 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
15035 last_unchanged_at_beg_row + 1, 0);
15036 if (row)
15037 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
15040 /* Start from first_unchanged_at_end_row looking for PT. */
15041 else if (first_unchanged_at_end_row)
15043 row = row_containing_pos (w, PT - delta,
15044 first_unchanged_at_end_row, NULL, 0);
15045 if (row)
15046 set_cursor_from_row (w, row, w->current_matrix, delta,
15047 delta_bytes, dy, dvpos);
15050 /* Give up if cursor was not found. */
15051 if (w->cursor.vpos < 0)
15053 clear_glyph_matrix (w->desired_matrix);
15054 return -1;
15058 /* Don't let the cursor end in the scroll margins. */
15060 int this_scroll_margin, cursor_height;
15062 this_scroll_margin = max (0, scroll_margin);
15063 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
15064 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
15065 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
15067 if ((w->cursor.y < this_scroll_margin
15068 && CHARPOS (start) > BEGV)
15069 /* Old redisplay didn't take scroll margin into account at the bottom,
15070 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
15071 || (w->cursor.y + (make_cursor_line_fully_visible_p
15072 ? cursor_height + this_scroll_margin
15073 : 1)) > it.last_visible_y)
15075 w->cursor.vpos = -1;
15076 clear_glyph_matrix (w->desired_matrix);
15077 return -1;
15081 /* Scroll the display. Do it before changing the current matrix so
15082 that xterm.c doesn't get confused about where the cursor glyph is
15083 found. */
15084 if (dy && run.height)
15086 update_begin (f);
15088 if (FRAME_WINDOW_P (f))
15090 FRAME_RIF (f)->update_window_begin_hook (w);
15091 FRAME_RIF (f)->clear_window_mouse_face (w);
15092 FRAME_RIF (f)->scroll_run_hook (w, &run);
15093 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
15095 else
15097 /* Terminal frame. In this case, dvpos gives the number of
15098 lines to scroll by; dvpos < 0 means scroll up. */
15099 int first_unchanged_at_end_vpos
15100 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
15101 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
15102 int end = (WINDOW_TOP_EDGE_LINE (w)
15103 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
15104 + window_internal_height (w));
15106 /* Perform the operation on the screen. */
15107 if (dvpos > 0)
15109 /* Scroll last_unchanged_at_beg_row to the end of the
15110 window down dvpos lines. */
15111 set_terminal_window (f, end);
15113 /* On dumb terminals delete dvpos lines at the end
15114 before inserting dvpos empty lines. */
15115 if (!FRAME_SCROLL_REGION_OK (f))
15116 ins_del_lines (f, end - dvpos, -dvpos);
15118 /* Insert dvpos empty lines in front of
15119 last_unchanged_at_beg_row. */
15120 ins_del_lines (f, from, dvpos);
15122 else if (dvpos < 0)
15124 /* Scroll up last_unchanged_at_beg_vpos to the end of
15125 the window to last_unchanged_at_beg_vpos - |dvpos|. */
15126 set_terminal_window (f, end);
15128 /* Delete dvpos lines in front of
15129 last_unchanged_at_beg_vpos. ins_del_lines will set
15130 the cursor to the given vpos and emit |dvpos| delete
15131 line sequences. */
15132 ins_del_lines (f, from + dvpos, dvpos);
15134 /* On a dumb terminal insert dvpos empty lines at the
15135 end. */
15136 if (!FRAME_SCROLL_REGION_OK (f))
15137 ins_del_lines (f, end + dvpos, -dvpos);
15140 set_terminal_window (f, 0);
15143 update_end (f);
15146 /* Shift reused rows of the current matrix to the right position.
15147 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
15148 text. */
15149 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
15150 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
15151 if (dvpos < 0)
15153 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
15154 bottom_vpos, dvpos);
15155 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
15156 bottom_vpos, 0);
15158 else if (dvpos > 0)
15160 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
15161 bottom_vpos, dvpos);
15162 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
15163 first_unchanged_at_end_vpos + dvpos, 0);
15166 /* For frame-based redisplay, make sure that current frame and window
15167 matrix are in sync with respect to glyph memory. */
15168 if (!FRAME_WINDOW_P (f))
15169 sync_frame_with_window_matrix_rows (w);
15171 /* Adjust buffer positions in reused rows. */
15172 if (delta || delta_bytes)
15173 increment_matrix_positions (current_matrix,
15174 first_unchanged_at_end_vpos + dvpos,
15175 bottom_vpos, delta, delta_bytes);
15177 /* Adjust Y positions. */
15178 if (dy)
15179 shift_glyph_matrix (w, current_matrix,
15180 first_unchanged_at_end_vpos + dvpos,
15181 bottom_vpos, dy);
15183 if (first_unchanged_at_end_row)
15185 first_unchanged_at_end_row += dvpos;
15186 if (first_unchanged_at_end_row->y >= it.last_visible_y
15187 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
15188 first_unchanged_at_end_row = NULL;
15191 /* If scrolling up, there may be some lines to display at the end of
15192 the window. */
15193 last_text_row_at_end = NULL;
15194 if (dy < 0)
15196 /* Scrolling up can leave for example a partially visible line
15197 at the end of the window to be redisplayed. */
15198 /* Set last_row to the glyph row in the current matrix where the
15199 window end line is found. It has been moved up or down in
15200 the matrix by dvpos. */
15201 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
15202 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
15204 /* If last_row is the window end line, it should display text. */
15205 xassert (last_row->displays_text_p);
15207 /* If window end line was partially visible before, begin
15208 displaying at that line. Otherwise begin displaying with the
15209 line following it. */
15210 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
15212 init_to_row_start (&it, w, last_row);
15213 it.vpos = last_vpos;
15214 it.current_y = last_row->y;
15216 else
15218 init_to_row_end (&it, w, last_row);
15219 it.vpos = 1 + last_vpos;
15220 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
15221 ++last_row;
15224 /* We may start in a continuation line. If so, we have to
15225 get the right continuation_lines_width and current_x. */
15226 it.continuation_lines_width = last_row->continuation_lines_width;
15227 it.hpos = it.current_x = 0;
15229 /* Display the rest of the lines at the window end. */
15230 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
15231 while (it.current_y < it.last_visible_y
15232 && !fonts_changed_p)
15234 /* Is it always sure that the display agrees with lines in
15235 the current matrix? I don't think so, so we mark rows
15236 displayed invalid in the current matrix by setting their
15237 enabled_p flag to zero. */
15238 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
15239 if (display_line (&it))
15240 last_text_row_at_end = it.glyph_row - 1;
15244 /* Update window_end_pos and window_end_vpos. */
15245 if (first_unchanged_at_end_row
15246 && !last_text_row_at_end)
15248 /* Window end line if one of the preserved rows from the current
15249 matrix. Set row to the last row displaying text in current
15250 matrix starting at first_unchanged_at_end_row, after
15251 scrolling. */
15252 xassert (first_unchanged_at_end_row->displays_text_p);
15253 row = find_last_row_displaying_text (w->current_matrix, &it,
15254 first_unchanged_at_end_row);
15255 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
15257 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
15258 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
15259 w->window_end_vpos
15260 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
15261 xassert (w->window_end_bytepos >= 0);
15262 IF_DEBUG (debug_method_add (w, "A"));
15264 else if (last_text_row_at_end)
15266 w->window_end_pos
15267 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
15268 w->window_end_bytepos
15269 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
15270 w->window_end_vpos
15271 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
15272 xassert (w->window_end_bytepos >= 0);
15273 IF_DEBUG (debug_method_add (w, "B"));
15275 else if (last_text_row)
15277 /* We have displayed either to the end of the window or at the
15278 end of the window, i.e. the last row with text is to be found
15279 in the desired matrix. */
15280 w->window_end_pos
15281 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
15282 w->window_end_bytepos
15283 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
15284 w->window_end_vpos
15285 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
15286 xassert (w->window_end_bytepos >= 0);
15288 else if (first_unchanged_at_end_row == NULL
15289 && last_text_row == NULL
15290 && last_text_row_at_end == NULL)
15292 /* Displayed to end of window, but no line containing text was
15293 displayed. Lines were deleted at the end of the window. */
15294 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
15295 int vpos = XFASTINT (w->window_end_vpos);
15296 struct glyph_row *current_row = current_matrix->rows + vpos;
15297 struct glyph_row *desired_row = desired_matrix->rows + vpos;
15299 for (row = NULL;
15300 row == NULL && vpos >= first_vpos;
15301 --vpos, --current_row, --desired_row)
15303 if (desired_row->enabled_p)
15305 if (desired_row->displays_text_p)
15306 row = desired_row;
15308 else if (current_row->displays_text_p)
15309 row = current_row;
15312 xassert (row != NULL);
15313 w->window_end_vpos = make_number (vpos + 1);
15314 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
15315 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
15316 xassert (w->window_end_bytepos >= 0);
15317 IF_DEBUG (debug_method_add (w, "C"));
15319 else
15320 abort ();
15322 #if 0 /* This leads to problems, for instance when the cursor is
15323 at ZV, and the cursor line displays no text. */
15324 /* Disable rows below what's displayed in the window. This makes
15325 debugging easier. */
15326 enable_glyph_matrix_rows (current_matrix,
15327 XFASTINT (w->window_end_vpos) + 1,
15328 bottom_vpos, 0);
15329 #endif
15331 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
15332 debug_end_vpos = XFASTINT (w->window_end_vpos));
15334 /* Record that display has not been completed. */
15335 w->window_end_valid = Qnil;
15336 w->desired_matrix->no_scrolling_p = 1;
15337 return 3;
15339 #undef GIVE_UP
15344 /***********************************************************************
15345 More debugging support
15346 ***********************************************************************/
15348 #if GLYPH_DEBUG
15350 void dump_glyph_row P_ ((struct glyph_row *, int, int));
15351 void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
15352 void dump_glyph P_ ((struct glyph_row *, struct glyph *, int));
15355 /* Dump the contents of glyph matrix MATRIX on stderr.
15357 GLYPHS 0 means don't show glyph contents.
15358 GLYPHS 1 means show glyphs in short form
15359 GLYPHS > 1 means show glyphs in long form. */
15361 void
15362 dump_glyph_matrix (matrix, glyphs)
15363 struct glyph_matrix *matrix;
15364 int glyphs;
15366 int i;
15367 for (i = 0; i < matrix->nrows; ++i)
15368 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
15372 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
15373 the glyph row and area where the glyph comes from. */
15375 void
15376 dump_glyph (row, glyph, area)
15377 struct glyph_row *row;
15378 struct glyph *glyph;
15379 int area;
15381 if (glyph->type == CHAR_GLYPH)
15383 fprintf (stderr,
15384 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
15385 glyph - row->glyphs[TEXT_AREA],
15386 'C',
15387 glyph->charpos,
15388 (BUFFERP (glyph->object)
15389 ? 'B'
15390 : (STRINGP (glyph->object)
15391 ? 'S'
15392 : '-')),
15393 glyph->pixel_width,
15394 glyph->u.ch,
15395 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
15396 ? glyph->u.ch
15397 : '.'),
15398 glyph->face_id,
15399 glyph->left_box_line_p,
15400 glyph->right_box_line_p);
15402 else if (glyph->type == STRETCH_GLYPH)
15404 fprintf (stderr,
15405 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
15406 glyph - row->glyphs[TEXT_AREA],
15407 'S',
15408 glyph->charpos,
15409 (BUFFERP (glyph->object)
15410 ? 'B'
15411 : (STRINGP (glyph->object)
15412 ? 'S'
15413 : '-')),
15414 glyph->pixel_width,
15416 '.',
15417 glyph->face_id,
15418 glyph->left_box_line_p,
15419 glyph->right_box_line_p);
15421 else if (glyph->type == IMAGE_GLYPH)
15423 fprintf (stderr,
15424 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
15425 glyph - row->glyphs[TEXT_AREA],
15426 'I',
15427 glyph->charpos,
15428 (BUFFERP (glyph->object)
15429 ? 'B'
15430 : (STRINGP (glyph->object)
15431 ? 'S'
15432 : '-')),
15433 glyph->pixel_width,
15434 glyph->u.img_id,
15435 '.',
15436 glyph->face_id,
15437 glyph->left_box_line_p,
15438 glyph->right_box_line_p);
15440 else if (glyph->type == COMPOSITE_GLYPH)
15442 fprintf (stderr,
15443 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
15444 glyph - row->glyphs[TEXT_AREA],
15445 '+',
15446 glyph->charpos,
15447 (BUFFERP (glyph->object)
15448 ? 'B'
15449 : (STRINGP (glyph->object)
15450 ? 'S'
15451 : '-')),
15452 glyph->pixel_width,
15453 glyph->u.cmp_id,
15454 '.',
15455 glyph->face_id,
15456 glyph->left_box_line_p,
15457 glyph->right_box_line_p);
15462 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
15463 GLYPHS 0 means don't show glyph contents.
15464 GLYPHS 1 means show glyphs in short form
15465 GLYPHS > 1 means show glyphs in long form. */
15467 void
15468 dump_glyph_row (row, vpos, glyphs)
15469 struct glyph_row *row;
15470 int vpos, glyphs;
15472 if (glyphs != 1)
15474 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
15475 fprintf (stderr, "======================================================================\n");
15477 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d\
15478 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
15479 vpos,
15480 MATRIX_ROW_START_CHARPOS (row),
15481 MATRIX_ROW_END_CHARPOS (row),
15482 row->used[TEXT_AREA],
15483 row->contains_overlapping_glyphs_p,
15484 row->enabled_p,
15485 row->truncated_on_left_p,
15486 row->truncated_on_right_p,
15487 row->continued_p,
15488 MATRIX_ROW_CONTINUATION_LINE_P (row),
15489 row->displays_text_p,
15490 row->ends_at_zv_p,
15491 row->fill_line_p,
15492 row->ends_in_middle_of_char_p,
15493 row->starts_in_middle_of_char_p,
15494 row->mouse_face_p,
15495 row->x,
15496 row->y,
15497 row->pixel_width,
15498 row->height,
15499 row->visible_height,
15500 row->ascent,
15501 row->phys_ascent);
15502 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
15503 row->end.overlay_string_index,
15504 row->continuation_lines_width);
15505 fprintf (stderr, "%9d %5d\n",
15506 CHARPOS (row->start.string_pos),
15507 CHARPOS (row->end.string_pos));
15508 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
15509 row->end.dpvec_index);
15512 if (glyphs > 1)
15514 int area;
15516 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
15518 struct glyph *glyph = row->glyphs[area];
15519 struct glyph *glyph_end = glyph + row->used[area];
15521 /* Glyph for a line end in text. */
15522 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
15523 ++glyph_end;
15525 if (glyph < glyph_end)
15526 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
15528 for (; glyph < glyph_end; ++glyph)
15529 dump_glyph (row, glyph, area);
15532 else if (glyphs == 1)
15534 int area;
15536 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
15538 char *s = (char *) alloca (row->used[area] + 1);
15539 int i;
15541 for (i = 0; i < row->used[area]; ++i)
15543 struct glyph *glyph = row->glyphs[area] + i;
15544 if (glyph->type == CHAR_GLYPH
15545 && glyph->u.ch < 0x80
15546 && glyph->u.ch >= ' ')
15547 s[i] = glyph->u.ch;
15548 else
15549 s[i] = '.';
15552 s[i] = '\0';
15553 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
15559 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
15560 Sdump_glyph_matrix, 0, 1, "p",
15561 doc: /* Dump the current matrix of the selected window to stderr.
15562 Shows contents of glyph row structures. With non-nil
15563 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
15564 glyphs in short form, otherwise show glyphs in long form. */)
15565 (glyphs)
15566 Lisp_Object glyphs;
15568 struct window *w = XWINDOW (selected_window);
15569 struct buffer *buffer = XBUFFER (w->buffer);
15571 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
15572 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
15573 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
15574 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
15575 fprintf (stderr, "=============================================\n");
15576 dump_glyph_matrix (w->current_matrix,
15577 NILP (glyphs) ? 0 : XINT (glyphs));
15578 return Qnil;
15582 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
15583 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
15586 struct frame *f = XFRAME (selected_frame);
15587 dump_glyph_matrix (f->current_matrix, 1);
15588 return Qnil;
15592 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
15593 doc: /* Dump glyph row ROW to stderr.
15594 GLYPH 0 means don't dump glyphs.
15595 GLYPH 1 means dump glyphs in short form.
15596 GLYPH > 1 or omitted means dump glyphs in long form. */)
15597 (row, glyphs)
15598 Lisp_Object row, glyphs;
15600 struct glyph_matrix *matrix;
15601 int vpos;
15603 CHECK_NUMBER (row);
15604 matrix = XWINDOW (selected_window)->current_matrix;
15605 vpos = XINT (row);
15606 if (vpos >= 0 && vpos < matrix->nrows)
15607 dump_glyph_row (MATRIX_ROW (matrix, vpos),
15608 vpos,
15609 INTEGERP (glyphs) ? XINT (glyphs) : 2);
15610 return Qnil;
15614 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
15615 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
15616 GLYPH 0 means don't dump glyphs.
15617 GLYPH 1 means dump glyphs in short form.
15618 GLYPH > 1 or omitted means dump glyphs in long form. */)
15619 (row, glyphs)
15620 Lisp_Object row, glyphs;
15622 struct frame *sf = SELECTED_FRAME ();
15623 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
15624 int vpos;
15626 CHECK_NUMBER (row);
15627 vpos = XINT (row);
15628 if (vpos >= 0 && vpos < m->nrows)
15629 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
15630 INTEGERP (glyphs) ? XINT (glyphs) : 2);
15631 return Qnil;
15635 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
15636 doc: /* Toggle tracing of redisplay.
15637 With ARG, turn tracing on if and only if ARG is positive. */)
15638 (arg)
15639 Lisp_Object arg;
15641 if (NILP (arg))
15642 trace_redisplay_p = !trace_redisplay_p;
15643 else
15645 arg = Fprefix_numeric_value (arg);
15646 trace_redisplay_p = XINT (arg) > 0;
15649 return Qnil;
15653 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
15654 doc: /* Like `format', but print result to stderr.
15655 usage: (trace-to-stderr STRING &rest OBJECTS) */)
15656 (nargs, args)
15657 int nargs;
15658 Lisp_Object *args;
15660 Lisp_Object s = Fformat (nargs, args);
15661 fprintf (stderr, "%s", SDATA (s));
15662 return Qnil;
15665 #endif /* GLYPH_DEBUG */
15669 /***********************************************************************
15670 Building Desired Matrix Rows
15671 ***********************************************************************/
15673 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
15674 Used for non-window-redisplay windows, and for windows w/o left fringe. */
15676 static struct glyph_row *
15677 get_overlay_arrow_glyph_row (w, overlay_arrow_string)
15678 struct window *w;
15679 Lisp_Object overlay_arrow_string;
15681 struct frame *f = XFRAME (WINDOW_FRAME (w));
15682 struct buffer *buffer = XBUFFER (w->buffer);
15683 struct buffer *old = current_buffer;
15684 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
15685 int arrow_len = SCHARS (overlay_arrow_string);
15686 const unsigned char *arrow_end = arrow_string + arrow_len;
15687 const unsigned char *p;
15688 struct it it;
15689 int multibyte_p;
15690 int n_glyphs_before;
15692 set_buffer_temp (buffer);
15693 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
15694 it.glyph_row->used[TEXT_AREA] = 0;
15695 SET_TEXT_POS (it.position, 0, 0);
15697 multibyte_p = !NILP (buffer->enable_multibyte_characters);
15698 p = arrow_string;
15699 while (p < arrow_end)
15701 Lisp_Object face, ilisp;
15703 /* Get the next character. */
15704 if (multibyte_p)
15705 it.c = string_char_and_length (p, arrow_len, &it.len);
15706 else
15707 it.c = *p, it.len = 1;
15708 p += it.len;
15710 /* Get its face. */
15711 ilisp = make_number (p - arrow_string);
15712 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
15713 it.face_id = compute_char_face (f, it.c, face);
15715 /* Compute its width, get its glyphs. */
15716 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
15717 SET_TEXT_POS (it.position, -1, -1);
15718 PRODUCE_GLYPHS (&it);
15720 /* If this character doesn't fit any more in the line, we have
15721 to remove some glyphs. */
15722 if (it.current_x > it.last_visible_x)
15724 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
15725 break;
15729 set_buffer_temp (old);
15730 return it.glyph_row;
15734 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
15735 glyphs are only inserted for terminal frames since we can't really
15736 win with truncation glyphs when partially visible glyphs are
15737 involved. Which glyphs to insert is determined by
15738 produce_special_glyphs. */
15740 static void
15741 insert_left_trunc_glyphs (it)
15742 struct it *it;
15744 struct it truncate_it;
15745 struct glyph *from, *end, *to, *toend;
15747 xassert (!FRAME_WINDOW_P (it->f));
15749 /* Get the truncation glyphs. */
15750 truncate_it = *it;
15751 truncate_it.current_x = 0;
15752 truncate_it.face_id = DEFAULT_FACE_ID;
15753 truncate_it.glyph_row = &scratch_glyph_row;
15754 truncate_it.glyph_row->used[TEXT_AREA] = 0;
15755 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
15756 truncate_it.object = make_number (0);
15757 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
15759 /* Overwrite glyphs from IT with truncation glyphs. */
15760 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
15761 end = from + truncate_it.glyph_row->used[TEXT_AREA];
15762 to = it->glyph_row->glyphs[TEXT_AREA];
15763 toend = to + it->glyph_row->used[TEXT_AREA];
15765 while (from < end)
15766 *to++ = *from++;
15768 /* There may be padding glyphs left over. Overwrite them too. */
15769 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
15771 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
15772 while (from < end)
15773 *to++ = *from++;
15776 if (to > toend)
15777 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
15781 /* Compute the pixel height and width of IT->glyph_row.
15783 Most of the time, ascent and height of a display line will be equal
15784 to the max_ascent and max_height values of the display iterator
15785 structure. This is not the case if
15787 1. We hit ZV without displaying anything. In this case, max_ascent
15788 and max_height will be zero.
15790 2. We have some glyphs that don't contribute to the line height.
15791 (The glyph row flag contributes_to_line_height_p is for future
15792 pixmap extensions).
15794 The first case is easily covered by using default values because in
15795 these cases, the line height does not really matter, except that it
15796 must not be zero. */
15798 static void
15799 compute_line_metrics (it)
15800 struct it *it;
15802 struct glyph_row *row = it->glyph_row;
15803 int area, i;
15805 if (FRAME_WINDOW_P (it->f))
15807 int i, min_y, max_y;
15809 /* The line may consist of one space only, that was added to
15810 place the cursor on it. If so, the row's height hasn't been
15811 computed yet. */
15812 if (row->height == 0)
15814 if (it->max_ascent + it->max_descent == 0)
15815 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
15816 row->ascent = it->max_ascent;
15817 row->height = it->max_ascent + it->max_descent;
15818 row->phys_ascent = it->max_phys_ascent;
15819 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
15820 row->extra_line_spacing = it->max_extra_line_spacing;
15823 /* Compute the width of this line. */
15824 row->pixel_width = row->x;
15825 for (i = 0; i < row->used[TEXT_AREA]; ++i)
15826 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
15828 xassert (row->pixel_width >= 0);
15829 xassert (row->ascent >= 0 && row->height > 0);
15831 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
15832 || MATRIX_ROW_OVERLAPS_PRED_P (row));
15834 /* If first line's physical ascent is larger than its logical
15835 ascent, use the physical ascent, and make the row taller.
15836 This makes accented characters fully visible. */
15837 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
15838 && row->phys_ascent > row->ascent)
15840 row->height += row->phys_ascent - row->ascent;
15841 row->ascent = row->phys_ascent;
15844 /* Compute how much of the line is visible. */
15845 row->visible_height = row->height;
15847 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
15848 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
15850 if (row->y < min_y)
15851 row->visible_height -= min_y - row->y;
15852 if (row->y + row->height > max_y)
15853 row->visible_height -= row->y + row->height - max_y;
15855 else
15857 row->pixel_width = row->used[TEXT_AREA];
15858 if (row->continued_p)
15859 row->pixel_width -= it->continuation_pixel_width;
15860 else if (row->truncated_on_right_p)
15861 row->pixel_width -= it->truncation_pixel_width;
15862 row->ascent = row->phys_ascent = 0;
15863 row->height = row->phys_height = row->visible_height = 1;
15864 row->extra_line_spacing = 0;
15867 /* Compute a hash code for this row. */
15868 row->hash = 0;
15869 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
15870 for (i = 0; i < row->used[area]; ++i)
15871 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
15872 + row->glyphs[area][i].u.val
15873 + row->glyphs[area][i].face_id
15874 + row->glyphs[area][i].padding_p
15875 + (row->glyphs[area][i].type << 2));
15877 it->max_ascent = it->max_descent = 0;
15878 it->max_phys_ascent = it->max_phys_descent = 0;
15882 /* Append one space to the glyph row of iterator IT if doing a
15883 window-based redisplay. The space has the same face as
15884 IT->face_id. Value is non-zero if a space was added.
15886 This function is called to make sure that there is always one glyph
15887 at the end of a glyph row that the cursor can be set on under
15888 window-systems. (If there weren't such a glyph we would not know
15889 how wide and tall a box cursor should be displayed).
15891 At the same time this space let's a nicely handle clearing to the
15892 end of the line if the row ends in italic text. */
15894 static int
15895 append_space_for_newline (it, default_face_p)
15896 struct it *it;
15897 int default_face_p;
15899 if (FRAME_WINDOW_P (it->f))
15901 int n = it->glyph_row->used[TEXT_AREA];
15903 if (it->glyph_row->glyphs[TEXT_AREA] + n
15904 < it->glyph_row->glyphs[1 + TEXT_AREA])
15906 /* Save some values that must not be changed.
15907 Must save IT->c and IT->len because otherwise
15908 ITERATOR_AT_END_P wouldn't work anymore after
15909 append_space_for_newline has been called. */
15910 enum display_element_type saved_what = it->what;
15911 int saved_c = it->c, saved_len = it->len;
15912 int saved_x = it->current_x;
15913 int saved_face_id = it->face_id;
15914 struct text_pos saved_pos;
15915 Lisp_Object saved_object;
15916 struct face *face;
15918 saved_object = it->object;
15919 saved_pos = it->position;
15921 it->what = IT_CHARACTER;
15922 bzero (&it->position, sizeof it->position);
15923 it->object = make_number (0);
15924 it->c = ' ';
15925 it->len = 1;
15927 if (default_face_p)
15928 it->face_id = DEFAULT_FACE_ID;
15929 else if (it->face_before_selective_p)
15930 it->face_id = it->saved_face_id;
15931 face = FACE_FROM_ID (it->f, it->face_id);
15932 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
15934 PRODUCE_GLYPHS (it);
15936 it->override_ascent = -1;
15937 it->constrain_row_ascent_descent_p = 0;
15938 it->current_x = saved_x;
15939 it->object = saved_object;
15940 it->position = saved_pos;
15941 it->what = saved_what;
15942 it->face_id = saved_face_id;
15943 it->len = saved_len;
15944 it->c = saved_c;
15945 return 1;
15949 return 0;
15953 /* Extend the face of the last glyph in the text area of IT->glyph_row
15954 to the end of the display line. Called from display_line.
15955 If the glyph row is empty, add a space glyph to it so that we
15956 know the face to draw. Set the glyph row flag fill_line_p. */
15958 static void
15959 extend_face_to_end_of_line (it)
15960 struct it *it;
15962 struct face *face;
15963 struct frame *f = it->f;
15965 /* If line is already filled, do nothing. */
15966 if (it->current_x >= it->last_visible_x)
15967 return;
15969 /* Face extension extends the background and box of IT->face_id
15970 to the end of the line. If the background equals the background
15971 of the frame, we don't have to do anything. */
15972 if (it->face_before_selective_p)
15973 face = FACE_FROM_ID (it->f, it->saved_face_id);
15974 else
15975 face = FACE_FROM_ID (f, it->face_id);
15977 if (FRAME_WINDOW_P (f)
15978 && it->glyph_row->displays_text_p
15979 && face->box == FACE_NO_BOX
15980 && face->background == FRAME_BACKGROUND_PIXEL (f)
15981 && !face->stipple)
15982 return;
15984 /* Set the glyph row flag indicating that the face of the last glyph
15985 in the text area has to be drawn to the end of the text area. */
15986 it->glyph_row->fill_line_p = 1;
15988 /* If current character of IT is not ASCII, make sure we have the
15989 ASCII face. This will be automatically undone the next time
15990 get_next_display_element returns a multibyte character. Note
15991 that the character will always be single byte in unibyte text. */
15992 if (!ASCII_CHAR_P (it->c))
15994 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
15997 if (FRAME_WINDOW_P (f))
15999 /* If the row is empty, add a space with the current face of IT,
16000 so that we know which face to draw. */
16001 if (it->glyph_row->used[TEXT_AREA] == 0)
16003 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
16004 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
16005 it->glyph_row->used[TEXT_AREA] = 1;
16008 else
16010 /* Save some values that must not be changed. */
16011 int saved_x = it->current_x;
16012 struct text_pos saved_pos;
16013 Lisp_Object saved_object;
16014 enum display_element_type saved_what = it->what;
16015 int saved_face_id = it->face_id;
16017 saved_object = it->object;
16018 saved_pos = it->position;
16020 it->what = IT_CHARACTER;
16021 bzero (&it->position, sizeof it->position);
16022 it->object = make_number (0);
16023 it->c = ' ';
16024 it->len = 1;
16025 it->face_id = face->id;
16027 PRODUCE_GLYPHS (it);
16029 while (it->current_x <= it->last_visible_x)
16030 PRODUCE_GLYPHS (it);
16032 /* Don't count these blanks really. It would let us insert a left
16033 truncation glyph below and make us set the cursor on them, maybe. */
16034 it->current_x = saved_x;
16035 it->object = saved_object;
16036 it->position = saved_pos;
16037 it->what = saved_what;
16038 it->face_id = saved_face_id;
16043 /* Value is non-zero if text starting at CHARPOS in current_buffer is
16044 trailing whitespace. */
16046 static int
16047 trailing_whitespace_p (charpos)
16048 int charpos;
16050 int bytepos = CHAR_TO_BYTE (charpos);
16051 int c = 0;
16053 while (bytepos < ZV_BYTE
16054 && (c = FETCH_CHAR (bytepos),
16055 c == ' ' || c == '\t'))
16056 ++bytepos;
16058 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
16060 if (bytepos != PT_BYTE)
16061 return 1;
16063 return 0;
16067 /* Highlight trailing whitespace, if any, in ROW. */
16069 void
16070 highlight_trailing_whitespace (f, row)
16071 struct frame *f;
16072 struct glyph_row *row;
16074 int used = row->used[TEXT_AREA];
16076 if (used)
16078 struct glyph *start = row->glyphs[TEXT_AREA];
16079 struct glyph *glyph = start + used - 1;
16081 /* Skip over glyphs inserted to display the cursor at the
16082 end of a line, for extending the face of the last glyph
16083 to the end of the line on terminals, and for truncation
16084 and continuation glyphs. */
16085 while (glyph >= start
16086 && glyph->type == CHAR_GLYPH
16087 && INTEGERP (glyph->object))
16088 --glyph;
16090 /* If last glyph is a space or stretch, and it's trailing
16091 whitespace, set the face of all trailing whitespace glyphs in
16092 IT->glyph_row to `trailing-whitespace'. */
16093 if (glyph >= start
16094 && BUFFERP (glyph->object)
16095 && (glyph->type == STRETCH_GLYPH
16096 || (glyph->type == CHAR_GLYPH
16097 && glyph->u.ch == ' '))
16098 && trailing_whitespace_p (glyph->charpos))
16100 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
16101 if (face_id < 0)
16102 return;
16104 while (glyph >= start
16105 && BUFFERP (glyph->object)
16106 && (glyph->type == STRETCH_GLYPH
16107 || (glyph->type == CHAR_GLYPH
16108 && glyph->u.ch == ' ')))
16109 (glyph--)->face_id = face_id;
16115 /* Value is non-zero if glyph row ROW in window W should be
16116 used to hold the cursor. */
16118 static int
16119 cursor_row_p (w, row)
16120 struct window *w;
16121 struct glyph_row *row;
16123 int cursor_row_p = 1;
16125 if (PT == MATRIX_ROW_END_CHARPOS (row))
16127 /* Suppose the row ends on a string.
16128 Unless the row is continued, that means it ends on a newline
16129 in the string. If it's anything other than a display string
16130 (e.g. a before-string from an overlay), we don't want the
16131 cursor there. (This heuristic seems to give the optimal
16132 behavior for the various types of multi-line strings.) */
16133 if (CHARPOS (row->end.string_pos) >= 0)
16135 if (row->continued_p)
16136 cursor_row_p = 1;
16137 else
16139 /* Check for `display' property. */
16140 struct glyph *beg = row->glyphs[TEXT_AREA];
16141 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
16142 struct glyph *glyph;
16144 cursor_row_p = 0;
16145 for (glyph = end; glyph >= beg; --glyph)
16146 if (STRINGP (glyph->object))
16148 Lisp_Object prop
16149 = Fget_char_property (make_number (PT),
16150 Qdisplay, Qnil);
16151 cursor_row_p =
16152 (!NILP (prop)
16153 && display_prop_string_p (prop, glyph->object));
16154 break;
16158 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
16160 /* If the row ends in middle of a real character,
16161 and the line is continued, we want the cursor here.
16162 That's because MATRIX_ROW_END_CHARPOS would equal
16163 PT if PT is before the character. */
16164 if (!row->ends_in_ellipsis_p)
16165 cursor_row_p = row->continued_p;
16166 else
16167 /* If the row ends in an ellipsis, then
16168 MATRIX_ROW_END_CHARPOS will equal point after the invisible text.
16169 We want that position to be displayed after the ellipsis. */
16170 cursor_row_p = 0;
16172 /* If the row ends at ZV, display the cursor at the end of that
16173 row instead of at the start of the row below. */
16174 else if (row->ends_at_zv_p)
16175 cursor_row_p = 1;
16176 else
16177 cursor_row_p = 0;
16180 return cursor_row_p;
16184 /* Construct the glyph row IT->glyph_row in the desired matrix of
16185 IT->w from text at the current position of IT. See dispextern.h
16186 for an overview of struct it. Value is non-zero if
16187 IT->glyph_row displays text, as opposed to a line displaying ZV
16188 only. */
16190 static int
16191 display_line (it)
16192 struct it *it;
16194 struct glyph_row *row = it->glyph_row;
16195 Lisp_Object overlay_arrow_string;
16197 /* We always start displaying at hpos zero even if hscrolled. */
16198 xassert (it->hpos == 0 && it->current_x == 0);
16200 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
16201 >= it->w->desired_matrix->nrows)
16203 it->w->nrows_scale_factor++;
16204 fonts_changed_p = 1;
16205 return 0;
16208 /* Is IT->w showing the region? */
16209 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
16211 /* Clear the result glyph row and enable it. */
16212 prepare_desired_row (row);
16214 row->y = it->current_y;
16215 row->start = it->start;
16216 row->continuation_lines_width = it->continuation_lines_width;
16217 row->displays_text_p = 1;
16218 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
16219 it->starts_in_middle_of_char_p = 0;
16221 /* Arrange the overlays nicely for our purposes. Usually, we call
16222 display_line on only one line at a time, in which case this
16223 can't really hurt too much, or we call it on lines which appear
16224 one after another in the buffer, in which case all calls to
16225 recenter_overlay_lists but the first will be pretty cheap. */
16226 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
16228 /* Move over display elements that are not visible because we are
16229 hscrolled. This may stop at an x-position < IT->first_visible_x
16230 if the first glyph is partially visible or if we hit a line end. */
16231 if (it->current_x < it->first_visible_x)
16233 move_it_in_display_line_to (it, ZV, it->first_visible_x,
16234 MOVE_TO_POS | MOVE_TO_X);
16237 /* Get the initial row height. This is either the height of the
16238 text hscrolled, if there is any, or zero. */
16239 row->ascent = it->max_ascent;
16240 row->height = it->max_ascent + it->max_descent;
16241 row->phys_ascent = it->max_phys_ascent;
16242 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
16243 row->extra_line_spacing = it->max_extra_line_spacing;
16245 /* Loop generating characters. The loop is left with IT on the next
16246 character to display. */
16247 while (1)
16249 int n_glyphs_before, hpos_before, x_before;
16250 int x, i, nglyphs;
16251 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
16253 /* Retrieve the next thing to display. Value is zero if end of
16254 buffer reached. */
16255 if (!get_next_display_element (it))
16257 /* Maybe add a space at the end of this line that is used to
16258 display the cursor there under X. Set the charpos of the
16259 first glyph of blank lines not corresponding to any text
16260 to -1. */
16261 #ifdef HAVE_WINDOW_SYSTEM
16262 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
16263 row->exact_window_width_line_p = 1;
16264 else
16265 #endif /* HAVE_WINDOW_SYSTEM */
16266 if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
16267 || row->used[TEXT_AREA] == 0)
16269 row->glyphs[TEXT_AREA]->charpos = -1;
16270 row->displays_text_p = 0;
16272 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
16273 && (!MINI_WINDOW_P (it->w)
16274 || (minibuf_level && EQ (it->window, minibuf_window))))
16275 row->indicate_empty_line_p = 1;
16278 it->continuation_lines_width = 0;
16279 row->ends_at_zv_p = 1;
16280 break;
16283 /* Now, get the metrics of what we want to display. This also
16284 generates glyphs in `row' (which is IT->glyph_row). */
16285 n_glyphs_before = row->used[TEXT_AREA];
16286 x = it->current_x;
16288 /* Remember the line height so far in case the next element doesn't
16289 fit on the line. */
16290 if (!it->truncate_lines_p)
16292 ascent = it->max_ascent;
16293 descent = it->max_descent;
16294 phys_ascent = it->max_phys_ascent;
16295 phys_descent = it->max_phys_descent;
16298 PRODUCE_GLYPHS (it);
16300 /* If this display element was in marginal areas, continue with
16301 the next one. */
16302 if (it->area != TEXT_AREA)
16304 row->ascent = max (row->ascent, it->max_ascent);
16305 row->height = max (row->height, it->max_ascent + it->max_descent);
16306 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16307 row->phys_height = max (row->phys_height,
16308 it->max_phys_ascent + it->max_phys_descent);
16309 row->extra_line_spacing = max (row->extra_line_spacing,
16310 it->max_extra_line_spacing);
16311 set_iterator_to_next (it, 1);
16312 continue;
16315 /* Does the display element fit on the line? If we truncate
16316 lines, we should draw past the right edge of the window. If
16317 we don't truncate, we want to stop so that we can display the
16318 continuation glyph before the right margin. If lines are
16319 continued, there are two possible strategies for characters
16320 resulting in more than 1 glyph (e.g. tabs): Display as many
16321 glyphs as possible in this line and leave the rest for the
16322 continuation line, or display the whole element in the next
16323 line. Original redisplay did the former, so we do it also. */
16324 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
16325 hpos_before = it->hpos;
16326 x_before = x;
16328 if (/* Not a newline. */
16329 nglyphs > 0
16330 /* Glyphs produced fit entirely in the line. */
16331 && it->current_x < it->last_visible_x)
16333 it->hpos += nglyphs;
16334 row->ascent = max (row->ascent, it->max_ascent);
16335 row->height = max (row->height, it->max_ascent + it->max_descent);
16336 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16337 row->phys_height = max (row->phys_height,
16338 it->max_phys_ascent + it->max_phys_descent);
16339 row->extra_line_spacing = max (row->extra_line_spacing,
16340 it->max_extra_line_spacing);
16341 if (it->current_x - it->pixel_width < it->first_visible_x)
16342 row->x = x - it->first_visible_x;
16344 else
16346 int new_x;
16347 struct glyph *glyph;
16349 for (i = 0; i < nglyphs; ++i, x = new_x)
16351 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
16352 new_x = x + glyph->pixel_width;
16354 if (/* Lines are continued. */
16355 !it->truncate_lines_p
16356 && (/* Glyph doesn't fit on the line. */
16357 new_x > it->last_visible_x
16358 /* Or it fits exactly on a window system frame. */
16359 || (new_x == it->last_visible_x
16360 && FRAME_WINDOW_P (it->f))))
16362 /* End of a continued line. */
16364 if (it->hpos == 0
16365 || (new_x == it->last_visible_x
16366 && FRAME_WINDOW_P (it->f)))
16368 /* Current glyph is the only one on the line or
16369 fits exactly on the line. We must continue
16370 the line because we can't draw the cursor
16371 after the glyph. */
16372 row->continued_p = 1;
16373 it->current_x = new_x;
16374 it->continuation_lines_width += new_x;
16375 ++it->hpos;
16376 if (i == nglyphs - 1)
16378 set_iterator_to_next (it, 1);
16379 #ifdef HAVE_WINDOW_SYSTEM
16380 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
16382 if (!get_next_display_element (it))
16384 row->exact_window_width_line_p = 1;
16385 it->continuation_lines_width = 0;
16386 row->continued_p = 0;
16387 row->ends_at_zv_p = 1;
16389 else if (ITERATOR_AT_END_OF_LINE_P (it))
16391 row->continued_p = 0;
16392 row->exact_window_width_line_p = 1;
16395 #endif /* HAVE_WINDOW_SYSTEM */
16398 else if (CHAR_GLYPH_PADDING_P (*glyph)
16399 && !FRAME_WINDOW_P (it->f))
16401 /* A padding glyph that doesn't fit on this line.
16402 This means the whole character doesn't fit
16403 on the line. */
16404 row->used[TEXT_AREA] = n_glyphs_before;
16406 /* Fill the rest of the row with continuation
16407 glyphs like in 20.x. */
16408 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
16409 < row->glyphs[1 + TEXT_AREA])
16410 produce_special_glyphs (it, IT_CONTINUATION);
16412 row->continued_p = 1;
16413 it->current_x = x_before;
16414 it->continuation_lines_width += x_before;
16416 /* Restore the height to what it was before the
16417 element not fitting on the line. */
16418 it->max_ascent = ascent;
16419 it->max_descent = descent;
16420 it->max_phys_ascent = phys_ascent;
16421 it->max_phys_descent = phys_descent;
16423 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
16425 /* A TAB that extends past the right edge of the
16426 window. This produces a single glyph on
16427 window system frames. We leave the glyph in
16428 this row and let it fill the row, but don't
16429 consume the TAB. */
16430 it->continuation_lines_width += it->last_visible_x;
16431 row->ends_in_middle_of_char_p = 1;
16432 row->continued_p = 1;
16433 glyph->pixel_width = it->last_visible_x - x;
16434 it->starts_in_middle_of_char_p = 1;
16436 else
16438 /* Something other than a TAB that draws past
16439 the right edge of the window. Restore
16440 positions to values before the element. */
16441 row->used[TEXT_AREA] = n_glyphs_before + i;
16443 /* Display continuation glyphs. */
16444 if (!FRAME_WINDOW_P (it->f))
16445 produce_special_glyphs (it, IT_CONTINUATION);
16446 row->continued_p = 1;
16448 it->current_x = x_before;
16449 it->continuation_lines_width += x;
16450 extend_face_to_end_of_line (it);
16452 if (nglyphs > 1 && i > 0)
16454 row->ends_in_middle_of_char_p = 1;
16455 it->starts_in_middle_of_char_p = 1;
16458 /* Restore the height to what it was before the
16459 element not fitting on the line. */
16460 it->max_ascent = ascent;
16461 it->max_descent = descent;
16462 it->max_phys_ascent = phys_ascent;
16463 it->max_phys_descent = phys_descent;
16466 break;
16468 else if (new_x > it->first_visible_x)
16470 /* Increment number of glyphs actually displayed. */
16471 ++it->hpos;
16473 if (x < it->first_visible_x)
16474 /* Glyph is partially visible, i.e. row starts at
16475 negative X position. */
16476 row->x = x - it->first_visible_x;
16478 else
16480 /* Glyph is completely off the left margin of the
16481 window. This should not happen because of the
16482 move_it_in_display_line at the start of this
16483 function, unless the text display area of the
16484 window is empty. */
16485 xassert (it->first_visible_x <= it->last_visible_x);
16489 row->ascent = max (row->ascent, it->max_ascent);
16490 row->height = max (row->height, it->max_ascent + it->max_descent);
16491 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16492 row->phys_height = max (row->phys_height,
16493 it->max_phys_ascent + it->max_phys_descent);
16494 row->extra_line_spacing = max (row->extra_line_spacing,
16495 it->max_extra_line_spacing);
16497 /* End of this display line if row is continued. */
16498 if (row->continued_p || row->ends_at_zv_p)
16499 break;
16502 at_end_of_line:
16503 /* Is this a line end? If yes, we're also done, after making
16504 sure that a non-default face is extended up to the right
16505 margin of the window. */
16506 if (ITERATOR_AT_END_OF_LINE_P (it))
16508 int used_before = row->used[TEXT_AREA];
16510 row->ends_in_newline_from_string_p = STRINGP (it->object);
16512 #ifdef HAVE_WINDOW_SYSTEM
16513 /* Add a space at the end of the line that is used to
16514 display the cursor there. */
16515 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
16516 append_space_for_newline (it, 0);
16517 #endif /* HAVE_WINDOW_SYSTEM */
16519 /* Extend the face to the end of the line. */
16520 extend_face_to_end_of_line (it);
16522 /* Make sure we have the position. */
16523 if (used_before == 0)
16524 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
16526 /* Consume the line end. This skips over invisible lines. */
16527 set_iterator_to_next (it, 1);
16528 it->continuation_lines_width = 0;
16529 break;
16532 /* Proceed with next display element. Note that this skips
16533 over lines invisible because of selective display. */
16534 set_iterator_to_next (it, 1);
16536 /* If we truncate lines, we are done when the last displayed
16537 glyphs reach past the right margin of the window. */
16538 if (it->truncate_lines_p
16539 && (FRAME_WINDOW_P (it->f)
16540 ? (it->current_x >= it->last_visible_x)
16541 : (it->current_x > it->last_visible_x)))
16543 /* Maybe add truncation glyphs. */
16544 if (!FRAME_WINDOW_P (it->f))
16546 int i, n;
16548 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
16549 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
16550 break;
16552 for (n = row->used[TEXT_AREA]; i < n; ++i)
16554 row->used[TEXT_AREA] = i;
16555 produce_special_glyphs (it, IT_TRUNCATION);
16558 #ifdef HAVE_WINDOW_SYSTEM
16559 else
16561 /* Don't truncate if we can overflow newline into fringe. */
16562 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
16564 if (!get_next_display_element (it))
16566 it->continuation_lines_width = 0;
16567 row->ends_at_zv_p = 1;
16568 row->exact_window_width_line_p = 1;
16569 break;
16571 if (ITERATOR_AT_END_OF_LINE_P (it))
16573 row->exact_window_width_line_p = 1;
16574 goto at_end_of_line;
16578 #endif /* HAVE_WINDOW_SYSTEM */
16580 row->truncated_on_right_p = 1;
16581 it->continuation_lines_width = 0;
16582 reseat_at_next_visible_line_start (it, 0);
16583 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
16584 it->hpos = hpos_before;
16585 it->current_x = x_before;
16586 break;
16590 /* If line is not empty and hscrolled, maybe insert truncation glyphs
16591 at the left window margin. */
16592 if (it->first_visible_x
16593 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
16595 if (!FRAME_WINDOW_P (it->f))
16596 insert_left_trunc_glyphs (it);
16597 row->truncated_on_left_p = 1;
16600 /* If the start of this line is the overlay arrow-position, then
16601 mark this glyph row as the one containing the overlay arrow.
16602 This is clearly a mess with variable size fonts. It would be
16603 better to let it be displayed like cursors under X. */
16604 if ((row->displays_text_p || !overlay_arrow_seen)
16605 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
16606 !NILP (overlay_arrow_string)))
16608 /* Overlay arrow in window redisplay is a fringe bitmap. */
16609 if (STRINGP (overlay_arrow_string))
16611 struct glyph_row *arrow_row
16612 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
16613 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
16614 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
16615 struct glyph *p = row->glyphs[TEXT_AREA];
16616 struct glyph *p2, *end;
16618 /* Copy the arrow glyphs. */
16619 while (glyph < arrow_end)
16620 *p++ = *glyph++;
16622 /* Throw away padding glyphs. */
16623 p2 = p;
16624 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
16625 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
16626 ++p2;
16627 if (p2 > p)
16629 while (p2 < end)
16630 *p++ = *p2++;
16631 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
16634 else
16636 xassert (INTEGERP (overlay_arrow_string));
16637 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
16639 overlay_arrow_seen = 1;
16642 /* Compute pixel dimensions of this line. */
16643 compute_line_metrics (it);
16645 /* Remember the position at which this line ends. */
16646 row->end = it->current;
16648 /* Record whether this row ends inside an ellipsis. */
16649 row->ends_in_ellipsis_p
16650 = (it->method == GET_FROM_DISPLAY_VECTOR
16651 && it->ellipsis_p);
16653 /* Save fringe bitmaps in this row. */
16654 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
16655 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
16656 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
16657 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
16659 it->left_user_fringe_bitmap = 0;
16660 it->left_user_fringe_face_id = 0;
16661 it->right_user_fringe_bitmap = 0;
16662 it->right_user_fringe_face_id = 0;
16664 /* Maybe set the cursor. */
16665 if (it->w->cursor.vpos < 0
16666 && PT >= MATRIX_ROW_START_CHARPOS (row)
16667 && PT <= MATRIX_ROW_END_CHARPOS (row)
16668 && cursor_row_p (it->w, row))
16669 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
16671 /* Highlight trailing whitespace. */
16672 if (!NILP (Vshow_trailing_whitespace))
16673 highlight_trailing_whitespace (it->f, it->glyph_row);
16675 /* Prepare for the next line. This line starts horizontally at (X
16676 HPOS) = (0 0). Vertical positions are incremented. As a
16677 convenience for the caller, IT->glyph_row is set to the next
16678 row to be used. */
16679 it->current_x = it->hpos = 0;
16680 it->current_y += row->height;
16681 ++it->vpos;
16682 ++it->glyph_row;
16683 it->start = it->current;
16684 return row->displays_text_p;
16689 /***********************************************************************
16690 Menu Bar
16691 ***********************************************************************/
16693 /* Redisplay the menu bar in the frame for window W.
16695 The menu bar of X frames that don't have X toolkit support is
16696 displayed in a special window W->frame->menu_bar_window.
16698 The menu bar of terminal frames is treated specially as far as
16699 glyph matrices are concerned. Menu bar lines are not part of
16700 windows, so the update is done directly on the frame matrix rows
16701 for the menu bar. */
16703 static void
16704 display_menu_bar (w)
16705 struct window *w;
16707 struct frame *f = XFRAME (WINDOW_FRAME (w));
16708 struct it it;
16709 Lisp_Object items;
16710 int i;
16712 /* Don't do all this for graphical frames. */
16713 #ifdef HAVE_NTGUI
16714 if (FRAME_W32_P (f))
16715 return;
16716 #endif
16717 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
16718 if (FRAME_X_P (f))
16719 return;
16720 #endif
16721 #ifdef MAC_OS
16722 if (FRAME_MAC_P (f))
16723 return;
16724 #endif
16726 #ifdef USE_X_TOOLKIT
16727 xassert (!FRAME_WINDOW_P (f));
16728 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
16729 it.first_visible_x = 0;
16730 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
16731 #else /* not USE_X_TOOLKIT */
16732 if (FRAME_WINDOW_P (f))
16734 /* Menu bar lines are displayed in the desired matrix of the
16735 dummy window menu_bar_window. */
16736 struct window *menu_w;
16737 xassert (WINDOWP (f->menu_bar_window));
16738 menu_w = XWINDOW (f->menu_bar_window);
16739 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
16740 MENU_FACE_ID);
16741 it.first_visible_x = 0;
16742 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
16744 else
16746 /* This is a TTY frame, i.e. character hpos/vpos are used as
16747 pixel x/y. */
16748 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
16749 MENU_FACE_ID);
16750 it.first_visible_x = 0;
16751 it.last_visible_x = FRAME_COLS (f);
16753 #endif /* not USE_X_TOOLKIT */
16755 if (! mode_line_inverse_video)
16756 /* Force the menu-bar to be displayed in the default face. */
16757 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
16759 /* Clear all rows of the menu bar. */
16760 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
16762 struct glyph_row *row = it.glyph_row + i;
16763 clear_glyph_row (row);
16764 row->enabled_p = 1;
16765 row->full_width_p = 1;
16768 /* Display all items of the menu bar. */
16769 items = FRAME_MENU_BAR_ITEMS (it.f);
16770 for (i = 0; i < XVECTOR (items)->size; i += 4)
16772 Lisp_Object string;
16774 /* Stop at nil string. */
16775 string = AREF (items, i + 1);
16776 if (NILP (string))
16777 break;
16779 /* Remember where item was displayed. */
16780 ASET (items, i + 3, make_number (it.hpos));
16782 /* Display the item, pad with one space. */
16783 if (it.current_x < it.last_visible_x)
16784 display_string (NULL, string, Qnil, 0, 0, &it,
16785 SCHARS (string) + 1, 0, 0, -1);
16788 /* Fill out the line with spaces. */
16789 if (it.current_x < it.last_visible_x)
16790 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
16792 /* Compute the total height of the lines. */
16793 compute_line_metrics (&it);
16798 /***********************************************************************
16799 Mode Line
16800 ***********************************************************************/
16802 /* Redisplay mode lines in the window tree whose root is WINDOW. If
16803 FORCE is non-zero, redisplay mode lines unconditionally.
16804 Otherwise, redisplay only mode lines that are garbaged. Value is
16805 the number of windows whose mode lines were redisplayed. */
16807 static int
16808 redisplay_mode_lines (window, force)
16809 Lisp_Object window;
16810 int force;
16812 int nwindows = 0;
16814 while (!NILP (window))
16816 struct window *w = XWINDOW (window);
16818 if (WINDOWP (w->hchild))
16819 nwindows += redisplay_mode_lines (w->hchild, force);
16820 else if (WINDOWP (w->vchild))
16821 nwindows += redisplay_mode_lines (w->vchild, force);
16822 else if (force
16823 || FRAME_GARBAGED_P (XFRAME (w->frame))
16824 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
16826 struct text_pos lpoint;
16827 struct buffer *old = current_buffer;
16829 /* Set the window's buffer for the mode line display. */
16830 SET_TEXT_POS (lpoint, PT, PT_BYTE);
16831 set_buffer_internal_1 (XBUFFER (w->buffer));
16833 /* Point refers normally to the selected window. For any
16834 other window, set up appropriate value. */
16835 if (!EQ (window, selected_window))
16837 struct text_pos pt;
16839 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
16840 if (CHARPOS (pt) < BEGV)
16841 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
16842 else if (CHARPOS (pt) > (ZV - 1))
16843 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
16844 else
16845 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
16848 /* Display mode lines. */
16849 clear_glyph_matrix (w->desired_matrix);
16850 if (display_mode_lines (w))
16852 ++nwindows;
16853 w->must_be_updated_p = 1;
16856 /* Restore old settings. */
16857 set_buffer_internal_1 (old);
16858 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
16861 window = w->next;
16864 return nwindows;
16868 /* Display the mode and/or top line of window W. Value is the number
16869 of mode lines displayed. */
16871 static int
16872 display_mode_lines (w)
16873 struct window *w;
16875 Lisp_Object old_selected_window, old_selected_frame;
16876 int n = 0;
16878 old_selected_frame = selected_frame;
16879 selected_frame = w->frame;
16880 old_selected_window = selected_window;
16881 XSETWINDOW (selected_window, w);
16883 /* These will be set while the mode line specs are processed. */
16884 line_number_displayed = 0;
16885 w->column_number_displayed = Qnil;
16887 if (WINDOW_WANTS_MODELINE_P (w))
16889 struct window *sel_w = XWINDOW (old_selected_window);
16891 /* Select mode line face based on the real selected window. */
16892 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
16893 current_buffer->mode_line_format);
16894 ++n;
16897 if (WINDOW_WANTS_HEADER_LINE_P (w))
16899 display_mode_line (w, HEADER_LINE_FACE_ID,
16900 current_buffer->header_line_format);
16901 ++n;
16904 selected_frame = old_selected_frame;
16905 selected_window = old_selected_window;
16906 return n;
16910 /* Display mode or top line of window W. FACE_ID specifies which line
16911 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
16912 FORMAT is the mode line format to display. Value is the pixel
16913 height of the mode line displayed. */
16915 static int
16916 display_mode_line (w, face_id, format)
16917 struct window *w;
16918 enum face_id face_id;
16919 Lisp_Object format;
16921 struct it it;
16922 struct face *face;
16923 int count = SPECPDL_INDEX ();
16925 init_iterator (&it, w, -1, -1, NULL, face_id);
16926 /* Don't extend on a previously drawn mode-line.
16927 This may happen if called from pos_visible_p. */
16928 it.glyph_row->enabled_p = 0;
16929 prepare_desired_row (it.glyph_row);
16931 it.glyph_row->mode_line_p = 1;
16933 if (! mode_line_inverse_video)
16934 /* Force the mode-line to be displayed in the default face. */
16935 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
16937 record_unwind_protect (unwind_format_mode_line,
16938 format_mode_line_unwind_data (NULL, Qnil, 0));
16940 mode_line_target = MODE_LINE_DISPLAY;
16942 /* Temporarily make frame's keyboard the current kboard so that
16943 kboard-local variables in the mode_line_format will get the right
16944 values. */
16945 push_kboard (FRAME_KBOARD (it.f));
16946 record_unwind_save_match_data ();
16947 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
16948 pop_kboard ();
16950 unbind_to (count, Qnil);
16952 /* Fill up with spaces. */
16953 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
16955 compute_line_metrics (&it);
16956 it.glyph_row->full_width_p = 1;
16957 it.glyph_row->continued_p = 0;
16958 it.glyph_row->truncated_on_left_p = 0;
16959 it.glyph_row->truncated_on_right_p = 0;
16961 /* Make a 3D mode-line have a shadow at its right end. */
16962 face = FACE_FROM_ID (it.f, face_id);
16963 extend_face_to_end_of_line (&it);
16964 if (face->box != FACE_NO_BOX)
16966 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
16967 + it.glyph_row->used[TEXT_AREA] - 1);
16968 last->right_box_line_p = 1;
16971 return it.glyph_row->height;
16974 /* Move element ELT in LIST to the front of LIST.
16975 Return the updated list. */
16977 static Lisp_Object
16978 move_elt_to_front (elt, list)
16979 Lisp_Object elt, list;
16981 register Lisp_Object tail, prev;
16982 register Lisp_Object tem;
16984 tail = list;
16985 prev = Qnil;
16986 while (CONSP (tail))
16988 tem = XCAR (tail);
16990 if (EQ (elt, tem))
16992 /* Splice out the link TAIL. */
16993 if (NILP (prev))
16994 list = XCDR (tail);
16995 else
16996 Fsetcdr (prev, XCDR (tail));
16998 /* Now make it the first. */
16999 Fsetcdr (tail, list);
17000 return tail;
17002 else
17003 prev = tail;
17004 tail = XCDR (tail);
17005 QUIT;
17008 /* Not found--return unchanged LIST. */
17009 return list;
17012 /* Contribute ELT to the mode line for window IT->w. How it
17013 translates into text depends on its data type.
17015 IT describes the display environment in which we display, as usual.
17017 DEPTH is the depth in recursion. It is used to prevent
17018 infinite recursion here.
17020 FIELD_WIDTH is the number of characters the display of ELT should
17021 occupy in the mode line, and PRECISION is the maximum number of
17022 characters to display from ELT's representation. See
17023 display_string for details.
17025 Returns the hpos of the end of the text generated by ELT.
17027 PROPS is a property list to add to any string we encounter.
17029 If RISKY is nonzero, remove (disregard) any properties in any string
17030 we encounter, and ignore :eval and :propertize.
17032 The global variable `mode_line_target' determines whether the
17033 output is passed to `store_mode_line_noprop',
17034 `store_mode_line_string', or `display_string'. */
17036 static int
17037 display_mode_element (it, depth, field_width, precision, elt, props, risky)
17038 struct it *it;
17039 int depth;
17040 int field_width, precision;
17041 Lisp_Object elt, props;
17042 int risky;
17044 int n = 0, field, prec;
17045 int literal = 0;
17047 tail_recurse:
17048 if (depth > 100)
17049 elt = build_string ("*too-deep*");
17051 depth++;
17053 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
17055 case Lisp_String:
17057 /* A string: output it and check for %-constructs within it. */
17058 unsigned char c;
17059 int offset = 0;
17061 if (SCHARS (elt) > 0
17062 && (!NILP (props) || risky))
17064 Lisp_Object oprops, aelt;
17065 oprops = Ftext_properties_at (make_number (0), elt);
17067 /* If the starting string's properties are not what
17068 we want, translate the string. Also, if the string
17069 is risky, do that anyway. */
17071 if (NILP (Fequal (props, oprops)) || risky)
17073 /* If the starting string has properties,
17074 merge the specified ones onto the existing ones. */
17075 if (! NILP (oprops) && !risky)
17077 Lisp_Object tem;
17079 oprops = Fcopy_sequence (oprops);
17080 tem = props;
17081 while (CONSP (tem))
17083 oprops = Fplist_put (oprops, XCAR (tem),
17084 XCAR (XCDR (tem)));
17085 tem = XCDR (XCDR (tem));
17087 props = oprops;
17090 aelt = Fassoc (elt, mode_line_proptrans_alist);
17091 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
17093 /* AELT is what we want. Move it to the front
17094 without consing. */
17095 elt = XCAR (aelt);
17096 mode_line_proptrans_alist
17097 = move_elt_to_front (aelt, mode_line_proptrans_alist);
17099 else
17101 Lisp_Object tem;
17103 /* If AELT has the wrong props, it is useless.
17104 so get rid of it. */
17105 if (! NILP (aelt))
17106 mode_line_proptrans_alist
17107 = Fdelq (aelt, mode_line_proptrans_alist);
17109 elt = Fcopy_sequence (elt);
17110 Fset_text_properties (make_number (0), Flength (elt),
17111 props, elt);
17112 /* Add this item to mode_line_proptrans_alist. */
17113 mode_line_proptrans_alist
17114 = Fcons (Fcons (elt, props),
17115 mode_line_proptrans_alist);
17116 /* Truncate mode_line_proptrans_alist
17117 to at most 50 elements. */
17118 tem = Fnthcdr (make_number (50),
17119 mode_line_proptrans_alist);
17120 if (! NILP (tem))
17121 XSETCDR (tem, Qnil);
17126 offset = 0;
17128 if (literal)
17130 prec = precision - n;
17131 switch (mode_line_target)
17133 case MODE_LINE_NOPROP:
17134 case MODE_LINE_TITLE:
17135 n += store_mode_line_noprop (SDATA (elt), -1, prec);
17136 break;
17137 case MODE_LINE_STRING:
17138 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
17139 break;
17140 case MODE_LINE_DISPLAY:
17141 n += display_string (NULL, elt, Qnil, 0, 0, it,
17142 0, prec, 0, STRING_MULTIBYTE (elt));
17143 break;
17146 break;
17149 /* Handle the non-literal case. */
17151 while ((precision <= 0 || n < precision)
17152 && SREF (elt, offset) != 0
17153 && (mode_line_target != MODE_LINE_DISPLAY
17154 || it->current_x < it->last_visible_x))
17156 int last_offset = offset;
17158 /* Advance to end of string or next format specifier. */
17159 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
17162 if (offset - 1 != last_offset)
17164 int nchars, nbytes;
17166 /* Output to end of string or up to '%'. Field width
17167 is length of string. Don't output more than
17168 PRECISION allows us. */
17169 offset--;
17171 prec = c_string_width (SDATA (elt) + last_offset,
17172 offset - last_offset, precision - n,
17173 &nchars, &nbytes);
17175 switch (mode_line_target)
17177 case MODE_LINE_NOPROP:
17178 case MODE_LINE_TITLE:
17179 n += store_mode_line_noprop (SDATA (elt) + last_offset, 0, prec);
17180 break;
17181 case MODE_LINE_STRING:
17183 int bytepos = last_offset;
17184 int charpos = string_byte_to_char (elt, bytepos);
17185 int endpos = (precision <= 0
17186 ? string_byte_to_char (elt, offset)
17187 : charpos + nchars);
17189 n += store_mode_line_string (NULL,
17190 Fsubstring (elt, make_number (charpos),
17191 make_number (endpos)),
17192 0, 0, 0, Qnil);
17194 break;
17195 case MODE_LINE_DISPLAY:
17197 int bytepos = last_offset;
17198 int charpos = string_byte_to_char (elt, bytepos);
17200 if (precision <= 0)
17201 nchars = string_byte_to_char (elt, offset) - charpos;
17202 n += display_string (NULL, elt, Qnil, 0, charpos,
17203 it, 0, nchars, 0,
17204 STRING_MULTIBYTE (elt));
17206 break;
17209 else /* c == '%' */
17211 int percent_position = offset;
17213 /* Get the specified minimum width. Zero means
17214 don't pad. */
17215 field = 0;
17216 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
17217 field = field * 10 + c - '0';
17219 /* Don't pad beyond the total padding allowed. */
17220 if (field_width - n > 0 && field > field_width - n)
17221 field = field_width - n;
17223 /* Note that either PRECISION <= 0 or N < PRECISION. */
17224 prec = precision - n;
17226 if (c == 'M')
17227 n += display_mode_element (it, depth, field, prec,
17228 Vglobal_mode_string, props,
17229 risky);
17230 else if (c != 0)
17232 int multibyte;
17233 int bytepos, charpos;
17234 unsigned char *spec;
17236 bytepos = percent_position;
17237 charpos = (STRING_MULTIBYTE (elt)
17238 ? string_byte_to_char (elt, bytepos)
17239 : bytepos);
17240 spec
17241 = decode_mode_spec (it->w, c, field, prec, &multibyte);
17243 switch (mode_line_target)
17245 case MODE_LINE_NOPROP:
17246 case MODE_LINE_TITLE:
17247 n += store_mode_line_noprop (spec, field, prec);
17248 break;
17249 case MODE_LINE_STRING:
17251 int len = strlen (spec);
17252 Lisp_Object tem = make_string (spec, len);
17253 props = Ftext_properties_at (make_number (charpos), elt);
17254 /* Should only keep face property in props */
17255 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
17257 break;
17258 case MODE_LINE_DISPLAY:
17260 int nglyphs_before, nwritten;
17262 nglyphs_before = it->glyph_row->used[TEXT_AREA];
17263 nwritten = display_string (spec, Qnil, elt,
17264 charpos, 0, it,
17265 field, prec, 0,
17266 multibyte);
17268 /* Assign to the glyphs written above the
17269 string where the `%x' came from, position
17270 of the `%'. */
17271 if (nwritten > 0)
17273 struct glyph *glyph
17274 = (it->glyph_row->glyphs[TEXT_AREA]
17275 + nglyphs_before);
17276 int i;
17278 for (i = 0; i < nwritten; ++i)
17280 glyph[i].object = elt;
17281 glyph[i].charpos = charpos;
17284 n += nwritten;
17287 break;
17290 else /* c == 0 */
17291 break;
17295 break;
17297 case Lisp_Symbol:
17298 /* A symbol: process the value of the symbol recursively
17299 as if it appeared here directly. Avoid error if symbol void.
17300 Special case: if value of symbol is a string, output the string
17301 literally. */
17303 register Lisp_Object tem;
17305 /* If the variable is not marked as risky to set
17306 then its contents are risky to use. */
17307 if (NILP (Fget (elt, Qrisky_local_variable)))
17308 risky = 1;
17310 tem = Fboundp (elt);
17311 if (!NILP (tem))
17313 tem = Fsymbol_value (elt);
17314 /* If value is a string, output that string literally:
17315 don't check for % within it. */
17316 if (STRINGP (tem))
17317 literal = 1;
17319 if (!EQ (tem, elt))
17321 /* Give up right away for nil or t. */
17322 elt = tem;
17323 goto tail_recurse;
17327 break;
17329 case Lisp_Cons:
17331 register Lisp_Object car, tem;
17333 /* A cons cell: five distinct cases.
17334 If first element is :eval or :propertize, do something special.
17335 If first element is a string or a cons, process all the elements
17336 and effectively concatenate them.
17337 If first element is a negative number, truncate displaying cdr to
17338 at most that many characters. If positive, pad (with spaces)
17339 to at least that many characters.
17340 If first element is a symbol, process the cadr or caddr recursively
17341 according to whether the symbol's value is non-nil or nil. */
17342 car = XCAR (elt);
17343 if (EQ (car, QCeval))
17345 /* An element of the form (:eval FORM) means evaluate FORM
17346 and use the result as mode line elements. */
17348 if (risky)
17349 break;
17351 if (CONSP (XCDR (elt)))
17353 Lisp_Object spec;
17354 spec = safe_eval (XCAR (XCDR (elt)));
17355 n += display_mode_element (it, depth, field_width - n,
17356 precision - n, spec, props,
17357 risky);
17360 else if (EQ (car, QCpropertize))
17362 /* An element of the form (:propertize ELT PROPS...)
17363 means display ELT but applying properties PROPS. */
17365 if (risky)
17366 break;
17368 if (CONSP (XCDR (elt)))
17369 n += display_mode_element (it, depth, field_width - n,
17370 precision - n, XCAR (XCDR (elt)),
17371 XCDR (XCDR (elt)), risky);
17373 else if (SYMBOLP (car))
17375 tem = Fboundp (car);
17376 elt = XCDR (elt);
17377 if (!CONSP (elt))
17378 goto invalid;
17379 /* elt is now the cdr, and we know it is a cons cell.
17380 Use its car if CAR has a non-nil value. */
17381 if (!NILP (tem))
17383 tem = Fsymbol_value (car);
17384 if (!NILP (tem))
17386 elt = XCAR (elt);
17387 goto tail_recurse;
17390 /* Symbol's value is nil (or symbol is unbound)
17391 Get the cddr of the original list
17392 and if possible find the caddr and use that. */
17393 elt = XCDR (elt);
17394 if (NILP (elt))
17395 break;
17396 else if (!CONSP (elt))
17397 goto invalid;
17398 elt = XCAR (elt);
17399 goto tail_recurse;
17401 else if (INTEGERP (car))
17403 register int lim = XINT (car);
17404 elt = XCDR (elt);
17405 if (lim < 0)
17407 /* Negative int means reduce maximum width. */
17408 if (precision <= 0)
17409 precision = -lim;
17410 else
17411 precision = min (precision, -lim);
17413 else if (lim > 0)
17415 /* Padding specified. Don't let it be more than
17416 current maximum. */
17417 if (precision > 0)
17418 lim = min (precision, lim);
17420 /* If that's more padding than already wanted, queue it.
17421 But don't reduce padding already specified even if
17422 that is beyond the current truncation point. */
17423 field_width = max (lim, field_width);
17425 goto tail_recurse;
17427 else if (STRINGP (car) || CONSP (car))
17429 register int limit = 50;
17430 /* Limit is to protect against circular lists. */
17431 while (CONSP (elt)
17432 && --limit > 0
17433 && (precision <= 0 || n < precision))
17435 n += display_mode_element (it, depth,
17436 /* Do padding only after the last
17437 element in the list. */
17438 (! CONSP (XCDR (elt))
17439 ? field_width - n
17440 : 0),
17441 precision - n, XCAR (elt),
17442 props, risky);
17443 elt = XCDR (elt);
17447 break;
17449 default:
17450 invalid:
17451 elt = build_string ("*invalid*");
17452 goto tail_recurse;
17455 /* Pad to FIELD_WIDTH. */
17456 if (field_width > 0 && n < field_width)
17458 switch (mode_line_target)
17460 case MODE_LINE_NOPROP:
17461 case MODE_LINE_TITLE:
17462 n += store_mode_line_noprop ("", field_width - n, 0);
17463 break;
17464 case MODE_LINE_STRING:
17465 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
17466 break;
17467 case MODE_LINE_DISPLAY:
17468 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
17469 0, 0, 0);
17470 break;
17474 return n;
17477 /* Store a mode-line string element in mode_line_string_list.
17479 If STRING is non-null, display that C string. Otherwise, the Lisp
17480 string LISP_STRING is displayed.
17482 FIELD_WIDTH is the minimum number of output glyphs to produce.
17483 If STRING has fewer characters than FIELD_WIDTH, pad to the right
17484 with spaces. FIELD_WIDTH <= 0 means don't pad.
17486 PRECISION is the maximum number of characters to output from
17487 STRING. PRECISION <= 0 means don't truncate the string.
17489 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
17490 properties to the string.
17492 PROPS are the properties to add to the string.
17493 The mode_line_string_face face property is always added to the string.
17496 static int
17497 store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
17498 char *string;
17499 Lisp_Object lisp_string;
17500 int copy_string;
17501 int field_width;
17502 int precision;
17503 Lisp_Object props;
17505 int len;
17506 int n = 0;
17508 if (string != NULL)
17510 len = strlen (string);
17511 if (precision > 0 && len > precision)
17512 len = precision;
17513 lisp_string = make_string (string, len);
17514 if (NILP (props))
17515 props = mode_line_string_face_prop;
17516 else if (!NILP (mode_line_string_face))
17518 Lisp_Object face = Fplist_get (props, Qface);
17519 props = Fcopy_sequence (props);
17520 if (NILP (face))
17521 face = mode_line_string_face;
17522 else
17523 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
17524 props = Fplist_put (props, Qface, face);
17526 Fadd_text_properties (make_number (0), make_number (len),
17527 props, lisp_string);
17529 else
17531 len = XFASTINT (Flength (lisp_string));
17532 if (precision > 0 && len > precision)
17534 len = precision;
17535 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
17536 precision = -1;
17538 if (!NILP (mode_line_string_face))
17540 Lisp_Object face;
17541 if (NILP (props))
17542 props = Ftext_properties_at (make_number (0), lisp_string);
17543 face = Fplist_get (props, Qface);
17544 if (NILP (face))
17545 face = mode_line_string_face;
17546 else
17547 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
17548 props = Fcons (Qface, Fcons (face, Qnil));
17549 if (copy_string)
17550 lisp_string = Fcopy_sequence (lisp_string);
17552 if (!NILP (props))
17553 Fadd_text_properties (make_number (0), make_number (len),
17554 props, lisp_string);
17557 if (len > 0)
17559 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
17560 n += len;
17563 if (field_width > len)
17565 field_width -= len;
17566 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
17567 if (!NILP (props))
17568 Fadd_text_properties (make_number (0), make_number (field_width),
17569 props, lisp_string);
17570 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
17571 n += field_width;
17574 return n;
17578 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
17579 1, 4, 0,
17580 doc: /* Format a string out of a mode line format specification.
17581 First arg FORMAT specifies the mode line format (see `mode-line-format'
17582 for details) to use.
17584 Optional second arg FACE specifies the face property to put
17585 on all characters for which no face is specified.
17586 The value t means whatever face the window's mode line currently uses
17587 \(either `mode-line' or `mode-line-inactive', depending).
17588 A value of nil means the default is no face property.
17589 If FACE is an integer, the value string has no text properties.
17591 Optional third and fourth args WINDOW and BUFFER specify the window
17592 and buffer to use as the context for the formatting (defaults
17593 are the selected window and the window's buffer). */)
17594 (format, face, window, buffer)
17595 Lisp_Object format, face, window, buffer;
17597 struct it it;
17598 int len;
17599 struct window *w;
17600 struct buffer *old_buffer = NULL;
17601 int face_id = -1;
17602 int no_props = INTEGERP (face);
17603 int count = SPECPDL_INDEX ();
17604 Lisp_Object str;
17605 int string_start = 0;
17607 if (NILP (window))
17608 window = selected_window;
17609 CHECK_WINDOW (window);
17610 w = XWINDOW (window);
17612 if (NILP (buffer))
17613 buffer = w->buffer;
17614 CHECK_BUFFER (buffer);
17616 /* Make formatting the modeline a non-op when noninteractive, otherwise
17617 there will be problems later caused by a partially initialized frame. */
17618 if (NILP (format) || noninteractive)
17619 return empty_unibyte_string;
17621 if (no_props)
17622 face = Qnil;
17624 if (!NILP (face))
17626 if (EQ (face, Qt))
17627 face = (EQ (window, selected_window) ? Qmode_line : Qmode_line_inactive);
17628 face_id = lookup_named_face (XFRAME (WINDOW_FRAME (w)), face, 0);
17631 if (face_id < 0)
17632 face_id = DEFAULT_FACE_ID;
17634 if (XBUFFER (buffer) != current_buffer)
17635 old_buffer = current_buffer;
17637 /* Save things including mode_line_proptrans_alist,
17638 and set that to nil so that we don't alter the outer value. */
17639 record_unwind_protect (unwind_format_mode_line,
17640 format_mode_line_unwind_data
17641 (old_buffer, selected_window, 1));
17642 mode_line_proptrans_alist = Qnil;
17644 Fselect_window (window, Qt);
17645 if (old_buffer)
17646 set_buffer_internal_1 (XBUFFER (buffer));
17648 init_iterator (&it, w, -1, -1, NULL, face_id);
17650 if (no_props)
17652 mode_line_target = MODE_LINE_NOPROP;
17653 mode_line_string_face_prop = Qnil;
17654 mode_line_string_list = Qnil;
17655 string_start = MODE_LINE_NOPROP_LEN (0);
17657 else
17659 mode_line_target = MODE_LINE_STRING;
17660 mode_line_string_list = Qnil;
17661 mode_line_string_face = face;
17662 mode_line_string_face_prop
17663 = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil)));
17666 push_kboard (FRAME_KBOARD (it.f));
17667 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
17668 pop_kboard ();
17670 if (no_props)
17672 len = MODE_LINE_NOPROP_LEN (string_start);
17673 str = make_string (mode_line_noprop_buf + string_start, len);
17675 else
17677 mode_line_string_list = Fnreverse (mode_line_string_list);
17678 str = Fmapconcat (intern ("identity"), mode_line_string_list,
17679 empty_unibyte_string);
17682 unbind_to (count, Qnil);
17683 return str;
17686 /* Write a null-terminated, right justified decimal representation of
17687 the positive integer D to BUF using a minimal field width WIDTH. */
17689 static void
17690 pint2str (buf, width, d)
17691 register char *buf;
17692 register int width;
17693 register int d;
17695 register char *p = buf;
17697 if (d <= 0)
17698 *p++ = '0';
17699 else
17701 while (d > 0)
17703 *p++ = d % 10 + '0';
17704 d /= 10;
17708 for (width -= (int) (p - buf); width > 0; --width)
17709 *p++ = ' ';
17710 *p-- = '\0';
17711 while (p > buf)
17713 d = *buf;
17714 *buf++ = *p;
17715 *p-- = d;
17719 /* Write a null-terminated, right justified decimal and "human
17720 readable" representation of the nonnegative integer D to BUF using
17721 a minimal field width WIDTH. D should be smaller than 999.5e24. */
17723 static const char power_letter[] =
17725 0, /* not used */
17726 'k', /* kilo */
17727 'M', /* mega */
17728 'G', /* giga */
17729 'T', /* tera */
17730 'P', /* peta */
17731 'E', /* exa */
17732 'Z', /* zetta */
17733 'Y' /* yotta */
17736 static void
17737 pint2hrstr (buf, width, d)
17738 char *buf;
17739 int width;
17740 int d;
17742 /* We aim to represent the nonnegative integer D as
17743 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
17744 int quotient = d;
17745 int remainder = 0;
17746 /* -1 means: do not use TENTHS. */
17747 int tenths = -1;
17748 int exponent = 0;
17750 /* Length of QUOTIENT.TENTHS as a string. */
17751 int length;
17753 char * psuffix;
17754 char * p;
17756 if (1000 <= quotient)
17758 /* Scale to the appropriate EXPONENT. */
17761 remainder = quotient % 1000;
17762 quotient /= 1000;
17763 exponent++;
17765 while (1000 <= quotient);
17767 /* Round to nearest and decide whether to use TENTHS or not. */
17768 if (quotient <= 9)
17770 tenths = remainder / 100;
17771 if (50 <= remainder % 100)
17773 if (tenths < 9)
17774 tenths++;
17775 else
17777 quotient++;
17778 if (quotient == 10)
17779 tenths = -1;
17780 else
17781 tenths = 0;
17785 else
17786 if (500 <= remainder)
17788 if (quotient < 999)
17789 quotient++;
17790 else
17792 quotient = 1;
17793 exponent++;
17794 tenths = 0;
17799 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
17800 if (tenths == -1 && quotient <= 99)
17801 if (quotient <= 9)
17802 length = 1;
17803 else
17804 length = 2;
17805 else
17806 length = 3;
17807 p = psuffix = buf + max (width, length);
17809 /* Print EXPONENT. */
17810 if (exponent)
17811 *psuffix++ = power_letter[exponent];
17812 *psuffix = '\0';
17814 /* Print TENTHS. */
17815 if (tenths >= 0)
17817 *--p = '0' + tenths;
17818 *--p = '.';
17821 /* Print QUOTIENT. */
17824 int digit = quotient % 10;
17825 *--p = '0' + digit;
17827 while ((quotient /= 10) != 0);
17829 /* Print leading spaces. */
17830 while (buf < p)
17831 *--p = ' ';
17834 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
17835 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
17836 type of CODING_SYSTEM. Return updated pointer into BUF. */
17838 static unsigned char invalid_eol_type[] = "(*invalid*)";
17840 static char *
17841 decode_mode_spec_coding (coding_system, buf, eol_flag)
17842 Lisp_Object coding_system;
17843 register char *buf;
17844 int eol_flag;
17846 Lisp_Object val;
17847 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
17848 const unsigned char *eol_str;
17849 int eol_str_len;
17850 /* The EOL conversion we are using. */
17851 Lisp_Object eoltype;
17853 val = CODING_SYSTEM_SPEC (coding_system);
17854 eoltype = Qnil;
17856 if (!VECTORP (val)) /* Not yet decided. */
17858 if (multibyte)
17859 *buf++ = '-';
17860 if (eol_flag)
17861 eoltype = eol_mnemonic_undecided;
17862 /* Don't mention EOL conversion if it isn't decided. */
17864 else
17866 Lisp_Object attrs;
17867 Lisp_Object eolvalue;
17869 attrs = AREF (val, 0);
17870 eolvalue = AREF (val, 2);
17872 if (multibyte)
17873 *buf++ = XFASTINT (CODING_ATTR_MNEMONIC (attrs));
17875 if (eol_flag)
17877 /* The EOL conversion that is normal on this system. */
17879 if (NILP (eolvalue)) /* Not yet decided. */
17880 eoltype = eol_mnemonic_undecided;
17881 else if (VECTORP (eolvalue)) /* Not yet decided. */
17882 eoltype = eol_mnemonic_undecided;
17883 else /* eolvalue is Qunix, Qdos, or Qmac. */
17884 eoltype = (EQ (eolvalue, Qunix)
17885 ? eol_mnemonic_unix
17886 : (EQ (eolvalue, Qdos) == 1
17887 ? eol_mnemonic_dos : eol_mnemonic_mac));
17891 if (eol_flag)
17893 /* Mention the EOL conversion if it is not the usual one. */
17894 if (STRINGP (eoltype))
17896 eol_str = SDATA (eoltype);
17897 eol_str_len = SBYTES (eoltype);
17899 else if (CHARACTERP (eoltype))
17901 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
17902 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
17903 eol_str = tmp;
17905 else
17907 eol_str = invalid_eol_type;
17908 eol_str_len = sizeof (invalid_eol_type) - 1;
17910 bcopy (eol_str, buf, eol_str_len);
17911 buf += eol_str_len;
17914 return buf;
17917 /* Return a string for the output of a mode line %-spec for window W,
17918 generated by character C. PRECISION >= 0 means don't return a
17919 string longer than that value. FIELD_WIDTH > 0 means pad the
17920 string returned with spaces to that value. Return 1 in *MULTIBYTE
17921 if the result is multibyte text.
17923 Note we operate on the current buffer for most purposes,
17924 the exception being w->base_line_pos. */
17926 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
17928 static char *
17929 decode_mode_spec (w, c, field_width, precision, multibyte)
17930 struct window *w;
17931 register int c;
17932 int field_width, precision;
17933 int *multibyte;
17935 Lisp_Object obj;
17936 struct frame *f = XFRAME (WINDOW_FRAME (w));
17937 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
17938 struct buffer *b = current_buffer;
17940 obj = Qnil;
17941 *multibyte = 0;
17943 switch (c)
17945 case '*':
17946 if (!NILP (b->read_only))
17947 return "%";
17948 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
17949 return "*";
17950 return "-";
17952 case '+':
17953 /* This differs from %* only for a modified read-only buffer. */
17954 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
17955 return "*";
17956 if (!NILP (b->read_only))
17957 return "%";
17958 return "-";
17960 case '&':
17961 /* This differs from %* in ignoring read-only-ness. */
17962 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
17963 return "*";
17964 return "-";
17966 case '%':
17967 return "%";
17969 case '[':
17971 int i;
17972 char *p;
17974 if (command_loop_level > 5)
17975 return "[[[... ";
17976 p = decode_mode_spec_buf;
17977 for (i = 0; i < command_loop_level; i++)
17978 *p++ = '[';
17979 *p = 0;
17980 return decode_mode_spec_buf;
17983 case ']':
17985 int i;
17986 char *p;
17988 if (command_loop_level > 5)
17989 return " ...]]]";
17990 p = decode_mode_spec_buf;
17991 for (i = 0; i < command_loop_level; i++)
17992 *p++ = ']';
17993 *p = 0;
17994 return decode_mode_spec_buf;
17997 case '-':
17999 register int i;
18001 /* Let lots_of_dashes be a string of infinite length. */
18002 if (mode_line_target == MODE_LINE_NOPROP ||
18003 mode_line_target == MODE_LINE_STRING)
18004 return "--";
18005 if (field_width <= 0
18006 || field_width > sizeof (lots_of_dashes))
18008 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
18009 decode_mode_spec_buf[i] = '-';
18010 decode_mode_spec_buf[i] = '\0';
18011 return decode_mode_spec_buf;
18013 else
18014 return lots_of_dashes;
18017 case 'b':
18018 obj = b->name;
18019 break;
18021 case 'c':
18022 /* %c and %l are ignored in `frame-title-format'.
18023 (In redisplay_internal, the frame title is drawn _before_ the
18024 windows are updated, so the stuff which depends on actual
18025 window contents (such as %l) may fail to render properly, or
18026 even crash emacs.) */
18027 if (mode_line_target == MODE_LINE_TITLE)
18028 return "";
18029 else
18031 int col = (int) current_column (); /* iftc */
18032 w->column_number_displayed = make_number (col);
18033 pint2str (decode_mode_spec_buf, field_width, col);
18034 return decode_mode_spec_buf;
18037 case 'e':
18038 #ifndef SYSTEM_MALLOC
18040 if (NILP (Vmemory_full))
18041 return "";
18042 else
18043 return "!MEM FULL! ";
18045 #else
18046 return "";
18047 #endif
18049 case 'F':
18050 /* %F displays the frame name. */
18051 if (!NILP (f->title))
18052 return (char *) SDATA (f->title);
18053 if (f->explicit_name || ! FRAME_WINDOW_P (f))
18054 return (char *) SDATA (f->name);
18055 return "Emacs";
18057 case 'f':
18058 obj = b->filename;
18059 break;
18061 case 'i':
18063 int size = ZV - BEGV;
18064 pint2str (decode_mode_spec_buf, field_width, size);
18065 return decode_mode_spec_buf;
18068 case 'I':
18070 int size = ZV - BEGV;
18071 pint2hrstr (decode_mode_spec_buf, field_width, size);
18072 return decode_mode_spec_buf;
18075 case 'l':
18077 int startpos, startpos_byte, line, linepos, linepos_byte;
18078 int topline, nlines, junk, height;
18080 /* %c and %l are ignored in `frame-title-format'. */
18081 if (mode_line_target == MODE_LINE_TITLE)
18082 return "";
18084 startpos = XMARKER (w->start)->charpos;
18085 startpos_byte = marker_byte_position (w->start);
18086 height = WINDOW_TOTAL_LINES (w);
18088 /* If we decided that this buffer isn't suitable for line numbers,
18089 don't forget that too fast. */
18090 if (EQ (w->base_line_pos, w->buffer))
18091 goto no_value;
18092 /* But do forget it, if the window shows a different buffer now. */
18093 else if (BUFFERP (w->base_line_pos))
18094 w->base_line_pos = Qnil;
18096 /* If the buffer is very big, don't waste time. */
18097 if (INTEGERP (Vline_number_display_limit)
18098 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
18100 w->base_line_pos = Qnil;
18101 w->base_line_number = Qnil;
18102 goto no_value;
18105 if (INTEGERP (w->base_line_number)
18106 && INTEGERP (w->base_line_pos)
18107 && XFASTINT (w->base_line_pos) <= startpos)
18109 line = XFASTINT (w->base_line_number);
18110 linepos = XFASTINT (w->base_line_pos);
18111 linepos_byte = buf_charpos_to_bytepos (b, linepos);
18113 else
18115 line = 1;
18116 linepos = BUF_BEGV (b);
18117 linepos_byte = BUF_BEGV_BYTE (b);
18120 /* Count lines from base line to window start position. */
18121 nlines = display_count_lines (linepos, linepos_byte,
18122 startpos_byte,
18123 startpos, &junk);
18125 topline = nlines + line;
18127 /* Determine a new base line, if the old one is too close
18128 or too far away, or if we did not have one.
18129 "Too close" means it's plausible a scroll-down would
18130 go back past it. */
18131 if (startpos == BUF_BEGV (b))
18133 w->base_line_number = make_number (topline);
18134 w->base_line_pos = make_number (BUF_BEGV (b));
18136 else if (nlines < height + 25 || nlines > height * 3 + 50
18137 || linepos == BUF_BEGV (b))
18139 int limit = BUF_BEGV (b);
18140 int limit_byte = BUF_BEGV_BYTE (b);
18141 int position;
18142 int distance = (height * 2 + 30) * line_number_display_limit_width;
18144 if (startpos - distance > limit)
18146 limit = startpos - distance;
18147 limit_byte = CHAR_TO_BYTE (limit);
18150 nlines = display_count_lines (startpos, startpos_byte,
18151 limit_byte,
18152 - (height * 2 + 30),
18153 &position);
18154 /* If we couldn't find the lines we wanted within
18155 line_number_display_limit_width chars per line,
18156 give up on line numbers for this window. */
18157 if (position == limit_byte && limit == startpos - distance)
18159 w->base_line_pos = w->buffer;
18160 w->base_line_number = Qnil;
18161 goto no_value;
18164 w->base_line_number = make_number (topline - nlines);
18165 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
18168 /* Now count lines from the start pos to point. */
18169 nlines = display_count_lines (startpos, startpos_byte,
18170 PT_BYTE, PT, &junk);
18172 /* Record that we did display the line number. */
18173 line_number_displayed = 1;
18175 /* Make the string to show. */
18176 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
18177 return decode_mode_spec_buf;
18178 no_value:
18180 char* p = decode_mode_spec_buf;
18181 int pad = field_width - 2;
18182 while (pad-- > 0)
18183 *p++ = ' ';
18184 *p++ = '?';
18185 *p++ = '?';
18186 *p = '\0';
18187 return decode_mode_spec_buf;
18190 break;
18192 case 'm':
18193 obj = b->mode_name;
18194 break;
18196 case 'n':
18197 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
18198 return " Narrow";
18199 break;
18201 case 'p':
18203 int pos = marker_position (w->start);
18204 int total = BUF_ZV (b) - BUF_BEGV (b);
18206 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
18208 if (pos <= BUF_BEGV (b))
18209 return "All";
18210 else
18211 return "Bottom";
18213 else if (pos <= BUF_BEGV (b))
18214 return "Top";
18215 else
18217 if (total > 1000000)
18218 /* Do it differently for a large value, to avoid overflow. */
18219 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
18220 else
18221 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
18222 /* We can't normally display a 3-digit number,
18223 so get us a 2-digit number that is close. */
18224 if (total == 100)
18225 total = 99;
18226 sprintf (decode_mode_spec_buf, "%2d%%", total);
18227 return decode_mode_spec_buf;
18231 /* Display percentage of size above the bottom of the screen. */
18232 case 'P':
18234 int toppos = marker_position (w->start);
18235 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
18236 int total = BUF_ZV (b) - BUF_BEGV (b);
18238 if (botpos >= BUF_ZV (b))
18240 if (toppos <= BUF_BEGV (b))
18241 return "All";
18242 else
18243 return "Bottom";
18245 else
18247 if (total > 1000000)
18248 /* Do it differently for a large value, to avoid overflow. */
18249 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
18250 else
18251 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
18252 /* We can't normally display a 3-digit number,
18253 so get us a 2-digit number that is close. */
18254 if (total == 100)
18255 total = 99;
18256 if (toppos <= BUF_BEGV (b))
18257 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
18258 else
18259 sprintf (decode_mode_spec_buf, "%2d%%", total);
18260 return decode_mode_spec_buf;
18264 case 's':
18265 /* status of process */
18266 obj = Fget_buffer_process (Fcurrent_buffer ());
18267 if (NILP (obj))
18268 return "no process";
18269 #ifdef subprocesses
18270 obj = Fsymbol_name (Fprocess_status (obj));
18271 #endif
18272 break;
18274 case '@':
18276 Lisp_Object val;
18277 val = call1 (intern ("file-remote-p"), current_buffer->directory);
18278 if (NILP (val))
18279 return "-";
18280 else
18281 return "@";
18284 case 't': /* indicate TEXT or BINARY */
18285 #ifdef MODE_LINE_BINARY_TEXT
18286 return MODE_LINE_BINARY_TEXT (b);
18287 #else
18288 return "T";
18289 #endif
18291 case 'z':
18292 /* coding-system (not including end-of-line format) */
18293 case 'Z':
18294 /* coding-system (including end-of-line type) */
18296 int eol_flag = (c == 'Z');
18297 char *p = decode_mode_spec_buf;
18299 if (! FRAME_WINDOW_P (f))
18301 /* No need to mention EOL here--the terminal never needs
18302 to do EOL conversion. */
18303 p = decode_mode_spec_coding (CODING_ID_NAME
18304 (FRAME_KEYBOARD_CODING (f)->id),
18305 p, 0);
18306 p = decode_mode_spec_coding (CODING_ID_NAME
18307 (FRAME_TERMINAL_CODING (f)->id),
18308 p, 0);
18310 p = decode_mode_spec_coding (b->buffer_file_coding_system,
18311 p, eol_flag);
18313 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
18314 #ifdef subprocesses
18315 obj = Fget_buffer_process (Fcurrent_buffer ());
18316 if (PROCESSP (obj))
18318 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
18319 p, eol_flag);
18320 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
18321 p, eol_flag);
18323 #endif /* subprocesses */
18324 #endif /* 0 */
18325 *p = 0;
18326 return decode_mode_spec_buf;
18330 if (STRINGP (obj))
18332 *multibyte = STRING_MULTIBYTE (obj);
18333 return (char *) SDATA (obj);
18335 else
18336 return "";
18340 /* Count up to COUNT lines starting from START / START_BYTE.
18341 But don't go beyond LIMIT_BYTE.
18342 Return the number of lines thus found (always nonnegative).
18344 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
18346 static int
18347 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
18348 int start, start_byte, limit_byte, count;
18349 int *byte_pos_ptr;
18351 register unsigned char *cursor;
18352 unsigned char *base;
18354 register int ceiling;
18355 register unsigned char *ceiling_addr;
18356 int orig_count = count;
18358 /* If we are not in selective display mode,
18359 check only for newlines. */
18360 int selective_display = (!NILP (current_buffer->selective_display)
18361 && !INTEGERP (current_buffer->selective_display));
18363 if (count > 0)
18365 while (start_byte < limit_byte)
18367 ceiling = BUFFER_CEILING_OF (start_byte);
18368 ceiling = min (limit_byte - 1, ceiling);
18369 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
18370 base = (cursor = BYTE_POS_ADDR (start_byte));
18371 while (1)
18373 if (selective_display)
18374 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
18376 else
18377 while (*cursor != '\n' && ++cursor != ceiling_addr)
18380 if (cursor != ceiling_addr)
18382 if (--count == 0)
18384 start_byte += cursor - base + 1;
18385 *byte_pos_ptr = start_byte;
18386 return orig_count;
18388 else
18389 if (++cursor == ceiling_addr)
18390 break;
18392 else
18393 break;
18395 start_byte += cursor - base;
18398 else
18400 while (start_byte > limit_byte)
18402 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
18403 ceiling = max (limit_byte, ceiling);
18404 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
18405 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
18406 while (1)
18408 if (selective_display)
18409 while (--cursor != ceiling_addr
18410 && *cursor != '\n' && *cursor != 015)
18412 else
18413 while (--cursor != ceiling_addr && *cursor != '\n')
18416 if (cursor != ceiling_addr)
18418 if (++count == 0)
18420 start_byte += cursor - base + 1;
18421 *byte_pos_ptr = start_byte;
18422 /* When scanning backwards, we should
18423 not count the newline posterior to which we stop. */
18424 return - orig_count - 1;
18427 else
18428 break;
18430 /* Here we add 1 to compensate for the last decrement
18431 of CURSOR, which took it past the valid range. */
18432 start_byte += cursor - base + 1;
18436 *byte_pos_ptr = limit_byte;
18438 if (count < 0)
18439 return - orig_count + count;
18440 return orig_count - count;
18446 /***********************************************************************
18447 Displaying strings
18448 ***********************************************************************/
18450 /* Display a NUL-terminated string, starting with index START.
18452 If STRING is non-null, display that C string. Otherwise, the Lisp
18453 string LISP_STRING is displayed.
18455 If FACE_STRING is not nil, FACE_STRING_POS is a position in
18456 FACE_STRING. Display STRING or LISP_STRING with the face at
18457 FACE_STRING_POS in FACE_STRING:
18459 Display the string in the environment given by IT, but use the
18460 standard display table, temporarily.
18462 FIELD_WIDTH is the minimum number of output glyphs to produce.
18463 If STRING has fewer characters than FIELD_WIDTH, pad to the right
18464 with spaces. If STRING has more characters, more than FIELD_WIDTH
18465 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
18467 PRECISION is the maximum number of characters to output from
18468 STRING. PRECISION < 0 means don't truncate the string.
18470 This is roughly equivalent to printf format specifiers:
18472 FIELD_WIDTH PRECISION PRINTF
18473 ----------------------------------------
18474 -1 -1 %s
18475 -1 10 %.10s
18476 10 -1 %10s
18477 20 10 %20.10s
18479 MULTIBYTE zero means do not display multibyte chars, > 0 means do
18480 display them, and < 0 means obey the current buffer's value of
18481 enable_multibyte_characters.
18483 Value is the number of columns displayed. */
18485 static int
18486 display_string (string, lisp_string, face_string, face_string_pos,
18487 start, it, field_width, precision, max_x, multibyte)
18488 unsigned char *string;
18489 Lisp_Object lisp_string;
18490 Lisp_Object face_string;
18491 EMACS_INT face_string_pos;
18492 EMACS_INT start;
18493 struct it *it;
18494 int field_width, precision, max_x;
18495 int multibyte;
18497 int hpos_at_start = it->hpos;
18498 int saved_face_id = it->face_id;
18499 struct glyph_row *row = it->glyph_row;
18501 /* Initialize the iterator IT for iteration over STRING beginning
18502 with index START. */
18503 reseat_to_string (it, string, lisp_string, start,
18504 precision, field_width, multibyte);
18506 /* If displaying STRING, set up the face of the iterator
18507 from LISP_STRING, if that's given. */
18508 if (STRINGP (face_string))
18510 EMACS_INT endptr;
18511 struct face *face;
18513 it->face_id
18514 = face_at_string_position (it->w, face_string, face_string_pos,
18515 0, it->region_beg_charpos,
18516 it->region_end_charpos,
18517 &endptr, it->base_face_id, 0);
18518 face = FACE_FROM_ID (it->f, it->face_id);
18519 it->face_box_p = face->box != FACE_NO_BOX;
18522 /* Set max_x to the maximum allowed X position. Don't let it go
18523 beyond the right edge of the window. */
18524 if (max_x <= 0)
18525 max_x = it->last_visible_x;
18526 else
18527 max_x = min (max_x, it->last_visible_x);
18529 /* Skip over display elements that are not visible. because IT->w is
18530 hscrolled. */
18531 if (it->current_x < it->first_visible_x)
18532 move_it_in_display_line_to (it, 100000, it->first_visible_x,
18533 MOVE_TO_POS | MOVE_TO_X);
18535 row->ascent = it->max_ascent;
18536 row->height = it->max_ascent + it->max_descent;
18537 row->phys_ascent = it->max_phys_ascent;
18538 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
18539 row->extra_line_spacing = it->max_extra_line_spacing;
18541 /* This condition is for the case that we are called with current_x
18542 past last_visible_x. */
18543 while (it->current_x < max_x)
18545 int x_before, x, n_glyphs_before, i, nglyphs;
18547 /* Get the next display element. */
18548 if (!get_next_display_element (it))
18549 break;
18551 /* Produce glyphs. */
18552 x_before = it->current_x;
18553 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
18554 PRODUCE_GLYPHS (it);
18556 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
18557 i = 0;
18558 x = x_before;
18559 while (i < nglyphs)
18561 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
18563 if (!it->truncate_lines_p
18564 && x + glyph->pixel_width > max_x)
18566 /* End of continued line or max_x reached. */
18567 if (CHAR_GLYPH_PADDING_P (*glyph))
18569 /* A wide character is unbreakable. */
18570 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
18571 it->current_x = x_before;
18573 else
18575 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
18576 it->current_x = x;
18578 break;
18580 else if (x + glyph->pixel_width >= it->first_visible_x)
18582 /* Glyph is at least partially visible. */
18583 ++it->hpos;
18584 if (x < it->first_visible_x)
18585 it->glyph_row->x = x - it->first_visible_x;
18587 else
18589 /* Glyph is off the left margin of the display area.
18590 Should not happen. */
18591 abort ();
18594 row->ascent = max (row->ascent, it->max_ascent);
18595 row->height = max (row->height, it->max_ascent + it->max_descent);
18596 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
18597 row->phys_height = max (row->phys_height,
18598 it->max_phys_ascent + it->max_phys_descent);
18599 row->extra_line_spacing = max (row->extra_line_spacing,
18600 it->max_extra_line_spacing);
18601 x += glyph->pixel_width;
18602 ++i;
18605 /* Stop if max_x reached. */
18606 if (i < nglyphs)
18607 break;
18609 /* Stop at line ends. */
18610 if (ITERATOR_AT_END_OF_LINE_P (it))
18612 it->continuation_lines_width = 0;
18613 break;
18616 set_iterator_to_next (it, 1);
18618 /* Stop if truncating at the right edge. */
18619 if (it->truncate_lines_p
18620 && it->current_x >= it->last_visible_x)
18622 /* Add truncation mark, but don't do it if the line is
18623 truncated at a padding space. */
18624 if (IT_CHARPOS (*it) < it->string_nchars)
18626 if (!FRAME_WINDOW_P (it->f))
18628 int i, n;
18630 if (it->current_x > it->last_visible_x)
18632 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
18633 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
18634 break;
18635 for (n = row->used[TEXT_AREA]; i < n; ++i)
18637 row->used[TEXT_AREA] = i;
18638 produce_special_glyphs (it, IT_TRUNCATION);
18641 produce_special_glyphs (it, IT_TRUNCATION);
18643 it->glyph_row->truncated_on_right_p = 1;
18645 break;
18649 /* Maybe insert a truncation at the left. */
18650 if (it->first_visible_x
18651 && IT_CHARPOS (*it) > 0)
18653 if (!FRAME_WINDOW_P (it->f))
18654 insert_left_trunc_glyphs (it);
18655 it->glyph_row->truncated_on_left_p = 1;
18658 it->face_id = saved_face_id;
18660 /* Value is number of columns displayed. */
18661 return it->hpos - hpos_at_start;
18666 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
18667 appears as an element of LIST or as the car of an element of LIST.
18668 If PROPVAL is a list, compare each element against LIST in that
18669 way, and return 1/2 if any element of PROPVAL is found in LIST.
18670 Otherwise return 0. This function cannot quit.
18671 The return value is 2 if the text is invisible but with an ellipsis
18672 and 1 if it's invisible and without an ellipsis. */
18675 invisible_p (propval, list)
18676 register Lisp_Object propval;
18677 Lisp_Object list;
18679 register Lisp_Object tail, proptail;
18681 for (tail = list; CONSP (tail); tail = XCDR (tail))
18683 register Lisp_Object tem;
18684 tem = XCAR (tail);
18685 if (EQ (propval, tem))
18686 return 1;
18687 if (CONSP (tem) && EQ (propval, XCAR (tem)))
18688 return NILP (XCDR (tem)) ? 1 : 2;
18691 if (CONSP (propval))
18693 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
18695 Lisp_Object propelt;
18696 propelt = XCAR (proptail);
18697 for (tail = list; CONSP (tail); tail = XCDR (tail))
18699 register Lisp_Object tem;
18700 tem = XCAR (tail);
18701 if (EQ (propelt, tem))
18702 return 1;
18703 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
18704 return NILP (XCDR (tem)) ? 1 : 2;
18709 return 0;
18712 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
18713 doc: /* Non-nil if the property makes the text invisible.
18714 POS-OR-PROP can be a marker or number, in which case it is taken to be
18715 a position in the current buffer and the value of the `invisible' property
18716 is checked; or it can be some other value, which is then presumed to be the
18717 value of the `invisible' property of the text of interest.
18718 The non-nil value returned can be t for truly invisible text or something
18719 else if the text is replaced by an ellipsis. */)
18720 (pos_or_prop)
18721 Lisp_Object pos_or_prop;
18723 Lisp_Object prop
18724 = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
18725 ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
18726 : pos_or_prop);
18727 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
18728 return (invis == 0 ? Qnil
18729 : invis == 1 ? Qt
18730 : make_number (invis));
18733 /* Calculate a width or height in pixels from a specification using
18734 the following elements:
18736 SPEC ::=
18737 NUM - a (fractional) multiple of the default font width/height
18738 (NUM) - specifies exactly NUM pixels
18739 UNIT - a fixed number of pixels, see below.
18740 ELEMENT - size of a display element in pixels, see below.
18741 (NUM . SPEC) - equals NUM * SPEC
18742 (+ SPEC SPEC ...) - add pixel values
18743 (- SPEC SPEC ...) - subtract pixel values
18744 (- SPEC) - negate pixel value
18746 NUM ::=
18747 INT or FLOAT - a number constant
18748 SYMBOL - use symbol's (buffer local) variable binding.
18750 UNIT ::=
18751 in - pixels per inch *)
18752 mm - pixels per 1/1000 meter *)
18753 cm - pixels per 1/100 meter *)
18754 width - width of current font in pixels.
18755 height - height of current font in pixels.
18757 *) using the ratio(s) defined in display-pixels-per-inch.
18759 ELEMENT ::=
18761 left-fringe - left fringe width in pixels
18762 right-fringe - right fringe width in pixels
18764 left-margin - left margin width in pixels
18765 right-margin - right margin width in pixels
18767 scroll-bar - scroll-bar area width in pixels
18769 Examples:
18771 Pixels corresponding to 5 inches:
18772 (5 . in)
18774 Total width of non-text areas on left side of window (if scroll-bar is on left):
18775 '(space :width (+ left-fringe left-margin scroll-bar))
18777 Align to first text column (in header line):
18778 '(space :align-to 0)
18780 Align to middle of text area minus half the width of variable `my-image'
18781 containing a loaded image:
18782 '(space :align-to (0.5 . (- text my-image)))
18784 Width of left margin minus width of 1 character in the default font:
18785 '(space :width (- left-margin 1))
18787 Width of left margin minus width of 2 characters in the current font:
18788 '(space :width (- left-margin (2 . width)))
18790 Center 1 character over left-margin (in header line):
18791 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
18793 Different ways to express width of left fringe plus left margin minus one pixel:
18794 '(space :width (- (+ left-fringe left-margin) (1)))
18795 '(space :width (+ left-fringe left-margin (- (1))))
18796 '(space :width (+ left-fringe left-margin (-1)))
18800 #define NUMVAL(X) \
18801 ((INTEGERP (X) || FLOATP (X)) \
18802 ? XFLOATINT (X) \
18803 : - 1)
18806 calc_pixel_width_or_height (res, it, prop, font, width_p, align_to)
18807 double *res;
18808 struct it *it;
18809 Lisp_Object prop;
18810 struct font *font;
18811 int width_p, *align_to;
18813 double pixels;
18815 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
18816 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
18818 if (NILP (prop))
18819 return OK_PIXELS (0);
18821 xassert (FRAME_LIVE_P (it->f));
18823 if (SYMBOLP (prop))
18825 if (SCHARS (SYMBOL_NAME (prop)) == 2)
18827 char *unit = SDATA (SYMBOL_NAME (prop));
18829 if (unit[0] == 'i' && unit[1] == 'n')
18830 pixels = 1.0;
18831 else if (unit[0] == 'm' && unit[1] == 'm')
18832 pixels = 25.4;
18833 else if (unit[0] == 'c' && unit[1] == 'm')
18834 pixels = 2.54;
18835 else
18836 pixels = 0;
18837 if (pixels > 0)
18839 double ppi;
18840 #ifdef HAVE_WINDOW_SYSTEM
18841 if (FRAME_WINDOW_P (it->f)
18842 && (ppi = (width_p
18843 ? FRAME_X_DISPLAY_INFO (it->f)->resx
18844 : FRAME_X_DISPLAY_INFO (it->f)->resy),
18845 ppi > 0))
18846 return OK_PIXELS (ppi / pixels);
18847 #endif
18849 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
18850 || (CONSP (Vdisplay_pixels_per_inch)
18851 && (ppi = (width_p
18852 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
18853 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
18854 ppi > 0)))
18855 return OK_PIXELS (ppi / pixels);
18857 return 0;
18861 #ifdef HAVE_WINDOW_SYSTEM
18862 if (EQ (prop, Qheight))
18863 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
18864 if (EQ (prop, Qwidth))
18865 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
18866 #else
18867 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
18868 return OK_PIXELS (1);
18869 #endif
18871 if (EQ (prop, Qtext))
18872 return OK_PIXELS (width_p
18873 ? window_box_width (it->w, TEXT_AREA)
18874 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
18876 if (align_to && *align_to < 0)
18878 *res = 0;
18879 if (EQ (prop, Qleft))
18880 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
18881 if (EQ (prop, Qright))
18882 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
18883 if (EQ (prop, Qcenter))
18884 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
18885 + window_box_width (it->w, TEXT_AREA) / 2);
18886 if (EQ (prop, Qleft_fringe))
18887 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
18888 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
18889 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
18890 if (EQ (prop, Qright_fringe))
18891 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
18892 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
18893 : window_box_right_offset (it->w, TEXT_AREA));
18894 if (EQ (prop, Qleft_margin))
18895 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
18896 if (EQ (prop, Qright_margin))
18897 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
18898 if (EQ (prop, Qscroll_bar))
18899 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
18901 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
18902 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
18903 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
18904 : 0)));
18906 else
18908 if (EQ (prop, Qleft_fringe))
18909 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
18910 if (EQ (prop, Qright_fringe))
18911 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
18912 if (EQ (prop, Qleft_margin))
18913 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
18914 if (EQ (prop, Qright_margin))
18915 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
18916 if (EQ (prop, Qscroll_bar))
18917 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
18920 prop = Fbuffer_local_value (prop, it->w->buffer);
18923 if (INTEGERP (prop) || FLOATP (prop))
18925 int base_unit = (width_p
18926 ? FRAME_COLUMN_WIDTH (it->f)
18927 : FRAME_LINE_HEIGHT (it->f));
18928 return OK_PIXELS (XFLOATINT (prop) * base_unit);
18931 if (CONSP (prop))
18933 Lisp_Object car = XCAR (prop);
18934 Lisp_Object cdr = XCDR (prop);
18936 if (SYMBOLP (car))
18938 #ifdef HAVE_WINDOW_SYSTEM
18939 if (FRAME_WINDOW_P (it->f)
18940 && valid_image_p (prop))
18942 int id = lookup_image (it->f, prop);
18943 struct image *img = IMAGE_FROM_ID (it->f, id);
18945 return OK_PIXELS (width_p ? img->width : img->height);
18947 #endif
18948 if (EQ (car, Qplus) || EQ (car, Qminus))
18950 int first = 1;
18951 double px;
18953 pixels = 0;
18954 while (CONSP (cdr))
18956 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
18957 font, width_p, align_to))
18958 return 0;
18959 if (first)
18960 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
18961 else
18962 pixels += px;
18963 cdr = XCDR (cdr);
18965 if (EQ (car, Qminus))
18966 pixels = -pixels;
18967 return OK_PIXELS (pixels);
18970 car = Fbuffer_local_value (car, it->w->buffer);
18973 if (INTEGERP (car) || FLOATP (car))
18975 double fact;
18976 pixels = XFLOATINT (car);
18977 if (NILP (cdr))
18978 return OK_PIXELS (pixels);
18979 if (calc_pixel_width_or_height (&fact, it, cdr,
18980 font, width_p, align_to))
18981 return OK_PIXELS (pixels * fact);
18982 return 0;
18985 return 0;
18988 return 0;
18992 /***********************************************************************
18993 Glyph Display
18994 ***********************************************************************/
18996 #ifdef HAVE_WINDOW_SYSTEM
18998 #if GLYPH_DEBUG
19000 void
19001 dump_glyph_string (s)
19002 struct glyph_string *s;
19004 fprintf (stderr, "glyph string\n");
19005 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
19006 s->x, s->y, s->width, s->height);
19007 fprintf (stderr, " ybase = %d\n", s->ybase);
19008 fprintf (stderr, " hl = %d\n", s->hl);
19009 fprintf (stderr, " left overhang = %d, right = %d\n",
19010 s->left_overhang, s->right_overhang);
19011 fprintf (stderr, " nchars = %d\n", s->nchars);
19012 fprintf (stderr, " extends to end of line = %d\n",
19013 s->extends_to_end_of_line_p);
19014 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
19015 fprintf (stderr, " bg width = %d\n", s->background_width);
19018 #endif /* GLYPH_DEBUG */
19020 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
19021 of XChar2b structures for S; it can't be allocated in
19022 init_glyph_string because it must be allocated via `alloca'. W
19023 is the window on which S is drawn. ROW and AREA are the glyph row
19024 and area within the row from which S is constructed. START is the
19025 index of the first glyph structure covered by S. HL is a
19026 face-override for drawing S. */
19028 #ifdef HAVE_NTGUI
19029 #define OPTIONAL_HDC(hdc) hdc,
19030 #define DECLARE_HDC(hdc) HDC hdc;
19031 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
19032 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
19033 #endif
19035 #ifndef OPTIONAL_HDC
19036 #define OPTIONAL_HDC(hdc)
19037 #define DECLARE_HDC(hdc)
19038 #define ALLOCATE_HDC(hdc, f)
19039 #define RELEASE_HDC(hdc, f)
19040 #endif
19042 static void
19043 init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
19044 struct glyph_string *s;
19045 DECLARE_HDC (hdc)
19046 XChar2b *char2b;
19047 struct window *w;
19048 struct glyph_row *row;
19049 enum glyph_row_area area;
19050 int start;
19051 enum draw_glyphs_face hl;
19053 bzero (s, sizeof *s);
19054 s->w = w;
19055 s->f = XFRAME (w->frame);
19056 #ifdef HAVE_NTGUI
19057 s->hdc = hdc;
19058 #endif
19059 s->display = FRAME_X_DISPLAY (s->f);
19060 s->window = FRAME_X_WINDOW (s->f);
19061 s->char2b = char2b;
19062 s->hl = hl;
19063 s->row = row;
19064 s->area = area;
19065 s->first_glyph = row->glyphs[area] + start;
19066 s->height = row->height;
19067 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
19069 /* Display the internal border below the tool-bar window. */
19070 if (WINDOWP (s->f->tool_bar_window)
19071 && s->w == XWINDOW (s->f->tool_bar_window))
19072 s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
19074 s->ybase = s->y + row->ascent;
19078 /* Append the list of glyph strings with head H and tail T to the list
19079 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
19081 static INLINE void
19082 append_glyph_string_lists (head, tail, h, t)
19083 struct glyph_string **head, **tail;
19084 struct glyph_string *h, *t;
19086 if (h)
19088 if (*head)
19089 (*tail)->next = h;
19090 else
19091 *head = h;
19092 h->prev = *tail;
19093 *tail = t;
19098 /* Prepend the list of glyph strings with head H and tail T to the
19099 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
19100 result. */
19102 static INLINE void
19103 prepend_glyph_string_lists (head, tail, h, t)
19104 struct glyph_string **head, **tail;
19105 struct glyph_string *h, *t;
19107 if (h)
19109 if (*head)
19110 (*head)->prev = t;
19111 else
19112 *tail = t;
19113 t->next = *head;
19114 *head = h;
19119 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
19120 Set *HEAD and *TAIL to the resulting list. */
19122 static INLINE void
19123 append_glyph_string (head, tail, s)
19124 struct glyph_string **head, **tail;
19125 struct glyph_string *s;
19127 s->next = s->prev = NULL;
19128 append_glyph_string_lists (head, tail, s, s);
19132 /* Get face and two-byte form of character C in face FACE_ID on frame
19133 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
19134 means we want to display multibyte text. DISPLAY_P non-zero means
19135 make sure that X resources for the face returned are allocated.
19136 Value is a pointer to a realized face that is ready for display if
19137 DISPLAY_P is non-zero. */
19139 static INLINE struct face *
19140 get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
19141 struct frame *f;
19142 int c, face_id;
19143 XChar2b *char2b;
19144 int multibyte_p, display_p;
19146 struct face *face = FACE_FROM_ID (f, face_id);
19148 if (face->font)
19150 unsigned code = face->font->driver->encode_char (face->font, c);
19152 if (code != FONT_INVALID_CODE)
19153 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
19154 else
19155 STORE_XCHAR2B (char2b, 0, 0);
19158 /* Make sure X resources of the face are allocated. */
19159 #ifdef HAVE_X_WINDOWS
19160 if (display_p)
19161 #endif
19163 xassert (face != NULL);
19164 PREPARE_FACE_FOR_DISPLAY (f, face);
19167 return face;
19171 /* Get face and two-byte form of character glyph GLYPH on frame F.
19172 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
19173 a pointer to a realized face that is ready for display. */
19175 static INLINE struct face *
19176 get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
19177 struct frame *f;
19178 struct glyph *glyph;
19179 XChar2b *char2b;
19180 int *two_byte_p;
19182 struct face *face;
19184 xassert (glyph->type == CHAR_GLYPH);
19185 face = FACE_FROM_ID (f, glyph->face_id);
19187 if (two_byte_p)
19188 *two_byte_p = 0;
19190 if (face->font)
19192 unsigned code = face->font->driver->encode_char (face->font, glyph->u.ch);
19194 if (code != FONT_INVALID_CODE)
19195 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
19196 else
19197 STORE_XCHAR2B (char2b, 0, code);
19200 /* Make sure X resources of the face are allocated. */
19201 xassert (face != NULL);
19202 PREPARE_FACE_FOR_DISPLAY (f, face);
19203 return face;
19207 /* Fill glyph string S with composition components specified by S->cmp.
19209 BASE_FACE is the base face of the composition.
19210 S->gidx is the index of the first component for S.
19212 OVERLAPS non-zero means S should draw the foreground only, and use
19213 its physical height for clipping. See also draw_glyphs.
19215 Value is the index of a component not in S. */
19217 static int
19218 fill_composite_glyph_string (s, base_face, overlaps)
19219 struct glyph_string *s;
19220 struct face *base_face;
19221 int overlaps;
19223 int i;
19225 xassert (s);
19227 s->for_overlaps = overlaps;
19229 if (s->cmp->method == COMPOSITION_WITH_GLYPH_STRING)
19231 Lisp_Object gstring
19232 = AREF (XHASH_TABLE (composition_hash_table)->key_and_value,
19233 s->cmp->hash_index * 2);
19235 s->face = base_face;
19236 s->font = base_face->font;
19237 for (i = 0, s->nchars = 0; i < s->cmp->glyph_len; i++, s->nchars++)
19239 Lisp_Object g = LGSTRING_GLYPH (gstring, i);
19240 unsigned code;
19241 XChar2b * store_pos;
19242 if (NILP (g))
19243 break;
19244 code = LGLYPH_CODE (g);
19245 store_pos = s->char2b + i;
19246 STORE_XCHAR2B (store_pos, code >> 8, code & 0xFF);
19248 s->width = s->cmp->pixel_width;
19250 else
19252 /* For all glyphs of this composition, starting at the offset
19253 S->gidx, until we reach the end of the definition or encounter a
19254 glyph that requires the different face, add it to S. */
19255 struct face *face;
19257 s->face = NULL;
19258 s->font = NULL;
19259 for (i = s->gidx; i < s->cmp->glyph_len; i++)
19261 int c = COMPOSITION_GLYPH (s->cmp, i);
19263 if (c != '\t')
19265 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
19266 -1, Qnil);
19268 face = get_char_face_and_encoding (s->f, c, face_id,
19269 s->char2b + i, 1, 1);
19270 if (face)
19272 if (! s->face)
19274 s->face = face;
19275 s->font = s->face->font;
19277 else if (s->face != face)
19278 break;
19281 ++s->nchars;
19284 /* All glyph strings for the same composition has the same width,
19285 i.e. the width set for the first component of the composition. */
19286 s->width = s->first_glyph->pixel_width;
19289 /* If the specified font could not be loaded, use the frame's
19290 default font, but record the fact that we couldn't load it in
19291 the glyph string so that we can draw rectangles for the
19292 characters of the glyph string. */
19293 if (s->font == NULL)
19295 s->font_not_found_p = 1;
19296 s->font = FRAME_FONT (s->f);
19299 /* Adjust base line for subscript/superscript text. */
19300 s->ybase += s->first_glyph->voffset;
19302 /* This glyph string must always be drawn with 16-bit functions. */
19303 s->two_byte_p = 1;
19305 return s->gidx + s->nchars;
19309 /* Fill glyph string S from a sequence of character glyphs.
19311 FACE_ID is the face id of the string. START is the index of the
19312 first glyph to consider, END is the index of the last + 1.
19313 OVERLAPS non-zero means S should draw the foreground only, and use
19314 its physical height for clipping. See also draw_glyphs.
19316 Value is the index of the first glyph not in S. */
19318 static int
19319 fill_glyph_string (s, face_id, start, end, overlaps)
19320 struct glyph_string *s;
19321 int face_id;
19322 int start, end, overlaps;
19324 struct glyph *glyph, *last;
19325 int voffset;
19326 int glyph_not_available_p;
19328 xassert (s->f == XFRAME (s->w->frame));
19329 xassert (s->nchars == 0);
19330 xassert (start >= 0 && end > start);
19332 s->for_overlaps = overlaps,
19333 glyph = s->row->glyphs[s->area] + start;
19334 last = s->row->glyphs[s->area] + end;
19335 voffset = glyph->voffset;
19336 s->padding_p = glyph->padding_p;
19337 glyph_not_available_p = glyph->glyph_not_available_p;
19339 while (glyph < last
19340 && glyph->type == CHAR_GLYPH
19341 && glyph->voffset == voffset
19342 /* Same face id implies same font, nowadays. */
19343 && glyph->face_id == face_id
19344 && glyph->glyph_not_available_p == glyph_not_available_p)
19346 int two_byte_p;
19348 s->face = get_glyph_face_and_encoding (s->f, glyph,
19349 s->char2b + s->nchars,
19350 &two_byte_p);
19351 s->two_byte_p = two_byte_p;
19352 ++s->nchars;
19353 xassert (s->nchars <= end - start);
19354 s->width += glyph->pixel_width;
19355 if (glyph++->padding_p != s->padding_p)
19356 break;
19359 s->font = s->face->font;
19361 /* If the specified font could not be loaded, use the frame's font,
19362 but record the fact that we couldn't load it in
19363 S->font_not_found_p so that we can draw rectangles for the
19364 characters of the glyph string. */
19365 if (s->font == NULL || glyph_not_available_p)
19367 s->font_not_found_p = 1;
19368 s->font = FRAME_FONT (s->f);
19371 /* Adjust base line for subscript/superscript text. */
19372 s->ybase += voffset;
19374 xassert (s->face && s->face->gc);
19375 return glyph - s->row->glyphs[s->area];
19379 /* Fill glyph string S from image glyph S->first_glyph. */
19381 static void
19382 fill_image_glyph_string (s)
19383 struct glyph_string *s;
19385 xassert (s->first_glyph->type == IMAGE_GLYPH);
19386 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
19387 xassert (s->img);
19388 s->slice = s->first_glyph->slice;
19389 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
19390 s->font = s->face->font;
19391 s->width = s->first_glyph->pixel_width;
19393 /* Adjust base line for subscript/superscript text. */
19394 s->ybase += s->first_glyph->voffset;
19398 /* Fill glyph string S from a sequence of stretch glyphs.
19400 ROW is the glyph row in which the glyphs are found, AREA is the
19401 area within the row. START is the index of the first glyph to
19402 consider, END is the index of the last + 1.
19404 Value is the index of the first glyph not in S. */
19406 static int
19407 fill_stretch_glyph_string (s, row, area, start, end)
19408 struct glyph_string *s;
19409 struct glyph_row *row;
19410 enum glyph_row_area area;
19411 int start, end;
19413 struct glyph *glyph, *last;
19414 int voffset, face_id;
19416 xassert (s->first_glyph->type == STRETCH_GLYPH);
19418 glyph = s->row->glyphs[s->area] + start;
19419 last = s->row->glyphs[s->area] + end;
19420 face_id = glyph->face_id;
19421 s->face = FACE_FROM_ID (s->f, face_id);
19422 s->font = s->face->font;
19423 s->width = glyph->pixel_width;
19424 s->nchars = 1;
19425 voffset = glyph->voffset;
19427 for (++glyph;
19428 (glyph < last
19429 && glyph->type == STRETCH_GLYPH
19430 && glyph->voffset == voffset
19431 && glyph->face_id == face_id);
19432 ++glyph)
19433 s->width += glyph->pixel_width;
19435 /* Adjust base line for subscript/superscript text. */
19436 s->ybase += voffset;
19438 /* The case that face->gc == 0 is handled when drawing the glyph
19439 string by calling PREPARE_FACE_FOR_DISPLAY. */
19440 xassert (s->face);
19441 return glyph - s->row->glyphs[s->area];
19444 static struct font_metrics *
19445 get_per_char_metric (f, font, char2b)
19446 struct frame *f;
19447 struct font *font;
19448 XChar2b *char2b;
19450 static struct font_metrics metrics;
19451 unsigned code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
19452 struct font *fontp;
19454 if (! font || code == FONT_INVALID_CODE)
19455 return NULL;
19456 font->driver->text_extents (font, &code, 1, &metrics);
19457 return &metrics;
19460 /* EXPORT for RIF:
19461 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
19462 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
19463 assumed to be zero. */
19465 void
19466 x_get_glyph_overhangs (glyph, f, left, right)
19467 struct glyph *glyph;
19468 struct frame *f;
19469 int *left, *right;
19471 *left = *right = 0;
19473 if (glyph->type == CHAR_GLYPH)
19475 struct face *face;
19476 XChar2b char2b;
19477 struct font_metrics *pcm;
19479 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
19480 if (face->font && (pcm = get_per_char_metric (f, face->font, &char2b)))
19482 if (pcm->rbearing > pcm->width)
19483 *right = pcm->rbearing - pcm->width;
19484 if (pcm->lbearing < 0)
19485 *left = -pcm->lbearing;
19488 else if (glyph->type == COMPOSITE_GLYPH)
19490 struct composition *cmp = composition_table[glyph->u.cmp_id];
19492 *right = cmp->rbearing - cmp->pixel_width;
19493 *left = - cmp->lbearing;
19498 /* Return the index of the first glyph preceding glyph string S that
19499 is overwritten by S because of S's left overhang. Value is -1
19500 if no glyphs are overwritten. */
19502 static int
19503 left_overwritten (s)
19504 struct glyph_string *s;
19506 int k;
19508 if (s->left_overhang)
19510 int x = 0, i;
19511 struct glyph *glyphs = s->row->glyphs[s->area];
19512 int first = s->first_glyph - glyphs;
19514 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
19515 x -= glyphs[i].pixel_width;
19517 k = i + 1;
19519 else
19520 k = -1;
19522 return k;
19526 /* Return the index of the first glyph preceding glyph string S that
19527 is overwriting S because of its right overhang. Value is -1 if no
19528 glyph in front of S overwrites S. */
19530 static int
19531 left_overwriting (s)
19532 struct glyph_string *s;
19534 int i, k, x;
19535 struct glyph *glyphs = s->row->glyphs[s->area];
19536 int first = s->first_glyph - glyphs;
19538 k = -1;
19539 x = 0;
19540 for (i = first - 1; i >= 0; --i)
19542 int left, right;
19543 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
19544 if (x + right > 0)
19545 k = i;
19546 x -= glyphs[i].pixel_width;
19549 return k;
19553 /* Return the index of the last glyph following glyph string S that is
19554 not overwritten by S because of S's right overhang. Value is -1 if
19555 no such glyph is found. */
19557 static int
19558 right_overwritten (s)
19559 struct glyph_string *s;
19561 int k = -1;
19563 if (s->right_overhang)
19565 int x = 0, i;
19566 struct glyph *glyphs = s->row->glyphs[s->area];
19567 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
19568 int end = s->row->used[s->area];
19570 for (i = first; i < end && s->right_overhang > x; ++i)
19571 x += glyphs[i].pixel_width;
19573 k = i;
19576 return k;
19580 /* Return the index of the last glyph following glyph string S that
19581 overwrites S because of its left overhang. Value is negative
19582 if no such glyph is found. */
19584 static int
19585 right_overwriting (s)
19586 struct glyph_string *s;
19588 int i, k, x;
19589 int end = s->row->used[s->area];
19590 struct glyph *glyphs = s->row->glyphs[s->area];
19591 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
19593 k = -1;
19594 x = 0;
19595 for (i = first; i < end; ++i)
19597 int left, right;
19598 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
19599 if (x - left < 0)
19600 k = i;
19601 x += glyphs[i].pixel_width;
19604 return k;
19608 /* Set background width of glyph string S. START is the index of the
19609 first glyph following S. LAST_X is the right-most x-position + 1
19610 in the drawing area. */
19612 static INLINE void
19613 set_glyph_string_background_width (s, start, last_x)
19614 struct glyph_string *s;
19615 int start;
19616 int last_x;
19618 /* If the face of this glyph string has to be drawn to the end of
19619 the drawing area, set S->extends_to_end_of_line_p. */
19621 if (start == s->row->used[s->area]
19622 && s->area == TEXT_AREA
19623 && ((s->row->fill_line_p
19624 && (s->hl == DRAW_NORMAL_TEXT
19625 || s->hl == DRAW_IMAGE_RAISED
19626 || s->hl == DRAW_IMAGE_SUNKEN))
19627 || s->hl == DRAW_MOUSE_FACE))
19628 s->extends_to_end_of_line_p = 1;
19630 /* If S extends its face to the end of the line, set its
19631 background_width to the distance to the right edge of the drawing
19632 area. */
19633 if (s->extends_to_end_of_line_p)
19634 s->background_width = last_x - s->x + 1;
19635 else
19636 s->background_width = s->width;
19640 /* Compute overhangs and x-positions for glyph string S and its
19641 predecessors, or successors. X is the starting x-position for S.
19642 BACKWARD_P non-zero means process predecessors. */
19644 static void
19645 compute_overhangs_and_x (s, x, backward_p)
19646 struct glyph_string *s;
19647 int x;
19648 int backward_p;
19650 if (backward_p)
19652 while (s)
19654 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
19655 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
19656 x -= s->width;
19657 s->x = x;
19658 s = s->prev;
19661 else
19663 while (s)
19665 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
19666 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
19667 s->x = x;
19668 x += s->width;
19669 s = s->next;
19676 /* The following macros are only called from draw_glyphs below.
19677 They reference the following parameters of that function directly:
19678 `w', `row', `area', and `overlap_p'
19679 as well as the following local variables:
19680 `s', `f', and `hdc' (in W32) */
19682 #ifdef HAVE_NTGUI
19683 /* On W32, silently add local `hdc' variable to argument list of
19684 init_glyph_string. */
19685 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
19686 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
19687 #else
19688 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
19689 init_glyph_string (s, char2b, w, row, area, start, hl)
19690 #endif
19692 /* Add a glyph string for a stretch glyph to the list of strings
19693 between HEAD and TAIL. START is the index of the stretch glyph in
19694 row area AREA of glyph row ROW. END is the index of the last glyph
19695 in that glyph row area. X is the current output position assigned
19696 to the new glyph string constructed. HL overrides that face of the
19697 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
19698 is the right-most x-position of the drawing area. */
19700 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
19701 and below -- keep them on one line. */
19702 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
19703 do \
19705 s = (struct glyph_string *) alloca (sizeof *s); \
19706 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
19707 START = fill_stretch_glyph_string (s, row, area, START, END); \
19708 append_glyph_string (&HEAD, &TAIL, s); \
19709 s->x = (X); \
19711 while (0)
19714 /* Add a glyph string for an image glyph to the list of strings
19715 between HEAD and TAIL. START is the index of the image glyph in
19716 row area AREA of glyph row ROW. END is the index of the last glyph
19717 in that glyph row area. X is the current output position assigned
19718 to the new glyph string constructed. HL overrides that face of the
19719 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
19720 is the right-most x-position of the drawing area. */
19722 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
19723 do \
19725 s = (struct glyph_string *) alloca (sizeof *s); \
19726 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
19727 fill_image_glyph_string (s); \
19728 append_glyph_string (&HEAD, &TAIL, s); \
19729 ++START; \
19730 s->x = (X); \
19732 while (0)
19735 /* Add a glyph string for a sequence of character glyphs to the list
19736 of strings between HEAD and TAIL. START is the index of the first
19737 glyph in row area AREA of glyph row ROW that is part of the new
19738 glyph string. END is the index of the last glyph in that glyph row
19739 area. X is the current output position assigned to the new glyph
19740 string constructed. HL overrides that face of the glyph; e.g. it
19741 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
19742 right-most x-position of the drawing area. */
19744 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
19745 do \
19747 int face_id; \
19748 XChar2b *char2b; \
19750 face_id = (row)->glyphs[area][START].face_id; \
19752 s = (struct glyph_string *) alloca (sizeof *s); \
19753 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
19754 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
19755 append_glyph_string (&HEAD, &TAIL, s); \
19756 s->x = (X); \
19757 START = fill_glyph_string (s, face_id, START, END, overlaps); \
19759 while (0)
19762 /* Add a glyph string for a composite sequence to the list of strings
19763 between HEAD and TAIL. START is the index of the first glyph in
19764 row area AREA of glyph row ROW that is part of the new glyph
19765 string. END is the index of the last glyph in that glyph row area.
19766 X is the current output position assigned to the new glyph string
19767 constructed. HL overrides that face of the glyph; e.g. it is
19768 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
19769 x-position of the drawing area. */
19771 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
19772 do { \
19773 int face_id = (row)->glyphs[area][START].face_id; \
19774 struct face *base_face = FACE_FROM_ID (f, face_id); \
19775 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
19776 struct composition *cmp = composition_table[cmp_id]; \
19777 XChar2b *char2b; \
19778 struct glyph_string *first_s; \
19779 int n; \
19781 char2b = (XChar2b *) alloca ((sizeof *char2b) * cmp->glyph_len); \
19783 /* Make glyph_strings for each glyph sequence that is drawable by \
19784 the same face, and append them to HEAD/TAIL. */ \
19785 for (n = 0; n < cmp->glyph_len;) \
19787 s = (struct glyph_string *) alloca (sizeof *s); \
19788 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
19789 append_glyph_string (&(HEAD), &(TAIL), s); \
19790 s->cmp = cmp; \
19791 s->gidx = n; \
19792 s->x = (X); \
19793 if (n == 0) \
19794 first_s = s; \
19795 n = fill_composite_glyph_string (s, base_face, overlaps); \
19798 ++START; \
19799 s = first_s; \
19800 } while (0)
19803 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
19804 of AREA of glyph row ROW on window W between indices START and END.
19805 HL overrides the face for drawing glyph strings, e.g. it is
19806 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
19807 x-positions of the drawing area.
19809 This is an ugly monster macro construct because we must use alloca
19810 to allocate glyph strings (because draw_glyphs can be called
19811 asynchronously). */
19813 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
19814 do \
19816 HEAD = TAIL = NULL; \
19817 while (START < END) \
19819 struct glyph *first_glyph = (row)->glyphs[area] + START; \
19820 switch (first_glyph->type) \
19822 case CHAR_GLYPH: \
19823 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
19824 HL, X, LAST_X); \
19825 break; \
19827 case COMPOSITE_GLYPH: \
19828 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
19829 HL, X, LAST_X); \
19830 break; \
19832 case STRETCH_GLYPH: \
19833 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
19834 HL, X, LAST_X); \
19835 break; \
19837 case IMAGE_GLYPH: \
19838 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
19839 HL, X, LAST_X); \
19840 break; \
19842 default: \
19843 abort (); \
19846 if (s) \
19848 set_glyph_string_background_width (s, START, LAST_X); \
19849 (X) += s->width; \
19853 while (0)
19856 /* Draw glyphs between START and END in AREA of ROW on window W,
19857 starting at x-position X. X is relative to AREA in W. HL is a
19858 face-override with the following meaning:
19860 DRAW_NORMAL_TEXT draw normally
19861 DRAW_CURSOR draw in cursor face
19862 DRAW_MOUSE_FACE draw in mouse face.
19863 DRAW_INVERSE_VIDEO draw in mode line face
19864 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
19865 DRAW_IMAGE_RAISED draw an image with a raised relief around it
19867 If OVERLAPS is non-zero, draw only the foreground of characters and
19868 clip to the physical height of ROW. Non-zero value also defines
19869 the overlapping part to be drawn:
19871 OVERLAPS_PRED overlap with preceding rows
19872 OVERLAPS_SUCC overlap with succeeding rows
19873 OVERLAPS_BOTH overlap with both preceding/succeeding rows
19874 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
19876 Value is the x-position reached, relative to AREA of W. */
19878 static int
19879 draw_glyphs (w, x, row, area, start, end, hl, overlaps)
19880 struct window *w;
19881 int x;
19882 struct glyph_row *row;
19883 enum glyph_row_area area;
19884 EMACS_INT start, end;
19885 enum draw_glyphs_face hl;
19886 int overlaps;
19888 struct glyph_string *head, *tail;
19889 struct glyph_string *s;
19890 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
19891 int last_x, area_width;
19892 int x_reached;
19893 int i, j;
19894 struct frame *f = XFRAME (WINDOW_FRAME (w));
19895 DECLARE_HDC (hdc);
19897 ALLOCATE_HDC (hdc, f);
19899 /* Let's rather be paranoid than getting a SEGV. */
19900 end = min (end, row->used[area]);
19901 start = max (0, start);
19902 start = min (end, start);
19904 /* Translate X to frame coordinates. Set last_x to the right
19905 end of the drawing area. */
19906 if (row->full_width_p)
19908 /* X is relative to the left edge of W, without scroll bars
19909 or fringes. */
19910 x += WINDOW_LEFT_EDGE_X (w);
19911 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
19913 else
19915 int area_left = window_box_left (w, area);
19916 x += area_left;
19917 area_width = window_box_width (w, area);
19918 last_x = area_left + area_width;
19921 /* Build a doubly-linked list of glyph_string structures between
19922 head and tail from what we have to draw. Note that the macro
19923 BUILD_GLYPH_STRINGS will modify its start parameter. That's
19924 the reason we use a separate variable `i'. */
19925 i = start;
19926 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
19927 if (tail)
19928 x_reached = tail->x + tail->background_width;
19929 else
19930 x_reached = x;
19932 /* If there are any glyphs with lbearing < 0 or rbearing > width in
19933 the row, redraw some glyphs in front or following the glyph
19934 strings built above. */
19935 if (head && !overlaps && row->contains_overlapping_glyphs_p)
19937 int dummy_x = 0;
19938 struct glyph_string *h, *t;
19940 /* Compute overhangs for all glyph strings. */
19941 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
19942 for (s = head; s; s = s->next)
19943 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
19945 /* Prepend glyph strings for glyphs in front of the first glyph
19946 string that are overwritten because of the first glyph
19947 string's left overhang. The background of all strings
19948 prepended must be drawn because the first glyph string
19949 draws over it. */
19950 i = left_overwritten (head);
19951 if (i >= 0)
19953 j = i;
19954 BUILD_GLYPH_STRINGS (j, start, h, t,
19955 DRAW_NORMAL_TEXT, dummy_x, last_x);
19956 start = i;
19957 compute_overhangs_and_x (t, head->x, 1);
19958 prepend_glyph_string_lists (&head, &tail, h, t);
19959 clip_head = head;
19962 /* Prepend glyph strings for glyphs in front of the first glyph
19963 string that overwrite that glyph string because of their
19964 right overhang. For these strings, only the foreground must
19965 be drawn, because it draws over the glyph string at `head'.
19966 The background must not be drawn because this would overwrite
19967 right overhangs of preceding glyphs for which no glyph
19968 strings exist. */
19969 i = left_overwriting (head);
19970 if (i >= 0)
19972 clip_head = head;
19973 BUILD_GLYPH_STRINGS (i, start, h, t,
19974 DRAW_NORMAL_TEXT, dummy_x, last_x);
19975 for (s = h; s; s = s->next)
19976 s->background_filled_p = 1;
19977 compute_overhangs_and_x (t, head->x, 1);
19978 prepend_glyph_string_lists (&head, &tail, h, t);
19981 /* Append glyphs strings for glyphs following the last glyph
19982 string tail that are overwritten by tail. The background of
19983 these strings has to be drawn because tail's foreground draws
19984 over it. */
19985 i = right_overwritten (tail);
19986 if (i >= 0)
19988 BUILD_GLYPH_STRINGS (end, i, h, t,
19989 DRAW_NORMAL_TEXT, x, last_x);
19990 compute_overhangs_and_x (h, tail->x + tail->width, 0);
19991 append_glyph_string_lists (&head, &tail, h, t);
19992 clip_tail = tail;
19995 /* Append glyph strings for glyphs following the last glyph
19996 string tail that overwrite tail. The foreground of such
19997 glyphs has to be drawn because it writes into the background
19998 of tail. The background must not be drawn because it could
19999 paint over the foreground of following glyphs. */
20000 i = right_overwriting (tail);
20001 if (i >= 0)
20003 clip_tail = tail;
20004 i++; /* We must include the Ith glyph. */
20005 BUILD_GLYPH_STRINGS (end, i, h, t,
20006 DRAW_NORMAL_TEXT, x, last_x);
20007 for (s = h; s; s = s->next)
20008 s->background_filled_p = 1;
20009 compute_overhangs_and_x (h, tail->x + tail->width, 0);
20010 append_glyph_string_lists (&head, &tail, h, t);
20012 if (clip_head || clip_tail)
20013 for (s = head; s; s = s->next)
20015 s->clip_head = clip_head;
20016 s->clip_tail = clip_tail;
20020 /* Draw all strings. */
20021 for (s = head; s; s = s->next)
20022 FRAME_RIF (f)->draw_glyph_string (s);
20024 if (area == TEXT_AREA
20025 && !row->full_width_p
20026 /* When drawing overlapping rows, only the glyph strings'
20027 foreground is drawn, which doesn't erase a cursor
20028 completely. */
20029 && !overlaps)
20031 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
20032 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
20033 : (tail ? tail->x + tail->background_width : x));
20035 int text_left = window_box_left (w, TEXT_AREA);
20036 x0 -= text_left;
20037 x1 -= text_left;
20039 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
20040 row->y, MATRIX_ROW_BOTTOM_Y (row));
20043 /* Value is the x-position up to which drawn, relative to AREA of W.
20044 This doesn't include parts drawn because of overhangs. */
20045 if (row->full_width_p)
20046 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
20047 else
20048 x_reached -= window_box_left (w, area);
20050 RELEASE_HDC (hdc, f);
20052 return x_reached;
20055 /* Expand row matrix if too narrow. Don't expand if area
20056 is not present. */
20058 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
20060 if (!fonts_changed_p \
20061 && (it->glyph_row->glyphs[area] \
20062 < it->glyph_row->glyphs[area + 1])) \
20064 it->w->ncols_scale_factor++; \
20065 fonts_changed_p = 1; \
20069 /* Store one glyph for IT->char_to_display in IT->glyph_row.
20070 Called from x_produce_glyphs when IT->glyph_row is non-null. */
20072 static INLINE void
20073 append_glyph (it)
20074 struct it *it;
20076 struct glyph *glyph;
20077 enum glyph_row_area area = it->area;
20079 xassert (it->glyph_row);
20080 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
20082 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
20083 if (glyph < it->glyph_row->glyphs[area + 1])
20085 glyph->charpos = CHARPOS (it->position);
20086 glyph->object = it->object;
20087 if (it->pixel_width > 0)
20089 glyph->pixel_width = it->pixel_width;
20090 glyph->padding_p = 0;
20092 else
20094 /* Assure at least 1-pixel width. Otherwise, cursor can't
20095 be displayed correctly. */
20096 glyph->pixel_width = 1;
20097 glyph->padding_p = 1;
20099 glyph->ascent = it->ascent;
20100 glyph->descent = it->descent;
20101 glyph->voffset = it->voffset;
20102 glyph->type = CHAR_GLYPH;
20103 glyph->multibyte_p = it->multibyte_p;
20104 glyph->left_box_line_p = it->start_of_box_run_p;
20105 glyph->right_box_line_p = it->end_of_box_run_p;
20106 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
20107 || it->phys_descent > it->descent);
20108 glyph->glyph_not_available_p = it->glyph_not_available_p;
20109 glyph->face_id = it->face_id;
20110 glyph->u.ch = it->char_to_display;
20111 glyph->slice = null_glyph_slice;
20112 glyph->font_type = FONT_TYPE_UNKNOWN;
20113 ++it->glyph_row->used[area];
20115 else
20116 IT_EXPAND_MATRIX_WIDTH (it, area);
20119 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
20120 Called from x_produce_glyphs when IT->glyph_row is non-null. */
20122 static INLINE void
20123 append_composite_glyph (it)
20124 struct it *it;
20126 struct glyph *glyph;
20127 enum glyph_row_area area = it->area;
20129 xassert (it->glyph_row);
20131 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
20132 if (glyph < it->glyph_row->glyphs[area + 1])
20134 glyph->charpos = CHARPOS (it->position);
20135 glyph->object = it->object;
20136 glyph->pixel_width = it->pixel_width;
20137 glyph->ascent = it->ascent;
20138 glyph->descent = it->descent;
20139 glyph->voffset = it->voffset;
20140 glyph->type = COMPOSITE_GLYPH;
20141 glyph->multibyte_p = it->multibyte_p;
20142 glyph->left_box_line_p = it->start_of_box_run_p;
20143 glyph->right_box_line_p = it->end_of_box_run_p;
20144 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
20145 || it->phys_descent > it->descent);
20146 glyph->padding_p = 0;
20147 glyph->glyph_not_available_p = 0;
20148 glyph->face_id = it->face_id;
20149 glyph->u.cmp_id = it->cmp_id;
20150 glyph->slice = null_glyph_slice;
20151 glyph->font_type = FONT_TYPE_UNKNOWN;
20152 ++it->glyph_row->used[area];
20154 else
20155 IT_EXPAND_MATRIX_WIDTH (it, area);
20159 /* Change IT->ascent and IT->height according to the setting of
20160 IT->voffset. */
20162 static INLINE void
20163 take_vertical_position_into_account (it)
20164 struct it *it;
20166 if (it->voffset)
20168 if (it->voffset < 0)
20169 /* Increase the ascent so that we can display the text higher
20170 in the line. */
20171 it->ascent -= it->voffset;
20172 else
20173 /* Increase the descent so that we can display the text lower
20174 in the line. */
20175 it->descent += it->voffset;
20180 /* Produce glyphs/get display metrics for the image IT is loaded with.
20181 See the description of struct display_iterator in dispextern.h for
20182 an overview of struct display_iterator. */
20184 static void
20185 produce_image_glyph (it)
20186 struct it *it;
20188 struct image *img;
20189 struct face *face;
20190 int glyph_ascent, crop;
20191 struct glyph_slice slice;
20193 xassert (it->what == IT_IMAGE);
20195 face = FACE_FROM_ID (it->f, it->face_id);
20196 xassert (face);
20197 /* Make sure X resources of the face is loaded. */
20198 PREPARE_FACE_FOR_DISPLAY (it->f, face);
20200 if (it->image_id < 0)
20202 /* Fringe bitmap. */
20203 it->ascent = it->phys_ascent = 0;
20204 it->descent = it->phys_descent = 0;
20205 it->pixel_width = 0;
20206 it->nglyphs = 0;
20207 return;
20210 img = IMAGE_FROM_ID (it->f, it->image_id);
20211 xassert (img);
20212 /* Make sure X resources of the image is loaded. */
20213 prepare_image_for_display (it->f, img);
20215 slice.x = slice.y = 0;
20216 slice.width = img->width;
20217 slice.height = img->height;
20219 if (INTEGERP (it->slice.x))
20220 slice.x = XINT (it->slice.x);
20221 else if (FLOATP (it->slice.x))
20222 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
20224 if (INTEGERP (it->slice.y))
20225 slice.y = XINT (it->slice.y);
20226 else if (FLOATP (it->slice.y))
20227 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
20229 if (INTEGERP (it->slice.width))
20230 slice.width = XINT (it->slice.width);
20231 else if (FLOATP (it->slice.width))
20232 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
20234 if (INTEGERP (it->slice.height))
20235 slice.height = XINT (it->slice.height);
20236 else if (FLOATP (it->slice.height))
20237 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
20239 if (slice.x >= img->width)
20240 slice.x = img->width;
20241 if (slice.y >= img->height)
20242 slice.y = img->height;
20243 if (slice.x + slice.width >= img->width)
20244 slice.width = img->width - slice.x;
20245 if (slice.y + slice.height > img->height)
20246 slice.height = img->height - slice.y;
20248 if (slice.width == 0 || slice.height == 0)
20249 return;
20251 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
20253 it->descent = slice.height - glyph_ascent;
20254 if (slice.y == 0)
20255 it->descent += img->vmargin;
20256 if (slice.y + slice.height == img->height)
20257 it->descent += img->vmargin;
20258 it->phys_descent = it->descent;
20260 it->pixel_width = slice.width;
20261 if (slice.x == 0)
20262 it->pixel_width += img->hmargin;
20263 if (slice.x + slice.width == img->width)
20264 it->pixel_width += img->hmargin;
20266 /* It's quite possible for images to have an ascent greater than
20267 their height, so don't get confused in that case. */
20268 if (it->descent < 0)
20269 it->descent = 0;
20271 #if 0 /* this breaks image tiling */
20272 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
20273 int face_ascent = face->font ? FONT_BASE (face->font) : FRAME_BASELINE_OFFSET (it->f);
20274 if (face_ascent > it->ascent)
20275 it->ascent = it->phys_ascent = face_ascent;
20276 #endif
20278 it->nglyphs = 1;
20280 if (face->box != FACE_NO_BOX)
20282 if (face->box_line_width > 0)
20284 if (slice.y == 0)
20285 it->ascent += face->box_line_width;
20286 if (slice.y + slice.height == img->height)
20287 it->descent += face->box_line_width;
20290 if (it->start_of_box_run_p && slice.x == 0)
20291 it->pixel_width += eabs (face->box_line_width);
20292 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
20293 it->pixel_width += eabs (face->box_line_width);
20296 take_vertical_position_into_account (it);
20298 /* Automatically crop wide image glyphs at right edge so we can
20299 draw the cursor on same display row. */
20300 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
20301 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
20303 it->pixel_width -= crop;
20304 slice.width -= crop;
20307 if (it->glyph_row)
20309 struct glyph *glyph;
20310 enum glyph_row_area area = it->area;
20312 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
20313 if (glyph < it->glyph_row->glyphs[area + 1])
20315 glyph->charpos = CHARPOS (it->position);
20316 glyph->object = it->object;
20317 glyph->pixel_width = it->pixel_width;
20318 glyph->ascent = glyph_ascent;
20319 glyph->descent = it->descent;
20320 glyph->voffset = it->voffset;
20321 glyph->type = IMAGE_GLYPH;
20322 glyph->multibyte_p = it->multibyte_p;
20323 glyph->left_box_line_p = it->start_of_box_run_p;
20324 glyph->right_box_line_p = it->end_of_box_run_p;
20325 glyph->overlaps_vertically_p = 0;
20326 glyph->padding_p = 0;
20327 glyph->glyph_not_available_p = 0;
20328 glyph->face_id = it->face_id;
20329 glyph->u.img_id = img->id;
20330 glyph->slice = slice;
20331 glyph->font_type = FONT_TYPE_UNKNOWN;
20332 ++it->glyph_row->used[area];
20334 else
20335 IT_EXPAND_MATRIX_WIDTH (it, area);
20340 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
20341 of the glyph, WIDTH and HEIGHT are the width and height of the
20342 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
20344 static void
20345 append_stretch_glyph (it, object, width, height, ascent)
20346 struct it *it;
20347 Lisp_Object object;
20348 int width, height;
20349 int ascent;
20351 struct glyph *glyph;
20352 enum glyph_row_area area = it->area;
20354 xassert (ascent >= 0 && ascent <= height);
20356 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
20357 if (glyph < it->glyph_row->glyphs[area + 1])
20359 glyph->charpos = CHARPOS (it->position);
20360 glyph->object = object;
20361 glyph->pixel_width = width;
20362 glyph->ascent = ascent;
20363 glyph->descent = height - ascent;
20364 glyph->voffset = it->voffset;
20365 glyph->type = STRETCH_GLYPH;
20366 glyph->multibyte_p = it->multibyte_p;
20367 glyph->left_box_line_p = it->start_of_box_run_p;
20368 glyph->right_box_line_p = it->end_of_box_run_p;
20369 glyph->overlaps_vertically_p = 0;
20370 glyph->padding_p = 0;
20371 glyph->glyph_not_available_p = 0;
20372 glyph->face_id = it->face_id;
20373 glyph->u.stretch.ascent = ascent;
20374 glyph->u.stretch.height = height;
20375 glyph->slice = null_glyph_slice;
20376 glyph->font_type = FONT_TYPE_UNKNOWN;
20377 ++it->glyph_row->used[area];
20379 else
20380 IT_EXPAND_MATRIX_WIDTH (it, area);
20384 /* Produce a stretch glyph for iterator IT. IT->object is the value
20385 of the glyph property displayed. The value must be a list
20386 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
20387 being recognized:
20389 1. `:width WIDTH' specifies that the space should be WIDTH *
20390 canonical char width wide. WIDTH may be an integer or floating
20391 point number.
20393 2. `:relative-width FACTOR' specifies that the width of the stretch
20394 should be computed from the width of the first character having the
20395 `glyph' property, and should be FACTOR times that width.
20397 3. `:align-to HPOS' specifies that the space should be wide enough
20398 to reach HPOS, a value in canonical character units.
20400 Exactly one of the above pairs must be present.
20402 4. `:height HEIGHT' specifies that the height of the stretch produced
20403 should be HEIGHT, measured in canonical character units.
20405 5. `:relative-height FACTOR' specifies that the height of the
20406 stretch should be FACTOR times the height of the characters having
20407 the glyph property.
20409 Either none or exactly one of 4 or 5 must be present.
20411 6. `:ascent ASCENT' specifies that ASCENT percent of the height
20412 of the stretch should be used for the ascent of the stretch.
20413 ASCENT must be in the range 0 <= ASCENT <= 100. */
20415 static void
20416 produce_stretch_glyph (it)
20417 struct it *it;
20419 /* (space :width WIDTH :height HEIGHT ...) */
20420 Lisp_Object prop, plist;
20421 int width = 0, height = 0, align_to = -1;
20422 int zero_width_ok_p = 0, zero_height_ok_p = 0;
20423 int ascent = 0;
20424 double tem;
20425 struct face *face = FACE_FROM_ID (it->f, it->face_id);
20426 struct font *font = face->font ? face->font : FRAME_FONT (it->f);
20428 PREPARE_FACE_FOR_DISPLAY (it->f, face);
20430 /* List should start with `space'. */
20431 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
20432 plist = XCDR (it->object);
20434 /* Compute the width of the stretch. */
20435 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
20436 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
20438 /* Absolute width `:width WIDTH' specified and valid. */
20439 zero_width_ok_p = 1;
20440 width = (int)tem;
20442 else if (prop = Fplist_get (plist, QCrelative_width),
20443 NUMVAL (prop) > 0)
20445 /* Relative width `:relative-width FACTOR' specified and valid.
20446 Compute the width of the characters having the `glyph'
20447 property. */
20448 struct it it2;
20449 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
20451 it2 = *it;
20452 if (it->multibyte_p)
20454 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
20455 - IT_BYTEPOS (*it));
20456 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
20458 else
20459 it2.c = *p, it2.len = 1;
20461 it2.glyph_row = NULL;
20462 it2.what = IT_CHARACTER;
20463 x_produce_glyphs (&it2);
20464 width = NUMVAL (prop) * it2.pixel_width;
20466 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
20467 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
20469 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
20470 align_to = (align_to < 0
20472 : align_to - window_box_left_offset (it->w, TEXT_AREA));
20473 else if (align_to < 0)
20474 align_to = window_box_left_offset (it->w, TEXT_AREA);
20475 width = max (0, (int)tem + align_to - it->current_x);
20476 zero_width_ok_p = 1;
20478 else
20479 /* Nothing specified -> width defaults to canonical char width. */
20480 width = FRAME_COLUMN_WIDTH (it->f);
20482 if (width <= 0 && (width < 0 || !zero_width_ok_p))
20483 width = 1;
20485 /* Compute height. */
20486 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
20487 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
20489 height = (int)tem;
20490 zero_height_ok_p = 1;
20492 else if (prop = Fplist_get (plist, QCrelative_height),
20493 NUMVAL (prop) > 0)
20494 height = FONT_HEIGHT (font) * NUMVAL (prop);
20495 else
20496 height = FONT_HEIGHT (font);
20498 if (height <= 0 && (height < 0 || !zero_height_ok_p))
20499 height = 1;
20501 /* Compute percentage of height used for ascent. If
20502 `:ascent ASCENT' is present and valid, use that. Otherwise,
20503 derive the ascent from the font in use. */
20504 if (prop = Fplist_get (plist, QCascent),
20505 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
20506 ascent = height * NUMVAL (prop) / 100.0;
20507 else if (!NILP (prop)
20508 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
20509 ascent = min (max (0, (int)tem), height);
20510 else
20511 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
20513 if (width > 0 && !it->truncate_lines_p
20514 && it->current_x + width > it->last_visible_x)
20515 width = it->last_visible_x - it->current_x - 1;
20517 if (width > 0 && height > 0 && it->glyph_row)
20519 Lisp_Object object = it->stack[it->sp - 1].string;
20520 if (!STRINGP (object))
20521 object = it->w->buffer;
20522 append_stretch_glyph (it, object, width, height, ascent);
20525 it->pixel_width = width;
20526 it->ascent = it->phys_ascent = ascent;
20527 it->descent = it->phys_descent = height - it->ascent;
20528 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
20530 take_vertical_position_into_account (it);
20533 /* Get line-height and line-spacing property at point.
20534 If line-height has format (HEIGHT TOTAL), return TOTAL
20535 in TOTAL_HEIGHT. */
20537 static Lisp_Object
20538 get_line_height_property (it, prop)
20539 struct it *it;
20540 Lisp_Object prop;
20542 Lisp_Object position;
20544 if (STRINGP (it->object))
20545 position = make_number (IT_STRING_CHARPOS (*it));
20546 else if (BUFFERP (it->object))
20547 position = make_number (IT_CHARPOS (*it));
20548 else
20549 return Qnil;
20551 return Fget_char_property (position, prop, it->object);
20554 /* Calculate line-height and line-spacing properties.
20555 An integer value specifies explicit pixel value.
20556 A float value specifies relative value to current face height.
20557 A cons (float . face-name) specifies relative value to
20558 height of specified face font.
20560 Returns height in pixels, or nil. */
20563 static Lisp_Object
20564 calc_line_height_property (it, val, font, boff, override)
20565 struct it *it;
20566 Lisp_Object val;
20567 struct font *font;
20568 int boff, override;
20570 Lisp_Object face_name = Qnil;
20571 int ascent, descent, height;
20573 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
20574 return val;
20576 if (CONSP (val))
20578 face_name = XCAR (val);
20579 val = XCDR (val);
20580 if (!NUMBERP (val))
20581 val = make_number (1);
20582 if (NILP (face_name))
20584 height = it->ascent + it->descent;
20585 goto scale;
20589 if (NILP (face_name))
20591 font = FRAME_FONT (it->f);
20592 boff = FRAME_BASELINE_OFFSET (it->f);
20594 else if (EQ (face_name, Qt))
20596 override = 0;
20598 else
20600 int face_id;
20601 struct face *face;
20603 face_id = lookup_named_face (it->f, face_name, 0);
20604 if (face_id < 0)
20605 return make_number (-1);
20607 face = FACE_FROM_ID (it->f, face_id);
20608 font = face->font;
20609 if (font == NULL)
20610 return make_number (-1);
20611 boff = font->baseline_offset;
20612 if (font->vertical_centering)
20613 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
20616 ascent = FONT_BASE (font) + boff;
20617 descent = FONT_DESCENT (font) - boff;
20619 if (override)
20621 it->override_ascent = ascent;
20622 it->override_descent = descent;
20623 it->override_boff = boff;
20626 height = ascent + descent;
20628 scale:
20629 if (FLOATP (val))
20630 height = (int)(XFLOAT_DATA (val) * height);
20631 else if (INTEGERP (val))
20632 height *= XINT (val);
20634 return make_number (height);
20638 /* RIF:
20639 Produce glyphs/get display metrics for the display element IT is
20640 loaded with. See the description of struct it in dispextern.h
20641 for an overview of struct it. */
20643 void
20644 x_produce_glyphs (it)
20645 struct it *it;
20647 int extra_line_spacing = it->extra_line_spacing;
20649 it->glyph_not_available_p = 0;
20651 if (it->what == IT_CHARACTER)
20653 XChar2b char2b;
20654 struct font *font;
20655 struct face *face = FACE_FROM_ID (it->f, it->face_id);
20656 struct font_metrics *pcm;
20657 int font_not_found_p;
20658 int boff; /* baseline offset */
20659 /* We may change it->multibyte_p upon unibyte<->multibyte
20660 conversion. So, save the current value now and restore it
20661 later.
20663 Note: It seems that we don't have to record multibyte_p in
20664 struct glyph because the character code itself tells if or
20665 not the character is multibyte. Thus, in the future, we must
20666 consider eliminating the field `multibyte_p' in the struct
20667 glyph. */
20668 int saved_multibyte_p = it->multibyte_p;
20670 /* Maybe translate single-byte characters to multibyte, or the
20671 other way. */
20672 it->char_to_display = it->c;
20673 if (!ASCII_BYTE_P (it->c)
20674 && ! it->multibyte_p)
20676 if (SINGLE_BYTE_CHAR_P (it->c)
20677 && unibyte_display_via_language_environment)
20678 it->char_to_display = unibyte_char_to_multibyte (it->c);
20679 if (! SINGLE_BYTE_CHAR_P (it->char_to_display))
20681 it->multibyte_p = 1;
20682 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display,
20683 -1, Qnil);
20684 face = FACE_FROM_ID (it->f, it->face_id);
20688 /* Get font to use. Encode IT->char_to_display. */
20689 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
20690 &char2b, it->multibyte_p, 0);
20691 font = face->font;
20693 /* When no suitable font found, use the default font. */
20694 font_not_found_p = font == NULL;
20695 if (font_not_found_p)
20697 font = FRAME_FONT (it->f);
20698 boff = FRAME_BASELINE_OFFSET (it->f);
20700 else
20702 boff = font->baseline_offset;
20703 if (font->vertical_centering)
20704 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
20707 if (it->char_to_display >= ' '
20708 && (!it->multibyte_p || it->char_to_display < 128))
20710 /* Either unibyte or ASCII. */
20711 int stretched_p;
20713 it->nglyphs = 1;
20715 pcm = get_per_char_metric (it->f, font, &char2b);
20717 if (it->override_ascent >= 0)
20719 it->ascent = it->override_ascent;
20720 it->descent = it->override_descent;
20721 boff = it->override_boff;
20723 else
20725 it->ascent = FONT_BASE (font) + boff;
20726 it->descent = FONT_DESCENT (font) - boff;
20729 if (pcm)
20731 it->phys_ascent = pcm->ascent + boff;
20732 it->phys_descent = pcm->descent - boff;
20733 it->pixel_width = pcm->width;
20735 else
20737 it->glyph_not_available_p = 1;
20738 it->phys_ascent = it->ascent;
20739 it->phys_descent = it->descent;
20740 it->pixel_width = FONT_WIDTH (font);
20743 if (it->constrain_row_ascent_descent_p)
20745 if (it->descent > it->max_descent)
20747 it->ascent += it->descent - it->max_descent;
20748 it->descent = it->max_descent;
20750 if (it->ascent > it->max_ascent)
20752 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
20753 it->ascent = it->max_ascent;
20755 it->phys_ascent = min (it->phys_ascent, it->ascent);
20756 it->phys_descent = min (it->phys_descent, it->descent);
20757 extra_line_spacing = 0;
20760 /* If this is a space inside a region of text with
20761 `space-width' property, change its width. */
20762 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
20763 if (stretched_p)
20764 it->pixel_width *= XFLOATINT (it->space_width);
20766 /* If face has a box, add the box thickness to the character
20767 height. If character has a box line to the left and/or
20768 right, add the box line width to the character's width. */
20769 if (face->box != FACE_NO_BOX)
20771 int thick = face->box_line_width;
20773 if (thick > 0)
20775 it->ascent += thick;
20776 it->descent += thick;
20778 else
20779 thick = -thick;
20781 if (it->start_of_box_run_p)
20782 it->pixel_width += thick;
20783 if (it->end_of_box_run_p)
20784 it->pixel_width += thick;
20787 /* If face has an overline, add the height of the overline
20788 (1 pixel) and a 1 pixel margin to the character height. */
20789 if (face->overline_p)
20790 it->ascent += overline_margin;
20792 if (it->constrain_row_ascent_descent_p)
20794 if (it->ascent > it->max_ascent)
20795 it->ascent = it->max_ascent;
20796 if (it->descent > it->max_descent)
20797 it->descent = it->max_descent;
20800 take_vertical_position_into_account (it);
20802 /* If we have to actually produce glyphs, do it. */
20803 if (it->glyph_row)
20805 if (stretched_p)
20807 /* Translate a space with a `space-width' property
20808 into a stretch glyph. */
20809 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
20810 / FONT_HEIGHT (font));
20811 append_stretch_glyph (it, it->object, it->pixel_width,
20812 it->ascent + it->descent, ascent);
20814 else
20815 append_glyph (it);
20817 /* If characters with lbearing or rbearing are displayed
20818 in this line, record that fact in a flag of the
20819 glyph row. This is used to optimize X output code. */
20820 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
20821 it->glyph_row->contains_overlapping_glyphs_p = 1;
20823 if (! stretched_p && it->pixel_width == 0)
20824 /* We assure that all visible glyphs have at least 1-pixel
20825 width. */
20826 it->pixel_width = 1;
20828 else if (it->char_to_display == '\n')
20830 /* A newline has no width but we need the height of the line.
20831 But if previous part of the line set a height, don't
20832 increase that height */
20834 Lisp_Object height;
20835 Lisp_Object total_height = Qnil;
20837 it->override_ascent = -1;
20838 it->pixel_width = 0;
20839 it->nglyphs = 0;
20841 height = get_line_height_property(it, Qline_height);
20842 /* Split (line-height total-height) list */
20843 if (CONSP (height)
20844 && CONSP (XCDR (height))
20845 && NILP (XCDR (XCDR (height))))
20847 total_height = XCAR (XCDR (height));
20848 height = XCAR (height);
20850 height = calc_line_height_property(it, height, font, boff, 1);
20852 if (it->override_ascent >= 0)
20854 it->ascent = it->override_ascent;
20855 it->descent = it->override_descent;
20856 boff = it->override_boff;
20858 else
20860 it->ascent = FONT_BASE (font) + boff;
20861 it->descent = FONT_DESCENT (font) - boff;
20864 if (EQ (height, Qt))
20866 if (it->descent > it->max_descent)
20868 it->ascent += it->descent - it->max_descent;
20869 it->descent = it->max_descent;
20871 if (it->ascent > it->max_ascent)
20873 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
20874 it->ascent = it->max_ascent;
20876 it->phys_ascent = min (it->phys_ascent, it->ascent);
20877 it->phys_descent = min (it->phys_descent, it->descent);
20878 it->constrain_row_ascent_descent_p = 1;
20879 extra_line_spacing = 0;
20881 else
20883 Lisp_Object spacing;
20885 it->phys_ascent = it->ascent;
20886 it->phys_descent = it->descent;
20888 if ((it->max_ascent > 0 || it->max_descent > 0)
20889 && face->box != FACE_NO_BOX
20890 && face->box_line_width > 0)
20892 it->ascent += face->box_line_width;
20893 it->descent += face->box_line_width;
20895 if (!NILP (height)
20896 && XINT (height) > it->ascent + it->descent)
20897 it->ascent = XINT (height) - it->descent;
20899 if (!NILP (total_height))
20900 spacing = calc_line_height_property(it, total_height, font, boff, 0);
20901 else
20903 spacing = get_line_height_property(it, Qline_spacing);
20904 spacing = calc_line_height_property(it, spacing, font, boff, 0);
20906 if (INTEGERP (spacing))
20908 extra_line_spacing = XINT (spacing);
20909 if (!NILP (total_height))
20910 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
20914 else if (it->char_to_display == '\t')
20916 int tab_width = it->tab_width * FRAME_SPACE_WIDTH (it->f);
20917 int x = it->current_x + it->continuation_lines_width;
20918 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
20920 /* If the distance from the current position to the next tab
20921 stop is less than a space character width, use the
20922 tab stop after that. */
20923 if (next_tab_x - x < FRAME_SPACE_WIDTH (it->f))
20924 next_tab_x += tab_width;
20926 it->pixel_width = next_tab_x - x;
20927 it->nglyphs = 1;
20928 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
20929 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
20931 if (it->glyph_row)
20933 append_stretch_glyph (it, it->object, it->pixel_width,
20934 it->ascent + it->descent, it->ascent);
20937 else
20939 /* A multi-byte character. Assume that the display width of the
20940 character is the width of the character multiplied by the
20941 width of the font. */
20943 /* If we found a font, this font should give us the right
20944 metrics. If we didn't find a font, use the frame's
20945 default font and calculate the width of the character by
20946 multiplying the width of font by the width of the
20947 character. */
20949 pcm = get_per_char_metric (it->f, font, &char2b);
20951 if (font_not_found_p || !pcm)
20953 int char_width = CHAR_WIDTH (it->char_to_display);
20955 if (char_width == 0)
20956 /* This is a non spacing character. But, as we are
20957 going to display an empty box, the box must occupy
20958 at least one column. */
20959 char_width = 1;
20960 it->glyph_not_available_p = 1;
20961 it->pixel_width = FRAME_COLUMN_WIDTH (it->f) * char_width;
20962 it->phys_ascent = FONT_BASE (font) + boff;
20963 it->phys_descent = FONT_DESCENT (font) - boff;
20965 else
20967 it->pixel_width = pcm->width;
20968 it->phys_ascent = pcm->ascent + boff;
20969 it->phys_descent = pcm->descent - boff;
20970 if (it->glyph_row
20971 && (pcm->lbearing < 0
20972 || pcm->rbearing > pcm->width))
20973 it->glyph_row->contains_overlapping_glyphs_p = 1;
20975 it->nglyphs = 1;
20976 it->ascent = FONT_BASE (font) + boff;
20977 it->descent = FONT_DESCENT (font) - boff;
20978 if (face->box != FACE_NO_BOX)
20980 int thick = face->box_line_width;
20982 if (thick > 0)
20984 it->ascent += thick;
20985 it->descent += thick;
20987 else
20988 thick = - thick;
20990 if (it->start_of_box_run_p)
20991 it->pixel_width += thick;
20992 if (it->end_of_box_run_p)
20993 it->pixel_width += thick;
20996 /* If face has an overline, add the height of the overline
20997 (1 pixel) and a 1 pixel margin to the character height. */
20998 if (face->overline_p)
20999 it->ascent += overline_margin;
21001 take_vertical_position_into_account (it);
21003 if (it->ascent < 0)
21004 it->ascent = 0;
21005 if (it->descent < 0)
21006 it->descent = 0;
21008 if (it->glyph_row)
21009 append_glyph (it);
21010 if (it->pixel_width == 0)
21011 /* We assure that all visible glyphs have at least 1-pixel
21012 width. */
21013 it->pixel_width = 1;
21015 it->multibyte_p = saved_multibyte_p;
21017 else if (it->what == IT_COMPOSITION)
21019 /* Note: A composition is represented as one glyph in the
21020 glyph matrix. There are no padding glyphs.
21022 Important is that pixel_width, ascent, and descent are the
21023 values of what is drawn by draw_glyphs (i.e. the values of
21024 the overall glyphs composed). */
21025 struct face *face = FACE_FROM_ID (it->f, it->face_id);
21026 int boff; /* baseline offset */
21027 struct composition *cmp = composition_table[it->cmp_id];
21028 int glyph_len = cmp->glyph_len;
21029 struct font *font = face->font;
21031 it->nglyphs = 1;
21033 if (cmp->method == COMPOSITION_WITH_GLYPH_STRING)
21035 PREPARE_FACE_FOR_DISPLAY (it->f, face);
21036 font_prepare_composition (cmp, it->f);
21038 else
21039 /* If we have not yet calculated pixel size data of glyphs of
21040 the composition for the current face font, calculate them
21041 now. Theoretically, we have to check all fonts for the
21042 glyphs, but that requires much time and memory space. So,
21043 here we check only the font of the first glyph. This leads
21044 to incorrect display, but it's very rare, and C-l (recenter)
21045 can correct the display anyway. */
21046 if (! cmp->font || cmp->font != font)
21048 /* Ascent and descent of the font of the first character
21049 of this composition (adjusted by baseline offset).
21050 Ascent and descent of overall glyphs should not be less
21051 than them respectively. */
21052 int font_ascent, font_descent, font_height;
21053 /* Bounding box of the overall glyphs. */
21054 int leftmost, rightmost, lowest, highest;
21055 int lbearing, rbearing;
21056 int i, width, ascent, descent;
21057 int left_padded = 0, right_padded = 0;
21058 int face_id;
21059 int c;
21060 XChar2b char2b;
21061 struct font_metrics *pcm;
21062 int font_not_found_p;
21063 int pos;
21065 for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
21066 if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
21067 break;
21068 if (glyph_len < cmp->glyph_len)
21069 right_padded = 1;
21070 for (i = 0; i < glyph_len; i++)
21072 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
21073 break;
21074 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
21076 if (i > 0)
21077 left_padded = 1;
21079 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
21080 : IT_CHARPOS (*it));
21081 /* When no suitable font found, use the default font. */
21082 font_not_found_p = font == NULL;
21083 if (font_not_found_p)
21085 face = face->ascii_face;
21086 font = face->font;
21088 boff = font->baseline_offset;
21089 if (font->vertical_centering)
21090 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
21091 font_ascent = FONT_BASE (font) + boff;
21092 font_descent = FONT_DESCENT (font) - boff;
21093 font_height = FONT_HEIGHT (font);
21095 cmp->font = (void *) font;
21097 pcm = NULL;
21098 if (! font_not_found_p)
21100 get_char_face_and_encoding (it->f, c, it->face_id,
21101 &char2b, it->multibyte_p, 0);
21102 pcm = get_per_char_metric (it->f, font, &char2b);
21105 /* Initialize the bounding box. */
21106 if (pcm)
21108 width = pcm->width;
21109 ascent = pcm->ascent;
21110 descent = pcm->descent;
21111 lbearing = pcm->lbearing;
21112 rbearing = pcm->rbearing;
21114 else
21116 width = FONT_WIDTH (font);
21117 ascent = FONT_BASE (font);
21118 descent = FONT_DESCENT (font);
21119 lbearing = 0;
21120 rbearing = width;
21123 rightmost = width;
21124 leftmost = 0;
21125 lowest = - descent + boff;
21126 highest = ascent + boff;
21128 if (! font_not_found_p
21129 && font->default_ascent
21130 && CHAR_TABLE_P (Vuse_default_ascent)
21131 && !NILP (Faref (Vuse_default_ascent,
21132 make_number (it->char_to_display))))
21133 highest = font->default_ascent + boff;
21135 /* Draw the first glyph at the normal position. It may be
21136 shifted to right later if some other glyphs are drawn
21137 at the left. */
21138 cmp->offsets[i * 2] = 0;
21139 cmp->offsets[i * 2 + 1] = boff;
21140 cmp->lbearing = lbearing;
21141 cmp->rbearing = rbearing;
21143 /* Set cmp->offsets for the remaining glyphs. */
21144 for (i++; i < glyph_len; i++)
21146 int left, right, btm, top;
21147 int ch = COMPOSITION_GLYPH (cmp, i);
21148 int face_id;
21149 struct face *this_face;
21150 int this_boff;
21152 if (ch == '\t')
21153 ch = ' ';
21154 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
21155 this_face = FACE_FROM_ID (it->f, face_id);
21156 font = this_face->font;
21158 if (font == NULL)
21159 pcm = NULL;
21160 else
21162 this_boff = font->baseline_offset;
21163 if (font->vertical_centering)
21164 this_boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
21165 get_char_face_and_encoding (it->f, ch, face_id,
21166 &char2b, it->multibyte_p, 0);
21167 pcm = get_per_char_metric (it->f, font, &char2b);
21169 if (! pcm)
21170 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
21171 else
21173 width = pcm->width;
21174 ascent = pcm->ascent;
21175 descent = pcm->descent;
21176 lbearing = pcm->lbearing;
21177 rbearing = pcm->rbearing;
21178 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
21180 /* Relative composition with or without
21181 alternate chars. */
21182 left = (leftmost + rightmost - width) / 2;
21183 btm = - descent + boff;
21184 if (font->relative_compose
21185 && (! CHAR_TABLE_P (Vignore_relative_composition)
21186 || NILP (Faref (Vignore_relative_composition,
21187 make_number (ch)))))
21190 if (- descent >= font->relative_compose)
21191 /* One extra pixel between two glyphs. */
21192 btm = highest + 1;
21193 else if (ascent <= 0)
21194 /* One extra pixel between two glyphs. */
21195 btm = lowest - 1 - ascent - descent;
21198 else
21200 /* A composition rule is specified by an integer
21201 value that encodes global and new reference
21202 points (GREF and NREF). GREF and NREF are
21203 specified by numbers as below:
21205 0---1---2 -- ascent
21209 9--10--11 -- center
21211 ---3---4---5--- baseline
21213 6---7---8 -- descent
21215 int rule = COMPOSITION_RULE (cmp, i);
21216 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
21218 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
21219 grefx = gref % 3, nrefx = nref % 3;
21220 grefy = gref / 3, nrefy = nref / 3;
21221 if (xoff)
21222 xoff = font_height * (xoff - 128) / 256;
21223 if (yoff)
21224 yoff = font_height * (yoff - 128) / 256;
21226 left = (leftmost
21227 + grefx * (rightmost - leftmost) / 2
21228 - nrefx * width / 2
21229 + xoff);
21231 btm = ((grefy == 0 ? highest
21232 : grefy == 1 ? 0
21233 : grefy == 2 ? lowest
21234 : (highest + lowest) / 2)
21235 - (nrefy == 0 ? ascent + descent
21236 : nrefy == 1 ? descent - boff
21237 : nrefy == 2 ? 0
21238 : (ascent + descent) / 2)
21239 + yoff);
21242 cmp->offsets[i * 2] = left;
21243 cmp->offsets[i * 2 + 1] = btm + descent;
21245 /* Update the bounding box of the overall glyphs. */
21246 if (width > 0)
21248 right = left + width;
21249 if (left < leftmost)
21250 leftmost = left;
21251 if (right > rightmost)
21252 rightmost = right;
21254 top = btm + descent + ascent;
21255 if (top > highest)
21256 highest = top;
21257 if (btm < lowest)
21258 lowest = btm;
21260 if (cmp->lbearing > left + lbearing)
21261 cmp->lbearing = left + lbearing;
21262 if (cmp->rbearing < left + rbearing)
21263 cmp->rbearing = left + rbearing;
21267 /* If there are glyphs whose x-offsets are negative,
21268 shift all glyphs to the right and make all x-offsets
21269 non-negative. */
21270 if (leftmost < 0)
21272 for (i = 0; i < cmp->glyph_len; i++)
21273 cmp->offsets[i * 2] -= leftmost;
21274 rightmost -= leftmost;
21275 cmp->lbearing -= leftmost;
21276 cmp->rbearing -= leftmost;
21279 if (left_padded && cmp->lbearing < 0)
21281 for (i = 0; i < cmp->glyph_len; i++)
21282 cmp->offsets[i * 2] -= cmp->lbearing;
21283 rightmost -= cmp->lbearing;
21284 cmp->rbearing -= cmp->lbearing;
21285 cmp->lbearing = 0;
21287 if (right_padded && rightmost < cmp->rbearing)
21289 rightmost = cmp->rbearing;
21292 cmp->pixel_width = rightmost;
21293 cmp->ascent = highest;
21294 cmp->descent = - lowest;
21295 if (cmp->ascent < font_ascent)
21296 cmp->ascent = font_ascent;
21297 if (cmp->descent < font_descent)
21298 cmp->descent = font_descent;
21301 if (it->glyph_row
21302 && (cmp->lbearing < 0
21303 || cmp->rbearing > cmp->pixel_width))
21304 it->glyph_row->contains_overlapping_glyphs_p = 1;
21306 it->pixel_width = cmp->pixel_width;
21307 it->ascent = it->phys_ascent = cmp->ascent;
21308 it->descent = it->phys_descent = cmp->descent;
21309 if (face->box != FACE_NO_BOX)
21311 int thick = face->box_line_width;
21313 if (thick > 0)
21315 it->ascent += thick;
21316 it->descent += thick;
21318 else
21319 thick = - thick;
21321 if (it->start_of_box_run_p)
21322 it->pixel_width += thick;
21323 if (it->end_of_box_run_p)
21324 it->pixel_width += thick;
21327 /* If face has an overline, add the height of the overline
21328 (1 pixel) and a 1 pixel margin to the character height. */
21329 if (face->overline_p)
21330 it->ascent += overline_margin;
21332 take_vertical_position_into_account (it);
21333 if (it->ascent < 0)
21334 it->ascent = 0;
21335 if (it->descent < 0)
21336 it->descent = 0;
21338 if (it->glyph_row)
21339 append_composite_glyph (it);
21341 else if (it->what == IT_IMAGE)
21342 produce_image_glyph (it);
21343 else if (it->what == IT_STRETCH)
21344 produce_stretch_glyph (it);
21346 /* Accumulate dimensions. Note: can't assume that it->descent > 0
21347 because this isn't true for images with `:ascent 100'. */
21348 xassert (it->ascent >= 0 && it->descent >= 0);
21349 if (it->area == TEXT_AREA)
21350 it->current_x += it->pixel_width;
21352 if (extra_line_spacing > 0)
21354 it->descent += extra_line_spacing;
21355 if (extra_line_spacing > it->max_extra_line_spacing)
21356 it->max_extra_line_spacing = extra_line_spacing;
21359 it->max_ascent = max (it->max_ascent, it->ascent);
21360 it->max_descent = max (it->max_descent, it->descent);
21361 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
21362 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
21365 /* EXPORT for RIF:
21366 Output LEN glyphs starting at START at the nominal cursor position.
21367 Advance the nominal cursor over the text. The global variable
21368 updated_window contains the window being updated, updated_row is
21369 the glyph row being updated, and updated_area is the area of that
21370 row being updated. */
21372 void
21373 x_write_glyphs (start, len)
21374 struct glyph *start;
21375 int len;
21377 int x, hpos;
21379 xassert (updated_window && updated_row);
21380 BLOCK_INPUT;
21382 /* Write glyphs. */
21384 hpos = start - updated_row->glyphs[updated_area];
21385 x = draw_glyphs (updated_window, output_cursor.x,
21386 updated_row, updated_area,
21387 hpos, hpos + len,
21388 DRAW_NORMAL_TEXT, 0);
21390 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
21391 if (updated_area == TEXT_AREA
21392 && updated_window->phys_cursor_on_p
21393 && updated_window->phys_cursor.vpos == output_cursor.vpos
21394 && updated_window->phys_cursor.hpos >= hpos
21395 && updated_window->phys_cursor.hpos < hpos + len)
21396 updated_window->phys_cursor_on_p = 0;
21398 UNBLOCK_INPUT;
21400 /* Advance the output cursor. */
21401 output_cursor.hpos += len;
21402 output_cursor.x = x;
21406 /* EXPORT for RIF:
21407 Insert LEN glyphs from START at the nominal cursor position. */
21409 void
21410 x_insert_glyphs (start, len)
21411 struct glyph *start;
21412 int len;
21414 struct frame *f;
21415 struct window *w;
21416 int line_height, shift_by_width, shifted_region_width;
21417 struct glyph_row *row;
21418 struct glyph *glyph;
21419 int frame_x, frame_y;
21420 EMACS_INT hpos;
21422 xassert (updated_window && updated_row);
21423 BLOCK_INPUT;
21424 w = updated_window;
21425 f = XFRAME (WINDOW_FRAME (w));
21427 /* Get the height of the line we are in. */
21428 row = updated_row;
21429 line_height = row->height;
21431 /* Get the width of the glyphs to insert. */
21432 shift_by_width = 0;
21433 for (glyph = start; glyph < start + len; ++glyph)
21434 shift_by_width += glyph->pixel_width;
21436 /* Get the width of the region to shift right. */
21437 shifted_region_width = (window_box_width (w, updated_area)
21438 - output_cursor.x
21439 - shift_by_width);
21441 /* Shift right. */
21442 frame_x = window_box_left (w, updated_area) + output_cursor.x;
21443 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
21445 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
21446 line_height, shift_by_width);
21448 /* Write the glyphs. */
21449 hpos = start - row->glyphs[updated_area];
21450 draw_glyphs (w, output_cursor.x, row, updated_area,
21451 hpos, hpos + len,
21452 DRAW_NORMAL_TEXT, 0);
21454 /* Advance the output cursor. */
21455 output_cursor.hpos += len;
21456 output_cursor.x += shift_by_width;
21457 UNBLOCK_INPUT;
21461 /* EXPORT for RIF:
21462 Erase the current text line from the nominal cursor position
21463 (inclusive) to pixel column TO_X (exclusive). The idea is that
21464 everything from TO_X onward is already erased.
21466 TO_X is a pixel position relative to updated_area of
21467 updated_window. TO_X == -1 means clear to the end of this area. */
21469 void
21470 x_clear_end_of_line (to_x)
21471 int to_x;
21473 struct frame *f;
21474 struct window *w = updated_window;
21475 int max_x, min_y, max_y;
21476 int from_x, from_y, to_y;
21478 xassert (updated_window && updated_row);
21479 f = XFRAME (w->frame);
21481 if (updated_row->full_width_p)
21482 max_x = WINDOW_TOTAL_WIDTH (w);
21483 else
21484 max_x = window_box_width (w, updated_area);
21485 max_y = window_text_bottom_y (w);
21487 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
21488 of window. For TO_X > 0, truncate to end of drawing area. */
21489 if (to_x == 0)
21490 return;
21491 else if (to_x < 0)
21492 to_x = max_x;
21493 else
21494 to_x = min (to_x, max_x);
21496 to_y = min (max_y, output_cursor.y + updated_row->height);
21498 /* Notice if the cursor will be cleared by this operation. */
21499 if (!updated_row->full_width_p)
21500 notice_overwritten_cursor (w, updated_area,
21501 output_cursor.x, -1,
21502 updated_row->y,
21503 MATRIX_ROW_BOTTOM_Y (updated_row));
21505 from_x = output_cursor.x;
21507 /* Translate to frame coordinates. */
21508 if (updated_row->full_width_p)
21510 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
21511 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
21513 else
21515 int area_left = window_box_left (w, updated_area);
21516 from_x += area_left;
21517 to_x += area_left;
21520 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
21521 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
21522 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
21524 /* Prevent inadvertently clearing to end of the X window. */
21525 if (to_x > from_x && to_y > from_y)
21527 BLOCK_INPUT;
21528 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
21529 to_x - from_x, to_y - from_y);
21530 UNBLOCK_INPUT;
21534 #endif /* HAVE_WINDOW_SYSTEM */
21538 /***********************************************************************
21539 Cursor types
21540 ***********************************************************************/
21542 /* Value is the internal representation of the specified cursor type
21543 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
21544 of the bar cursor. */
21546 static enum text_cursor_kinds
21547 get_specified_cursor_type (arg, width)
21548 Lisp_Object arg;
21549 int *width;
21551 enum text_cursor_kinds type;
21553 if (NILP (arg))
21554 return NO_CURSOR;
21556 if (EQ (arg, Qbox))
21557 return FILLED_BOX_CURSOR;
21559 if (EQ (arg, Qhollow))
21560 return HOLLOW_BOX_CURSOR;
21562 if (EQ (arg, Qbar))
21564 *width = 2;
21565 return BAR_CURSOR;
21568 if (CONSP (arg)
21569 && EQ (XCAR (arg), Qbar)
21570 && INTEGERP (XCDR (arg))
21571 && XINT (XCDR (arg)) >= 0)
21573 *width = XINT (XCDR (arg));
21574 return BAR_CURSOR;
21577 if (EQ (arg, Qhbar))
21579 *width = 2;
21580 return HBAR_CURSOR;
21583 if (CONSP (arg)
21584 && EQ (XCAR (arg), Qhbar)
21585 && INTEGERP (XCDR (arg))
21586 && XINT (XCDR (arg)) >= 0)
21588 *width = XINT (XCDR (arg));
21589 return HBAR_CURSOR;
21592 /* Treat anything unknown as "hollow box cursor".
21593 It was bad to signal an error; people have trouble fixing
21594 .Xdefaults with Emacs, when it has something bad in it. */
21595 type = HOLLOW_BOX_CURSOR;
21597 return type;
21600 /* Set the default cursor types for specified frame. */
21601 void
21602 set_frame_cursor_types (f, arg)
21603 struct frame *f;
21604 Lisp_Object arg;
21606 int width;
21607 Lisp_Object tem;
21609 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
21610 FRAME_CURSOR_WIDTH (f) = width;
21612 /* By default, set up the blink-off state depending on the on-state. */
21614 tem = Fassoc (arg, Vblink_cursor_alist);
21615 if (!NILP (tem))
21617 FRAME_BLINK_OFF_CURSOR (f)
21618 = get_specified_cursor_type (XCDR (tem), &width);
21619 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
21621 else
21622 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
21626 /* Return the cursor we want to be displayed in window W. Return
21627 width of bar/hbar cursor through WIDTH arg. Return with
21628 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
21629 (i.e. if the `system caret' should track this cursor).
21631 In a mini-buffer window, we want the cursor only to appear if we
21632 are reading input from this window. For the selected window, we
21633 want the cursor type given by the frame parameter or buffer local
21634 setting of cursor-type. If explicitly marked off, draw no cursor.
21635 In all other cases, we want a hollow box cursor. */
21637 static enum text_cursor_kinds
21638 get_window_cursor_type (w, glyph, width, active_cursor)
21639 struct window *w;
21640 struct glyph *glyph;
21641 int *width;
21642 int *active_cursor;
21644 struct frame *f = XFRAME (w->frame);
21645 struct buffer *b = XBUFFER (w->buffer);
21646 int cursor_type = DEFAULT_CURSOR;
21647 Lisp_Object alt_cursor;
21648 int non_selected = 0;
21650 *active_cursor = 1;
21652 /* Echo area */
21653 if (cursor_in_echo_area
21654 && FRAME_HAS_MINIBUF_P (f)
21655 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
21657 if (w == XWINDOW (echo_area_window))
21659 if (EQ (b->cursor_type, Qt) || NILP (b->cursor_type))
21661 *width = FRAME_CURSOR_WIDTH (f);
21662 return FRAME_DESIRED_CURSOR (f);
21664 else
21665 return get_specified_cursor_type (b->cursor_type, width);
21668 *active_cursor = 0;
21669 non_selected = 1;
21672 /* Detect a nonselected window or nonselected frame. */
21673 else if (w != XWINDOW (f->selected_window)
21674 #ifdef HAVE_WINDOW_SYSTEM
21675 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
21676 #endif
21679 *active_cursor = 0;
21681 if (MINI_WINDOW_P (w) && minibuf_level == 0)
21682 return NO_CURSOR;
21684 non_selected = 1;
21687 /* Never display a cursor in a window in which cursor-type is nil. */
21688 if (NILP (b->cursor_type))
21689 return NO_CURSOR;
21691 /* Get the normal cursor type for this window. */
21692 if (EQ (b->cursor_type, Qt))
21694 cursor_type = FRAME_DESIRED_CURSOR (f);
21695 *width = FRAME_CURSOR_WIDTH (f);
21697 else
21698 cursor_type = get_specified_cursor_type (b->cursor_type, width);
21700 /* Use cursor-in-non-selected-windows instead
21701 for non-selected window or frame. */
21702 if (non_selected)
21704 alt_cursor = b->cursor_in_non_selected_windows;
21705 if (!EQ (Qt, alt_cursor))
21706 return get_specified_cursor_type (alt_cursor, width);
21707 /* t means modify the normal cursor type. */
21708 if (cursor_type == FILLED_BOX_CURSOR)
21709 cursor_type = HOLLOW_BOX_CURSOR;
21710 else if (cursor_type == BAR_CURSOR && *width > 1)
21711 --*width;
21712 return cursor_type;
21715 /* Use normal cursor if not blinked off. */
21716 if (!w->cursor_off_p)
21718 #ifdef HAVE_WINDOW_SYSTEM
21719 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
21721 if (cursor_type == FILLED_BOX_CURSOR)
21723 /* Using a block cursor on large images can be very annoying.
21724 So use a hollow cursor for "large" images.
21725 If image is not transparent (no mask), also use hollow cursor. */
21726 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
21727 if (img != NULL && IMAGEP (img->spec))
21729 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
21730 where N = size of default frame font size.
21731 This should cover most of the "tiny" icons people may use. */
21732 if (!img->mask
21733 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
21734 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
21735 cursor_type = HOLLOW_BOX_CURSOR;
21738 else if (cursor_type != NO_CURSOR)
21740 /* Display current only supports BOX and HOLLOW cursors for images.
21741 So for now, unconditionally use a HOLLOW cursor when cursor is
21742 not a solid box cursor. */
21743 cursor_type = HOLLOW_BOX_CURSOR;
21746 #endif
21747 return cursor_type;
21750 /* Cursor is blinked off, so determine how to "toggle" it. */
21752 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
21753 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
21754 return get_specified_cursor_type (XCDR (alt_cursor), width);
21756 /* Then see if frame has specified a specific blink off cursor type. */
21757 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
21759 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
21760 return FRAME_BLINK_OFF_CURSOR (f);
21763 #if 0
21764 /* Some people liked having a permanently visible blinking cursor,
21765 while others had very strong opinions against it. So it was
21766 decided to remove it. KFS 2003-09-03 */
21768 /* Finally perform built-in cursor blinking:
21769 filled box <-> hollow box
21770 wide [h]bar <-> narrow [h]bar
21771 narrow [h]bar <-> no cursor
21772 other type <-> no cursor */
21774 if (cursor_type == FILLED_BOX_CURSOR)
21775 return HOLLOW_BOX_CURSOR;
21777 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
21779 *width = 1;
21780 return cursor_type;
21782 #endif
21784 return NO_CURSOR;
21788 #ifdef HAVE_WINDOW_SYSTEM
21790 /* Notice when the text cursor of window W has been completely
21791 overwritten by a drawing operation that outputs glyphs in AREA
21792 starting at X0 and ending at X1 in the line starting at Y0 and
21793 ending at Y1. X coordinates are area-relative. X1 < 0 means all
21794 the rest of the line after X0 has been written. Y coordinates
21795 are window-relative. */
21797 static void
21798 notice_overwritten_cursor (w, area, x0, x1, y0, y1)
21799 struct window *w;
21800 enum glyph_row_area area;
21801 int x0, y0, x1, y1;
21803 int cx0, cx1, cy0, cy1;
21804 struct glyph_row *row;
21806 if (!w->phys_cursor_on_p)
21807 return;
21808 if (area != TEXT_AREA)
21809 return;
21811 if (w->phys_cursor.vpos < 0
21812 || w->phys_cursor.vpos >= w->current_matrix->nrows
21813 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
21814 !(row->enabled_p && row->displays_text_p)))
21815 return;
21817 if (row->cursor_in_fringe_p)
21819 row->cursor_in_fringe_p = 0;
21820 draw_fringe_bitmap (w, row, 0);
21821 w->phys_cursor_on_p = 0;
21822 return;
21825 cx0 = w->phys_cursor.x;
21826 cx1 = cx0 + w->phys_cursor_width;
21827 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
21828 return;
21830 /* The cursor image will be completely removed from the
21831 screen if the output area intersects the cursor area in
21832 y-direction. When we draw in [y0 y1[, and some part of
21833 the cursor is at y < y0, that part must have been drawn
21834 before. When scrolling, the cursor is erased before
21835 actually scrolling, so we don't come here. When not
21836 scrolling, the rows above the old cursor row must have
21837 changed, and in this case these rows must have written
21838 over the cursor image.
21840 Likewise if part of the cursor is below y1, with the
21841 exception of the cursor being in the first blank row at
21842 the buffer and window end because update_text_area
21843 doesn't draw that row. (Except when it does, but
21844 that's handled in update_text_area.) */
21846 cy0 = w->phys_cursor.y;
21847 cy1 = cy0 + w->phys_cursor_height;
21848 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
21849 return;
21851 w->phys_cursor_on_p = 0;
21854 #endif /* HAVE_WINDOW_SYSTEM */
21857 /************************************************************************
21858 Mouse Face
21859 ************************************************************************/
21861 #ifdef HAVE_WINDOW_SYSTEM
21863 /* EXPORT for RIF:
21864 Fix the display of area AREA of overlapping row ROW in window W
21865 with respect to the overlapping part OVERLAPS. */
21867 void
21868 x_fix_overlapping_area (w, row, area, overlaps)
21869 struct window *w;
21870 struct glyph_row *row;
21871 enum glyph_row_area area;
21872 int overlaps;
21874 int i, x;
21876 BLOCK_INPUT;
21878 x = 0;
21879 for (i = 0; i < row->used[area];)
21881 if (row->glyphs[area][i].overlaps_vertically_p)
21883 int start = i, start_x = x;
21887 x += row->glyphs[area][i].pixel_width;
21888 ++i;
21890 while (i < row->used[area]
21891 && row->glyphs[area][i].overlaps_vertically_p);
21893 draw_glyphs (w, start_x, row, area,
21894 start, i,
21895 DRAW_NORMAL_TEXT, overlaps);
21897 else
21899 x += row->glyphs[area][i].pixel_width;
21900 ++i;
21904 UNBLOCK_INPUT;
21908 /* EXPORT:
21909 Draw the cursor glyph of window W in glyph row ROW. See the
21910 comment of draw_glyphs for the meaning of HL. */
21912 void
21913 draw_phys_cursor_glyph (w, row, hl)
21914 struct window *w;
21915 struct glyph_row *row;
21916 enum draw_glyphs_face hl;
21918 /* If cursor hpos is out of bounds, don't draw garbage. This can
21919 happen in mini-buffer windows when switching between echo area
21920 glyphs and mini-buffer. */
21921 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
21923 int on_p = w->phys_cursor_on_p;
21924 int x1;
21925 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
21926 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
21927 hl, 0);
21928 w->phys_cursor_on_p = on_p;
21930 if (hl == DRAW_CURSOR)
21931 w->phys_cursor_width = x1 - w->phys_cursor.x;
21932 /* When we erase the cursor, and ROW is overlapped by other
21933 rows, make sure that these overlapping parts of other rows
21934 are redrawn. */
21935 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
21937 w->phys_cursor_width = x1 - w->phys_cursor.x;
21939 if (row > w->current_matrix->rows
21940 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
21941 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
21942 OVERLAPS_ERASED_CURSOR);
21944 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
21945 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
21946 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
21947 OVERLAPS_ERASED_CURSOR);
21953 /* EXPORT:
21954 Erase the image of a cursor of window W from the screen. */
21956 void
21957 erase_phys_cursor (w)
21958 struct window *w;
21960 struct frame *f = XFRAME (w->frame);
21961 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21962 int hpos = w->phys_cursor.hpos;
21963 int vpos = w->phys_cursor.vpos;
21964 int mouse_face_here_p = 0;
21965 struct glyph_matrix *active_glyphs = w->current_matrix;
21966 struct glyph_row *cursor_row;
21967 struct glyph *cursor_glyph;
21968 enum draw_glyphs_face hl;
21970 /* No cursor displayed or row invalidated => nothing to do on the
21971 screen. */
21972 if (w->phys_cursor_type == NO_CURSOR)
21973 goto mark_cursor_off;
21975 /* VPOS >= active_glyphs->nrows means that window has been resized.
21976 Don't bother to erase the cursor. */
21977 if (vpos >= active_glyphs->nrows)
21978 goto mark_cursor_off;
21980 /* If row containing cursor is marked invalid, there is nothing we
21981 can do. */
21982 cursor_row = MATRIX_ROW (active_glyphs, vpos);
21983 if (!cursor_row->enabled_p)
21984 goto mark_cursor_off;
21986 /* If line spacing is > 0, old cursor may only be partially visible in
21987 window after split-window. So adjust visible height. */
21988 cursor_row->visible_height = min (cursor_row->visible_height,
21989 window_text_bottom_y (w) - cursor_row->y);
21991 /* If row is completely invisible, don't attempt to delete a cursor which
21992 isn't there. This can happen if cursor is at top of a window, and
21993 we switch to a buffer with a header line in that window. */
21994 if (cursor_row->visible_height <= 0)
21995 goto mark_cursor_off;
21997 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
21998 if (cursor_row->cursor_in_fringe_p)
22000 cursor_row->cursor_in_fringe_p = 0;
22001 draw_fringe_bitmap (w, cursor_row, 0);
22002 goto mark_cursor_off;
22005 /* This can happen when the new row is shorter than the old one.
22006 In this case, either draw_glyphs or clear_end_of_line
22007 should have cleared the cursor. Note that we wouldn't be
22008 able to erase the cursor in this case because we don't have a
22009 cursor glyph at hand. */
22010 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
22011 goto mark_cursor_off;
22013 /* If the cursor is in the mouse face area, redisplay that when
22014 we clear the cursor. */
22015 if (! NILP (dpyinfo->mouse_face_window)
22016 && w == XWINDOW (dpyinfo->mouse_face_window)
22017 && (vpos > dpyinfo->mouse_face_beg_row
22018 || (vpos == dpyinfo->mouse_face_beg_row
22019 && hpos >= dpyinfo->mouse_face_beg_col))
22020 && (vpos < dpyinfo->mouse_face_end_row
22021 || (vpos == dpyinfo->mouse_face_end_row
22022 && hpos < dpyinfo->mouse_face_end_col))
22023 /* Don't redraw the cursor's spot in mouse face if it is at the
22024 end of a line (on a newline). The cursor appears there, but
22025 mouse highlighting does not. */
22026 && cursor_row->used[TEXT_AREA] > hpos)
22027 mouse_face_here_p = 1;
22029 /* Maybe clear the display under the cursor. */
22030 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
22032 int x, y, left_x;
22033 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
22034 int width;
22036 cursor_glyph = get_phys_cursor_glyph (w);
22037 if (cursor_glyph == NULL)
22038 goto mark_cursor_off;
22040 width = cursor_glyph->pixel_width;
22041 left_x = window_box_left_offset (w, TEXT_AREA);
22042 x = w->phys_cursor.x;
22043 if (x < left_x)
22044 width -= left_x - x;
22045 width = min (width, window_box_width (w, TEXT_AREA) - x);
22046 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
22047 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
22049 if (width > 0)
22050 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
22053 /* Erase the cursor by redrawing the character underneath it. */
22054 if (mouse_face_here_p)
22055 hl = DRAW_MOUSE_FACE;
22056 else
22057 hl = DRAW_NORMAL_TEXT;
22058 draw_phys_cursor_glyph (w, cursor_row, hl);
22060 mark_cursor_off:
22061 w->phys_cursor_on_p = 0;
22062 w->phys_cursor_type = NO_CURSOR;
22066 /* EXPORT:
22067 Display or clear cursor of window W. If ON is zero, clear the
22068 cursor. If it is non-zero, display the cursor. If ON is nonzero,
22069 where to put the cursor is specified by HPOS, VPOS, X and Y. */
22071 void
22072 display_and_set_cursor (w, on, hpos, vpos, x, y)
22073 struct window *w;
22074 int on, hpos, vpos, x, y;
22076 struct frame *f = XFRAME (w->frame);
22077 int new_cursor_type;
22078 int new_cursor_width;
22079 int active_cursor;
22080 struct glyph_row *glyph_row;
22081 struct glyph *glyph;
22083 /* This is pointless on invisible frames, and dangerous on garbaged
22084 windows and frames; in the latter case, the frame or window may
22085 be in the midst of changing its size, and x and y may be off the
22086 window. */
22087 if (! FRAME_VISIBLE_P (f)
22088 || FRAME_GARBAGED_P (f)
22089 || vpos >= w->current_matrix->nrows
22090 || hpos >= w->current_matrix->matrix_w)
22091 return;
22093 /* If cursor is off and we want it off, return quickly. */
22094 if (!on && !w->phys_cursor_on_p)
22095 return;
22097 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
22098 /* If cursor row is not enabled, we don't really know where to
22099 display the cursor. */
22100 if (!glyph_row->enabled_p)
22102 w->phys_cursor_on_p = 0;
22103 return;
22106 glyph = NULL;
22107 if (!glyph_row->exact_window_width_line_p
22108 || hpos < glyph_row->used[TEXT_AREA])
22109 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
22111 xassert (interrupt_input_blocked);
22113 /* Set new_cursor_type to the cursor we want to be displayed. */
22114 new_cursor_type = get_window_cursor_type (w, glyph,
22115 &new_cursor_width, &active_cursor);
22117 /* If cursor is currently being shown and we don't want it to be or
22118 it is in the wrong place, or the cursor type is not what we want,
22119 erase it. */
22120 if (w->phys_cursor_on_p
22121 && (!on
22122 || w->phys_cursor.x != x
22123 || w->phys_cursor.y != y
22124 || new_cursor_type != w->phys_cursor_type
22125 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
22126 && new_cursor_width != w->phys_cursor_width)))
22127 erase_phys_cursor (w);
22129 /* Don't check phys_cursor_on_p here because that flag is only set
22130 to zero in some cases where we know that the cursor has been
22131 completely erased, to avoid the extra work of erasing the cursor
22132 twice. In other words, phys_cursor_on_p can be 1 and the cursor
22133 still not be visible, or it has only been partly erased. */
22134 if (on)
22136 w->phys_cursor_ascent = glyph_row->ascent;
22137 w->phys_cursor_height = glyph_row->height;
22139 /* Set phys_cursor_.* before x_draw_.* is called because some
22140 of them may need the information. */
22141 w->phys_cursor.x = x;
22142 w->phys_cursor.y = glyph_row->y;
22143 w->phys_cursor.hpos = hpos;
22144 w->phys_cursor.vpos = vpos;
22147 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
22148 new_cursor_type, new_cursor_width,
22149 on, active_cursor);
22153 /* Switch the display of W's cursor on or off, according to the value
22154 of ON. */
22156 static void
22157 update_window_cursor (w, on)
22158 struct window *w;
22159 int on;
22161 /* Don't update cursor in windows whose frame is in the process
22162 of being deleted. */
22163 if (w->current_matrix)
22165 BLOCK_INPUT;
22166 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
22167 w->phys_cursor.x, w->phys_cursor.y);
22168 UNBLOCK_INPUT;
22173 /* Call update_window_cursor with parameter ON_P on all leaf windows
22174 in the window tree rooted at W. */
22176 static void
22177 update_cursor_in_window_tree (w, on_p)
22178 struct window *w;
22179 int on_p;
22181 while (w)
22183 if (!NILP (w->hchild))
22184 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
22185 else if (!NILP (w->vchild))
22186 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
22187 else
22188 update_window_cursor (w, on_p);
22190 w = NILP (w->next) ? 0 : XWINDOW (w->next);
22195 /* EXPORT:
22196 Display the cursor on window W, or clear it, according to ON_P.
22197 Don't change the cursor's position. */
22199 void
22200 x_update_cursor (f, on_p)
22201 struct frame *f;
22202 int on_p;
22204 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
22208 /* EXPORT:
22209 Clear the cursor of window W to background color, and mark the
22210 cursor as not shown. This is used when the text where the cursor
22211 is is about to be rewritten. */
22213 void
22214 x_clear_cursor (w)
22215 struct window *w;
22217 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
22218 update_window_cursor (w, 0);
22222 /* EXPORT:
22223 Display the active region described by mouse_face_* according to DRAW. */
22225 void
22226 show_mouse_face (dpyinfo, draw)
22227 Display_Info *dpyinfo;
22228 enum draw_glyphs_face draw;
22230 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
22231 struct frame *f = XFRAME (WINDOW_FRAME (w));
22233 if (/* If window is in the process of being destroyed, don't bother
22234 to do anything. */
22235 w->current_matrix != NULL
22236 /* Don't update mouse highlight if hidden */
22237 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
22238 /* Recognize when we are called to operate on rows that don't exist
22239 anymore. This can happen when a window is split. */
22240 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
22242 int phys_cursor_on_p = w->phys_cursor_on_p;
22243 struct glyph_row *row, *first, *last;
22245 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
22246 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
22248 for (row = first; row <= last && row->enabled_p; ++row)
22250 int start_hpos, end_hpos, start_x;
22252 /* For all but the first row, the highlight starts at column 0. */
22253 if (row == first)
22255 start_hpos = dpyinfo->mouse_face_beg_col;
22256 start_x = dpyinfo->mouse_face_beg_x;
22258 else
22260 start_hpos = 0;
22261 start_x = 0;
22264 if (row == last)
22265 end_hpos = dpyinfo->mouse_face_end_col;
22266 else
22268 end_hpos = row->used[TEXT_AREA];
22269 if (draw == DRAW_NORMAL_TEXT)
22270 row->fill_line_p = 1; /* Clear to end of line */
22273 if (end_hpos > start_hpos)
22275 draw_glyphs (w, start_x, row, TEXT_AREA,
22276 start_hpos, end_hpos,
22277 draw, 0);
22279 row->mouse_face_p
22280 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
22284 /* When we've written over the cursor, arrange for it to
22285 be displayed again. */
22286 if (phys_cursor_on_p && !w->phys_cursor_on_p)
22288 BLOCK_INPUT;
22289 display_and_set_cursor (w, 1,
22290 w->phys_cursor.hpos, w->phys_cursor.vpos,
22291 w->phys_cursor.x, w->phys_cursor.y);
22292 UNBLOCK_INPUT;
22296 /* Change the mouse cursor. */
22297 if (draw == DRAW_NORMAL_TEXT && !EQ (dpyinfo->mouse_face_window, f->tool_bar_window))
22298 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
22299 else if (draw == DRAW_MOUSE_FACE)
22300 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
22301 else
22302 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
22305 /* EXPORT:
22306 Clear out the mouse-highlighted active region.
22307 Redraw it un-highlighted first. Value is non-zero if mouse
22308 face was actually drawn unhighlighted. */
22311 clear_mouse_face (dpyinfo)
22312 Display_Info *dpyinfo;
22314 int cleared = 0;
22316 if (!dpyinfo->mouse_face_hidden && !NILP (dpyinfo->mouse_face_window))
22318 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
22319 cleared = 1;
22322 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
22323 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
22324 dpyinfo->mouse_face_window = Qnil;
22325 dpyinfo->mouse_face_overlay = Qnil;
22326 return cleared;
22330 /* EXPORT:
22331 Non-zero if physical cursor of window W is within mouse face. */
22334 cursor_in_mouse_face_p (w)
22335 struct window *w;
22337 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
22338 int in_mouse_face = 0;
22340 if (WINDOWP (dpyinfo->mouse_face_window)
22341 && XWINDOW (dpyinfo->mouse_face_window) == w)
22343 int hpos = w->phys_cursor.hpos;
22344 int vpos = w->phys_cursor.vpos;
22346 if (vpos >= dpyinfo->mouse_face_beg_row
22347 && vpos <= dpyinfo->mouse_face_end_row
22348 && (vpos > dpyinfo->mouse_face_beg_row
22349 || hpos >= dpyinfo->mouse_face_beg_col)
22350 && (vpos < dpyinfo->mouse_face_end_row
22351 || hpos < dpyinfo->mouse_face_end_col
22352 || dpyinfo->mouse_face_past_end))
22353 in_mouse_face = 1;
22356 return in_mouse_face;
22362 /* Find the glyph matrix position of buffer position CHARPOS in window
22363 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
22364 current glyphs must be up to date. If CHARPOS is above window
22365 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
22366 of last line in W. In the row containing CHARPOS, stop before glyphs
22367 having STOP as object. */
22369 #if 1 /* This is a version of fast_find_position that's more correct
22370 in the presence of hscrolling, for example. I didn't install
22371 it right away because the problem fixed is minor, it failed
22372 in 20.x as well, and I think it's too risky to install
22373 so near the release of 21.1. 2001-09-25 gerd. */
22375 #ifndef HAVE_CARBON
22376 static
22377 #endif
22379 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
22380 struct window *w;
22381 EMACS_INT charpos;
22382 int *hpos, *vpos, *x, *y;
22383 Lisp_Object stop;
22385 struct glyph_row *row, *first;
22386 struct glyph *glyph, *end;
22387 int past_end = 0;
22389 first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
22390 if (charpos < MATRIX_ROW_START_CHARPOS (first))
22392 *x = first->x;
22393 *y = first->y;
22394 *hpos = 0;
22395 *vpos = MATRIX_ROW_VPOS (first, w->current_matrix);
22396 return 1;
22399 row = row_containing_pos (w, charpos, first, NULL, 0);
22400 if (row == NULL)
22402 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
22403 past_end = 1;
22406 /* If whole rows or last part of a row came from a display overlay,
22407 row_containing_pos will skip over such rows because their end pos
22408 equals the start pos of the overlay or interval.
22410 Move back if we have a STOP object and previous row's
22411 end glyph came from STOP. */
22412 if (!NILP (stop))
22414 struct glyph_row *prev;
22415 while ((prev = row - 1, prev >= first)
22416 && MATRIX_ROW_END_CHARPOS (prev) == charpos
22417 && prev->used[TEXT_AREA] > 0)
22419 struct glyph *beg = prev->glyphs[TEXT_AREA];
22420 glyph = beg + prev->used[TEXT_AREA];
22421 while (--glyph >= beg
22422 && INTEGERP (glyph->object));
22423 if (glyph < beg
22424 || !EQ (stop, glyph->object))
22425 break;
22426 row = prev;
22430 *x = row->x;
22431 *y = row->y;
22432 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
22434 glyph = row->glyphs[TEXT_AREA];
22435 end = glyph + row->used[TEXT_AREA];
22437 /* Skip over glyphs not having an object at the start of the row.
22438 These are special glyphs like truncation marks on terminal
22439 frames. */
22440 if (row->displays_text_p)
22441 while (glyph < end
22442 && INTEGERP (glyph->object)
22443 && !EQ (stop, glyph->object)
22444 && glyph->charpos < 0)
22446 *x += glyph->pixel_width;
22447 ++glyph;
22450 while (glyph < end
22451 && !INTEGERP (glyph->object)
22452 && !EQ (stop, glyph->object)
22453 && (!BUFFERP (glyph->object)
22454 || glyph->charpos < charpos))
22456 *x += glyph->pixel_width;
22457 ++glyph;
22460 *hpos = glyph - row->glyphs[TEXT_AREA];
22461 return !past_end;
22464 #else /* not 1 */
22466 static int
22467 fast_find_position (w, pos, hpos, vpos, x, y, stop)
22468 struct window *w;
22469 EMACS_INT pos;
22470 int *hpos, *vpos, *x, *y;
22471 Lisp_Object stop;
22473 int i;
22474 int lastcol;
22475 int maybe_next_line_p = 0;
22476 int line_start_position;
22477 int yb = window_text_bottom_y (w);
22478 struct glyph_row *row, *best_row;
22479 int row_vpos, best_row_vpos;
22480 int current_x;
22482 row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
22483 row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
22485 while (row->y < yb)
22487 if (row->used[TEXT_AREA])
22488 line_start_position = row->glyphs[TEXT_AREA]->charpos;
22489 else
22490 line_start_position = 0;
22492 if (line_start_position > pos)
22493 break;
22494 /* If the position sought is the end of the buffer,
22495 don't include the blank lines at the bottom of the window. */
22496 else if (line_start_position == pos
22497 && pos == BUF_ZV (XBUFFER (w->buffer)))
22499 maybe_next_line_p = 1;
22500 break;
22502 else if (line_start_position > 0)
22504 best_row = row;
22505 best_row_vpos = row_vpos;
22508 if (row->y + row->height >= yb)
22509 break;
22511 ++row;
22512 ++row_vpos;
22515 /* Find the right column within BEST_ROW. */
22516 lastcol = 0;
22517 current_x = best_row->x;
22518 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
22520 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
22521 int charpos = glyph->charpos;
22523 if (BUFFERP (glyph->object))
22525 if (charpos == pos)
22527 *hpos = i;
22528 *vpos = best_row_vpos;
22529 *x = current_x;
22530 *y = best_row->y;
22531 return 1;
22533 else if (charpos > pos)
22534 break;
22536 else if (EQ (glyph->object, stop))
22537 break;
22539 if (charpos > 0)
22540 lastcol = i;
22541 current_x += glyph->pixel_width;
22544 /* If we're looking for the end of the buffer,
22545 and we didn't find it in the line we scanned,
22546 use the start of the following line. */
22547 if (maybe_next_line_p)
22549 ++best_row;
22550 ++best_row_vpos;
22551 lastcol = 0;
22552 current_x = best_row->x;
22555 *vpos = best_row_vpos;
22556 *hpos = lastcol + 1;
22557 *x = current_x;
22558 *y = best_row->y;
22559 return 0;
22562 #endif /* not 1 */
22565 /* Find the position of the glyph for position POS in OBJECT in
22566 window W's current matrix, and return in *X, *Y the pixel
22567 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
22569 RIGHT_P non-zero means return the position of the right edge of the
22570 glyph, RIGHT_P zero means return the left edge position.
22572 If no glyph for POS exists in the matrix, return the position of
22573 the glyph with the next smaller position that is in the matrix, if
22574 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
22575 exists in the matrix, return the position of the glyph with the
22576 next larger position in OBJECT.
22578 Value is non-zero if a glyph was found. */
22580 static int
22581 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
22582 struct window *w;
22583 EMACS_INT pos;
22584 Lisp_Object object;
22585 int *hpos, *vpos, *x, *y;
22586 int right_p;
22588 int yb = window_text_bottom_y (w);
22589 struct glyph_row *r;
22590 struct glyph *best_glyph = NULL;
22591 struct glyph_row *best_row = NULL;
22592 int best_x = 0;
22594 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
22595 r->enabled_p && r->y < yb;
22596 ++r)
22598 struct glyph *g = r->glyphs[TEXT_AREA];
22599 struct glyph *e = g + r->used[TEXT_AREA];
22600 int gx;
22602 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
22603 if (EQ (g->object, object))
22605 if (g->charpos == pos)
22607 best_glyph = g;
22608 best_x = gx;
22609 best_row = r;
22610 goto found;
22612 else if (best_glyph == NULL
22613 || ((eabs (g->charpos - pos)
22614 < eabs (best_glyph->charpos - pos))
22615 && (right_p
22616 ? g->charpos < pos
22617 : g->charpos > pos)))
22619 best_glyph = g;
22620 best_x = gx;
22621 best_row = r;
22626 found:
22628 if (best_glyph)
22630 *x = best_x;
22631 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
22633 if (right_p)
22635 *x += best_glyph->pixel_width;
22636 ++*hpos;
22639 *y = best_row->y;
22640 *vpos = best_row - w->current_matrix->rows;
22643 return best_glyph != NULL;
22647 /* See if position X, Y is within a hot-spot of an image. */
22649 static int
22650 on_hot_spot_p (hot_spot, x, y)
22651 Lisp_Object hot_spot;
22652 int x, y;
22654 if (!CONSP (hot_spot))
22655 return 0;
22657 if (EQ (XCAR (hot_spot), Qrect))
22659 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
22660 Lisp_Object rect = XCDR (hot_spot);
22661 Lisp_Object tem;
22662 if (!CONSP (rect))
22663 return 0;
22664 if (!CONSP (XCAR (rect)))
22665 return 0;
22666 if (!CONSP (XCDR (rect)))
22667 return 0;
22668 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
22669 return 0;
22670 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
22671 return 0;
22672 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
22673 return 0;
22674 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
22675 return 0;
22676 return 1;
22678 else if (EQ (XCAR (hot_spot), Qcircle))
22680 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
22681 Lisp_Object circ = XCDR (hot_spot);
22682 Lisp_Object lr, lx0, ly0;
22683 if (CONSP (circ)
22684 && CONSP (XCAR (circ))
22685 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
22686 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
22687 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
22689 double r = XFLOATINT (lr);
22690 double dx = XINT (lx0) - x;
22691 double dy = XINT (ly0) - y;
22692 return (dx * dx + dy * dy <= r * r);
22695 else if (EQ (XCAR (hot_spot), Qpoly))
22697 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
22698 if (VECTORP (XCDR (hot_spot)))
22700 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
22701 Lisp_Object *poly = v->contents;
22702 int n = v->size;
22703 int i;
22704 int inside = 0;
22705 Lisp_Object lx, ly;
22706 int x0, y0;
22708 /* Need an even number of coordinates, and at least 3 edges. */
22709 if (n < 6 || n & 1)
22710 return 0;
22712 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
22713 If count is odd, we are inside polygon. Pixels on edges
22714 may or may not be included depending on actual geometry of the
22715 polygon. */
22716 if ((lx = poly[n-2], !INTEGERP (lx))
22717 || (ly = poly[n-1], !INTEGERP (lx)))
22718 return 0;
22719 x0 = XINT (lx), y0 = XINT (ly);
22720 for (i = 0; i < n; i += 2)
22722 int x1 = x0, y1 = y0;
22723 if ((lx = poly[i], !INTEGERP (lx))
22724 || (ly = poly[i+1], !INTEGERP (ly)))
22725 return 0;
22726 x0 = XINT (lx), y0 = XINT (ly);
22728 /* Does this segment cross the X line? */
22729 if (x0 >= x)
22731 if (x1 >= x)
22732 continue;
22734 else if (x1 < x)
22735 continue;
22736 if (y > y0 && y > y1)
22737 continue;
22738 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
22739 inside = !inside;
22741 return inside;
22744 return 0;
22747 Lisp_Object
22748 find_hot_spot (map, x, y)
22749 Lisp_Object map;
22750 int x, y;
22752 while (CONSP (map))
22754 if (CONSP (XCAR (map))
22755 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
22756 return XCAR (map);
22757 map = XCDR (map);
22760 return Qnil;
22763 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
22764 3, 3, 0,
22765 doc: /* Lookup in image map MAP coordinates X and Y.
22766 An image map is an alist where each element has the format (AREA ID PLIST).
22767 An AREA is specified as either a rectangle, a circle, or a polygon:
22768 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
22769 pixel coordinates of the upper left and bottom right corners.
22770 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
22771 and the radius of the circle; r may be a float or integer.
22772 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
22773 vector describes one corner in the polygon.
22774 Returns the alist element for the first matching AREA in MAP. */)
22775 (map, x, y)
22776 Lisp_Object map;
22777 Lisp_Object x, y;
22779 if (NILP (map))
22780 return Qnil;
22782 CHECK_NUMBER (x);
22783 CHECK_NUMBER (y);
22785 return find_hot_spot (map, XINT (x), XINT (y));
22789 /* Display frame CURSOR, optionally using shape defined by POINTER. */
22790 static void
22791 define_frame_cursor1 (f, cursor, pointer)
22792 struct frame *f;
22793 Cursor cursor;
22794 Lisp_Object pointer;
22796 /* Do not change cursor shape while dragging mouse. */
22797 if (!NILP (do_mouse_tracking))
22798 return;
22800 if (!NILP (pointer))
22802 if (EQ (pointer, Qarrow))
22803 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
22804 else if (EQ (pointer, Qhand))
22805 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
22806 else if (EQ (pointer, Qtext))
22807 cursor = FRAME_X_OUTPUT (f)->text_cursor;
22808 else if (EQ (pointer, intern ("hdrag")))
22809 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
22810 #ifdef HAVE_X_WINDOWS
22811 else if (EQ (pointer, intern ("vdrag")))
22812 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
22813 #endif
22814 else if (EQ (pointer, intern ("hourglass")))
22815 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
22816 else if (EQ (pointer, Qmodeline))
22817 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
22818 else
22819 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
22822 if (cursor != No_Cursor)
22823 FRAME_RIF (f)->define_frame_cursor (f, cursor);
22826 /* Take proper action when mouse has moved to the mode or header line
22827 or marginal area AREA of window W, x-position X and y-position Y.
22828 X is relative to the start of the text display area of W, so the
22829 width of bitmap areas and scroll bars must be subtracted to get a
22830 position relative to the start of the mode line. */
22832 static void
22833 note_mode_line_or_margin_highlight (window, x, y, area)
22834 Lisp_Object window;
22835 int x, y;
22836 enum window_part area;
22838 struct window *w = XWINDOW (window);
22839 struct frame *f = XFRAME (w->frame);
22840 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
22841 Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
22842 Lisp_Object pointer = Qnil;
22843 int charpos, dx, dy, width, height;
22844 Lisp_Object string, object = Qnil;
22845 Lisp_Object pos, help;
22847 Lisp_Object mouse_face;
22848 int original_x_pixel = x;
22849 struct glyph * glyph = NULL, * row_start_glyph = NULL;
22850 struct glyph_row *row;
22852 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
22854 int x0;
22855 struct glyph *end;
22857 string = mode_line_string (w, area, &x, &y, &charpos,
22858 &object, &dx, &dy, &width, &height);
22860 row = (area == ON_MODE_LINE
22861 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
22862 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
22864 /* Find glyph */
22865 if (row->mode_line_p && row->enabled_p)
22867 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
22868 end = glyph + row->used[TEXT_AREA];
22870 for (x0 = original_x_pixel;
22871 glyph < end && x0 >= glyph->pixel_width;
22872 ++glyph)
22873 x0 -= glyph->pixel_width;
22875 if (glyph >= end)
22876 glyph = NULL;
22879 else
22881 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
22882 string = marginal_area_string (w, area, &x, &y, &charpos,
22883 &object, &dx, &dy, &width, &height);
22886 help = Qnil;
22888 if (IMAGEP (object))
22890 Lisp_Object image_map, hotspot;
22891 if ((image_map = Fplist_get (XCDR (object), QCmap),
22892 !NILP (image_map))
22893 && (hotspot = find_hot_spot (image_map, dx, dy),
22894 CONSP (hotspot))
22895 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
22897 Lisp_Object area_id, plist;
22899 area_id = XCAR (hotspot);
22900 /* Could check AREA_ID to see if we enter/leave this hot-spot.
22901 If so, we could look for mouse-enter, mouse-leave
22902 properties in PLIST (and do something...). */
22903 hotspot = XCDR (hotspot);
22904 if (CONSP (hotspot)
22905 && (plist = XCAR (hotspot), CONSP (plist)))
22907 pointer = Fplist_get (plist, Qpointer);
22908 if (NILP (pointer))
22909 pointer = Qhand;
22910 help = Fplist_get (plist, Qhelp_echo);
22911 if (!NILP (help))
22913 help_echo_string = help;
22914 /* Is this correct? ++kfs */
22915 XSETWINDOW (help_echo_window, w);
22916 help_echo_object = w->buffer;
22917 help_echo_pos = charpos;
22921 if (NILP (pointer))
22922 pointer = Fplist_get (XCDR (object), QCpointer);
22925 if (STRINGP (string))
22927 pos = make_number (charpos);
22928 /* If we're on a string with `help-echo' text property, arrange
22929 for the help to be displayed. This is done by setting the
22930 global variable help_echo_string to the help string. */
22931 if (NILP (help))
22933 help = Fget_text_property (pos, Qhelp_echo, string);
22934 if (!NILP (help))
22936 help_echo_string = help;
22937 XSETWINDOW (help_echo_window, w);
22938 help_echo_object = string;
22939 help_echo_pos = charpos;
22943 if (NILP (pointer))
22944 pointer = Fget_text_property (pos, Qpointer, string);
22946 /* Change the mouse pointer according to what is under X/Y. */
22947 if (NILP (pointer) && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
22949 Lisp_Object map;
22950 map = Fget_text_property (pos, Qlocal_map, string);
22951 if (!KEYMAPP (map))
22952 map = Fget_text_property (pos, Qkeymap, string);
22953 if (!KEYMAPP (map))
22954 cursor = dpyinfo->vertical_scroll_bar_cursor;
22957 /* Change the mouse face according to what is under X/Y. */
22958 mouse_face = Fget_text_property (pos, Qmouse_face, string);
22959 if (!NILP (mouse_face)
22960 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
22961 && glyph)
22963 Lisp_Object b, e;
22965 struct glyph * tmp_glyph;
22967 int gpos;
22968 int gseq_length;
22969 int total_pixel_width;
22970 EMACS_INT ignore;
22972 int vpos, hpos;
22974 b = Fprevious_single_property_change (make_number (charpos + 1),
22975 Qmouse_face, string, Qnil);
22976 if (NILP (b))
22977 b = make_number (0);
22979 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
22980 if (NILP (e))
22981 e = make_number (SCHARS (string));
22983 /* Calculate the position(glyph position: GPOS) of GLYPH in
22984 displayed string. GPOS is different from CHARPOS.
22986 CHARPOS is the position of glyph in internal string
22987 object. A mode line string format has structures which
22988 is converted to a flatten by emacs lisp interpreter.
22989 The internal string is an element of the structures.
22990 The displayed string is the flatten string. */
22991 gpos = 0;
22992 if (glyph > row_start_glyph)
22994 tmp_glyph = glyph - 1;
22995 while (tmp_glyph >= row_start_glyph
22996 && tmp_glyph->charpos >= XINT (b)
22997 && EQ (tmp_glyph->object, glyph->object))
22999 tmp_glyph--;
23000 gpos++;
23004 /* Calculate the lenght(glyph sequence length: GSEQ_LENGTH) of
23005 displayed string holding GLYPH.
23007 GSEQ_LENGTH is different from SCHARS (STRING).
23008 SCHARS (STRING) returns the length of the internal string. */
23009 for (tmp_glyph = glyph, gseq_length = gpos;
23010 tmp_glyph->charpos < XINT (e);
23011 tmp_glyph++, gseq_length++)
23013 if (!EQ (tmp_glyph->object, glyph->object))
23014 break;
23017 total_pixel_width = 0;
23018 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
23019 total_pixel_width += tmp_glyph->pixel_width;
23021 /* Pre calculation of re-rendering position */
23022 vpos = (x - gpos);
23023 hpos = (area == ON_MODE_LINE
23024 ? (w->current_matrix)->nrows - 1
23025 : 0);
23027 /* If the re-rendering position is included in the last
23028 re-rendering area, we should do nothing. */
23029 if ( EQ (window, dpyinfo->mouse_face_window)
23030 && dpyinfo->mouse_face_beg_col <= vpos
23031 && vpos < dpyinfo->mouse_face_end_col
23032 && dpyinfo->mouse_face_beg_row == hpos )
23033 return;
23035 if (clear_mouse_face (dpyinfo))
23036 cursor = No_Cursor;
23038 dpyinfo->mouse_face_beg_col = vpos;
23039 dpyinfo->mouse_face_beg_row = hpos;
23041 dpyinfo->mouse_face_beg_x = original_x_pixel - (total_pixel_width + dx);
23042 dpyinfo->mouse_face_beg_y = 0;
23044 dpyinfo->mouse_face_end_col = vpos + gseq_length;
23045 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_beg_row;
23047 dpyinfo->mouse_face_end_x = 0;
23048 dpyinfo->mouse_face_end_y = 0;
23050 dpyinfo->mouse_face_past_end = 0;
23051 dpyinfo->mouse_face_window = window;
23053 dpyinfo->mouse_face_face_id = face_at_string_position (w, string,
23054 charpos,
23055 0, 0, 0, &ignore,
23056 glyph->face_id, 1);
23057 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
23059 if (NILP (pointer))
23060 pointer = Qhand;
23062 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
23063 clear_mouse_face (dpyinfo);
23065 define_frame_cursor1 (f, cursor, pointer);
23069 /* EXPORT:
23070 Take proper action when the mouse has moved to position X, Y on
23071 frame F as regards highlighting characters that have mouse-face
23072 properties. Also de-highlighting chars where the mouse was before.
23073 X and Y can be negative or out of range. */
23075 void
23076 note_mouse_highlight (f, x, y)
23077 struct frame *f;
23078 int x, y;
23080 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
23081 enum window_part part;
23082 Lisp_Object window;
23083 struct window *w;
23084 Cursor cursor = No_Cursor;
23085 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
23086 struct buffer *b;
23088 /* When a menu is active, don't highlight because this looks odd. */
23089 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (MAC_OS)
23090 if (popup_activated ())
23091 return;
23092 #endif
23094 if (NILP (Vmouse_highlight)
23095 || !f->glyphs_initialized_p)
23096 return;
23098 dpyinfo->mouse_face_mouse_x = x;
23099 dpyinfo->mouse_face_mouse_y = y;
23100 dpyinfo->mouse_face_mouse_frame = f;
23102 if (dpyinfo->mouse_face_defer)
23103 return;
23105 if (gc_in_progress)
23107 dpyinfo->mouse_face_deferred_gc = 1;
23108 return;
23111 /* Which window is that in? */
23112 window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
23114 /* If we were displaying active text in another window, clear that.
23115 Also clear if we move out of text area in same window. */
23116 if (! EQ (window, dpyinfo->mouse_face_window)
23117 || (part != ON_TEXT && part != ON_MODE_LINE && part != ON_HEADER_LINE
23118 && !NILP (dpyinfo->mouse_face_window)))
23119 clear_mouse_face (dpyinfo);
23121 /* Not on a window -> return. */
23122 if (!WINDOWP (window))
23123 return;
23125 /* Reset help_echo_string. It will get recomputed below. */
23126 help_echo_string = Qnil;
23128 /* Convert to window-relative pixel coordinates. */
23129 w = XWINDOW (window);
23130 frame_to_window_pixel_xy (w, &x, &y);
23132 /* Handle tool-bar window differently since it doesn't display a
23133 buffer. */
23134 if (EQ (window, f->tool_bar_window))
23136 note_tool_bar_highlight (f, x, y);
23137 return;
23140 /* Mouse is on the mode, header line or margin? */
23141 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
23142 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
23144 note_mode_line_or_margin_highlight (window, x, y, part);
23145 return;
23148 if (part == ON_VERTICAL_BORDER)
23150 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
23151 help_echo_string = build_string ("drag-mouse-1: resize");
23153 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
23154 || part == ON_SCROLL_BAR)
23155 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
23156 else
23157 cursor = FRAME_X_OUTPUT (f)->text_cursor;
23159 /* Are we in a window whose display is up to date?
23160 And verify the buffer's text has not changed. */
23161 b = XBUFFER (w->buffer);
23162 if (part == ON_TEXT
23163 && EQ (w->window_end_valid, w->buffer)
23164 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
23165 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
23167 int hpos, vpos, pos, i, dx, dy, area;
23168 struct glyph *glyph;
23169 Lisp_Object object;
23170 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
23171 Lisp_Object *overlay_vec = NULL;
23172 int noverlays;
23173 struct buffer *obuf;
23174 int obegv, ozv, same_region;
23176 /* Find the glyph under X/Y. */
23177 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
23179 /* Look for :pointer property on image. */
23180 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
23182 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
23183 if (img != NULL && IMAGEP (img->spec))
23185 Lisp_Object image_map, hotspot;
23186 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
23187 !NILP (image_map))
23188 && (hotspot = find_hot_spot (image_map,
23189 glyph->slice.x + dx,
23190 glyph->slice.y + dy),
23191 CONSP (hotspot))
23192 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
23194 Lisp_Object area_id, plist;
23196 area_id = XCAR (hotspot);
23197 /* Could check AREA_ID to see if we enter/leave this hot-spot.
23198 If so, we could look for mouse-enter, mouse-leave
23199 properties in PLIST (and do something...). */
23200 hotspot = XCDR (hotspot);
23201 if (CONSP (hotspot)
23202 && (plist = XCAR (hotspot), CONSP (plist)))
23204 pointer = Fplist_get (plist, Qpointer);
23205 if (NILP (pointer))
23206 pointer = Qhand;
23207 help_echo_string = Fplist_get (plist, Qhelp_echo);
23208 if (!NILP (help_echo_string))
23210 help_echo_window = window;
23211 help_echo_object = glyph->object;
23212 help_echo_pos = glyph->charpos;
23216 if (NILP (pointer))
23217 pointer = Fplist_get (XCDR (img->spec), QCpointer);
23221 /* Clear mouse face if X/Y not over text. */
23222 if (glyph == NULL
23223 || area != TEXT_AREA
23224 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
23226 if (clear_mouse_face (dpyinfo))
23227 cursor = No_Cursor;
23228 if (NILP (pointer))
23230 if (area != TEXT_AREA)
23231 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
23232 else
23233 pointer = Vvoid_text_area_pointer;
23235 goto set_cursor;
23238 pos = glyph->charpos;
23239 object = glyph->object;
23240 if (!STRINGP (object) && !BUFFERP (object))
23241 goto set_cursor;
23243 /* If we get an out-of-range value, return now; avoid an error. */
23244 if (BUFFERP (object) && pos > BUF_Z (b))
23245 goto set_cursor;
23247 /* Make the window's buffer temporarily current for
23248 overlays_at and compute_char_face. */
23249 obuf = current_buffer;
23250 current_buffer = b;
23251 obegv = BEGV;
23252 ozv = ZV;
23253 BEGV = BEG;
23254 ZV = Z;
23256 /* Is this char mouse-active or does it have help-echo? */
23257 position = make_number (pos);
23259 if (BUFFERP (object))
23261 /* Put all the overlays we want in a vector in overlay_vec. */
23262 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
23263 /* Sort overlays into increasing priority order. */
23264 noverlays = sort_overlays (overlay_vec, noverlays, w);
23266 else
23267 noverlays = 0;
23269 same_region = (EQ (window, dpyinfo->mouse_face_window)
23270 && vpos >= dpyinfo->mouse_face_beg_row
23271 && vpos <= dpyinfo->mouse_face_end_row
23272 && (vpos > dpyinfo->mouse_face_beg_row
23273 || hpos >= dpyinfo->mouse_face_beg_col)
23274 && (vpos < dpyinfo->mouse_face_end_row
23275 || hpos < dpyinfo->mouse_face_end_col
23276 || dpyinfo->mouse_face_past_end));
23278 if (same_region)
23279 cursor = No_Cursor;
23281 /* Check mouse-face highlighting. */
23282 if (! same_region
23283 /* If there exists an overlay with mouse-face overlapping
23284 the one we are currently highlighting, we have to
23285 check if we enter the overlapping overlay, and then
23286 highlight only that. */
23287 || (OVERLAYP (dpyinfo->mouse_face_overlay)
23288 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
23290 /* Find the highest priority overlay that has a mouse-face
23291 property. */
23292 overlay = Qnil;
23293 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
23295 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
23296 if (!NILP (mouse_face))
23297 overlay = overlay_vec[i];
23300 /* If we're actually highlighting the same overlay as
23301 before, there's no need to do that again. */
23302 if (!NILP (overlay)
23303 && EQ (overlay, dpyinfo->mouse_face_overlay))
23304 goto check_help_echo;
23306 dpyinfo->mouse_face_overlay = overlay;
23308 /* Clear the display of the old active region, if any. */
23309 if (clear_mouse_face (dpyinfo))
23310 cursor = No_Cursor;
23312 /* If no overlay applies, get a text property. */
23313 if (NILP (overlay))
23314 mouse_face = Fget_text_property (position, Qmouse_face, object);
23316 /* Handle the overlay case. */
23317 if (!NILP (overlay))
23319 /* Find the range of text around this char that
23320 should be active. */
23321 Lisp_Object before, after;
23322 EMACS_INT ignore;
23324 before = Foverlay_start (overlay);
23325 after = Foverlay_end (overlay);
23326 /* Record this as the current active region. */
23327 fast_find_position (w, XFASTINT (before),
23328 &dpyinfo->mouse_face_beg_col,
23329 &dpyinfo->mouse_face_beg_row,
23330 &dpyinfo->mouse_face_beg_x,
23331 &dpyinfo->mouse_face_beg_y, Qnil);
23333 dpyinfo->mouse_face_past_end
23334 = !fast_find_position (w, XFASTINT (after),
23335 &dpyinfo->mouse_face_end_col,
23336 &dpyinfo->mouse_face_end_row,
23337 &dpyinfo->mouse_face_end_x,
23338 &dpyinfo->mouse_face_end_y, Qnil);
23339 dpyinfo->mouse_face_window = window;
23341 dpyinfo->mouse_face_face_id
23342 = face_at_buffer_position (w, pos, 0, 0,
23343 &ignore, pos + 1,
23344 !dpyinfo->mouse_face_hidden);
23346 /* Display it as active. */
23347 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
23348 cursor = No_Cursor;
23350 /* Handle the text property case. */
23351 else if (!NILP (mouse_face) && BUFFERP (object))
23353 /* Find the range of text around this char that
23354 should be active. */
23355 Lisp_Object before, after, beginning, end;
23356 EMACS_INT ignore;
23358 beginning = Fmarker_position (w->start);
23359 end = make_number (BUF_Z (XBUFFER (object))
23360 - XFASTINT (w->window_end_pos));
23361 before
23362 = Fprevious_single_property_change (make_number (pos + 1),
23363 Qmouse_face,
23364 object, beginning);
23365 after
23366 = Fnext_single_property_change (position, Qmouse_face,
23367 object, end);
23369 /* Record this as the current active region. */
23370 fast_find_position (w, XFASTINT (before),
23371 &dpyinfo->mouse_face_beg_col,
23372 &dpyinfo->mouse_face_beg_row,
23373 &dpyinfo->mouse_face_beg_x,
23374 &dpyinfo->mouse_face_beg_y, Qnil);
23375 dpyinfo->mouse_face_past_end
23376 = !fast_find_position (w, XFASTINT (after),
23377 &dpyinfo->mouse_face_end_col,
23378 &dpyinfo->mouse_face_end_row,
23379 &dpyinfo->mouse_face_end_x,
23380 &dpyinfo->mouse_face_end_y, Qnil);
23381 dpyinfo->mouse_face_window = window;
23383 if (BUFFERP (object))
23384 dpyinfo->mouse_face_face_id
23385 = face_at_buffer_position (w, pos, 0, 0,
23386 &ignore, pos + 1,
23387 !dpyinfo->mouse_face_hidden);
23389 /* Display it as active. */
23390 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
23391 cursor = No_Cursor;
23393 else if (!NILP (mouse_face) && STRINGP (object))
23395 Lisp_Object b, e;
23396 EMACS_INT ignore;
23398 b = Fprevious_single_property_change (make_number (pos + 1),
23399 Qmouse_face,
23400 object, Qnil);
23401 e = Fnext_single_property_change (position, Qmouse_face,
23402 object, Qnil);
23403 if (NILP (b))
23404 b = make_number (0);
23405 if (NILP (e))
23406 e = make_number (SCHARS (object) - 1);
23408 fast_find_string_pos (w, XINT (b), object,
23409 &dpyinfo->mouse_face_beg_col,
23410 &dpyinfo->mouse_face_beg_row,
23411 &dpyinfo->mouse_face_beg_x,
23412 &dpyinfo->mouse_face_beg_y, 0);
23413 fast_find_string_pos (w, XINT (e), object,
23414 &dpyinfo->mouse_face_end_col,
23415 &dpyinfo->mouse_face_end_row,
23416 &dpyinfo->mouse_face_end_x,
23417 &dpyinfo->mouse_face_end_y, 1);
23418 dpyinfo->mouse_face_past_end = 0;
23419 dpyinfo->mouse_face_window = window;
23420 dpyinfo->mouse_face_face_id
23421 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
23422 glyph->face_id, 1);
23423 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
23424 cursor = No_Cursor;
23426 else if (STRINGP (object) && NILP (mouse_face))
23428 /* A string which doesn't have mouse-face, but
23429 the text ``under'' it might have. */
23430 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
23431 int start = MATRIX_ROW_START_CHARPOS (r);
23433 pos = string_buffer_position (w, object, start);
23434 if (pos > 0)
23435 mouse_face = get_char_property_and_overlay (make_number (pos),
23436 Qmouse_face,
23437 w->buffer,
23438 &overlay);
23439 if (!NILP (mouse_face) && !NILP (overlay))
23441 Lisp_Object before = Foverlay_start (overlay);
23442 Lisp_Object after = Foverlay_end (overlay);
23443 EMACS_INT ignore;
23445 /* Note that we might not be able to find position
23446 BEFORE in the glyph matrix if the overlay is
23447 entirely covered by a `display' property. In
23448 this case, we overshoot. So let's stop in
23449 the glyph matrix before glyphs for OBJECT. */
23450 fast_find_position (w, XFASTINT (before),
23451 &dpyinfo->mouse_face_beg_col,
23452 &dpyinfo->mouse_face_beg_row,
23453 &dpyinfo->mouse_face_beg_x,
23454 &dpyinfo->mouse_face_beg_y,
23455 object);
23457 dpyinfo->mouse_face_past_end
23458 = !fast_find_position (w, XFASTINT (after),
23459 &dpyinfo->mouse_face_end_col,
23460 &dpyinfo->mouse_face_end_row,
23461 &dpyinfo->mouse_face_end_x,
23462 &dpyinfo->mouse_face_end_y,
23463 Qnil);
23464 dpyinfo->mouse_face_window = window;
23465 dpyinfo->mouse_face_face_id
23466 = face_at_buffer_position (w, pos, 0, 0,
23467 &ignore, pos + 1,
23468 !dpyinfo->mouse_face_hidden);
23470 /* Display it as active. */
23471 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
23472 cursor = No_Cursor;
23477 check_help_echo:
23479 /* Look for a `help-echo' property. */
23480 if (NILP (help_echo_string)) {
23481 Lisp_Object help, overlay;
23483 /* Check overlays first. */
23484 help = overlay = Qnil;
23485 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
23487 overlay = overlay_vec[i];
23488 help = Foverlay_get (overlay, Qhelp_echo);
23491 if (!NILP (help))
23493 help_echo_string = help;
23494 help_echo_window = window;
23495 help_echo_object = overlay;
23496 help_echo_pos = pos;
23498 else
23500 Lisp_Object object = glyph->object;
23501 int charpos = glyph->charpos;
23503 /* Try text properties. */
23504 if (STRINGP (object)
23505 && charpos >= 0
23506 && charpos < SCHARS (object))
23508 help = Fget_text_property (make_number (charpos),
23509 Qhelp_echo, object);
23510 if (NILP (help))
23512 /* If the string itself doesn't specify a help-echo,
23513 see if the buffer text ``under'' it does. */
23514 struct glyph_row *r
23515 = MATRIX_ROW (w->current_matrix, vpos);
23516 int start = MATRIX_ROW_START_CHARPOS (r);
23517 int pos = string_buffer_position (w, object, start);
23518 if (pos > 0)
23520 help = Fget_char_property (make_number (pos),
23521 Qhelp_echo, w->buffer);
23522 if (!NILP (help))
23524 charpos = pos;
23525 object = w->buffer;
23530 else if (BUFFERP (object)
23531 && charpos >= BEGV
23532 && charpos < ZV)
23533 help = Fget_text_property (make_number (charpos), Qhelp_echo,
23534 object);
23536 if (!NILP (help))
23538 help_echo_string = help;
23539 help_echo_window = window;
23540 help_echo_object = object;
23541 help_echo_pos = charpos;
23546 /* Look for a `pointer' property. */
23547 if (NILP (pointer))
23549 /* Check overlays first. */
23550 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
23551 pointer = Foverlay_get (overlay_vec[i], Qpointer);
23553 if (NILP (pointer))
23555 Lisp_Object object = glyph->object;
23556 int charpos = glyph->charpos;
23558 /* Try text properties. */
23559 if (STRINGP (object)
23560 && charpos >= 0
23561 && charpos < SCHARS (object))
23563 pointer = Fget_text_property (make_number (charpos),
23564 Qpointer, object);
23565 if (NILP (pointer))
23567 /* If the string itself doesn't specify a pointer,
23568 see if the buffer text ``under'' it does. */
23569 struct glyph_row *r
23570 = MATRIX_ROW (w->current_matrix, vpos);
23571 int start = MATRIX_ROW_START_CHARPOS (r);
23572 int pos = string_buffer_position (w, object, start);
23573 if (pos > 0)
23574 pointer = Fget_char_property (make_number (pos),
23575 Qpointer, w->buffer);
23578 else if (BUFFERP (object)
23579 && charpos >= BEGV
23580 && charpos < ZV)
23581 pointer = Fget_text_property (make_number (charpos),
23582 Qpointer, object);
23586 BEGV = obegv;
23587 ZV = ozv;
23588 current_buffer = obuf;
23591 set_cursor:
23593 define_frame_cursor1 (f, cursor, pointer);
23597 /* EXPORT for RIF:
23598 Clear any mouse-face on window W. This function is part of the
23599 redisplay interface, and is called from try_window_id and similar
23600 functions to ensure the mouse-highlight is off. */
23602 void
23603 x_clear_window_mouse_face (w)
23604 struct window *w;
23606 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
23607 Lisp_Object window;
23609 BLOCK_INPUT;
23610 XSETWINDOW (window, w);
23611 if (EQ (window, dpyinfo->mouse_face_window))
23612 clear_mouse_face (dpyinfo);
23613 UNBLOCK_INPUT;
23617 /* EXPORT:
23618 Just discard the mouse face information for frame F, if any.
23619 This is used when the size of F is changed. */
23621 void
23622 cancel_mouse_face (f)
23623 struct frame *f;
23625 Lisp_Object window;
23626 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
23628 window = dpyinfo->mouse_face_window;
23629 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
23631 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
23632 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
23633 dpyinfo->mouse_face_window = Qnil;
23638 #endif /* HAVE_WINDOW_SYSTEM */
23641 /***********************************************************************
23642 Exposure Events
23643 ***********************************************************************/
23645 #ifdef HAVE_WINDOW_SYSTEM
23647 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
23648 which intersects rectangle R. R is in window-relative coordinates. */
23650 static void
23651 expose_area (w, row, r, area)
23652 struct window *w;
23653 struct glyph_row *row;
23654 XRectangle *r;
23655 enum glyph_row_area area;
23657 struct glyph *first = row->glyphs[area];
23658 struct glyph *end = row->glyphs[area] + row->used[area];
23659 struct glyph *last;
23660 int first_x, start_x, x;
23662 if (area == TEXT_AREA && row->fill_line_p)
23663 /* If row extends face to end of line write the whole line. */
23664 draw_glyphs (w, 0, row, area,
23665 0, row->used[area],
23666 DRAW_NORMAL_TEXT, 0);
23667 else
23669 /* Set START_X to the window-relative start position for drawing glyphs of
23670 AREA. The first glyph of the text area can be partially visible.
23671 The first glyphs of other areas cannot. */
23672 start_x = window_box_left_offset (w, area);
23673 x = start_x;
23674 if (area == TEXT_AREA)
23675 x += row->x;
23677 /* Find the first glyph that must be redrawn. */
23678 while (first < end
23679 && x + first->pixel_width < r->x)
23681 x += first->pixel_width;
23682 ++first;
23685 /* Find the last one. */
23686 last = first;
23687 first_x = x;
23688 while (last < end
23689 && x < r->x + r->width)
23691 x += last->pixel_width;
23692 ++last;
23695 /* Repaint. */
23696 if (last > first)
23697 draw_glyphs (w, first_x - start_x, row, area,
23698 first - row->glyphs[area], last - row->glyphs[area],
23699 DRAW_NORMAL_TEXT, 0);
23704 /* Redraw the parts of the glyph row ROW on window W intersecting
23705 rectangle R. R is in window-relative coordinates. Value is
23706 non-zero if mouse-face was overwritten. */
23708 static int
23709 expose_line (w, row, r)
23710 struct window *w;
23711 struct glyph_row *row;
23712 XRectangle *r;
23714 xassert (row->enabled_p);
23716 if (row->mode_line_p || w->pseudo_window_p)
23717 draw_glyphs (w, 0, row, TEXT_AREA,
23718 0, row->used[TEXT_AREA],
23719 DRAW_NORMAL_TEXT, 0);
23720 else
23722 if (row->used[LEFT_MARGIN_AREA])
23723 expose_area (w, row, r, LEFT_MARGIN_AREA);
23724 if (row->used[TEXT_AREA])
23725 expose_area (w, row, r, TEXT_AREA);
23726 if (row->used[RIGHT_MARGIN_AREA])
23727 expose_area (w, row, r, RIGHT_MARGIN_AREA);
23728 draw_row_fringe_bitmaps (w, row);
23731 return row->mouse_face_p;
23735 /* Redraw those parts of glyphs rows during expose event handling that
23736 overlap other rows. Redrawing of an exposed line writes over parts
23737 of lines overlapping that exposed line; this function fixes that.
23739 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
23740 row in W's current matrix that is exposed and overlaps other rows.
23741 LAST_OVERLAPPING_ROW is the last such row. */
23743 static void
23744 expose_overlaps (w, first_overlapping_row, last_overlapping_row, r)
23745 struct window *w;
23746 struct glyph_row *first_overlapping_row;
23747 struct glyph_row *last_overlapping_row;
23748 XRectangle *r;
23750 struct glyph_row *row;
23752 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
23753 if (row->overlapping_p)
23755 xassert (row->enabled_p && !row->mode_line_p);
23757 row->clip = r;
23758 if (row->used[LEFT_MARGIN_AREA])
23759 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
23761 if (row->used[TEXT_AREA])
23762 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
23764 if (row->used[RIGHT_MARGIN_AREA])
23765 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
23766 row->clip = NULL;
23771 /* Return non-zero if W's cursor intersects rectangle R. */
23773 static int
23774 phys_cursor_in_rect_p (w, r)
23775 struct window *w;
23776 XRectangle *r;
23778 XRectangle cr, result;
23779 struct glyph *cursor_glyph;
23780 struct glyph_row *row;
23782 if (w->phys_cursor.vpos >= 0
23783 && w->phys_cursor.vpos < w->current_matrix->nrows
23784 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
23785 row->enabled_p)
23786 && row->cursor_in_fringe_p)
23788 /* Cursor is in the fringe. */
23789 cr.x = window_box_right_offset (w,
23790 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
23791 ? RIGHT_MARGIN_AREA
23792 : TEXT_AREA));
23793 cr.y = row->y;
23794 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
23795 cr.height = row->height;
23796 return x_intersect_rectangles (&cr, r, &result);
23799 cursor_glyph = get_phys_cursor_glyph (w);
23800 if (cursor_glyph)
23802 /* r is relative to W's box, but w->phys_cursor.x is relative
23803 to left edge of W's TEXT area. Adjust it. */
23804 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
23805 cr.y = w->phys_cursor.y;
23806 cr.width = cursor_glyph->pixel_width;
23807 cr.height = w->phys_cursor_height;
23808 /* ++KFS: W32 version used W32-specific IntersectRect here, but
23809 I assume the effect is the same -- and this is portable. */
23810 return x_intersect_rectangles (&cr, r, &result);
23812 /* If we don't understand the format, pretend we're not in the hot-spot. */
23813 return 0;
23817 /* EXPORT:
23818 Draw a vertical window border to the right of window W if W doesn't
23819 have vertical scroll bars. */
23821 void
23822 x_draw_vertical_border (w)
23823 struct window *w;
23825 struct frame *f = XFRAME (WINDOW_FRAME (w));
23827 /* We could do better, if we knew what type of scroll-bar the adjacent
23828 windows (on either side) have... But we don't :-(
23829 However, I think this works ok. ++KFS 2003-04-25 */
23831 /* Redraw borders between horizontally adjacent windows. Don't
23832 do it for frames with vertical scroll bars because either the
23833 right scroll bar of a window, or the left scroll bar of its
23834 neighbor will suffice as a border. */
23835 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
23836 return;
23838 if (!WINDOW_RIGHTMOST_P (w)
23839 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
23841 int x0, x1, y0, y1;
23843 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
23844 y1 -= 1;
23846 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
23847 x1 -= 1;
23849 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
23851 else if (!WINDOW_LEFTMOST_P (w)
23852 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
23854 int x0, x1, y0, y1;
23856 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
23857 y1 -= 1;
23859 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
23860 x0 -= 1;
23862 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
23867 /* Redraw the part of window W intersection rectangle FR. Pixel
23868 coordinates in FR are frame-relative. Call this function with
23869 input blocked. Value is non-zero if the exposure overwrites
23870 mouse-face. */
23872 static int
23873 expose_window (w, fr)
23874 struct window *w;
23875 XRectangle *fr;
23877 struct frame *f = XFRAME (w->frame);
23878 XRectangle wr, r;
23879 int mouse_face_overwritten_p = 0;
23881 /* If window is not yet fully initialized, do nothing. This can
23882 happen when toolkit scroll bars are used and a window is split.
23883 Reconfiguring the scroll bar will generate an expose for a newly
23884 created window. */
23885 if (w->current_matrix == NULL)
23886 return 0;
23888 /* When we're currently updating the window, display and current
23889 matrix usually don't agree. Arrange for a thorough display
23890 later. */
23891 if (w == updated_window)
23893 SET_FRAME_GARBAGED (f);
23894 return 0;
23897 /* Frame-relative pixel rectangle of W. */
23898 wr.x = WINDOW_LEFT_EDGE_X (w);
23899 wr.y = WINDOW_TOP_EDGE_Y (w);
23900 wr.width = WINDOW_TOTAL_WIDTH (w);
23901 wr.height = WINDOW_TOTAL_HEIGHT (w);
23903 if (x_intersect_rectangles (fr, &wr, &r))
23905 int yb = window_text_bottom_y (w);
23906 struct glyph_row *row;
23907 int cursor_cleared_p;
23908 struct glyph_row *first_overlapping_row, *last_overlapping_row;
23910 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
23911 r.x, r.y, r.width, r.height));
23913 /* Convert to window coordinates. */
23914 r.x -= WINDOW_LEFT_EDGE_X (w);
23915 r.y -= WINDOW_TOP_EDGE_Y (w);
23917 /* Turn off the cursor. */
23918 if (!w->pseudo_window_p
23919 && phys_cursor_in_rect_p (w, &r))
23921 x_clear_cursor (w);
23922 cursor_cleared_p = 1;
23924 else
23925 cursor_cleared_p = 0;
23927 /* Update lines intersecting rectangle R. */
23928 first_overlapping_row = last_overlapping_row = NULL;
23929 for (row = w->current_matrix->rows;
23930 row->enabled_p;
23931 ++row)
23933 int y0 = row->y;
23934 int y1 = MATRIX_ROW_BOTTOM_Y (row);
23936 if ((y0 >= r.y && y0 < r.y + r.height)
23937 || (y1 > r.y && y1 < r.y + r.height)
23938 || (r.y >= y0 && r.y < y1)
23939 || (r.y + r.height > y0 && r.y + r.height < y1))
23941 /* A header line may be overlapping, but there is no need
23942 to fix overlapping areas for them. KFS 2005-02-12 */
23943 if (row->overlapping_p && !row->mode_line_p)
23945 if (first_overlapping_row == NULL)
23946 first_overlapping_row = row;
23947 last_overlapping_row = row;
23950 row->clip = fr;
23951 if (expose_line (w, row, &r))
23952 mouse_face_overwritten_p = 1;
23953 row->clip = NULL;
23955 else if (row->overlapping_p)
23957 /* We must redraw a row overlapping the exposed area. */
23958 if (y0 < r.y
23959 ? y0 + row->phys_height > r.y
23960 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
23962 if (first_overlapping_row == NULL)
23963 first_overlapping_row = row;
23964 last_overlapping_row = row;
23968 if (y1 >= yb)
23969 break;
23972 /* Display the mode line if there is one. */
23973 if (WINDOW_WANTS_MODELINE_P (w)
23974 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
23975 row->enabled_p)
23976 && row->y < r.y + r.height)
23978 if (expose_line (w, row, &r))
23979 mouse_face_overwritten_p = 1;
23982 if (!w->pseudo_window_p)
23984 /* Fix the display of overlapping rows. */
23985 if (first_overlapping_row)
23986 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
23987 fr);
23989 /* Draw border between windows. */
23990 x_draw_vertical_border (w);
23992 /* Turn the cursor on again. */
23993 if (cursor_cleared_p)
23994 update_window_cursor (w, 1);
23998 return mouse_face_overwritten_p;
24003 /* Redraw (parts) of all windows in the window tree rooted at W that
24004 intersect R. R contains frame pixel coordinates. Value is
24005 non-zero if the exposure overwrites mouse-face. */
24007 static int
24008 expose_window_tree (w, r)
24009 struct window *w;
24010 XRectangle *r;
24012 struct frame *f = XFRAME (w->frame);
24013 int mouse_face_overwritten_p = 0;
24015 while (w && !FRAME_GARBAGED_P (f))
24017 if (!NILP (w->hchild))
24018 mouse_face_overwritten_p
24019 |= expose_window_tree (XWINDOW (w->hchild), r);
24020 else if (!NILP (w->vchild))
24021 mouse_face_overwritten_p
24022 |= expose_window_tree (XWINDOW (w->vchild), r);
24023 else
24024 mouse_face_overwritten_p |= expose_window (w, r);
24026 w = NILP (w->next) ? NULL : XWINDOW (w->next);
24029 return mouse_face_overwritten_p;
24033 /* EXPORT:
24034 Redisplay an exposed area of frame F. X and Y are the upper-left
24035 corner of the exposed rectangle. W and H are width and height of
24036 the exposed area. All are pixel values. W or H zero means redraw
24037 the entire frame. */
24039 void
24040 expose_frame (f, x, y, w, h)
24041 struct frame *f;
24042 int x, y, w, h;
24044 XRectangle r;
24045 int mouse_face_overwritten_p = 0;
24047 TRACE ((stderr, "expose_frame "));
24049 /* No need to redraw if frame will be redrawn soon. */
24050 if (FRAME_GARBAGED_P (f))
24052 TRACE ((stderr, " garbaged\n"));
24053 return;
24056 /* If basic faces haven't been realized yet, there is no point in
24057 trying to redraw anything. This can happen when we get an expose
24058 event while Emacs is starting, e.g. by moving another window. */
24059 if (FRAME_FACE_CACHE (f) == NULL
24060 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
24062 TRACE ((stderr, " no faces\n"));
24063 return;
24066 if (w == 0 || h == 0)
24068 r.x = r.y = 0;
24069 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
24070 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
24072 else
24074 r.x = x;
24075 r.y = y;
24076 r.width = w;
24077 r.height = h;
24080 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
24081 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
24083 if (WINDOWP (f->tool_bar_window))
24084 mouse_face_overwritten_p
24085 |= expose_window (XWINDOW (f->tool_bar_window), &r);
24087 #ifdef HAVE_X_WINDOWS
24088 #ifndef MSDOS
24089 #ifndef USE_X_TOOLKIT
24090 if (WINDOWP (f->menu_bar_window))
24091 mouse_face_overwritten_p
24092 |= expose_window (XWINDOW (f->menu_bar_window), &r);
24093 #endif /* not USE_X_TOOLKIT */
24094 #endif
24095 #endif
24097 /* Some window managers support a focus-follows-mouse style with
24098 delayed raising of frames. Imagine a partially obscured frame,
24099 and moving the mouse into partially obscured mouse-face on that
24100 frame. The visible part of the mouse-face will be highlighted,
24101 then the WM raises the obscured frame. With at least one WM, KDE
24102 2.1, Emacs is not getting any event for the raising of the frame
24103 (even tried with SubstructureRedirectMask), only Expose events.
24104 These expose events will draw text normally, i.e. not
24105 highlighted. Which means we must redo the highlight here.
24106 Subsume it under ``we love X''. --gerd 2001-08-15 */
24107 /* Included in Windows version because Windows most likely does not
24108 do the right thing if any third party tool offers
24109 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
24110 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
24112 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
24113 if (f == dpyinfo->mouse_face_mouse_frame)
24115 int x = dpyinfo->mouse_face_mouse_x;
24116 int y = dpyinfo->mouse_face_mouse_y;
24117 clear_mouse_face (dpyinfo);
24118 note_mouse_highlight (f, x, y);
24124 /* EXPORT:
24125 Determine the intersection of two rectangles R1 and R2. Return
24126 the intersection in *RESULT. Value is non-zero if RESULT is not
24127 empty. */
24130 x_intersect_rectangles (r1, r2, result)
24131 XRectangle *r1, *r2, *result;
24133 XRectangle *left, *right;
24134 XRectangle *upper, *lower;
24135 int intersection_p = 0;
24137 /* Rearrange so that R1 is the left-most rectangle. */
24138 if (r1->x < r2->x)
24139 left = r1, right = r2;
24140 else
24141 left = r2, right = r1;
24143 /* X0 of the intersection is right.x0, if this is inside R1,
24144 otherwise there is no intersection. */
24145 if (right->x <= left->x + left->width)
24147 result->x = right->x;
24149 /* The right end of the intersection is the minimum of the
24150 the right ends of left and right. */
24151 result->width = (min (left->x + left->width, right->x + right->width)
24152 - result->x);
24154 /* Same game for Y. */
24155 if (r1->y < r2->y)
24156 upper = r1, lower = r2;
24157 else
24158 upper = r2, lower = r1;
24160 /* The upper end of the intersection is lower.y0, if this is inside
24161 of upper. Otherwise, there is no intersection. */
24162 if (lower->y <= upper->y + upper->height)
24164 result->y = lower->y;
24166 /* The lower end of the intersection is the minimum of the lower
24167 ends of upper and lower. */
24168 result->height = (min (lower->y + lower->height,
24169 upper->y + upper->height)
24170 - result->y);
24171 intersection_p = 1;
24175 return intersection_p;
24178 #endif /* HAVE_WINDOW_SYSTEM */
24181 /***********************************************************************
24182 Initialization
24183 ***********************************************************************/
24185 void
24186 syms_of_xdisp ()
24188 Vwith_echo_area_save_vector = Qnil;
24189 staticpro (&Vwith_echo_area_save_vector);
24191 Vmessage_stack = Qnil;
24192 staticpro (&Vmessage_stack);
24194 Qinhibit_redisplay = intern ("inhibit-redisplay");
24195 staticpro (&Qinhibit_redisplay);
24197 message_dolog_marker1 = Fmake_marker ();
24198 staticpro (&message_dolog_marker1);
24199 message_dolog_marker2 = Fmake_marker ();
24200 staticpro (&message_dolog_marker2);
24201 message_dolog_marker3 = Fmake_marker ();
24202 staticpro (&message_dolog_marker3);
24204 #if GLYPH_DEBUG
24205 defsubr (&Sdump_frame_glyph_matrix);
24206 defsubr (&Sdump_glyph_matrix);
24207 defsubr (&Sdump_glyph_row);
24208 defsubr (&Sdump_tool_bar_row);
24209 defsubr (&Strace_redisplay);
24210 defsubr (&Strace_to_stderr);
24211 #endif
24212 #ifdef HAVE_WINDOW_SYSTEM
24213 defsubr (&Stool_bar_lines_needed);
24214 defsubr (&Slookup_image_map);
24215 #endif
24216 defsubr (&Sformat_mode_line);
24217 defsubr (&Sinvisible_p);
24219 staticpro (&Qmenu_bar_update_hook);
24220 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
24222 staticpro (&Qoverriding_terminal_local_map);
24223 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
24225 staticpro (&Qoverriding_local_map);
24226 Qoverriding_local_map = intern ("overriding-local-map");
24228 staticpro (&Qwindow_scroll_functions);
24229 Qwindow_scroll_functions = intern ("window-scroll-functions");
24231 staticpro (&Qwindow_text_change_functions);
24232 Qwindow_text_change_functions = intern ("window-text-change-functions");
24234 staticpro (&Qredisplay_end_trigger_functions);
24235 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
24237 staticpro (&Qinhibit_point_motion_hooks);
24238 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
24240 Qeval = intern ("eval");
24241 staticpro (&Qeval);
24243 QCdata = intern (":data");
24244 staticpro (&QCdata);
24245 Qdisplay = intern ("display");
24246 staticpro (&Qdisplay);
24247 Qspace_width = intern ("space-width");
24248 staticpro (&Qspace_width);
24249 Qraise = intern ("raise");
24250 staticpro (&Qraise);
24251 Qslice = intern ("slice");
24252 staticpro (&Qslice);
24253 Qspace = intern ("space");
24254 staticpro (&Qspace);
24255 Qmargin = intern ("margin");
24256 staticpro (&Qmargin);
24257 Qpointer = intern ("pointer");
24258 staticpro (&Qpointer);
24259 Qleft_margin = intern ("left-margin");
24260 staticpro (&Qleft_margin);
24261 Qright_margin = intern ("right-margin");
24262 staticpro (&Qright_margin);
24263 Qcenter = intern ("center");
24264 staticpro (&Qcenter);
24265 Qline_height = intern ("line-height");
24266 staticpro (&Qline_height);
24267 QCalign_to = intern (":align-to");
24268 staticpro (&QCalign_to);
24269 QCrelative_width = intern (":relative-width");
24270 staticpro (&QCrelative_width);
24271 QCrelative_height = intern (":relative-height");
24272 staticpro (&QCrelative_height);
24273 QCeval = intern (":eval");
24274 staticpro (&QCeval);
24275 QCpropertize = intern (":propertize");
24276 staticpro (&QCpropertize);
24277 QCfile = intern (":file");
24278 staticpro (&QCfile);
24279 Qfontified = intern ("fontified");
24280 staticpro (&Qfontified);
24281 Qfontification_functions = intern ("fontification-functions");
24282 staticpro (&Qfontification_functions);
24283 Qtrailing_whitespace = intern ("trailing-whitespace");
24284 staticpro (&Qtrailing_whitespace);
24285 Qescape_glyph = intern ("escape-glyph");
24286 staticpro (&Qescape_glyph);
24287 Qnobreak_space = intern ("nobreak-space");
24288 staticpro (&Qnobreak_space);
24289 Qimage = intern ("image");
24290 staticpro (&Qimage);
24291 QCmap = intern (":map");
24292 staticpro (&QCmap);
24293 QCpointer = intern (":pointer");
24294 staticpro (&QCpointer);
24295 Qrect = intern ("rect");
24296 staticpro (&Qrect);
24297 Qcircle = intern ("circle");
24298 staticpro (&Qcircle);
24299 Qpoly = intern ("poly");
24300 staticpro (&Qpoly);
24301 Qmessage_truncate_lines = intern ("message-truncate-lines");
24302 staticpro (&Qmessage_truncate_lines);
24303 Qgrow_only = intern ("grow-only");
24304 staticpro (&Qgrow_only);
24305 Qinhibit_menubar_update = intern ("inhibit-menubar-update");
24306 staticpro (&Qinhibit_menubar_update);
24307 Qinhibit_eval_during_redisplay = intern ("inhibit-eval-during-redisplay");
24308 staticpro (&Qinhibit_eval_during_redisplay);
24309 Qposition = intern ("position");
24310 staticpro (&Qposition);
24311 Qbuffer_position = intern ("buffer-position");
24312 staticpro (&Qbuffer_position);
24313 Qobject = intern ("object");
24314 staticpro (&Qobject);
24315 Qbar = intern ("bar");
24316 staticpro (&Qbar);
24317 Qhbar = intern ("hbar");
24318 staticpro (&Qhbar);
24319 Qbox = intern ("box");
24320 staticpro (&Qbox);
24321 Qhollow = intern ("hollow");
24322 staticpro (&Qhollow);
24323 Qhand = intern ("hand");
24324 staticpro (&Qhand);
24325 Qarrow = intern ("arrow");
24326 staticpro (&Qarrow);
24327 Qtext = intern ("text");
24328 staticpro (&Qtext);
24329 Qrisky_local_variable = intern ("risky-local-variable");
24330 staticpro (&Qrisky_local_variable);
24331 Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
24332 staticpro (&Qinhibit_free_realized_faces);
24334 list_of_error = Fcons (Fcons (intern ("error"),
24335 Fcons (intern ("void-variable"), Qnil)),
24336 Qnil);
24337 staticpro (&list_of_error);
24339 Qlast_arrow_position = intern ("last-arrow-position");
24340 staticpro (&Qlast_arrow_position);
24341 Qlast_arrow_string = intern ("last-arrow-string");
24342 staticpro (&Qlast_arrow_string);
24344 Qoverlay_arrow_string = intern ("overlay-arrow-string");
24345 staticpro (&Qoverlay_arrow_string);
24346 Qoverlay_arrow_bitmap = intern ("overlay-arrow-bitmap");
24347 staticpro (&Qoverlay_arrow_bitmap);
24349 echo_buffer[0] = echo_buffer[1] = Qnil;
24350 staticpro (&echo_buffer[0]);
24351 staticpro (&echo_buffer[1]);
24353 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
24354 staticpro (&echo_area_buffer[0]);
24355 staticpro (&echo_area_buffer[1]);
24357 Vmessages_buffer_name = build_string ("*Messages*");
24358 staticpro (&Vmessages_buffer_name);
24360 mode_line_proptrans_alist = Qnil;
24361 staticpro (&mode_line_proptrans_alist);
24362 mode_line_string_list = Qnil;
24363 staticpro (&mode_line_string_list);
24364 mode_line_string_face = Qnil;
24365 staticpro (&mode_line_string_face);
24366 mode_line_string_face_prop = Qnil;
24367 staticpro (&mode_line_string_face_prop);
24368 Vmode_line_unwind_vector = Qnil;
24369 staticpro (&Vmode_line_unwind_vector);
24371 help_echo_string = Qnil;
24372 staticpro (&help_echo_string);
24373 help_echo_object = Qnil;
24374 staticpro (&help_echo_object);
24375 help_echo_window = Qnil;
24376 staticpro (&help_echo_window);
24377 previous_help_echo_string = Qnil;
24378 staticpro (&previous_help_echo_string);
24379 help_echo_pos = -1;
24381 #ifdef HAVE_WINDOW_SYSTEM
24382 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
24383 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
24384 For example, if a block cursor is over a tab, it will be drawn as
24385 wide as that tab on the display. */);
24386 x_stretch_cursor_p = 0;
24387 #endif
24389 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
24390 doc: /* *Non-nil means highlight trailing whitespace.
24391 The face used for trailing whitespace is `trailing-whitespace'. */);
24392 Vshow_trailing_whitespace = Qnil;
24394 DEFVAR_LISP ("nobreak-char-display", &Vnobreak_char_display,
24395 doc: /* *Control highlighting of nobreak space and soft hyphen.
24396 A value of t means highlight the character itself (for nobreak space,
24397 use face `nobreak-space').
24398 A value of nil means no highlighting.
24399 Other values mean display the escape glyph followed by an ordinary
24400 space or ordinary hyphen. */);
24401 Vnobreak_char_display = Qt;
24403 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
24404 doc: /* *The pointer shape to show in void text areas.
24405 A value of nil means to show the text pointer. Other options are `arrow',
24406 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
24407 Vvoid_text_area_pointer = Qarrow;
24409 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
24410 doc: /* Non-nil means don't actually do any redisplay.
24411 This is used for internal purposes. */);
24412 Vinhibit_redisplay = Qnil;
24414 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
24415 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
24416 Vglobal_mode_string = Qnil;
24418 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
24419 doc: /* Marker for where to display an arrow on top of the buffer text.
24420 This must be the beginning of a line in order to work.
24421 See also `overlay-arrow-string'. */);
24422 Voverlay_arrow_position = Qnil;
24424 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
24425 doc: /* String to display as an arrow in non-window frames.
24426 See also `overlay-arrow-position'. */);
24427 Voverlay_arrow_string = build_string ("=>");
24429 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list,
24430 doc: /* List of variables (symbols) which hold markers for overlay arrows.
24431 The symbols on this list are examined during redisplay to determine
24432 where to display overlay arrows. */);
24433 Voverlay_arrow_variable_list
24434 = Fcons (intern ("overlay-arrow-position"), Qnil);
24436 DEFVAR_INT ("scroll-step", &scroll_step,
24437 doc: /* *The number of lines to try scrolling a window by when point moves out.
24438 If that fails to bring point back on frame, point is centered instead.
24439 If this is zero, point is always centered after it moves off frame.
24440 If you want scrolling to always be a line at a time, you should set
24441 `scroll-conservatively' to a large value rather than set this to 1. */);
24443 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
24444 doc: /* *Scroll up to this many lines, to bring point back on screen.
24445 If point moves off-screen, redisplay will scroll by up to
24446 `scroll-conservatively' lines in order to bring point just barely
24447 onto the screen again. If that cannot be done, then redisplay
24448 recenters point as usual.
24450 A value of zero means always recenter point if it moves off screen. */);
24451 scroll_conservatively = 0;
24453 DEFVAR_INT ("scroll-margin", &scroll_margin,
24454 doc: /* *Number of lines of margin at the top and bottom of a window.
24455 Recenter the window whenever point gets within this many lines
24456 of the top or bottom of the window. */);
24457 scroll_margin = 0;
24459 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch,
24460 doc: /* Pixels per inch value for non-window system displays.
24461 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
24462 Vdisplay_pixels_per_inch = make_float (72.0);
24464 #if GLYPH_DEBUG
24465 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
24466 #endif
24468 DEFVAR_BOOL ("truncate-partial-width-windows",
24469 &truncate_partial_width_windows,
24470 doc: /* *Non-nil means truncate lines in all windows less than full frame wide.
24471 Nil means to respect the value of `truncate-lines'. */);
24472 truncate_partial_width_windows = 1;
24474 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
24475 doc: /* When nil, display the mode-line/header-line/menu-bar in the default face.
24476 Any other value means to use the appropriate face, `mode-line',
24477 `header-line', or `menu' respectively. */);
24478 mode_line_inverse_video = 1;
24480 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
24481 doc: /* *Maximum buffer size for which line number should be displayed.
24482 If the buffer is bigger than this, the line number does not appear
24483 in the mode line. A value of nil means no limit. */);
24484 Vline_number_display_limit = Qnil;
24486 DEFVAR_INT ("line-number-display-limit-width",
24487 &line_number_display_limit_width,
24488 doc: /* *Maximum line width (in characters) for line number display.
24489 If the average length of the lines near point is bigger than this, then the
24490 line number may be omitted from the mode line. */);
24491 line_number_display_limit_width = 200;
24493 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
24494 doc: /* *Non-nil means highlight region even in nonselected windows. */);
24495 highlight_nonselected_windows = 0;
24497 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
24498 doc: /* Non-nil if more than one frame is visible on this display.
24499 Minibuffer-only frames don't count, but iconified frames do.
24500 This variable is not guaranteed to be accurate except while processing
24501 `frame-title-format' and `icon-title-format'. */);
24503 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
24504 doc: /* Template for displaying the title bar of visible frames.
24505 \(Assuming the window manager supports this feature.)
24507 This variable has the same structure as `mode-line-format', except that
24508 the %c and %l constructs are ignored. It is used only on frames for
24509 which no explicit name has been set \(see `modify-frame-parameters'). */);
24511 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
24512 doc: /* Template for displaying the title bar of an iconified frame.
24513 \(Assuming the window manager supports this feature.)
24514 This variable has the same structure as `mode-line-format' (which see),
24515 and is used only on frames for which no explicit name has been set
24516 \(see `modify-frame-parameters'). */);
24517 Vicon_title_format
24518 = Vframe_title_format
24519 = Fcons (intern ("multiple-frames"),
24520 Fcons (build_string ("%b"),
24521 Fcons (Fcons (empty_unibyte_string,
24522 Fcons (intern ("invocation-name"),
24523 Fcons (build_string ("@"),
24524 Fcons (intern ("system-name"),
24525 Qnil)))),
24526 Qnil)));
24528 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
24529 doc: /* Maximum number of lines to keep in the message log buffer.
24530 If nil, disable message logging. If t, log messages but don't truncate
24531 the buffer when it becomes large. */);
24532 Vmessage_log_max = make_number (100);
24534 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
24535 doc: /* Functions called before redisplay, if window sizes have changed.
24536 The value should be a list of functions that take one argument.
24537 Just before redisplay, for each frame, if any of its windows have changed
24538 size since the last redisplay, or have been split or deleted,
24539 all the functions in the list are called, with the frame as argument. */);
24540 Vwindow_size_change_functions = Qnil;
24542 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
24543 doc: /* List of functions to call before redisplaying a window with scrolling.
24544 Each function is called with two arguments, the window
24545 and its new display-start position. Note that the value of `window-end'
24546 is not valid when these functions are called. */);
24547 Vwindow_scroll_functions = Qnil;
24549 DEFVAR_LISP ("window-text-change-functions",
24550 &Vwindow_text_change_functions,
24551 doc: /* Functions to call in redisplay when text in the window might change. */);
24552 Vwindow_text_change_functions = Qnil;
24554 DEFVAR_LISP ("redisplay-end-trigger-functions", &Vredisplay_end_trigger_functions,
24555 doc: /* Functions called when redisplay of a window reaches the end trigger.
24556 Each function is called with two arguments, the window and the end trigger value.
24557 See `set-window-redisplay-end-trigger'. */);
24558 Vredisplay_end_trigger_functions = Qnil;
24560 DEFVAR_LISP ("mouse-autoselect-window", &Vmouse_autoselect_window,
24561 doc: /* *Non-nil means autoselect window with mouse pointer.
24562 If nil, do not autoselect windows.
24563 A positive number means delay autoselection by that many seconds: a
24564 window is autoselected only after the mouse has remained in that
24565 window for the duration of the delay.
24566 A negative number has a similar effect, but causes windows to be
24567 autoselected only after the mouse has stopped moving. \(Because of
24568 the way Emacs compares mouse events, you will occasionally wait twice
24569 that time before the window gets selected.\)
24570 Any other value means to autoselect window instantaneously when the
24571 mouse pointer enters it.
24573 Autoselection selects the minibuffer only if it is active, and never
24574 unselects the minibuffer if it is active.
24576 When customizing this variable make sure that the actual value of
24577 `focus-follows-mouse' matches the behavior of your window manager. */);
24578 Vmouse_autoselect_window = Qnil;
24580 DEFVAR_LISP ("auto-resize-tool-bars", &Vauto_resize_tool_bars,
24581 doc: /* *Non-nil means automatically resize tool-bars.
24582 This dynamically changes the tool-bar's height to the minimum height
24583 that is needed to make all tool-bar items visible.
24584 If value is `grow-only', the tool-bar's height is only increased
24585 automatically; to decrease the tool-bar height, use \\[recenter]. */);
24586 Vauto_resize_tool_bars = Qt;
24588 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
24589 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
24590 auto_raise_tool_bar_buttons_p = 1;
24592 DEFVAR_BOOL ("make-cursor-line-fully-visible", &make_cursor_line_fully_visible_p,
24593 doc: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
24594 make_cursor_line_fully_visible_p = 1;
24596 DEFVAR_LISP ("tool-bar-border", &Vtool_bar_border,
24597 doc: /* *Border below tool-bar in pixels.
24598 If an integer, use it as the height of the border.
24599 If it is one of `internal-border-width' or `border-width', use the
24600 value of the corresponding frame parameter.
24601 Otherwise, no border is added below the tool-bar. */);
24602 Vtool_bar_border = Qinternal_border_width;
24604 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
24605 doc: /* *Margin around tool-bar buttons in pixels.
24606 If an integer, use that for both horizontal and vertical margins.
24607 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
24608 HORZ specifying the horizontal margin, and VERT specifying the
24609 vertical margin. */);
24610 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
24612 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
24613 doc: /* *Relief thickness of tool-bar buttons. */);
24614 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
24616 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
24617 doc: /* List of functions to call to fontify regions of text.
24618 Each function is called with one argument POS. Functions must
24619 fontify a region starting at POS in the current buffer, and give
24620 fontified regions the property `fontified'. */);
24621 Vfontification_functions = Qnil;
24622 Fmake_variable_buffer_local (Qfontification_functions);
24624 DEFVAR_BOOL ("unibyte-display-via-language-environment",
24625 &unibyte_display_via_language_environment,
24626 doc: /* *Non-nil means display unibyte text according to language environment.
24627 Specifically this means that unibyte non-ASCII characters
24628 are displayed by converting them to the equivalent multibyte characters
24629 according to the current language environment. As a result, they are
24630 displayed according to the current fontset. */);
24631 unibyte_display_via_language_environment = 0;
24633 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
24634 doc: /* *Maximum height for resizing mini-windows.
24635 If a float, it specifies a fraction of the mini-window frame's height.
24636 If an integer, it specifies a number of lines. */);
24637 Vmax_mini_window_height = make_float (0.25);
24639 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
24640 doc: /* *How to resize mini-windows.
24641 A value of nil means don't automatically resize mini-windows.
24642 A value of t means resize them to fit the text displayed in them.
24643 A value of `grow-only', the default, means let mini-windows grow
24644 only, until their display becomes empty, at which point the windows
24645 go back to their normal size. */);
24646 Vresize_mini_windows = Qgrow_only;
24648 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
24649 doc: /* Alist specifying how to blink the cursor off.
24650 Each element has the form (ON-STATE . OFF-STATE). Whenever the
24651 `cursor-type' frame-parameter or variable equals ON-STATE,
24652 comparing using `equal', Emacs uses OFF-STATE to specify
24653 how to blink it off. ON-STATE and OFF-STATE are values for
24654 the `cursor-type' frame parameter.
24656 If a frame's ON-STATE has no entry in this list,
24657 the frame's other specifications determine how to blink the cursor off. */);
24658 Vblink_cursor_alist = Qnil;
24660 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
24661 doc: /* *Non-nil means scroll the display automatically to make point visible. */);
24662 automatic_hscrolling_p = 1;
24663 Qauto_hscroll_mode = intern ("auto-hscroll-mode");
24664 staticpro (&Qauto_hscroll_mode);
24666 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
24667 doc: /* *How many columns away from the window edge point is allowed to get
24668 before automatic hscrolling will horizontally scroll the window. */);
24669 hscroll_margin = 5;
24671 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
24672 doc: /* *How many columns to scroll the window when point gets too close to the edge.
24673 When point is less than `hscroll-margin' columns from the window
24674 edge, automatic hscrolling will scroll the window by the amount of columns
24675 determined by this variable. If its value is a positive integer, scroll that
24676 many columns. If it's a positive floating-point number, it specifies the
24677 fraction of the window's width to scroll. If it's nil or zero, point will be
24678 centered horizontally after the scroll. Any other value, including negative
24679 numbers, are treated as if the value were zero.
24681 Automatic hscrolling always moves point outside the scroll margin, so if
24682 point was more than scroll step columns inside the margin, the window will
24683 scroll more than the value given by the scroll step.
24685 Note that the lower bound for automatic hscrolling specified by `scroll-left'
24686 and `scroll-right' overrides this variable's effect. */);
24687 Vhscroll_step = make_number (0);
24689 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
24690 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
24691 Bind this around calls to `message' to let it take effect. */);
24692 message_truncate_lines = 0;
24694 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
24695 doc: /* Normal hook run to update the menu bar definitions.
24696 Redisplay runs this hook before it redisplays the menu bar.
24697 This is used to update submenus such as Buffers,
24698 whose contents depend on various data. */);
24699 Vmenu_bar_update_hook = Qnil;
24701 DEFVAR_LISP ("menu-updating-frame", &Vmenu_updating_frame,
24702 doc: /* Frame for which we are updating a menu.
24703 The enable predicate for a menu binding should check this variable. */);
24704 Vmenu_updating_frame = Qnil;
24706 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
24707 doc: /* Non-nil means don't update menu bars. Internal use only. */);
24708 inhibit_menubar_update = 0;
24710 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
24711 doc: /* Non-nil means don't eval Lisp during redisplay. */);
24712 inhibit_eval_during_redisplay = 0;
24714 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
24715 doc: /* Non-nil means don't free realized faces. Internal use only. */);
24716 inhibit_free_realized_faces = 0;
24718 #if GLYPH_DEBUG
24719 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
24720 doc: /* Inhibit try_window_id display optimization. */);
24721 inhibit_try_window_id = 0;
24723 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
24724 doc: /* Inhibit try_window_reusing display optimization. */);
24725 inhibit_try_window_reusing = 0;
24727 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
24728 doc: /* Inhibit try_cursor_movement display optimization. */);
24729 inhibit_try_cursor_movement = 0;
24730 #endif /* GLYPH_DEBUG */
24732 DEFVAR_INT ("overline-margin", &overline_margin,
24733 doc: /* *Space between overline and text, in pixels.
24734 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
24735 margin to the caracter height. */);
24736 overline_margin = 2;
24740 /* Initialize this module when Emacs starts. */
24742 void
24743 init_xdisp ()
24745 Lisp_Object root_window;
24746 struct window *mini_w;
24748 current_header_line_height = current_mode_line_height = -1;
24750 CHARPOS (this_line_start_pos) = 0;
24752 mini_w = XWINDOW (minibuf_window);
24753 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
24755 if (!noninteractive)
24757 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
24758 int i;
24760 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
24761 set_window_height (root_window,
24762 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
24764 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
24765 set_window_height (minibuf_window, 1, 0);
24767 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
24768 mini_w->total_cols = make_number (FRAME_COLS (f));
24770 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
24771 scratch_glyph_row.glyphs[TEXT_AREA + 1]
24772 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
24774 /* The default ellipsis glyphs `...'. */
24775 for (i = 0; i < 3; ++i)
24776 default_invis_vector[i] = make_number ('.');
24780 /* Allocate the buffer for frame titles.
24781 Also used for `format-mode-line'. */
24782 int size = 100;
24783 mode_line_noprop_buf = (char *) xmalloc (size);
24784 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
24785 mode_line_noprop_ptr = mode_line_noprop_buf;
24786 mode_line_target = MODE_LINE_DISPLAY;
24789 help_echo_showing_p = 0;
24793 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
24794 (do not change this comment) */