1 /* Display generation from window structure and buffer text.
2 Copyright (C) 1985,86,87,88,93,94,95,97,98,99,2000,01,02,03,04
3 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* New redisplay written by Gerd Moellmann <gerd@gnu.org>.
26 Emacs separates the task of updating the display from code
27 modifying global state, e.g. buffer text. This way functions
28 operating on buffers don't also have to be concerned with updating
31 Updating the display is triggered by the Lisp interpreter when it
32 decides it's time to do it. This is done either automatically for
33 you as part of the interpreter's command loop or as the result of
34 calling Lisp functions like `sit-for'. The C function `redisplay'
35 in xdisp.c is the only entry into the inner redisplay code. (Or,
36 let's say almost---see the description of direct update
39 The following diagram shows how redisplay code is invoked. As you
40 can see, Lisp calls redisplay and vice versa. Under window systems
41 like X, some portions of the redisplay code are also called
42 asynchronously during mouse movement or expose events. It is very
43 important that these code parts do NOT use the C library (malloc,
44 free) because many C libraries under Unix are not reentrant. They
45 may also NOT call functions of the Lisp interpreter which could
46 change the interpreter's state. If you don't follow these rules,
47 you will encounter bugs which are very hard to explain.
49 (Direct functions, see below)
50 direct_output_for_insert,
51 direct_forward_char (dispnew.c)
52 +---------------------------------+
55 +--------------+ redisplay +----------------+
56 | Lisp machine |---------------->| Redisplay code |<--+
57 +--------------+ (xdisp.c) +----------------+ |
59 +----------------------------------+ |
60 Don't use this path when called |
63 expose_window (asynchronous) |
65 X expose events -----+
67 What does redisplay do? Obviously, it has to figure out somehow what
68 has been changed since the last time the display has been updated,
69 and to make these changes visible. Preferably it would do that in
70 a moderately intelligent way, i.e. fast.
72 Changes in buffer text can be deduced from window and buffer
73 structures, and from some global variables like `beg_unchanged' and
74 `end_unchanged'. The contents of the display are additionally
75 recorded in a `glyph matrix', a two-dimensional matrix of glyph
76 structures. Each row in such a matrix corresponds to a line on the
77 display, and each glyph in a row corresponds to a column displaying
78 a character, an image, or what else. This matrix is called the
79 `current glyph matrix' or `current matrix' in redisplay
82 For buffer parts that have been changed since the last update, a
83 second glyph matrix is constructed, the so called `desired glyph
84 matrix' or short `desired matrix'. Current and desired matrix are
85 then compared to find a cheap way to update the display, e.g. by
86 reusing part of the display by scrolling lines.
91 You will find a lot of redisplay optimizations when you start
92 looking at the innards of redisplay. The overall goal of all these
93 optimizations is to make redisplay fast because it is done
96 Two optimizations are not found in xdisp.c. These are the direct
97 operations mentioned above. As the name suggests they follow a
98 different principle than the rest of redisplay. Instead of
99 building a desired matrix and then comparing it with the current
100 display, they perform their actions directly on the display and on
103 One direct operation updates the display after one character has
104 been entered. The other one moves the cursor by one position
105 forward or backward. You find these functions under the names
106 `direct_output_for_insert' and `direct_output_forward_char' in
112 Desired matrices are always built per Emacs window. The function
113 `display_line' is the central function to look at if you are
114 interested. It constructs one row in a desired matrix given an
115 iterator structure containing both a buffer position and a
116 description of the environment in which the text is to be
117 displayed. But this is too early, read on.
119 Characters and pixmaps displayed for a range of buffer text depend
120 on various settings of buffers and windows, on overlays and text
121 properties, on display tables, on selective display. The good news
122 is that all this hairy stuff is hidden behind a small set of
123 interface functions taking an iterator structure (struct it)
126 Iteration over things to be displayed is then simple. It is
127 started by initializing an iterator with a call to init_iterator.
128 Calls to get_next_display_element fill the iterator structure with
129 relevant information about the next thing to display. Calls to
130 set_iterator_to_next move the iterator to the next thing.
132 Besides this, an iterator also contains information about the
133 display environment in which glyphs for display elements are to be
134 produced. It has fields for the width and height of the display,
135 the information whether long lines are truncated or continued, a
136 current X and Y position, and lots of other stuff you can better
139 Glyphs in a desired matrix are normally constructed in a loop
140 calling get_next_display_element and then produce_glyphs. The call
141 to produce_glyphs will fill the iterator structure with pixel
142 information about the element being displayed and at the same time
143 produce glyphs for it. If the display element fits on the line
144 being displayed, set_iterator_to_next is called next, otherwise the
145 glyphs produced are discarded.
150 That just couldn't be all, could it? What about terminal types not
151 supporting operations on sub-windows of the screen? To update the
152 display on such a terminal, window-based glyph matrices are not
153 well suited. To be able to reuse part of the display (scrolling
154 lines up and down), we must instead have a view of the whole
155 screen. This is what `frame matrices' are for. They are a trick.
157 Frames on terminals like above have a glyph pool. Windows on such
158 a frame sub-allocate their glyph memory from their frame's glyph
159 pool. The frame itself is given its own glyph matrices. By
160 coincidence---or maybe something else---rows in window glyph
161 matrices are slices of corresponding rows in frame matrices. Thus
162 writing to window matrices implicitly updates a frame matrix which
163 provides us with the view of the whole screen that we originally
164 wanted to have without having to move many bytes around. To be
165 honest, there is a little bit more done, but not much more. If you
166 plan to extend that code, take a look at dispnew.c. The function
167 build_frame_matrix is a good starting point. */
173 #include "keyboard.h"
176 #include "termchar.h"
177 #include "dispextern.h"
181 #include "commands.h"
185 #include "termhooks.h"
186 #include "intervals.h"
189 #include "region-cache.h"
191 #include "blockinput.h"
193 #ifdef HAVE_X_WINDOWS
203 #ifndef FRAME_X_OUTPUT
204 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
207 #define INFINITY 10000000
209 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
211 extern void set_frame_menubar
P_ ((struct frame
*f
, int, int));
212 extern int pending_menu_activation
;
215 extern int interrupt_input
;
216 extern int command_loop_level
;
218 extern int minibuffer_auto_raise
;
219 extern Lisp_Object Vminibuffer_list
;
221 extern Lisp_Object Qface
;
222 extern Lisp_Object Qmode_line
, Qmode_line_inactive
, Qheader_line
;
224 extern Lisp_Object Voverriding_local_map
;
225 extern Lisp_Object Voverriding_local_map_menu_flag
;
226 extern Lisp_Object Qmenu_item
;
227 extern Lisp_Object Qwhen
;
228 extern Lisp_Object Qhelp_echo
;
230 Lisp_Object Qoverriding_local_map
, Qoverriding_terminal_local_map
;
231 Lisp_Object Qwindow_scroll_functions
, Vwindow_scroll_functions
;
232 Lisp_Object Qredisplay_end_trigger_functions
;
233 Lisp_Object Qinhibit_point_motion_hooks
;
234 Lisp_Object QCeval
, QCfile
, QCdata
, QCpropertize
;
235 Lisp_Object Qfontified
;
236 Lisp_Object Qgrow_only
;
237 Lisp_Object Qinhibit_eval_during_redisplay
;
238 Lisp_Object Qbuffer_position
, Qposition
, Qobject
;
241 Lisp_Object Qbar
, Qhbar
, Qbox
, Qhollow
;
244 Lisp_Object Qarrow
, Qhand
, Qtext
;
246 Lisp_Object Qrisky_local_variable
;
248 /* Holds the list (error). */
249 Lisp_Object list_of_error
;
251 /* Functions called to fontify regions of text. */
253 Lisp_Object Vfontification_functions
;
254 Lisp_Object Qfontification_functions
;
256 /* Non-zero means automatically select any window when the mouse
257 cursor moves into it. */
258 int mouse_autoselect_window
;
260 /* Non-zero means draw tool bar buttons raised when the mouse moves
263 int auto_raise_tool_bar_buttons_p
;
265 /* Margin around tool bar buttons in pixels. */
267 Lisp_Object Vtool_bar_button_margin
;
269 /* Thickness of shadow to draw around tool bar buttons. */
271 EMACS_INT tool_bar_button_relief
;
273 /* Non-zero means automatically resize tool-bars so that all tool-bar
274 items are visible, and no blank lines remain. */
276 int auto_resize_tool_bars_p
;
278 /* Non-zero means draw block and hollow cursor as wide as the glyph
279 under it. For example, if a block cursor is over a tab, it will be
280 drawn as wide as that tab on the display. */
282 int x_stretch_cursor_p
;
284 /* Non-nil means don't actually do any redisplay. */
286 Lisp_Object Vinhibit_redisplay
, Qinhibit_redisplay
;
288 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
290 int inhibit_eval_during_redisplay
;
292 /* Names of text properties relevant for redisplay. */
294 Lisp_Object Qdisplay
;
295 extern Lisp_Object Qface
, Qinvisible
, Qwidth
;
297 /* Symbols used in text property values. */
299 Lisp_Object Vdisplay_pixels_per_inch
;
300 Lisp_Object Qspace
, QCalign_to
, QCrelative_width
, QCrelative_height
;
301 Lisp_Object Qleft_margin
, Qright_margin
, Qspace_width
, Qraise
;
304 Lisp_Object Qmargin
, Qpointer
;
305 Lisp_Object Qline_height
, Qtotal
;
306 extern Lisp_Object Qheight
;
307 extern Lisp_Object QCwidth
, QCheight
, QCascent
;
308 extern Lisp_Object Qscroll_bar
;
309 extern Lisp_Object Qcursor
;
311 /* Non-nil means highlight trailing whitespace. */
313 Lisp_Object Vshow_trailing_whitespace
;
315 #ifdef HAVE_WINDOW_SYSTEM
316 extern Lisp_Object Voverflow_newline_into_fringe
;
318 /* Test if overflow newline into fringe. Called with iterator IT
319 at or past right window margin, and with IT->current_x set. */
321 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) \
322 (!NILP (Voverflow_newline_into_fringe) \
323 && FRAME_WINDOW_P (it->f) \
324 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
325 && it->current_x == it->last_visible_x)
327 #endif /* HAVE_WINDOW_SYSTEM */
329 /* Non-nil means show the text cursor in void text areas
330 i.e. in blank areas after eol and eob. This used to be
331 the default in 21.3. */
333 Lisp_Object Vvoid_text_area_pointer
;
335 /* Name of the face used to highlight trailing whitespace. */
337 Lisp_Object Qtrailing_whitespace
;
339 /* The symbol `image' which is the car of the lists used to represent
344 /* The image map types. */
345 Lisp_Object QCmap
, QCpointer
;
346 Lisp_Object Qrect
, Qcircle
, Qpoly
;
348 /* Non-zero means print newline to stdout before next mini-buffer
351 int noninteractive_need_newline
;
353 /* Non-zero means print newline to message log before next message. */
355 static int message_log_need_newline
;
357 /* Three markers that message_dolog uses.
358 It could allocate them itself, but that causes trouble
359 in handling memory-full errors. */
360 static Lisp_Object message_dolog_marker1
;
361 static Lisp_Object message_dolog_marker2
;
362 static Lisp_Object message_dolog_marker3
;
364 /* The buffer position of the first character appearing entirely or
365 partially on the line of the selected window which contains the
366 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
367 redisplay optimization in redisplay_internal. */
369 static struct text_pos this_line_start_pos
;
371 /* Number of characters past the end of the line above, including the
372 terminating newline. */
374 static struct text_pos this_line_end_pos
;
376 /* The vertical positions and the height of this line. */
378 static int this_line_vpos
;
379 static int this_line_y
;
380 static int this_line_pixel_height
;
382 /* X position at which this display line starts. Usually zero;
383 negative if first character is partially visible. */
385 static int this_line_start_x
;
387 /* Buffer that this_line_.* variables are referring to. */
389 static struct buffer
*this_line_buffer
;
391 /* Nonzero means truncate lines in all windows less wide than the
394 int truncate_partial_width_windows
;
396 /* A flag to control how to display unibyte 8-bit character. */
398 int unibyte_display_via_language_environment
;
400 /* Nonzero means we have more than one non-mini-buffer-only frame.
401 Not guaranteed to be accurate except while parsing
402 frame-title-format. */
406 Lisp_Object Vglobal_mode_string
;
409 /* List of variables (symbols) which hold markers for overlay arrows.
410 The symbols on this list are examined during redisplay to determine
411 where to display overlay arrows. */
413 Lisp_Object Voverlay_arrow_variable_list
;
415 /* Marker for where to display an arrow on top of the buffer text. */
417 Lisp_Object Voverlay_arrow_position
;
419 /* String to display for the arrow. Only used on terminal frames. */
421 Lisp_Object Voverlay_arrow_string
;
423 /* Values of those variables at last redisplay are stored as
424 properties on `overlay-arrow-position' symbol. However, if
425 Voverlay_arrow_position is a marker, last-arrow-position is its
426 numerical position. */
428 Lisp_Object Qlast_arrow_position
, Qlast_arrow_string
;
430 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
431 properties on a symbol in overlay-arrow-variable-list. */
433 Lisp_Object Qoverlay_arrow_string
, Qoverlay_arrow_bitmap
;
435 /* Like mode-line-format, but for the title bar on a visible frame. */
437 Lisp_Object Vframe_title_format
;
439 /* Like mode-line-format, but for the title bar on an iconified frame. */
441 Lisp_Object Vicon_title_format
;
443 /* List of functions to call when a window's size changes. These
444 functions get one arg, a frame on which one or more windows' sizes
447 static Lisp_Object Vwindow_size_change_functions
;
449 Lisp_Object Qmenu_bar_update_hook
, Vmenu_bar_update_hook
;
451 /* Nonzero if overlay arrow has been displayed once in this window. */
453 static int overlay_arrow_seen
;
455 /* Nonzero means highlight the region even in nonselected windows. */
457 int highlight_nonselected_windows
;
459 /* If cursor motion alone moves point off frame, try scrolling this
460 many lines up or down if that will bring it back. */
462 static EMACS_INT scroll_step
;
464 /* Nonzero means scroll just far enough to bring point back on the
465 screen, when appropriate. */
467 static EMACS_INT scroll_conservatively
;
469 /* Recenter the window whenever point gets within this many lines of
470 the top or bottom of the window. This value is translated into a
471 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
472 that there is really a fixed pixel height scroll margin. */
474 EMACS_INT scroll_margin
;
476 /* Number of windows showing the buffer of the selected window (or
477 another buffer with the same base buffer). keyboard.c refers to
482 /* Vector containing glyphs for an ellipsis `...'. */
484 static Lisp_Object default_invis_vector
[3];
486 /* Zero means display the mode-line/header-line/menu-bar in the default face
487 (this slightly odd definition is for compatibility with previous versions
488 of emacs), non-zero means display them using their respective faces.
490 This variable is deprecated. */
492 int mode_line_inverse_video
;
494 /* Prompt to display in front of the mini-buffer contents. */
496 Lisp_Object minibuf_prompt
;
498 /* Width of current mini-buffer prompt. Only set after display_line
499 of the line that contains the prompt. */
501 int minibuf_prompt_width
;
503 /* This is the window where the echo area message was displayed. It
504 is always a mini-buffer window, but it may not be the same window
505 currently active as a mini-buffer. */
507 Lisp_Object echo_area_window
;
509 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
510 pushes the current message and the value of
511 message_enable_multibyte on the stack, the function restore_message
512 pops the stack and displays MESSAGE again. */
514 Lisp_Object Vmessage_stack
;
516 /* Nonzero means multibyte characters were enabled when the echo area
517 message was specified. */
519 int message_enable_multibyte
;
521 /* Nonzero if we should redraw the mode lines on the next redisplay. */
523 int update_mode_lines
;
525 /* Nonzero if window sizes or contents have changed since last
526 redisplay that finished. */
528 int windows_or_buffers_changed
;
530 /* Nonzero means a frame's cursor type has been changed. */
532 int cursor_type_changed
;
534 /* Nonzero after display_mode_line if %l was used and it displayed a
537 int line_number_displayed
;
539 /* Maximum buffer size for which to display line numbers. */
541 Lisp_Object Vline_number_display_limit
;
543 /* Line width to consider when repositioning for line number display. */
545 static EMACS_INT line_number_display_limit_width
;
547 /* Number of lines to keep in the message log buffer. t means
548 infinite. nil means don't log at all. */
550 Lisp_Object Vmessage_log_max
;
552 /* The name of the *Messages* buffer, a string. */
554 static Lisp_Object Vmessages_buffer_name
;
556 /* Current, index 0, and last displayed echo area message. Either
557 buffers from echo_buffers, or nil to indicate no message. */
559 Lisp_Object echo_area_buffer
[2];
561 /* The buffers referenced from echo_area_buffer. */
563 static Lisp_Object echo_buffer
[2];
565 /* A vector saved used in with_area_buffer to reduce consing. */
567 static Lisp_Object Vwith_echo_area_save_vector
;
569 /* Non-zero means display_echo_area should display the last echo area
570 message again. Set by redisplay_preserve_echo_area. */
572 static int display_last_displayed_message_p
;
574 /* Nonzero if echo area is being used by print; zero if being used by
577 int message_buf_print
;
579 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
581 Lisp_Object Qinhibit_menubar_update
;
582 int inhibit_menubar_update
;
584 /* Maximum height for resizing mini-windows. Either a float
585 specifying a fraction of the available height, or an integer
586 specifying a number of lines. */
588 Lisp_Object Vmax_mini_window_height
;
590 /* Non-zero means messages should be displayed with truncated
591 lines instead of being continued. */
593 int message_truncate_lines
;
594 Lisp_Object Qmessage_truncate_lines
;
596 /* Set to 1 in clear_message to make redisplay_internal aware
597 of an emptied echo area. */
599 static int message_cleared_p
;
601 /* Non-zero means we want a hollow cursor in windows that are not
602 selected. Zero means there's no cursor in such windows. */
604 Lisp_Object Vcursor_in_non_selected_windows
;
605 Lisp_Object Qcursor_in_non_selected_windows
;
607 /* How to blink the default frame cursor off. */
608 Lisp_Object Vblink_cursor_alist
;
610 /* A scratch glyph row with contents used for generating truncation
611 glyphs. Also used in direct_output_for_insert. */
613 #define MAX_SCRATCH_GLYPHS 100
614 struct glyph_row scratch_glyph_row
;
615 static struct glyph scratch_glyphs
[MAX_SCRATCH_GLYPHS
];
617 /* Ascent and height of the last line processed by move_it_to. */
619 static int last_max_ascent
, last_height
;
621 /* Non-zero if there's a help-echo in the echo area. */
623 int help_echo_showing_p
;
625 /* If >= 0, computed, exact values of mode-line and header-line height
626 to use in the macros CURRENT_MODE_LINE_HEIGHT and
627 CURRENT_HEADER_LINE_HEIGHT. */
629 int current_mode_line_height
, current_header_line_height
;
631 /* The maximum distance to look ahead for text properties. Values
632 that are too small let us call compute_char_face and similar
633 functions too often which is expensive. Values that are too large
634 let us call compute_char_face and alike too often because we
635 might not be interested in text properties that far away. */
637 #define TEXT_PROP_DISTANCE_LIMIT 100
641 /* Variables to turn off display optimizations from Lisp. */
643 int inhibit_try_window_id
, inhibit_try_window_reusing
;
644 int inhibit_try_cursor_movement
;
646 /* Non-zero means print traces of redisplay if compiled with
649 int trace_redisplay_p
;
651 #endif /* GLYPH_DEBUG */
653 #ifdef DEBUG_TRACE_MOVE
654 /* Non-zero means trace with TRACE_MOVE to stderr. */
657 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
659 #define TRACE_MOVE(x) (void) 0
662 /* Non-zero means automatically scroll windows horizontally to make
665 int automatic_hscrolling_p
;
667 /* How close to the margin can point get before the window is scrolled
669 EMACS_INT hscroll_margin
;
671 /* How much to scroll horizontally when point is inside the above margin. */
672 Lisp_Object Vhscroll_step
;
674 /* The variable `resize-mini-windows'. If nil, don't resize
675 mini-windows. If t, always resize them to fit the text they
676 display. If `grow-only', let mini-windows grow only until they
679 Lisp_Object Vresize_mini_windows
;
681 /* Buffer being redisplayed -- for redisplay_window_error. */
683 struct buffer
*displayed_buffer
;
685 /* Value returned from text property handlers (see below). */
690 HANDLED_RECOMPUTE_PROPS
,
691 HANDLED_OVERLAY_STRING_CONSUMED
,
695 /* A description of text properties that redisplay is interested
700 /* The name of the property. */
703 /* A unique index for the property. */
706 /* A handler function called to set up iterator IT from the property
707 at IT's current position. Value is used to steer handle_stop. */
708 enum prop_handled (*handler
) P_ ((struct it
*it
));
711 static enum prop_handled handle_face_prop
P_ ((struct it
*));
712 static enum prop_handled handle_invisible_prop
P_ ((struct it
*));
713 static enum prop_handled handle_display_prop
P_ ((struct it
*));
714 static enum prop_handled handle_composition_prop
P_ ((struct it
*));
715 static enum prop_handled handle_overlay_change
P_ ((struct it
*));
716 static enum prop_handled handle_fontified_prop
P_ ((struct it
*));
718 /* Properties handled by iterators. */
720 static struct props it_props
[] =
722 {&Qfontified
, FONTIFIED_PROP_IDX
, handle_fontified_prop
},
723 /* Handle `face' before `display' because some sub-properties of
724 `display' need to know the face. */
725 {&Qface
, FACE_PROP_IDX
, handle_face_prop
},
726 {&Qdisplay
, DISPLAY_PROP_IDX
, handle_display_prop
},
727 {&Qinvisible
, INVISIBLE_PROP_IDX
, handle_invisible_prop
},
728 {&Qcomposition
, COMPOSITION_PROP_IDX
, handle_composition_prop
},
732 /* Value is the position described by X. If X is a marker, value is
733 the marker_position of X. Otherwise, value is X. */
735 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
737 /* Enumeration returned by some move_it_.* functions internally. */
741 /* Not used. Undefined value. */
744 /* Move ended at the requested buffer position or ZV. */
745 MOVE_POS_MATCH_OR_ZV
,
747 /* Move ended at the requested X pixel position. */
750 /* Move within a line ended at the end of a line that must be
754 /* Move within a line ended at the end of a line that would
755 be displayed truncated. */
758 /* Move within a line ended at a line end. */
762 /* This counter is used to clear the face cache every once in a while
763 in redisplay_internal. It is incremented for each redisplay.
764 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
767 #define CLEAR_FACE_CACHE_COUNT 500
768 static int clear_face_cache_count
;
770 /* Record the previous terminal frame we displayed. */
772 static struct frame
*previous_terminal_frame
;
774 /* Non-zero while redisplay_internal is in progress. */
778 /* Non-zero means don't free realized faces. Bound while freeing
779 realized faces is dangerous because glyph matrices might still
782 int inhibit_free_realized_faces
;
783 Lisp_Object Qinhibit_free_realized_faces
;
785 /* If a string, XTread_socket generates an event to display that string.
786 (The display is done in read_char.) */
788 Lisp_Object help_echo_string
;
789 Lisp_Object help_echo_window
;
790 Lisp_Object help_echo_object
;
793 /* Temporary variable for XTread_socket. */
795 Lisp_Object previous_help_echo_string
;
797 /* Null glyph slice */
799 static struct glyph_slice null_glyph_slice
= { 0, 0, 0, 0 };
802 /* Function prototypes. */
804 static void setup_for_ellipsis
P_ ((struct it
*));
805 static void mark_window_display_accurate_1
P_ ((struct window
*, int));
806 static int single_display_prop_string_p
P_ ((Lisp_Object
, Lisp_Object
));
807 static int display_prop_string_p
P_ ((Lisp_Object
, Lisp_Object
));
808 static int cursor_row_p
P_ ((struct window
*, struct glyph_row
*));
809 static int redisplay_mode_lines
P_ ((Lisp_Object
, int));
810 static char *decode_mode_spec_coding
P_ ((Lisp_Object
, char *, int));
813 static int invisible_text_between_p
P_ ((struct it
*, int, int));
816 static int next_element_from_ellipsis
P_ ((struct it
*));
817 static void pint2str
P_ ((char *, int, int));
818 static void pint2hrstr
P_ ((char *, int, int));
819 static struct text_pos run_window_scroll_functions
P_ ((Lisp_Object
,
821 static void reconsider_clip_changes
P_ ((struct window
*, struct buffer
*));
822 static int text_outside_line_unchanged_p
P_ ((struct window
*, int, int));
823 static void store_frame_title_char
P_ ((char));
824 static int store_frame_title
P_ ((const unsigned char *, int, int));
825 static void x_consider_frame_title
P_ ((Lisp_Object
));
826 static void handle_stop
P_ ((struct it
*));
827 static int tool_bar_lines_needed
P_ ((struct frame
*));
828 static int single_display_prop_intangible_p
P_ ((Lisp_Object
));
829 static void ensure_echo_area_buffers
P_ ((void));
830 static Lisp_Object unwind_with_echo_area_buffer
P_ ((Lisp_Object
));
831 static Lisp_Object with_echo_area_buffer_unwind_data
P_ ((struct window
*));
832 static int with_echo_area_buffer
P_ ((struct window
*, int,
833 int (*) (EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
),
834 EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
835 static void clear_garbaged_frames
P_ ((void));
836 static int current_message_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
837 static int truncate_message_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
838 static int set_message_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
839 static int display_echo_area
P_ ((struct window
*));
840 static int display_echo_area_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
841 static int resize_mini_window_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
842 static Lisp_Object unwind_redisplay
P_ ((Lisp_Object
));
843 static int string_char_and_length
P_ ((const unsigned char *, int, int *));
844 static struct text_pos display_prop_end
P_ ((struct it
*, Lisp_Object
,
846 static int compute_window_start_on_continuation_line
P_ ((struct window
*));
847 static Lisp_Object safe_eval_handler
P_ ((Lisp_Object
));
848 static void insert_left_trunc_glyphs
P_ ((struct it
*));
849 static struct glyph_row
*get_overlay_arrow_glyph_row
P_ ((struct window
*,
851 static void extend_face_to_end_of_line
P_ ((struct it
*));
852 static int append_space_for_newline
P_ ((struct it
*, int));
853 static int make_cursor_line_fully_visible
P_ ((struct window
*, int));
854 static int try_scrolling
P_ ((Lisp_Object
, int, EMACS_INT
, EMACS_INT
, int, int));
855 static int try_cursor_movement
P_ ((Lisp_Object
, struct text_pos
, int *));
856 static int trailing_whitespace_p
P_ ((int));
857 static int message_log_check_duplicate
P_ ((int, int, int, int));
858 static void push_it
P_ ((struct it
*));
859 static void pop_it
P_ ((struct it
*));
860 static void sync_frame_with_window_matrix_rows
P_ ((struct window
*));
861 static void select_frame_for_redisplay
P_ ((Lisp_Object
));
862 static void redisplay_internal
P_ ((int));
863 static int echo_area_display
P_ ((int));
864 static void redisplay_windows
P_ ((Lisp_Object
));
865 static void redisplay_window
P_ ((Lisp_Object
, int));
866 static Lisp_Object
redisplay_window_error ();
867 static Lisp_Object redisplay_window_0
P_ ((Lisp_Object
));
868 static Lisp_Object redisplay_window_1
P_ ((Lisp_Object
));
869 static void update_menu_bar
P_ ((struct frame
*, int));
870 static int try_window_reusing_current_matrix
P_ ((struct window
*));
871 static int try_window_id
P_ ((struct window
*));
872 static int display_line
P_ ((struct it
*));
873 static int display_mode_lines
P_ ((struct window
*));
874 static int display_mode_line
P_ ((struct window
*, enum face_id
, Lisp_Object
));
875 static int display_mode_element
P_ ((struct it
*, int, int, int, Lisp_Object
, Lisp_Object
, int));
876 static int store_mode_line_string
P_ ((char *, Lisp_Object
, int, int, int, Lisp_Object
));
877 static char *decode_mode_spec
P_ ((struct window
*, int, int, int, int *));
878 static void display_menu_bar
P_ ((struct window
*));
879 static int display_count_lines
P_ ((int, int, int, int, int *));
880 static int display_string
P_ ((unsigned char *, Lisp_Object
, Lisp_Object
,
881 int, int, struct it
*, int, int, int, int));
882 static void compute_line_metrics
P_ ((struct it
*));
883 static void run_redisplay_end_trigger_hook
P_ ((struct it
*));
884 static int get_overlay_strings
P_ ((struct it
*, int));
885 static void next_overlay_string
P_ ((struct it
*));
886 static void reseat
P_ ((struct it
*, struct text_pos
, int));
887 static void reseat_1
P_ ((struct it
*, struct text_pos
, int));
888 static void back_to_previous_visible_line_start
P_ ((struct it
*));
889 static void reseat_at_previous_visible_line_start
P_ ((struct it
*));
890 static void reseat_at_next_visible_line_start
P_ ((struct it
*, int));
891 static int next_element_from_display_vector
P_ ((struct it
*));
892 static int next_element_from_string
P_ ((struct it
*));
893 static int next_element_from_c_string
P_ ((struct it
*));
894 static int next_element_from_buffer
P_ ((struct it
*));
895 static int next_element_from_composition
P_ ((struct it
*));
896 static int next_element_from_image
P_ ((struct it
*));
897 static int next_element_from_stretch
P_ ((struct it
*));
898 static void load_overlay_strings
P_ ((struct it
*, int));
899 static int init_from_display_pos
P_ ((struct it
*, struct window
*,
900 struct display_pos
*));
901 static void reseat_to_string
P_ ((struct it
*, unsigned char *,
902 Lisp_Object
, int, int, int, int));
903 static enum move_it_result move_it_in_display_line_to
P_ ((struct it
*,
905 void move_it_vertically_backward
P_ ((struct it
*, int));
906 static void init_to_row_start
P_ ((struct it
*, struct window
*,
907 struct glyph_row
*));
908 static int init_to_row_end
P_ ((struct it
*, struct window
*,
909 struct glyph_row
*));
910 static void back_to_previous_line_start
P_ ((struct it
*));
911 static int forward_to_next_line_start
P_ ((struct it
*, int *));
912 static struct text_pos string_pos_nchars_ahead
P_ ((struct text_pos
,
914 static struct text_pos string_pos
P_ ((int, Lisp_Object
));
915 static struct text_pos c_string_pos
P_ ((int, unsigned char *, int));
916 static int number_of_chars
P_ ((unsigned char *, int));
917 static void compute_stop_pos
P_ ((struct it
*));
918 static void compute_string_pos
P_ ((struct text_pos
*, struct text_pos
,
920 static int face_before_or_after_it_pos
P_ ((struct it
*, int));
921 static int next_overlay_change
P_ ((int));
922 static int handle_single_display_prop
P_ ((struct it
*, Lisp_Object
,
923 Lisp_Object
, struct text_pos
*,
925 static int underlying_face_id
P_ ((struct it
*));
926 static int in_ellipses_for_invisible_text_p
P_ ((struct display_pos
*,
929 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
930 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
932 #ifdef HAVE_WINDOW_SYSTEM
934 static void update_tool_bar
P_ ((struct frame
*, int));
935 static void build_desired_tool_bar_string
P_ ((struct frame
*f
));
936 static int redisplay_tool_bar
P_ ((struct frame
*));
937 static void display_tool_bar_line
P_ ((struct it
*));
938 static void notice_overwritten_cursor
P_ ((struct window
*,
940 int, int, int, int));
944 #endif /* HAVE_WINDOW_SYSTEM */
947 /***********************************************************************
948 Window display dimensions
949 ***********************************************************************/
951 /* Return the bottom boundary y-position for text lines in window W.
952 This is the first y position at which a line cannot start.
953 It is relative to the top of the window.
955 This is the height of W minus the height of a mode line, if any. */
958 window_text_bottom_y (w
)
961 int height
= WINDOW_TOTAL_HEIGHT (w
);
963 if (WINDOW_WANTS_MODELINE_P (w
))
964 height
-= CURRENT_MODE_LINE_HEIGHT (w
);
968 /* Return the pixel width of display area AREA of window W. AREA < 0
969 means return the total width of W, not including fringes to
970 the left and right of the window. */
973 window_box_width (w
, area
)
977 int cols
= XFASTINT (w
->total_cols
);
980 if (!w
->pseudo_window_p
)
982 cols
-= WINDOW_SCROLL_BAR_COLS (w
);
984 if (area
== TEXT_AREA
)
986 if (INTEGERP (w
->left_margin_cols
))
987 cols
-= XFASTINT (w
->left_margin_cols
);
988 if (INTEGERP (w
->right_margin_cols
))
989 cols
-= XFASTINT (w
->right_margin_cols
);
990 pixels
= -WINDOW_TOTAL_FRINGE_WIDTH (w
);
992 else if (area
== LEFT_MARGIN_AREA
)
994 cols
= (INTEGERP (w
->left_margin_cols
)
995 ? XFASTINT (w
->left_margin_cols
) : 0);
998 else if (area
== RIGHT_MARGIN_AREA
)
1000 cols
= (INTEGERP (w
->right_margin_cols
)
1001 ? XFASTINT (w
->right_margin_cols
) : 0);
1006 return cols
* WINDOW_FRAME_COLUMN_WIDTH (w
) + pixels
;
1010 /* Return the pixel height of the display area of window W, not
1011 including mode lines of W, if any. */
1014 window_box_height (w
)
1017 struct frame
*f
= XFRAME (w
->frame
);
1018 int height
= WINDOW_TOTAL_HEIGHT (w
);
1020 xassert (height
>= 0);
1022 /* Note: the code below that determines the mode-line/header-line
1023 height is essentially the same as that contained in the macro
1024 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1025 the appropriate glyph row has its `mode_line_p' flag set,
1026 and if it doesn't, uses estimate_mode_line_height instead. */
1028 if (WINDOW_WANTS_MODELINE_P (w
))
1030 struct glyph_row
*ml_row
1031 = (w
->current_matrix
&& w
->current_matrix
->rows
1032 ? MATRIX_MODE_LINE_ROW (w
->current_matrix
)
1034 if (ml_row
&& ml_row
->mode_line_p
)
1035 height
-= ml_row
->height
;
1037 height
-= estimate_mode_line_height (f
, CURRENT_MODE_LINE_FACE_ID (w
));
1040 if (WINDOW_WANTS_HEADER_LINE_P (w
))
1042 struct glyph_row
*hl_row
1043 = (w
->current_matrix
&& w
->current_matrix
->rows
1044 ? MATRIX_HEADER_LINE_ROW (w
->current_matrix
)
1046 if (hl_row
&& hl_row
->mode_line_p
)
1047 height
-= hl_row
->height
;
1049 height
-= estimate_mode_line_height (f
, HEADER_LINE_FACE_ID
);
1052 /* With a very small font and a mode-line that's taller than
1053 default, we might end up with a negative height. */
1054 return max (0, height
);
1057 /* Return the window-relative coordinate of the left edge of display
1058 area AREA of window W. AREA < 0 means return the left edge of the
1059 whole window, to the right of the left fringe of W. */
1062 window_box_left_offset (w
, area
)
1068 if (w
->pseudo_window_p
)
1071 x
= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w
);
1073 if (area
== TEXT_AREA
)
1074 x
+= (WINDOW_LEFT_FRINGE_WIDTH (w
)
1075 + window_box_width (w
, LEFT_MARGIN_AREA
));
1076 else if (area
== RIGHT_MARGIN_AREA
)
1077 x
+= (WINDOW_LEFT_FRINGE_WIDTH (w
)
1078 + window_box_width (w
, LEFT_MARGIN_AREA
)
1079 + window_box_width (w
, TEXT_AREA
)
1080 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
1082 : WINDOW_RIGHT_FRINGE_WIDTH (w
)));
1083 else if (area
== LEFT_MARGIN_AREA
1084 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
))
1085 x
+= WINDOW_LEFT_FRINGE_WIDTH (w
);
1091 /* Return the window-relative coordinate of the right edge of display
1092 area AREA of window W. AREA < 0 means return the left edge of the
1093 whole window, to the left of the right fringe of W. */
1096 window_box_right_offset (w
, area
)
1100 return window_box_left_offset (w
, area
) + window_box_width (w
, area
);
1103 /* Return the frame-relative coordinate of the left edge of display
1104 area AREA of window W. AREA < 0 means return the left edge of the
1105 whole window, to the right of the left fringe of W. */
1108 window_box_left (w
, area
)
1112 struct frame
*f
= XFRAME (w
->frame
);
1115 if (w
->pseudo_window_p
)
1116 return FRAME_INTERNAL_BORDER_WIDTH (f
);
1118 x
= (WINDOW_LEFT_EDGE_X (w
)
1119 + window_box_left_offset (w
, area
));
1125 /* Return the frame-relative coordinate of the right edge of display
1126 area AREA of window W. AREA < 0 means return the left edge of the
1127 whole window, to the left of the right fringe of W. */
1130 window_box_right (w
, area
)
1134 return window_box_left (w
, area
) + window_box_width (w
, area
);
1137 /* Get the bounding box of the display area AREA of window W, without
1138 mode lines, in frame-relative coordinates. AREA < 0 means the
1139 whole window, not including the left and right fringes of
1140 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1141 coordinates of the upper-left corner of the box. Return in
1142 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1145 window_box (w
, area
, box_x
, box_y
, box_width
, box_height
)
1148 int *box_x
, *box_y
, *box_width
, *box_height
;
1151 *box_width
= window_box_width (w
, area
);
1153 *box_height
= window_box_height (w
);
1155 *box_x
= window_box_left (w
, area
);
1158 *box_y
= WINDOW_TOP_EDGE_Y (w
);
1159 if (WINDOW_WANTS_HEADER_LINE_P (w
))
1160 *box_y
+= CURRENT_HEADER_LINE_HEIGHT (w
);
1165 /* Get the bounding box of the display area AREA of window W, without
1166 mode lines. AREA < 0 means the whole window, not including the
1167 left and right fringe of the window. Return in *TOP_LEFT_X
1168 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1169 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1170 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1174 window_box_edges (w
, area
, top_left_x
, top_left_y
,
1175 bottom_right_x
, bottom_right_y
)
1178 int *top_left_x
, *top_left_y
, *bottom_right_x
, *bottom_right_y
;
1180 window_box (w
, area
, top_left_x
, top_left_y
, bottom_right_x
,
1182 *bottom_right_x
+= *top_left_x
;
1183 *bottom_right_y
+= *top_left_y
;
1188 /***********************************************************************
1190 ***********************************************************************/
1192 /* Return the bottom y-position of the line the iterator IT is in.
1193 This can modify IT's settings. */
1199 int line_height
= it
->max_ascent
+ it
->max_descent
;
1200 int line_top_y
= it
->current_y
;
1202 if (line_height
== 0)
1205 line_height
= last_height
;
1206 else if (IT_CHARPOS (*it
) < ZV
)
1208 move_it_by_lines (it
, 1, 1);
1209 line_height
= (it
->max_ascent
|| it
->max_descent
1210 ? it
->max_ascent
+ it
->max_descent
1215 struct glyph_row
*row
= it
->glyph_row
;
1217 /* Use the default character height. */
1218 it
->glyph_row
= NULL
;
1219 it
->what
= IT_CHARACTER
;
1222 PRODUCE_GLYPHS (it
);
1223 line_height
= it
->ascent
+ it
->descent
;
1224 it
->glyph_row
= row
;
1228 return line_top_y
+ line_height
;
1232 /* Return 1 if position CHARPOS is visible in window W. Set *FULLY to
1233 1 if POS is visible and the line containing POS is fully visible.
1234 EXACT_MODE_LINE_HEIGHTS_P non-zero means compute exact mode-line
1235 and header-lines heights. */
1238 pos_visible_p (w
, charpos
, fully
, x
, y
, exact_mode_line_heights_p
)
1240 int charpos
, *fully
, *x
, *y
, exact_mode_line_heights_p
;
1243 struct text_pos top
;
1245 struct buffer
*old_buffer
= NULL
;
1247 if (XBUFFER (w
->buffer
) != current_buffer
)
1249 old_buffer
= current_buffer
;
1250 set_buffer_internal_1 (XBUFFER (w
->buffer
));
1253 *fully
= visible_p
= 0;
1254 SET_TEXT_POS_FROM_MARKER (top
, w
->start
);
1256 /* Compute exact mode line heights, if requested. */
1257 if (exact_mode_line_heights_p
)
1259 if (WINDOW_WANTS_MODELINE_P (w
))
1260 current_mode_line_height
1261 = display_mode_line (w
, CURRENT_MODE_LINE_FACE_ID (w
),
1262 current_buffer
->mode_line_format
);
1264 if (WINDOW_WANTS_HEADER_LINE_P (w
))
1265 current_header_line_height
1266 = display_mode_line (w
, HEADER_LINE_FACE_ID
,
1267 current_buffer
->header_line_format
);
1270 start_display (&it
, w
, top
);
1271 move_it_to (&it
, charpos
, 0, it
.last_visible_y
, -1,
1272 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
1274 /* Note that we may overshoot because of invisible text. */
1275 if (IT_CHARPOS (it
) >= charpos
)
1277 int top_y
= it
.current_y
;
1278 int bottom_y
= line_bottom_y (&it
);
1279 int window_top_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
1281 if (top_y
< window_top_y
)
1282 visible_p
= bottom_y
> window_top_y
;
1283 else if (top_y
< it
.last_visible_y
)
1286 *fully
= bottom_y
<= it
.last_visible_y
;
1291 *y
= max (top_y
+ it
.max_ascent
- it
.ascent
, window_top_y
);
1294 else if (it
.current_y
+ it
.max_ascent
+ it
.max_descent
> it
.last_visible_y
)
1299 move_it_by_lines (&it
, 1, 0);
1300 if (charpos
< IT_CHARPOS (it
))
1305 move_it_to (&it2
, charpos
, -1, -1, -1, MOVE_TO_POS
);
1307 *y
= it2
.current_y
+ it2
.max_ascent
- it2
.ascent
;
1313 set_buffer_internal_1 (old_buffer
);
1315 current_header_line_height
= current_mode_line_height
= -1;
1321 /* Return the next character from STR which is MAXLEN bytes long.
1322 Return in *LEN the length of the character. This is like
1323 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1324 we find one, we return a `?', but with the length of the invalid
1328 string_char_and_length (str
, maxlen
, len
)
1329 const unsigned char *str
;
1334 c
= STRING_CHAR_AND_LENGTH (str
, maxlen
, *len
);
1335 if (!CHAR_VALID_P (c
, 1))
1336 /* We may not change the length here because other places in Emacs
1337 don't use this function, i.e. they silently accept invalid
1346 /* Given a position POS containing a valid character and byte position
1347 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1349 static struct text_pos
1350 string_pos_nchars_ahead (pos
, string
, nchars
)
1351 struct text_pos pos
;
1355 xassert (STRINGP (string
) && nchars
>= 0);
1357 if (STRING_MULTIBYTE (string
))
1359 int rest
= SBYTES (string
) - BYTEPOS (pos
);
1360 const unsigned char *p
= SDATA (string
) + BYTEPOS (pos
);
1365 string_char_and_length (p
, rest
, &len
);
1366 p
+= len
, rest
-= len
;
1367 xassert (rest
>= 0);
1369 BYTEPOS (pos
) += len
;
1373 SET_TEXT_POS (pos
, CHARPOS (pos
) + nchars
, BYTEPOS (pos
) + nchars
);
1379 /* Value is the text position, i.e. character and byte position,
1380 for character position CHARPOS in STRING. */
1382 static INLINE
struct text_pos
1383 string_pos (charpos
, string
)
1387 struct text_pos pos
;
1388 xassert (STRINGP (string
));
1389 xassert (charpos
>= 0);
1390 SET_TEXT_POS (pos
, charpos
, string_char_to_byte (string
, charpos
));
1395 /* Value is a text position, i.e. character and byte position, for
1396 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1397 means recognize multibyte characters. */
1399 static struct text_pos
1400 c_string_pos (charpos
, s
, multibyte_p
)
1405 struct text_pos pos
;
1407 xassert (s
!= NULL
);
1408 xassert (charpos
>= 0);
1412 int rest
= strlen (s
), len
;
1414 SET_TEXT_POS (pos
, 0, 0);
1417 string_char_and_length (s
, rest
, &len
);
1418 s
+= len
, rest
-= len
;
1419 xassert (rest
>= 0);
1421 BYTEPOS (pos
) += len
;
1425 SET_TEXT_POS (pos
, charpos
, charpos
);
1431 /* Value is the number of characters in C string S. MULTIBYTE_P
1432 non-zero means recognize multibyte characters. */
1435 number_of_chars (s
, multibyte_p
)
1443 int rest
= strlen (s
), len
;
1444 unsigned char *p
= (unsigned char *) s
;
1446 for (nchars
= 0; rest
> 0; ++nchars
)
1448 string_char_and_length (p
, rest
, &len
);
1449 rest
-= len
, p
+= len
;
1453 nchars
= strlen (s
);
1459 /* Compute byte position NEWPOS->bytepos corresponding to
1460 NEWPOS->charpos. POS is a known position in string STRING.
1461 NEWPOS->charpos must be >= POS.charpos. */
1464 compute_string_pos (newpos
, pos
, string
)
1465 struct text_pos
*newpos
, pos
;
1468 xassert (STRINGP (string
));
1469 xassert (CHARPOS (*newpos
) >= CHARPOS (pos
));
1471 if (STRING_MULTIBYTE (string
))
1472 *newpos
= string_pos_nchars_ahead (pos
, string
,
1473 CHARPOS (*newpos
) - CHARPOS (pos
));
1475 BYTEPOS (*newpos
) = CHARPOS (*newpos
);
1479 Return an estimation of the pixel height of mode or top lines on
1480 frame F. FACE_ID specifies what line's height to estimate. */
1483 estimate_mode_line_height (f
, face_id
)
1485 enum face_id face_id
;
1487 #ifdef HAVE_WINDOW_SYSTEM
1488 if (FRAME_WINDOW_P (f
))
1490 int height
= FONT_HEIGHT (FRAME_FONT (f
));
1492 /* This function is called so early when Emacs starts that the face
1493 cache and mode line face are not yet initialized. */
1494 if (FRAME_FACE_CACHE (f
))
1496 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1500 height
= FONT_HEIGHT (face
->font
);
1501 if (face
->box_line_width
> 0)
1502 height
+= 2 * face
->box_line_width
;
1513 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1514 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1515 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1516 not force the value into range. */
1519 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
, noclip
)
1521 register int pix_x
, pix_y
;
1523 NativeRectangle
*bounds
;
1527 #ifdef HAVE_WINDOW_SYSTEM
1528 if (FRAME_WINDOW_P (f
))
1530 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1531 even for negative values. */
1533 pix_x
-= FRAME_COLUMN_WIDTH (f
) - 1;
1535 pix_y
-= FRAME_LINE_HEIGHT (f
) - 1;
1537 pix_x
= FRAME_PIXEL_X_TO_COL (f
, pix_x
);
1538 pix_y
= FRAME_PIXEL_Y_TO_LINE (f
, pix_y
);
1541 STORE_NATIVE_RECT (*bounds
,
1542 FRAME_COL_TO_PIXEL_X (f
, pix_x
),
1543 FRAME_LINE_TO_PIXEL_Y (f
, pix_y
),
1544 FRAME_COLUMN_WIDTH (f
) - 1,
1545 FRAME_LINE_HEIGHT (f
) - 1);
1551 else if (pix_x
> FRAME_TOTAL_COLS (f
))
1552 pix_x
= FRAME_TOTAL_COLS (f
);
1556 else if (pix_y
> FRAME_LINES (f
))
1557 pix_y
= FRAME_LINES (f
);
1567 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1568 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1569 can't tell the positions because W's display is not up to date,
1573 glyph_to_pixel_coords (w
, hpos
, vpos
, frame_x
, frame_y
)
1576 int *frame_x
, *frame_y
;
1578 #ifdef HAVE_WINDOW_SYSTEM
1579 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w
))))
1583 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
1584 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
1586 if (display_completed
)
1588 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
1589 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
1590 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
1596 hpos
+= glyph
->pixel_width
;
1600 /* If first glyph is partially visible, its first visible position is still 0. */
1612 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, hpos
);
1613 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, vpos
);
1624 #ifdef HAVE_WINDOW_SYSTEM
1626 /* Find the glyph under window-relative coordinates X/Y in window W.
1627 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1628 strings. Return in *HPOS and *VPOS the row and column number of
1629 the glyph found. Return in *AREA the glyph area containing X.
1630 Value is a pointer to the glyph found or null if X/Y is not on
1631 text, or we can't tell because W's current matrix is not up to
1634 static struct glyph
*
1635 x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, dx
, dy
, area
)
1638 int *hpos
, *vpos
, *dx
, *dy
, *area
;
1640 struct glyph
*glyph
, *end
;
1641 struct glyph_row
*row
= NULL
;
1644 /* Find row containing Y. Give up if some row is not enabled. */
1645 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
1647 row
= MATRIX_ROW (w
->current_matrix
, i
);
1648 if (!row
->enabled_p
)
1650 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
1657 /* Give up if Y is not in the window. */
1658 if (i
== w
->current_matrix
->nrows
)
1661 /* Get the glyph area containing X. */
1662 if (w
->pseudo_window_p
)
1669 if (x
< window_box_left_offset (w
, TEXT_AREA
))
1671 *area
= LEFT_MARGIN_AREA
;
1672 x0
= window_box_left_offset (w
, LEFT_MARGIN_AREA
);
1674 else if (x
< window_box_right_offset (w
, TEXT_AREA
))
1677 x0
= window_box_left_offset (w
, TEXT_AREA
) + min (row
->x
, 0);
1681 *area
= RIGHT_MARGIN_AREA
;
1682 x0
= window_box_left_offset (w
, RIGHT_MARGIN_AREA
);
1686 /* Find glyph containing X. */
1687 glyph
= row
->glyphs
[*area
];
1688 end
= glyph
+ row
->used
[*area
];
1690 while (glyph
< end
&& x
>= glyph
->pixel_width
)
1692 x
-= glyph
->pixel_width
;
1702 *dy
= y
- (row
->y
+ row
->ascent
- glyph
->ascent
);
1705 *hpos
= glyph
- row
->glyphs
[*area
];
1711 Convert frame-relative x/y to coordinates relative to window W.
1712 Takes pseudo-windows into account. */
1715 frame_to_window_pixel_xy (w
, x
, y
)
1719 if (w
->pseudo_window_p
)
1721 /* A pseudo-window is always full-width, and starts at the
1722 left edge of the frame, plus a frame border. */
1723 struct frame
*f
= XFRAME (w
->frame
);
1724 *x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
1725 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
1729 *x
-= WINDOW_LEFT_EDGE_X (w
);
1730 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
1735 Return in *R the clipping rectangle for glyph string S. */
1738 get_glyph_string_clip_rect (s
, nr
)
1739 struct glyph_string
*s
;
1740 NativeRectangle
*nr
;
1744 if (s
->row
->full_width_p
)
1746 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1747 r
.x
= WINDOW_LEFT_EDGE_X (s
->w
);
1748 r
.width
= WINDOW_TOTAL_WIDTH (s
->w
);
1750 /* Unless displaying a mode or menu bar line, which are always
1751 fully visible, clip to the visible part of the row. */
1752 if (s
->w
->pseudo_window_p
)
1753 r
.height
= s
->row
->visible_height
;
1755 r
.height
= s
->height
;
1759 /* This is a text line that may be partially visible. */
1760 r
.x
= window_box_left (s
->w
, s
->area
);
1761 r
.width
= window_box_width (s
->w
, s
->area
);
1762 r
.height
= s
->row
->visible_height
;
1765 /* If S draws overlapping rows, it's sufficient to use the top and
1766 bottom of the window for clipping because this glyph string
1767 intentionally draws over other lines. */
1768 if (s
->for_overlaps_p
)
1770 r
.y
= WINDOW_HEADER_LINE_HEIGHT (s
->w
);
1771 r
.height
= window_text_bottom_y (s
->w
) - r
.y
;
1775 /* Don't use S->y for clipping because it doesn't take partially
1776 visible lines into account. For example, it can be negative for
1777 partially visible lines at the top of a window. */
1778 if (!s
->row
->full_width_p
1779 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
1780 r
.y
= WINDOW_HEADER_LINE_HEIGHT (s
->w
);
1782 r
.y
= max (0, s
->row
->y
);
1784 /* If drawing a tool-bar window, draw it over the internal border
1785 at the top of the window. */
1786 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
1787 r
.y
-= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
1790 r
.y
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
.y
);
1792 /* If drawing the cursor, don't let glyph draw outside its
1793 advertised boundaries. Cleartype does this under some circumstances. */
1794 if (s
->hl
== DRAW_CURSOR
)
1796 struct glyph
*glyph
= s
->first_glyph
;
1801 r
.width
-= s
->x
- r
.x
;
1804 r
.width
= min (r
.width
, glyph
->pixel_width
);
1806 /* Don't draw cursor glyph taller than our actual glyph. */
1807 height
= max (FRAME_LINE_HEIGHT (s
->f
), glyph
->ascent
+ glyph
->descent
);
1808 if (height
< r
.height
)
1810 int max_y
= r
.y
+ r
.height
;
1811 r
.y
= min (max_y
, s
->ybase
+ glyph
->descent
- height
);
1812 r
.height
= min (max_y
- r
.y
, height
);
1816 #ifdef CONVERT_FROM_XRECT
1817 CONVERT_FROM_XRECT (r
, *nr
);
1823 #endif /* HAVE_WINDOW_SYSTEM */
1826 /***********************************************************************
1827 Lisp form evaluation
1828 ***********************************************************************/
1830 /* Error handler for safe_eval and safe_call. */
1833 safe_eval_handler (arg
)
1836 add_to_log ("Error during redisplay: %s", arg
, Qnil
);
1841 /* Evaluate SEXPR and return the result, or nil if something went
1842 wrong. Prevent redisplay during the evaluation. */
1850 if (inhibit_eval_during_redisplay
)
1854 int count
= SPECPDL_INDEX ();
1855 struct gcpro gcpro1
;
1858 specbind (Qinhibit_redisplay
, Qt
);
1859 /* Use Qt to ensure debugger does not run,
1860 so there is no possibility of wanting to redisplay. */
1861 val
= internal_condition_case_1 (Feval
, sexpr
, Qt
,
1864 val
= unbind_to (count
, val
);
1871 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
1872 Return the result, or nil if something went wrong. Prevent
1873 redisplay during the evaluation. */
1876 safe_call (nargs
, args
)
1882 if (inhibit_eval_during_redisplay
)
1886 int count
= SPECPDL_INDEX ();
1887 struct gcpro gcpro1
;
1890 gcpro1
.nvars
= nargs
;
1891 specbind (Qinhibit_redisplay
, Qt
);
1892 /* Use Qt to ensure debugger does not run,
1893 so there is no possibility of wanting to redisplay. */
1894 val
= internal_condition_case_2 (Ffuncall
, nargs
, args
, Qt
,
1897 val
= unbind_to (count
, val
);
1904 /* Call function FN with one argument ARG.
1905 Return the result, or nil if something went wrong. */
1908 safe_call1 (fn
, arg
)
1909 Lisp_Object fn
, arg
;
1911 Lisp_Object args
[2];
1914 return safe_call (2, args
);
1919 /***********************************************************************
1921 ***********************************************************************/
1925 /* Define CHECK_IT to perform sanity checks on iterators.
1926 This is for debugging. It is too slow to do unconditionally. */
1932 if (it
->method
== next_element_from_string
)
1934 xassert (STRINGP (it
->string
));
1935 xassert (IT_STRING_CHARPOS (*it
) >= 0);
1939 xassert (IT_STRING_CHARPOS (*it
) < 0);
1940 if (it
->method
== next_element_from_buffer
)
1942 /* Check that character and byte positions agree. */
1943 xassert (IT_CHARPOS (*it
) == BYTE_TO_CHAR (IT_BYTEPOS (*it
)));
1948 xassert (it
->current
.dpvec_index
>= 0);
1950 xassert (it
->current
.dpvec_index
< 0);
1953 #define CHECK_IT(IT) check_it ((IT))
1957 #define CHECK_IT(IT) (void) 0
1964 /* Check that the window end of window W is what we expect it
1965 to be---the last row in the current matrix displaying text. */
1968 check_window_end (w
)
1971 if (!MINI_WINDOW_P (w
)
1972 && !NILP (w
->window_end_valid
))
1974 struct glyph_row
*row
;
1975 xassert ((row
= MATRIX_ROW (w
->current_matrix
,
1976 XFASTINT (w
->window_end_vpos
)),
1978 || MATRIX_ROW_DISPLAYS_TEXT_P (row
)
1979 || MATRIX_ROW_VPOS (row
, w
->current_matrix
) == 0));
1983 #define CHECK_WINDOW_END(W) check_window_end ((W))
1985 #else /* not GLYPH_DEBUG */
1987 #define CHECK_WINDOW_END(W) (void) 0
1989 #endif /* not GLYPH_DEBUG */
1993 /***********************************************************************
1994 Iterator initialization
1995 ***********************************************************************/
1997 /* Initialize IT for displaying current_buffer in window W, starting
1998 at character position CHARPOS. CHARPOS < 0 means that no buffer
1999 position is specified which is useful when the iterator is assigned
2000 a position later. BYTEPOS is the byte position corresponding to
2001 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2003 If ROW is not null, calls to produce_glyphs with IT as parameter
2004 will produce glyphs in that row.
2006 BASE_FACE_ID is the id of a base face to use. It must be one of
2007 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2008 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2009 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2011 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2012 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2013 will be initialized to use the corresponding mode line glyph row of
2014 the desired matrix of W. */
2017 init_iterator (it
, w
, charpos
, bytepos
, row
, base_face_id
)
2020 int charpos
, bytepos
;
2021 struct glyph_row
*row
;
2022 enum face_id base_face_id
;
2024 int highlight_region_p
;
2026 /* Some precondition checks. */
2027 xassert (w
!= NULL
&& it
!= NULL
);
2028 xassert (charpos
< 0 || (charpos
>= BUF_BEG (current_buffer
)
2031 /* If face attributes have been changed since the last redisplay,
2032 free realized faces now because they depend on face definitions
2033 that might have changed. Don't free faces while there might be
2034 desired matrices pending which reference these faces. */
2035 if (face_change_count
&& !inhibit_free_realized_faces
)
2037 face_change_count
= 0;
2038 free_all_realized_faces (Qnil
);
2041 /* Use one of the mode line rows of W's desired matrix if
2045 if (base_face_id
== MODE_LINE_FACE_ID
2046 || base_face_id
== MODE_LINE_INACTIVE_FACE_ID
)
2047 row
= MATRIX_MODE_LINE_ROW (w
->desired_matrix
);
2048 else if (base_face_id
== HEADER_LINE_FACE_ID
)
2049 row
= MATRIX_HEADER_LINE_ROW (w
->desired_matrix
);
2053 bzero (it
, sizeof *it
);
2054 it
->current
.overlay_string_index
= -1;
2055 it
->current
.dpvec_index
= -1;
2056 it
->base_face_id
= base_face_id
;
2058 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = -1;
2060 /* The window in which we iterate over current_buffer: */
2061 XSETWINDOW (it
->window
, w
);
2063 it
->f
= XFRAME (w
->frame
);
2065 /* Extra space between lines (on window systems only). */
2066 if (base_face_id
== DEFAULT_FACE_ID
2067 && FRAME_WINDOW_P (it
->f
))
2069 if (NATNUMP (current_buffer
->extra_line_spacing
))
2070 it
->extra_line_spacing
= XFASTINT (current_buffer
->extra_line_spacing
);
2071 else if (FLOATP (current_buffer
->extra_line_spacing
))
2072 it
->extra_line_spacing
= (XFLOAT_DATA (current_buffer
->extra_line_spacing
)
2073 * FRAME_LINE_HEIGHT (it
->f
));
2074 else if (it
->f
->extra_line_spacing
> 0)
2075 it
->extra_line_spacing
= it
->f
->extra_line_spacing
;
2078 /* If realized faces have been removed, e.g. because of face
2079 attribute changes of named faces, recompute them. When running
2080 in batch mode, the face cache of Vterminal_frame is null. If
2081 we happen to get called, make a dummy face cache. */
2082 if (noninteractive
&& FRAME_FACE_CACHE (it
->f
) == NULL
)
2083 init_frame_faces (it
->f
);
2084 if (FRAME_FACE_CACHE (it
->f
)->used
== 0)
2085 recompute_basic_faces (it
->f
);
2087 /* Current value of the `slice', `space-width', and 'height' properties. */
2088 it
->slice
.x
= it
->slice
.y
= it
->slice
.width
= it
->slice
.height
= Qnil
;
2089 it
->space_width
= Qnil
;
2090 it
->font_height
= Qnil
;
2091 it
->override_ascent
= -1;
2093 /* Are control characters displayed as `^C'? */
2094 it
->ctl_arrow_p
= !NILP (current_buffer
->ctl_arrow
);
2096 /* -1 means everything between a CR and the following line end
2097 is invisible. >0 means lines indented more than this value are
2099 it
->selective
= (INTEGERP (current_buffer
->selective_display
)
2100 ? XFASTINT (current_buffer
->selective_display
)
2101 : (!NILP (current_buffer
->selective_display
)
2103 it
->selective_display_ellipsis_p
2104 = !NILP (current_buffer
->selective_display_ellipses
);
2106 /* Display table to use. */
2107 it
->dp
= window_display_table (w
);
2109 /* Are multibyte characters enabled in current_buffer? */
2110 it
->multibyte_p
= !NILP (current_buffer
->enable_multibyte_characters
);
2112 /* Non-zero if we should highlight the region. */
2114 = (!NILP (Vtransient_mark_mode
)
2115 && !NILP (current_buffer
->mark_active
)
2116 && XMARKER (current_buffer
->mark
)->buffer
!= 0);
2118 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2119 start and end of a visible region in window IT->w. Set both to
2120 -1 to indicate no region. */
2121 if (highlight_region_p
2122 /* Maybe highlight only in selected window. */
2123 && (/* Either show region everywhere. */
2124 highlight_nonselected_windows
2125 /* Or show region in the selected window. */
2126 || w
== XWINDOW (selected_window
)
2127 /* Or show the region if we are in the mini-buffer and W is
2128 the window the mini-buffer refers to. */
2129 || (MINI_WINDOW_P (XWINDOW (selected_window
))
2130 && WINDOWP (minibuf_selected_window
)
2131 && w
== XWINDOW (minibuf_selected_window
))))
2133 int charpos
= marker_position (current_buffer
->mark
);
2134 it
->region_beg_charpos
= min (PT
, charpos
);
2135 it
->region_end_charpos
= max (PT
, charpos
);
2138 it
->region_beg_charpos
= it
->region_end_charpos
= -1;
2140 /* Get the position at which the redisplay_end_trigger hook should
2141 be run, if it is to be run at all. */
2142 if (MARKERP (w
->redisplay_end_trigger
)
2143 && XMARKER (w
->redisplay_end_trigger
)->buffer
!= 0)
2144 it
->redisplay_end_trigger_charpos
2145 = marker_position (w
->redisplay_end_trigger
);
2146 else if (INTEGERP (w
->redisplay_end_trigger
))
2147 it
->redisplay_end_trigger_charpos
= XINT (w
->redisplay_end_trigger
);
2149 /* Correct bogus values of tab_width. */
2150 it
->tab_width
= XINT (current_buffer
->tab_width
);
2151 if (it
->tab_width
<= 0 || it
->tab_width
> 1000)
2154 /* Are lines in the display truncated? */
2155 it
->truncate_lines_p
2156 = (base_face_id
!= DEFAULT_FACE_ID
2157 || XINT (it
->w
->hscroll
)
2158 || (truncate_partial_width_windows
2159 && !WINDOW_FULL_WIDTH_P (it
->w
))
2160 || !NILP (current_buffer
->truncate_lines
));
2162 /* Get dimensions of truncation and continuation glyphs. These are
2163 displayed as fringe bitmaps under X, so we don't need them for such
2165 if (!FRAME_WINDOW_P (it
->f
))
2167 if (it
->truncate_lines_p
)
2169 /* We will need the truncation glyph. */
2170 xassert (it
->glyph_row
== NULL
);
2171 produce_special_glyphs (it
, IT_TRUNCATION
);
2172 it
->truncation_pixel_width
= it
->pixel_width
;
2176 /* We will need the continuation glyph. */
2177 xassert (it
->glyph_row
== NULL
);
2178 produce_special_glyphs (it
, IT_CONTINUATION
);
2179 it
->continuation_pixel_width
= it
->pixel_width
;
2182 /* Reset these values to zero because the produce_special_glyphs
2183 above has changed them. */
2184 it
->pixel_width
= it
->ascent
= it
->descent
= 0;
2185 it
->phys_ascent
= it
->phys_descent
= 0;
2188 /* Set this after getting the dimensions of truncation and
2189 continuation glyphs, so that we don't produce glyphs when calling
2190 produce_special_glyphs, above. */
2191 it
->glyph_row
= row
;
2192 it
->area
= TEXT_AREA
;
2194 /* Get the dimensions of the display area. The display area
2195 consists of the visible window area plus a horizontally scrolled
2196 part to the left of the window. All x-values are relative to the
2197 start of this total display area. */
2198 if (base_face_id
!= DEFAULT_FACE_ID
)
2200 /* Mode lines, menu bar in terminal frames. */
2201 it
->first_visible_x
= 0;
2202 it
->last_visible_x
= WINDOW_TOTAL_WIDTH (w
);
2207 = XFASTINT (it
->w
->hscroll
) * FRAME_COLUMN_WIDTH (it
->f
);
2208 it
->last_visible_x
= (it
->first_visible_x
2209 + window_box_width (w
, TEXT_AREA
));
2211 /* If we truncate lines, leave room for the truncator glyph(s) at
2212 the right margin. Otherwise, leave room for the continuation
2213 glyph(s). Truncation and continuation glyphs are not inserted
2214 for window-based redisplay. */
2215 if (!FRAME_WINDOW_P (it
->f
))
2217 if (it
->truncate_lines_p
)
2218 it
->last_visible_x
-= it
->truncation_pixel_width
;
2220 it
->last_visible_x
-= it
->continuation_pixel_width
;
2223 it
->header_line_p
= WINDOW_WANTS_HEADER_LINE_P (w
);
2224 it
->current_y
= WINDOW_HEADER_LINE_HEIGHT (w
) + w
->vscroll
;
2227 /* Leave room for a border glyph. */
2228 if (!FRAME_WINDOW_P (it
->f
)
2229 && !WINDOW_RIGHTMOST_P (it
->w
))
2230 it
->last_visible_x
-= 1;
2232 it
->last_visible_y
= window_text_bottom_y (w
);
2234 /* For mode lines and alike, arrange for the first glyph having a
2235 left box line if the face specifies a box. */
2236 if (base_face_id
!= DEFAULT_FACE_ID
)
2240 it
->face_id
= base_face_id
;
2242 /* If we have a boxed mode line, make the first character appear
2243 with a left box line. */
2244 face
= FACE_FROM_ID (it
->f
, base_face_id
);
2245 if (face
->box
!= FACE_NO_BOX
)
2246 it
->start_of_box_run_p
= 1;
2249 /* If a buffer position was specified, set the iterator there,
2250 getting overlays and face properties from that position. */
2251 if (charpos
>= BUF_BEG (current_buffer
))
2253 it
->end_charpos
= ZV
;
2255 IT_CHARPOS (*it
) = charpos
;
2257 /* Compute byte position if not specified. */
2258 if (bytepos
< charpos
)
2259 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (charpos
);
2261 IT_BYTEPOS (*it
) = bytepos
;
2263 it
->start
= it
->current
;
2265 /* Compute faces etc. */
2266 reseat (it
, it
->current
.pos
, 1);
2273 /* Initialize IT for the display of window W with window start POS. */
2276 start_display (it
, w
, pos
)
2279 struct text_pos pos
;
2281 struct glyph_row
*row
;
2282 int first_vpos
= WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0;
2284 row
= w
->desired_matrix
->rows
+ first_vpos
;
2285 init_iterator (it
, w
, CHARPOS (pos
), BYTEPOS (pos
), row
, DEFAULT_FACE_ID
);
2286 it
->first_vpos
= first_vpos
;
2288 if (!it
->truncate_lines_p
)
2290 int start_at_line_beg_p
;
2291 int first_y
= it
->current_y
;
2293 /* If window start is not at a line start, skip forward to POS to
2294 get the correct continuation lines width. */
2295 start_at_line_beg_p
= (CHARPOS (pos
) == BEGV
2296 || FETCH_BYTE (BYTEPOS (pos
) - 1) == '\n');
2297 if (!start_at_line_beg_p
)
2301 reseat_at_previous_visible_line_start (it
);
2302 move_it_to (it
, CHARPOS (pos
), -1, -1, -1, MOVE_TO_POS
);
2304 new_x
= it
->current_x
+ it
->pixel_width
;
2306 /* If lines are continued, this line may end in the middle
2307 of a multi-glyph character (e.g. a control character
2308 displayed as \003, or in the middle of an overlay
2309 string). In this case move_it_to above will not have
2310 taken us to the start of the continuation line but to the
2311 end of the continued line. */
2312 if (it
->current_x
> 0
2313 && !it
->truncate_lines_p
/* Lines are continued. */
2314 && (/* And glyph doesn't fit on the line. */
2315 new_x
> it
->last_visible_x
2316 /* Or it fits exactly and we're on a window
2318 || (new_x
== it
->last_visible_x
2319 && FRAME_WINDOW_P (it
->f
))))
2321 if (it
->current
.dpvec_index
>= 0
2322 || it
->current
.overlay_string_index
>= 0)
2324 set_iterator_to_next (it
, 1);
2325 move_it_in_display_line_to (it
, -1, -1, 0);
2328 it
->continuation_lines_width
+= it
->current_x
;
2331 /* We're starting a new display line, not affected by the
2332 height of the continued line, so clear the appropriate
2333 fields in the iterator structure. */
2334 it
->max_ascent
= it
->max_descent
= 0;
2335 it
->max_phys_ascent
= it
->max_phys_descent
= 0;
2337 it
->current_y
= first_y
;
2339 it
->current_x
= it
->hpos
= 0;
2343 #if 0 /* Don't assert the following because start_display is sometimes
2344 called intentionally with a window start that is not at a
2345 line start. Please leave this code in as a comment. */
2347 /* Window start should be on a line start, now. */
2348 xassert (it
->continuation_lines_width
2349 || IT_CHARPOS (it
) == BEGV
2350 || FETCH_BYTE (IT_BYTEPOS (it
) - 1) == '\n');
2355 /* Return 1 if POS is a position in ellipses displayed for invisible
2356 text. W is the window we display, for text property lookup. */
2359 in_ellipses_for_invisible_text_p (pos
, w
)
2360 struct display_pos
*pos
;
2363 Lisp_Object prop
, window
;
2365 int charpos
= CHARPOS (pos
->pos
);
2367 /* If POS specifies a position in a display vector, this might
2368 be for an ellipsis displayed for invisible text. We won't
2369 get the iterator set up for delivering that ellipsis unless
2370 we make sure that it gets aware of the invisible text. */
2371 if (pos
->dpvec_index
>= 0
2372 && pos
->overlay_string_index
< 0
2373 && CHARPOS (pos
->string_pos
) < 0
2375 && (XSETWINDOW (window
, w
),
2376 prop
= Fget_char_property (make_number (charpos
),
2377 Qinvisible
, window
),
2378 !TEXT_PROP_MEANS_INVISIBLE (prop
)))
2380 prop
= Fget_char_property (make_number (charpos
- 1), Qinvisible
,
2382 ellipses_p
= 2 == TEXT_PROP_MEANS_INVISIBLE (prop
);
2389 /* Initialize IT for stepping through current_buffer in window W,
2390 starting at position POS that includes overlay string and display
2391 vector/ control character translation position information. Value
2392 is zero if there are overlay strings with newlines at POS. */
2395 init_from_display_pos (it
, w
, pos
)
2398 struct display_pos
*pos
;
2400 int charpos
= CHARPOS (pos
->pos
), bytepos
= BYTEPOS (pos
->pos
);
2401 int i
, overlay_strings_with_newlines
= 0;
2403 /* If POS specifies a position in a display vector, this might
2404 be for an ellipsis displayed for invisible text. We won't
2405 get the iterator set up for delivering that ellipsis unless
2406 we make sure that it gets aware of the invisible text. */
2407 if (in_ellipses_for_invisible_text_p (pos
, w
))
2413 /* Keep in mind: the call to reseat in init_iterator skips invisible
2414 text, so we might end up at a position different from POS. This
2415 is only a problem when POS is a row start after a newline and an
2416 overlay starts there with an after-string, and the overlay has an
2417 invisible property. Since we don't skip invisible text in
2418 display_line and elsewhere immediately after consuming the
2419 newline before the row start, such a POS will not be in a string,
2420 but the call to init_iterator below will move us to the
2422 init_iterator (it
, w
, charpos
, bytepos
, NULL
, DEFAULT_FACE_ID
);
2424 for (i
= 0; i
< it
->n_overlay_strings
; ++i
)
2426 const char *s
= SDATA (it
->overlay_strings
[i
]);
2427 const char *e
= s
+ SBYTES (it
->overlay_strings
[i
]);
2429 while (s
< e
&& *s
!= '\n')
2434 overlay_strings_with_newlines
= 1;
2439 /* If position is within an overlay string, set up IT to the right
2441 if (pos
->overlay_string_index
>= 0)
2445 /* If the first overlay string happens to have a `display'
2446 property for an image, the iterator will be set up for that
2447 image, and we have to undo that setup first before we can
2448 correct the overlay string index. */
2449 if (it
->method
== next_element_from_image
)
2452 /* We already have the first chunk of overlay strings in
2453 IT->overlay_strings. Load more until the one for
2454 pos->overlay_string_index is in IT->overlay_strings. */
2455 if (pos
->overlay_string_index
>= OVERLAY_STRING_CHUNK_SIZE
)
2457 int n
= pos
->overlay_string_index
/ OVERLAY_STRING_CHUNK_SIZE
;
2458 it
->current
.overlay_string_index
= 0;
2461 load_overlay_strings (it
, 0);
2462 it
->current
.overlay_string_index
+= OVERLAY_STRING_CHUNK_SIZE
;
2466 it
->current
.overlay_string_index
= pos
->overlay_string_index
;
2467 relative_index
= (it
->current
.overlay_string_index
2468 % OVERLAY_STRING_CHUNK_SIZE
);
2469 it
->string
= it
->overlay_strings
[relative_index
];
2470 xassert (STRINGP (it
->string
));
2471 it
->current
.string_pos
= pos
->string_pos
;
2472 it
->method
= next_element_from_string
;
2475 #if 0 /* This is bogus because POS not having an overlay string
2476 position does not mean it's after the string. Example: A
2477 line starting with a before-string and initialization of IT
2478 to the previous row's end position. */
2479 else if (it
->current
.overlay_string_index
>= 0)
2481 /* If POS says we're already after an overlay string ending at
2482 POS, make sure to pop the iterator because it will be in
2483 front of that overlay string. When POS is ZV, we've thereby
2484 also ``processed'' overlay strings at ZV. */
2487 it
->current
.overlay_string_index
= -1;
2488 it
->method
= next_element_from_buffer
;
2489 if (CHARPOS (pos
->pos
) == ZV
)
2490 it
->overlay_strings_at_end_processed_p
= 1;
2494 if (CHARPOS (pos
->string_pos
) >= 0)
2496 /* Recorded position is not in an overlay string, but in another
2497 string. This can only be a string from a `display' property.
2498 IT should already be filled with that string. */
2499 it
->current
.string_pos
= pos
->string_pos
;
2500 xassert (STRINGP (it
->string
));
2503 /* Restore position in display vector translations, control
2504 character translations or ellipses. */
2505 if (pos
->dpvec_index
>= 0)
2507 if (it
->dpvec
== NULL
)
2508 get_next_display_element (it
);
2509 xassert (it
->dpvec
&& it
->current
.dpvec_index
== 0);
2510 it
->current
.dpvec_index
= pos
->dpvec_index
;
2514 return !overlay_strings_with_newlines
;
2518 /* Initialize IT for stepping through current_buffer in window W
2519 starting at ROW->start. */
2522 init_to_row_start (it
, w
, row
)
2525 struct glyph_row
*row
;
2527 init_from_display_pos (it
, w
, &row
->start
);
2528 it
->start
= row
->start
;
2529 it
->continuation_lines_width
= row
->continuation_lines_width
;
2534 /* Initialize IT for stepping through current_buffer in window W
2535 starting in the line following ROW, i.e. starting at ROW->end.
2536 Value is zero if there are overlay strings with newlines at ROW's
2540 init_to_row_end (it
, w
, row
)
2543 struct glyph_row
*row
;
2547 if (init_from_display_pos (it
, w
, &row
->end
))
2549 if (row
->continued_p
)
2550 it
->continuation_lines_width
2551 = row
->continuation_lines_width
+ row
->pixel_width
;
2562 /***********************************************************************
2564 ***********************************************************************/
2566 /* Called when IT reaches IT->stop_charpos. Handle text property and
2567 overlay changes. Set IT->stop_charpos to the next position where
2574 enum prop_handled handled
;
2575 int handle_overlay_change_p
= 1;
2579 it
->current
.dpvec_index
= -1;
2583 handled
= HANDLED_NORMALLY
;
2585 /* Call text property handlers. */
2586 for (p
= it_props
; p
->handler
; ++p
)
2588 handled
= p
->handler (it
);
2590 if (handled
== HANDLED_RECOMPUTE_PROPS
)
2592 else if (handled
== HANDLED_RETURN
)
2594 else if (handled
== HANDLED_OVERLAY_STRING_CONSUMED
)
2595 handle_overlay_change_p
= 0;
2598 if (handled
!= HANDLED_RECOMPUTE_PROPS
)
2600 /* Don't check for overlay strings below when set to deliver
2601 characters from a display vector. */
2602 if (it
->method
== next_element_from_display_vector
)
2603 handle_overlay_change_p
= 0;
2605 /* Handle overlay changes. */
2606 if (handle_overlay_change_p
)
2607 handled
= handle_overlay_change (it
);
2609 /* Determine where to stop next. */
2610 if (handled
== HANDLED_NORMALLY
)
2611 compute_stop_pos (it
);
2614 while (handled
== HANDLED_RECOMPUTE_PROPS
);
2618 /* Compute IT->stop_charpos from text property and overlay change
2619 information for IT's current position. */
2622 compute_stop_pos (it
)
2625 register INTERVAL iv
, next_iv
;
2626 Lisp_Object object
, limit
, position
;
2628 /* If nowhere else, stop at the end. */
2629 it
->stop_charpos
= it
->end_charpos
;
2631 if (STRINGP (it
->string
))
2633 /* Strings are usually short, so don't limit the search for
2635 object
= it
->string
;
2637 position
= make_number (IT_STRING_CHARPOS (*it
));
2643 /* If next overlay change is in front of the current stop pos
2644 (which is IT->end_charpos), stop there. Note: value of
2645 next_overlay_change is point-max if no overlay change
2647 charpos
= next_overlay_change (IT_CHARPOS (*it
));
2648 if (charpos
< it
->stop_charpos
)
2649 it
->stop_charpos
= charpos
;
2651 /* If showing the region, we have to stop at the region
2652 start or end because the face might change there. */
2653 if (it
->region_beg_charpos
> 0)
2655 if (IT_CHARPOS (*it
) < it
->region_beg_charpos
)
2656 it
->stop_charpos
= min (it
->stop_charpos
, it
->region_beg_charpos
);
2657 else if (IT_CHARPOS (*it
) < it
->region_end_charpos
)
2658 it
->stop_charpos
= min (it
->stop_charpos
, it
->region_end_charpos
);
2661 /* Set up variables for computing the stop position from text
2662 property changes. */
2663 XSETBUFFER (object
, current_buffer
);
2664 limit
= make_number (IT_CHARPOS (*it
) + TEXT_PROP_DISTANCE_LIMIT
);
2665 position
= make_number (IT_CHARPOS (*it
));
2669 /* Get the interval containing IT's position. Value is a null
2670 interval if there isn't such an interval. */
2671 iv
= validate_interval_range (object
, &position
, &position
, 0);
2672 if (!NULL_INTERVAL_P (iv
))
2674 Lisp_Object values_here
[LAST_PROP_IDX
];
2677 /* Get properties here. */
2678 for (p
= it_props
; p
->handler
; ++p
)
2679 values_here
[p
->idx
] = textget (iv
->plist
, *p
->name
);
2681 /* Look for an interval following iv that has different
2683 for (next_iv
= next_interval (iv
);
2684 (!NULL_INTERVAL_P (next_iv
)
2686 || XFASTINT (limit
) > next_iv
->position
));
2687 next_iv
= next_interval (next_iv
))
2689 for (p
= it_props
; p
->handler
; ++p
)
2691 Lisp_Object new_value
;
2693 new_value
= textget (next_iv
->plist
, *p
->name
);
2694 if (!EQ (values_here
[p
->idx
], new_value
))
2702 if (!NULL_INTERVAL_P (next_iv
))
2704 if (INTEGERP (limit
)
2705 && next_iv
->position
>= XFASTINT (limit
))
2706 /* No text property change up to limit. */
2707 it
->stop_charpos
= min (XFASTINT (limit
), it
->stop_charpos
);
2709 /* Text properties change in next_iv. */
2710 it
->stop_charpos
= min (it
->stop_charpos
, next_iv
->position
);
2714 xassert (STRINGP (it
->string
)
2715 || (it
->stop_charpos
>= BEGV
2716 && it
->stop_charpos
>= IT_CHARPOS (*it
)));
2720 /* Return the position of the next overlay change after POS in
2721 current_buffer. Value is point-max if no overlay change
2722 follows. This is like `next-overlay-change' but doesn't use
2726 next_overlay_change (pos
)
2731 Lisp_Object
*overlays
;
2734 /* Get all overlays at the given position. */
2735 GET_OVERLAYS_AT (pos
, overlays
, noverlays
, &endpos
, 1);
2737 /* If any of these overlays ends before endpos,
2738 use its ending point instead. */
2739 for (i
= 0; i
< noverlays
; ++i
)
2744 oend
= OVERLAY_END (overlays
[i
]);
2745 oendpos
= OVERLAY_POSITION (oend
);
2746 endpos
= min (endpos
, oendpos
);
2754 /***********************************************************************
2756 ***********************************************************************/
2758 /* Handle changes in the `fontified' property of the current buffer by
2759 calling hook functions from Qfontification_functions to fontify
2762 static enum prop_handled
2763 handle_fontified_prop (it
)
2766 Lisp_Object prop
, pos
;
2767 enum prop_handled handled
= HANDLED_NORMALLY
;
2769 /* Get the value of the `fontified' property at IT's current buffer
2770 position. (The `fontified' property doesn't have a special
2771 meaning in strings.) If the value is nil, call functions from
2772 Qfontification_functions. */
2773 if (!STRINGP (it
->string
)
2775 && !NILP (Vfontification_functions
)
2776 && !NILP (Vrun_hooks
)
2777 && (pos
= make_number (IT_CHARPOS (*it
)),
2778 prop
= Fget_char_property (pos
, Qfontified
, Qnil
),
2781 int count
= SPECPDL_INDEX ();
2784 val
= Vfontification_functions
;
2785 specbind (Qfontification_functions
, Qnil
);
2787 if (!CONSP (val
) || EQ (XCAR (val
), Qlambda
))
2788 safe_call1 (val
, pos
);
2791 Lisp_Object globals
, fn
;
2792 struct gcpro gcpro1
, gcpro2
;
2795 GCPRO2 (val
, globals
);
2797 for (; CONSP (val
); val
= XCDR (val
))
2803 /* A value of t indicates this hook has a local
2804 binding; it means to run the global binding too.
2805 In a global value, t should not occur. If it
2806 does, we must ignore it to avoid an endless
2808 for (globals
= Fdefault_value (Qfontification_functions
);
2810 globals
= XCDR (globals
))
2812 fn
= XCAR (globals
);
2814 safe_call1 (fn
, pos
);
2818 safe_call1 (fn
, pos
);
2824 unbind_to (count
, Qnil
);
2826 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
2827 something. This avoids an endless loop if they failed to
2828 fontify the text for which reason ever. */
2829 if (!NILP (Fget_char_property (pos
, Qfontified
, Qnil
)))
2830 handled
= HANDLED_RECOMPUTE_PROPS
;
2838 /***********************************************************************
2840 ***********************************************************************/
2842 /* Set up iterator IT from face properties at its current position.
2843 Called from handle_stop. */
2845 static enum prop_handled
2846 handle_face_prop (it
)
2849 int new_face_id
, next_stop
;
2851 if (!STRINGP (it
->string
))
2854 = face_at_buffer_position (it
->w
,
2856 it
->region_beg_charpos
,
2857 it
->region_end_charpos
,
2860 + TEXT_PROP_DISTANCE_LIMIT
),
2863 /* Is this a start of a run of characters with box face?
2864 Caveat: this can be called for a freshly initialized
2865 iterator; face_id is -1 in this case. We know that the new
2866 face will not change until limit, i.e. if the new face has a
2867 box, all characters up to limit will have one. But, as
2868 usual, we don't know whether limit is really the end. */
2869 if (new_face_id
!= it
->face_id
)
2871 struct face
*new_face
= FACE_FROM_ID (it
->f
, new_face_id
);
2873 /* If new face has a box but old face has not, this is
2874 the start of a run of characters with box, i.e. it has
2875 a shadow on the left side. The value of face_id of the
2876 iterator will be -1 if this is the initial call that gets
2877 the face. In this case, we have to look in front of IT's
2878 position and see whether there is a face != new_face_id. */
2879 it
->start_of_box_run_p
2880 = (new_face
->box
!= FACE_NO_BOX
2881 && (it
->face_id
>= 0
2882 || IT_CHARPOS (*it
) == BEG
2883 || new_face_id
!= face_before_it_pos (it
)));
2884 it
->face_box_p
= new_face
->box
!= FACE_NO_BOX
;
2889 int base_face_id
, bufpos
;
2891 if (it
->current
.overlay_string_index
>= 0)
2892 bufpos
= IT_CHARPOS (*it
);
2896 /* For strings from a buffer, i.e. overlay strings or strings
2897 from a `display' property, use the face at IT's current
2898 buffer position as the base face to merge with, so that
2899 overlay strings appear in the same face as surrounding
2900 text, unless they specify their own faces. */
2901 base_face_id
= underlying_face_id (it
);
2903 new_face_id
= face_at_string_position (it
->w
,
2905 IT_STRING_CHARPOS (*it
),
2907 it
->region_beg_charpos
,
2908 it
->region_end_charpos
,
2912 #if 0 /* This shouldn't be neccessary. Let's check it. */
2913 /* If IT is used to display a mode line we would really like to
2914 use the mode line face instead of the frame's default face. */
2915 if (it
->glyph_row
== MATRIX_MODE_LINE_ROW (it
->w
->desired_matrix
)
2916 && new_face_id
== DEFAULT_FACE_ID
)
2917 new_face_id
= CURRENT_MODE_LINE_FACE_ID (it
->w
);
2920 /* Is this a start of a run of characters with box? Caveat:
2921 this can be called for a freshly allocated iterator; face_id
2922 is -1 is this case. We know that the new face will not
2923 change until the next check pos, i.e. if the new face has a
2924 box, all characters up to that position will have a
2925 box. But, as usual, we don't know whether that position
2926 is really the end. */
2927 if (new_face_id
!= it
->face_id
)
2929 struct face
*new_face
= FACE_FROM_ID (it
->f
, new_face_id
);
2930 struct face
*old_face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2932 /* If new face has a box but old face hasn't, this is the
2933 start of a run of characters with box, i.e. it has a
2934 shadow on the left side. */
2935 it
->start_of_box_run_p
2936 = new_face
->box
&& (old_face
== NULL
|| !old_face
->box
);
2937 it
->face_box_p
= new_face
->box
!= FACE_NO_BOX
;
2941 it
->face_id
= new_face_id
;
2942 return HANDLED_NORMALLY
;
2946 /* Return the ID of the face ``underlying'' IT's current position,
2947 which is in a string. If the iterator is associated with a
2948 buffer, return the face at IT's current buffer position.
2949 Otherwise, use the iterator's base_face_id. */
2952 underlying_face_id (it
)
2955 int face_id
= it
->base_face_id
, i
;
2957 xassert (STRINGP (it
->string
));
2959 for (i
= it
->sp
- 1; i
>= 0; --i
)
2960 if (NILP (it
->stack
[i
].string
))
2961 face_id
= it
->stack
[i
].face_id
;
2967 /* Compute the face one character before or after the current position
2968 of IT. BEFORE_P non-zero means get the face in front of IT's
2969 position. Value is the id of the face. */
2972 face_before_or_after_it_pos (it
, before_p
)
2977 int next_check_charpos
;
2978 struct text_pos pos
;
2980 xassert (it
->s
== NULL
);
2982 if (STRINGP (it
->string
))
2984 int bufpos
, base_face_id
;
2986 /* No face change past the end of the string (for the case
2987 we are padding with spaces). No face change before the
2989 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
)
2990 || (IT_STRING_CHARPOS (*it
) == 0 && before_p
))
2993 /* Set pos to the position before or after IT's current position. */
2995 pos
= string_pos (IT_STRING_CHARPOS (*it
) - 1, it
->string
);
2997 /* For composition, we must check the character after the
2999 pos
= (it
->what
== IT_COMPOSITION
3000 ? string_pos (IT_STRING_CHARPOS (*it
) + it
->cmp_len
, it
->string
)
3001 : string_pos (IT_STRING_CHARPOS (*it
) + 1, it
->string
));
3003 if (it
->current
.overlay_string_index
>= 0)
3004 bufpos
= IT_CHARPOS (*it
);
3008 base_face_id
= underlying_face_id (it
);
3010 /* Get the face for ASCII, or unibyte. */
3011 face_id
= face_at_string_position (it
->w
,
3015 it
->region_beg_charpos
,
3016 it
->region_end_charpos
,
3017 &next_check_charpos
,
3020 /* Correct the face for charsets different from ASCII. Do it
3021 for the multibyte case only. The face returned above is
3022 suitable for unibyte text if IT->string is unibyte. */
3023 if (STRING_MULTIBYTE (it
->string
))
3025 const unsigned char *p
= SDATA (it
->string
) + BYTEPOS (pos
);
3026 int rest
= SBYTES (it
->string
) - BYTEPOS (pos
);
3028 struct face
*face
= FACE_FROM_ID (it
->f
, face_id
);
3030 c
= string_char_and_length (p
, rest
, &len
);
3031 face_id
= FACE_FOR_CHAR (it
->f
, face
, c
);
3036 if ((IT_CHARPOS (*it
) >= ZV
&& !before_p
)
3037 || (IT_CHARPOS (*it
) <= BEGV
&& before_p
))
3040 limit
= IT_CHARPOS (*it
) + TEXT_PROP_DISTANCE_LIMIT
;
3041 pos
= it
->current
.pos
;
3044 DEC_TEXT_POS (pos
, it
->multibyte_p
);
3047 if (it
->what
== IT_COMPOSITION
)
3048 /* For composition, we must check the position after the
3050 pos
.charpos
+= it
->cmp_len
, pos
.bytepos
+= it
->len
;
3052 INC_TEXT_POS (pos
, it
->multibyte_p
);
3055 /* Determine face for CHARSET_ASCII, or unibyte. */
3056 face_id
= face_at_buffer_position (it
->w
,
3058 it
->region_beg_charpos
,
3059 it
->region_end_charpos
,
3060 &next_check_charpos
,
3063 /* Correct the face for charsets different from ASCII. Do it
3064 for the multibyte case only. The face returned above is
3065 suitable for unibyte text if current_buffer is unibyte. */
3066 if (it
->multibyte_p
)
3068 int c
= FETCH_MULTIBYTE_CHAR (BYTEPOS (pos
));
3069 struct face
*face
= FACE_FROM_ID (it
->f
, face_id
);
3070 face_id
= FACE_FOR_CHAR (it
->f
, face
, c
);
3079 /***********************************************************************
3081 ***********************************************************************/
3083 /* Set up iterator IT from invisible properties at its current
3084 position. Called from handle_stop. */
3086 static enum prop_handled
3087 handle_invisible_prop (it
)
3090 enum prop_handled handled
= HANDLED_NORMALLY
;
3092 if (STRINGP (it
->string
))
3094 extern Lisp_Object Qinvisible
;
3095 Lisp_Object prop
, end_charpos
, limit
, charpos
;
3097 /* Get the value of the invisible text property at the
3098 current position. Value will be nil if there is no such
3100 charpos
= make_number (IT_STRING_CHARPOS (*it
));
3101 prop
= Fget_text_property (charpos
, Qinvisible
, it
->string
);
3104 && IT_STRING_CHARPOS (*it
) < it
->end_charpos
)
3106 handled
= HANDLED_RECOMPUTE_PROPS
;
3108 /* Get the position at which the next change of the
3109 invisible text property can be found in IT->string.
3110 Value will be nil if the property value is the same for
3111 all the rest of IT->string. */
3112 XSETINT (limit
, SCHARS (it
->string
));
3113 end_charpos
= Fnext_single_property_change (charpos
, Qinvisible
,
3116 /* Text at current position is invisible. The next
3117 change in the property is at position end_charpos.
3118 Move IT's current position to that position. */
3119 if (INTEGERP (end_charpos
)
3120 && XFASTINT (end_charpos
) < XFASTINT (limit
))
3122 struct text_pos old
;
3123 old
= it
->current
.string_pos
;
3124 IT_STRING_CHARPOS (*it
) = XFASTINT (end_charpos
);
3125 compute_string_pos (&it
->current
.string_pos
, old
, it
->string
);
3129 /* The rest of the string is invisible. If this is an
3130 overlay string, proceed with the next overlay string
3131 or whatever comes and return a character from there. */
3132 if (it
->current
.overlay_string_index
>= 0)
3134 next_overlay_string (it
);
3135 /* Don't check for overlay strings when we just
3136 finished processing them. */
3137 handled
= HANDLED_OVERLAY_STRING_CONSUMED
;
3141 IT_STRING_CHARPOS (*it
) = SCHARS (it
->string
);
3142 IT_STRING_BYTEPOS (*it
) = SBYTES (it
->string
);
3149 int invis_p
, newpos
, next_stop
, start_charpos
;
3150 Lisp_Object pos
, prop
, overlay
;
3152 /* First of all, is there invisible text at this position? */
3153 start_charpos
= IT_CHARPOS (*it
);
3154 pos
= make_number (IT_CHARPOS (*it
));
3155 prop
= get_char_property_and_overlay (pos
, Qinvisible
, it
->window
,
3157 invis_p
= TEXT_PROP_MEANS_INVISIBLE (prop
);
3159 /* If we are on invisible text, skip over it. */
3160 if (invis_p
&& IT_CHARPOS (*it
) < it
->end_charpos
)
3162 /* Record whether we have to display an ellipsis for the
3164 int display_ellipsis_p
= invis_p
== 2;
3166 handled
= HANDLED_RECOMPUTE_PROPS
;
3168 /* Loop skipping over invisible text. The loop is left at
3169 ZV or with IT on the first char being visible again. */
3172 /* Try to skip some invisible text. Return value is the
3173 position reached which can be equal to IT's position
3174 if there is nothing invisible here. This skips both
3175 over invisible text properties and overlays with
3176 invisible property. */
3177 newpos
= skip_invisible (IT_CHARPOS (*it
),
3178 &next_stop
, ZV
, it
->window
);
3180 /* If we skipped nothing at all we weren't at invisible
3181 text in the first place. If everything to the end of
3182 the buffer was skipped, end the loop. */
3183 if (newpos
== IT_CHARPOS (*it
) || newpos
>= ZV
)
3187 /* We skipped some characters but not necessarily
3188 all there are. Check if we ended up on visible
3189 text. Fget_char_property returns the property of
3190 the char before the given position, i.e. if we
3191 get invis_p = 0, this means that the char at
3192 newpos is visible. */
3193 pos
= make_number (newpos
);
3194 prop
= Fget_char_property (pos
, Qinvisible
, it
->window
);
3195 invis_p
= TEXT_PROP_MEANS_INVISIBLE (prop
);
3198 /* If we ended up on invisible text, proceed to
3199 skip starting with next_stop. */
3201 IT_CHARPOS (*it
) = next_stop
;
3205 /* The position newpos is now either ZV or on visible text. */
3206 IT_CHARPOS (*it
) = newpos
;
3207 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (newpos
);
3209 /* If there are before-strings at the start of invisible
3210 text, and the text is invisible because of a text
3211 property, arrange to show before-strings because 20.x did
3212 it that way. (If the text is invisible because of an
3213 overlay property instead of a text property, this is
3214 already handled in the overlay code.) */
3216 && get_overlay_strings (it
, start_charpos
))
3218 handled
= HANDLED_RECOMPUTE_PROPS
;
3219 it
->stack
[it
->sp
- 1].display_ellipsis_p
= display_ellipsis_p
;
3221 else if (display_ellipsis_p
)
3222 setup_for_ellipsis (it
);
3230 /* Make iterator IT return `...' next. */
3233 setup_for_ellipsis (it
)
3237 && VECTORP (DISP_INVIS_VECTOR (it
->dp
)))
3239 struct Lisp_Vector
*v
= XVECTOR (DISP_INVIS_VECTOR (it
->dp
));
3240 it
->dpvec
= v
->contents
;
3241 it
->dpend
= v
->contents
+ v
->size
;
3245 /* Default `...'. */
3246 it
->dpvec
= default_invis_vector
;
3247 it
->dpend
= default_invis_vector
+ 3;
3250 /* The ellipsis display does not replace the display of the
3251 character at the new position. Indicate this by setting
3252 IT->dpvec_char_len to zero. */
3253 it
->dpvec_char_len
= 0;
3255 it
->current
.dpvec_index
= 0;
3256 it
->method
= next_element_from_display_vector
;
3261 /***********************************************************************
3263 ***********************************************************************/
3265 /* Set up iterator IT from `display' property at its current position.
3266 Called from handle_stop. */
3268 static enum prop_handled
3269 handle_display_prop (it
)
3272 Lisp_Object prop
, object
;
3273 struct text_pos
*position
;
3274 int display_replaced_p
= 0;
3276 if (STRINGP (it
->string
))
3278 object
= it
->string
;
3279 position
= &it
->current
.string_pos
;
3283 object
= it
->w
->buffer
;
3284 position
= &it
->current
.pos
;
3287 /* Reset those iterator values set from display property values. */
3288 it
->slice
.x
= it
->slice
.y
= it
->slice
.width
= it
->slice
.height
= Qnil
;
3289 it
->space_width
= Qnil
;
3290 it
->font_height
= Qnil
;
3293 /* We don't support recursive `display' properties, i.e. string
3294 values that have a string `display' property, that have a string
3295 `display' property etc. */
3296 if (!it
->string_from_display_prop_p
)
3297 it
->area
= TEXT_AREA
;
3299 prop
= Fget_char_property (make_number (position
->charpos
),
3302 return HANDLED_NORMALLY
;
3305 /* Simple properties. */
3306 && !EQ (XCAR (prop
), Qimage
)
3307 && !EQ (XCAR (prop
), Qspace
)
3308 && !EQ (XCAR (prop
), Qwhen
)
3309 && !EQ (XCAR (prop
), Qslice
)
3310 && !EQ (XCAR (prop
), Qspace_width
)
3311 && !EQ (XCAR (prop
), Qheight
)
3312 && !EQ (XCAR (prop
), Qraise
)
3313 /* Marginal area specifications. */
3314 && !(CONSP (XCAR (prop
)) && EQ (XCAR (XCAR (prop
)), Qmargin
))
3315 && !EQ (XCAR (prop
), Qleft_fringe
)
3316 && !EQ (XCAR (prop
), Qright_fringe
)
3317 && !NILP (XCAR (prop
)))
3319 for (; CONSP (prop
); prop
= XCDR (prop
))
3321 if (handle_single_display_prop (it
, XCAR (prop
), object
,
3322 position
, display_replaced_p
))
3323 display_replaced_p
= 1;
3326 else if (VECTORP (prop
))
3329 for (i
= 0; i
< ASIZE (prop
); ++i
)
3330 if (handle_single_display_prop (it
, AREF (prop
, i
), object
,
3331 position
, display_replaced_p
))
3332 display_replaced_p
= 1;
3336 if (handle_single_display_prop (it
, prop
, object
, position
, 0))
3337 display_replaced_p
= 1;
3340 return display_replaced_p
? HANDLED_RETURN
: HANDLED_NORMALLY
;
3344 /* Value is the position of the end of the `display' property starting
3345 at START_POS in OBJECT. */
3347 static struct text_pos
3348 display_prop_end (it
, object
, start_pos
)
3351 struct text_pos start_pos
;
3354 struct text_pos end_pos
;
3356 end
= Fnext_single_char_property_change (make_number (CHARPOS (start_pos
)),
3357 Qdisplay
, object
, Qnil
);
3358 CHARPOS (end_pos
) = XFASTINT (end
);
3359 if (STRINGP (object
))
3360 compute_string_pos (&end_pos
, start_pos
, it
->string
);
3362 BYTEPOS (end_pos
) = CHAR_TO_BYTE (XFASTINT (end
));
3368 /* Set up IT from a single `display' sub-property value PROP. OBJECT
3369 is the object in which the `display' property was found. *POSITION
3370 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3371 means that we previously saw a display sub-property which already
3372 replaced text display with something else, for example an image;
3373 ignore such properties after the first one has been processed.
3375 If PROP is a `space' or `image' sub-property, set *POSITION to the
3376 end position of the `display' property.
3378 Value is non-zero if something was found which replaces the display
3379 of buffer or string text. */
3382 handle_single_display_prop (it
, prop
, object
, position
,
3383 display_replaced_before_p
)
3387 struct text_pos
*position
;
3388 int display_replaced_before_p
;
3391 int replaces_text_display_p
= 0;
3394 /* If PROP is a list of the form `(when FORM . VALUE)', FORM is
3395 evaluated. If the result is nil, VALUE is ignored. */
3397 if (CONSP (prop
) && EQ (XCAR (prop
), Qwhen
))
3406 if (!NILP (form
) && !EQ (form
, Qt
))
3408 int count
= SPECPDL_INDEX ();
3409 struct gcpro gcpro1
;
3411 /* Bind `object' to the object having the `display' property, a
3412 buffer or string. Bind `position' to the position in the
3413 object where the property was found, and `buffer-position'
3414 to the current position in the buffer. */
3415 specbind (Qobject
, object
);
3416 specbind (Qposition
, make_number (CHARPOS (*position
)));
3417 specbind (Qbuffer_position
,
3418 make_number (STRINGP (object
)
3419 ? IT_CHARPOS (*it
) : CHARPOS (*position
)));
3421 form
= safe_eval (form
);
3423 unbind_to (count
, Qnil
);
3430 && EQ (XCAR (prop
), Qheight
)
3431 && CONSP (XCDR (prop
)))
3433 if (FRAME_TERMCAP_P (it
->f
) || FRAME_MSDOS_P (it
->f
))
3436 /* `(height HEIGHT)'. */
3437 it
->font_height
= XCAR (XCDR (prop
));
3438 if (!NILP (it
->font_height
))
3440 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
3441 int new_height
= -1;
3443 if (CONSP (it
->font_height
)
3444 && (EQ (XCAR (it
->font_height
), Qplus
)
3445 || EQ (XCAR (it
->font_height
), Qminus
))
3446 && CONSP (XCDR (it
->font_height
))
3447 && INTEGERP (XCAR (XCDR (it
->font_height
))))
3449 /* `(+ N)' or `(- N)' where N is an integer. */
3450 int steps
= XINT (XCAR (XCDR (it
->font_height
)));
3451 if (EQ (XCAR (it
->font_height
), Qplus
))
3453 it
->face_id
= smaller_face (it
->f
, it
->face_id
, steps
);
3455 else if (FUNCTIONP (it
->font_height
))
3457 /* Call function with current height as argument.
3458 Value is the new height. */
3460 height
= safe_call1 (it
->font_height
,
3461 face
->lface
[LFACE_HEIGHT_INDEX
]);
3462 if (NUMBERP (height
))
3463 new_height
= XFLOATINT (height
);
3465 else if (NUMBERP (it
->font_height
))
3467 /* Value is a multiple of the canonical char height. */
3470 face
= FACE_FROM_ID (it
->f
, DEFAULT_FACE_ID
);
3471 new_height
= (XFLOATINT (it
->font_height
)
3472 * XINT (face
->lface
[LFACE_HEIGHT_INDEX
]));
3476 /* Evaluate IT->font_height with `height' bound to the
3477 current specified height to get the new height. */
3479 int count
= SPECPDL_INDEX ();
3481 specbind (Qheight
, face
->lface
[LFACE_HEIGHT_INDEX
]);
3482 value
= safe_eval (it
->font_height
);
3483 unbind_to (count
, Qnil
);
3485 if (NUMBERP (value
))
3486 new_height
= XFLOATINT (value
);
3490 it
->face_id
= face_with_height (it
->f
, it
->face_id
, new_height
);
3493 else if (CONSP (prop
)
3494 && EQ (XCAR (prop
), Qspace_width
)
3495 && CONSP (XCDR (prop
)))
3497 /* `(space_width WIDTH)'. */
3498 if (FRAME_TERMCAP_P (it
->f
) || FRAME_MSDOS_P (it
->f
))
3501 value
= XCAR (XCDR (prop
));
3502 if (NUMBERP (value
) && XFLOATINT (value
) > 0)
3503 it
->space_width
= value
;
3505 else if (CONSP (prop
)
3506 && EQ (XCAR (prop
), Qslice
))
3508 /* `(slice X Y WIDTH HEIGHT)'. */
3511 if (FRAME_TERMCAP_P (it
->f
) || FRAME_MSDOS_P (it
->f
))
3514 if (tem
= XCDR (prop
), CONSP (tem
))
3516 it
->slice
.x
= XCAR (tem
);
3517 if (tem
= XCDR (tem
), CONSP (tem
))
3519 it
->slice
.y
= XCAR (tem
);
3520 if (tem
= XCDR (tem
), CONSP (tem
))
3522 it
->slice
.width
= XCAR (tem
);
3523 if (tem
= XCDR (tem
), CONSP (tem
))
3524 it
->slice
.height
= XCAR (tem
);
3529 else if (CONSP (prop
)
3530 && EQ (XCAR (prop
), Qraise
)
3531 && CONSP (XCDR (prop
)))
3533 /* `(raise FACTOR)'. */
3534 if (FRAME_TERMCAP_P (it
->f
) || FRAME_MSDOS_P (it
->f
))
3537 #ifdef HAVE_WINDOW_SYSTEM
3538 value
= XCAR (XCDR (prop
));
3539 if (NUMBERP (value
))
3541 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
3542 it
->voffset
= - (XFLOATINT (value
)
3543 * (FONT_HEIGHT (face
->font
)));
3545 #endif /* HAVE_WINDOW_SYSTEM */
3547 else if (!it
->string_from_display_prop_p
)
3549 /* `((margin left-margin) VALUE)' or `((margin right-margin)
3550 VALUE) or `((margin nil) VALUE)' or VALUE. */
3551 Lisp_Object location
, value
;
3552 struct text_pos start_pos
;
3555 /* Characters having this form of property are not displayed, so
3556 we have to find the end of the property. */
3557 start_pos
= *position
;
3558 *position
= display_prop_end (it
, object
, start_pos
);
3561 /* Let's stop at the new position and assume that all
3562 text properties change there. */
3563 it
->stop_charpos
= position
->charpos
;
3566 && (EQ (XCAR (prop
), Qleft_fringe
)
3567 || EQ (XCAR (prop
), Qright_fringe
))
3568 && CONSP (XCDR (prop
)))
3570 unsigned face_id
= DEFAULT_FACE_ID
;
3572 /* Save current settings of IT so that we can restore them
3573 when we are finished with the glyph property value. */
3575 /* `(left-fringe BITMAP FACE)'. */
3576 if (FRAME_TERMCAP_P (it
->f
) || FRAME_MSDOS_P (it
->f
))
3579 #ifdef HAVE_WINDOW_SYSTEM
3580 value
= XCAR (XCDR (prop
));
3581 if (!NUMBERP (value
)
3582 || !valid_fringe_bitmap_id_p (XINT (value
)))
3585 if (CONSP (XCDR (XCDR (prop
))))
3587 Lisp_Object face_name
= XCAR (XCDR (XCDR (prop
)));
3589 face_id
= lookup_named_face (it
->f
, face_name
, 'A');
3596 it
->area
= TEXT_AREA
;
3597 it
->what
= IT_IMAGE
;
3598 it
->image_id
= -1; /* no image */
3599 it
->position
= start_pos
;
3600 it
->object
= NILP (object
) ? it
->w
->buffer
: object
;
3601 it
->method
= next_element_from_image
;
3602 it
->face_id
= face_id
;
3604 /* Say that we haven't consumed the characters with
3605 `display' property yet. The call to pop_it in
3606 set_iterator_to_next will clean this up. */
3607 *position
= start_pos
;
3609 if (EQ (XCAR (prop
), Qleft_fringe
))
3611 it
->left_user_fringe_bitmap
= XINT (value
);
3612 it
->left_user_fringe_face_id
= face_id
;
3616 it
->right_user_fringe_bitmap
= XINT (value
);
3617 it
->right_user_fringe_face_id
= face_id
;
3619 #endif /* HAVE_WINDOW_SYSTEM */
3623 location
= Qunbound
;
3624 if (CONSP (prop
) && CONSP (XCAR (prop
)))
3628 value
= XCDR (prop
);
3630 value
= XCAR (value
);
3633 if (EQ (XCAR (tem
), Qmargin
)
3634 && (tem
= XCDR (tem
),
3635 tem
= CONSP (tem
) ? XCAR (tem
) : Qnil
,
3637 || EQ (tem
, Qleft_margin
)
3638 || EQ (tem
, Qright_margin
))))
3642 if (EQ (location
, Qunbound
))
3648 valid_p
= (STRINGP (value
)
3649 #ifdef HAVE_WINDOW_SYSTEM
3650 || (!FRAME_TERMCAP_P (it
->f
) && valid_image_p (value
))
3651 #endif /* not HAVE_WINDOW_SYSTEM */
3652 || (CONSP (value
) && EQ (XCAR (value
), Qspace
)));
3654 if ((EQ (location
, Qleft_margin
)
3655 || EQ (location
, Qright_margin
)
3658 && !display_replaced_before_p
)
3660 replaces_text_display_p
= 1;
3662 /* Save current settings of IT so that we can restore them
3663 when we are finished with the glyph property value. */
3666 if (NILP (location
))
3667 it
->area
= TEXT_AREA
;
3668 else if (EQ (location
, Qleft_margin
))
3669 it
->area
= LEFT_MARGIN_AREA
;
3671 it
->area
= RIGHT_MARGIN_AREA
;
3673 if (STRINGP (value
))
3676 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
3677 it
->current
.overlay_string_index
= -1;
3678 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = 0;
3679 it
->end_charpos
= it
->string_nchars
= SCHARS (it
->string
);
3680 it
->method
= next_element_from_string
;
3681 it
->stop_charpos
= 0;
3682 it
->string_from_display_prop_p
= 1;
3683 /* Say that we haven't consumed the characters with
3684 `display' property yet. The call to pop_it in
3685 set_iterator_to_next will clean this up. */
3686 *position
= start_pos
;
3688 else if (CONSP (value
) && EQ (XCAR (value
), Qspace
))
3690 it
->method
= next_element_from_stretch
;
3692 it
->current
.pos
= it
->position
= start_pos
;
3694 #ifdef HAVE_WINDOW_SYSTEM
3697 it
->what
= IT_IMAGE
;
3698 it
->image_id
= lookup_image (it
->f
, value
);
3699 it
->position
= start_pos
;
3700 it
->object
= NILP (object
) ? it
->w
->buffer
: object
;
3701 it
->method
= next_element_from_image
;
3703 /* Say that we haven't consumed the characters with
3704 `display' property yet. The call to pop_it in
3705 set_iterator_to_next will clean this up. */
3706 *position
= start_pos
;
3708 #endif /* HAVE_WINDOW_SYSTEM */
3711 /* Invalid property or property not supported. Restore
3712 the position to what it was before. */
3713 *position
= start_pos
;
3716 return replaces_text_display_p
;
3720 /* Check if PROP is a display sub-property value whose text should be
3721 treated as intangible. */
3724 single_display_prop_intangible_p (prop
)
3727 /* Skip over `when FORM'. */
3728 if (CONSP (prop
) && EQ (XCAR (prop
), Qwhen
))
3742 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
3743 we don't need to treat text as intangible. */
3744 if (EQ (XCAR (prop
), Qmargin
))
3752 || EQ (XCAR (prop
), Qleft_margin
)
3753 || EQ (XCAR (prop
), Qright_margin
))
3757 return (CONSP (prop
)
3758 && (EQ (XCAR (prop
), Qimage
)
3759 || EQ (XCAR (prop
), Qspace
)));
3763 /* Check if PROP is a display property value whose text should be
3764 treated as intangible. */
3767 display_prop_intangible_p (prop
)
3771 && CONSP (XCAR (prop
))
3772 && !EQ (Qmargin
, XCAR (XCAR (prop
))))
3774 /* A list of sub-properties. */
3775 while (CONSP (prop
))
3777 if (single_display_prop_intangible_p (XCAR (prop
)))
3782 else if (VECTORP (prop
))
3784 /* A vector of sub-properties. */
3786 for (i
= 0; i
< ASIZE (prop
); ++i
)
3787 if (single_display_prop_intangible_p (AREF (prop
, i
)))
3791 return single_display_prop_intangible_p (prop
);
3797 /* Return 1 if PROP is a display sub-property value containing STRING. */
3800 single_display_prop_string_p (prop
, string
)
3801 Lisp_Object prop
, string
;
3803 if (EQ (string
, prop
))
3806 /* Skip over `when FORM'. */
3807 if (CONSP (prop
) && EQ (XCAR (prop
), Qwhen
))
3816 /* Skip over `margin LOCATION'. */
3817 if (EQ (XCAR (prop
), Qmargin
))
3828 return CONSP (prop
) && EQ (XCAR (prop
), string
);
3832 /* Return 1 if STRING appears in the `display' property PROP. */
3835 display_prop_string_p (prop
, string
)
3836 Lisp_Object prop
, string
;
3839 && CONSP (XCAR (prop
))
3840 && !EQ (Qmargin
, XCAR (XCAR (prop
))))
3842 /* A list of sub-properties. */
3843 while (CONSP (prop
))
3845 if (single_display_prop_string_p (XCAR (prop
), string
))
3850 else if (VECTORP (prop
))
3852 /* A vector of sub-properties. */
3854 for (i
= 0; i
< ASIZE (prop
); ++i
)
3855 if (single_display_prop_string_p (AREF (prop
, i
), string
))
3859 return single_display_prop_string_p (prop
, string
);
3865 /* Determine from which buffer position in W's buffer STRING comes
3866 from. AROUND_CHARPOS is an approximate position where it could
3867 be from. Value is the buffer position or 0 if it couldn't be
3870 W's buffer must be current.
3872 This function is necessary because we don't record buffer positions
3873 in glyphs generated from strings (to keep struct glyph small).
3874 This function may only use code that doesn't eval because it is
3875 called asynchronously from note_mouse_highlight. */
3878 string_buffer_position (w
, string
, around_charpos
)
3883 Lisp_Object limit
, prop
, pos
;
3884 const int MAX_DISTANCE
= 1000;
3887 pos
= make_number (around_charpos
);
3888 limit
= make_number (min (XINT (pos
) + MAX_DISTANCE
, ZV
));
3889 while (!found
&& !EQ (pos
, limit
))
3891 prop
= Fget_char_property (pos
, Qdisplay
, Qnil
);
3892 if (!NILP (prop
) && display_prop_string_p (prop
, string
))
3895 pos
= Fnext_single_char_property_change (pos
, Qdisplay
, Qnil
, limit
);
3900 pos
= make_number (around_charpos
);
3901 limit
= make_number (max (XINT (pos
) - MAX_DISTANCE
, BEGV
));
3902 while (!found
&& !EQ (pos
, limit
))
3904 prop
= Fget_char_property (pos
, Qdisplay
, Qnil
);
3905 if (!NILP (prop
) && display_prop_string_p (prop
, string
))
3908 pos
= Fprevious_single_char_property_change (pos
, Qdisplay
, Qnil
,
3913 return found
? XINT (pos
) : 0;
3918 /***********************************************************************
3919 `composition' property
3920 ***********************************************************************/
3922 /* Set up iterator IT from `composition' property at its current
3923 position. Called from handle_stop. */
3925 static enum prop_handled
3926 handle_composition_prop (it
)
3929 Lisp_Object prop
, string
;
3930 int pos
, pos_byte
, end
;
3931 enum prop_handled handled
= HANDLED_NORMALLY
;
3933 if (STRINGP (it
->string
))
3935 pos
= IT_STRING_CHARPOS (*it
);
3936 pos_byte
= IT_STRING_BYTEPOS (*it
);
3937 string
= it
->string
;
3941 pos
= IT_CHARPOS (*it
);
3942 pos_byte
= IT_BYTEPOS (*it
);
3946 /* If there's a valid composition and point is not inside of the
3947 composition (in the case that the composition is from the current
3948 buffer), draw a glyph composed from the composition components. */
3949 if (find_composition (pos
, -1, &pos
, &end
, &prop
, string
)
3950 && COMPOSITION_VALID_P (pos
, end
, prop
)
3951 && (STRINGP (it
->string
) || (PT
<= pos
|| PT
>= end
)))
3953 int id
= get_composition_id (pos
, pos_byte
, end
- pos
, prop
, string
);
3957 it
->method
= next_element_from_composition
;
3959 it
->cmp_len
= COMPOSITION_LENGTH (prop
);
3960 /* For a terminal, draw only the first character of the
3962 it
->c
= COMPOSITION_GLYPH (composition_table
[id
], 0);
3963 it
->len
= (STRINGP (it
->string
)
3964 ? string_char_to_byte (it
->string
, end
)
3965 : CHAR_TO_BYTE (end
)) - pos_byte
;
3966 it
->stop_charpos
= end
;
3967 handled
= HANDLED_RETURN
;
3976 /***********************************************************************
3978 ***********************************************************************/
3980 /* The following structure is used to record overlay strings for
3981 later sorting in load_overlay_strings. */
3983 struct overlay_entry
3985 Lisp_Object overlay
;
3992 /* Set up iterator IT from overlay strings at its current position.
3993 Called from handle_stop. */
3995 static enum prop_handled
3996 handle_overlay_change (it
)
3999 if (!STRINGP (it
->string
) && get_overlay_strings (it
, 0))
4000 return HANDLED_RECOMPUTE_PROPS
;
4002 return HANDLED_NORMALLY
;
4006 /* Set up the next overlay string for delivery by IT, if there is an
4007 overlay string to deliver. Called by set_iterator_to_next when the
4008 end of the current overlay string is reached. If there are more
4009 overlay strings to display, IT->string and
4010 IT->current.overlay_string_index are set appropriately here.
4011 Otherwise IT->string is set to nil. */
4014 next_overlay_string (it
)
4017 ++it
->current
.overlay_string_index
;
4018 if (it
->current
.overlay_string_index
== it
->n_overlay_strings
)
4020 /* No more overlay strings. Restore IT's settings to what
4021 they were before overlay strings were processed, and
4022 continue to deliver from current_buffer. */
4023 int display_ellipsis_p
= it
->stack
[it
->sp
- 1].display_ellipsis_p
;
4026 xassert (it
->stop_charpos
>= BEGV
4027 && it
->stop_charpos
<= it
->end_charpos
);
4029 it
->current
.overlay_string_index
= -1;
4030 SET_TEXT_POS (it
->current
.string_pos
, -1, -1);
4031 it
->n_overlay_strings
= 0;
4032 it
->method
= next_element_from_buffer
;
4034 /* If we're at the end of the buffer, record that we have
4035 processed the overlay strings there already, so that
4036 next_element_from_buffer doesn't try it again. */
4037 if (IT_CHARPOS (*it
) >= it
->end_charpos
)
4038 it
->overlay_strings_at_end_processed_p
= 1;
4040 /* If we have to display `...' for invisible text, set
4041 the iterator up for that. */
4042 if (display_ellipsis_p
)
4043 setup_for_ellipsis (it
);
4047 /* There are more overlay strings to process. If
4048 IT->current.overlay_string_index has advanced to a position
4049 where we must load IT->overlay_strings with more strings, do
4051 int i
= it
->current
.overlay_string_index
% OVERLAY_STRING_CHUNK_SIZE
;
4053 if (it
->current
.overlay_string_index
&& i
== 0)
4054 load_overlay_strings (it
, 0);
4056 /* Initialize IT to deliver display elements from the overlay
4058 it
->string
= it
->overlay_strings
[i
];
4059 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
4060 SET_TEXT_POS (it
->current
.string_pos
, 0, 0);
4061 it
->method
= next_element_from_string
;
4062 it
->stop_charpos
= 0;
4069 /* Compare two overlay_entry structures E1 and E2. Used as a
4070 comparison function for qsort in load_overlay_strings. Overlay
4071 strings for the same position are sorted so that
4073 1. All after-strings come in front of before-strings, except
4074 when they come from the same overlay.
4076 2. Within after-strings, strings are sorted so that overlay strings
4077 from overlays with higher priorities come first.
4079 2. Within before-strings, strings are sorted so that overlay
4080 strings from overlays with higher priorities come last.
4082 Value is analogous to strcmp. */
4086 compare_overlay_entries (e1
, e2
)
4089 struct overlay_entry
*entry1
= (struct overlay_entry
*) e1
;
4090 struct overlay_entry
*entry2
= (struct overlay_entry
*) e2
;
4093 if (entry1
->after_string_p
!= entry2
->after_string_p
)
4095 /* Let after-strings appear in front of before-strings if
4096 they come from different overlays. */
4097 if (EQ (entry1
->overlay
, entry2
->overlay
))
4098 result
= entry1
->after_string_p
? 1 : -1;
4100 result
= entry1
->after_string_p
? -1 : 1;
4102 else if (entry1
->after_string_p
)
4103 /* After-strings sorted in order of decreasing priority. */
4104 result
= entry2
->priority
- entry1
->priority
;
4106 /* Before-strings sorted in order of increasing priority. */
4107 result
= entry1
->priority
- entry2
->priority
;
4113 /* Load the vector IT->overlay_strings with overlay strings from IT's
4114 current buffer position, or from CHARPOS if that is > 0. Set
4115 IT->n_overlays to the total number of overlay strings found.
4117 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4118 a time. On entry into load_overlay_strings,
4119 IT->current.overlay_string_index gives the number of overlay
4120 strings that have already been loaded by previous calls to this
4123 IT->add_overlay_start contains an additional overlay start
4124 position to consider for taking overlay strings from, if non-zero.
4125 This position comes into play when the overlay has an `invisible'
4126 property, and both before and after-strings. When we've skipped to
4127 the end of the overlay, because of its `invisible' property, we
4128 nevertheless want its before-string to appear.
4129 IT->add_overlay_start will contain the overlay start position
4132 Overlay strings are sorted so that after-string strings come in
4133 front of before-string strings. Within before and after-strings,
4134 strings are sorted by overlay priority. See also function
4135 compare_overlay_entries. */
4138 load_overlay_strings (it
, charpos
)
4142 extern Lisp_Object Qafter_string
, Qbefore_string
, Qwindow
, Qpriority
;
4143 Lisp_Object overlay
, window
, str
, invisible
;
4144 struct Lisp_Overlay
*ov
;
4147 int n
= 0, i
, j
, invis_p
;
4148 struct overlay_entry
*entries
4149 = (struct overlay_entry
*) alloca (size
* sizeof *entries
);
4152 charpos
= IT_CHARPOS (*it
);
4154 /* Append the overlay string STRING of overlay OVERLAY to vector
4155 `entries' which has size `size' and currently contains `n'
4156 elements. AFTER_P non-zero means STRING is an after-string of
4158 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4161 Lisp_Object priority; \
4165 int new_size = 2 * size; \
4166 struct overlay_entry *old = entries; \
4168 (struct overlay_entry *) alloca (new_size \
4169 * sizeof *entries); \
4170 bcopy (old, entries, size * sizeof *entries); \
4174 entries[n].string = (STRING); \
4175 entries[n].overlay = (OVERLAY); \
4176 priority = Foverlay_get ((OVERLAY), Qpriority); \
4177 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4178 entries[n].after_string_p = (AFTER_P); \
4183 /* Process overlay before the overlay center. */
4184 for (ov
= current_buffer
->overlays_before
; ov
; ov
= ov
->next
)
4186 XSETMISC (overlay
, ov
);
4187 xassert (OVERLAYP (overlay
));
4188 start
= OVERLAY_POSITION (OVERLAY_START (overlay
));
4189 end
= OVERLAY_POSITION (OVERLAY_END (overlay
));
4194 /* Skip this overlay if it doesn't start or end at IT's current
4196 if (end
!= charpos
&& start
!= charpos
)
4199 /* Skip this overlay if it doesn't apply to IT->w. */
4200 window
= Foverlay_get (overlay
, Qwindow
);
4201 if (WINDOWP (window
) && XWINDOW (window
) != it
->w
)
4204 /* If the text ``under'' the overlay is invisible, both before-
4205 and after-strings from this overlay are visible; start and
4206 end position are indistinguishable. */
4207 invisible
= Foverlay_get (overlay
, Qinvisible
);
4208 invis_p
= TEXT_PROP_MEANS_INVISIBLE (invisible
);
4210 /* If overlay has a non-empty before-string, record it. */
4211 if ((start
== charpos
|| (end
== charpos
&& invis_p
))
4212 && (str
= Foverlay_get (overlay
, Qbefore_string
), STRINGP (str
))
4214 RECORD_OVERLAY_STRING (overlay
, str
, 0);
4216 /* If overlay has a non-empty after-string, record it. */
4217 if ((end
== charpos
|| (start
== charpos
&& invis_p
))
4218 && (str
= Foverlay_get (overlay
, Qafter_string
), STRINGP (str
))
4220 RECORD_OVERLAY_STRING (overlay
, str
, 1);
4223 /* Process overlays after the overlay center. */
4224 for (ov
= current_buffer
->overlays_after
; ov
; ov
= ov
->next
)
4226 XSETMISC (overlay
, ov
);
4227 xassert (OVERLAYP (overlay
));
4228 start
= OVERLAY_POSITION (OVERLAY_START (overlay
));
4229 end
= OVERLAY_POSITION (OVERLAY_END (overlay
));
4231 if (start
> charpos
)
4234 /* Skip this overlay if it doesn't start or end at IT's current
4236 if (end
!= charpos
&& start
!= charpos
)
4239 /* Skip this overlay if it doesn't apply to IT->w. */
4240 window
= Foverlay_get (overlay
, Qwindow
);
4241 if (WINDOWP (window
) && XWINDOW (window
) != it
->w
)
4244 /* If the text ``under'' the overlay is invisible, it has a zero
4245 dimension, and both before- and after-strings apply. */
4246 invisible
= Foverlay_get (overlay
, Qinvisible
);
4247 invis_p
= TEXT_PROP_MEANS_INVISIBLE (invisible
);
4249 /* If overlay has a non-empty before-string, record it. */
4250 if ((start
== charpos
|| (end
== charpos
&& invis_p
))
4251 && (str
= Foverlay_get (overlay
, Qbefore_string
), STRINGP (str
))
4253 RECORD_OVERLAY_STRING (overlay
, str
, 0);
4255 /* If overlay has a non-empty after-string, record it. */
4256 if ((end
== charpos
|| (start
== charpos
&& invis_p
))
4257 && (str
= Foverlay_get (overlay
, Qafter_string
), STRINGP (str
))
4259 RECORD_OVERLAY_STRING (overlay
, str
, 1);
4262 #undef RECORD_OVERLAY_STRING
4266 qsort (entries
, n
, sizeof *entries
, compare_overlay_entries
);
4268 /* Record the total number of strings to process. */
4269 it
->n_overlay_strings
= n
;
4271 /* IT->current.overlay_string_index is the number of overlay strings
4272 that have already been consumed by IT. Copy some of the
4273 remaining overlay strings to IT->overlay_strings. */
4275 j
= it
->current
.overlay_string_index
;
4276 while (i
< OVERLAY_STRING_CHUNK_SIZE
&& j
< n
)
4277 it
->overlay_strings
[i
++] = entries
[j
++].string
;
4283 /* Get the first chunk of overlay strings at IT's current buffer
4284 position, or at CHARPOS if that is > 0. Value is non-zero if at
4285 least one overlay string was found. */
4288 get_overlay_strings (it
, charpos
)
4292 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4293 process. This fills IT->overlay_strings with strings, and sets
4294 IT->n_overlay_strings to the total number of strings to process.
4295 IT->pos.overlay_string_index has to be set temporarily to zero
4296 because load_overlay_strings needs this; it must be set to -1
4297 when no overlay strings are found because a zero value would
4298 indicate a position in the first overlay string. */
4299 it
->current
.overlay_string_index
= 0;
4300 load_overlay_strings (it
, charpos
);
4302 /* If we found overlay strings, set up IT to deliver display
4303 elements from the first one. Otherwise set up IT to deliver
4304 from current_buffer. */
4305 if (it
->n_overlay_strings
)
4307 /* Make sure we know settings in current_buffer, so that we can
4308 restore meaningful values when we're done with the overlay
4310 compute_stop_pos (it
);
4311 xassert (it
->face_id
>= 0);
4313 /* Save IT's settings. They are restored after all overlay
4314 strings have been processed. */
4315 xassert (it
->sp
== 0);
4318 /* Set up IT to deliver display elements from the first overlay
4320 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = 0;
4321 it
->string
= it
->overlay_strings
[0];
4322 it
->stop_charpos
= 0;
4323 xassert (STRINGP (it
->string
));
4324 it
->end_charpos
= SCHARS (it
->string
);
4325 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
4326 it
->method
= next_element_from_string
;
4331 it
->current
.overlay_string_index
= -1;
4332 it
->method
= next_element_from_buffer
;
4337 /* Value is non-zero if we found at least one overlay string. */
4338 return STRINGP (it
->string
);
4343 /***********************************************************************
4344 Saving and restoring state
4345 ***********************************************************************/
4347 /* Save current settings of IT on IT->stack. Called, for example,
4348 before setting up IT for an overlay string, to be able to restore
4349 IT's settings to what they were after the overlay string has been
4356 struct iterator_stack_entry
*p
;
4358 xassert (it
->sp
< 2);
4359 p
= it
->stack
+ it
->sp
;
4361 p
->stop_charpos
= it
->stop_charpos
;
4362 xassert (it
->face_id
>= 0);
4363 p
->face_id
= it
->face_id
;
4364 p
->string
= it
->string
;
4365 p
->pos
= it
->current
;
4366 p
->end_charpos
= it
->end_charpos
;
4367 p
->string_nchars
= it
->string_nchars
;
4369 p
->multibyte_p
= it
->multibyte_p
;
4370 p
->slice
= it
->slice
;
4371 p
->space_width
= it
->space_width
;
4372 p
->font_height
= it
->font_height
;
4373 p
->voffset
= it
->voffset
;
4374 p
->string_from_display_prop_p
= it
->string_from_display_prop_p
;
4375 p
->display_ellipsis_p
= 0;
4380 /* Restore IT's settings from IT->stack. Called, for example, when no
4381 more overlay strings must be processed, and we return to delivering
4382 display elements from a buffer, or when the end of a string from a
4383 `display' property is reached and we return to delivering display
4384 elements from an overlay string, or from a buffer. */
4390 struct iterator_stack_entry
*p
;
4392 xassert (it
->sp
> 0);
4394 p
= it
->stack
+ it
->sp
;
4395 it
->stop_charpos
= p
->stop_charpos
;
4396 it
->face_id
= p
->face_id
;
4397 it
->string
= p
->string
;
4398 it
->current
= p
->pos
;
4399 it
->end_charpos
= p
->end_charpos
;
4400 it
->string_nchars
= p
->string_nchars
;
4402 it
->multibyte_p
= p
->multibyte_p
;
4403 it
->slice
= p
->slice
;
4404 it
->space_width
= p
->space_width
;
4405 it
->font_height
= p
->font_height
;
4406 it
->voffset
= p
->voffset
;
4407 it
->string_from_display_prop_p
= p
->string_from_display_prop_p
;
4412 /***********************************************************************
4414 ***********************************************************************/
4416 /* Set IT's current position to the previous line start. */
4419 back_to_previous_line_start (it
)
4422 IT_CHARPOS (*it
) = find_next_newline_no_quit (IT_CHARPOS (*it
) - 1, -1);
4423 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (IT_CHARPOS (*it
));
4427 /* Move IT to the next line start.
4429 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
4430 we skipped over part of the text (as opposed to moving the iterator
4431 continuously over the text). Otherwise, don't change the value
4434 Newlines may come from buffer text, overlay strings, or strings
4435 displayed via the `display' property. That's the reason we can't
4436 simply use find_next_newline_no_quit.
4438 Note that this function may not skip over invisible text that is so
4439 because of text properties and immediately follows a newline. If
4440 it would, function reseat_at_next_visible_line_start, when called
4441 from set_iterator_to_next, would effectively make invisible
4442 characters following a newline part of the wrong glyph row, which
4443 leads to wrong cursor motion. */
4446 forward_to_next_line_start (it
, skipped_p
)
4450 int old_selective
, newline_found_p
, n
;
4451 const int MAX_NEWLINE_DISTANCE
= 500;
4453 /* If already on a newline, just consume it to avoid unintended
4454 skipping over invisible text below. */
4455 if (it
->what
== IT_CHARACTER
4457 && CHARPOS (it
->position
) == IT_CHARPOS (*it
))
4459 set_iterator_to_next (it
, 0);
4464 /* Don't handle selective display in the following. It's (a)
4465 unnecessary because it's done by the caller, and (b) leads to an
4466 infinite recursion because next_element_from_ellipsis indirectly
4467 calls this function. */
4468 old_selective
= it
->selective
;
4471 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
4472 from buffer text. */
4473 for (n
= newline_found_p
= 0;
4474 !newline_found_p
&& n
< MAX_NEWLINE_DISTANCE
;
4475 n
+= STRINGP (it
->string
) ? 0 : 1)
4477 if (!get_next_display_element (it
))
4479 newline_found_p
= it
->what
== IT_CHARACTER
&& it
->c
== '\n';
4480 set_iterator_to_next (it
, 0);
4483 /* If we didn't find a newline near enough, see if we can use a
4485 if (!newline_found_p
)
4487 int start
= IT_CHARPOS (*it
);
4488 int limit
= find_next_newline_no_quit (start
, 1);
4491 xassert (!STRINGP (it
->string
));
4493 /* If there isn't any `display' property in sight, and no
4494 overlays, we can just use the position of the newline in
4496 if (it
->stop_charpos
>= limit
4497 || ((pos
= Fnext_single_property_change (make_number (start
),
4499 Qnil
, make_number (limit
)),
4501 && next_overlay_change (start
) == ZV
))
4503 IT_CHARPOS (*it
) = limit
;
4504 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (limit
);
4505 *skipped_p
= newline_found_p
= 1;
4509 while (get_next_display_element (it
)
4510 && !newline_found_p
)
4512 newline_found_p
= ITERATOR_AT_END_OF_LINE_P (it
);
4513 set_iterator_to_next (it
, 0);
4518 it
->selective
= old_selective
;
4519 return newline_found_p
;
4523 /* Set IT's current position to the previous visible line start. Skip
4524 invisible text that is so either due to text properties or due to
4525 selective display. Caution: this does not change IT->current_x and
4529 back_to_previous_visible_line_start (it
)
4534 /* Go back one newline if not on BEGV already. */
4535 if (IT_CHARPOS (*it
) > BEGV
)
4536 back_to_previous_line_start (it
);
4538 /* Move over lines that are invisible because of selective display
4539 or text properties. */
4540 while (IT_CHARPOS (*it
) > BEGV
4545 /* If selective > 0, then lines indented more than that values
4547 if (it
->selective
> 0
4548 && indented_beyond_p (IT_CHARPOS (*it
), IT_BYTEPOS (*it
),
4549 (double) it
->selective
)) /* iftc */
4555 prop
= Fget_char_property (make_number (IT_CHARPOS (*it
)),
4556 Qinvisible
, it
->window
);
4557 if (TEXT_PROP_MEANS_INVISIBLE (prop
))
4563 struct it it2
= *it
;
4565 if (handle_display_prop (&it2
) == HANDLED_RETURN
)
4569 /* Back one more newline if the current one is invisible. */
4571 back_to_previous_line_start (it
);
4574 xassert (IT_CHARPOS (*it
) >= BEGV
);
4575 xassert (IT_CHARPOS (*it
) == BEGV
4576 || FETCH_BYTE (IT_BYTEPOS (*it
) - 1) == '\n');
4581 /* Reseat iterator IT at the previous visible line start. Skip
4582 invisible text that is so either due to text properties or due to
4583 selective display. At the end, update IT's overlay information,
4584 face information etc. */
4587 reseat_at_previous_visible_line_start (it
)
4590 back_to_previous_visible_line_start (it
);
4591 reseat (it
, it
->current
.pos
, 1);
4596 /* Reseat iterator IT on the next visible line start in the current
4597 buffer. ON_NEWLINE_P non-zero means position IT on the newline
4598 preceding the line start. Skip over invisible text that is so
4599 because of selective display. Compute faces, overlays etc at the
4600 new position. Note that this function does not skip over text that
4601 is invisible because of text properties. */
4604 reseat_at_next_visible_line_start (it
, on_newline_p
)
4608 int newline_found_p
, skipped_p
= 0;
4610 newline_found_p
= forward_to_next_line_start (it
, &skipped_p
);
4612 /* Skip over lines that are invisible because they are indented
4613 more than the value of IT->selective. */
4614 if (it
->selective
> 0)
4615 while (IT_CHARPOS (*it
) < ZV
4616 && indented_beyond_p (IT_CHARPOS (*it
), IT_BYTEPOS (*it
),
4617 (double) it
->selective
)) /* iftc */
4619 xassert (FETCH_BYTE (IT_BYTEPOS (*it
) - 1) == '\n');
4620 newline_found_p
= forward_to_next_line_start (it
, &skipped_p
);
4623 /* Position on the newline if that's what's requested. */
4624 if (on_newline_p
&& newline_found_p
)
4626 if (STRINGP (it
->string
))
4628 if (IT_STRING_CHARPOS (*it
) > 0)
4630 --IT_STRING_CHARPOS (*it
);
4631 --IT_STRING_BYTEPOS (*it
);
4634 else if (IT_CHARPOS (*it
) > BEGV
)
4638 reseat (it
, it
->current
.pos
, 0);
4642 reseat (it
, it
->current
.pos
, 0);
4649 /***********************************************************************
4650 Changing an iterator's position
4651 ***********************************************************************/
4653 /* Change IT's current position to POS in current_buffer. If FORCE_P
4654 is non-zero, always check for text properties at the new position.
4655 Otherwise, text properties are only looked up if POS >=
4656 IT->check_charpos of a property. */
4659 reseat (it
, pos
, force_p
)
4661 struct text_pos pos
;
4664 int original_pos
= IT_CHARPOS (*it
);
4666 reseat_1 (it
, pos
, 0);
4668 /* Determine where to check text properties. Avoid doing it
4669 where possible because text property lookup is very expensive. */
4671 || CHARPOS (pos
) > it
->stop_charpos
4672 || CHARPOS (pos
) < original_pos
)
4679 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
4680 IT->stop_pos to POS, also. */
4683 reseat_1 (it
, pos
, set_stop_p
)
4685 struct text_pos pos
;
4688 /* Don't call this function when scanning a C string. */
4689 xassert (it
->s
== NULL
);
4691 /* POS must be a reasonable value. */
4692 xassert (CHARPOS (pos
) >= BEGV
&& CHARPOS (pos
) <= ZV
);
4694 it
->current
.pos
= it
->position
= pos
;
4695 XSETBUFFER (it
->object
, current_buffer
);
4696 it
->end_charpos
= ZV
;
4698 it
->current
.dpvec_index
= -1;
4699 it
->current
.overlay_string_index
= -1;
4700 IT_STRING_CHARPOS (*it
) = -1;
4701 IT_STRING_BYTEPOS (*it
) = -1;
4703 it
->method
= next_element_from_buffer
;
4704 /* RMS: I added this to fix a bug in move_it_vertically_backward
4705 where it->area continued to relate to the starting point
4706 for the backward motion. Bug report from
4707 Nick Roberts <nick@nick.uklinux.net> on 19 May 2003.
4708 However, I am not sure whether reseat still does the right thing
4709 in general after this change. */
4710 it
->area
= TEXT_AREA
;
4711 it
->multibyte_p
= !NILP (current_buffer
->enable_multibyte_characters
);
4713 it
->face_before_selective_p
= 0;
4716 it
->stop_charpos
= CHARPOS (pos
);
4720 /* Set up IT for displaying a string, starting at CHARPOS in window W.
4721 If S is non-null, it is a C string to iterate over. Otherwise,
4722 STRING gives a Lisp string to iterate over.
4724 If PRECISION > 0, don't return more then PRECISION number of
4725 characters from the string.
4727 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
4728 characters have been returned. FIELD_WIDTH < 0 means an infinite
4731 MULTIBYTE = 0 means disable processing of multibyte characters,
4732 MULTIBYTE > 0 means enable it,
4733 MULTIBYTE < 0 means use IT->multibyte_p.
4735 IT must be initialized via a prior call to init_iterator before
4736 calling this function. */
4739 reseat_to_string (it
, s
, string
, charpos
, precision
, field_width
, multibyte
)
4744 int precision
, field_width
, multibyte
;
4746 /* No region in strings. */
4747 it
->region_beg_charpos
= it
->region_end_charpos
= -1;
4749 /* No text property checks performed by default, but see below. */
4750 it
->stop_charpos
= -1;
4752 /* Set iterator position and end position. */
4753 bzero (&it
->current
, sizeof it
->current
);
4754 it
->current
.overlay_string_index
= -1;
4755 it
->current
.dpvec_index
= -1;
4756 xassert (charpos
>= 0);
4758 /* If STRING is specified, use its multibyteness, otherwise use the
4759 setting of MULTIBYTE, if specified. */
4761 it
->multibyte_p
= multibyte
> 0;
4765 xassert (STRINGP (string
));
4766 it
->string
= string
;
4768 it
->end_charpos
= it
->string_nchars
= SCHARS (string
);
4769 it
->method
= next_element_from_string
;
4770 it
->current
.string_pos
= string_pos (charpos
, string
);
4777 /* Note that we use IT->current.pos, not it->current.string_pos,
4778 for displaying C strings. */
4779 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = -1;
4780 if (it
->multibyte_p
)
4782 it
->current
.pos
= c_string_pos (charpos
, s
, 1);
4783 it
->end_charpos
= it
->string_nchars
= number_of_chars (s
, 1);
4787 IT_CHARPOS (*it
) = IT_BYTEPOS (*it
) = charpos
;
4788 it
->end_charpos
= it
->string_nchars
= strlen (s
);
4791 it
->method
= next_element_from_c_string
;
4794 /* PRECISION > 0 means don't return more than PRECISION characters
4796 if (precision
> 0 && it
->end_charpos
- charpos
> precision
)
4797 it
->end_charpos
= it
->string_nchars
= charpos
+ precision
;
4799 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
4800 characters have been returned. FIELD_WIDTH == 0 means don't pad,
4801 FIELD_WIDTH < 0 means infinite field width. This is useful for
4802 padding with `-' at the end of a mode line. */
4803 if (field_width
< 0)
4804 field_width
= INFINITY
;
4805 if (field_width
> it
->end_charpos
- charpos
)
4806 it
->end_charpos
= charpos
+ field_width
;
4808 /* Use the standard display table for displaying strings. */
4809 if (DISP_TABLE_P (Vstandard_display_table
))
4810 it
->dp
= XCHAR_TABLE (Vstandard_display_table
);
4812 it
->stop_charpos
= charpos
;
4818 /***********************************************************************
4820 ***********************************************************************/
4822 /* Load IT's display element fields with information about the next
4823 display element from the current position of IT. Value is zero if
4824 end of buffer (or C string) is reached. */
4827 get_next_display_element (it
)
4830 /* Non-zero means that we found a display element. Zero means that
4831 we hit the end of what we iterate over. Performance note: the
4832 function pointer `method' used here turns out to be faster than
4833 using a sequence of if-statements. */
4834 int success_p
= (*it
->method
) (it
);
4836 if (it
->what
== IT_CHARACTER
)
4838 /* Map via display table or translate control characters.
4839 IT->c, IT->len etc. have been set to the next character by
4840 the function call above. If we have a display table, and it
4841 contains an entry for IT->c, translate it. Don't do this if
4842 IT->c itself comes from a display table, otherwise we could
4843 end up in an infinite recursion. (An alternative could be to
4844 count the recursion depth of this function and signal an
4845 error when a certain maximum depth is reached.) Is it worth
4847 if (success_p
&& it
->dpvec
== NULL
)
4852 && (dv
= DISP_CHAR_VECTOR (it
->dp
, it
->c
),
4855 struct Lisp_Vector
*v
= XVECTOR (dv
);
4857 /* Return the first character from the display table
4858 entry, if not empty. If empty, don't display the
4859 current character. */
4862 it
->dpvec_char_len
= it
->len
;
4863 it
->dpvec
= v
->contents
;
4864 it
->dpend
= v
->contents
+ v
->size
;
4865 it
->current
.dpvec_index
= 0;
4866 it
->method
= next_element_from_display_vector
;
4867 success_p
= get_next_display_element (it
);
4871 set_iterator_to_next (it
, 0);
4872 success_p
= get_next_display_element (it
);
4876 /* Translate control characters into `\003' or `^C' form.
4877 Control characters coming from a display table entry are
4878 currently not translated because we use IT->dpvec to hold
4879 the translation. This could easily be changed but I
4880 don't believe that it is worth doing.
4882 If it->multibyte_p is nonzero, eight-bit characters and
4883 non-printable multibyte characters are also translated to
4886 If it->multibyte_p is zero, eight-bit characters that
4887 don't have corresponding multibyte char code are also
4888 translated to octal form. */
4889 else if ((it
->c
< ' '
4890 && (it
->area
!= TEXT_AREA
4891 || (it
->c
!= '\n' && it
->c
!= '\t')))
4895 || !CHAR_PRINTABLE_P (it
->c
))
4897 && it
->c
== unibyte_char_to_multibyte (it
->c
))))
4899 /* IT->c is a control character which must be displayed
4900 either as '\003' or as `^C' where the '\\' and '^'
4901 can be defined in the display table. Fill
4902 IT->ctl_chars with glyphs for what we have to
4903 display. Then, set IT->dpvec to these glyphs. */
4906 if (it
->c
< 128 && it
->ctl_arrow_p
)
4908 /* Set IT->ctl_chars[0] to the glyph for `^'. */
4910 && INTEGERP (DISP_CTRL_GLYPH (it
->dp
))
4911 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it
->dp
))))
4912 g
= XINT (DISP_CTRL_GLYPH (it
->dp
));
4914 g
= FAST_MAKE_GLYPH ('^', 0);
4915 XSETINT (it
->ctl_chars
[0], g
);
4917 g
= FAST_MAKE_GLYPH (it
->c
^ 0100, 0);
4918 XSETINT (it
->ctl_chars
[1], g
);
4920 /* Set up IT->dpvec and return first character from it. */
4921 it
->dpvec_char_len
= it
->len
;
4922 it
->dpvec
= it
->ctl_chars
;
4923 it
->dpend
= it
->dpvec
+ 2;
4924 it
->current
.dpvec_index
= 0;
4925 it
->method
= next_element_from_display_vector
;
4926 get_next_display_element (it
);
4930 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
4935 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
4937 && INTEGERP (DISP_ESCAPE_GLYPH (it
->dp
))
4938 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it
->dp
))))
4939 escape_glyph
= XFASTINT (DISP_ESCAPE_GLYPH (it
->dp
));
4941 escape_glyph
= FAST_MAKE_GLYPH ('\\', 0);
4943 if (SINGLE_BYTE_CHAR_P (it
->c
))
4944 str
[0] = it
->c
, len
= 1;
4947 len
= CHAR_STRING_NO_SIGNAL (it
->c
, str
);
4950 /* It's an invalid character, which
4951 shouldn't happen actually, but due to
4952 bugs it may happen. Let's print the char
4953 as is, there's not much meaningful we can
4956 str
[1] = it
->c
>> 8;
4957 str
[2] = it
->c
>> 16;
4958 str
[3] = it
->c
>> 24;
4963 for (i
= 0; i
< len
; i
++)
4965 XSETINT (it
->ctl_chars
[i
* 4], escape_glyph
);
4966 /* Insert three more glyphs into IT->ctl_chars for
4967 the octal display of the character. */
4968 g
= FAST_MAKE_GLYPH (((str
[i
] >> 6) & 7) + '0', 0);
4969 XSETINT (it
->ctl_chars
[i
* 4 + 1], g
);
4970 g
= FAST_MAKE_GLYPH (((str
[i
] >> 3) & 7) + '0', 0);
4971 XSETINT (it
->ctl_chars
[i
* 4 + 2], g
);
4972 g
= FAST_MAKE_GLYPH ((str
[i
] & 7) + '0', 0);
4973 XSETINT (it
->ctl_chars
[i
* 4 + 3], g
);
4976 /* Set up IT->dpvec and return the first character
4978 it
->dpvec_char_len
= it
->len
;
4979 it
->dpvec
= it
->ctl_chars
;
4980 it
->dpend
= it
->dpvec
+ len
* 4;
4981 it
->current
.dpvec_index
= 0;
4982 it
->method
= next_element_from_display_vector
;
4983 get_next_display_element (it
);
4988 /* Adjust face id for a multibyte character. There are no
4989 multibyte character in unibyte text. */
4992 && FRAME_WINDOW_P (it
->f
))
4994 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
4995 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->c
);
4999 /* Is this character the last one of a run of characters with
5000 box? If yes, set IT->end_of_box_run_p to 1. */
5007 it
->end_of_box_run_p
5008 = ((face_id
= face_after_it_pos (it
),
5009 face_id
!= it
->face_id
)
5010 && (face
= FACE_FROM_ID (it
->f
, face_id
),
5011 face
->box
== FACE_NO_BOX
));
5014 /* Value is 0 if end of buffer or string reached. */
5019 /* Move IT to the next display element.
5021 RESEAT_P non-zero means if called on a newline in buffer text,
5022 skip to the next visible line start.
5024 Functions get_next_display_element and set_iterator_to_next are
5025 separate because I find this arrangement easier to handle than a
5026 get_next_display_element function that also increments IT's
5027 position. The way it is we can first look at an iterator's current
5028 display element, decide whether it fits on a line, and if it does,
5029 increment the iterator position. The other way around we probably
5030 would either need a flag indicating whether the iterator has to be
5031 incremented the next time, or we would have to implement a
5032 decrement position function which would not be easy to write. */
5035 set_iterator_to_next (it
, reseat_p
)
5039 /* Reset flags indicating start and end of a sequence of characters
5040 with box. Reset them at the start of this function because
5041 moving the iterator to a new position might set them. */
5042 it
->start_of_box_run_p
= it
->end_of_box_run_p
= 0;
5044 if (it
->method
== next_element_from_buffer
)
5046 /* The current display element of IT is a character from
5047 current_buffer. Advance in the buffer, and maybe skip over
5048 invisible lines that are so because of selective display. */
5049 if (ITERATOR_AT_END_OF_LINE_P (it
) && reseat_p
)
5050 reseat_at_next_visible_line_start (it
, 0);
5053 xassert (it
->len
!= 0);
5054 IT_BYTEPOS (*it
) += it
->len
;
5055 IT_CHARPOS (*it
) += 1;
5056 xassert (IT_BYTEPOS (*it
) == CHAR_TO_BYTE (IT_CHARPOS (*it
)));
5059 else if (it
->method
== next_element_from_composition
)
5061 xassert (it
->cmp_id
>= 0 && it
->cmp_id
< n_compositions
);
5062 if (STRINGP (it
->string
))
5064 IT_STRING_BYTEPOS (*it
) += it
->len
;
5065 IT_STRING_CHARPOS (*it
) += it
->cmp_len
;
5066 it
->method
= next_element_from_string
;
5067 goto consider_string_end
;
5071 IT_BYTEPOS (*it
) += it
->len
;
5072 IT_CHARPOS (*it
) += it
->cmp_len
;
5073 it
->method
= next_element_from_buffer
;
5076 else if (it
->method
== next_element_from_c_string
)
5078 /* Current display element of IT is from a C string. */
5079 IT_BYTEPOS (*it
) += it
->len
;
5080 IT_CHARPOS (*it
) += 1;
5082 else if (it
->method
== next_element_from_display_vector
)
5084 /* Current display element of IT is from a display table entry.
5085 Advance in the display table definition. Reset it to null if
5086 end reached, and continue with characters from buffers/
5088 ++it
->current
.dpvec_index
;
5090 /* Restore face of the iterator to what they were before the
5091 display vector entry (these entries may contain faces). */
5092 it
->face_id
= it
->saved_face_id
;
5094 if (it
->dpvec
+ it
->current
.dpvec_index
== it
->dpend
)
5097 it
->method
= next_element_from_c_string
;
5098 else if (STRINGP (it
->string
))
5099 it
->method
= next_element_from_string
;
5101 it
->method
= next_element_from_buffer
;
5104 it
->current
.dpvec_index
= -1;
5106 /* Skip over characters which were displayed via IT->dpvec. */
5107 if (it
->dpvec_char_len
< 0)
5108 reseat_at_next_visible_line_start (it
, 1);
5109 else if (it
->dpvec_char_len
> 0)
5111 it
->len
= it
->dpvec_char_len
;
5112 set_iterator_to_next (it
, reseat_p
);
5116 else if (it
->method
== next_element_from_string
)
5118 /* Current display element is a character from a Lisp string. */
5119 xassert (it
->s
== NULL
&& STRINGP (it
->string
));
5120 IT_STRING_BYTEPOS (*it
) += it
->len
;
5121 IT_STRING_CHARPOS (*it
) += 1;
5123 consider_string_end
:
5125 if (it
->current
.overlay_string_index
>= 0)
5127 /* IT->string is an overlay string. Advance to the
5128 next, if there is one. */
5129 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
))
5130 next_overlay_string (it
);
5134 /* IT->string is not an overlay string. If we reached
5135 its end, and there is something on IT->stack, proceed
5136 with what is on the stack. This can be either another
5137 string, this time an overlay string, or a buffer. */
5138 if (IT_STRING_CHARPOS (*it
) == SCHARS (it
->string
)
5142 if (!STRINGP (it
->string
))
5143 it
->method
= next_element_from_buffer
;
5145 goto consider_string_end
;
5149 else if (it
->method
== next_element_from_image
5150 || it
->method
== next_element_from_stretch
)
5152 /* The position etc with which we have to proceed are on
5153 the stack. The position may be at the end of a string,
5154 if the `display' property takes up the whole string. */
5157 if (STRINGP (it
->string
))
5159 it
->method
= next_element_from_string
;
5160 goto consider_string_end
;
5163 it
->method
= next_element_from_buffer
;
5166 /* There are no other methods defined, so this should be a bug. */
5169 xassert (it
->method
!= next_element_from_string
5170 || (STRINGP (it
->string
)
5171 && IT_STRING_CHARPOS (*it
) >= 0));
5175 /* Load IT's display element fields with information about the next
5176 display element which comes from a display table entry or from the
5177 result of translating a control character to one of the forms `^C'
5178 or `\003'. IT->dpvec holds the glyphs to return as characters. */
5181 next_element_from_display_vector (it
)
5185 xassert (it
->dpvec
&& it
->current
.dpvec_index
>= 0);
5187 /* Remember the current face id in case glyphs specify faces.
5188 IT's face is restored in set_iterator_to_next. */
5189 it
->saved_face_id
= it
->face_id
;
5191 if (INTEGERP (*it
->dpvec
)
5192 && GLYPH_CHAR_VALID_P (XFASTINT (*it
->dpvec
)))
5197 g
= XFASTINT (it
->dpvec
[it
->current
.dpvec_index
]);
5198 it
->c
= FAST_GLYPH_CHAR (g
);
5199 it
->len
= CHAR_BYTES (it
->c
);
5201 /* The entry may contain a face id to use. Such a face id is
5202 the id of a Lisp face, not a realized face. A face id of
5203 zero means no face is specified. */
5204 lface_id
= FAST_GLYPH_FACE (g
);
5207 /* The function returns -1 if lface_id is invalid. */
5208 int face_id
= ascii_face_of_lisp_face (it
->f
, lface_id
);
5210 it
->face_id
= face_id
;
5214 /* Display table entry is invalid. Return a space. */
5215 it
->c
= ' ', it
->len
= 1;
5217 /* Don't change position and object of the iterator here. They are
5218 still the values of the character that had this display table
5219 entry or was translated, and that's what we want. */
5220 it
->what
= IT_CHARACTER
;
5225 /* Load IT with the next display element from Lisp string IT->string.
5226 IT->current.string_pos is the current position within the string.
5227 If IT->current.overlay_string_index >= 0, the Lisp string is an
5231 next_element_from_string (it
)
5234 struct text_pos position
;
5236 xassert (STRINGP (it
->string
));
5237 xassert (IT_STRING_CHARPOS (*it
) >= 0);
5238 position
= it
->current
.string_pos
;
5240 /* Time to check for invisible text? */
5241 if (IT_STRING_CHARPOS (*it
) < it
->end_charpos
5242 && IT_STRING_CHARPOS (*it
) == it
->stop_charpos
)
5246 /* Since a handler may have changed IT->method, we must
5248 return get_next_display_element (it
);
5251 if (it
->current
.overlay_string_index
>= 0)
5253 /* Get the next character from an overlay string. In overlay
5254 strings, There is no field width or padding with spaces to
5256 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
))
5261 else if (STRING_MULTIBYTE (it
->string
))
5263 int remaining
= SBYTES (it
->string
) - IT_STRING_BYTEPOS (*it
);
5264 const unsigned char *s
= (SDATA (it
->string
)
5265 + IT_STRING_BYTEPOS (*it
));
5266 it
->c
= string_char_and_length (s
, remaining
, &it
->len
);
5270 it
->c
= SREF (it
->string
, IT_STRING_BYTEPOS (*it
));
5276 /* Get the next character from a Lisp string that is not an
5277 overlay string. Such strings come from the mode line, for
5278 example. We may have to pad with spaces, or truncate the
5279 string. See also next_element_from_c_string. */
5280 if (IT_STRING_CHARPOS (*it
) >= it
->end_charpos
)
5285 else if (IT_STRING_CHARPOS (*it
) >= it
->string_nchars
)
5287 /* Pad with spaces. */
5288 it
->c
= ' ', it
->len
= 1;
5289 CHARPOS (position
) = BYTEPOS (position
) = -1;
5291 else if (STRING_MULTIBYTE (it
->string
))
5293 int maxlen
= SBYTES (it
->string
) - IT_STRING_BYTEPOS (*it
);
5294 const unsigned char *s
= (SDATA (it
->string
)
5295 + IT_STRING_BYTEPOS (*it
));
5296 it
->c
= string_char_and_length (s
, maxlen
, &it
->len
);
5300 it
->c
= SREF (it
->string
, IT_STRING_BYTEPOS (*it
));
5305 /* Record what we have and where it came from. Note that we store a
5306 buffer position in IT->position although it could arguably be a
5308 it
->what
= IT_CHARACTER
;
5309 it
->object
= it
->string
;
5310 it
->position
= position
;
5315 /* Load IT with next display element from C string IT->s.
5316 IT->string_nchars is the maximum number of characters to return
5317 from the string. IT->end_charpos may be greater than
5318 IT->string_nchars when this function is called, in which case we
5319 may have to return padding spaces. Value is zero if end of string
5320 reached, including padding spaces. */
5323 next_element_from_c_string (it
)
5329 it
->what
= IT_CHARACTER
;
5330 BYTEPOS (it
->position
) = CHARPOS (it
->position
) = 0;
5333 /* IT's position can be greater IT->string_nchars in case a field
5334 width or precision has been specified when the iterator was
5336 if (IT_CHARPOS (*it
) >= it
->end_charpos
)
5338 /* End of the game. */
5342 else if (IT_CHARPOS (*it
) >= it
->string_nchars
)
5344 /* Pad with spaces. */
5345 it
->c
= ' ', it
->len
= 1;
5346 BYTEPOS (it
->position
) = CHARPOS (it
->position
) = -1;
5348 else if (it
->multibyte_p
)
5350 /* Implementation note: The calls to strlen apparently aren't a
5351 performance problem because there is no noticeable performance
5352 difference between Emacs running in unibyte or multibyte mode. */
5353 int maxlen
= strlen (it
->s
) - IT_BYTEPOS (*it
);
5354 it
->c
= string_char_and_length (it
->s
+ IT_BYTEPOS (*it
),
5358 it
->c
= it
->s
[IT_BYTEPOS (*it
)], it
->len
= 1;
5364 /* Set up IT to return characters from an ellipsis, if appropriate.
5365 The definition of the ellipsis glyphs may come from a display table
5366 entry. This function Fills IT with the first glyph from the
5367 ellipsis if an ellipsis is to be displayed. */
5370 next_element_from_ellipsis (it
)
5373 if (it
->selective_display_ellipsis_p
)
5375 if (it
->dp
&& VECTORP (DISP_INVIS_VECTOR (it
->dp
)))
5377 /* Use the display table definition for `...'. Invalid glyphs
5378 will be handled by the method returning elements from dpvec. */
5379 struct Lisp_Vector
*v
= XVECTOR (DISP_INVIS_VECTOR (it
->dp
));
5380 it
->dpvec_char_len
= it
->len
;
5381 it
->dpvec
= v
->contents
;
5382 it
->dpend
= v
->contents
+ v
->size
;
5383 it
->current
.dpvec_index
= 0;
5384 it
->method
= next_element_from_display_vector
;
5388 /* Use default `...' which is stored in default_invis_vector. */
5389 it
->dpvec_char_len
= it
->len
;
5390 it
->dpvec
= default_invis_vector
;
5391 it
->dpend
= default_invis_vector
+ 3;
5392 it
->current
.dpvec_index
= 0;
5393 it
->method
= next_element_from_display_vector
;
5398 /* The face at the current position may be different from the
5399 face we find after the invisible text. Remember what it
5400 was in IT->saved_face_id, and signal that it's there by
5401 setting face_before_selective_p. */
5402 it
->saved_face_id
= it
->face_id
;
5403 it
->method
= next_element_from_buffer
;
5404 reseat_at_next_visible_line_start (it
, 1);
5405 it
->face_before_selective_p
= 1;
5408 return get_next_display_element (it
);
5412 /* Deliver an image display element. The iterator IT is already
5413 filled with image information (done in handle_display_prop). Value
5418 next_element_from_image (it
)
5421 it
->what
= IT_IMAGE
;
5426 /* Fill iterator IT with next display element from a stretch glyph
5427 property. IT->object is the value of the text property. Value is
5431 next_element_from_stretch (it
)
5434 it
->what
= IT_STRETCH
;
5439 /* Load IT with the next display element from current_buffer. Value
5440 is zero if end of buffer reached. IT->stop_charpos is the next
5441 position at which to stop and check for text properties or buffer
5445 next_element_from_buffer (it
)
5450 /* Check this assumption, otherwise, we would never enter the
5451 if-statement, below. */
5452 xassert (IT_CHARPOS (*it
) >= BEGV
5453 && IT_CHARPOS (*it
) <= it
->stop_charpos
);
5455 if (IT_CHARPOS (*it
) >= it
->stop_charpos
)
5457 if (IT_CHARPOS (*it
) >= it
->end_charpos
)
5459 int overlay_strings_follow_p
;
5461 /* End of the game, except when overlay strings follow that
5462 haven't been returned yet. */
5463 if (it
->overlay_strings_at_end_processed_p
)
5464 overlay_strings_follow_p
= 0;
5467 it
->overlay_strings_at_end_processed_p
= 1;
5468 overlay_strings_follow_p
= get_overlay_strings (it
, 0);
5471 if (overlay_strings_follow_p
)
5472 success_p
= get_next_display_element (it
);
5476 it
->position
= it
->current
.pos
;
5483 return get_next_display_element (it
);
5488 /* No face changes, overlays etc. in sight, so just return a
5489 character from current_buffer. */
5492 /* Maybe run the redisplay end trigger hook. Performance note:
5493 This doesn't seem to cost measurable time. */
5494 if (it
->redisplay_end_trigger_charpos
5496 && IT_CHARPOS (*it
) >= it
->redisplay_end_trigger_charpos
)
5497 run_redisplay_end_trigger_hook (it
);
5499 /* Get the next character, maybe multibyte. */
5500 p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
5501 if (it
->multibyte_p
&& !ASCII_BYTE_P (*p
))
5503 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT_BYTE
? ZV_BYTE
: GPT_BYTE
)
5504 - IT_BYTEPOS (*it
));
5505 it
->c
= string_char_and_length (p
, maxlen
, &it
->len
);
5508 it
->c
= *p
, it
->len
= 1;
5510 /* Record what we have and where it came from. */
5511 it
->what
= IT_CHARACTER
;;
5512 it
->object
= it
->w
->buffer
;
5513 it
->position
= it
->current
.pos
;
5515 /* Normally we return the character found above, except when we
5516 really want to return an ellipsis for selective display. */
5521 /* A value of selective > 0 means hide lines indented more
5522 than that number of columns. */
5523 if (it
->selective
> 0
5524 && IT_CHARPOS (*it
) + 1 < ZV
5525 && indented_beyond_p (IT_CHARPOS (*it
) + 1,
5526 IT_BYTEPOS (*it
) + 1,
5527 (double) it
->selective
)) /* iftc */
5529 success_p
= next_element_from_ellipsis (it
);
5530 it
->dpvec_char_len
= -1;
5533 else if (it
->c
== '\r' && it
->selective
== -1)
5535 /* A value of selective == -1 means that everything from the
5536 CR to the end of the line is invisible, with maybe an
5537 ellipsis displayed for it. */
5538 success_p
= next_element_from_ellipsis (it
);
5539 it
->dpvec_char_len
= -1;
5544 /* Value is zero if end of buffer reached. */
5545 xassert (!success_p
|| it
->what
!= IT_CHARACTER
|| it
->len
> 0);
5550 /* Run the redisplay end trigger hook for IT. */
5553 run_redisplay_end_trigger_hook (it
)
5556 Lisp_Object args
[3];
5558 /* IT->glyph_row should be non-null, i.e. we should be actually
5559 displaying something, or otherwise we should not run the hook. */
5560 xassert (it
->glyph_row
);
5562 /* Set up hook arguments. */
5563 args
[0] = Qredisplay_end_trigger_functions
;
5564 args
[1] = it
->window
;
5565 XSETINT (args
[2], it
->redisplay_end_trigger_charpos
);
5566 it
->redisplay_end_trigger_charpos
= 0;
5568 /* Since we are *trying* to run these functions, don't try to run
5569 them again, even if they get an error. */
5570 it
->w
->redisplay_end_trigger
= Qnil
;
5571 Frun_hook_with_args (3, args
);
5573 /* Notice if it changed the face of the character we are on. */
5574 handle_face_prop (it
);
5578 /* Deliver a composition display element. The iterator IT is already
5579 filled with composition information (done in
5580 handle_composition_prop). Value is always 1. */
5583 next_element_from_composition (it
)
5586 it
->what
= IT_COMPOSITION
;
5587 it
->position
= (STRINGP (it
->string
)
5588 ? it
->current
.string_pos
5595 /***********************************************************************
5596 Moving an iterator without producing glyphs
5597 ***********************************************************************/
5599 /* Move iterator IT to a specified buffer or X position within one
5600 line on the display without producing glyphs.
5602 OP should be a bit mask including some or all of these bits:
5603 MOVE_TO_X: Stop on reaching x-position TO_X.
5604 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
5605 Regardless of OP's value, stop in reaching the end of the display line.
5607 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
5608 This means, in particular, that TO_X includes window's horizontal
5611 The return value has several possible values that
5612 say what condition caused the scan to stop:
5614 MOVE_POS_MATCH_OR_ZV
5615 - when TO_POS or ZV was reached.
5618 -when TO_X was reached before TO_POS or ZV were reached.
5621 - when we reached the end of the display area and the line must
5625 - when we reached the end of the display area and the line is
5629 - when we stopped at a line end, i.e. a newline or a CR and selective
5632 static enum move_it_result
5633 move_it_in_display_line_to (it
, to_charpos
, to_x
, op
)
5635 int to_charpos
, to_x
, op
;
5637 enum move_it_result result
= MOVE_UNDEFINED
;
5638 struct glyph_row
*saved_glyph_row
;
5640 /* Don't produce glyphs in produce_glyphs. */
5641 saved_glyph_row
= it
->glyph_row
;
5642 it
->glyph_row
= NULL
;
5644 #define BUFFER_POS_REACHED_P() \
5645 ((op & MOVE_TO_POS) != 0 \
5646 && BUFFERP (it->object) \
5647 && IT_CHARPOS (*it) >= to_charpos)
5651 int x
, i
, ascent
= 0, descent
= 0;
5653 /* Stop when ZV reached.
5654 We used to stop here when TO_CHARPOS reached as well, but that is
5655 too soon if this glyph does not fit on this line. So we handle it
5656 explicitly below. */
5657 if (!get_next_display_element (it
)
5658 || (it
->truncate_lines_p
5659 && BUFFER_POS_REACHED_P ()))
5661 result
= MOVE_POS_MATCH_OR_ZV
;
5665 /* The call to produce_glyphs will get the metrics of the
5666 display element IT is loaded with. We record in x the
5667 x-position before this display element in case it does not
5671 /* Remember the line height so far in case the next element doesn't
5673 if (!it
->truncate_lines_p
)
5675 ascent
= it
->max_ascent
;
5676 descent
= it
->max_descent
;
5679 PRODUCE_GLYPHS (it
);
5681 if (it
->area
!= TEXT_AREA
)
5683 set_iterator_to_next (it
, 1);
5687 /* The number of glyphs we get back in IT->nglyphs will normally
5688 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
5689 character on a terminal frame, or (iii) a line end. For the
5690 second case, IT->nglyphs - 1 padding glyphs will be present
5691 (on X frames, there is only one glyph produced for a
5692 composite character.
5694 The behavior implemented below means, for continuation lines,
5695 that as many spaces of a TAB as fit on the current line are
5696 displayed there. For terminal frames, as many glyphs of a
5697 multi-glyph character are displayed in the current line, too.
5698 This is what the old redisplay code did, and we keep it that
5699 way. Under X, the whole shape of a complex character must
5700 fit on the line or it will be completely displayed in the
5703 Note that both for tabs and padding glyphs, all glyphs have
5707 /* More than one glyph or glyph doesn't fit on line. All
5708 glyphs have the same width. */
5709 int single_glyph_width
= it
->pixel_width
/ it
->nglyphs
;
5712 for (i
= 0; i
< it
->nglyphs
; ++i
, x
= new_x
)
5714 new_x
= x
+ single_glyph_width
;
5716 /* We want to leave anything reaching TO_X to the caller. */
5717 if ((op
& MOVE_TO_X
) && new_x
> to_x
)
5719 if (BUFFER_POS_REACHED_P ())
5720 goto buffer_pos_reached
;
5722 result
= MOVE_X_REACHED
;
5725 else if (/* Lines are continued. */
5726 !it
->truncate_lines_p
5727 && (/* And glyph doesn't fit on the line. */
5728 new_x
> it
->last_visible_x
5729 /* Or it fits exactly and we're on a window
5731 || (new_x
== it
->last_visible_x
5732 && FRAME_WINDOW_P (it
->f
))))
5734 if (/* IT->hpos == 0 means the very first glyph
5735 doesn't fit on the line, e.g. a wide image. */
5737 || (new_x
== it
->last_visible_x
5738 && FRAME_WINDOW_P (it
->f
)))
5741 it
->current_x
= new_x
;
5742 if (i
== it
->nglyphs
- 1)
5744 set_iterator_to_next (it
, 1);
5745 #ifdef HAVE_WINDOW_SYSTEM
5746 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
5748 if (!get_next_display_element (it
))
5750 result
= MOVE_POS_MATCH_OR_ZV
;
5753 if (BUFFER_POS_REACHED_P ())
5755 if (ITERATOR_AT_END_OF_LINE_P (it
))
5756 result
= MOVE_POS_MATCH_OR_ZV
;
5758 result
= MOVE_LINE_CONTINUED
;
5761 if (ITERATOR_AT_END_OF_LINE_P (it
))
5763 result
= MOVE_NEWLINE_OR_CR
;
5767 #endif /* HAVE_WINDOW_SYSTEM */
5773 it
->max_ascent
= ascent
;
5774 it
->max_descent
= descent
;
5777 TRACE_MOVE ((stderr
, "move_it_in: continued at %d\n",
5779 result
= MOVE_LINE_CONTINUED
;
5782 else if (BUFFER_POS_REACHED_P ())
5783 goto buffer_pos_reached
;
5784 else if (new_x
> it
->first_visible_x
)
5786 /* Glyph is visible. Increment number of glyphs that
5787 would be displayed. */
5792 /* Glyph is completely off the left margin of the display
5793 area. Nothing to do. */
5797 if (result
!= MOVE_UNDEFINED
)
5800 else if (BUFFER_POS_REACHED_P ())
5804 it
->max_ascent
= ascent
;
5805 it
->max_descent
= descent
;
5806 result
= MOVE_POS_MATCH_OR_ZV
;
5809 else if ((op
& MOVE_TO_X
) && it
->current_x
>= to_x
)
5811 /* Stop when TO_X specified and reached. This check is
5812 necessary here because of lines consisting of a line end,
5813 only. The line end will not produce any glyphs and we
5814 would never get MOVE_X_REACHED. */
5815 xassert (it
->nglyphs
== 0);
5816 result
= MOVE_X_REACHED
;
5820 /* Is this a line end? If yes, we're done. */
5821 if (ITERATOR_AT_END_OF_LINE_P (it
))
5823 result
= MOVE_NEWLINE_OR_CR
;
5827 /* The current display element has been consumed. Advance
5829 set_iterator_to_next (it
, 1);
5831 /* Stop if lines are truncated and IT's current x-position is
5832 past the right edge of the window now. */
5833 if (it
->truncate_lines_p
5834 && it
->current_x
>= it
->last_visible_x
)
5836 #ifdef HAVE_WINDOW_SYSTEM
5837 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
5839 if (!get_next_display_element (it
)
5840 || BUFFER_POS_REACHED_P ())
5842 result
= MOVE_POS_MATCH_OR_ZV
;
5845 if (ITERATOR_AT_END_OF_LINE_P (it
))
5847 result
= MOVE_NEWLINE_OR_CR
;
5851 #endif /* HAVE_WINDOW_SYSTEM */
5852 result
= MOVE_LINE_TRUNCATED
;
5857 #undef BUFFER_POS_REACHED_P
5859 /* Restore the iterator settings altered at the beginning of this
5861 it
->glyph_row
= saved_glyph_row
;
5866 /* Move IT forward until it satisfies one or more of the criteria in
5867 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
5869 OP is a bit-mask that specifies where to stop, and in particular,
5870 which of those four position arguments makes a difference. See the
5871 description of enum move_operation_enum.
5873 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
5874 screen line, this function will set IT to the next position >
5878 move_it_to (it
, to_charpos
, to_x
, to_y
, to_vpos
, op
)
5880 int to_charpos
, to_x
, to_y
, to_vpos
;
5883 enum move_it_result skip
, skip2
= MOVE_X_REACHED
;
5889 if (op
& MOVE_TO_VPOS
)
5891 /* If no TO_CHARPOS and no TO_X specified, stop at the
5892 start of the line TO_VPOS. */
5893 if ((op
& (MOVE_TO_X
| MOVE_TO_POS
)) == 0)
5895 if (it
->vpos
== to_vpos
)
5901 skip
= move_it_in_display_line_to (it
, -1, -1, 0);
5905 /* TO_VPOS >= 0 means stop at TO_X in the line at
5906 TO_VPOS, or at TO_POS, whichever comes first. */
5907 if (it
->vpos
== to_vpos
)
5913 skip
= move_it_in_display_line_to (it
, to_charpos
, to_x
, op
);
5915 if (skip
== MOVE_POS_MATCH_OR_ZV
|| it
->vpos
== to_vpos
)
5920 else if (skip
== MOVE_X_REACHED
&& it
->vpos
!= to_vpos
)
5922 /* We have reached TO_X but not in the line we want. */
5923 skip
= move_it_in_display_line_to (it
, to_charpos
,
5925 if (skip
== MOVE_POS_MATCH_OR_ZV
)
5933 else if (op
& MOVE_TO_Y
)
5935 struct it it_backup
;
5937 /* TO_Y specified means stop at TO_X in the line containing
5938 TO_Y---or at TO_CHARPOS if this is reached first. The
5939 problem is that we can't really tell whether the line
5940 contains TO_Y before we have completely scanned it, and
5941 this may skip past TO_X. What we do is to first scan to
5944 If TO_X is not specified, use a TO_X of zero. The reason
5945 is to make the outcome of this function more predictable.
5946 If we didn't use TO_X == 0, we would stop at the end of
5947 the line which is probably not what a caller would expect
5949 skip
= move_it_in_display_line_to (it
, to_charpos
,
5953 | (op
& MOVE_TO_POS
)));
5955 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
5956 if (skip
== MOVE_POS_MATCH_OR_ZV
)
5962 /* If TO_X was reached, we would like to know whether TO_Y
5963 is in the line. This can only be said if we know the
5964 total line height which requires us to scan the rest of
5966 if (skip
== MOVE_X_REACHED
)
5969 TRACE_MOVE ((stderr
, "move_it: from %d\n", IT_CHARPOS (*it
)));
5970 skip2
= move_it_in_display_line_to (it
, to_charpos
, -1,
5972 TRACE_MOVE ((stderr
, "move_it: to %d\n", IT_CHARPOS (*it
)));
5975 /* Now, decide whether TO_Y is in this line. */
5976 line_height
= it
->max_ascent
+ it
->max_descent
;
5977 TRACE_MOVE ((stderr
, "move_it: line_height = %d\n", line_height
));
5979 if (to_y
>= it
->current_y
5980 && to_y
< it
->current_y
+ line_height
)
5982 if (skip
== MOVE_X_REACHED
)
5983 /* If TO_Y is in this line and TO_X was reached above,
5984 we scanned too far. We have to restore IT's settings
5985 to the ones before skipping. */
5989 else if (skip
== MOVE_X_REACHED
)
5992 if (skip
== MOVE_POS_MATCH_OR_ZV
)
6000 skip
= move_it_in_display_line_to (it
, to_charpos
, -1, MOVE_TO_POS
);
6004 case MOVE_POS_MATCH_OR_ZV
:
6008 case MOVE_NEWLINE_OR_CR
:
6009 set_iterator_to_next (it
, 1);
6010 it
->continuation_lines_width
= 0;
6013 case MOVE_LINE_TRUNCATED
:
6014 it
->continuation_lines_width
= 0;
6015 reseat_at_next_visible_line_start (it
, 0);
6016 if ((op
& MOVE_TO_POS
) != 0
6017 && IT_CHARPOS (*it
) > to_charpos
)
6024 case MOVE_LINE_CONTINUED
:
6025 it
->continuation_lines_width
+= it
->current_x
;
6032 /* Reset/increment for the next run. */
6033 recenter_overlay_lists (current_buffer
, IT_CHARPOS (*it
));
6034 it
->current_x
= it
->hpos
= 0;
6035 it
->current_y
+= it
->max_ascent
+ it
->max_descent
;
6037 last_height
= it
->max_ascent
+ it
->max_descent
;
6038 last_max_ascent
= it
->max_ascent
;
6039 it
->max_ascent
= it
->max_descent
= 0;
6044 TRACE_MOVE ((stderr
, "move_it_to: reached %d\n", reached
));
6048 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
6050 If DY > 0, move IT backward at least that many pixels. DY = 0
6051 means move IT backward to the preceding line start or BEGV. This
6052 function may move over more than DY pixels if IT->current_y - DY
6053 ends up in the middle of a line; in this case IT->current_y will be
6054 set to the top of the line moved to. */
6057 move_it_vertically_backward (it
, dy
)
6063 int start_pos
= IT_CHARPOS (*it
);
6067 /* Estimate how many newlines we must move back. */
6068 nlines
= max (1, dy
/ FRAME_LINE_HEIGHT (it
->f
));
6070 /* Set the iterator's position that many lines back. */
6071 while (nlines
-- && IT_CHARPOS (*it
) > BEGV
)
6072 back_to_previous_visible_line_start (it
);
6074 /* Reseat the iterator here. When moving backward, we don't want
6075 reseat to skip forward over invisible text, set up the iterator
6076 to deliver from overlay strings at the new position etc. So,
6077 use reseat_1 here. */
6078 reseat_1 (it
, it
->current
.pos
, 1);
6080 /* We are now surely at a line start. */
6081 it
->current_x
= it
->hpos
= 0;
6082 it
->continuation_lines_width
= 0;
6084 /* Move forward and see what y-distance we moved. First move to the
6085 start of the next line so that we get its height. We need this
6086 height to be able to tell whether we reached the specified
6089 it2
.max_ascent
= it2
.max_descent
= 0;
6090 move_it_to (&it2
, start_pos
, -1, -1, it2
.vpos
+ 1,
6091 MOVE_TO_POS
| MOVE_TO_VPOS
);
6092 xassert (IT_CHARPOS (*it
) >= BEGV
);
6095 move_it_to (&it2
, start_pos
, -1, -1, -1, MOVE_TO_POS
);
6096 xassert (IT_CHARPOS (*it
) >= BEGV
);
6097 /* H is the actual vertical distance from the position in *IT
6098 and the starting position. */
6099 h
= it2
.current_y
- it
->current_y
;
6100 /* NLINES is the distance in number of lines. */
6101 nlines
= it2
.vpos
- it
->vpos
;
6103 /* Correct IT's y and vpos position
6104 so that they are relative to the starting point. */
6110 /* DY == 0 means move to the start of the screen line. The
6111 value of nlines is > 0 if continuation lines were involved. */
6113 move_it_by_lines (it
, nlines
, 1);
6114 xassert (IT_CHARPOS (*it
) <= start_pos
);
6118 /* The y-position we try to reach, relative to *IT.
6119 Note that H has been subtracted in front of the if-statement. */
6120 int target_y
= it
->current_y
+ h
- dy
;
6121 int y0
= it3
.current_y
;
6122 int y1
= line_bottom_y (&it3
);
6123 int line_height
= y1
- y0
;
6125 /* If we did not reach target_y, try to move further backward if
6126 we can. If we moved too far backward, try to move forward. */
6127 if (target_y
< it
->current_y
6128 /* This is heuristic. In a window that's 3 lines high, with
6129 a line height of 13 pixels each, recentering with point
6130 on the bottom line will try to move -39/2 = 19 pixels
6131 backward. Try to avoid moving into the first line. */
6132 && it
->current_y
- target_y
> line_height
/ 3 * 2
6133 && IT_CHARPOS (*it
) > BEGV
)
6135 TRACE_MOVE ((stderr
, " not far enough -> move_vert %d\n",
6136 target_y
- it
->current_y
));
6137 move_it_vertically (it
, target_y
- it
->current_y
);
6138 xassert (IT_CHARPOS (*it
) >= BEGV
);
6140 else if (target_y
>= it
->current_y
+ line_height
6141 && IT_CHARPOS (*it
) < ZV
)
6143 /* Should move forward by at least one line, maybe more.
6145 Note: Calling move_it_by_lines can be expensive on
6146 terminal frames, where compute_motion is used (via
6147 vmotion) to do the job, when there are very long lines
6148 and truncate-lines is nil. That's the reason for
6149 treating terminal frames specially here. */
6151 if (!FRAME_WINDOW_P (it
->f
))
6152 move_it_vertically (it
, target_y
- (it
->current_y
+ line_height
));
6157 move_it_by_lines (it
, 1, 1);
6159 while (target_y
>= line_bottom_y (it
) && IT_CHARPOS (*it
) < ZV
);
6162 xassert (IT_CHARPOS (*it
) >= BEGV
);
6168 /* Move IT by a specified amount of pixel lines DY. DY negative means
6169 move backwards. DY = 0 means move to start of screen line. At the
6170 end, IT will be on the start of a screen line. */
6173 move_it_vertically (it
, dy
)
6178 move_it_vertically_backward (it
, -dy
);
6181 TRACE_MOVE ((stderr
, "move_it_v: from %d, %d\n", IT_CHARPOS (*it
), dy
));
6182 move_it_to (it
, ZV
, -1, it
->current_y
+ dy
, -1,
6183 MOVE_TO_POS
| MOVE_TO_Y
);
6184 TRACE_MOVE ((stderr
, "move_it_v: to %d\n", IT_CHARPOS (*it
)));
6186 /* If buffer ends in ZV without a newline, move to the start of
6187 the line to satisfy the post-condition. */
6188 if (IT_CHARPOS (*it
) == ZV
6189 && FETCH_BYTE (IT_BYTEPOS (*it
) - 1) != '\n')
6190 move_it_by_lines (it
, 0, 0);
6195 /* Move iterator IT past the end of the text line it is in. */
6198 move_it_past_eol (it
)
6201 enum move_it_result rc
;
6203 rc
= move_it_in_display_line_to (it
, Z
, 0, MOVE_TO_POS
);
6204 if (rc
== MOVE_NEWLINE_OR_CR
)
6205 set_iterator_to_next (it
, 0);
6209 #if 0 /* Currently not used. */
6211 /* Return non-zero if some text between buffer positions START_CHARPOS
6212 and END_CHARPOS is invisible. IT->window is the window for text
6216 invisible_text_between_p (it
, start_charpos
, end_charpos
)
6218 int start_charpos
, end_charpos
;
6220 Lisp_Object prop
, limit
;
6221 int invisible_found_p
;
6223 xassert (it
!= NULL
&& start_charpos
<= end_charpos
);
6225 /* Is text at START invisible? */
6226 prop
= Fget_char_property (make_number (start_charpos
), Qinvisible
,
6228 if (TEXT_PROP_MEANS_INVISIBLE (prop
))
6229 invisible_found_p
= 1;
6232 limit
= Fnext_single_char_property_change (make_number (start_charpos
),
6234 make_number (end_charpos
));
6235 invisible_found_p
= XFASTINT (limit
) < end_charpos
;
6238 return invisible_found_p
;
6244 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
6245 negative means move up. DVPOS == 0 means move to the start of the
6246 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
6247 NEED_Y_P is zero, IT->current_y will be left unchanged.
6249 Further optimization ideas: If we would know that IT->f doesn't use
6250 a face with proportional font, we could be faster for
6251 truncate-lines nil. */
6254 move_it_by_lines (it
, dvpos
, need_y_p
)
6256 int dvpos
, need_y_p
;
6258 struct position pos
;
6260 if (!FRAME_WINDOW_P (it
->f
))
6262 struct text_pos textpos
;
6264 /* We can use vmotion on frames without proportional fonts. */
6265 pos
= *vmotion (IT_CHARPOS (*it
), dvpos
, it
->w
);
6266 SET_TEXT_POS (textpos
, pos
.bufpos
, pos
.bytepos
);
6267 reseat (it
, textpos
, 1);
6268 it
->vpos
+= pos
.vpos
;
6269 it
->current_y
+= pos
.vpos
;
6271 else if (dvpos
== 0)
6273 /* DVPOS == 0 means move to the start of the screen line. */
6274 move_it_vertically_backward (it
, 0);
6275 xassert (it
->current_x
== 0 && it
->hpos
== 0);
6278 move_it_to (it
, -1, -1, -1, it
->vpos
+ dvpos
, MOVE_TO_VPOS
);
6282 int start_charpos
, i
;
6284 /* Start at the beginning of the screen line containing IT's
6286 move_it_vertically_backward (it
, 0);
6288 /* Go back -DVPOS visible lines and reseat the iterator there. */
6289 start_charpos
= IT_CHARPOS (*it
);
6290 for (i
= -dvpos
; i
&& IT_CHARPOS (*it
) > BEGV
; --i
)
6291 back_to_previous_visible_line_start (it
);
6292 reseat (it
, it
->current
.pos
, 1);
6293 it
->current_x
= it
->hpos
= 0;
6295 /* Above call may have moved too far if continuation lines
6296 are involved. Scan forward and see if it did. */
6298 it2
.vpos
= it2
.current_y
= 0;
6299 move_it_to (&it2
, start_charpos
, -1, -1, -1, MOVE_TO_POS
);
6300 it
->vpos
-= it2
.vpos
;
6301 it
->current_y
-= it2
.current_y
;
6302 it
->current_x
= it
->hpos
= 0;
6304 /* If we moved too far, move IT some lines forward. */
6305 if (it2
.vpos
> -dvpos
)
6307 int delta
= it2
.vpos
+ dvpos
;
6308 move_it_to (it
, -1, -1, -1, it
->vpos
+ delta
, MOVE_TO_VPOS
);
6313 /* Return 1 if IT points into the middle of a display vector. */
6316 in_display_vector_p (it
)
6319 return (it
->method
== next_element_from_display_vector
6320 && it
->current
.dpvec_index
> 0
6321 && it
->dpvec
+ it
->current
.dpvec_index
!= it
->dpend
);
6325 /***********************************************************************
6327 ***********************************************************************/
6330 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
6334 add_to_log (format
, arg1
, arg2
)
6336 Lisp_Object arg1
, arg2
;
6338 Lisp_Object args
[3];
6339 Lisp_Object msg
, fmt
;
6342 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
6345 /* Do nothing if called asynchronously. Inserting text into
6346 a buffer may call after-change-functions and alike and
6347 that would means running Lisp asynchronously. */
6348 if (handling_signal
)
6352 GCPRO4 (fmt
, msg
, arg1
, arg2
);
6354 args
[0] = fmt
= build_string (format
);
6357 msg
= Fformat (3, args
);
6359 len
= SBYTES (msg
) + 1;
6360 SAFE_ALLOCA (buffer
, char *, len
);
6361 bcopy (SDATA (msg
), buffer
, len
);
6363 message_dolog (buffer
, len
- 1, 1, 0);
6370 /* Output a newline in the *Messages* buffer if "needs" one. */
6373 message_log_maybe_newline ()
6375 if (message_log_need_newline
)
6376 message_dolog ("", 0, 1, 0);
6380 /* Add a string M of length NBYTES to the message log, optionally
6381 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
6382 nonzero, means interpret the contents of M as multibyte. This
6383 function calls low-level routines in order to bypass text property
6384 hooks, etc. which might not be safe to run. */
6387 message_dolog (m
, nbytes
, nlflag
, multibyte
)
6389 int nbytes
, nlflag
, multibyte
;
6391 if (!NILP (Vmemory_full
))
6394 if (!NILP (Vmessage_log_max
))
6396 struct buffer
*oldbuf
;
6397 Lisp_Object oldpoint
, oldbegv
, oldzv
;
6398 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
6399 int point_at_end
= 0;
6401 Lisp_Object old_deactivate_mark
, tem
;
6402 struct gcpro gcpro1
;
6404 old_deactivate_mark
= Vdeactivate_mark
;
6405 oldbuf
= current_buffer
;
6406 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name
));
6407 current_buffer
->undo_list
= Qt
;
6409 oldpoint
= message_dolog_marker1
;
6410 set_marker_restricted (oldpoint
, make_number (PT
), Qnil
);
6411 oldbegv
= message_dolog_marker2
;
6412 set_marker_restricted (oldbegv
, make_number (BEGV
), Qnil
);
6413 oldzv
= message_dolog_marker3
;
6414 set_marker_restricted (oldzv
, make_number (ZV
), Qnil
);
6415 GCPRO1 (old_deactivate_mark
);
6423 BEGV_BYTE
= BEG_BYTE
;
6426 TEMP_SET_PT_BOTH (Z
, Z_BYTE
);
6428 /* Insert the string--maybe converting multibyte to single byte
6429 or vice versa, so that all the text fits the buffer. */
6431 && NILP (current_buffer
->enable_multibyte_characters
))
6433 int i
, c
, char_bytes
;
6434 unsigned char work
[1];
6436 /* Convert a multibyte string to single-byte
6437 for the *Message* buffer. */
6438 for (i
= 0; i
< nbytes
; i
+= char_bytes
)
6440 c
= string_char_and_length (m
+ i
, nbytes
- i
, &char_bytes
);
6441 work
[0] = (SINGLE_BYTE_CHAR_P (c
)
6443 : multibyte_char_to_unibyte (c
, Qnil
));
6444 insert_1_both (work
, 1, 1, 1, 0, 0);
6447 else if (! multibyte
6448 && ! NILP (current_buffer
->enable_multibyte_characters
))
6450 int i
, c
, char_bytes
;
6451 unsigned char *msg
= (unsigned char *) m
;
6452 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
6453 /* Convert a single-byte string to multibyte
6454 for the *Message* buffer. */
6455 for (i
= 0; i
< nbytes
; i
++)
6457 c
= unibyte_char_to_multibyte (msg
[i
]);
6458 char_bytes
= CHAR_STRING (c
, str
);
6459 insert_1_both (str
, 1, char_bytes
, 1, 0, 0);
6463 insert_1 (m
, nbytes
, 1, 0, 0);
6467 int this_bol
, this_bol_byte
, prev_bol
, prev_bol_byte
, dup
;
6468 insert_1 ("\n", 1, 1, 0, 0);
6470 scan_newline (Z
, Z_BYTE
, BEG
, BEG_BYTE
, -2, 0);
6472 this_bol_byte
= PT_BYTE
;
6474 /* See if this line duplicates the previous one.
6475 If so, combine duplicates. */
6478 scan_newline (PT
, PT_BYTE
, BEG
, BEG_BYTE
, -2, 0);
6480 prev_bol_byte
= PT_BYTE
;
6482 dup
= message_log_check_duplicate (prev_bol
, prev_bol_byte
,
6483 this_bol
, this_bol_byte
);
6486 del_range_both (prev_bol
, prev_bol_byte
,
6487 this_bol
, this_bol_byte
, 0);
6493 /* If you change this format, don't forget to also
6494 change message_log_check_duplicate. */
6495 sprintf (dupstr
, " [%d times]", dup
);
6496 duplen
= strlen (dupstr
);
6497 TEMP_SET_PT_BOTH (Z
- 1, Z_BYTE
- 1);
6498 insert_1 (dupstr
, duplen
, 1, 0, 1);
6503 /* If we have more than the desired maximum number of lines
6504 in the *Messages* buffer now, delete the oldest ones.
6505 This is safe because we don't have undo in this buffer. */
6507 if (NATNUMP (Vmessage_log_max
))
6509 scan_newline (Z
, Z_BYTE
, BEG
, BEG_BYTE
,
6510 -XFASTINT (Vmessage_log_max
) - 1, 0);
6511 del_range_both (BEG
, BEG_BYTE
, PT
, PT_BYTE
, 0);
6514 BEGV
= XMARKER (oldbegv
)->charpos
;
6515 BEGV_BYTE
= marker_byte_position (oldbegv
);
6524 ZV
= XMARKER (oldzv
)->charpos
;
6525 ZV_BYTE
= marker_byte_position (oldzv
);
6529 TEMP_SET_PT_BOTH (Z
, Z_BYTE
);
6531 /* We can't do Fgoto_char (oldpoint) because it will run some
6533 TEMP_SET_PT_BOTH (XMARKER (oldpoint
)->charpos
,
6534 XMARKER (oldpoint
)->bytepos
);
6537 unchain_marker (XMARKER (oldpoint
));
6538 unchain_marker (XMARKER (oldbegv
));
6539 unchain_marker (XMARKER (oldzv
));
6541 tem
= Fget_buffer_window (Fcurrent_buffer (), Qt
);
6542 set_buffer_internal (oldbuf
);
6544 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
6545 message_log_need_newline
= !nlflag
;
6546 Vdeactivate_mark
= old_deactivate_mark
;
6551 /* We are at the end of the buffer after just having inserted a newline.
6552 (Note: We depend on the fact we won't be crossing the gap.)
6553 Check to see if the most recent message looks a lot like the previous one.
6554 Return 0 if different, 1 if the new one should just replace it, or a
6555 value N > 1 if we should also append " [N times]". */
6558 message_log_check_duplicate (prev_bol
, prev_bol_byte
, this_bol
, this_bol_byte
)
6559 int prev_bol
, this_bol
;
6560 int prev_bol_byte
, this_bol_byte
;
6563 int len
= Z_BYTE
- 1 - this_bol_byte
;
6565 unsigned char *p1
= BUF_BYTE_ADDRESS (current_buffer
, prev_bol_byte
);
6566 unsigned char *p2
= BUF_BYTE_ADDRESS (current_buffer
, this_bol_byte
);
6568 for (i
= 0; i
< len
; i
++)
6570 if (i
>= 3 && p1
[i
-3] == '.' && p1
[i
-2] == '.' && p1
[i
-1] == '.')
6578 if (*p1
++ == ' ' && *p1
++ == '[')
6581 while (*p1
>= '0' && *p1
<= '9')
6582 n
= n
* 10 + *p1
++ - '0';
6583 if (strncmp (p1
, " times]\n", 8) == 0)
6590 /* Display an echo area message M with a specified length of NBYTES
6591 bytes. The string may include null characters. If M is 0, clear
6592 out any existing message, and let the mini-buffer text show
6595 The buffer M must continue to exist until after the echo area gets
6596 cleared or some other message gets displayed there. This means do
6597 not pass text that is stored in a Lisp string; do not pass text in
6598 a buffer that was alloca'd. */
6601 message2 (m
, nbytes
, multibyte
)
6606 /* First flush out any partial line written with print. */
6607 message_log_maybe_newline ();
6609 message_dolog (m
, nbytes
, 1, multibyte
);
6610 message2_nolog (m
, nbytes
, multibyte
);
6614 /* The non-logging counterpart of message2. */
6617 message2_nolog (m
, nbytes
, multibyte
)
6619 int nbytes
, multibyte
;
6621 struct frame
*sf
= SELECTED_FRAME ();
6622 message_enable_multibyte
= multibyte
;
6626 if (noninteractive_need_newline
)
6627 putc ('\n', stderr
);
6628 noninteractive_need_newline
= 0;
6630 fwrite (m
, nbytes
, 1, stderr
);
6631 if (cursor_in_echo_area
== 0)
6632 fprintf (stderr
, "\n");
6635 /* A null message buffer means that the frame hasn't really been
6636 initialized yet. Error messages get reported properly by
6637 cmd_error, so this must be just an informative message; toss it. */
6638 else if (INTERACTIVE
6639 && sf
->glyphs_initialized_p
6640 && FRAME_MESSAGE_BUF (sf
))
6642 Lisp_Object mini_window
;
6645 /* Get the frame containing the mini-buffer
6646 that the selected frame is using. */
6647 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
6648 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
6650 FRAME_SAMPLE_VISIBILITY (f
);
6651 if (FRAME_VISIBLE_P (sf
)
6652 && ! FRAME_VISIBLE_P (f
))
6653 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window
)));
6657 set_message (m
, Qnil
, nbytes
, multibyte
);
6658 if (minibuffer_auto_raise
)
6659 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window
)));
6662 clear_message (1, 1);
6664 do_pending_window_change (0);
6665 echo_area_display (1);
6666 do_pending_window_change (0);
6667 if (frame_up_to_date_hook
!= 0 && ! gc_in_progress
)
6668 (*frame_up_to_date_hook
) (f
);
6673 /* Display an echo area message M with a specified length of NBYTES
6674 bytes. The string may include null characters. If M is not a
6675 string, clear out any existing message, and let the mini-buffer
6676 text show through. */
6679 message3 (m
, nbytes
, multibyte
)
6684 struct gcpro gcpro1
;
6688 /* First flush out any partial line written with print. */
6689 message_log_maybe_newline ();
6691 message_dolog (SDATA (m
), nbytes
, 1, multibyte
);
6692 message3_nolog (m
, nbytes
, multibyte
);
6698 /* The non-logging version of message3. */
6701 message3_nolog (m
, nbytes
, multibyte
)
6703 int nbytes
, multibyte
;
6705 struct frame
*sf
= SELECTED_FRAME ();
6706 message_enable_multibyte
= multibyte
;
6710 if (noninteractive_need_newline
)
6711 putc ('\n', stderr
);
6712 noninteractive_need_newline
= 0;
6714 fwrite (SDATA (m
), nbytes
, 1, stderr
);
6715 if (cursor_in_echo_area
== 0)
6716 fprintf (stderr
, "\n");
6719 /* A null message buffer means that the frame hasn't really been
6720 initialized yet. Error messages get reported properly by
6721 cmd_error, so this must be just an informative message; toss it. */
6722 else if (INTERACTIVE
6723 && sf
->glyphs_initialized_p
6724 && FRAME_MESSAGE_BUF (sf
))
6726 Lisp_Object mini_window
;
6730 /* Get the frame containing the mini-buffer
6731 that the selected frame is using. */
6732 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
6733 frame
= XWINDOW (mini_window
)->frame
;
6736 FRAME_SAMPLE_VISIBILITY (f
);
6737 if (FRAME_VISIBLE_P (sf
)
6738 && !FRAME_VISIBLE_P (f
))
6739 Fmake_frame_visible (frame
);
6741 if (STRINGP (m
) && SCHARS (m
) > 0)
6743 set_message (NULL
, m
, nbytes
, multibyte
);
6744 if (minibuffer_auto_raise
)
6745 Fraise_frame (frame
);
6748 clear_message (1, 1);
6750 do_pending_window_change (0);
6751 echo_area_display (1);
6752 do_pending_window_change (0);
6753 if (frame_up_to_date_hook
!= 0 && ! gc_in_progress
)
6754 (*frame_up_to_date_hook
) (f
);
6759 /* Display a null-terminated echo area message M. If M is 0, clear
6760 out any existing message, and let the mini-buffer text show through.
6762 The buffer M must continue to exist until after the echo area gets
6763 cleared or some other message gets displayed there. Do not pass
6764 text that is stored in a Lisp string. Do not pass text in a buffer
6765 that was alloca'd. */
6771 message2 (m
, (m
? strlen (m
) : 0), 0);
6775 /* The non-logging counterpart of message1. */
6781 message2_nolog (m
, (m
? strlen (m
) : 0), 0);
6784 /* Display a message M which contains a single %s
6785 which gets replaced with STRING. */
6788 message_with_string (m
, string
, log
)
6793 CHECK_STRING (string
);
6799 if (noninteractive_need_newline
)
6800 putc ('\n', stderr
);
6801 noninteractive_need_newline
= 0;
6802 fprintf (stderr
, m
, SDATA (string
));
6803 if (cursor_in_echo_area
== 0)
6804 fprintf (stderr
, "\n");
6808 else if (INTERACTIVE
)
6810 /* The frame whose minibuffer we're going to display the message on.
6811 It may be larger than the selected frame, so we need
6812 to use its buffer, not the selected frame's buffer. */
6813 Lisp_Object mini_window
;
6814 struct frame
*f
, *sf
= SELECTED_FRAME ();
6816 /* Get the frame containing the minibuffer
6817 that the selected frame is using. */
6818 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
6819 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
6821 /* A null message buffer means that the frame hasn't really been
6822 initialized yet. Error messages get reported properly by
6823 cmd_error, so this must be just an informative message; toss it. */
6824 if (FRAME_MESSAGE_BUF (f
))
6826 Lisp_Object args
[2], message
;
6827 struct gcpro gcpro1
, gcpro2
;
6829 args
[0] = build_string (m
);
6830 args
[1] = message
= string
;
6831 GCPRO2 (args
[0], message
);
6834 message
= Fformat (2, args
);
6837 message3 (message
, SBYTES (message
), STRING_MULTIBYTE (message
));
6839 message3_nolog (message
, SBYTES (message
), STRING_MULTIBYTE (message
));
6843 /* Print should start at the beginning of the message
6844 buffer next time. */
6845 message_buf_print
= 0;
6851 /* Dump an informative message to the minibuf. If M is 0, clear out
6852 any existing message, and let the mini-buffer text show through. */
6856 message (m
, a1
, a2
, a3
)
6858 EMACS_INT a1
, a2
, a3
;
6864 if (noninteractive_need_newline
)
6865 putc ('\n', stderr
);
6866 noninteractive_need_newline
= 0;
6867 fprintf (stderr
, m
, a1
, a2
, a3
);
6868 if (cursor_in_echo_area
== 0)
6869 fprintf (stderr
, "\n");
6873 else if (INTERACTIVE
)
6875 /* The frame whose mini-buffer we're going to display the message
6876 on. It may be larger than the selected frame, so we need to
6877 use its buffer, not the selected frame's buffer. */
6878 Lisp_Object mini_window
;
6879 struct frame
*f
, *sf
= SELECTED_FRAME ();
6881 /* Get the frame containing the mini-buffer
6882 that the selected frame is using. */
6883 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
6884 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
6886 /* A null message buffer means that the frame hasn't really been
6887 initialized yet. Error messages get reported properly by
6888 cmd_error, so this must be just an informative message; toss
6890 if (FRAME_MESSAGE_BUF (f
))
6901 len
= doprnt (FRAME_MESSAGE_BUF (f
),
6902 FRAME_MESSAGE_BUF_SIZE (f
), m
, (char *)0, 3, a
);
6904 len
= doprnt (FRAME_MESSAGE_BUF (f
),
6905 FRAME_MESSAGE_BUF_SIZE (f
), m
, (char *)0, 3,
6907 #endif /* NO_ARG_ARRAY */
6909 message2 (FRAME_MESSAGE_BUF (f
), len
, 0);
6914 /* Print should start at the beginning of the message
6915 buffer next time. */
6916 message_buf_print
= 0;
6922 /* The non-logging version of message. */
6925 message_nolog (m
, a1
, a2
, a3
)
6927 EMACS_INT a1
, a2
, a3
;
6929 Lisp_Object old_log_max
;
6930 old_log_max
= Vmessage_log_max
;
6931 Vmessage_log_max
= Qnil
;
6932 message (m
, a1
, a2
, a3
);
6933 Vmessage_log_max
= old_log_max
;
6937 /* Display the current message in the current mini-buffer. This is
6938 only called from error handlers in process.c, and is not time
6944 if (!NILP (echo_area_buffer
[0]))
6947 string
= Fcurrent_message ();
6948 message3 (string
, SBYTES (string
),
6949 !NILP (current_buffer
->enable_multibyte_characters
));
6954 /* Make sure echo area buffers in `echo_buffers' are live.
6955 If they aren't, make new ones. */
6958 ensure_echo_area_buffers ()
6962 for (i
= 0; i
< 2; ++i
)
6963 if (!BUFFERP (echo_buffer
[i
])
6964 || NILP (XBUFFER (echo_buffer
[i
])->name
))
6967 Lisp_Object old_buffer
;
6970 old_buffer
= echo_buffer
[i
];
6971 sprintf (name
, " *Echo Area %d*", i
);
6972 echo_buffer
[i
] = Fget_buffer_create (build_string (name
));
6973 XBUFFER (echo_buffer
[i
])->truncate_lines
= Qnil
;
6975 for (j
= 0; j
< 2; ++j
)
6976 if (EQ (old_buffer
, echo_area_buffer
[j
]))
6977 echo_area_buffer
[j
] = echo_buffer
[i
];
6982 /* Call FN with args A1..A4 with either the current or last displayed
6983 echo_area_buffer as current buffer.
6985 WHICH zero means use the current message buffer
6986 echo_area_buffer[0]. If that is nil, choose a suitable buffer
6987 from echo_buffer[] and clear it.
6989 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
6990 suitable buffer from echo_buffer[] and clear it.
6992 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
6993 that the current message becomes the last displayed one, make
6994 choose a suitable buffer for echo_area_buffer[0], and clear it.
6996 Value is what FN returns. */
6999 with_echo_area_buffer (w
, which
, fn
, a1
, a2
, a3
, a4
)
7002 int (*fn
) P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
7008 int this_one
, the_other
, clear_buffer_p
, rc
;
7009 int count
= SPECPDL_INDEX ();
7011 /* If buffers aren't live, make new ones. */
7012 ensure_echo_area_buffers ();
7017 this_one
= 0, the_other
= 1;
7019 this_one
= 1, the_other
= 0;
7022 this_one
= 0, the_other
= 1;
7025 /* We need a fresh one in case the current echo buffer equals
7026 the one containing the last displayed echo area message. */
7027 if (!NILP (echo_area_buffer
[this_one
])
7028 && EQ (echo_area_buffer
[this_one
], echo_area_buffer
[the_other
]))
7029 echo_area_buffer
[this_one
] = Qnil
;
7032 /* Choose a suitable buffer from echo_buffer[] is we don't
7034 if (NILP (echo_area_buffer
[this_one
]))
7036 echo_area_buffer
[this_one
]
7037 = (EQ (echo_area_buffer
[the_other
], echo_buffer
[this_one
])
7038 ? echo_buffer
[the_other
]
7039 : echo_buffer
[this_one
]);
7043 buffer
= echo_area_buffer
[this_one
];
7045 /* Don't get confused by reusing the buffer used for echoing
7046 for a different purpose. */
7047 if (echo_kboard
== NULL
&& EQ (buffer
, echo_message_buffer
))
7050 record_unwind_protect (unwind_with_echo_area_buffer
,
7051 with_echo_area_buffer_unwind_data (w
));
7053 /* Make the echo area buffer current. Note that for display
7054 purposes, it is not necessary that the displayed window's buffer
7055 == current_buffer, except for text property lookup. So, let's
7056 only set that buffer temporarily here without doing a full
7057 Fset_window_buffer. We must also change w->pointm, though,
7058 because otherwise an assertions in unshow_buffer fails, and Emacs
7060 set_buffer_internal_1 (XBUFFER (buffer
));
7064 set_marker_both (w
->pointm
, buffer
, BEG
, BEG_BYTE
);
7067 current_buffer
->undo_list
= Qt
;
7068 current_buffer
->read_only
= Qnil
;
7069 specbind (Qinhibit_read_only
, Qt
);
7070 specbind (Qinhibit_modification_hooks
, Qt
);
7072 if (clear_buffer_p
&& Z
> BEG
)
7075 xassert (BEGV
>= BEG
);
7076 xassert (ZV
<= Z
&& ZV
>= BEGV
);
7078 rc
= fn (a1
, a2
, a3
, a4
);
7080 xassert (BEGV
>= BEG
);
7081 xassert (ZV
<= Z
&& ZV
>= BEGV
);
7083 unbind_to (count
, Qnil
);
7088 /* Save state that should be preserved around the call to the function
7089 FN called in with_echo_area_buffer. */
7092 with_echo_area_buffer_unwind_data (w
)
7098 /* Reduce consing by keeping one vector in
7099 Vwith_echo_area_save_vector. */
7100 vector
= Vwith_echo_area_save_vector
;
7101 Vwith_echo_area_save_vector
= Qnil
;
7104 vector
= Fmake_vector (make_number (7), Qnil
);
7106 XSETBUFFER (AREF (vector
, i
), current_buffer
); ++i
;
7107 AREF (vector
, i
) = Vdeactivate_mark
, ++i
;
7108 AREF (vector
, i
) = make_number (windows_or_buffers_changed
), ++i
;
7112 XSETWINDOW (AREF (vector
, i
), w
); ++i
;
7113 AREF (vector
, i
) = w
->buffer
; ++i
;
7114 AREF (vector
, i
) = make_number (XMARKER (w
->pointm
)->charpos
); ++i
;
7115 AREF (vector
, i
) = make_number (XMARKER (w
->pointm
)->bytepos
); ++i
;
7120 for (; i
< end
; ++i
)
7121 AREF (vector
, i
) = Qnil
;
7124 xassert (i
== ASIZE (vector
));
7129 /* Restore global state from VECTOR which was created by
7130 with_echo_area_buffer_unwind_data. */
7133 unwind_with_echo_area_buffer (vector
)
7136 set_buffer_internal_1 (XBUFFER (AREF (vector
, 0)));
7137 Vdeactivate_mark
= AREF (vector
, 1);
7138 windows_or_buffers_changed
= XFASTINT (AREF (vector
, 2));
7140 if (WINDOWP (AREF (vector
, 3)))
7143 Lisp_Object buffer
, charpos
, bytepos
;
7145 w
= XWINDOW (AREF (vector
, 3));
7146 buffer
= AREF (vector
, 4);
7147 charpos
= AREF (vector
, 5);
7148 bytepos
= AREF (vector
, 6);
7151 set_marker_both (w
->pointm
, buffer
,
7152 XFASTINT (charpos
), XFASTINT (bytepos
));
7155 Vwith_echo_area_save_vector
= vector
;
7160 /* Set up the echo area for use by print functions. MULTIBYTE_P
7161 non-zero means we will print multibyte. */
7164 setup_echo_area_for_printing (multibyte_p
)
7167 /* If we can't find an echo area any more, exit. */
7168 if (! FRAME_LIVE_P (XFRAME (selected_frame
)))
7171 ensure_echo_area_buffers ();
7173 if (!message_buf_print
)
7175 /* A message has been output since the last time we printed.
7176 Choose a fresh echo area buffer. */
7177 if (EQ (echo_area_buffer
[1], echo_buffer
[0]))
7178 echo_area_buffer
[0] = echo_buffer
[1];
7180 echo_area_buffer
[0] = echo_buffer
[0];
7182 /* Switch to that buffer and clear it. */
7183 set_buffer_internal (XBUFFER (echo_area_buffer
[0]));
7184 current_buffer
->truncate_lines
= Qnil
;
7188 int count
= SPECPDL_INDEX ();
7189 specbind (Qinhibit_read_only
, Qt
);
7190 /* Note that undo recording is always disabled. */
7192 unbind_to (count
, Qnil
);
7194 TEMP_SET_PT_BOTH (BEG
, BEG_BYTE
);
7196 /* Set up the buffer for the multibyteness we need. */
7198 != !NILP (current_buffer
->enable_multibyte_characters
))
7199 Fset_buffer_multibyte (multibyte_p
? Qt
: Qnil
);
7201 /* Raise the frame containing the echo area. */
7202 if (minibuffer_auto_raise
)
7204 struct frame
*sf
= SELECTED_FRAME ();
7205 Lisp_Object mini_window
;
7206 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
7207 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window
)));
7210 message_log_maybe_newline ();
7211 message_buf_print
= 1;
7215 if (NILP (echo_area_buffer
[0]))
7217 if (EQ (echo_area_buffer
[1], echo_buffer
[0]))
7218 echo_area_buffer
[0] = echo_buffer
[1];
7220 echo_area_buffer
[0] = echo_buffer
[0];
7223 if (current_buffer
!= XBUFFER (echo_area_buffer
[0]))
7225 /* Someone switched buffers between print requests. */
7226 set_buffer_internal (XBUFFER (echo_area_buffer
[0]));
7227 current_buffer
->truncate_lines
= Qnil
;
7233 /* Display an echo area message in window W. Value is non-zero if W's
7234 height is changed. If display_last_displayed_message_p is
7235 non-zero, display the message that was last displayed, otherwise
7236 display the current message. */
7239 display_echo_area (w
)
7242 int i
, no_message_p
, window_height_changed_p
, count
;
7244 /* Temporarily disable garbage collections while displaying the echo
7245 area. This is done because a GC can print a message itself.
7246 That message would modify the echo area buffer's contents while a
7247 redisplay of the buffer is going on, and seriously confuse
7249 count
= inhibit_garbage_collection ();
7251 /* If there is no message, we must call display_echo_area_1
7252 nevertheless because it resizes the window. But we will have to
7253 reset the echo_area_buffer in question to nil at the end because
7254 with_echo_area_buffer will sets it to an empty buffer. */
7255 i
= display_last_displayed_message_p
? 1 : 0;
7256 no_message_p
= NILP (echo_area_buffer
[i
]);
7258 window_height_changed_p
7259 = with_echo_area_buffer (w
, display_last_displayed_message_p
,
7260 display_echo_area_1
,
7261 (EMACS_INT
) w
, Qnil
, 0, 0);
7264 echo_area_buffer
[i
] = Qnil
;
7266 unbind_to (count
, Qnil
);
7267 return window_height_changed_p
;
7271 /* Helper for display_echo_area. Display the current buffer which
7272 contains the current echo area message in window W, a mini-window,
7273 a pointer to which is passed in A1. A2..A4 are currently not used.
7274 Change the height of W so that all of the message is displayed.
7275 Value is non-zero if height of W was changed. */
7278 display_echo_area_1 (a1
, a2
, a3
, a4
)
7283 struct window
*w
= (struct window
*) a1
;
7285 struct text_pos start
;
7286 int window_height_changed_p
= 0;
7288 /* Do this before displaying, so that we have a large enough glyph
7289 matrix for the display. */
7290 window_height_changed_p
= resize_mini_window (w
, 0);
7293 clear_glyph_matrix (w
->desired_matrix
);
7294 XSETWINDOW (window
, w
);
7295 SET_TEXT_POS (start
, BEG
, BEG_BYTE
);
7296 try_window (window
, start
);
7298 return window_height_changed_p
;
7302 /* Resize the echo area window to exactly the size needed for the
7303 currently displayed message, if there is one. If a mini-buffer
7304 is active, don't shrink it. */
7307 resize_echo_area_exactly ()
7309 if (BUFFERP (echo_area_buffer
[0])
7310 && WINDOWP (echo_area_window
))
7312 struct window
*w
= XWINDOW (echo_area_window
);
7314 Lisp_Object resize_exactly
;
7316 if (minibuf_level
== 0)
7317 resize_exactly
= Qt
;
7319 resize_exactly
= Qnil
;
7321 resized_p
= with_echo_area_buffer (w
, 0, resize_mini_window_1
,
7322 (EMACS_INT
) w
, resize_exactly
, 0, 0);
7325 ++windows_or_buffers_changed
;
7326 ++update_mode_lines
;
7327 redisplay_internal (0);
7333 /* Callback function for with_echo_area_buffer, when used from
7334 resize_echo_area_exactly. A1 contains a pointer to the window to
7335 resize, EXACTLY non-nil means resize the mini-window exactly to the
7336 size of the text displayed. A3 and A4 are not used. Value is what
7337 resize_mini_window returns. */
7340 resize_mini_window_1 (a1
, exactly
, a3
, a4
)
7342 Lisp_Object exactly
;
7345 return resize_mini_window ((struct window
*) a1
, !NILP (exactly
));
7349 /* Resize mini-window W to fit the size of its contents. EXACT:P
7350 means size the window exactly to the size needed. Otherwise, it's
7351 only enlarged until W's buffer is empty. Value is non-zero if
7352 the window height has been changed. */
7355 resize_mini_window (w
, exact_p
)
7359 struct frame
*f
= XFRAME (w
->frame
);
7360 int window_height_changed_p
= 0;
7362 xassert (MINI_WINDOW_P (w
));
7364 /* Don't resize windows while redisplaying a window; it would
7365 confuse redisplay functions when the size of the window they are
7366 displaying changes from under them. Such a resizing can happen,
7367 for instance, when which-func prints a long message while
7368 we are running fontification-functions. We're running these
7369 functions with safe_call which binds inhibit-redisplay to t. */
7370 if (!NILP (Vinhibit_redisplay
))
7373 /* Nil means don't try to resize. */
7374 if (NILP (Vresize_mini_windows
)
7375 || (FRAME_X_P (f
) && FRAME_X_OUTPUT (f
) == NULL
))
7378 if (!FRAME_MINIBUF_ONLY_P (f
))
7381 struct window
*root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
7382 int total_height
= WINDOW_TOTAL_LINES (root
) + WINDOW_TOTAL_LINES (w
);
7383 int height
, max_height
;
7384 int unit
= FRAME_LINE_HEIGHT (f
);
7385 struct text_pos start
;
7386 struct buffer
*old_current_buffer
= NULL
;
7388 if (current_buffer
!= XBUFFER (w
->buffer
))
7390 old_current_buffer
= current_buffer
;
7391 set_buffer_internal (XBUFFER (w
->buffer
));
7394 init_iterator (&it
, w
, BEGV
, BEGV_BYTE
, NULL
, DEFAULT_FACE_ID
);
7396 /* Compute the max. number of lines specified by the user. */
7397 if (FLOATP (Vmax_mini_window_height
))
7398 max_height
= XFLOATINT (Vmax_mini_window_height
) * FRAME_LINES (f
);
7399 else if (INTEGERP (Vmax_mini_window_height
))
7400 max_height
= XINT (Vmax_mini_window_height
);
7402 max_height
= total_height
/ 4;
7404 /* Correct that max. height if it's bogus. */
7405 max_height
= max (1, max_height
);
7406 max_height
= min (total_height
, max_height
);
7408 /* Find out the height of the text in the window. */
7409 if (it
.truncate_lines_p
)
7414 move_it_to (&it
, ZV
, -1, -1, -1, MOVE_TO_POS
);
7415 if (it
.max_ascent
== 0 && it
.max_descent
== 0)
7416 height
= it
.current_y
+ last_height
;
7418 height
= it
.current_y
+ it
.max_ascent
+ it
.max_descent
;
7419 height
-= it
.extra_line_spacing
;
7420 height
= (height
+ unit
- 1) / unit
;
7423 /* Compute a suitable window start. */
7424 if (height
> max_height
)
7426 height
= max_height
;
7427 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
7428 move_it_vertically_backward (&it
, (height
- 1) * unit
);
7429 start
= it
.current
.pos
;
7432 SET_TEXT_POS (start
, BEGV
, BEGV_BYTE
);
7433 SET_MARKER_FROM_TEXT_POS (w
->start
, start
);
7435 if (EQ (Vresize_mini_windows
, Qgrow_only
))
7437 /* Let it grow only, until we display an empty message, in which
7438 case the window shrinks again. */
7439 if (height
> WINDOW_TOTAL_LINES (w
))
7441 int old_height
= WINDOW_TOTAL_LINES (w
);
7442 freeze_window_starts (f
, 1);
7443 grow_mini_window (w
, height
- WINDOW_TOTAL_LINES (w
));
7444 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
7446 else if (height
< WINDOW_TOTAL_LINES (w
)
7447 && (exact_p
|| BEGV
== ZV
))
7449 int old_height
= WINDOW_TOTAL_LINES (w
);
7450 freeze_window_starts (f
, 0);
7451 shrink_mini_window (w
);
7452 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
7457 /* Always resize to exact size needed. */
7458 if (height
> WINDOW_TOTAL_LINES (w
))
7460 int old_height
= WINDOW_TOTAL_LINES (w
);
7461 freeze_window_starts (f
, 1);
7462 grow_mini_window (w
, height
- WINDOW_TOTAL_LINES (w
));
7463 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
7465 else if (height
< WINDOW_TOTAL_LINES (w
))
7467 int old_height
= WINDOW_TOTAL_LINES (w
);
7468 freeze_window_starts (f
, 0);
7469 shrink_mini_window (w
);
7473 freeze_window_starts (f
, 1);
7474 grow_mini_window (w
, height
- WINDOW_TOTAL_LINES (w
));
7477 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
7481 if (old_current_buffer
)
7482 set_buffer_internal (old_current_buffer
);
7485 return window_height_changed_p
;
7489 /* Value is the current message, a string, or nil if there is no
7497 if (NILP (echo_area_buffer
[0]))
7501 with_echo_area_buffer (0, 0, current_message_1
,
7502 (EMACS_INT
) &msg
, Qnil
, 0, 0);
7504 echo_area_buffer
[0] = Qnil
;
7512 current_message_1 (a1
, a2
, a3
, a4
)
7517 Lisp_Object
*msg
= (Lisp_Object
*) a1
;
7520 *msg
= make_buffer_string (BEG
, Z
, 1);
7527 /* Push the current message on Vmessage_stack for later restauration
7528 by restore_message. Value is non-zero if the current message isn't
7529 empty. This is a relatively infrequent operation, so it's not
7530 worth optimizing. */
7536 msg
= current_message ();
7537 Vmessage_stack
= Fcons (msg
, Vmessage_stack
);
7538 return STRINGP (msg
);
7542 /* Restore message display from the top of Vmessage_stack. */
7549 xassert (CONSP (Vmessage_stack
));
7550 msg
= XCAR (Vmessage_stack
);
7552 message3_nolog (msg
, SBYTES (msg
), STRING_MULTIBYTE (msg
));
7554 message3_nolog (msg
, 0, 0);
7558 /* Handler for record_unwind_protect calling pop_message. */
7561 pop_message_unwind (dummy
)
7568 /* Pop the top-most entry off Vmessage_stack. */
7573 xassert (CONSP (Vmessage_stack
));
7574 Vmessage_stack
= XCDR (Vmessage_stack
);
7578 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
7579 exits. If the stack is not empty, we have a missing pop_message
7583 check_message_stack ()
7585 if (!NILP (Vmessage_stack
))
7590 /* Truncate to NCHARS what will be displayed in the echo area the next
7591 time we display it---but don't redisplay it now. */
7594 truncate_echo_area (nchars
)
7598 echo_area_buffer
[0] = Qnil
;
7599 /* A null message buffer means that the frame hasn't really been
7600 initialized yet. Error messages get reported properly by
7601 cmd_error, so this must be just an informative message; toss it. */
7602 else if (!noninteractive
7604 && !NILP (echo_area_buffer
[0]))
7606 struct frame
*sf
= SELECTED_FRAME ();
7607 if (FRAME_MESSAGE_BUF (sf
))
7608 with_echo_area_buffer (0, 0, truncate_message_1
, nchars
, Qnil
, 0, 0);
7613 /* Helper function for truncate_echo_area. Truncate the current
7614 message to at most NCHARS characters. */
7617 truncate_message_1 (nchars
, a2
, a3
, a4
)
7622 if (BEG
+ nchars
< Z
)
7623 del_range (BEG
+ nchars
, Z
);
7625 echo_area_buffer
[0] = Qnil
;
7630 /* Set the current message to a substring of S or STRING.
7632 If STRING is a Lisp string, set the message to the first NBYTES
7633 bytes from STRING. NBYTES zero means use the whole string. If
7634 STRING is multibyte, the message will be displayed multibyte.
7636 If S is not null, set the message to the first LEN bytes of S. LEN
7637 zero means use the whole string. MULTIBYTE_P non-zero means S is
7638 multibyte. Display the message multibyte in that case. */
7641 set_message (s
, string
, nbytes
, multibyte_p
)
7644 int nbytes
, multibyte_p
;
7646 message_enable_multibyte
7647 = ((s
&& multibyte_p
)
7648 || (STRINGP (string
) && STRING_MULTIBYTE (string
)));
7650 with_echo_area_buffer (0, -1, set_message_1
,
7651 (EMACS_INT
) s
, string
, nbytes
, multibyte_p
);
7652 message_buf_print
= 0;
7653 help_echo_showing_p
= 0;
7657 /* Helper function for set_message. Arguments have the same meaning
7658 as there, with A1 corresponding to S and A2 corresponding to STRING
7659 This function is called with the echo area buffer being
7663 set_message_1 (a1
, a2
, nbytes
, multibyte_p
)
7666 EMACS_INT nbytes
, multibyte_p
;
7668 const char *s
= (const char *) a1
;
7669 Lisp_Object string
= a2
;
7673 /* Change multibyteness of the echo buffer appropriately. */
7674 if (message_enable_multibyte
7675 != !NILP (current_buffer
->enable_multibyte_characters
))
7676 Fset_buffer_multibyte (message_enable_multibyte
? Qt
: Qnil
);
7678 current_buffer
->truncate_lines
= message_truncate_lines
? Qt
: Qnil
;
7680 /* Insert new message at BEG. */
7681 TEMP_SET_PT_BOTH (BEG
, BEG_BYTE
);
7683 if (STRINGP (string
))
7688 nbytes
= SBYTES (string
);
7689 nchars
= string_byte_to_char (string
, nbytes
);
7691 /* This function takes care of single/multibyte conversion. We
7692 just have to ensure that the echo area buffer has the right
7693 setting of enable_multibyte_characters. */
7694 insert_from_string (string
, 0, 0, nchars
, nbytes
, 1);
7699 nbytes
= strlen (s
);
7701 if (multibyte_p
&& NILP (current_buffer
->enable_multibyte_characters
))
7703 /* Convert from multi-byte to single-byte. */
7705 unsigned char work
[1];
7707 /* Convert a multibyte string to single-byte. */
7708 for (i
= 0; i
< nbytes
; i
+= n
)
7710 c
= string_char_and_length (s
+ i
, nbytes
- i
, &n
);
7711 work
[0] = (SINGLE_BYTE_CHAR_P (c
)
7713 : multibyte_char_to_unibyte (c
, Qnil
));
7714 insert_1_both (work
, 1, 1, 1, 0, 0);
7717 else if (!multibyte_p
7718 && !NILP (current_buffer
->enable_multibyte_characters
))
7720 /* Convert from single-byte to multi-byte. */
7722 const unsigned char *msg
= (const unsigned char *) s
;
7723 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
7725 /* Convert a single-byte string to multibyte. */
7726 for (i
= 0; i
< nbytes
; i
++)
7728 c
= unibyte_char_to_multibyte (msg
[i
]);
7729 n
= CHAR_STRING (c
, str
);
7730 insert_1_both (str
, 1, n
, 1, 0, 0);
7734 insert_1 (s
, nbytes
, 1, 0, 0);
7741 /* Clear messages. CURRENT_P non-zero means clear the current
7742 message. LAST_DISPLAYED_P non-zero means clear the message
7746 clear_message (current_p
, last_displayed_p
)
7747 int current_p
, last_displayed_p
;
7751 echo_area_buffer
[0] = Qnil
;
7752 message_cleared_p
= 1;
7755 if (last_displayed_p
)
7756 echo_area_buffer
[1] = Qnil
;
7758 message_buf_print
= 0;
7761 /* Clear garbaged frames.
7763 This function is used where the old redisplay called
7764 redraw_garbaged_frames which in turn called redraw_frame which in
7765 turn called clear_frame. The call to clear_frame was a source of
7766 flickering. I believe a clear_frame is not necessary. It should
7767 suffice in the new redisplay to invalidate all current matrices,
7768 and ensure a complete redisplay of all windows. */
7771 clear_garbaged_frames ()
7775 Lisp_Object tail
, frame
;
7776 int changed_count
= 0;
7778 FOR_EACH_FRAME (tail
, frame
)
7780 struct frame
*f
= XFRAME (frame
);
7782 if (FRAME_VISIBLE_P (f
) && FRAME_GARBAGED_P (f
))
7786 Fredraw_frame (frame
);
7787 f
->force_flush_display_p
= 1;
7789 clear_current_matrices (f
);
7798 ++windows_or_buffers_changed
;
7803 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
7804 is non-zero update selected_frame. Value is non-zero if the
7805 mini-windows height has been changed. */
7808 echo_area_display (update_frame_p
)
7811 Lisp_Object mini_window
;
7814 int window_height_changed_p
= 0;
7815 struct frame
*sf
= SELECTED_FRAME ();
7817 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
7818 w
= XWINDOW (mini_window
);
7819 f
= XFRAME (WINDOW_FRAME (w
));
7821 /* Don't display if frame is invisible or not yet initialized. */
7822 if (!FRAME_VISIBLE_P (f
) || !f
->glyphs_initialized_p
)
7825 /* The terminal frame is used as the first Emacs frame on the Mac OS. */
7827 #ifdef HAVE_WINDOW_SYSTEM
7828 /* When Emacs starts, selected_frame may be a visible terminal
7829 frame, even if we run under a window system. If we let this
7830 through, a message would be displayed on the terminal. */
7831 if (EQ (selected_frame
, Vterminal_frame
)
7832 && !NILP (Vwindow_system
))
7834 #endif /* HAVE_WINDOW_SYSTEM */
7837 /* Redraw garbaged frames. */
7839 clear_garbaged_frames ();
7841 if (!NILP (echo_area_buffer
[0]) || minibuf_level
== 0)
7843 echo_area_window
= mini_window
;
7844 window_height_changed_p
= display_echo_area (w
);
7845 w
->must_be_updated_p
= 1;
7847 /* Update the display, unless called from redisplay_internal.
7848 Also don't update the screen during redisplay itself. The
7849 update will happen at the end of redisplay, and an update
7850 here could cause confusion. */
7851 if (update_frame_p
&& !redisplaying_p
)
7855 /* If the display update has been interrupted by pending
7856 input, update mode lines in the frame. Due to the
7857 pending input, it might have been that redisplay hasn't
7858 been called, so that mode lines above the echo area are
7859 garbaged. This looks odd, so we prevent it here. */
7860 if (!display_completed
)
7861 n
= redisplay_mode_lines (FRAME_ROOT_WINDOW (f
), 0);
7863 if (window_height_changed_p
7864 /* Don't do this if Emacs is shutting down. Redisplay
7865 needs to run hooks. */
7866 && !NILP (Vrun_hooks
))
7868 /* Must update other windows. Likewise as in other
7869 cases, don't let this update be interrupted by
7871 int count
= SPECPDL_INDEX ();
7872 specbind (Qredisplay_dont_pause
, Qt
);
7873 windows_or_buffers_changed
= 1;
7874 redisplay_internal (0);
7875 unbind_to (count
, Qnil
);
7877 else if (FRAME_WINDOW_P (f
) && n
== 0)
7879 /* Window configuration is the same as before.
7880 Can do with a display update of the echo area,
7881 unless we displayed some mode lines. */
7882 update_single_window (w
, 1);
7883 rif
->flush_display (f
);
7886 update_frame (f
, 1, 1);
7888 /* If cursor is in the echo area, make sure that the next
7889 redisplay displays the minibuffer, so that the cursor will
7890 be replaced with what the minibuffer wants. */
7891 if (cursor_in_echo_area
)
7892 ++windows_or_buffers_changed
;
7895 else if (!EQ (mini_window
, selected_window
))
7896 windows_or_buffers_changed
++;
7898 /* Last displayed message is now the current message. */
7899 echo_area_buffer
[1] = echo_area_buffer
[0];
7901 /* Prevent redisplay optimization in redisplay_internal by resetting
7902 this_line_start_pos. This is done because the mini-buffer now
7903 displays the message instead of its buffer text. */
7904 if (EQ (mini_window
, selected_window
))
7905 CHARPOS (this_line_start_pos
) = 0;
7907 return window_height_changed_p
;
7912 /***********************************************************************
7914 ***********************************************************************/
7917 /* The frame title buffering code is also used by Fformat_mode_line.
7918 So it is not conditioned by HAVE_WINDOW_SYSTEM. */
7920 /* A buffer for constructing frame titles in it; allocated from the
7921 heap in init_xdisp and resized as needed in store_frame_title_char. */
7923 static char *frame_title_buf
;
7925 /* The buffer's end, and a current output position in it. */
7927 static char *frame_title_buf_end
;
7928 static char *frame_title_ptr
;
7931 /* Store a single character C for the frame title in frame_title_buf.
7932 Re-allocate frame_title_buf if necessary. */
7936 store_frame_title_char (char c
)
7938 store_frame_title_char (c
)
7942 /* If output position has reached the end of the allocated buffer,
7943 double the buffer's size. */
7944 if (frame_title_ptr
== frame_title_buf_end
)
7946 int len
= frame_title_ptr
- frame_title_buf
;
7947 int new_size
= 2 * len
* sizeof *frame_title_buf
;
7948 frame_title_buf
= (char *) xrealloc (frame_title_buf
, new_size
);
7949 frame_title_buf_end
= frame_title_buf
+ new_size
;
7950 frame_title_ptr
= frame_title_buf
+ len
;
7953 *frame_title_ptr
++ = c
;
7957 /* Store part of a frame title in frame_title_buf, beginning at
7958 frame_title_ptr. STR is the string to store. Do not copy
7959 characters that yield more columns than PRECISION; PRECISION <= 0
7960 means copy the whole string. Pad with spaces until FIELD_WIDTH
7961 number of characters have been copied; FIELD_WIDTH <= 0 means don't
7962 pad. Called from display_mode_element when it is used to build a
7966 store_frame_title (str
, field_width
, precision
)
7967 const unsigned char *str
;
7968 int field_width
, precision
;
7973 /* Copy at most PRECISION chars from STR. */
7974 nbytes
= strlen (str
);
7975 n
+= c_string_width (str
, nbytes
, precision
, &dummy
, &nbytes
);
7977 store_frame_title_char (*str
++);
7979 /* Fill up with spaces until FIELD_WIDTH reached. */
7980 while (field_width
> 0
7983 store_frame_title_char (' ');
7990 #ifdef HAVE_WINDOW_SYSTEM
7992 /* Set the title of FRAME, if it has changed. The title format is
7993 Vicon_title_format if FRAME is iconified, otherwise it is
7994 frame_title_format. */
7997 x_consider_frame_title (frame
)
8000 struct frame
*f
= XFRAME (frame
);
8002 if (FRAME_WINDOW_P (f
)
8003 || FRAME_MINIBUF_ONLY_P (f
)
8004 || f
->explicit_name
)
8006 /* Do we have more than one visible frame on this X display? */
8009 struct buffer
*obuf
;
8013 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCDR (tail
))
8015 Lisp_Object other_frame
= XCAR (tail
);
8016 struct frame
*tf
= XFRAME (other_frame
);
8019 && FRAME_KBOARD (tf
) == FRAME_KBOARD (f
)
8020 && !FRAME_MINIBUF_ONLY_P (tf
)
8021 && !EQ (other_frame
, tip_frame
)
8022 && (FRAME_VISIBLE_P (tf
) || FRAME_ICONIFIED_P (tf
)))
8026 /* Set global variable indicating that multiple frames exist. */
8027 multiple_frames
= CONSP (tail
);
8029 /* Switch to the buffer of selected window of the frame. Set up
8030 frame_title_ptr so that display_mode_element will output into it;
8031 then display the title. */
8032 obuf
= current_buffer
;
8033 set_buffer_internal_1 (XBUFFER (XWINDOW (f
->selected_window
)->buffer
));
8034 fmt
= FRAME_ICONIFIED_P (f
) ? Vicon_title_format
: Vframe_title_format
;
8035 frame_title_ptr
= frame_title_buf
;
8036 init_iterator (&it
, XWINDOW (f
->selected_window
), -1, -1,
8037 NULL
, DEFAULT_FACE_ID
);
8038 display_mode_element (&it
, 0, -1, -1, fmt
, Qnil
, 0);
8039 len
= frame_title_ptr
- frame_title_buf
;
8040 frame_title_ptr
= NULL
;
8041 set_buffer_internal_1 (obuf
);
8043 /* Set the title only if it's changed. This avoids consing in
8044 the common case where it hasn't. (If it turns out that we've
8045 already wasted too much time by walking through the list with
8046 display_mode_element, then we might need to optimize at a
8047 higher level than this.) */
8048 if (! STRINGP (f
->name
)
8049 || SBYTES (f
->name
) != len
8050 || bcmp (frame_title_buf
, SDATA (f
->name
), len
) != 0)
8051 x_implicitly_set_name (f
, make_string (frame_title_buf
, len
), Qnil
);
8055 #endif /* not HAVE_WINDOW_SYSTEM */
8060 /***********************************************************************
8062 ***********************************************************************/
8065 /* Prepare for redisplay by updating menu-bar item lists when
8066 appropriate. This can call eval. */
8069 prepare_menu_bars ()
8072 struct gcpro gcpro1
, gcpro2
;
8074 Lisp_Object tooltip_frame
;
8076 #ifdef HAVE_WINDOW_SYSTEM
8077 tooltip_frame
= tip_frame
;
8079 tooltip_frame
= Qnil
;
8082 /* Update all frame titles based on their buffer names, etc. We do
8083 this before the menu bars so that the buffer-menu will show the
8084 up-to-date frame titles. */
8085 #ifdef HAVE_WINDOW_SYSTEM
8086 if (windows_or_buffers_changed
|| update_mode_lines
)
8088 Lisp_Object tail
, frame
;
8090 FOR_EACH_FRAME (tail
, frame
)
8093 if (!EQ (frame
, tooltip_frame
)
8094 && (FRAME_VISIBLE_P (f
) || FRAME_ICONIFIED_P (f
)))
8095 x_consider_frame_title (frame
);
8098 #endif /* HAVE_WINDOW_SYSTEM */
8100 /* Update the menu bar item lists, if appropriate. This has to be
8101 done before any actual redisplay or generation of display lines. */
8102 all_windows
= (update_mode_lines
8103 || buffer_shared
> 1
8104 || windows_or_buffers_changed
);
8107 Lisp_Object tail
, frame
;
8108 int count
= SPECPDL_INDEX ();
8110 record_unwind_protect (Fset_match_data
, Fmatch_data (Qnil
, Qnil
));
8112 FOR_EACH_FRAME (tail
, frame
)
8116 /* Ignore tooltip frame. */
8117 if (EQ (frame
, tooltip_frame
))
8120 /* If a window on this frame changed size, report that to
8121 the user and clear the size-change flag. */
8122 if (FRAME_WINDOW_SIZES_CHANGED (f
))
8124 Lisp_Object functions
;
8126 /* Clear flag first in case we get an error below. */
8127 FRAME_WINDOW_SIZES_CHANGED (f
) = 0;
8128 functions
= Vwindow_size_change_functions
;
8129 GCPRO2 (tail
, functions
);
8131 while (CONSP (functions
))
8133 call1 (XCAR (functions
), frame
);
8134 functions
= XCDR (functions
);
8140 update_menu_bar (f
, 0);
8141 #ifdef HAVE_WINDOW_SYSTEM
8142 update_tool_bar (f
, 0);
8147 unbind_to (count
, Qnil
);
8151 struct frame
*sf
= SELECTED_FRAME ();
8152 update_menu_bar (sf
, 1);
8153 #ifdef HAVE_WINDOW_SYSTEM
8154 update_tool_bar (sf
, 1);
8158 /* Motif needs this. See comment in xmenu.c. Turn it off when
8159 pending_menu_activation is not defined. */
8160 #ifdef USE_X_TOOLKIT
8161 pending_menu_activation
= 0;
8166 /* Update the menu bar item list for frame F. This has to be done
8167 before we start to fill in any display lines, because it can call
8170 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
8173 update_menu_bar (f
, save_match_data
)
8175 int save_match_data
;
8178 register struct window
*w
;
8180 /* If called recursively during a menu update, do nothing. This can
8181 happen when, for instance, an activate-menubar-hook causes a
8183 if (inhibit_menubar_update
)
8186 window
= FRAME_SELECTED_WINDOW (f
);
8187 w
= XWINDOW (window
);
8189 #if 0 /* The if statement below this if statement used to include the
8190 condition !NILP (w->update_mode_line), rather than using
8191 update_mode_lines directly, and this if statement may have
8192 been added to make that condition work. Now the if
8193 statement below matches its comment, this isn't needed. */
8194 if (update_mode_lines
)
8195 w
->update_mode_line
= Qt
;
8198 if (FRAME_WINDOW_P (f
)
8200 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8201 || defined (USE_GTK)
8202 FRAME_EXTERNAL_MENU_BAR (f
)
8204 FRAME_MENU_BAR_LINES (f
) > 0
8206 : FRAME_MENU_BAR_LINES (f
) > 0)
8208 /* If the user has switched buffers or windows, we need to
8209 recompute to reflect the new bindings. But we'll
8210 recompute when update_mode_lines is set too; that means
8211 that people can use force-mode-line-update to request
8212 that the menu bar be recomputed. The adverse effect on
8213 the rest of the redisplay algorithm is about the same as
8214 windows_or_buffers_changed anyway. */
8215 if (windows_or_buffers_changed
8216 /* This used to test w->update_mode_line, but we believe
8217 there is no need to recompute the menu in that case. */
8218 || update_mode_lines
8219 || ((BUF_SAVE_MODIFF (XBUFFER (w
->buffer
))
8220 < BUF_MODIFF (XBUFFER (w
->buffer
)))
8221 != !NILP (w
->last_had_star
))
8222 || ((!NILP (Vtransient_mark_mode
)
8223 && !NILP (XBUFFER (w
->buffer
)->mark_active
))
8224 != !NILP (w
->region_showing
)))
8226 struct buffer
*prev
= current_buffer
;
8227 int count
= SPECPDL_INDEX ();
8229 specbind (Qinhibit_menubar_update
, Qt
);
8231 set_buffer_internal_1 (XBUFFER (w
->buffer
));
8232 if (save_match_data
)
8233 record_unwind_protect (Fset_match_data
, Fmatch_data (Qnil
, Qnil
));
8234 if (NILP (Voverriding_local_map_menu_flag
))
8236 specbind (Qoverriding_terminal_local_map
, Qnil
);
8237 specbind (Qoverriding_local_map
, Qnil
);
8240 /* Run the Lucid hook. */
8241 safe_run_hooks (Qactivate_menubar_hook
);
8243 /* If it has changed current-menubar from previous value,
8244 really recompute the menu-bar from the value. */
8245 if (! NILP (Vlucid_menu_bar_dirty_flag
))
8246 call0 (Qrecompute_lucid_menubar
);
8248 safe_run_hooks (Qmenu_bar_update_hook
);
8249 FRAME_MENU_BAR_ITEMS (f
) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f
));
8251 /* Redisplay the menu bar in case we changed it. */
8252 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8253 || defined (USE_GTK)
8254 if (FRAME_WINDOW_P (f
)
8255 #if defined (MAC_OS)
8256 /* All frames on Mac OS share the same menubar. So only the
8257 selected frame should be allowed to set it. */
8258 && f
== SELECTED_FRAME ()
8261 set_frame_menubar (f
, 0, 0);
8263 /* On a terminal screen, the menu bar is an ordinary screen
8264 line, and this makes it get updated. */
8265 w
->update_mode_line
= Qt
;
8266 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8267 /* In the non-toolkit version, the menu bar is an ordinary screen
8268 line, and this makes it get updated. */
8269 w
->update_mode_line
= Qt
;
8270 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8272 unbind_to (count
, Qnil
);
8273 set_buffer_internal_1 (prev
);
8280 /***********************************************************************
8282 ***********************************************************************/
8284 #ifdef HAVE_WINDOW_SYSTEM
8287 Nominal cursor position -- where to draw output.
8288 HPOS and VPOS are window relative glyph matrix coordinates.
8289 X and Y are window relative pixel coordinates. */
8291 struct cursor_pos output_cursor
;
8295 Set the global variable output_cursor to CURSOR. All cursor
8296 positions are relative to updated_window. */
8299 set_output_cursor (cursor
)
8300 struct cursor_pos
*cursor
;
8302 output_cursor
.hpos
= cursor
->hpos
;
8303 output_cursor
.vpos
= cursor
->vpos
;
8304 output_cursor
.x
= cursor
->x
;
8305 output_cursor
.y
= cursor
->y
;
8310 Set a nominal cursor position.
8312 HPOS and VPOS are column/row positions in a window glyph matrix. X
8313 and Y are window text area relative pixel positions.
8315 If this is done during an update, updated_window will contain the
8316 window that is being updated and the position is the future output
8317 cursor position for that window. If updated_window is null, use
8318 selected_window and display the cursor at the given position. */
8321 x_cursor_to (vpos
, hpos
, y
, x
)
8322 int vpos
, hpos
, y
, x
;
8326 /* If updated_window is not set, work on selected_window. */
8330 w
= XWINDOW (selected_window
);
8332 /* Set the output cursor. */
8333 output_cursor
.hpos
= hpos
;
8334 output_cursor
.vpos
= vpos
;
8335 output_cursor
.x
= x
;
8336 output_cursor
.y
= y
;
8338 /* If not called as part of an update, really display the cursor.
8339 This will also set the cursor position of W. */
8340 if (updated_window
== NULL
)
8343 display_and_set_cursor (w
, 1, hpos
, vpos
, x
, y
);
8344 if (rif
->flush_display_optional
)
8345 rif
->flush_display_optional (SELECTED_FRAME ());
8350 #endif /* HAVE_WINDOW_SYSTEM */
8353 /***********************************************************************
8355 ***********************************************************************/
8357 #ifdef HAVE_WINDOW_SYSTEM
8359 /* Where the mouse was last time we reported a mouse event. */
8361 FRAME_PTR last_mouse_frame
;
8363 /* Tool-bar item index of the item on which a mouse button was pressed
8366 int last_tool_bar_item
;
8369 /* Update the tool-bar item list for frame F. This has to be done
8370 before we start to fill in any display lines. Called from
8371 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
8372 and restore it here. */
8375 update_tool_bar (f
, save_match_data
)
8377 int save_match_data
;
8380 int do_update
= FRAME_EXTERNAL_TOOL_BAR (f
);
8382 int do_update
= WINDOWP (f
->tool_bar_window
)
8383 && WINDOW_TOTAL_LINES (XWINDOW (f
->tool_bar_window
)) > 0;
8391 window
= FRAME_SELECTED_WINDOW (f
);
8392 w
= XWINDOW (window
);
8394 /* If the user has switched buffers or windows, we need to
8395 recompute to reflect the new bindings. But we'll
8396 recompute when update_mode_lines is set too; that means
8397 that people can use force-mode-line-update to request
8398 that the menu bar be recomputed. The adverse effect on
8399 the rest of the redisplay algorithm is about the same as
8400 windows_or_buffers_changed anyway. */
8401 if (windows_or_buffers_changed
8402 || !NILP (w
->update_mode_line
)
8403 || update_mode_lines
8404 || ((BUF_SAVE_MODIFF (XBUFFER (w
->buffer
))
8405 < BUF_MODIFF (XBUFFER (w
->buffer
)))
8406 != !NILP (w
->last_had_star
))
8407 || ((!NILP (Vtransient_mark_mode
)
8408 && !NILP (XBUFFER (w
->buffer
)->mark_active
))
8409 != !NILP (w
->region_showing
)))
8411 struct buffer
*prev
= current_buffer
;
8412 int count
= SPECPDL_INDEX ();
8413 Lisp_Object old_tool_bar
;
8414 struct gcpro gcpro1
;
8416 /* Set current_buffer to the buffer of the selected
8417 window of the frame, so that we get the right local
8419 set_buffer_internal_1 (XBUFFER (w
->buffer
));
8421 /* Save match data, if we must. */
8422 if (save_match_data
)
8423 record_unwind_protect (Fset_match_data
, Fmatch_data (Qnil
, Qnil
));
8425 /* Make sure that we don't accidentally use bogus keymaps. */
8426 if (NILP (Voverriding_local_map_menu_flag
))
8428 specbind (Qoverriding_terminal_local_map
, Qnil
);
8429 specbind (Qoverriding_local_map
, Qnil
);
8432 old_tool_bar
= f
->tool_bar_items
;
8433 GCPRO1 (old_tool_bar
);
8435 /* Build desired tool-bar items from keymaps. */
8438 = tool_bar_items (f
->tool_bar_items
, &f
->n_tool_bar_items
);
8441 /* Redisplay the tool-bar if we changed it. */
8442 if (! NILP (Fequal (old_tool_bar
, f
->tool_bar_items
)))
8443 w
->update_mode_line
= Qt
;
8447 unbind_to (count
, Qnil
);
8448 set_buffer_internal_1 (prev
);
8454 /* Set F->desired_tool_bar_string to a Lisp string representing frame
8455 F's desired tool-bar contents. F->tool_bar_items must have
8456 been set up previously by calling prepare_menu_bars. */
8459 build_desired_tool_bar_string (f
)
8462 int i
, size
, size_needed
;
8463 struct gcpro gcpro1
, gcpro2
, gcpro3
;
8464 Lisp_Object image
, plist
, props
;
8466 image
= plist
= props
= Qnil
;
8467 GCPRO3 (image
, plist
, props
);
8469 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
8470 Otherwise, make a new string. */
8472 /* The size of the string we might be able to reuse. */
8473 size
= (STRINGP (f
->desired_tool_bar_string
)
8474 ? SCHARS (f
->desired_tool_bar_string
)
8477 /* We need one space in the string for each image. */
8478 size_needed
= f
->n_tool_bar_items
;
8480 /* Reuse f->desired_tool_bar_string, if possible. */
8481 if (size
< size_needed
|| NILP (f
->desired_tool_bar_string
))
8482 f
->desired_tool_bar_string
= Fmake_string (make_number (size_needed
),
8486 props
= list4 (Qdisplay
, Qnil
, Qmenu_item
, Qnil
);
8487 Fremove_text_properties (make_number (0), make_number (size
),
8488 props
, f
->desired_tool_bar_string
);
8491 /* Put a `display' property on the string for the images to display,
8492 put a `menu_item' property on tool-bar items with a value that
8493 is the index of the item in F's tool-bar item vector. */
8494 for (i
= 0; i
< f
->n_tool_bar_items
; ++i
)
8496 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
8498 int enabled_p
= !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P
));
8499 int selected_p
= !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P
));
8500 int hmargin
, vmargin
, relief
, idx
, end
;
8501 extern Lisp_Object QCrelief
, QCmargin
, QCconversion
;
8503 /* If image is a vector, choose the image according to the
8505 image
= PROP (TOOL_BAR_ITEM_IMAGES
);
8506 if (VECTORP (image
))
8510 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
8511 : TOOL_BAR_IMAGE_ENABLED_DESELECTED
);
8514 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
8515 : TOOL_BAR_IMAGE_DISABLED_DESELECTED
);
8517 xassert (ASIZE (image
) >= idx
);
8518 image
= AREF (image
, idx
);
8523 /* Ignore invalid image specifications. */
8524 if (!valid_image_p (image
))
8527 /* Display the tool-bar button pressed, or depressed. */
8528 plist
= Fcopy_sequence (XCDR (image
));
8530 /* Compute margin and relief to draw. */
8531 relief
= (tool_bar_button_relief
>= 0
8532 ? tool_bar_button_relief
8533 : DEFAULT_TOOL_BAR_BUTTON_RELIEF
);
8534 hmargin
= vmargin
= relief
;
8536 if (INTEGERP (Vtool_bar_button_margin
)
8537 && XINT (Vtool_bar_button_margin
) > 0)
8539 hmargin
+= XFASTINT (Vtool_bar_button_margin
);
8540 vmargin
+= XFASTINT (Vtool_bar_button_margin
);
8542 else if (CONSP (Vtool_bar_button_margin
))
8544 if (INTEGERP (XCAR (Vtool_bar_button_margin
))
8545 && XINT (XCAR (Vtool_bar_button_margin
)) > 0)
8546 hmargin
+= XFASTINT (XCAR (Vtool_bar_button_margin
));
8548 if (INTEGERP (XCDR (Vtool_bar_button_margin
))
8549 && XINT (XCDR (Vtool_bar_button_margin
)) > 0)
8550 vmargin
+= XFASTINT (XCDR (Vtool_bar_button_margin
));
8553 if (auto_raise_tool_bar_buttons_p
)
8555 /* Add a `:relief' property to the image spec if the item is
8559 plist
= Fplist_put (plist
, QCrelief
, make_number (-relief
));
8566 /* If image is selected, display it pressed, i.e. with a
8567 negative relief. If it's not selected, display it with a
8569 plist
= Fplist_put (plist
, QCrelief
,
8571 ? make_number (-relief
)
8572 : make_number (relief
)));
8577 /* Put a margin around the image. */
8578 if (hmargin
|| vmargin
)
8580 if (hmargin
== vmargin
)
8581 plist
= Fplist_put (plist
, QCmargin
, make_number (hmargin
));
8583 plist
= Fplist_put (plist
, QCmargin
,
8584 Fcons (make_number (hmargin
),
8585 make_number (vmargin
)));
8588 /* If button is not enabled, and we don't have special images
8589 for the disabled state, make the image appear disabled by
8590 applying an appropriate algorithm to it. */
8591 if (!enabled_p
&& idx
< 0)
8592 plist
= Fplist_put (plist
, QCconversion
, Qdisabled
);
8594 /* Put a `display' text property on the string for the image to
8595 display. Put a `menu-item' property on the string that gives
8596 the start of this item's properties in the tool-bar items
8598 image
= Fcons (Qimage
, plist
);
8599 props
= list4 (Qdisplay
, image
,
8600 Qmenu_item
, make_number (i
* TOOL_BAR_ITEM_NSLOTS
));
8602 /* Let the last image hide all remaining spaces in the tool bar
8603 string. The string can be longer than needed when we reuse a
8605 if (i
+ 1 == f
->n_tool_bar_items
)
8606 end
= SCHARS (f
->desired_tool_bar_string
);
8609 Fadd_text_properties (make_number (i
), make_number (end
),
8610 props
, f
->desired_tool_bar_string
);
8618 /* Display one line of the tool-bar of frame IT->f. */
8621 display_tool_bar_line (it
)
8624 struct glyph_row
*row
= it
->glyph_row
;
8625 int max_x
= it
->last_visible_x
;
8628 prepare_desired_row (row
);
8629 row
->y
= it
->current_y
;
8631 /* Note that this isn't made use of if the face hasn't a box,
8632 so there's no need to check the face here. */
8633 it
->start_of_box_run_p
= 1;
8635 while (it
->current_x
< max_x
)
8637 int x_before
, x
, n_glyphs_before
, i
, nglyphs
;
8639 /* Get the next display element. */
8640 if (!get_next_display_element (it
))
8643 /* Produce glyphs. */
8644 x_before
= it
->current_x
;
8645 n_glyphs_before
= it
->glyph_row
->used
[TEXT_AREA
];
8646 PRODUCE_GLYPHS (it
);
8648 nglyphs
= it
->glyph_row
->used
[TEXT_AREA
] - n_glyphs_before
;
8653 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
8655 if (x
+ glyph
->pixel_width
> max_x
)
8657 /* Glyph doesn't fit on line. */
8658 it
->glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
+ i
;
8664 x
+= glyph
->pixel_width
;
8668 /* Stop at line ends. */
8669 if (ITERATOR_AT_END_OF_LINE_P (it
))
8672 set_iterator_to_next (it
, 1);
8677 row
->displays_text_p
= row
->used
[TEXT_AREA
] != 0;
8678 extend_face_to_end_of_line (it
);
8679 last
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
] - 1;
8680 last
->right_box_line_p
= 1;
8681 if (last
== row
->glyphs
[TEXT_AREA
])
8682 last
->left_box_line_p
= 1;
8683 compute_line_metrics (it
);
8685 /* If line is empty, make it occupy the rest of the tool-bar. */
8686 if (!row
->displays_text_p
)
8688 row
->height
= row
->phys_height
= it
->last_visible_y
- row
->y
;
8689 row
->ascent
= row
->phys_ascent
= 0;
8692 row
->full_width_p
= 1;
8693 row
->continued_p
= 0;
8694 row
->truncated_on_left_p
= 0;
8695 row
->truncated_on_right_p
= 0;
8697 it
->current_x
= it
->hpos
= 0;
8698 it
->current_y
+= row
->height
;
8704 /* Value is the number of screen lines needed to make all tool-bar
8705 items of frame F visible. */
8708 tool_bar_lines_needed (f
)
8711 struct window
*w
= XWINDOW (f
->tool_bar_window
);
8714 /* Initialize an iterator for iteration over
8715 F->desired_tool_bar_string in the tool-bar window of frame F. */
8716 init_iterator (&it
, w
, -1, -1, w
->desired_matrix
->rows
, TOOL_BAR_FACE_ID
);
8717 it
.first_visible_x
= 0;
8718 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
8719 reseat_to_string (&it
, NULL
, f
->desired_tool_bar_string
, 0, 0, 0, -1);
8721 while (!ITERATOR_AT_END_P (&it
))
8723 it
.glyph_row
= w
->desired_matrix
->rows
;
8724 clear_glyph_row (it
.glyph_row
);
8725 display_tool_bar_line (&it
);
8728 return (it
.current_y
+ FRAME_LINE_HEIGHT (f
) - 1) / FRAME_LINE_HEIGHT (f
);
8732 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed
, Stool_bar_lines_needed
,
8734 doc
: /* Return the number of lines occupied by the tool bar of FRAME. */)
8743 frame
= selected_frame
;
8745 CHECK_FRAME (frame
);
8748 if (WINDOWP (f
->tool_bar_window
)
8749 || (w
= XWINDOW (f
->tool_bar_window
),
8750 WINDOW_TOTAL_LINES (w
) > 0))
8752 update_tool_bar (f
, 1);
8753 if (f
->n_tool_bar_items
)
8755 build_desired_tool_bar_string (f
);
8756 nlines
= tool_bar_lines_needed (f
);
8760 return make_number (nlines
);
8764 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
8765 height should be changed. */
8768 redisplay_tool_bar (f
)
8773 struct glyph_row
*row
;
8774 int change_height_p
= 0;
8777 if (FRAME_EXTERNAL_TOOL_BAR (f
))
8778 update_frame_tool_bar (f
);
8782 /* If frame hasn't a tool-bar window or if it is zero-height, don't
8783 do anything. This means you must start with tool-bar-lines
8784 non-zero to get the auto-sizing effect. Or in other words, you
8785 can turn off tool-bars by specifying tool-bar-lines zero. */
8786 if (!WINDOWP (f
->tool_bar_window
)
8787 || (w
= XWINDOW (f
->tool_bar_window
),
8788 WINDOW_TOTAL_LINES (w
) == 0))
8791 /* Set up an iterator for the tool-bar window. */
8792 init_iterator (&it
, w
, -1, -1, w
->desired_matrix
->rows
, TOOL_BAR_FACE_ID
);
8793 it
.first_visible_x
= 0;
8794 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
8797 /* Build a string that represents the contents of the tool-bar. */
8798 build_desired_tool_bar_string (f
);
8799 reseat_to_string (&it
, NULL
, f
->desired_tool_bar_string
, 0, 0, 0, -1);
8801 /* Display as many lines as needed to display all tool-bar items. */
8802 while (it
.current_y
< it
.last_visible_y
)
8803 display_tool_bar_line (&it
);
8805 /* It doesn't make much sense to try scrolling in the tool-bar
8806 window, so don't do it. */
8807 w
->desired_matrix
->no_scrolling_p
= 1;
8808 w
->must_be_updated_p
= 1;
8810 if (auto_resize_tool_bars_p
)
8814 /* If we couldn't display everything, change the tool-bar's
8816 if (IT_STRING_CHARPOS (it
) < it
.end_charpos
)
8817 change_height_p
= 1;
8819 /* If there are blank lines at the end, except for a partially
8820 visible blank line at the end that is smaller than
8821 FRAME_LINE_HEIGHT, change the tool-bar's height. */
8822 row
= it
.glyph_row
- 1;
8823 if (!row
->displays_text_p
8824 && row
->height
>= FRAME_LINE_HEIGHT (f
))
8825 change_height_p
= 1;
8827 /* If row displays tool-bar items, but is partially visible,
8828 change the tool-bar's height. */
8829 if (row
->displays_text_p
8830 && MATRIX_ROW_BOTTOM_Y (row
) > it
.last_visible_y
)
8831 change_height_p
= 1;
8833 /* Resize windows as needed by changing the `tool-bar-lines'
8836 && (nlines
= tool_bar_lines_needed (f
),
8837 nlines
!= WINDOW_TOTAL_LINES (w
)))
8839 extern Lisp_Object Qtool_bar_lines
;
8841 int old_height
= WINDOW_TOTAL_LINES (w
);
8843 XSETFRAME (frame
, f
);
8844 clear_glyph_matrix (w
->desired_matrix
);
8845 Fmodify_frame_parameters (frame
,
8846 Fcons (Fcons (Qtool_bar_lines
,
8847 make_number (nlines
)),
8849 if (WINDOW_TOTAL_LINES (w
) != old_height
)
8850 fonts_changed_p
= 1;
8854 return change_height_p
;
8858 /* Get information about the tool-bar item which is displayed in GLYPH
8859 on frame F. Return in *PROP_IDX the index where tool-bar item
8860 properties start in F->tool_bar_items. Value is zero if
8861 GLYPH doesn't display a tool-bar item. */
8864 tool_bar_item_info (f
, glyph
, prop_idx
)
8866 struct glyph
*glyph
;
8873 /* This function can be called asynchronously, which means we must
8874 exclude any possibility that Fget_text_property signals an
8876 charpos
= min (SCHARS (f
->current_tool_bar_string
), glyph
->charpos
);
8877 charpos
= max (0, charpos
);
8879 /* Get the text property `menu-item' at pos. The value of that
8880 property is the start index of this item's properties in
8881 F->tool_bar_items. */
8882 prop
= Fget_text_property (make_number (charpos
),
8883 Qmenu_item
, f
->current_tool_bar_string
);
8884 if (INTEGERP (prop
))
8886 *prop_idx
= XINT (prop
);
8896 /* Get information about the tool-bar item at position X/Y on frame F.
8897 Return in *GLYPH a pointer to the glyph of the tool-bar item in
8898 the current matrix of the tool-bar window of F, or NULL if not
8899 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
8900 item in F->tool_bar_items. Value is
8902 -1 if X/Y is not on a tool-bar item
8903 0 if X/Y is on the same item that was highlighted before.
8907 get_tool_bar_item (f
, x
, y
, glyph
, hpos
, vpos
, prop_idx
)
8910 struct glyph
**glyph
;
8911 int *hpos
, *vpos
, *prop_idx
;
8913 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
8914 struct window
*w
= XWINDOW (f
->tool_bar_window
);
8917 /* Find the glyph under X/Y. */
8918 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, 0, 0, &area
);
8922 /* Get the start of this tool-bar item's properties in
8923 f->tool_bar_items. */
8924 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
8927 /* Is mouse on the highlighted item? */
8928 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
8929 && *vpos
>= dpyinfo
->mouse_face_beg_row
8930 && *vpos
<= dpyinfo
->mouse_face_end_row
8931 && (*vpos
> dpyinfo
->mouse_face_beg_row
8932 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
8933 && (*vpos
< dpyinfo
->mouse_face_end_row
8934 || *hpos
< dpyinfo
->mouse_face_end_col
8935 || dpyinfo
->mouse_face_past_end
))
8943 Handle mouse button event on the tool-bar of frame F, at
8944 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
8945 0 for button release. MODIFIERS is event modifiers for button
8949 handle_tool_bar_click (f
, x
, y
, down_p
, modifiers
)
8952 unsigned int modifiers
;
8954 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
8955 struct window
*w
= XWINDOW (f
->tool_bar_window
);
8956 int hpos
, vpos
, prop_idx
;
8957 struct glyph
*glyph
;
8958 Lisp_Object enabled_p
;
8960 /* If not on the highlighted tool-bar item, return. */
8961 frame_to_window_pixel_xy (w
, &x
, &y
);
8962 if (get_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
8965 /* If item is disabled, do nothing. */
8966 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
8967 if (NILP (enabled_p
))
8972 /* Show item in pressed state. */
8973 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
8974 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
8975 last_tool_bar_item
= prop_idx
;
8979 Lisp_Object key
, frame
;
8980 struct input_event event
;
8983 /* Show item in released state. */
8984 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
8985 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
8987 key
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_KEY
);
8989 XSETFRAME (frame
, f
);
8990 event
.kind
= TOOL_BAR_EVENT
;
8991 event
.frame_or_window
= frame
;
8993 kbd_buffer_store_event (&event
);
8995 event
.kind
= TOOL_BAR_EVENT
;
8996 event
.frame_or_window
= frame
;
8998 event
.modifiers
= modifiers
;
8999 kbd_buffer_store_event (&event
);
9000 last_tool_bar_item
= -1;
9005 /* Possibly highlight a tool-bar item on frame F when mouse moves to
9006 tool-bar window-relative coordinates X/Y. Called from
9007 note_mouse_highlight. */
9010 note_tool_bar_highlight (f
, x
, y
)
9014 Lisp_Object window
= f
->tool_bar_window
;
9015 struct window
*w
= XWINDOW (window
);
9016 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
9018 struct glyph
*glyph
;
9019 struct glyph_row
*row
;
9021 Lisp_Object enabled_p
;
9023 enum draw_glyphs_face draw
= DRAW_IMAGE_RAISED
;
9024 int mouse_down_p
, rc
;
9026 /* Function note_mouse_highlight is called with negative x(y
9027 values when mouse moves outside of the frame. */
9028 if (x
<= 0 || y
<= 0)
9030 clear_mouse_face (dpyinfo
);
9034 rc
= get_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
9037 /* Not on tool-bar item. */
9038 clear_mouse_face (dpyinfo
);
9042 /* On same tool-bar item as before. */
9045 clear_mouse_face (dpyinfo
);
9047 /* Mouse is down, but on different tool-bar item? */
9048 mouse_down_p
= (dpyinfo
->grabbed
9049 && f
== last_mouse_frame
9050 && FRAME_LIVE_P (f
));
9052 && last_tool_bar_item
!= prop_idx
)
9055 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
9056 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
9058 /* If tool-bar item is not enabled, don't highlight it. */
9059 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
9060 if (!NILP (enabled_p
))
9062 /* Compute the x-position of the glyph. In front and past the
9063 image is a space. We include this in the highlighted area. */
9064 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
9065 for (i
= x
= 0; i
< hpos
; ++i
)
9066 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
9068 /* Record this as the current active region. */
9069 dpyinfo
->mouse_face_beg_col
= hpos
;
9070 dpyinfo
->mouse_face_beg_row
= vpos
;
9071 dpyinfo
->mouse_face_beg_x
= x
;
9072 dpyinfo
->mouse_face_beg_y
= row
->y
;
9073 dpyinfo
->mouse_face_past_end
= 0;
9075 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
9076 dpyinfo
->mouse_face_end_row
= vpos
;
9077 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
9078 dpyinfo
->mouse_face_end_y
= row
->y
;
9079 dpyinfo
->mouse_face_window
= window
;
9080 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
9082 /* Display it as active. */
9083 show_mouse_face (dpyinfo
, draw
);
9084 dpyinfo
->mouse_face_image_state
= draw
;
9089 /* Set help_echo_string to a help string to display for this tool-bar item.
9090 XTread_socket does the rest. */
9091 help_echo_object
= help_echo_window
= Qnil
;
9093 help_echo_string
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_HELP
);
9094 if (NILP (help_echo_string
))
9095 help_echo_string
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_CAPTION
);
9098 #endif /* HAVE_WINDOW_SYSTEM */
9102 /************************************************************************
9103 Horizontal scrolling
9104 ************************************************************************/
9106 static int hscroll_window_tree
P_ ((Lisp_Object
));
9107 static int hscroll_windows
P_ ((Lisp_Object
));
9109 /* For all leaf windows in the window tree rooted at WINDOW, set their
9110 hscroll value so that PT is (i) visible in the window, and (ii) so
9111 that it is not within a certain margin at the window's left and
9112 right border. Value is non-zero if any window's hscroll has been
9116 hscroll_window_tree (window
)
9119 int hscrolled_p
= 0;
9120 int hscroll_relative_p
= FLOATP (Vhscroll_step
);
9121 int hscroll_step_abs
= 0;
9122 double hscroll_step_rel
= 0;
9124 if (hscroll_relative_p
)
9126 hscroll_step_rel
= XFLOAT_DATA (Vhscroll_step
);
9127 if (hscroll_step_rel
< 0)
9129 hscroll_relative_p
= 0;
9130 hscroll_step_abs
= 0;
9133 else if (INTEGERP (Vhscroll_step
))
9135 hscroll_step_abs
= XINT (Vhscroll_step
);
9136 if (hscroll_step_abs
< 0)
9137 hscroll_step_abs
= 0;
9140 hscroll_step_abs
= 0;
9142 while (WINDOWP (window
))
9144 struct window
*w
= XWINDOW (window
);
9146 if (WINDOWP (w
->hchild
))
9147 hscrolled_p
|= hscroll_window_tree (w
->hchild
);
9148 else if (WINDOWP (w
->vchild
))
9149 hscrolled_p
|= hscroll_window_tree (w
->vchild
);
9150 else if (w
->cursor
.vpos
>= 0)
9153 int text_area_width
;
9154 struct glyph_row
*current_cursor_row
9155 = MATRIX_ROW (w
->current_matrix
, w
->cursor
.vpos
);
9156 struct glyph_row
*desired_cursor_row
9157 = MATRIX_ROW (w
->desired_matrix
, w
->cursor
.vpos
);
9158 struct glyph_row
*cursor_row
9159 = (desired_cursor_row
->enabled_p
9160 ? desired_cursor_row
9161 : current_cursor_row
);
9163 text_area_width
= window_box_width (w
, TEXT_AREA
);
9165 /* Scroll when cursor is inside this scroll margin. */
9166 h_margin
= hscroll_margin
* WINDOW_FRAME_COLUMN_WIDTH (w
);
9168 if ((XFASTINT (w
->hscroll
)
9169 && w
->cursor
.x
<= h_margin
)
9170 || (cursor_row
->enabled_p
9171 && cursor_row
->truncated_on_right_p
9172 && (w
->cursor
.x
>= text_area_width
- h_margin
)))
9176 struct buffer
*saved_current_buffer
;
9180 /* Find point in a display of infinite width. */
9181 saved_current_buffer
= current_buffer
;
9182 current_buffer
= XBUFFER (w
->buffer
);
9184 if (w
== XWINDOW (selected_window
))
9185 pt
= BUF_PT (current_buffer
);
9188 pt
= marker_position (w
->pointm
);
9189 pt
= max (BEGV
, pt
);
9193 /* Move iterator to pt starting at cursor_row->start in
9194 a line with infinite width. */
9195 init_to_row_start (&it
, w
, cursor_row
);
9196 it
.last_visible_x
= INFINITY
;
9197 move_it_in_display_line_to (&it
, pt
, -1, MOVE_TO_POS
);
9198 current_buffer
= saved_current_buffer
;
9200 /* Position cursor in window. */
9201 if (!hscroll_relative_p
&& hscroll_step_abs
== 0)
9202 hscroll
= max (0, (it
.current_x
9203 - (ITERATOR_AT_END_OF_LINE_P (&it
)
9204 ? (text_area_width
- 4 * FRAME_COLUMN_WIDTH (it
.f
))
9205 : (text_area_width
/ 2))))
9206 / FRAME_COLUMN_WIDTH (it
.f
);
9207 else if (w
->cursor
.x
>= text_area_width
- h_margin
)
9209 if (hscroll_relative_p
)
9210 wanted_x
= text_area_width
* (1 - hscroll_step_rel
)
9213 wanted_x
= text_area_width
9214 - hscroll_step_abs
* FRAME_COLUMN_WIDTH (it
.f
)
9217 = max (0, it
.current_x
- wanted_x
) / FRAME_COLUMN_WIDTH (it
.f
);
9221 if (hscroll_relative_p
)
9222 wanted_x
= text_area_width
* hscroll_step_rel
9225 wanted_x
= hscroll_step_abs
* FRAME_COLUMN_WIDTH (it
.f
)
9228 = max (0, it
.current_x
- wanted_x
) / FRAME_COLUMN_WIDTH (it
.f
);
9230 hscroll
= max (hscroll
, XFASTINT (w
->min_hscroll
));
9232 /* Don't call Fset_window_hscroll if value hasn't
9233 changed because it will prevent redisplay
9235 if (XFASTINT (w
->hscroll
) != hscroll
)
9237 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
9238 w
->hscroll
= make_number (hscroll
);
9247 /* Value is non-zero if hscroll of any leaf window has been changed. */
9252 /* Set hscroll so that cursor is visible and not inside horizontal
9253 scroll margins for all windows in the tree rooted at WINDOW. See
9254 also hscroll_window_tree above. Value is non-zero if any window's
9255 hscroll has been changed. If it has, desired matrices on the frame
9256 of WINDOW are cleared. */
9259 hscroll_windows (window
)
9264 if (automatic_hscrolling_p
)
9266 hscrolled_p
= hscroll_window_tree (window
);
9268 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window
))));
9277 /************************************************************************
9279 ************************************************************************/
9281 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
9282 to a non-zero value. This is sometimes handy to have in a debugger
9287 /* First and last unchanged row for try_window_id. */
9289 int debug_first_unchanged_at_end_vpos
;
9290 int debug_last_unchanged_at_beg_vpos
;
9292 /* Delta vpos and y. */
9294 int debug_dvpos
, debug_dy
;
9296 /* Delta in characters and bytes for try_window_id. */
9298 int debug_delta
, debug_delta_bytes
;
9300 /* Values of window_end_pos and window_end_vpos at the end of
9303 EMACS_INT debug_end_pos
, debug_end_vpos
;
9305 /* Append a string to W->desired_matrix->method. FMT is a printf
9306 format string. A1...A9 are a supplement for a variable-length
9307 argument list. If trace_redisplay_p is non-zero also printf the
9308 resulting string to stderr. */
9311 debug_method_add (w
, fmt
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
)
9314 int a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
;
9317 char *method
= w
->desired_matrix
->method
;
9318 int len
= strlen (method
);
9319 int size
= sizeof w
->desired_matrix
->method
;
9320 int remaining
= size
- len
- 1;
9322 sprintf (buffer
, fmt
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
);
9323 if (len
&& remaining
)
9329 strncpy (method
+ len
, buffer
, remaining
);
9331 if (trace_redisplay_p
)
9332 fprintf (stderr
, "%p (%s): %s\n",
9334 ((BUFFERP (w
->buffer
)
9335 && STRINGP (XBUFFER (w
->buffer
)->name
))
9336 ? (char *) SDATA (XBUFFER (w
->buffer
)->name
)
9341 #endif /* GLYPH_DEBUG */
9344 /* Value is non-zero if all changes in window W, which displays
9345 current_buffer, are in the text between START and END. START is a
9346 buffer position, END is given as a distance from Z. Used in
9347 redisplay_internal for display optimization. */
9350 text_outside_line_unchanged_p (w
, start
, end
)
9354 int unchanged_p
= 1;
9356 /* If text or overlays have changed, see where. */
9357 if (XFASTINT (w
->last_modified
) < MODIFF
9358 || XFASTINT (w
->last_overlay_modified
) < OVERLAY_MODIFF
)
9360 /* Gap in the line? */
9361 if (GPT
< start
|| Z
- GPT
< end
)
9364 /* Changes start in front of the line, or end after it? */
9366 && (BEG_UNCHANGED
< start
- 1
9367 || END_UNCHANGED
< end
))
9370 /* If selective display, can't optimize if changes start at the
9371 beginning of the line. */
9373 && INTEGERP (current_buffer
->selective_display
)
9374 && XINT (current_buffer
->selective_display
) > 0
9375 && (BEG_UNCHANGED
< start
|| GPT
<= start
))
9378 /* If there are overlays at the start or end of the line, these
9379 may have overlay strings with newlines in them. A change at
9380 START, for instance, may actually concern the display of such
9381 overlay strings as well, and they are displayed on different
9382 lines. So, quickly rule out this case. (For the future, it
9383 might be desirable to implement something more telling than
9384 just BEG/END_UNCHANGED.) */
9387 if (BEG
+ BEG_UNCHANGED
== start
9388 && overlay_touches_p (start
))
9390 if (END_UNCHANGED
== end
9391 && overlay_touches_p (Z
- end
))
9400 /* Do a frame update, taking possible shortcuts into account. This is
9401 the main external entry point for redisplay.
9403 If the last redisplay displayed an echo area message and that message
9404 is no longer requested, we clear the echo area or bring back the
9405 mini-buffer if that is in use. */
9410 redisplay_internal (0);
9415 overlay_arrow_string_or_property (var
, pbitmap
)
9419 Lisp_Object pstr
= Fget (var
, Qoverlay_arrow_string
);
9425 if (bitmap
= Fget (var
, Qoverlay_arrow_bitmap
), INTEGERP (bitmap
))
9426 *pbitmap
= XINT (bitmap
);
9431 return Voverlay_arrow_string
;
9434 /* Return 1 if there are any overlay-arrows in current_buffer. */
9436 overlay_arrow_in_current_buffer_p ()
9440 for (vlist
= Voverlay_arrow_variable_list
;
9442 vlist
= XCDR (vlist
))
9444 Lisp_Object var
= XCAR (vlist
);
9449 val
= find_symbol_value (var
);
9451 && current_buffer
== XMARKER (val
)->buffer
)
9458 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
9462 overlay_arrows_changed_p ()
9466 for (vlist
= Voverlay_arrow_variable_list
;
9468 vlist
= XCDR (vlist
))
9470 Lisp_Object var
= XCAR (vlist
);
9471 Lisp_Object val
, pstr
;
9475 val
= find_symbol_value (var
);
9478 if (! EQ (COERCE_MARKER (val
),
9479 Fget (var
, Qlast_arrow_position
))
9480 || ! (pstr
= overlay_arrow_string_or_property (var
, 0),
9481 EQ (pstr
, Fget (var
, Qlast_arrow_string
))))
9487 /* Mark overlay arrows to be updated on next redisplay. */
9490 update_overlay_arrows (up_to_date
)
9495 for (vlist
= Voverlay_arrow_variable_list
;
9497 vlist
= XCDR (vlist
))
9499 Lisp_Object var
= XCAR (vlist
);
9506 Lisp_Object val
= find_symbol_value (var
);
9507 Fput (var
, Qlast_arrow_position
,
9508 COERCE_MARKER (val
));
9509 Fput (var
, Qlast_arrow_string
,
9510 overlay_arrow_string_or_property (var
, 0));
9512 else if (up_to_date
< 0
9513 || !NILP (Fget (var
, Qlast_arrow_position
)))
9515 Fput (var
, Qlast_arrow_position
, Qt
);
9516 Fput (var
, Qlast_arrow_string
, Qt
);
9522 /* Return overlay arrow string at row, or nil. */
9525 overlay_arrow_at_row (f
, row
, pbitmap
)
9527 struct glyph_row
*row
;
9532 for (vlist
= Voverlay_arrow_variable_list
;
9534 vlist
= XCDR (vlist
))
9536 Lisp_Object var
= XCAR (vlist
);
9542 val
= find_symbol_value (var
);
9545 && current_buffer
== XMARKER (val
)->buffer
9546 && (MATRIX_ROW_START_CHARPOS (row
) == marker_position (val
)))
9548 val
= overlay_arrow_string_or_property (var
, pbitmap
);
9549 if (FRAME_WINDOW_P (f
))
9551 else if (STRINGP (val
))
9561 /* Return 1 if point moved out of or into a composition. Otherwise
9562 return 0. PREV_BUF and PREV_PT are the last point buffer and
9563 position. BUF and PT are the current point buffer and position. */
9566 check_point_in_composition (prev_buf
, prev_pt
, buf
, pt
)
9567 struct buffer
*prev_buf
, *buf
;
9574 XSETBUFFER (buffer
, buf
);
9575 /* Check a composition at the last point if point moved within the
9577 if (prev_buf
== buf
)
9580 /* Point didn't move. */
9583 if (prev_pt
> BUF_BEGV (buf
) && prev_pt
< BUF_ZV (buf
)
9584 && find_composition (prev_pt
, -1, &start
, &end
, &prop
, buffer
)
9585 && COMPOSITION_VALID_P (start
, end
, prop
)
9586 && start
< prev_pt
&& end
> prev_pt
)
9587 /* The last point was within the composition. Return 1 iff
9588 point moved out of the composition. */
9589 return (pt
<= start
|| pt
>= end
);
9592 /* Check a composition at the current point. */
9593 return (pt
> BUF_BEGV (buf
) && pt
< BUF_ZV (buf
)
9594 && find_composition (pt
, -1, &start
, &end
, &prop
, buffer
)
9595 && COMPOSITION_VALID_P (start
, end
, prop
)
9596 && start
< pt
&& end
> pt
);
9600 /* Reconsider the setting of B->clip_changed which is displayed
9604 reconsider_clip_changes (w
, b
)
9609 && !NILP (w
->window_end_valid
)
9610 && w
->current_matrix
->buffer
== b
9611 && w
->current_matrix
->zv
== BUF_ZV (b
)
9612 && w
->current_matrix
->begv
== BUF_BEGV (b
))
9613 b
->clip_changed
= 0;
9615 /* If display wasn't paused, and W is not a tool bar window, see if
9616 point has been moved into or out of a composition. In that case,
9617 we set b->clip_changed to 1 to force updating the screen. If
9618 b->clip_changed has already been set to 1, we can skip this
9620 if (!b
->clip_changed
9621 && BUFFERP (w
->buffer
) && !NILP (w
->window_end_valid
))
9625 if (w
== XWINDOW (selected_window
))
9626 pt
= BUF_PT (current_buffer
);
9628 pt
= marker_position (w
->pointm
);
9630 if ((w
->current_matrix
->buffer
!= XBUFFER (w
->buffer
)
9631 || pt
!= XINT (w
->last_point
))
9632 && check_point_in_composition (w
->current_matrix
->buffer
,
9633 XINT (w
->last_point
),
9634 XBUFFER (w
->buffer
), pt
))
9635 b
->clip_changed
= 1;
9640 /* Select FRAME to forward the values of frame-local variables into C
9641 variables so that the redisplay routines can access those values
9645 select_frame_for_redisplay (frame
)
9648 Lisp_Object tail
, sym
, val
;
9649 Lisp_Object old
= selected_frame
;
9651 selected_frame
= frame
;
9653 for (tail
= XFRAME (frame
)->param_alist
; CONSP (tail
); tail
= XCDR (tail
))
9654 if (CONSP (XCAR (tail
))
9655 && (sym
= XCAR (XCAR (tail
)),
9657 && (sym
= indirect_variable (sym
),
9658 val
= SYMBOL_VALUE (sym
),
9659 (BUFFER_LOCAL_VALUEP (val
)
9660 || SOME_BUFFER_LOCAL_VALUEP (val
)))
9661 && XBUFFER_LOCAL_VALUE (val
)->check_frame
)
9662 Fsymbol_value (sym
);
9664 for (tail
= XFRAME (old
)->param_alist
; CONSP (tail
); tail
= XCDR (tail
))
9665 if (CONSP (XCAR (tail
))
9666 && (sym
= XCAR (XCAR (tail
)),
9668 && (sym
= indirect_variable (sym
),
9669 val
= SYMBOL_VALUE (sym
),
9670 (BUFFER_LOCAL_VALUEP (val
)
9671 || SOME_BUFFER_LOCAL_VALUEP (val
)))
9672 && XBUFFER_LOCAL_VALUE (val
)->check_frame
)
9673 Fsymbol_value (sym
);
9677 #define STOP_POLLING \
9678 do { if (! polling_stopped_here) stop_polling (); \
9679 polling_stopped_here = 1; } while (0)
9681 #define RESUME_POLLING \
9682 do { if (polling_stopped_here) start_polling (); \
9683 polling_stopped_here = 0; } while (0)
9686 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
9687 response to any user action; therefore, we should preserve the echo
9688 area. (Actually, our caller does that job.) Perhaps in the future
9689 avoid recentering windows if it is not necessary; currently that
9690 causes some problems. */
9693 redisplay_internal (preserve_echo_area
)
9694 int preserve_echo_area
;
9696 struct window
*w
= XWINDOW (selected_window
);
9697 struct frame
*f
= XFRAME (w
->frame
);
9699 int must_finish
= 0;
9700 struct text_pos tlbufpos
, tlendpos
;
9701 int number_of_visible_frames
;
9703 struct frame
*sf
= SELECTED_FRAME ();
9704 int polling_stopped_here
= 0;
9706 /* Non-zero means redisplay has to consider all windows on all
9707 frames. Zero means, only selected_window is considered. */
9708 int consider_all_windows_p
;
9710 TRACE ((stderr
, "redisplay_internal %d\n", redisplaying_p
));
9712 /* No redisplay if running in batch mode or frame is not yet fully
9713 initialized, or redisplay is explicitly turned off by setting
9714 Vinhibit_redisplay. */
9716 || !NILP (Vinhibit_redisplay
)
9717 || !f
->glyphs_initialized_p
)
9720 /* The flag redisplay_performed_directly_p is set by
9721 direct_output_for_insert when it already did the whole screen
9722 update necessary. */
9723 if (redisplay_performed_directly_p
)
9725 redisplay_performed_directly_p
= 0;
9726 if (!hscroll_windows (selected_window
))
9730 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
9731 if (popup_activated ())
9735 /* I don't think this happens but let's be paranoid. */
9739 /* Record a function that resets redisplaying_p to its old value
9740 when we leave this function. */
9741 count
= SPECPDL_INDEX ();
9742 record_unwind_protect (unwind_redisplay
,
9743 Fcons (make_number (redisplaying_p
), selected_frame
));
9745 specbind (Qinhibit_free_realized_faces
, Qnil
);
9749 reconsider_clip_changes (w
, current_buffer
);
9751 /* If new fonts have been loaded that make a glyph matrix adjustment
9752 necessary, do it. */
9753 if (fonts_changed_p
)
9755 adjust_glyphs (NULL
);
9756 ++windows_or_buffers_changed
;
9757 fonts_changed_p
= 0;
9760 /* If face_change_count is non-zero, init_iterator will free all
9761 realized faces, which includes the faces referenced from current
9762 matrices. So, we can't reuse current matrices in this case. */
9763 if (face_change_count
)
9764 ++windows_or_buffers_changed
;
9766 if (! FRAME_WINDOW_P (sf
)
9767 && previous_terminal_frame
!= sf
)
9769 /* Since frames on an ASCII terminal share the same display
9770 area, displaying a different frame means redisplay the whole
9772 windows_or_buffers_changed
++;
9773 SET_FRAME_GARBAGED (sf
);
9774 XSETFRAME (Vterminal_frame
, sf
);
9776 previous_terminal_frame
= sf
;
9778 /* Set the visible flags for all frames. Do this before checking
9779 for resized or garbaged frames; they want to know if their frames
9780 are visible. See the comment in frame.h for
9781 FRAME_SAMPLE_VISIBILITY. */
9783 Lisp_Object tail
, frame
;
9785 number_of_visible_frames
= 0;
9787 FOR_EACH_FRAME (tail
, frame
)
9789 struct frame
*f
= XFRAME (frame
);
9791 FRAME_SAMPLE_VISIBILITY (f
);
9792 if (FRAME_VISIBLE_P (f
))
9793 ++number_of_visible_frames
;
9794 clear_desired_matrices (f
);
9798 /* Notice any pending interrupt request to change frame size. */
9799 do_pending_window_change (1);
9801 /* Clear frames marked as garbaged. */
9803 clear_garbaged_frames ();
9805 /* Build menubar and tool-bar items. */
9806 prepare_menu_bars ();
9808 if (windows_or_buffers_changed
)
9809 update_mode_lines
++;
9811 /* Detect case that we need to write or remove a star in the mode line. */
9812 if ((SAVE_MODIFF
< MODIFF
) != !NILP (w
->last_had_star
))
9814 w
->update_mode_line
= Qt
;
9815 if (buffer_shared
> 1)
9816 update_mode_lines
++;
9819 /* If %c is in the mode line, update it if needed. */
9820 if (!NILP (w
->column_number_displayed
)
9821 /* This alternative quickly identifies a common case
9822 where no change is needed. */
9823 && !(PT
== XFASTINT (w
->last_point
)
9824 && XFASTINT (w
->last_modified
) >= MODIFF
9825 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
)
9826 && (XFASTINT (w
->column_number_displayed
)
9827 != (int) current_column ())) /* iftc */
9828 w
->update_mode_line
= Qt
;
9830 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w
->frame
)) = -1;
9832 /* The variable buffer_shared is set in redisplay_window and
9833 indicates that we redisplay a buffer in different windows. See
9835 consider_all_windows_p
= (update_mode_lines
|| buffer_shared
> 1
9836 || cursor_type_changed
);
9838 /* If specs for an arrow have changed, do thorough redisplay
9839 to ensure we remove any arrow that should no longer exist. */
9840 if (overlay_arrows_changed_p ())
9841 consider_all_windows_p
= windows_or_buffers_changed
= 1;
9843 /* Normally the message* functions will have already displayed and
9844 updated the echo area, but the frame may have been trashed, or
9845 the update may have been preempted, so display the echo area
9846 again here. Checking message_cleared_p captures the case that
9847 the echo area should be cleared. */
9848 if ((!NILP (echo_area_buffer
[0]) && !display_last_displayed_message_p
)
9849 || (!NILP (echo_area_buffer
[1]) && display_last_displayed_message_p
)
9850 || (message_cleared_p
9851 && minibuf_level
== 0
9852 /* If the mini-window is currently selected, this means the
9853 echo-area doesn't show through. */
9854 && !MINI_WINDOW_P (XWINDOW (selected_window
))))
9856 int window_height_changed_p
= echo_area_display (0);
9859 /* If we don't display the current message, don't clear the
9860 message_cleared_p flag, because, if we did, we wouldn't clear
9861 the echo area in the next redisplay which doesn't preserve
9863 if (!display_last_displayed_message_p
)
9864 message_cleared_p
= 0;
9866 if (fonts_changed_p
)
9868 else if (window_height_changed_p
)
9870 consider_all_windows_p
= 1;
9871 ++update_mode_lines
;
9872 ++windows_or_buffers_changed
;
9874 /* If window configuration was changed, frames may have been
9875 marked garbaged. Clear them or we will experience
9876 surprises wrt scrolling. */
9878 clear_garbaged_frames ();
9881 else if (EQ (selected_window
, minibuf_window
)
9882 && (current_buffer
->clip_changed
9883 || XFASTINT (w
->last_modified
) < MODIFF
9884 || XFASTINT (w
->last_overlay_modified
) < OVERLAY_MODIFF
)
9885 && resize_mini_window (w
, 0))
9887 /* Resized active mini-window to fit the size of what it is
9888 showing if its contents might have changed. */
9890 consider_all_windows_p
= 1;
9891 ++windows_or_buffers_changed
;
9892 ++update_mode_lines
;
9894 /* If window configuration was changed, frames may have been
9895 marked garbaged. Clear them or we will experience
9896 surprises wrt scrolling. */
9898 clear_garbaged_frames ();
9902 /* If showing the region, and mark has changed, we must redisplay
9903 the whole window. The assignment to this_line_start_pos prevents
9904 the optimization directly below this if-statement. */
9905 if (((!NILP (Vtransient_mark_mode
)
9906 && !NILP (XBUFFER (w
->buffer
)->mark_active
))
9907 != !NILP (w
->region_showing
))
9908 || (!NILP (w
->region_showing
)
9909 && !EQ (w
->region_showing
,
9910 Fmarker_position (XBUFFER (w
->buffer
)->mark
))))
9911 CHARPOS (this_line_start_pos
) = 0;
9913 /* Optimize the case that only the line containing the cursor in the
9914 selected window has changed. Variables starting with this_ are
9915 set in display_line and record information about the line
9916 containing the cursor. */
9917 tlbufpos
= this_line_start_pos
;
9918 tlendpos
= this_line_end_pos
;
9919 if (!consider_all_windows_p
9920 && CHARPOS (tlbufpos
) > 0
9921 && NILP (w
->update_mode_line
)
9922 && !current_buffer
->clip_changed
9923 && !current_buffer
->prevent_redisplay_optimizations_p
9924 && FRAME_VISIBLE_P (XFRAME (w
->frame
))
9925 && !FRAME_OBSCURED_P (XFRAME (w
->frame
))
9926 /* Make sure recorded data applies to current buffer, etc. */
9927 && this_line_buffer
== current_buffer
9928 && current_buffer
== XBUFFER (w
->buffer
)
9929 && NILP (w
->force_start
)
9930 && NILP (w
->optional_new_start
)
9931 /* Point must be on the line that we have info recorded about. */
9932 && PT
>= CHARPOS (tlbufpos
)
9933 && PT
<= Z
- CHARPOS (tlendpos
)
9934 /* All text outside that line, including its final newline,
9935 must be unchanged */
9936 && text_outside_line_unchanged_p (w
, CHARPOS (tlbufpos
),
9937 CHARPOS (tlendpos
)))
9939 if (CHARPOS (tlbufpos
) > BEGV
9940 && FETCH_BYTE (BYTEPOS (tlbufpos
) - 1) != '\n'
9941 && (CHARPOS (tlbufpos
) == ZV
9942 || FETCH_BYTE (BYTEPOS (tlbufpos
)) == '\n'))
9943 /* Former continuation line has disappeared by becoming empty */
9945 else if (XFASTINT (w
->last_modified
) < MODIFF
9946 || XFASTINT (w
->last_overlay_modified
) < OVERLAY_MODIFF
9947 || MINI_WINDOW_P (w
))
9949 /* We have to handle the case of continuation around a
9950 wide-column character (See the comment in indent.c around
9953 For instance, in the following case:
9955 -------- Insert --------
9956 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
9957 J_I_ ==> J_I_ `^^' are cursors.
9961 As we have to redraw the line above, we should goto cancel. */
9964 int line_height_before
= this_line_pixel_height
;
9966 /* Note that start_display will handle the case that the
9967 line starting at tlbufpos is a continuation lines. */
9968 start_display (&it
, w
, tlbufpos
);
9970 /* Implementation note: It this still necessary? */
9971 if (it
.current_x
!= this_line_start_x
)
9974 TRACE ((stderr
, "trying display optimization 1\n"));
9975 w
->cursor
.vpos
= -1;
9976 overlay_arrow_seen
= 0;
9977 it
.vpos
= this_line_vpos
;
9978 it
.current_y
= this_line_y
;
9979 it
.glyph_row
= MATRIX_ROW (w
->desired_matrix
, this_line_vpos
);
9982 /* If line contains point, is not continued,
9983 and ends at same distance from eob as before, we win */
9984 if (w
->cursor
.vpos
>= 0
9985 /* Line is not continued, otherwise this_line_start_pos
9986 would have been set to 0 in display_line. */
9987 && CHARPOS (this_line_start_pos
)
9988 /* Line ends as before. */
9989 && CHARPOS (this_line_end_pos
) == CHARPOS (tlendpos
)
9990 /* Line has same height as before. Otherwise other lines
9991 would have to be shifted up or down. */
9992 && this_line_pixel_height
== line_height_before
)
9994 /* If this is not the window's last line, we must adjust
9995 the charstarts of the lines below. */
9996 if (it
.current_y
< it
.last_visible_y
)
9998 struct glyph_row
*row
9999 = MATRIX_ROW (w
->current_matrix
, this_line_vpos
+ 1);
10000 int delta
, delta_bytes
;
10002 if (Z
- CHARPOS (tlendpos
) == ZV
)
10004 /* This line ends at end of (accessible part of)
10005 buffer. There is no newline to count. */
10007 - CHARPOS (tlendpos
)
10008 - MATRIX_ROW_START_CHARPOS (row
));
10009 delta_bytes
= (Z_BYTE
10010 - BYTEPOS (tlendpos
)
10011 - MATRIX_ROW_START_BYTEPOS (row
));
10015 /* This line ends in a newline. Must take
10016 account of the newline and the rest of the
10017 text that follows. */
10019 - CHARPOS (tlendpos
)
10020 - MATRIX_ROW_START_CHARPOS (row
));
10021 delta_bytes
= (Z_BYTE
10022 - BYTEPOS (tlendpos
)
10023 - MATRIX_ROW_START_BYTEPOS (row
));
10026 increment_matrix_positions (w
->current_matrix
,
10027 this_line_vpos
+ 1,
10028 w
->current_matrix
->nrows
,
10029 delta
, delta_bytes
);
10032 /* If this row displays text now but previously didn't,
10033 or vice versa, w->window_end_vpos may have to be
10035 if ((it
.glyph_row
- 1)->displays_text_p
)
10037 if (XFASTINT (w
->window_end_vpos
) < this_line_vpos
)
10038 XSETINT (w
->window_end_vpos
, this_line_vpos
);
10040 else if (XFASTINT (w
->window_end_vpos
) == this_line_vpos
10041 && this_line_vpos
> 0)
10042 XSETINT (w
->window_end_vpos
, this_line_vpos
- 1);
10043 w
->window_end_valid
= Qnil
;
10045 /* Update hint: No need to try to scroll in update_window. */
10046 w
->desired_matrix
->no_scrolling_p
= 1;
10049 *w
->desired_matrix
->method
= 0;
10050 debug_method_add (w
, "optimization 1");
10052 #ifdef HAVE_WINDOW_SYSTEM
10053 update_window_fringes (w
, 0);
10060 else if (/* Cursor position hasn't changed. */
10061 PT
== XFASTINT (w
->last_point
)
10062 /* Make sure the cursor was last displayed
10063 in this window. Otherwise we have to reposition it. */
10064 && 0 <= w
->cursor
.vpos
10065 && WINDOW_TOTAL_LINES (w
) > w
->cursor
.vpos
)
10069 do_pending_window_change (1);
10071 /* We used to always goto end_of_redisplay here, but this
10072 isn't enough if we have a blinking cursor. */
10073 if (w
->cursor_off_p
== w
->last_cursor_off_p
)
10074 goto end_of_redisplay
;
10078 /* If highlighting the region, or if the cursor is in the echo area,
10079 then we can't just move the cursor. */
10080 else if (! (!NILP (Vtransient_mark_mode
)
10081 && !NILP (current_buffer
->mark_active
))
10082 && (EQ (selected_window
, current_buffer
->last_selected_window
)
10083 || highlight_nonselected_windows
)
10084 && NILP (w
->region_showing
)
10085 && NILP (Vshow_trailing_whitespace
)
10086 && !cursor_in_echo_area
)
10089 struct glyph_row
*row
;
10091 /* Skip from tlbufpos to PT and see where it is. Note that
10092 PT may be in invisible text. If so, we will end at the
10093 next visible position. */
10094 init_iterator (&it
, w
, CHARPOS (tlbufpos
), BYTEPOS (tlbufpos
),
10095 NULL
, DEFAULT_FACE_ID
);
10096 it
.current_x
= this_line_start_x
;
10097 it
.current_y
= this_line_y
;
10098 it
.vpos
= this_line_vpos
;
10100 /* The call to move_it_to stops in front of PT, but
10101 moves over before-strings. */
10102 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
10104 if (it
.vpos
== this_line_vpos
10105 && (row
= MATRIX_ROW (w
->current_matrix
, this_line_vpos
),
10108 xassert (this_line_vpos
== it
.vpos
);
10109 xassert (this_line_y
== it
.current_y
);
10110 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
10112 *w
->desired_matrix
->method
= 0;
10113 debug_method_add (w
, "optimization 3");
10122 /* Text changed drastically or point moved off of line. */
10123 SET_MATRIX_ROW_ENABLED_P (w
->desired_matrix
, this_line_vpos
, 0);
10126 CHARPOS (this_line_start_pos
) = 0;
10127 consider_all_windows_p
|= buffer_shared
> 1;
10128 ++clear_face_cache_count
;
10131 /* Build desired matrices, and update the display. If
10132 consider_all_windows_p is non-zero, do it for all windows on all
10133 frames. Otherwise do it for selected_window, only. */
10135 if (consider_all_windows_p
)
10137 Lisp_Object tail
, frame
;
10138 int i
, n
= 0, size
= 50;
10139 struct frame
**updated
10140 = (struct frame
**) alloca (size
* sizeof *updated
);
10142 /* Clear the face cache eventually. */
10143 if (clear_face_cache_count
> CLEAR_FACE_CACHE_COUNT
)
10145 clear_face_cache (0);
10146 clear_face_cache_count
= 0;
10149 /* Recompute # windows showing selected buffer. This will be
10150 incremented each time such a window is displayed. */
10153 FOR_EACH_FRAME (tail
, frame
)
10155 struct frame
*f
= XFRAME (frame
);
10157 if (FRAME_WINDOW_P (f
) || f
== sf
)
10159 if (! EQ (frame
, selected_frame
))
10160 /* Select the frame, for the sake of frame-local
10162 select_frame_for_redisplay (frame
);
10164 #ifdef HAVE_WINDOW_SYSTEM
10165 if (clear_face_cache_count
% 50 == 0
10166 && FRAME_WINDOW_P (f
))
10167 clear_image_cache (f
, 0);
10168 #endif /* HAVE_WINDOW_SYSTEM */
10170 /* Mark all the scroll bars to be removed; we'll redeem
10171 the ones we want when we redisplay their windows. */
10172 if (condemn_scroll_bars_hook
)
10173 condemn_scroll_bars_hook (f
);
10175 if (FRAME_VISIBLE_P (f
) && !FRAME_OBSCURED_P (f
))
10176 redisplay_windows (FRAME_ROOT_WINDOW (f
));
10178 /* Any scroll bars which redisplay_windows should have
10179 nuked should now go away. */
10180 if (judge_scroll_bars_hook
)
10181 judge_scroll_bars_hook (f
);
10183 /* If fonts changed, display again. */
10184 /* ??? rms: I suspect it is a mistake to jump all the way
10185 back to retry here. It should just retry this frame. */
10186 if (fonts_changed_p
)
10189 if (FRAME_VISIBLE_P (f
) && !FRAME_OBSCURED_P (f
))
10191 /* See if we have to hscroll. */
10192 if (hscroll_windows (f
->root_window
))
10195 /* Prevent various kinds of signals during display
10196 update. stdio is not robust about handling
10197 signals, which can cause an apparent I/O
10199 if (interrupt_input
)
10200 unrequest_sigio ();
10203 /* Update the display. */
10204 set_window_update_flags (XWINDOW (f
->root_window
), 1);
10205 pause
|= update_frame (f
, 0, 0);
10206 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
10213 int nbytes
= size
* sizeof *updated
;
10214 struct frame
**p
= (struct frame
**) alloca (2 * nbytes
);
10215 bcopy (updated
, p
, nbytes
);
10226 /* Do the mark_window_display_accurate after all windows have
10227 been redisplayed because this call resets flags in buffers
10228 which are needed for proper redisplay. */
10229 for (i
= 0; i
< n
; ++i
)
10231 struct frame
*f
= updated
[i
];
10232 mark_window_display_accurate (f
->root_window
, 1);
10233 if (frame_up_to_date_hook
)
10234 frame_up_to_date_hook (f
);
10238 else if (FRAME_VISIBLE_P (sf
) && !FRAME_OBSCURED_P (sf
))
10240 Lisp_Object mini_window
;
10241 struct frame
*mini_frame
;
10243 displayed_buffer
= XBUFFER (XWINDOW (selected_window
)->buffer
);
10244 /* Use list_of_error, not Qerror, so that
10245 we catch only errors and don't run the debugger. */
10246 internal_condition_case_1 (redisplay_window_1
, selected_window
,
10248 redisplay_window_error
);
10250 /* Compare desired and current matrices, perform output. */
10253 /* If fonts changed, display again. */
10254 if (fonts_changed_p
)
10257 /* Prevent various kinds of signals during display update.
10258 stdio is not robust about handling signals,
10259 which can cause an apparent I/O error. */
10260 if (interrupt_input
)
10261 unrequest_sigio ();
10264 if (FRAME_VISIBLE_P (sf
) && !FRAME_OBSCURED_P (sf
))
10266 if (hscroll_windows (selected_window
))
10269 XWINDOW (selected_window
)->must_be_updated_p
= 1;
10270 pause
= update_frame (sf
, 0, 0);
10273 /* We may have called echo_area_display at the top of this
10274 function. If the echo area is on another frame, that may
10275 have put text on a frame other than the selected one, so the
10276 above call to update_frame would not have caught it. Catch
10278 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
10279 mini_frame
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
10281 if (mini_frame
!= sf
&& FRAME_WINDOW_P (mini_frame
))
10283 XWINDOW (mini_window
)->must_be_updated_p
= 1;
10284 pause
|= update_frame (mini_frame
, 0, 0);
10285 if (!pause
&& hscroll_windows (mini_window
))
10290 /* If display was paused because of pending input, make sure we do a
10291 thorough update the next time. */
10294 /* Prevent the optimization at the beginning of
10295 redisplay_internal that tries a single-line update of the
10296 line containing the cursor in the selected window. */
10297 CHARPOS (this_line_start_pos
) = 0;
10299 /* Let the overlay arrow be updated the next time. */
10300 update_overlay_arrows (0);
10302 /* If we pause after scrolling, some rows in the current
10303 matrices of some windows are not valid. */
10304 if (!WINDOW_FULL_WIDTH_P (w
)
10305 && !FRAME_WINDOW_P (XFRAME (w
->frame
)))
10306 update_mode_lines
= 1;
10310 if (!consider_all_windows_p
)
10312 /* This has already been done above if
10313 consider_all_windows_p is set. */
10314 mark_window_display_accurate_1 (w
, 1);
10316 /* Say overlay arrows are up to date. */
10317 update_overlay_arrows (1);
10319 if (frame_up_to_date_hook
!= 0)
10320 frame_up_to_date_hook (sf
);
10323 update_mode_lines
= 0;
10324 windows_or_buffers_changed
= 0;
10325 cursor_type_changed
= 0;
10328 /* Start SIGIO interrupts coming again. Having them off during the
10329 code above makes it less likely one will discard output, but not
10330 impossible, since there might be stuff in the system buffer here.
10331 But it is much hairier to try to do anything about that. */
10332 if (interrupt_input
)
10336 /* If a frame has become visible which was not before, redisplay
10337 again, so that we display it. Expose events for such a frame
10338 (which it gets when becoming visible) don't call the parts of
10339 redisplay constructing glyphs, so simply exposing a frame won't
10340 display anything in this case. So, we have to display these
10341 frames here explicitly. */
10344 Lisp_Object tail
, frame
;
10347 FOR_EACH_FRAME (tail
, frame
)
10349 int this_is_visible
= 0;
10351 if (XFRAME (frame
)->visible
)
10352 this_is_visible
= 1;
10353 FRAME_SAMPLE_VISIBILITY (XFRAME (frame
));
10354 if (XFRAME (frame
)->visible
)
10355 this_is_visible
= 1;
10357 if (this_is_visible
)
10361 if (new_count
!= number_of_visible_frames
)
10362 windows_or_buffers_changed
++;
10365 /* Change frame size now if a change is pending. */
10366 do_pending_window_change (1);
10368 /* If we just did a pending size change, or have additional
10369 visible frames, redisplay again. */
10370 if (windows_or_buffers_changed
&& !pause
)
10374 unbind_to (count
, Qnil
);
10379 /* Redisplay, but leave alone any recent echo area message unless
10380 another message has been requested in its place.
10382 This is useful in situations where you need to redisplay but no
10383 user action has occurred, making it inappropriate for the message
10384 area to be cleared. See tracking_off and
10385 wait_reading_process_output for examples of these situations.
10387 FROM_WHERE is an integer saying from where this function was
10388 called. This is useful for debugging. */
10391 redisplay_preserve_echo_area (from_where
)
10394 TRACE ((stderr
, "redisplay_preserve_echo_area (%d)\n", from_where
));
10396 if (!NILP (echo_area_buffer
[1]))
10398 /* We have a previously displayed message, but no current
10399 message. Redisplay the previous message. */
10400 display_last_displayed_message_p
= 1;
10401 redisplay_internal (1);
10402 display_last_displayed_message_p
= 0;
10405 redisplay_internal (1);
10409 /* Function registered with record_unwind_protect in
10410 redisplay_internal. Reset redisplaying_p to the value it had
10411 before redisplay_internal was called, and clear
10412 prevent_freeing_realized_faces_p. It also selects the previously
10416 unwind_redisplay (val
)
10419 Lisp_Object old_redisplaying_p
, old_frame
;
10421 old_redisplaying_p
= XCAR (val
);
10422 redisplaying_p
= XFASTINT (old_redisplaying_p
);
10423 old_frame
= XCDR (val
);
10424 if (! EQ (old_frame
, selected_frame
))
10425 select_frame_for_redisplay (old_frame
);
10430 /* Mark the display of window W as accurate or inaccurate. If
10431 ACCURATE_P is non-zero mark display of W as accurate. If
10432 ACCURATE_P is zero, arrange for W to be redisplayed the next time
10433 redisplay_internal is called. */
10436 mark_window_display_accurate_1 (w
, accurate_p
)
10440 if (BUFFERP (w
->buffer
))
10442 struct buffer
*b
= XBUFFER (w
->buffer
);
10445 = make_number (accurate_p
? BUF_MODIFF (b
) : 0);
10446 w
->last_overlay_modified
10447 = make_number (accurate_p
? BUF_OVERLAY_MODIFF (b
) : 0);
10449 = BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
) ? Qt
: Qnil
;
10453 b
->clip_changed
= 0;
10454 b
->prevent_redisplay_optimizations_p
= 0;
10456 BUF_UNCHANGED_MODIFIED (b
) = BUF_MODIFF (b
);
10457 BUF_OVERLAY_UNCHANGED_MODIFIED (b
) = BUF_OVERLAY_MODIFF (b
);
10458 BUF_BEG_UNCHANGED (b
) = BUF_GPT (b
) - BUF_BEG (b
);
10459 BUF_END_UNCHANGED (b
) = BUF_Z (b
) - BUF_GPT (b
);
10461 w
->current_matrix
->buffer
= b
;
10462 w
->current_matrix
->begv
= BUF_BEGV (b
);
10463 w
->current_matrix
->zv
= BUF_ZV (b
);
10465 w
->last_cursor
= w
->cursor
;
10466 w
->last_cursor_off_p
= w
->cursor_off_p
;
10468 if (w
== XWINDOW (selected_window
))
10469 w
->last_point
= make_number (BUF_PT (b
));
10471 w
->last_point
= make_number (XMARKER (w
->pointm
)->charpos
);
10477 w
->window_end_valid
= w
->buffer
;
10478 #if 0 /* This is incorrect with variable-height lines. */
10479 xassert (XINT (w
->window_end_vpos
)
10480 < (WINDOW_TOTAL_LINES (w
)
10481 - (WINDOW_WANTS_MODELINE_P (w
) ? 1 : 0)));
10483 w
->update_mode_line
= Qnil
;
10488 /* Mark the display of windows in the window tree rooted at WINDOW as
10489 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
10490 windows as accurate. If ACCURATE_P is zero, arrange for windows to
10491 be redisplayed the next time redisplay_internal is called. */
10494 mark_window_display_accurate (window
, accurate_p
)
10495 Lisp_Object window
;
10500 for (; !NILP (window
); window
= w
->next
)
10502 w
= XWINDOW (window
);
10503 mark_window_display_accurate_1 (w
, accurate_p
);
10505 if (!NILP (w
->vchild
))
10506 mark_window_display_accurate (w
->vchild
, accurate_p
);
10507 if (!NILP (w
->hchild
))
10508 mark_window_display_accurate (w
->hchild
, accurate_p
);
10513 update_overlay_arrows (1);
10517 /* Force a thorough redisplay the next time by setting
10518 last_arrow_position and last_arrow_string to t, which is
10519 unequal to any useful value of Voverlay_arrow_... */
10520 update_overlay_arrows (-1);
10525 /* Return value in display table DP (Lisp_Char_Table *) for character
10526 C. Since a display table doesn't have any parent, we don't have to
10527 follow parent. Do not call this function directly but use the
10528 macro DISP_CHAR_VECTOR. */
10531 disp_char_vector (dp
, c
)
10532 struct Lisp_Char_Table
*dp
;
10538 if (SINGLE_BYTE_CHAR_P (c
))
10539 return (dp
->contents
[c
]);
10541 SPLIT_CHAR (c
, code
[0], code
[1], code
[2]);
10544 else if (code
[2] < 32)
10547 /* Here, the possible range of code[0] (== charset ID) is
10548 128..max_charset. Since the top level char table contains data
10549 for multibyte characters after 256th element, we must increment
10550 code[0] by 128 to get a correct index. */
10552 code
[3] = -1; /* anchor */
10554 for (i
= 0; code
[i
] >= 0; i
++, dp
= XCHAR_TABLE (val
))
10556 val
= dp
->contents
[code
[i
]];
10557 if (!SUB_CHAR_TABLE_P (val
))
10558 return (NILP (val
) ? dp
->defalt
: val
);
10561 /* Here, val is a sub char table. We return the default value of
10563 return (dp
->defalt
);
10568 /***********************************************************************
10570 ***********************************************************************/
10572 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
10575 redisplay_windows (window
)
10576 Lisp_Object window
;
10578 while (!NILP (window
))
10580 struct window
*w
= XWINDOW (window
);
10582 if (!NILP (w
->hchild
))
10583 redisplay_windows (w
->hchild
);
10584 else if (!NILP (w
->vchild
))
10585 redisplay_windows (w
->vchild
);
10588 displayed_buffer
= XBUFFER (w
->buffer
);
10589 /* Use list_of_error, not Qerror, so that
10590 we catch only errors and don't run the debugger. */
10591 internal_condition_case_1 (redisplay_window_0
, window
,
10593 redisplay_window_error
);
10601 redisplay_window_error ()
10603 displayed_buffer
->display_error_modiff
= BUF_MODIFF (displayed_buffer
);
10608 redisplay_window_0 (window
)
10609 Lisp_Object window
;
10611 if (displayed_buffer
->display_error_modiff
< BUF_MODIFF (displayed_buffer
))
10612 redisplay_window (window
, 0);
10617 redisplay_window_1 (window
)
10618 Lisp_Object window
;
10620 if (displayed_buffer
->display_error_modiff
< BUF_MODIFF (displayed_buffer
))
10621 redisplay_window (window
, 1);
10626 /* Increment GLYPH until it reaches END or CONDITION fails while
10627 adding (GLYPH)->pixel_width to X. */
10629 #define SKIP_GLYPHS(glyph, end, x, condition) \
10632 (x) += (glyph)->pixel_width; \
10635 while ((glyph) < (end) && (condition))
10638 /* Set cursor position of W. PT is assumed to be displayed in ROW.
10639 DELTA is the number of bytes by which positions recorded in ROW
10640 differ from current buffer positions. */
10643 set_cursor_from_row (w
, row
, matrix
, delta
, delta_bytes
, dy
, dvpos
)
10645 struct glyph_row
*row
;
10646 struct glyph_matrix
*matrix
;
10647 int delta
, delta_bytes
, dy
, dvpos
;
10649 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
10650 struct glyph
*end
= glyph
+ row
->used
[TEXT_AREA
];
10651 struct glyph
*cursor
= NULL
;
10652 /* The first glyph that starts a sequence of glyphs from string. */
10653 struct glyph
*string_start
;
10654 /* The X coordinate of string_start. */
10655 int string_start_x
;
10656 /* The last known character position. */
10657 int last_pos
= MATRIX_ROW_START_CHARPOS (row
) + delta
;
10658 /* The last known character position before string_start. */
10659 int string_before_pos
;
10662 int cursor_from_overlay_pos
= 0;
10663 int pt_old
= PT
- delta
;
10665 /* Skip over glyphs not having an object at the start of the row.
10666 These are special glyphs like truncation marks on terminal
10668 if (row
->displays_text_p
)
10670 && INTEGERP (glyph
->object
)
10671 && glyph
->charpos
< 0)
10673 x
+= glyph
->pixel_width
;
10677 string_start
= NULL
;
10679 && !INTEGERP (glyph
->object
)
10680 && (!BUFFERP (glyph
->object
)
10681 || (last_pos
= glyph
->charpos
) < pt_old
))
10683 if (! STRINGP (glyph
->object
))
10685 string_start
= NULL
;
10686 x
+= glyph
->pixel_width
;
10688 if (cursor_from_overlay_pos
10689 && last_pos
> cursor_from_overlay_pos
)
10691 cursor_from_overlay_pos
= 0;
10697 string_before_pos
= last_pos
;
10698 string_start
= glyph
;
10699 string_start_x
= x
;
10700 /* Skip all glyphs from string. */
10704 if ((cursor
== NULL
|| glyph
> cursor
)
10705 && !NILP (Fget_char_property (make_number ((glyph
)->charpos
),
10706 Qcursor
, (glyph
)->object
))
10707 && (pos
= string_buffer_position (w
, glyph
->object
,
10708 string_before_pos
),
10709 (pos
== 0 /* From overlay */
10710 || pos
== pt_old
)))
10712 /* Estimate overlay buffer position from the buffer
10713 positions of the glyphs before and after the overlay.
10714 Add 1 to last_pos so that if point corresponds to the
10715 glyph right after the overlay, we still use a 'cursor'
10716 property found in that overlay. */
10717 cursor_from_overlay_pos
= pos
== 0 ? last_pos
+1 : 0;
10721 x
+= glyph
->pixel_width
;
10724 while (glyph
< end
&& STRINGP (glyph
->object
));
10728 if (cursor
!= NULL
)
10733 else if (string_start
10734 && (glyph
== end
|| !BUFFERP (glyph
->object
) || last_pos
> pt_old
))
10736 /* We may have skipped over point because the previous glyphs
10737 are from string. As there's no easy way to know the
10738 character position of the current glyph, find the correct
10739 glyph on point by scanning from string_start again. */
10741 Lisp_Object string
;
10744 limit
= make_number (pt_old
+ 1);
10746 glyph
= string_start
;
10747 x
= string_start_x
;
10748 string
= glyph
->object
;
10749 pos
= string_buffer_position (w
, string
, string_before_pos
);
10750 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
10751 because we always put cursor after overlay strings. */
10752 while (pos
== 0 && glyph
< end
)
10754 string
= glyph
->object
;
10755 SKIP_GLYPHS (glyph
, end
, x
, EQ (glyph
->object
, string
));
10757 pos
= string_buffer_position (w
, glyph
->object
, string_before_pos
);
10760 while (glyph
< end
)
10762 pos
= XINT (Fnext_single_char_property_change
10763 (make_number (pos
), Qdisplay
, Qnil
, limit
));
10766 /* Skip glyphs from the same string. */
10767 string
= glyph
->object
;
10768 SKIP_GLYPHS (glyph
, end
, x
, EQ (glyph
->object
, string
));
10769 /* Skip glyphs from an overlay. */
10771 && ! string_buffer_position (w
, glyph
->object
, pos
))
10773 string
= glyph
->object
;
10774 SKIP_GLYPHS (glyph
, end
, x
, EQ (glyph
->object
, string
));
10779 w
->cursor
.hpos
= glyph
- row
->glyphs
[TEXT_AREA
];
10781 w
->cursor
.vpos
= MATRIX_ROW_VPOS (row
, matrix
) + dvpos
;
10782 w
->cursor
.y
= row
->y
+ dy
;
10784 if (w
== XWINDOW (selected_window
))
10786 if (!row
->continued_p
10787 && !MATRIX_ROW_CONTINUATION_LINE_P (row
)
10790 this_line_buffer
= XBUFFER (w
->buffer
);
10792 CHARPOS (this_line_start_pos
)
10793 = MATRIX_ROW_START_CHARPOS (row
) + delta
;
10794 BYTEPOS (this_line_start_pos
)
10795 = MATRIX_ROW_START_BYTEPOS (row
) + delta_bytes
;
10797 CHARPOS (this_line_end_pos
)
10798 = Z
- (MATRIX_ROW_END_CHARPOS (row
) + delta
);
10799 BYTEPOS (this_line_end_pos
)
10800 = Z_BYTE
- (MATRIX_ROW_END_BYTEPOS (row
) + delta_bytes
);
10802 this_line_y
= w
->cursor
.y
;
10803 this_line_pixel_height
= row
->height
;
10804 this_line_vpos
= w
->cursor
.vpos
;
10805 this_line_start_x
= row
->x
;
10808 CHARPOS (this_line_start_pos
) = 0;
10813 /* Run window scroll functions, if any, for WINDOW with new window
10814 start STARTP. Sets the window start of WINDOW to that position.
10816 We assume that the window's buffer is really current. */
10818 static INLINE
struct text_pos
10819 run_window_scroll_functions (window
, startp
)
10820 Lisp_Object window
;
10821 struct text_pos startp
;
10823 struct window
*w
= XWINDOW (window
);
10824 SET_MARKER_FROM_TEXT_POS (w
->start
, startp
);
10826 if (current_buffer
!= XBUFFER (w
->buffer
))
10829 if (!NILP (Vwindow_scroll_functions
))
10831 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
10832 make_number (CHARPOS (startp
)));
10833 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
10834 /* In case the hook functions switch buffers. */
10835 if (current_buffer
!= XBUFFER (w
->buffer
))
10836 set_buffer_internal_1 (XBUFFER (w
->buffer
));
10843 /* Make sure the line containing the cursor is fully visible.
10844 A value of 1 means there is nothing to be done.
10845 (Either the line is fully visible, or it cannot be made so,
10846 or we cannot tell.)
10848 If FORCE_P is non-zero, return 0 even if partial visible cursor row
10849 is higher than window.
10851 A value of 0 means the caller should do scrolling
10852 as if point had gone off the screen. */
10855 make_cursor_line_fully_visible (w
, force_p
)
10859 struct glyph_matrix
*matrix
;
10860 struct glyph_row
*row
;
10863 /* It's not always possible to find the cursor, e.g, when a window
10864 is full of overlay strings. Don't do anything in that case. */
10865 if (w
->cursor
.vpos
< 0)
10868 matrix
= w
->desired_matrix
;
10869 row
= MATRIX_ROW (matrix
, w
->cursor
.vpos
);
10871 /* If the cursor row is not partially visible, there's nothing to do. */
10872 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (row
))
10875 /* If the row the cursor is in is taller than the window's height,
10876 it's not clear what to do, so do nothing. */
10877 window_height
= window_box_height (w
);
10878 if (row
->height
>= window_height
)
10880 if (!force_p
|| w
->vscroll
)
10886 /* This code used to try to scroll the window just enough to make
10887 the line visible. It returned 0 to say that the caller should
10888 allocate larger glyph matrices. */
10890 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w
, row
))
10892 int dy
= row
->height
- row
->visible_height
;
10895 shift_glyph_matrix (w
, matrix
, 0, matrix
->nrows
, dy
);
10897 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
10899 int dy
= - (row
->height
- row
->visible_height
);
10902 shift_glyph_matrix (w
, matrix
, 0, matrix
->nrows
, dy
);
10905 /* When we change the cursor y-position of the selected window,
10906 change this_line_y as well so that the display optimization for
10907 the cursor line of the selected window in redisplay_internal uses
10908 the correct y-position. */
10909 if (w
== XWINDOW (selected_window
))
10910 this_line_y
= w
->cursor
.y
;
10912 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
10913 redisplay with larger matrices. */
10914 if (matrix
->nrows
< required_matrix_height (w
))
10916 fonts_changed_p
= 1;
10925 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
10926 non-zero means only WINDOW is redisplayed in redisplay_internal.
10927 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
10928 in redisplay_window to bring a partially visible line into view in
10929 the case that only the cursor has moved.
10931 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
10932 last screen line's vertical height extends past the end of the screen.
10936 1 if scrolling succeeded
10938 0 if scrolling didn't find point.
10940 -1 if new fonts have been loaded so that we must interrupt
10941 redisplay, adjust glyph matrices, and try again. */
10947 SCROLLING_NEED_LARGER_MATRICES
10951 try_scrolling (window
, just_this_one_p
, scroll_conservatively
,
10952 scroll_step
, temp_scroll_step
, last_line_misfit
)
10953 Lisp_Object window
;
10954 int just_this_one_p
;
10955 EMACS_INT scroll_conservatively
, scroll_step
;
10956 int temp_scroll_step
;
10957 int last_line_misfit
;
10959 struct window
*w
= XWINDOW (window
);
10960 struct frame
*f
= XFRAME (w
->frame
);
10961 struct text_pos scroll_margin_pos
;
10962 struct text_pos pos
;
10963 struct text_pos startp
;
10965 Lisp_Object window_end
;
10966 int this_scroll_margin
;
10970 int amount_to_scroll
= 0;
10971 Lisp_Object aggressive
;
10973 int extra_scroll_margin_lines
= last_line_misfit
? 1 : 0;
10976 debug_method_add (w
, "try_scrolling");
10979 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
10981 /* Compute scroll margin height in pixels. We scroll when point is
10982 within this distance from the top or bottom of the window. */
10983 if (scroll_margin
> 0)
10985 this_scroll_margin
= min (scroll_margin
, WINDOW_TOTAL_LINES (w
) / 4);
10986 this_scroll_margin
*= FRAME_LINE_HEIGHT (f
);
10989 this_scroll_margin
= 0;
10991 /* Force scroll_conservatively to have a reasonable value so it doesn't
10992 cause an overflow while computing how much to scroll. */
10993 if (scroll_conservatively
)
10994 scroll_conservatively
= min (scroll_conservatively
,
10995 MOST_POSITIVE_FIXNUM
/ FRAME_LINE_HEIGHT (f
));
10997 /* Compute how much we should try to scroll maximally to bring point
10999 if (scroll_step
|| scroll_conservatively
|| temp_scroll_step
)
11000 scroll_max
= max (scroll_step
,
11001 max (scroll_conservatively
, temp_scroll_step
));
11002 else if (NUMBERP (current_buffer
->scroll_down_aggressively
)
11003 || NUMBERP (current_buffer
->scroll_up_aggressively
))
11004 /* We're trying to scroll because of aggressive scrolling
11005 but no scroll_step is set. Choose an arbitrary one. Maybe
11006 there should be a variable for this. */
11010 scroll_max
*= FRAME_LINE_HEIGHT (f
);
11012 /* Decide whether we have to scroll down. Start at the window end
11013 and move this_scroll_margin up to find the position of the scroll
11015 window_end
= Fwindow_end (window
, Qt
);
11019 CHARPOS (scroll_margin_pos
) = XINT (window_end
);
11020 BYTEPOS (scroll_margin_pos
) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos
));
11022 if (this_scroll_margin
|| extra_scroll_margin_lines
)
11024 start_display (&it
, w
, scroll_margin_pos
);
11025 if (this_scroll_margin
)
11026 move_it_vertically (&it
, - this_scroll_margin
);
11027 if (extra_scroll_margin_lines
)
11028 move_it_by_lines (&it
, - extra_scroll_margin_lines
, 0);
11029 scroll_margin_pos
= it
.current
.pos
;
11032 if (PT
>= CHARPOS (scroll_margin_pos
))
11036 /* Point is in the scroll margin at the bottom of the window, or
11037 below. Compute a new window start that makes point visible. */
11039 /* Compute the distance from the scroll margin to PT.
11040 Give up if the distance is greater than scroll_max. */
11041 start_display (&it
, w
, scroll_margin_pos
);
11043 move_it_to (&it
, PT
, 0, it
.last_visible_y
, -1,
11044 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
11046 /* To make point visible, we have to move the window start
11047 down so that the line the cursor is in is visible, which
11048 means we have to add in the height of the cursor line. */
11049 dy
= line_bottom_y (&it
) - y0
;
11051 if (dy
> scroll_max
)
11052 return SCROLLING_FAILED
;
11054 /* Move the window start down. If scrolling conservatively,
11055 move it just enough down to make point visible. If
11056 scroll_step is set, move it down by scroll_step. */
11057 start_display (&it
, w
, startp
);
11059 if (scroll_conservatively
)
11060 /* Set AMOUNT_TO_SCROLL to at least one line,
11061 and at most scroll_conservatively lines. */
11063 = min (max (dy
, FRAME_LINE_HEIGHT (f
)),
11064 FRAME_LINE_HEIGHT (f
) * scroll_conservatively
);
11065 else if (scroll_step
|| temp_scroll_step
)
11066 amount_to_scroll
= scroll_max
;
11069 aggressive
= current_buffer
->scroll_up_aggressively
;
11070 height
= WINDOW_BOX_TEXT_HEIGHT (w
);
11071 if (NUMBERP (aggressive
))
11073 double float_amount
= XFLOATINT (aggressive
) * height
;
11074 amount_to_scroll
= float_amount
;
11075 if (amount_to_scroll
== 0 && float_amount
> 0)
11076 amount_to_scroll
= 1;
11080 if (amount_to_scroll
<= 0)
11081 return SCROLLING_FAILED
;
11083 /* If moving by amount_to_scroll leaves STARTP unchanged,
11084 move it down one screen line. */
11086 move_it_vertically (&it
, amount_to_scroll
);
11087 if (CHARPOS (it
.current
.pos
) == CHARPOS (startp
))
11088 move_it_by_lines (&it
, 1, 1);
11089 startp
= it
.current
.pos
;
11093 /* See if point is inside the scroll margin at the top of the
11095 scroll_margin_pos
= startp
;
11096 if (this_scroll_margin
)
11098 start_display (&it
, w
, startp
);
11099 move_it_vertically (&it
, this_scroll_margin
);
11100 scroll_margin_pos
= it
.current
.pos
;
11103 if (PT
< CHARPOS (scroll_margin_pos
))
11105 /* Point is in the scroll margin at the top of the window or
11106 above what is displayed in the window. */
11109 /* Compute the vertical distance from PT to the scroll
11110 margin position. Give up if distance is greater than
11112 SET_TEXT_POS (pos
, PT
, PT_BYTE
);
11113 start_display (&it
, w
, pos
);
11115 move_it_to (&it
, CHARPOS (scroll_margin_pos
), 0,
11116 it
.last_visible_y
, -1,
11117 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
11118 dy
= it
.current_y
- y0
;
11119 if (dy
> scroll_max
)
11120 return SCROLLING_FAILED
;
11122 /* Compute new window start. */
11123 start_display (&it
, w
, startp
);
11125 if (scroll_conservatively
)
11127 = max (dy
, FRAME_LINE_HEIGHT (f
) * max (scroll_step
, temp_scroll_step
));
11128 else if (scroll_step
|| temp_scroll_step
)
11129 amount_to_scroll
= scroll_max
;
11132 aggressive
= current_buffer
->scroll_down_aggressively
;
11133 height
= WINDOW_BOX_TEXT_HEIGHT (w
);
11134 if (NUMBERP (aggressive
))
11136 double float_amount
= XFLOATINT (aggressive
) * height
;
11137 amount_to_scroll
= float_amount
;
11138 if (amount_to_scroll
== 0 && float_amount
> 0)
11139 amount_to_scroll
= 1;
11143 if (amount_to_scroll
<= 0)
11144 return SCROLLING_FAILED
;
11146 move_it_vertically (&it
, - amount_to_scroll
);
11147 startp
= it
.current
.pos
;
11151 /* Run window scroll functions. */
11152 startp
= run_window_scroll_functions (window
, startp
);
11154 /* Display the window. Give up if new fonts are loaded, or if point
11156 if (!try_window (window
, startp
))
11157 rc
= SCROLLING_NEED_LARGER_MATRICES
;
11158 else if (w
->cursor
.vpos
< 0)
11160 clear_glyph_matrix (w
->desired_matrix
);
11161 rc
= SCROLLING_FAILED
;
11165 /* Maybe forget recorded base line for line number display. */
11166 if (!just_this_one_p
11167 || current_buffer
->clip_changed
11168 || BEG_UNCHANGED
< CHARPOS (startp
))
11169 w
->base_line_number
= Qnil
;
11171 /* If cursor ends up on a partially visible line,
11172 treat that as being off the bottom of the screen. */
11173 if (! make_cursor_line_fully_visible (w
, extra_scroll_margin_lines
<= 1))
11175 clear_glyph_matrix (w
->desired_matrix
);
11176 ++extra_scroll_margin_lines
;
11179 rc
= SCROLLING_SUCCESS
;
11186 /* Compute a suitable window start for window W if display of W starts
11187 on a continuation line. Value is non-zero if a new window start
11190 The new window start will be computed, based on W's width, starting
11191 from the start of the continued line. It is the start of the
11192 screen line with the minimum distance from the old start W->start. */
11195 compute_window_start_on_continuation_line (w
)
11198 struct text_pos pos
, start_pos
;
11199 int window_start_changed_p
= 0;
11201 SET_TEXT_POS_FROM_MARKER (start_pos
, w
->start
);
11203 /* If window start is on a continuation line... Window start may be
11204 < BEGV in case there's invisible text at the start of the
11205 buffer (M-x rmail, for example). */
11206 if (CHARPOS (start_pos
) > BEGV
11207 && FETCH_BYTE (BYTEPOS (start_pos
) - 1) != '\n')
11210 struct glyph_row
*row
;
11212 /* Handle the case that the window start is out of range. */
11213 if (CHARPOS (start_pos
) < BEGV
)
11214 SET_TEXT_POS (start_pos
, BEGV
, BEGV_BYTE
);
11215 else if (CHARPOS (start_pos
) > ZV
)
11216 SET_TEXT_POS (start_pos
, ZV
, ZV_BYTE
);
11218 /* Find the start of the continued line. This should be fast
11219 because scan_buffer is fast (newline cache). */
11220 row
= w
->desired_matrix
->rows
+ (WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0);
11221 init_iterator (&it
, w
, CHARPOS (start_pos
), BYTEPOS (start_pos
),
11222 row
, DEFAULT_FACE_ID
);
11223 reseat_at_previous_visible_line_start (&it
);
11225 /* If the line start is "too far" away from the window start,
11226 say it takes too much time to compute a new window start. */
11227 if (CHARPOS (start_pos
) - IT_CHARPOS (it
)
11228 < WINDOW_TOTAL_LINES (w
) * WINDOW_TOTAL_COLS (w
))
11230 int min_distance
, distance
;
11232 /* Move forward by display lines to find the new window
11233 start. If window width was enlarged, the new start can
11234 be expected to be > the old start. If window width was
11235 decreased, the new window start will be < the old start.
11236 So, we're looking for the display line start with the
11237 minimum distance from the old window start. */
11238 pos
= it
.current
.pos
;
11239 min_distance
= INFINITY
;
11240 while ((distance
= abs (CHARPOS (start_pos
) - IT_CHARPOS (it
))),
11241 distance
< min_distance
)
11243 min_distance
= distance
;
11244 pos
= it
.current
.pos
;
11245 move_it_by_lines (&it
, 1, 0);
11248 /* Set the window start there. */
11249 SET_MARKER_FROM_TEXT_POS (w
->start
, pos
);
11250 window_start_changed_p
= 1;
11254 return window_start_changed_p
;
11258 /* Try cursor movement in case text has not changed in window WINDOW,
11259 with window start STARTP. Value is
11261 CURSOR_MOVEMENT_SUCCESS if successful
11263 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
11265 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
11266 display. *SCROLL_STEP is set to 1, under certain circumstances, if
11267 we want to scroll as if scroll-step were set to 1. See the code.
11269 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
11270 which case we have to abort this redisplay, and adjust matrices
11275 CURSOR_MOVEMENT_SUCCESS
,
11276 CURSOR_MOVEMENT_CANNOT_BE_USED
,
11277 CURSOR_MOVEMENT_MUST_SCROLL
,
11278 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
11282 try_cursor_movement (window
, startp
, scroll_step
)
11283 Lisp_Object window
;
11284 struct text_pos startp
;
11287 struct window
*w
= XWINDOW (window
);
11288 struct frame
*f
= XFRAME (w
->frame
);
11289 int rc
= CURSOR_MOVEMENT_CANNOT_BE_USED
;
11292 if (inhibit_try_cursor_movement
)
11296 /* Handle case where text has not changed, only point, and it has
11297 not moved off the frame. */
11298 if (/* Point may be in this window. */
11299 PT
>= CHARPOS (startp
)
11300 /* Selective display hasn't changed. */
11301 && !current_buffer
->clip_changed
11302 /* Function force-mode-line-update is used to force a thorough
11303 redisplay. It sets either windows_or_buffers_changed or
11304 update_mode_lines. So don't take a shortcut here for these
11306 && !update_mode_lines
11307 && !windows_or_buffers_changed
11308 && !cursor_type_changed
11309 /* Can't use this case if highlighting a region. When a
11310 region exists, cursor movement has to do more than just
11312 && !(!NILP (Vtransient_mark_mode
)
11313 && !NILP (current_buffer
->mark_active
))
11314 && NILP (w
->region_showing
)
11315 && NILP (Vshow_trailing_whitespace
)
11316 /* Right after splitting windows, last_point may be nil. */
11317 && INTEGERP (w
->last_point
)
11318 /* This code is not used for mini-buffer for the sake of the case
11319 of redisplaying to replace an echo area message; since in
11320 that case the mini-buffer contents per se are usually
11321 unchanged. This code is of no real use in the mini-buffer
11322 since the handling of this_line_start_pos, etc., in redisplay
11323 handles the same cases. */
11324 && !EQ (window
, minibuf_window
)
11325 /* When splitting windows or for new windows, it happens that
11326 redisplay is called with a nil window_end_vpos or one being
11327 larger than the window. This should really be fixed in
11328 window.c. I don't have this on my list, now, so we do
11329 approximately the same as the old redisplay code. --gerd. */
11330 && INTEGERP (w
->window_end_vpos
)
11331 && XFASTINT (w
->window_end_vpos
) < w
->current_matrix
->nrows
11332 && (FRAME_WINDOW_P (f
)
11333 || !overlay_arrow_in_current_buffer_p ()))
11335 int this_scroll_margin
, top_scroll_margin
;
11336 struct glyph_row
*row
= NULL
;
11339 debug_method_add (w
, "cursor movement");
11342 /* Scroll if point within this distance from the top or bottom
11343 of the window. This is a pixel value. */
11344 this_scroll_margin
= max (0, scroll_margin
);
11345 this_scroll_margin
= min (this_scroll_margin
, WINDOW_TOTAL_LINES (w
) / 4);
11346 this_scroll_margin
*= FRAME_LINE_HEIGHT (f
);
11348 top_scroll_margin
= this_scroll_margin
;
11349 if (WINDOW_WANTS_HEADER_LINE_P (w
))
11350 top_scroll_margin
+= CURRENT_HEADER_LINE_HEIGHT (w
);
11352 /* Start with the row the cursor was displayed during the last
11353 not paused redisplay. Give up if that row is not valid. */
11354 if (w
->last_cursor
.vpos
< 0
11355 || w
->last_cursor
.vpos
>= w
->current_matrix
->nrows
)
11356 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11359 row
= MATRIX_ROW (w
->current_matrix
, w
->last_cursor
.vpos
);
11360 if (row
->mode_line_p
)
11362 if (!row
->enabled_p
)
11363 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11366 if (rc
== CURSOR_MOVEMENT_CANNOT_BE_USED
)
11369 int last_y
= window_text_bottom_y (w
) - this_scroll_margin
;
11371 if (PT
> XFASTINT (w
->last_point
))
11373 /* Point has moved forward. */
11374 while (MATRIX_ROW_END_CHARPOS (row
) < PT
11375 && MATRIX_ROW_BOTTOM_Y (row
) < last_y
)
11377 xassert (row
->enabled_p
);
11381 /* The end position of a row equals the start position
11382 of the next row. If PT is there, we would rather
11383 display it in the next line. */
11384 while (MATRIX_ROW_BOTTOM_Y (row
) < last_y
11385 && MATRIX_ROW_END_CHARPOS (row
) == PT
11386 && !cursor_row_p (w
, row
))
11389 /* If within the scroll margin, scroll. Note that
11390 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
11391 the next line would be drawn, and that
11392 this_scroll_margin can be zero. */
11393 if (MATRIX_ROW_BOTTOM_Y (row
) > last_y
11394 || PT
> MATRIX_ROW_END_CHARPOS (row
)
11395 /* Line is completely visible last line in window
11396 and PT is to be set in the next line. */
11397 || (MATRIX_ROW_BOTTOM_Y (row
) == last_y
11398 && PT
== MATRIX_ROW_END_CHARPOS (row
)
11399 && !row
->ends_at_zv_p
11400 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
)))
11403 else if (PT
< XFASTINT (w
->last_point
))
11405 /* Cursor has to be moved backward. Note that PT >=
11406 CHARPOS (startp) because of the outer if-statement. */
11407 while (!row
->mode_line_p
11408 && (MATRIX_ROW_START_CHARPOS (row
) > PT
11409 || (MATRIX_ROW_START_CHARPOS (row
) == PT
11410 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row
)))
11411 && (row
->y
> top_scroll_margin
11412 || CHARPOS (startp
) == BEGV
))
11414 xassert (row
->enabled_p
);
11418 /* Consider the following case: Window starts at BEGV,
11419 there is invisible, intangible text at BEGV, so that
11420 display starts at some point START > BEGV. It can
11421 happen that we are called with PT somewhere between
11422 BEGV and START. Try to handle that case. */
11423 if (row
< w
->current_matrix
->rows
11424 || row
->mode_line_p
)
11426 row
= w
->current_matrix
->rows
;
11427 if (row
->mode_line_p
)
11431 /* Due to newlines in overlay strings, we may have to
11432 skip forward over overlay strings. */
11433 while (MATRIX_ROW_BOTTOM_Y (row
) < last_y
11434 && MATRIX_ROW_END_CHARPOS (row
) == PT
11435 && !cursor_row_p (w
, row
))
11438 /* If within the scroll margin, scroll. */
11439 if (row
->y
< top_scroll_margin
11440 && CHARPOS (startp
) != BEGV
)
11444 if (PT
< MATRIX_ROW_START_CHARPOS (row
)
11445 || PT
> MATRIX_ROW_END_CHARPOS (row
))
11447 /* if PT is not in the glyph row, give up. */
11448 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11450 else if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row
))
11452 if (PT
== MATRIX_ROW_END_CHARPOS (row
)
11453 && !row
->ends_at_zv_p
11454 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
))
11455 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11456 else if (row
->height
> window_box_height (w
))
11458 /* If we end up in a partially visible line, let's
11459 make it fully visible, except when it's taller
11460 than the window, in which case we can't do much
11463 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11467 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
11468 if (!make_cursor_line_fully_visible (w
, 0))
11469 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11471 rc
= CURSOR_MOVEMENT_SUCCESS
;
11475 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11478 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
11479 rc
= CURSOR_MOVEMENT_SUCCESS
;
11488 set_vertical_scroll_bar (w
)
11491 int start
, end
, whole
;
11493 /* Calculate the start and end positions for the current window.
11494 At some point, it would be nice to choose between scrollbars
11495 which reflect the whole buffer size, with special markers
11496 indicating narrowing, and scrollbars which reflect only the
11499 Note that mini-buffers sometimes aren't displaying any text. */
11500 if (!MINI_WINDOW_P (w
)
11501 || (w
== XWINDOW (minibuf_window
)
11502 && NILP (echo_area_buffer
[0])))
11504 struct buffer
*buf
= XBUFFER (w
->buffer
);
11505 whole
= BUF_ZV (buf
) - BUF_BEGV (buf
);
11506 start
= marker_position (w
->start
) - BUF_BEGV (buf
);
11507 /* I don't think this is guaranteed to be right. For the
11508 moment, we'll pretend it is. */
11509 end
= BUF_Z (buf
) - XFASTINT (w
->window_end_pos
) - BUF_BEGV (buf
);
11513 if (whole
< (end
- start
))
11514 whole
= end
- start
;
11517 start
= end
= whole
= 0;
11519 /* Indicate what this scroll bar ought to be displaying now. */
11520 set_vertical_scroll_bar_hook (w
, end
- start
, whole
, start
);
11524 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
11525 selected_window is redisplayed.
11527 We can return without actually redisplaying the window if
11528 fonts_changed_p is nonzero. In that case, redisplay_internal will
11532 redisplay_window (window
, just_this_one_p
)
11533 Lisp_Object window
;
11534 int just_this_one_p
;
11536 struct window
*w
= XWINDOW (window
);
11537 struct frame
*f
= XFRAME (w
->frame
);
11538 struct buffer
*buffer
= XBUFFER (w
->buffer
);
11539 struct buffer
*old
= current_buffer
;
11540 struct text_pos lpoint
, opoint
, startp
;
11541 int update_mode_line
;
11544 /* Record it now because it's overwritten. */
11545 int current_matrix_up_to_date_p
= 0;
11546 int used_current_matrix_p
= 0;
11547 /* This is less strict than current_matrix_up_to_date_p.
11548 It indictes that the buffer contents and narrowing are unchanged. */
11549 int buffer_unchanged_p
= 0;
11550 int temp_scroll_step
= 0;
11551 int count
= SPECPDL_INDEX ();
11553 int centering_position
;
11554 int last_line_misfit
= 0;
11556 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
11559 /* W must be a leaf window here. */
11560 xassert (!NILP (w
->buffer
));
11562 *w
->desired_matrix
->method
= 0;
11565 specbind (Qinhibit_point_motion_hooks
, Qt
);
11567 reconsider_clip_changes (w
, buffer
);
11569 /* Has the mode line to be updated? */
11570 update_mode_line
= (!NILP (w
->update_mode_line
)
11571 || update_mode_lines
11572 || buffer
->clip_changed
11573 || buffer
->prevent_redisplay_optimizations_p
);
11575 if (MINI_WINDOW_P (w
))
11577 if (w
== XWINDOW (echo_area_window
)
11578 && !NILP (echo_area_buffer
[0]))
11580 if (update_mode_line
)
11581 /* We may have to update a tty frame's menu bar or a
11582 tool-bar. Example `M-x C-h C-h C-g'. */
11583 goto finish_menu_bars
;
11585 /* We've already displayed the echo area glyphs in this window. */
11586 goto finish_scroll_bars
;
11588 else if ((w
!= XWINDOW (minibuf_window
)
11589 || minibuf_level
== 0)
11590 /* When buffer is nonempty, redisplay window normally. */
11591 && BUF_Z (XBUFFER (w
->buffer
)) == BUF_BEG (XBUFFER (w
->buffer
))
11592 /* Quail displays non-mini buffers in minibuffer window.
11593 In that case, redisplay the window normally. */
11594 && !NILP (Fmemq (w
->buffer
, Vminibuffer_list
)))
11596 /* W is a mini-buffer window, but it's not active, so clear
11598 int yb
= window_text_bottom_y (w
);
11599 struct glyph_row
*row
;
11602 for (y
= 0, row
= w
->desired_matrix
->rows
;
11604 y
+= row
->height
, ++row
)
11605 blank_row (w
, row
, y
);
11606 goto finish_scroll_bars
;
11609 clear_glyph_matrix (w
->desired_matrix
);
11612 /* Otherwise set up data on this window; select its buffer and point
11614 /* Really select the buffer, for the sake of buffer-local
11616 set_buffer_internal_1 (XBUFFER (w
->buffer
));
11617 SET_TEXT_POS (opoint
, PT
, PT_BYTE
);
11619 current_matrix_up_to_date_p
11620 = (!NILP (w
->window_end_valid
)
11621 && !current_buffer
->clip_changed
11622 && !current_buffer
->prevent_redisplay_optimizations_p
11623 && XFASTINT (w
->last_modified
) >= MODIFF
11624 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
);
11627 = (!NILP (w
->window_end_valid
)
11628 && !current_buffer
->clip_changed
11629 && XFASTINT (w
->last_modified
) >= MODIFF
11630 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
);
11632 /* When windows_or_buffers_changed is non-zero, we can't rely on
11633 the window end being valid, so set it to nil there. */
11634 if (windows_or_buffers_changed
)
11636 /* If window starts on a continuation line, maybe adjust the
11637 window start in case the window's width changed. */
11638 if (XMARKER (w
->start
)->buffer
== current_buffer
)
11639 compute_window_start_on_continuation_line (w
);
11641 w
->window_end_valid
= Qnil
;
11644 /* Some sanity checks. */
11645 CHECK_WINDOW_END (w
);
11646 if (Z
== Z_BYTE
&& CHARPOS (opoint
) != BYTEPOS (opoint
))
11648 if (BYTEPOS (opoint
) < CHARPOS (opoint
))
11651 /* If %c is in mode line, update it if needed. */
11652 if (!NILP (w
->column_number_displayed
)
11653 /* This alternative quickly identifies a common case
11654 where no change is needed. */
11655 && !(PT
== XFASTINT (w
->last_point
)
11656 && XFASTINT (w
->last_modified
) >= MODIFF
11657 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
)
11658 && (XFASTINT (w
->column_number_displayed
)
11659 != (int) current_column ())) /* iftc */
11660 update_mode_line
= 1;
11662 /* Count number of windows showing the selected buffer. An indirect
11663 buffer counts as its base buffer. */
11664 if (!just_this_one_p
)
11666 struct buffer
*current_base
, *window_base
;
11667 current_base
= current_buffer
;
11668 window_base
= XBUFFER (XWINDOW (selected_window
)->buffer
);
11669 if (current_base
->base_buffer
)
11670 current_base
= current_base
->base_buffer
;
11671 if (window_base
->base_buffer
)
11672 window_base
= window_base
->base_buffer
;
11673 if (current_base
== window_base
)
11677 /* Point refers normally to the selected window. For any other
11678 window, set up appropriate value. */
11679 if (!EQ (window
, selected_window
))
11681 int new_pt
= XMARKER (w
->pointm
)->charpos
;
11682 int new_pt_byte
= marker_byte_position (w
->pointm
);
11686 new_pt_byte
= BEGV_BYTE
;
11687 set_marker_both (w
->pointm
, Qnil
, BEGV
, BEGV_BYTE
);
11689 else if (new_pt
> (ZV
- 1))
11692 new_pt_byte
= ZV_BYTE
;
11693 set_marker_both (w
->pointm
, Qnil
, ZV
, ZV_BYTE
);
11696 /* We don't use SET_PT so that the point-motion hooks don't run. */
11697 TEMP_SET_PT_BOTH (new_pt
, new_pt_byte
);
11700 /* If any of the character widths specified in the display table
11701 have changed, invalidate the width run cache. It's true that
11702 this may be a bit late to catch such changes, but the rest of
11703 redisplay goes (non-fatally) haywire when the display table is
11704 changed, so why should we worry about doing any better? */
11705 if (current_buffer
->width_run_cache
)
11707 struct Lisp_Char_Table
*disptab
= buffer_display_table ();
11709 if (! disptab_matches_widthtab (disptab
,
11710 XVECTOR (current_buffer
->width_table
)))
11712 invalidate_region_cache (current_buffer
,
11713 current_buffer
->width_run_cache
,
11715 recompute_width_table (current_buffer
, disptab
);
11719 /* If window-start is screwed up, choose a new one. */
11720 if (XMARKER (w
->start
)->buffer
!= current_buffer
)
11723 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
11725 /* If someone specified a new starting point but did not insist,
11726 check whether it can be used. */
11727 if (!NILP (w
->optional_new_start
)
11728 && CHARPOS (startp
) >= BEGV
11729 && CHARPOS (startp
) <= ZV
)
11731 w
->optional_new_start
= Qnil
;
11732 start_display (&it
, w
, startp
);
11733 move_it_to (&it
, PT
, 0, it
.last_visible_y
, -1,
11734 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
11735 if (IT_CHARPOS (it
) == PT
)
11736 w
->force_start
= Qt
;
11737 /* IT may overshoot PT if text at PT is invisible. */
11738 else if (IT_CHARPOS (it
) > PT
&& CHARPOS (startp
) <= PT
)
11739 w
->force_start
= Qt
;
11744 /* Handle case where place to start displaying has been specified,
11745 unless the specified location is outside the accessible range. */
11746 if (!NILP (w
->force_start
)
11747 || w
->frozen_window_start_p
)
11749 /* We set this later on if we have to adjust point. */
11752 w
->force_start
= Qnil
;
11754 w
->window_end_valid
= Qnil
;
11756 /* Forget any recorded base line for line number display. */
11757 if (!buffer_unchanged_p
)
11758 w
->base_line_number
= Qnil
;
11760 /* Redisplay the mode line. Select the buffer properly for that.
11761 Also, run the hook window-scroll-functions
11762 because we have scrolled. */
11763 /* Note, we do this after clearing force_start because
11764 if there's an error, it is better to forget about force_start
11765 than to get into an infinite loop calling the hook functions
11766 and having them get more errors. */
11767 if (!update_mode_line
11768 || ! NILP (Vwindow_scroll_functions
))
11770 update_mode_line
= 1;
11771 w
->update_mode_line
= Qt
;
11772 startp
= run_window_scroll_functions (window
, startp
);
11775 w
->last_modified
= make_number (0);
11776 w
->last_overlay_modified
= make_number (0);
11777 if (CHARPOS (startp
) < BEGV
)
11778 SET_TEXT_POS (startp
, BEGV
, BEGV_BYTE
);
11779 else if (CHARPOS (startp
) > ZV
)
11780 SET_TEXT_POS (startp
, ZV
, ZV_BYTE
);
11782 /* Redisplay, then check if cursor has been set during the
11783 redisplay. Give up if new fonts were loaded. */
11784 if (!try_window (window
, startp
))
11786 w
->force_start
= Qt
;
11787 clear_glyph_matrix (w
->desired_matrix
);
11788 goto need_larger_matrices
;
11791 if (w
->cursor
.vpos
< 0 && !w
->frozen_window_start_p
)
11793 /* If point does not appear, try to move point so it does
11794 appear. The desired matrix has been built above, so we
11795 can use it here. */
11796 new_vpos
= window_box_height (w
) / 2;
11799 if (!make_cursor_line_fully_visible (w
, 0))
11801 /* Point does appear, but on a line partly visible at end of window.
11802 Move it back to a fully-visible line. */
11803 new_vpos
= window_box_height (w
);
11806 /* If we need to move point for either of the above reasons,
11807 now actually do it. */
11810 struct glyph_row
*row
;
11812 row
= MATRIX_FIRST_TEXT_ROW (w
->desired_matrix
);
11813 while (MATRIX_ROW_BOTTOM_Y (row
) < new_vpos
)
11816 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row
),
11817 MATRIX_ROW_START_BYTEPOS (row
));
11819 if (w
!= XWINDOW (selected_window
))
11820 set_marker_both (w
->pointm
, Qnil
, PT
, PT_BYTE
);
11821 else if (current_buffer
== old
)
11822 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
11824 set_cursor_from_row (w
, row
, w
->desired_matrix
, 0, 0, 0, 0);
11826 /* If we are highlighting the region, then we just changed
11827 the region, so redisplay to show it. */
11828 if (!NILP (Vtransient_mark_mode
)
11829 && !NILP (current_buffer
->mark_active
))
11831 clear_glyph_matrix (w
->desired_matrix
);
11832 if (!try_window (window
, startp
))
11833 goto need_larger_matrices
;
11838 debug_method_add (w
, "forced window start");
11843 /* Handle case where text has not changed, only point, and it has
11844 not moved off the frame, and we are not retrying after hscroll.
11845 (current_matrix_up_to_date_p is nonzero when retrying.) */
11846 if (current_matrix_up_to_date_p
11847 && (rc
= try_cursor_movement (window
, startp
, &temp_scroll_step
),
11848 rc
!= CURSOR_MOVEMENT_CANNOT_BE_USED
))
11852 case CURSOR_MOVEMENT_SUCCESS
:
11853 used_current_matrix_p
= 1;
11856 #if 0 /* try_cursor_movement never returns this value. */
11857 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES
:
11858 goto need_larger_matrices
;
11861 case CURSOR_MOVEMENT_MUST_SCROLL
:
11862 goto try_to_scroll
;
11868 /* If current starting point was originally the beginning of a line
11869 but no longer is, find a new starting point. */
11870 else if (!NILP (w
->start_at_line_beg
)
11871 && !(CHARPOS (startp
) <= BEGV
11872 || FETCH_BYTE (BYTEPOS (startp
) - 1) == '\n'))
11875 debug_method_add (w
, "recenter 1");
11880 /* Try scrolling with try_window_id. Value is > 0 if update has
11881 been done, it is -1 if we know that the same window start will
11882 not work. It is 0 if unsuccessful for some other reason. */
11883 else if ((tem
= try_window_id (w
)) != 0)
11886 debug_method_add (w
, "try_window_id %d", tem
);
11889 if (fonts_changed_p
)
11890 goto need_larger_matrices
;
11894 /* Otherwise try_window_id has returned -1 which means that we
11895 don't want the alternative below this comment to execute. */
11897 else if (CHARPOS (startp
) >= BEGV
11898 && CHARPOS (startp
) <= ZV
11899 && PT
>= CHARPOS (startp
)
11900 && (CHARPOS (startp
) < ZV
11901 /* Avoid starting at end of buffer. */
11902 || CHARPOS (startp
) == BEGV
11903 || (XFASTINT (w
->last_modified
) >= MODIFF
11904 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
)))
11907 debug_method_add (w
, "same window start");
11910 /* Try to redisplay starting at same place as before.
11911 If point has not moved off frame, accept the results. */
11912 if (!current_matrix_up_to_date_p
11913 /* Don't use try_window_reusing_current_matrix in this case
11914 because a window scroll function can have changed the
11916 || !NILP (Vwindow_scroll_functions
)
11917 || MINI_WINDOW_P (w
)
11918 || !(used_current_matrix_p
11919 = try_window_reusing_current_matrix (w
)))
11921 IF_DEBUG (debug_method_add (w
, "1"));
11922 try_window (window
, startp
);
11925 if (fonts_changed_p
)
11926 goto need_larger_matrices
;
11928 if (w
->cursor
.vpos
>= 0)
11930 if (!just_this_one_p
11931 || current_buffer
->clip_changed
11932 || BEG_UNCHANGED
< CHARPOS (startp
))
11933 /* Forget any recorded base line for line number display. */
11934 w
->base_line_number
= Qnil
;
11936 if (!make_cursor_line_fully_visible (w
, 1))
11938 clear_glyph_matrix (w
->desired_matrix
);
11939 last_line_misfit
= 1;
11941 /* Drop through and scroll. */
11946 clear_glyph_matrix (w
->desired_matrix
);
11951 w
->last_modified
= make_number (0);
11952 w
->last_overlay_modified
= make_number (0);
11954 /* Redisplay the mode line. Select the buffer properly for that. */
11955 if (!update_mode_line
)
11957 update_mode_line
= 1;
11958 w
->update_mode_line
= Qt
;
11961 /* Try to scroll by specified few lines. */
11962 if ((scroll_conservatively
11964 || temp_scroll_step
11965 || NUMBERP (current_buffer
->scroll_up_aggressively
)
11966 || NUMBERP (current_buffer
->scroll_down_aggressively
))
11967 && !current_buffer
->clip_changed
11968 && CHARPOS (startp
) >= BEGV
11969 && CHARPOS (startp
) <= ZV
)
11971 /* The function returns -1 if new fonts were loaded, 1 if
11972 successful, 0 if not successful. */
11973 int rc
= try_scrolling (window
, just_this_one_p
,
11974 scroll_conservatively
,
11976 temp_scroll_step
, last_line_misfit
);
11979 case SCROLLING_SUCCESS
:
11982 case SCROLLING_NEED_LARGER_MATRICES
:
11983 goto need_larger_matrices
;
11985 case SCROLLING_FAILED
:
11993 /* Finally, just choose place to start which centers point */
11996 centering_position
= window_box_height (w
) / 2;
11999 /* Jump here with centering_position already set to 0. */
12002 debug_method_add (w
, "recenter");
12005 /* w->vscroll = 0; */
12007 /* Forget any previously recorded base line for line number display. */
12008 if (!buffer_unchanged_p
)
12009 w
->base_line_number
= Qnil
;
12011 /* Move backward half the height of the window. */
12012 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
12013 it
.current_y
= it
.last_visible_y
;
12014 move_it_vertically_backward (&it
, centering_position
);
12015 xassert (IT_CHARPOS (it
) >= BEGV
);
12017 /* The function move_it_vertically_backward may move over more
12018 than the specified y-distance. If it->w is small, e.g. a
12019 mini-buffer window, we may end up in front of the window's
12020 display area. Start displaying at the start of the line
12021 containing PT in this case. */
12022 if (it
.current_y
<= 0)
12024 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
12025 move_it_vertically (&it
, 0);
12026 xassert (IT_CHARPOS (it
) <= PT
);
12030 it
.current_x
= it
.hpos
= 0;
12032 /* Set startp here explicitly in case that helps avoid an infinite loop
12033 in case the window-scroll-functions functions get errors. */
12034 set_marker_both (w
->start
, Qnil
, IT_CHARPOS (it
), IT_BYTEPOS (it
));
12036 /* Run scroll hooks. */
12037 startp
= run_window_scroll_functions (window
, it
.current
.pos
);
12039 /* Redisplay the window. */
12040 if (!current_matrix_up_to_date_p
12041 || windows_or_buffers_changed
12042 || cursor_type_changed
12043 /* Don't use try_window_reusing_current_matrix in this case
12044 because it can have changed the buffer. */
12045 || !NILP (Vwindow_scroll_functions
)
12046 || !just_this_one_p
12047 || MINI_WINDOW_P (w
)
12048 || !(used_current_matrix_p
12049 = try_window_reusing_current_matrix (w
)))
12050 try_window (window
, startp
);
12052 /* If new fonts have been loaded (due to fontsets), give up. We
12053 have to start a new redisplay since we need to re-adjust glyph
12055 if (fonts_changed_p
)
12056 goto need_larger_matrices
;
12058 /* If cursor did not appear assume that the middle of the window is
12059 in the first line of the window. Do it again with the next line.
12060 (Imagine a window of height 100, displaying two lines of height
12061 60. Moving back 50 from it->last_visible_y will end in the first
12063 if (w
->cursor
.vpos
< 0)
12065 if (!NILP (w
->window_end_valid
)
12066 && PT
>= Z
- XFASTINT (w
->window_end_pos
))
12068 clear_glyph_matrix (w
->desired_matrix
);
12069 move_it_by_lines (&it
, 1, 0);
12070 try_window (window
, it
.current
.pos
);
12072 else if (PT
< IT_CHARPOS (it
))
12074 clear_glyph_matrix (w
->desired_matrix
);
12075 move_it_by_lines (&it
, -1, 0);
12076 try_window (window
, it
.current
.pos
);
12080 /* Not much we can do about it. */
12084 /* Consider the following case: Window starts at BEGV, there is
12085 invisible, intangible text at BEGV, so that display starts at
12086 some point START > BEGV. It can happen that we are called with
12087 PT somewhere between BEGV and START. Try to handle that case. */
12088 if (w
->cursor
.vpos
< 0)
12090 struct glyph_row
*row
= w
->current_matrix
->rows
;
12091 if (row
->mode_line_p
)
12093 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
12096 if (!make_cursor_line_fully_visible (w
, centering_position
> 0))
12098 /* If vscroll is enabled, disable it and try again. */
12102 clear_glyph_matrix (w
->desired_matrix
);
12106 /* If centering point failed to make the whole line visible,
12107 put point at the top instead. That has to make the whole line
12108 visible, if it can be done. */
12109 clear_glyph_matrix (w
->desired_matrix
);
12110 centering_position
= 0;
12116 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
12117 w
->start_at_line_beg
= ((CHARPOS (startp
) == BEGV
12118 || FETCH_BYTE (BYTEPOS (startp
) - 1) == '\n')
12121 /* Display the mode line, if we must. */
12122 if ((update_mode_line
12123 /* If window not full width, must redo its mode line
12124 if (a) the window to its side is being redone and
12125 (b) we do a frame-based redisplay. This is a consequence
12126 of how inverted lines are drawn in frame-based redisplay. */
12127 || (!just_this_one_p
12128 && !FRAME_WINDOW_P (f
)
12129 && !WINDOW_FULL_WIDTH_P (w
))
12130 /* Line number to display. */
12131 || INTEGERP (w
->base_line_pos
)
12132 /* Column number is displayed and different from the one displayed. */
12133 || (!NILP (w
->column_number_displayed
)
12134 && (XFASTINT (w
->column_number_displayed
)
12135 != (int) current_column ()))) /* iftc */
12136 /* This means that the window has a mode line. */
12137 && (WINDOW_WANTS_MODELINE_P (w
)
12138 || WINDOW_WANTS_HEADER_LINE_P (w
)))
12140 display_mode_lines (w
);
12142 /* If mode line height has changed, arrange for a thorough
12143 immediate redisplay using the correct mode line height. */
12144 if (WINDOW_WANTS_MODELINE_P (w
)
12145 && CURRENT_MODE_LINE_HEIGHT (w
) != DESIRED_MODE_LINE_HEIGHT (w
))
12147 fonts_changed_p
= 1;
12148 MATRIX_MODE_LINE_ROW (w
->current_matrix
)->height
12149 = DESIRED_MODE_LINE_HEIGHT (w
);
12152 /* If top line height has changed, arrange for a thorough
12153 immediate redisplay using the correct mode line height. */
12154 if (WINDOW_WANTS_HEADER_LINE_P (w
)
12155 && CURRENT_HEADER_LINE_HEIGHT (w
) != DESIRED_HEADER_LINE_HEIGHT (w
))
12157 fonts_changed_p
= 1;
12158 MATRIX_HEADER_LINE_ROW (w
->current_matrix
)->height
12159 = DESIRED_HEADER_LINE_HEIGHT (w
);
12162 if (fonts_changed_p
)
12163 goto need_larger_matrices
;
12166 if (!line_number_displayed
12167 && !BUFFERP (w
->base_line_pos
))
12169 w
->base_line_pos
= Qnil
;
12170 w
->base_line_number
= Qnil
;
12175 /* When we reach a frame's selected window, redo the frame's menu bar. */
12176 if (update_mode_line
12177 && EQ (FRAME_SELECTED_WINDOW (f
), window
))
12179 int redisplay_menu_p
= 0;
12180 int redisplay_tool_bar_p
= 0;
12182 if (FRAME_WINDOW_P (f
))
12184 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
12185 || defined (USE_GTK)
12186 redisplay_menu_p
= FRAME_EXTERNAL_MENU_BAR (f
);
12188 redisplay_menu_p
= FRAME_MENU_BAR_LINES (f
) > 0;
12192 redisplay_menu_p
= FRAME_MENU_BAR_LINES (f
) > 0;
12194 if (redisplay_menu_p
)
12195 display_menu_bar (w
);
12197 #ifdef HAVE_WINDOW_SYSTEM
12199 redisplay_tool_bar_p
= FRAME_EXTERNAL_TOOL_BAR (f
);
12201 redisplay_tool_bar_p
= WINDOWP (f
->tool_bar_window
)
12202 && (FRAME_TOOL_BAR_LINES (f
) > 0
12203 || auto_resize_tool_bars_p
);
12207 if (redisplay_tool_bar_p
)
12208 redisplay_tool_bar (f
);
12212 #ifdef HAVE_WINDOW_SYSTEM
12213 if (update_window_fringes (w
, 0)
12214 && !just_this_one_p
12215 && (used_current_matrix_p
|| overlay_arrow_seen
)
12216 && !w
->pseudo_window_p
)
12220 draw_window_fringes (w
);
12224 #endif /* HAVE_WINDOW_SYSTEM */
12226 /* We go to this label, with fonts_changed_p nonzero,
12227 if it is necessary to try again using larger glyph matrices.
12228 We have to redeem the scroll bar even in this case,
12229 because the loop in redisplay_internal expects that. */
12230 need_larger_matrices
:
12232 finish_scroll_bars
:
12234 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w
))
12236 /* Set the thumb's position and size. */
12237 set_vertical_scroll_bar (w
);
12239 /* Note that we actually used the scroll bar attached to this
12240 window, so it shouldn't be deleted at the end of redisplay. */
12241 redeem_scroll_bar_hook (w
);
12244 /* Restore current_buffer and value of point in it. */
12245 TEMP_SET_PT_BOTH (CHARPOS (opoint
), BYTEPOS (opoint
));
12246 set_buffer_internal_1 (old
);
12247 TEMP_SET_PT_BOTH (CHARPOS (lpoint
), BYTEPOS (lpoint
));
12249 unbind_to (count
, Qnil
);
12253 /* Build the complete desired matrix of WINDOW with a window start
12254 buffer position POS. Value is non-zero if successful. It is zero
12255 if fonts were loaded during redisplay which makes re-adjusting
12256 glyph matrices necessary. */
12259 try_window (window
, pos
)
12260 Lisp_Object window
;
12261 struct text_pos pos
;
12263 struct window
*w
= XWINDOW (window
);
12265 struct glyph_row
*last_text_row
= NULL
;
12267 /* Make POS the new window start. */
12268 set_marker_both (w
->start
, Qnil
, CHARPOS (pos
), BYTEPOS (pos
));
12270 /* Mark cursor position as unknown. No overlay arrow seen. */
12271 w
->cursor
.vpos
= -1;
12272 overlay_arrow_seen
= 0;
12274 /* Initialize iterator and info to start at POS. */
12275 start_display (&it
, w
, pos
);
12277 /* Display all lines of W. */
12278 while (it
.current_y
< it
.last_visible_y
)
12280 if (display_line (&it
))
12281 last_text_row
= it
.glyph_row
- 1;
12282 if (fonts_changed_p
)
12286 /* If bottom moved off end of frame, change mode line percentage. */
12287 if (XFASTINT (w
->window_end_pos
) <= 0
12288 && Z
!= IT_CHARPOS (it
))
12289 w
->update_mode_line
= Qt
;
12291 /* Set window_end_pos to the offset of the last character displayed
12292 on the window from the end of current_buffer. Set
12293 window_end_vpos to its row number. */
12296 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row
));
12297 w
->window_end_bytepos
12298 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
12300 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
12302 = make_number (MATRIX_ROW_VPOS (last_text_row
, w
->desired_matrix
));
12303 xassert (MATRIX_ROW (w
->desired_matrix
, XFASTINT (w
->window_end_vpos
))
12304 ->displays_text_p
);
12308 w
->window_end_bytepos
= Z_BYTE
- ZV_BYTE
;
12309 w
->window_end_pos
= make_number (Z
- ZV
);
12310 w
->window_end_vpos
= make_number (0);
12313 /* But that is not valid info until redisplay finishes. */
12314 w
->window_end_valid
= Qnil
;
12320 /************************************************************************
12321 Window redisplay reusing current matrix when buffer has not changed
12322 ************************************************************************/
12324 /* Try redisplay of window W showing an unchanged buffer with a
12325 different window start than the last time it was displayed by
12326 reusing its current matrix. Value is non-zero if successful.
12327 W->start is the new window start. */
12330 try_window_reusing_current_matrix (w
)
12333 struct frame
*f
= XFRAME (w
->frame
);
12334 struct glyph_row
*row
, *bottom_row
;
12337 struct text_pos start
, new_start
;
12338 int nrows_scrolled
, i
;
12339 struct glyph_row
*last_text_row
;
12340 struct glyph_row
*last_reused_text_row
;
12341 struct glyph_row
*start_row
;
12342 int start_vpos
, min_y
, max_y
;
12345 if (inhibit_try_window_reusing
)
12349 if (/* This function doesn't handle terminal frames. */
12350 !FRAME_WINDOW_P (f
)
12351 /* Don't try to reuse the display if windows have been split
12353 || windows_or_buffers_changed
12354 || cursor_type_changed
)
12357 /* Can't do this if region may have changed. */
12358 if ((!NILP (Vtransient_mark_mode
)
12359 && !NILP (current_buffer
->mark_active
))
12360 || !NILP (w
->region_showing
)
12361 || !NILP (Vshow_trailing_whitespace
))
12364 /* If top-line visibility has changed, give up. */
12365 if (WINDOW_WANTS_HEADER_LINE_P (w
)
12366 != MATRIX_HEADER_LINE_ROW (w
->current_matrix
)->mode_line_p
)
12369 /* Give up if old or new display is scrolled vertically. We could
12370 make this function handle this, but right now it doesn't. */
12371 start_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
12372 if (w
->vscroll
|| MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row
))
12375 /* The variable new_start now holds the new window start. The old
12376 start `start' can be determined from the current matrix. */
12377 SET_TEXT_POS_FROM_MARKER (new_start
, w
->start
);
12378 start
= start_row
->start
.pos
;
12379 start_vpos
= MATRIX_ROW_VPOS (start_row
, w
->current_matrix
);
12381 /* Clear the desired matrix for the display below. */
12382 clear_glyph_matrix (w
->desired_matrix
);
12384 if (CHARPOS (new_start
) <= CHARPOS (start
))
12388 /* Don't use this method if the display starts with an ellipsis
12389 displayed for invisible text. It's not easy to handle that case
12390 below, and it's certainly not worth the effort since this is
12391 not a frequent case. */
12392 if (in_ellipses_for_invisible_text_p (&start_row
->start
, w
))
12395 IF_DEBUG (debug_method_add (w
, "twu1"));
12397 /* Display up to a row that can be reused. The variable
12398 last_text_row is set to the last row displayed that displays
12399 text. Note that it.vpos == 0 if or if not there is a
12400 header-line; it's not the same as the MATRIX_ROW_VPOS! */
12401 start_display (&it
, w
, new_start
);
12402 first_row_y
= it
.current_y
;
12403 w
->cursor
.vpos
= -1;
12404 last_text_row
= last_reused_text_row
= NULL
;
12406 while (it
.current_y
< it
.last_visible_y
12407 && IT_CHARPOS (it
) < CHARPOS (start
)
12408 && !fonts_changed_p
)
12409 if (display_line (&it
))
12410 last_text_row
= it
.glyph_row
- 1;
12412 /* A value of current_y < last_visible_y means that we stopped
12413 at the previous window start, which in turn means that we
12414 have at least one reusable row. */
12415 if (it
.current_y
< it
.last_visible_y
)
12417 /* IT.vpos always starts from 0; it counts text lines. */
12418 nrows_scrolled
= it
.vpos
;
12420 /* Find PT if not already found in the lines displayed. */
12421 if (w
->cursor
.vpos
< 0)
12423 int dy
= it
.current_y
- first_row_y
;
12425 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
12426 row
= row_containing_pos (w
, PT
, row
, NULL
, dy
);
12428 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0,
12429 dy
, nrows_scrolled
);
12432 clear_glyph_matrix (w
->desired_matrix
);
12437 /* Scroll the display. Do it before the current matrix is
12438 changed. The problem here is that update has not yet
12439 run, i.e. part of the current matrix is not up to date.
12440 scroll_run_hook will clear the cursor, and use the
12441 current matrix to get the height of the row the cursor is
12443 run
.current_y
= first_row_y
;
12444 run
.desired_y
= it
.current_y
;
12445 run
.height
= it
.last_visible_y
- it
.current_y
;
12447 if (run
.height
> 0 && run
.current_y
!= run
.desired_y
)
12450 rif
->update_window_begin_hook (w
);
12451 rif
->clear_window_mouse_face (w
);
12452 rif
->scroll_run_hook (w
, &run
);
12453 rif
->update_window_end_hook (w
, 0, 0);
12457 /* Shift current matrix down by nrows_scrolled lines. */
12458 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
12459 rotate_matrix (w
->current_matrix
,
12461 MATRIX_ROW_VPOS (bottom_row
, w
->current_matrix
),
12464 /* Disable lines that must be updated. */
12465 for (i
= 0; i
< it
.vpos
; ++i
)
12466 (start_row
+ i
)->enabled_p
= 0;
12468 /* Re-compute Y positions. */
12469 min_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
12470 max_y
= it
.last_visible_y
;
12471 for (row
= start_row
+ nrows_scrolled
;
12475 row
->y
= it
.current_y
;
12476 row
->visible_height
= row
->height
;
12478 if (row
->y
< min_y
)
12479 row
->visible_height
-= min_y
- row
->y
;
12480 if (row
->y
+ row
->height
> max_y
)
12481 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
12482 row
->redraw_fringe_bitmaps_p
= 1;
12484 it
.current_y
+= row
->height
;
12486 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
12487 last_reused_text_row
= row
;
12488 if (MATRIX_ROW_BOTTOM_Y (row
) >= it
.last_visible_y
)
12492 /* Disable lines in the current matrix which are now
12493 below the window. */
12494 for (++row
; row
< bottom_row
; ++row
)
12495 row
->enabled_p
= 0;
12498 /* Update window_end_pos etc.; last_reused_text_row is the last
12499 reused row from the current matrix containing text, if any.
12500 The value of last_text_row is the last displayed line
12501 containing text. */
12502 if (last_reused_text_row
)
12504 w
->window_end_bytepos
12505 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_reused_text_row
);
12507 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_reused_text_row
));
12509 = make_number (MATRIX_ROW_VPOS (last_reused_text_row
,
12510 w
->current_matrix
));
12512 else if (last_text_row
)
12514 w
->window_end_bytepos
12515 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
12517 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
12519 = make_number (MATRIX_ROW_VPOS (last_text_row
, w
->desired_matrix
));
12523 /* This window must be completely empty. */
12524 w
->window_end_bytepos
= Z_BYTE
- ZV_BYTE
;
12525 w
->window_end_pos
= make_number (Z
- ZV
);
12526 w
->window_end_vpos
= make_number (0);
12528 w
->window_end_valid
= Qnil
;
12530 /* Update hint: don't try scrolling again in update_window. */
12531 w
->desired_matrix
->no_scrolling_p
= 1;
12534 debug_method_add (w
, "try_window_reusing_current_matrix 1");
12538 else if (CHARPOS (new_start
) > CHARPOS (start
))
12540 struct glyph_row
*pt_row
, *row
;
12541 struct glyph_row
*first_reusable_row
;
12542 struct glyph_row
*first_row_to_display
;
12544 int yb
= window_text_bottom_y (w
);
12546 /* Find the row starting at new_start, if there is one. Don't
12547 reuse a partially visible line at the end. */
12548 first_reusable_row
= start_row
;
12549 while (first_reusable_row
->enabled_p
12550 && MATRIX_ROW_BOTTOM_Y (first_reusable_row
) < yb
12551 && (MATRIX_ROW_START_CHARPOS (first_reusable_row
)
12552 < CHARPOS (new_start
)))
12553 ++first_reusable_row
;
12555 /* Give up if there is no row to reuse. */
12556 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row
) >= yb
12557 || !first_reusable_row
->enabled_p
12558 || (MATRIX_ROW_START_CHARPOS (first_reusable_row
)
12559 != CHARPOS (new_start
)))
12562 /* We can reuse fully visible rows beginning with
12563 first_reusable_row to the end of the window. Set
12564 first_row_to_display to the first row that cannot be reused.
12565 Set pt_row to the row containing point, if there is any. */
12567 for (first_row_to_display
= first_reusable_row
;
12568 MATRIX_ROW_BOTTOM_Y (first_row_to_display
) < yb
;
12569 ++first_row_to_display
)
12571 if (PT
>= MATRIX_ROW_START_CHARPOS (first_row_to_display
)
12572 && PT
< MATRIX_ROW_END_CHARPOS (first_row_to_display
))
12573 pt_row
= first_row_to_display
;
12576 /* Start displaying at the start of first_row_to_display. */
12577 xassert (first_row_to_display
->y
< yb
);
12578 init_to_row_start (&it
, w
, first_row_to_display
);
12580 nrows_scrolled
= (MATRIX_ROW_VPOS (first_reusable_row
, w
->current_matrix
)
12582 it
.vpos
= (MATRIX_ROW_VPOS (first_row_to_display
, w
->current_matrix
)
12584 it
.current_y
= (first_row_to_display
->y
- first_reusable_row
->y
12585 + WINDOW_HEADER_LINE_HEIGHT (w
));
12587 /* Display lines beginning with first_row_to_display in the
12588 desired matrix. Set last_text_row to the last row displayed
12589 that displays text. */
12590 it
.glyph_row
= MATRIX_ROW (w
->desired_matrix
, it
.vpos
);
12591 if (pt_row
== NULL
)
12592 w
->cursor
.vpos
= -1;
12593 last_text_row
= NULL
;
12594 while (it
.current_y
< it
.last_visible_y
&& !fonts_changed_p
)
12595 if (display_line (&it
))
12596 last_text_row
= it
.glyph_row
- 1;
12598 /* Give up If point isn't in a row displayed or reused. */
12599 if (w
->cursor
.vpos
< 0)
12601 clear_glyph_matrix (w
->desired_matrix
);
12605 /* If point is in a reused row, adjust y and vpos of the cursor
12609 w
->cursor
.vpos
-= nrows_scrolled
;
12610 w
->cursor
.y
-= first_reusable_row
->y
- start_row
->y
;
12613 /* Scroll the display. */
12614 run
.current_y
= first_reusable_row
->y
;
12615 run
.desired_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
12616 run
.height
= it
.last_visible_y
- run
.current_y
;
12617 dy
= run
.current_y
- run
.desired_y
;
12622 rif
->update_window_begin_hook (w
);
12623 rif
->clear_window_mouse_face (w
);
12624 rif
->scroll_run_hook (w
, &run
);
12625 rif
->update_window_end_hook (w
, 0, 0);
12629 /* Adjust Y positions of reused rows. */
12630 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
12631 min_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
12632 max_y
= it
.last_visible_y
;
12633 for (row
= first_reusable_row
; row
< first_row_to_display
; ++row
)
12636 row
->visible_height
= row
->height
;
12637 if (row
->y
< min_y
)
12638 row
->visible_height
-= min_y
- row
->y
;
12639 if (row
->y
+ row
->height
> max_y
)
12640 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
12641 row
->redraw_fringe_bitmaps_p
= 1;
12644 /* Scroll the current matrix. */
12645 xassert (nrows_scrolled
> 0);
12646 rotate_matrix (w
->current_matrix
,
12648 MATRIX_ROW_VPOS (bottom_row
, w
->current_matrix
),
12651 /* Disable rows not reused. */
12652 for (row
-= nrows_scrolled
; row
< bottom_row
; ++row
)
12653 row
->enabled_p
= 0;
12655 /* Point may have moved to a different line, so we cannot assume that
12656 the previous cursor position is valid; locate the correct row. */
12659 for (row
= MATRIX_ROW (w
->current_matrix
, w
->cursor
.vpos
);
12660 row
< bottom_row
&& PT
>= MATRIX_ROW_END_CHARPOS (row
);
12664 w
->cursor
.y
= row
->y
;
12666 if (row
< bottom_row
)
12668 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + w
->cursor
.hpos
;
12669 while (glyph
->charpos
< PT
)
12672 w
->cursor
.x
+= glyph
->pixel_width
;
12678 /* Adjust window end. A null value of last_text_row means that
12679 the window end is in reused rows which in turn means that
12680 only its vpos can have changed. */
12683 w
->window_end_bytepos
12684 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
12686 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
12688 = make_number (MATRIX_ROW_VPOS (last_text_row
, w
->desired_matrix
));
12693 = make_number (XFASTINT (w
->window_end_vpos
) - nrows_scrolled
);
12696 w
->window_end_valid
= Qnil
;
12697 w
->desired_matrix
->no_scrolling_p
= 1;
12700 debug_method_add (w
, "try_window_reusing_current_matrix 2");
12710 /************************************************************************
12711 Window redisplay reusing current matrix when buffer has changed
12712 ************************************************************************/
12714 static struct glyph_row
*find_last_unchanged_at_beg_row
P_ ((struct window
*));
12715 static struct glyph_row
*find_first_unchanged_at_end_row
P_ ((struct window
*,
12717 static struct glyph_row
*
12718 find_last_row_displaying_text
P_ ((struct glyph_matrix
*, struct it
*,
12719 struct glyph_row
*));
12722 /* Return the last row in MATRIX displaying text. If row START is
12723 non-null, start searching with that row. IT gives the dimensions
12724 of the display. Value is null if matrix is empty; otherwise it is
12725 a pointer to the row found. */
12727 static struct glyph_row
*
12728 find_last_row_displaying_text (matrix
, it
, start
)
12729 struct glyph_matrix
*matrix
;
12731 struct glyph_row
*start
;
12733 struct glyph_row
*row
, *row_found
;
12735 /* Set row_found to the last row in IT->w's current matrix
12736 displaying text. The loop looks funny but think of partially
12739 row
= start
? start
: MATRIX_FIRST_TEXT_ROW (matrix
);
12740 while (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
12742 xassert (row
->enabled_p
);
12744 if (MATRIX_ROW_BOTTOM_Y (row
) >= it
->last_visible_y
)
12753 /* Return the last row in the current matrix of W that is not affected
12754 by changes at the start of current_buffer that occurred since W's
12755 current matrix was built. Value is null if no such row exists.
12757 BEG_UNCHANGED us the number of characters unchanged at the start of
12758 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
12759 first changed character in current_buffer. Characters at positions <
12760 BEG + BEG_UNCHANGED are at the same buffer positions as they were
12761 when the current matrix was built. */
12763 static struct glyph_row
*
12764 find_last_unchanged_at_beg_row (w
)
12767 int first_changed_pos
= BEG
+ BEG_UNCHANGED
;
12768 struct glyph_row
*row
;
12769 struct glyph_row
*row_found
= NULL
;
12770 int yb
= window_text_bottom_y (w
);
12772 /* Find the last row displaying unchanged text. */
12773 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
12774 while (MATRIX_ROW_DISPLAYS_TEXT_P (row
)
12775 && MATRIX_ROW_START_CHARPOS (row
) < first_changed_pos
)
12777 if (/* If row ends before first_changed_pos, it is unchanged,
12778 except in some case. */
12779 MATRIX_ROW_END_CHARPOS (row
) <= first_changed_pos
12780 /* When row ends in ZV and we write at ZV it is not
12782 && !row
->ends_at_zv_p
12783 /* When first_changed_pos is the end of a continued line,
12784 row is not unchanged because it may be no longer
12786 && !(MATRIX_ROW_END_CHARPOS (row
) == first_changed_pos
12787 && (row
->continued_p
12788 || row
->exact_window_width_line_p
)))
12791 /* Stop if last visible row. */
12792 if (MATRIX_ROW_BOTTOM_Y (row
) >= yb
)
12802 /* Find the first glyph row in the current matrix of W that is not
12803 affected by changes at the end of current_buffer since the
12804 time W's current matrix was built.
12806 Return in *DELTA the number of chars by which buffer positions in
12807 unchanged text at the end of current_buffer must be adjusted.
12809 Return in *DELTA_BYTES the corresponding number of bytes.
12811 Value is null if no such row exists, i.e. all rows are affected by
12814 static struct glyph_row
*
12815 find_first_unchanged_at_end_row (w
, delta
, delta_bytes
)
12817 int *delta
, *delta_bytes
;
12819 struct glyph_row
*row
;
12820 struct glyph_row
*row_found
= NULL
;
12822 *delta
= *delta_bytes
= 0;
12824 /* Display must not have been paused, otherwise the current matrix
12825 is not up to date. */
12826 if (NILP (w
->window_end_valid
))
12829 /* A value of window_end_pos >= END_UNCHANGED means that the window
12830 end is in the range of changed text. If so, there is no
12831 unchanged row at the end of W's current matrix. */
12832 if (XFASTINT (w
->window_end_pos
) >= END_UNCHANGED
)
12835 /* Set row to the last row in W's current matrix displaying text. */
12836 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
12838 /* If matrix is entirely empty, no unchanged row exists. */
12839 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
12841 /* The value of row is the last glyph row in the matrix having a
12842 meaningful buffer position in it. The end position of row
12843 corresponds to window_end_pos. This allows us to translate
12844 buffer positions in the current matrix to current buffer
12845 positions for characters not in changed text. */
12846 int Z_old
= MATRIX_ROW_END_CHARPOS (row
) + XFASTINT (w
->window_end_pos
);
12847 int Z_BYTE_old
= MATRIX_ROW_END_BYTEPOS (row
) + w
->window_end_bytepos
;
12848 int last_unchanged_pos
, last_unchanged_pos_old
;
12849 struct glyph_row
*first_text_row
12850 = MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
12852 *delta
= Z
- Z_old
;
12853 *delta_bytes
= Z_BYTE
- Z_BYTE_old
;
12855 /* Set last_unchanged_pos to the buffer position of the last
12856 character in the buffer that has not been changed. Z is the
12857 index + 1 of the last character in current_buffer, i.e. by
12858 subtracting END_UNCHANGED we get the index of the last
12859 unchanged character, and we have to add BEG to get its buffer
12861 last_unchanged_pos
= Z
- END_UNCHANGED
+ BEG
;
12862 last_unchanged_pos_old
= last_unchanged_pos
- *delta
;
12864 /* Search backward from ROW for a row displaying a line that
12865 starts at a minimum position >= last_unchanged_pos_old. */
12866 for (; row
> first_text_row
; --row
)
12868 if (!row
->enabled_p
|| !MATRIX_ROW_DISPLAYS_TEXT_P (row
))
12871 if (MATRIX_ROW_START_CHARPOS (row
) >= last_unchanged_pos_old
)
12876 if (row_found
&& !MATRIX_ROW_DISPLAYS_TEXT_P (row_found
))
12883 /* Make sure that glyph rows in the current matrix of window W
12884 reference the same glyph memory as corresponding rows in the
12885 frame's frame matrix. This function is called after scrolling W's
12886 current matrix on a terminal frame in try_window_id and
12887 try_window_reusing_current_matrix. */
12890 sync_frame_with_window_matrix_rows (w
)
12893 struct frame
*f
= XFRAME (w
->frame
);
12894 struct glyph_row
*window_row
, *window_row_end
, *frame_row
;
12896 /* Preconditions: W must be a leaf window and full-width. Its frame
12897 must have a frame matrix. */
12898 xassert (NILP (w
->hchild
) && NILP (w
->vchild
));
12899 xassert (WINDOW_FULL_WIDTH_P (w
));
12900 xassert (!FRAME_WINDOW_P (f
));
12902 /* If W is a full-width window, glyph pointers in W's current matrix
12903 have, by definition, to be the same as glyph pointers in the
12904 corresponding frame matrix. Note that frame matrices have no
12905 marginal areas (see build_frame_matrix). */
12906 window_row
= w
->current_matrix
->rows
;
12907 window_row_end
= window_row
+ w
->current_matrix
->nrows
;
12908 frame_row
= f
->current_matrix
->rows
+ WINDOW_TOP_EDGE_LINE (w
);
12909 while (window_row
< window_row_end
)
12911 struct glyph
*start
= window_row
->glyphs
[LEFT_MARGIN_AREA
];
12912 struct glyph
*end
= window_row
->glyphs
[LAST_AREA
];
12914 frame_row
->glyphs
[LEFT_MARGIN_AREA
] = start
;
12915 frame_row
->glyphs
[TEXT_AREA
] = start
;
12916 frame_row
->glyphs
[RIGHT_MARGIN_AREA
] = end
;
12917 frame_row
->glyphs
[LAST_AREA
] = end
;
12919 /* Disable frame rows whose corresponding window rows have
12920 been disabled in try_window_id. */
12921 if (!window_row
->enabled_p
)
12922 frame_row
->enabled_p
= 0;
12924 ++window_row
, ++frame_row
;
12929 /* Find the glyph row in window W containing CHARPOS. Consider all
12930 rows between START and END (not inclusive). END null means search
12931 all rows to the end of the display area of W. Value is the row
12932 containing CHARPOS or null. */
12935 row_containing_pos (w
, charpos
, start
, end
, dy
)
12938 struct glyph_row
*start
, *end
;
12941 struct glyph_row
*row
= start
;
12944 /* If we happen to start on a header-line, skip that. */
12945 if (row
->mode_line_p
)
12948 if ((end
&& row
>= end
) || !row
->enabled_p
)
12951 last_y
= window_text_bottom_y (w
) - dy
;
12955 /* Give up if we have gone too far. */
12956 if (end
&& row
>= end
)
12958 /* This formerly returned if they were equal.
12959 I think that both quantities are of a "last plus one" type;
12960 if so, when they are equal, the row is within the screen. -- rms. */
12961 if (MATRIX_ROW_BOTTOM_Y (row
) > last_y
)
12964 /* If it is in this row, return this row. */
12965 if (! (MATRIX_ROW_END_CHARPOS (row
) < charpos
12966 || (MATRIX_ROW_END_CHARPOS (row
) == charpos
12967 /* The end position of a row equals the start
12968 position of the next row. If CHARPOS is there, we
12969 would rather display it in the next line, except
12970 when this line ends in ZV. */
12971 && !row
->ends_at_zv_p
12972 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
)))
12973 && charpos
>= MATRIX_ROW_START_CHARPOS (row
))
12980 /* Try to redisplay window W by reusing its existing display. W's
12981 current matrix must be up to date when this function is called,
12982 i.e. window_end_valid must not be nil.
12986 1 if display has been updated
12987 0 if otherwise unsuccessful
12988 -1 if redisplay with same window start is known not to succeed
12990 The following steps are performed:
12992 1. Find the last row in the current matrix of W that is not
12993 affected by changes at the start of current_buffer. If no such row
12996 2. Find the first row in W's current matrix that is not affected by
12997 changes at the end of current_buffer. Maybe there is no such row.
12999 3. Display lines beginning with the row + 1 found in step 1 to the
13000 row found in step 2 or, if step 2 didn't find a row, to the end of
13003 4. If cursor is not known to appear on the window, give up.
13005 5. If display stopped at the row found in step 2, scroll the
13006 display and current matrix as needed.
13008 6. Maybe display some lines at the end of W, if we must. This can
13009 happen under various circumstances, like a partially visible line
13010 becoming fully visible, or because newly displayed lines are displayed
13011 in smaller font sizes.
13013 7. Update W's window end information. */
13019 struct frame
*f
= XFRAME (w
->frame
);
13020 struct glyph_matrix
*current_matrix
= w
->current_matrix
;
13021 struct glyph_matrix
*desired_matrix
= w
->desired_matrix
;
13022 struct glyph_row
*last_unchanged_at_beg_row
;
13023 struct glyph_row
*first_unchanged_at_end_row
;
13024 struct glyph_row
*row
;
13025 struct glyph_row
*bottom_row
;
13028 int delta
= 0, delta_bytes
= 0, stop_pos
, dvpos
, dy
;
13029 struct text_pos start_pos
;
13031 int first_unchanged_at_end_vpos
= 0;
13032 struct glyph_row
*last_text_row
, *last_text_row_at_end
;
13033 struct text_pos start
;
13034 int first_changed_charpos
, last_changed_charpos
;
13037 if (inhibit_try_window_id
)
13041 /* This is handy for debugging. */
13043 #define GIVE_UP(X) \
13045 fprintf (stderr, "try_window_id give up %d\n", (X)); \
13049 #define GIVE_UP(X) return 0
13052 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
13054 /* Don't use this for mini-windows because these can show
13055 messages and mini-buffers, and we don't handle that here. */
13056 if (MINI_WINDOW_P (w
))
13059 /* This flag is used to prevent redisplay optimizations. */
13060 if (windows_or_buffers_changed
|| cursor_type_changed
)
13063 /* Verify that narrowing has not changed.
13064 Also verify that we were not told to prevent redisplay optimizations.
13065 It would be nice to further
13066 reduce the number of cases where this prevents try_window_id. */
13067 if (current_buffer
->clip_changed
13068 || current_buffer
->prevent_redisplay_optimizations_p
)
13071 /* Window must either use window-based redisplay or be full width. */
13072 if (!FRAME_WINDOW_P (f
)
13073 && (!line_ins_del_ok
13074 || !WINDOW_FULL_WIDTH_P (w
)))
13077 /* Give up if point is not known NOT to appear in W. */
13078 if (PT
< CHARPOS (start
))
13081 /* Another way to prevent redisplay optimizations. */
13082 if (XFASTINT (w
->last_modified
) == 0)
13085 /* Verify that window is not hscrolled. */
13086 if (XFASTINT (w
->hscroll
) != 0)
13089 /* Verify that display wasn't paused. */
13090 if (NILP (w
->window_end_valid
))
13093 /* Can't use this if highlighting a region because a cursor movement
13094 will do more than just set the cursor. */
13095 if (!NILP (Vtransient_mark_mode
)
13096 && !NILP (current_buffer
->mark_active
))
13099 /* Likewise if highlighting trailing whitespace. */
13100 if (!NILP (Vshow_trailing_whitespace
))
13103 /* Likewise if showing a region. */
13104 if (!NILP (w
->region_showing
))
13107 /* Can use this if overlay arrow position and or string have changed. */
13108 if (overlay_arrows_changed_p ())
13112 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
13113 only if buffer has really changed. The reason is that the gap is
13114 initially at Z for freshly visited files. The code below would
13115 set end_unchanged to 0 in that case. */
13116 if (MODIFF
> SAVE_MODIFF
13117 /* This seems to happen sometimes after saving a buffer. */
13118 || BEG_UNCHANGED
+ END_UNCHANGED
> Z_BYTE
)
13120 if (GPT
- BEG
< BEG_UNCHANGED
)
13121 BEG_UNCHANGED
= GPT
- BEG
;
13122 if (Z
- GPT
< END_UNCHANGED
)
13123 END_UNCHANGED
= Z
- GPT
;
13126 /* The position of the first and last character that has been changed. */
13127 first_changed_charpos
= BEG
+ BEG_UNCHANGED
;
13128 last_changed_charpos
= Z
- END_UNCHANGED
;
13130 /* If window starts after a line end, and the last change is in
13131 front of that newline, then changes don't affect the display.
13132 This case happens with stealth-fontification. Note that although
13133 the display is unchanged, glyph positions in the matrix have to
13134 be adjusted, of course. */
13135 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
13136 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
)
13137 && ((last_changed_charpos
< CHARPOS (start
)
13138 && CHARPOS (start
) == BEGV
)
13139 || (last_changed_charpos
< CHARPOS (start
) - 1
13140 && FETCH_BYTE (BYTEPOS (start
) - 1) == '\n')))
13142 int Z_old
, delta
, Z_BYTE_old
, delta_bytes
;
13143 struct glyph_row
*r0
;
13145 /* Compute how many chars/bytes have been added to or removed
13146 from the buffer. */
13147 Z_old
= MATRIX_ROW_END_CHARPOS (row
) + XFASTINT (w
->window_end_pos
);
13148 Z_BYTE_old
= MATRIX_ROW_END_BYTEPOS (row
) + w
->window_end_bytepos
;
13150 delta_bytes
= Z_BYTE
- Z_BYTE_old
;
13152 /* Give up if PT is not in the window. Note that it already has
13153 been checked at the start of try_window_id that PT is not in
13154 front of the window start. */
13155 if (PT
>= MATRIX_ROW_END_CHARPOS (row
) + delta
)
13158 /* If window start is unchanged, we can reuse the whole matrix
13159 as is, after adjusting glyph positions. No need to compute
13160 the window end again, since its offset from Z hasn't changed. */
13161 r0
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
13162 if (CHARPOS (start
) == MATRIX_ROW_START_CHARPOS (r0
) + delta
13163 && BYTEPOS (start
) == MATRIX_ROW_START_BYTEPOS (r0
) + delta_bytes
13164 /* PT must not be in a partially visible line. */
13165 && !(PT
>= MATRIX_ROW_START_CHARPOS (row
) + delta
13166 && MATRIX_ROW_BOTTOM_Y (row
) > window_text_bottom_y (w
)))
13168 /* Adjust positions in the glyph matrix. */
13169 if (delta
|| delta_bytes
)
13171 struct glyph_row
*r1
13172 = MATRIX_BOTTOM_TEXT_ROW (current_matrix
, w
);
13173 increment_matrix_positions (w
->current_matrix
,
13174 MATRIX_ROW_VPOS (r0
, current_matrix
),
13175 MATRIX_ROW_VPOS (r1
, current_matrix
),
13176 delta
, delta_bytes
);
13179 /* Set the cursor. */
13180 row
= row_containing_pos (w
, PT
, r0
, NULL
, 0);
13182 set_cursor_from_row (w
, row
, current_matrix
, 0, 0, 0, 0);
13189 /* Handle the case that changes are all below what is displayed in
13190 the window, and that PT is in the window. This shortcut cannot
13191 be taken if ZV is visible in the window, and text has been added
13192 there that is visible in the window. */
13193 if (first_changed_charpos
>= MATRIX_ROW_END_CHARPOS (row
)
13194 /* ZV is not visible in the window, or there are no
13195 changes at ZV, actually. */
13196 && (current_matrix
->zv
> MATRIX_ROW_END_CHARPOS (row
)
13197 || first_changed_charpos
== last_changed_charpos
))
13199 struct glyph_row
*r0
;
13201 /* Give up if PT is not in the window. Note that it already has
13202 been checked at the start of try_window_id that PT is not in
13203 front of the window start. */
13204 if (PT
>= MATRIX_ROW_END_CHARPOS (row
))
13207 /* If window start is unchanged, we can reuse the whole matrix
13208 as is, without changing glyph positions since no text has
13209 been added/removed in front of the window end. */
13210 r0
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
13211 if (TEXT_POS_EQUAL_P (start
, r0
->start
.pos
)
13212 /* PT must not be in a partially visible line. */
13213 && !(PT
>= MATRIX_ROW_START_CHARPOS (row
)
13214 && MATRIX_ROW_BOTTOM_Y (row
) > window_text_bottom_y (w
)))
13216 /* We have to compute the window end anew since text
13217 can have been added/removed after it. */
13219 = make_number (Z
- MATRIX_ROW_END_CHARPOS (row
));
13220 w
->window_end_bytepos
13221 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
13223 /* Set the cursor. */
13224 row
= row_containing_pos (w
, PT
, r0
, NULL
, 0);
13226 set_cursor_from_row (w
, row
, current_matrix
, 0, 0, 0, 0);
13233 /* Give up if window start is in the changed area.
13235 The condition used to read
13237 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
13239 but why that was tested escapes me at the moment. */
13240 if (CHARPOS (start
) >= first_changed_charpos
13241 && CHARPOS (start
) <= last_changed_charpos
)
13244 /* Check that window start agrees with the start of the first glyph
13245 row in its current matrix. Check this after we know the window
13246 start is not in changed text, otherwise positions would not be
13248 row
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
13249 if (!TEXT_POS_EQUAL_P (start
, row
->start
.pos
))
13252 /* Give up if the window ends in strings. Overlay strings
13253 at the end are difficult to handle, so don't try. */
13254 row
= MATRIX_ROW (current_matrix
, XFASTINT (w
->window_end_vpos
));
13255 if (MATRIX_ROW_START_CHARPOS (row
) == MATRIX_ROW_END_CHARPOS (row
))
13258 /* Compute the position at which we have to start displaying new
13259 lines. Some of the lines at the top of the window might be
13260 reusable because they are not displaying changed text. Find the
13261 last row in W's current matrix not affected by changes at the
13262 start of current_buffer. Value is null if changes start in the
13263 first line of window. */
13264 last_unchanged_at_beg_row
= find_last_unchanged_at_beg_row (w
);
13265 if (last_unchanged_at_beg_row
)
13267 /* Avoid starting to display in the moddle of a character, a TAB
13268 for instance. This is easier than to set up the iterator
13269 exactly, and it's not a frequent case, so the additional
13270 effort wouldn't really pay off. */
13271 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row
)
13272 || last_unchanged_at_beg_row
->ends_in_newline_from_string_p
)
13273 && last_unchanged_at_beg_row
> w
->current_matrix
->rows
)
13274 --last_unchanged_at_beg_row
;
13276 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row
))
13279 if (init_to_row_end (&it
, w
, last_unchanged_at_beg_row
) == 0)
13281 start_pos
= it
.current
.pos
;
13283 /* Start displaying new lines in the desired matrix at the same
13284 vpos we would use in the current matrix, i.e. below
13285 last_unchanged_at_beg_row. */
13286 it
.vpos
= 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row
,
13288 it
.glyph_row
= MATRIX_ROW (desired_matrix
, it
.vpos
);
13289 it
.current_y
= MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row
);
13291 xassert (it
.hpos
== 0 && it
.current_x
== 0);
13295 /* There are no reusable lines at the start of the window.
13296 Start displaying in the first text line. */
13297 start_display (&it
, w
, start
);
13298 it
.vpos
= it
.first_vpos
;
13299 start_pos
= it
.current
.pos
;
13302 /* Find the first row that is not affected by changes at the end of
13303 the buffer. Value will be null if there is no unchanged row, in
13304 which case we must redisplay to the end of the window. delta
13305 will be set to the value by which buffer positions beginning with
13306 first_unchanged_at_end_row have to be adjusted due to text
13308 first_unchanged_at_end_row
13309 = find_first_unchanged_at_end_row (w
, &delta
, &delta_bytes
);
13310 IF_DEBUG (debug_delta
= delta
);
13311 IF_DEBUG (debug_delta_bytes
= delta_bytes
);
13313 /* Set stop_pos to the buffer position up to which we will have to
13314 display new lines. If first_unchanged_at_end_row != NULL, this
13315 is the buffer position of the start of the line displayed in that
13316 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
13317 that we don't stop at a buffer position. */
13319 if (first_unchanged_at_end_row
)
13321 xassert (last_unchanged_at_beg_row
== NULL
13322 || first_unchanged_at_end_row
>= last_unchanged_at_beg_row
);
13324 /* If this is a continuation line, move forward to the next one
13325 that isn't. Changes in lines above affect this line.
13326 Caution: this may move first_unchanged_at_end_row to a row
13327 not displaying text. */
13328 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row
)
13329 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
)
13330 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row
)
13331 < it
.last_visible_y
))
13332 ++first_unchanged_at_end_row
;
13334 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
)
13335 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row
)
13336 >= it
.last_visible_y
))
13337 first_unchanged_at_end_row
= NULL
;
13340 stop_pos
= (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row
)
13342 first_unchanged_at_end_vpos
13343 = MATRIX_ROW_VPOS (first_unchanged_at_end_row
, current_matrix
);
13344 xassert (stop_pos
>= Z
- END_UNCHANGED
);
13347 else if (last_unchanged_at_beg_row
== NULL
)
13353 /* Either there is no unchanged row at the end, or the one we have
13354 now displays text. This is a necessary condition for the window
13355 end pos calculation at the end of this function. */
13356 xassert (first_unchanged_at_end_row
== NULL
13357 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
));
13359 debug_last_unchanged_at_beg_vpos
13360 = (last_unchanged_at_beg_row
13361 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row
, current_matrix
)
13363 debug_first_unchanged_at_end_vpos
= first_unchanged_at_end_vpos
;
13365 #endif /* GLYPH_DEBUG != 0 */
13368 /* Display new lines. Set last_text_row to the last new line
13369 displayed which has text on it, i.e. might end up as being the
13370 line where the window_end_vpos is. */
13371 w
->cursor
.vpos
= -1;
13372 last_text_row
= NULL
;
13373 overlay_arrow_seen
= 0;
13374 while (it
.current_y
< it
.last_visible_y
13375 && !fonts_changed_p
13376 && (first_unchanged_at_end_row
== NULL
13377 || IT_CHARPOS (it
) < stop_pos
))
13379 if (display_line (&it
))
13380 last_text_row
= it
.glyph_row
- 1;
13383 if (fonts_changed_p
)
13387 /* Compute differences in buffer positions, y-positions etc. for
13388 lines reused at the bottom of the window. Compute what we can
13390 if (first_unchanged_at_end_row
13391 /* No lines reused because we displayed everything up to the
13392 bottom of the window. */
13393 && it
.current_y
< it
.last_visible_y
)
13396 - MATRIX_ROW_VPOS (first_unchanged_at_end_row
,
13398 dy
= it
.current_y
- first_unchanged_at_end_row
->y
;
13399 run
.current_y
= first_unchanged_at_end_row
->y
;
13400 run
.desired_y
= run
.current_y
+ dy
;
13401 run
.height
= it
.last_visible_y
- max (run
.current_y
, run
.desired_y
);
13405 delta
= dvpos
= dy
= run
.current_y
= run
.desired_y
= run
.height
= 0;
13406 first_unchanged_at_end_row
= NULL
;
13408 IF_DEBUG (debug_dvpos
= dvpos
; debug_dy
= dy
);
13411 /* Find the cursor if not already found. We have to decide whether
13412 PT will appear on this window (it sometimes doesn't, but this is
13413 not a very frequent case.) This decision has to be made before
13414 the current matrix is altered. A value of cursor.vpos < 0 means
13415 that PT is either in one of the lines beginning at
13416 first_unchanged_at_end_row or below the window. Don't care for
13417 lines that might be displayed later at the window end; as
13418 mentioned, this is not a frequent case. */
13419 if (w
->cursor
.vpos
< 0)
13421 /* Cursor in unchanged rows at the top? */
13422 if (PT
< CHARPOS (start_pos
)
13423 && last_unchanged_at_beg_row
)
13425 row
= row_containing_pos (w
, PT
,
13426 MATRIX_FIRST_TEXT_ROW (w
->current_matrix
),
13427 last_unchanged_at_beg_row
+ 1, 0);
13429 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
13432 /* Start from first_unchanged_at_end_row looking for PT. */
13433 else if (first_unchanged_at_end_row
)
13435 row
= row_containing_pos (w
, PT
- delta
,
13436 first_unchanged_at_end_row
, NULL
, 0);
13438 set_cursor_from_row (w
, row
, w
->current_matrix
, delta
,
13439 delta_bytes
, dy
, dvpos
);
13442 /* Give up if cursor was not found. */
13443 if (w
->cursor
.vpos
< 0)
13445 clear_glyph_matrix (w
->desired_matrix
);
13450 /* Don't let the cursor end in the scroll margins. */
13452 int this_scroll_margin
, cursor_height
;
13454 this_scroll_margin
= max (0, scroll_margin
);
13455 this_scroll_margin
= min (this_scroll_margin
, WINDOW_TOTAL_LINES (w
) / 4);
13456 this_scroll_margin
*= FRAME_LINE_HEIGHT (it
.f
);
13457 cursor_height
= MATRIX_ROW (w
->desired_matrix
, w
->cursor
.vpos
)->height
;
13459 if ((w
->cursor
.y
< this_scroll_margin
13460 && CHARPOS (start
) > BEGV
)
13461 /* Old redisplay didn't take scroll margin into account at the bottom,
13462 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
13463 || w
->cursor
.y
+ cursor_height
+ this_scroll_margin
> it
.last_visible_y
)
13465 w
->cursor
.vpos
= -1;
13466 clear_glyph_matrix (w
->desired_matrix
);
13471 /* Scroll the display. Do it before changing the current matrix so
13472 that xterm.c doesn't get confused about where the cursor glyph is
13474 if (dy
&& run
.height
)
13478 if (FRAME_WINDOW_P (f
))
13480 rif
->update_window_begin_hook (w
);
13481 rif
->clear_window_mouse_face (w
);
13482 rif
->scroll_run_hook (w
, &run
);
13483 rif
->update_window_end_hook (w
, 0, 0);
13487 /* Terminal frame. In this case, dvpos gives the number of
13488 lines to scroll by; dvpos < 0 means scroll up. */
13489 int first_unchanged_at_end_vpos
13490 = MATRIX_ROW_VPOS (first_unchanged_at_end_row
, w
->current_matrix
);
13491 int from
= WINDOW_TOP_EDGE_LINE (w
) + first_unchanged_at_end_vpos
;
13492 int end
= (WINDOW_TOP_EDGE_LINE (w
)
13493 + (WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0)
13494 + window_internal_height (w
));
13496 /* Perform the operation on the screen. */
13499 /* Scroll last_unchanged_at_beg_row to the end of the
13500 window down dvpos lines. */
13501 set_terminal_window (end
);
13503 /* On dumb terminals delete dvpos lines at the end
13504 before inserting dvpos empty lines. */
13505 if (!scroll_region_ok
)
13506 ins_del_lines (end
- dvpos
, -dvpos
);
13508 /* Insert dvpos empty lines in front of
13509 last_unchanged_at_beg_row. */
13510 ins_del_lines (from
, dvpos
);
13512 else if (dvpos
< 0)
13514 /* Scroll up last_unchanged_at_beg_vpos to the end of
13515 the window to last_unchanged_at_beg_vpos - |dvpos|. */
13516 set_terminal_window (end
);
13518 /* Delete dvpos lines in front of
13519 last_unchanged_at_beg_vpos. ins_del_lines will set
13520 the cursor to the given vpos and emit |dvpos| delete
13522 ins_del_lines (from
+ dvpos
, dvpos
);
13524 /* On a dumb terminal insert dvpos empty lines at the
13526 if (!scroll_region_ok
)
13527 ins_del_lines (end
+ dvpos
, -dvpos
);
13530 set_terminal_window (0);
13536 /* Shift reused rows of the current matrix to the right position.
13537 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
13539 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (current_matrix
, w
);
13540 bottom_vpos
= MATRIX_ROW_VPOS (bottom_row
, current_matrix
);
13543 rotate_matrix (current_matrix
, first_unchanged_at_end_vpos
+ dvpos
,
13544 bottom_vpos
, dvpos
);
13545 enable_glyph_matrix_rows (current_matrix
, bottom_vpos
+ dvpos
,
13548 else if (dvpos
> 0)
13550 rotate_matrix (current_matrix
, first_unchanged_at_end_vpos
,
13551 bottom_vpos
, dvpos
);
13552 enable_glyph_matrix_rows (current_matrix
, first_unchanged_at_end_vpos
,
13553 first_unchanged_at_end_vpos
+ dvpos
, 0);
13556 /* For frame-based redisplay, make sure that current frame and window
13557 matrix are in sync with respect to glyph memory. */
13558 if (!FRAME_WINDOW_P (f
))
13559 sync_frame_with_window_matrix_rows (w
);
13561 /* Adjust buffer positions in reused rows. */
13563 increment_matrix_positions (current_matrix
,
13564 first_unchanged_at_end_vpos
+ dvpos
,
13565 bottom_vpos
, delta
, delta_bytes
);
13567 /* Adjust Y positions. */
13569 shift_glyph_matrix (w
, current_matrix
,
13570 first_unchanged_at_end_vpos
+ dvpos
,
13573 if (first_unchanged_at_end_row
)
13574 first_unchanged_at_end_row
+= dvpos
;
13576 /* If scrolling up, there may be some lines to display at the end of
13578 last_text_row_at_end
= NULL
;
13581 /* Scrolling up can leave for example a partially visible line
13582 at the end of the window to be redisplayed. */
13583 /* Set last_row to the glyph row in the current matrix where the
13584 window end line is found. It has been moved up or down in
13585 the matrix by dvpos. */
13586 int last_vpos
= XFASTINT (w
->window_end_vpos
) + dvpos
;
13587 struct glyph_row
*last_row
= MATRIX_ROW (current_matrix
, last_vpos
);
13589 /* If last_row is the window end line, it should display text. */
13590 xassert (last_row
->displays_text_p
);
13592 /* If window end line was partially visible before, begin
13593 displaying at that line. Otherwise begin displaying with the
13594 line following it. */
13595 if (MATRIX_ROW_BOTTOM_Y (last_row
) - dy
>= it
.last_visible_y
)
13597 init_to_row_start (&it
, w
, last_row
);
13598 it
.vpos
= last_vpos
;
13599 it
.current_y
= last_row
->y
;
13603 init_to_row_end (&it
, w
, last_row
);
13604 it
.vpos
= 1 + last_vpos
;
13605 it
.current_y
= MATRIX_ROW_BOTTOM_Y (last_row
);
13609 /* We may start in a continuation line. If so, we have to
13610 get the right continuation_lines_width and current_x. */
13611 it
.continuation_lines_width
= last_row
->continuation_lines_width
;
13612 it
.hpos
= it
.current_x
= 0;
13614 /* Display the rest of the lines at the window end. */
13615 it
.glyph_row
= MATRIX_ROW (desired_matrix
, it
.vpos
);
13616 while (it
.current_y
< it
.last_visible_y
13617 && !fonts_changed_p
)
13619 /* Is it always sure that the display agrees with lines in
13620 the current matrix? I don't think so, so we mark rows
13621 displayed invalid in the current matrix by setting their
13622 enabled_p flag to zero. */
13623 MATRIX_ROW (w
->current_matrix
, it
.vpos
)->enabled_p
= 0;
13624 if (display_line (&it
))
13625 last_text_row_at_end
= it
.glyph_row
- 1;
13629 /* Update window_end_pos and window_end_vpos. */
13630 if (first_unchanged_at_end_row
13631 && first_unchanged_at_end_row
->y
< it
.last_visible_y
13632 && !last_text_row_at_end
)
13634 /* Window end line if one of the preserved rows from the current
13635 matrix. Set row to the last row displaying text in current
13636 matrix starting at first_unchanged_at_end_row, after
13638 xassert (first_unchanged_at_end_row
->displays_text_p
);
13639 row
= find_last_row_displaying_text (w
->current_matrix
, &it
,
13640 first_unchanged_at_end_row
);
13641 xassert (row
&& MATRIX_ROW_DISPLAYS_TEXT_P (row
));
13643 w
->window_end_pos
= make_number (Z
- MATRIX_ROW_END_CHARPOS (row
));
13644 w
->window_end_bytepos
= Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
13646 = make_number (MATRIX_ROW_VPOS (row
, w
->current_matrix
));
13647 xassert (w
->window_end_bytepos
>= 0);
13648 IF_DEBUG (debug_method_add (w
, "A"));
13650 else if (last_text_row_at_end
)
13653 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row_at_end
));
13654 w
->window_end_bytepos
13655 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row_at_end
);
13657 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end
, desired_matrix
));
13658 xassert (w
->window_end_bytepos
>= 0);
13659 IF_DEBUG (debug_method_add (w
, "B"));
13661 else if (last_text_row
)
13663 /* We have displayed either to the end of the window or at the
13664 end of the window, i.e. the last row with text is to be found
13665 in the desired matrix. */
13667 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
13668 w
->window_end_bytepos
13669 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
13671 = make_number (MATRIX_ROW_VPOS (last_text_row
, desired_matrix
));
13672 xassert (w
->window_end_bytepos
>= 0);
13674 else if (first_unchanged_at_end_row
== NULL
13675 && last_text_row
== NULL
13676 && last_text_row_at_end
== NULL
)
13678 /* Displayed to end of window, but no line containing text was
13679 displayed. Lines were deleted at the end of the window. */
13680 int first_vpos
= WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0;
13681 int vpos
= XFASTINT (w
->window_end_vpos
);
13682 struct glyph_row
*current_row
= current_matrix
->rows
+ vpos
;
13683 struct glyph_row
*desired_row
= desired_matrix
->rows
+ vpos
;
13686 row
== NULL
&& vpos
>= first_vpos
;
13687 --vpos
, --current_row
, --desired_row
)
13689 if (desired_row
->enabled_p
)
13691 if (desired_row
->displays_text_p
)
13694 else if (current_row
->displays_text_p
)
13698 xassert (row
!= NULL
);
13699 w
->window_end_vpos
= make_number (vpos
+ 1);
13700 w
->window_end_pos
= make_number (Z
- MATRIX_ROW_END_CHARPOS (row
));
13701 w
->window_end_bytepos
= Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
13702 xassert (w
->window_end_bytepos
>= 0);
13703 IF_DEBUG (debug_method_add (w
, "C"));
13708 #if 0 /* This leads to problems, for instance when the cursor is
13709 at ZV, and the cursor line displays no text. */
13710 /* Disable rows below what's displayed in the window. This makes
13711 debugging easier. */
13712 enable_glyph_matrix_rows (current_matrix
,
13713 XFASTINT (w
->window_end_vpos
) + 1,
13717 IF_DEBUG (debug_end_pos
= XFASTINT (w
->window_end_pos
);
13718 debug_end_vpos
= XFASTINT (w
->window_end_vpos
));
13720 /* Record that display has not been completed. */
13721 w
->window_end_valid
= Qnil
;
13722 w
->desired_matrix
->no_scrolling_p
= 1;
13730 /***********************************************************************
13731 More debugging support
13732 ***********************************************************************/
13736 void dump_glyph_row
P_ ((struct glyph_row
*, int, int));
13737 void dump_glyph_matrix
P_ ((struct glyph_matrix
*, int));
13738 void dump_glyph
P_ ((struct glyph_row
*, struct glyph
*, int));
13741 /* Dump the contents of glyph matrix MATRIX on stderr.
13743 GLYPHS 0 means don't show glyph contents.
13744 GLYPHS 1 means show glyphs in short form
13745 GLYPHS > 1 means show glyphs in long form. */
13748 dump_glyph_matrix (matrix
, glyphs
)
13749 struct glyph_matrix
*matrix
;
13753 for (i
= 0; i
< matrix
->nrows
; ++i
)
13754 dump_glyph_row (MATRIX_ROW (matrix
, i
), i
, glyphs
);
13758 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
13759 the glyph row and area where the glyph comes from. */
13762 dump_glyph (row
, glyph
, area
)
13763 struct glyph_row
*row
;
13764 struct glyph
*glyph
;
13767 if (glyph
->type
== CHAR_GLYPH
)
13770 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13771 glyph
- row
->glyphs
[TEXT_AREA
],
13774 (BUFFERP (glyph
->object
)
13776 : (STRINGP (glyph
->object
)
13779 glyph
->pixel_width
,
13781 (glyph
->u
.ch
< 0x80 && glyph
->u
.ch
>= ' '
13785 glyph
->left_box_line_p
,
13786 glyph
->right_box_line_p
);
13788 else if (glyph
->type
== STRETCH_GLYPH
)
13791 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13792 glyph
- row
->glyphs
[TEXT_AREA
],
13795 (BUFFERP (glyph
->object
)
13797 : (STRINGP (glyph
->object
)
13800 glyph
->pixel_width
,
13804 glyph
->left_box_line_p
,
13805 glyph
->right_box_line_p
);
13807 else if (glyph
->type
== IMAGE_GLYPH
)
13810 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13811 glyph
- row
->glyphs
[TEXT_AREA
],
13814 (BUFFERP (glyph
->object
)
13816 : (STRINGP (glyph
->object
)
13819 glyph
->pixel_width
,
13823 glyph
->left_box_line_p
,
13824 glyph
->right_box_line_p
);
13829 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
13830 GLYPHS 0 means don't show glyph contents.
13831 GLYPHS 1 means show glyphs in short form
13832 GLYPHS > 1 means show glyphs in long form. */
13835 dump_glyph_row (row
, vpos
, glyphs
)
13836 struct glyph_row
*row
;
13841 fprintf (stderr
, "Row Start End Used oEI><O\\CTZFesm X Y W H V A P\n");
13842 fprintf (stderr
, "=======================================================================\n");
13844 fprintf (stderr
, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d%1.1d\
13845 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
13847 MATRIX_ROW_START_CHARPOS (row
),
13848 MATRIX_ROW_END_CHARPOS (row
),
13849 row
->used
[TEXT_AREA
],
13850 row
->contains_overlapping_glyphs_p
,
13852 row
->truncated_on_left_p
,
13853 row
->truncated_on_right_p
,
13854 row
->overlay_arrow_p
,
13856 MATRIX_ROW_CONTINUATION_LINE_P (row
),
13857 row
->displays_text_p
,
13860 row
->ends_in_middle_of_char_p
,
13861 row
->starts_in_middle_of_char_p
,
13867 row
->visible_height
,
13870 fprintf (stderr
, "%9d %5d\t%5d\n", row
->start
.overlay_string_index
,
13871 row
->end
.overlay_string_index
,
13872 row
->continuation_lines_width
);
13873 fprintf (stderr
, "%9d %5d\n",
13874 CHARPOS (row
->start
.string_pos
),
13875 CHARPOS (row
->end
.string_pos
));
13876 fprintf (stderr
, "%9d %5d\n", row
->start
.dpvec_index
,
13877 row
->end
.dpvec_index
);
13884 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
13886 struct glyph
*glyph
= row
->glyphs
[area
];
13887 struct glyph
*glyph_end
= glyph
+ row
->used
[area
];
13889 /* Glyph for a line end in text. */
13890 if (area
== TEXT_AREA
&& glyph
== glyph_end
&& glyph
->charpos
> 0)
13893 if (glyph
< glyph_end
)
13894 fprintf (stderr
, " Glyph Type Pos O W Code C Face LR\n");
13896 for (; glyph
< glyph_end
; ++glyph
)
13897 dump_glyph (row
, glyph
, area
);
13900 else if (glyphs
== 1)
13904 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
13906 char *s
= (char *) alloca (row
->used
[area
] + 1);
13909 for (i
= 0; i
< row
->used
[area
]; ++i
)
13911 struct glyph
*glyph
= row
->glyphs
[area
] + i
;
13912 if (glyph
->type
== CHAR_GLYPH
13913 && glyph
->u
.ch
< 0x80
13914 && glyph
->u
.ch
>= ' ')
13915 s
[i
] = glyph
->u
.ch
;
13921 fprintf (stderr
, "%3d: (%d) '%s'\n", vpos
, row
->enabled_p
, s
);
13927 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix
,
13928 Sdump_glyph_matrix
, 0, 1, "p",
13929 doc
: /* Dump the current matrix of the selected window to stderr.
13930 Shows contents of glyph row structures. With non-nil
13931 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
13932 glyphs in short form, otherwise show glyphs in long form. */)
13934 Lisp_Object glyphs
;
13936 struct window
*w
= XWINDOW (selected_window
);
13937 struct buffer
*buffer
= XBUFFER (w
->buffer
);
13939 fprintf (stderr
, "PT = %d, BEGV = %d. ZV = %d\n",
13940 BUF_PT (buffer
), BUF_BEGV (buffer
), BUF_ZV (buffer
));
13941 fprintf (stderr
, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
13942 w
->cursor
.x
, w
->cursor
.y
, w
->cursor
.hpos
, w
->cursor
.vpos
);
13943 fprintf (stderr
, "=============================================\n");
13944 dump_glyph_matrix (w
->current_matrix
,
13945 NILP (glyphs
) ? 0 : XINT (glyphs
));
13950 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix
,
13951 Sdump_frame_glyph_matrix
, 0, 0, "", doc
: /* */)
13954 struct frame
*f
= XFRAME (selected_frame
);
13955 dump_glyph_matrix (f
->current_matrix
, 1);
13960 DEFUN ("dump-glyph-row", Fdump_glyph_row
, Sdump_glyph_row
, 1, 2, "",
13961 doc
: /* Dump glyph row ROW to stderr.
13962 GLYPH 0 means don't dump glyphs.
13963 GLYPH 1 means dump glyphs in short form.
13964 GLYPH > 1 or omitted means dump glyphs in long form. */)
13966 Lisp_Object row
, glyphs
;
13968 struct glyph_matrix
*matrix
;
13971 CHECK_NUMBER (row
);
13972 matrix
= XWINDOW (selected_window
)->current_matrix
;
13974 if (vpos
>= 0 && vpos
< matrix
->nrows
)
13975 dump_glyph_row (MATRIX_ROW (matrix
, vpos
),
13977 INTEGERP (glyphs
) ? XINT (glyphs
) : 2);
13982 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row
, Sdump_tool_bar_row
, 1, 2, "",
13983 doc
: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
13984 GLYPH 0 means don't dump glyphs.
13985 GLYPH 1 means dump glyphs in short form.
13986 GLYPH > 1 or omitted means dump glyphs in long form. */)
13988 Lisp_Object row
, glyphs
;
13990 struct frame
*sf
= SELECTED_FRAME ();
13991 struct glyph_matrix
*m
= XWINDOW (sf
->tool_bar_window
)->current_matrix
;
13994 CHECK_NUMBER (row
);
13996 if (vpos
>= 0 && vpos
< m
->nrows
)
13997 dump_glyph_row (MATRIX_ROW (m
, vpos
), vpos
,
13998 INTEGERP (glyphs
) ? XINT (glyphs
) : 2);
14003 DEFUN ("trace-redisplay", Ftrace_redisplay
, Strace_redisplay
, 0, 1, "P",
14004 doc
: /* Toggle tracing of redisplay.
14005 With ARG, turn tracing on if and only if ARG is positive. */)
14010 trace_redisplay_p
= !trace_redisplay_p
;
14013 arg
= Fprefix_numeric_value (arg
);
14014 trace_redisplay_p
= XINT (arg
) > 0;
14021 DEFUN ("trace-to-stderr", Ftrace_to_stderr
, Strace_to_stderr
, 1, MANY
, "",
14022 doc
: /* Like `format', but print result to stderr.
14023 usage: (trace-to-stderr STRING &rest OBJECTS) */)
14028 Lisp_Object s
= Fformat (nargs
, args
);
14029 fprintf (stderr
, "%s", SDATA (s
));
14033 #endif /* GLYPH_DEBUG */
14037 /***********************************************************************
14038 Building Desired Matrix Rows
14039 ***********************************************************************/
14041 /* Return a temporary glyph row holding the glyphs of an overlay
14042 arrow. Only used for non-window-redisplay windows. */
14044 static struct glyph_row
*
14045 get_overlay_arrow_glyph_row (w
, overlay_arrow_string
)
14047 Lisp_Object overlay_arrow_string
;
14049 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
14050 struct buffer
*buffer
= XBUFFER (w
->buffer
);
14051 struct buffer
*old
= current_buffer
;
14052 const unsigned char *arrow_string
= SDATA (overlay_arrow_string
);
14053 int arrow_len
= SCHARS (overlay_arrow_string
);
14054 const unsigned char *arrow_end
= arrow_string
+ arrow_len
;
14055 const unsigned char *p
;
14058 int n_glyphs_before
;
14060 set_buffer_temp (buffer
);
14061 init_iterator (&it
, w
, -1, -1, &scratch_glyph_row
, DEFAULT_FACE_ID
);
14062 it
.glyph_row
->used
[TEXT_AREA
] = 0;
14063 SET_TEXT_POS (it
.position
, 0, 0);
14065 multibyte_p
= !NILP (buffer
->enable_multibyte_characters
);
14067 while (p
< arrow_end
)
14069 Lisp_Object face
, ilisp
;
14071 /* Get the next character. */
14073 it
.c
= string_char_and_length (p
, arrow_len
, &it
.len
);
14075 it
.c
= *p
, it
.len
= 1;
14078 /* Get its face. */
14079 ilisp
= make_number (p
- arrow_string
);
14080 face
= Fget_text_property (ilisp
, Qface
, overlay_arrow_string
);
14081 it
.face_id
= compute_char_face (f
, it
.c
, face
);
14083 /* Compute its width, get its glyphs. */
14084 n_glyphs_before
= it
.glyph_row
->used
[TEXT_AREA
];
14085 SET_TEXT_POS (it
.position
, -1, -1);
14086 PRODUCE_GLYPHS (&it
);
14088 /* If this character doesn't fit any more in the line, we have
14089 to remove some glyphs. */
14090 if (it
.current_x
> it
.last_visible_x
)
14092 it
.glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
;
14097 set_buffer_temp (old
);
14098 return it
.glyph_row
;
14102 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
14103 glyphs are only inserted for terminal frames since we can't really
14104 win with truncation glyphs when partially visible glyphs are
14105 involved. Which glyphs to insert is determined by
14106 produce_special_glyphs. */
14109 insert_left_trunc_glyphs (it
)
14112 struct it truncate_it
;
14113 struct glyph
*from
, *end
, *to
, *toend
;
14115 xassert (!FRAME_WINDOW_P (it
->f
));
14117 /* Get the truncation glyphs. */
14119 truncate_it
.current_x
= 0;
14120 truncate_it
.face_id
= DEFAULT_FACE_ID
;
14121 truncate_it
.glyph_row
= &scratch_glyph_row
;
14122 truncate_it
.glyph_row
->used
[TEXT_AREA
] = 0;
14123 CHARPOS (truncate_it
.position
) = BYTEPOS (truncate_it
.position
) = -1;
14124 truncate_it
.object
= make_number (0);
14125 produce_special_glyphs (&truncate_it
, IT_TRUNCATION
);
14127 /* Overwrite glyphs from IT with truncation glyphs. */
14128 from
= truncate_it
.glyph_row
->glyphs
[TEXT_AREA
];
14129 end
= from
+ truncate_it
.glyph_row
->used
[TEXT_AREA
];
14130 to
= it
->glyph_row
->glyphs
[TEXT_AREA
];
14131 toend
= to
+ it
->glyph_row
->used
[TEXT_AREA
];
14136 /* There may be padding glyphs left over. Overwrite them too. */
14137 while (to
< toend
&& CHAR_GLYPH_PADDING_P (*to
))
14139 from
= truncate_it
.glyph_row
->glyphs
[TEXT_AREA
];
14145 it
->glyph_row
->used
[TEXT_AREA
] = to
- it
->glyph_row
->glyphs
[TEXT_AREA
];
14149 /* Compute the pixel height and width of IT->glyph_row.
14151 Most of the time, ascent and height of a display line will be equal
14152 to the max_ascent and max_height values of the display iterator
14153 structure. This is not the case if
14155 1. We hit ZV without displaying anything. In this case, max_ascent
14156 and max_height will be zero.
14158 2. We have some glyphs that don't contribute to the line height.
14159 (The glyph row flag contributes_to_line_height_p is for future
14160 pixmap extensions).
14162 The first case is easily covered by using default values because in
14163 these cases, the line height does not really matter, except that it
14164 must not be zero. */
14167 compute_line_metrics (it
)
14170 struct glyph_row
*row
= it
->glyph_row
;
14173 if (FRAME_WINDOW_P (it
->f
))
14175 int i
, min_y
, max_y
;
14177 /* The line may consist of one space only, that was added to
14178 place the cursor on it. If so, the row's height hasn't been
14180 if (row
->height
== 0)
14182 if (it
->max_ascent
+ it
->max_descent
== 0)
14183 it
->max_descent
= it
->max_phys_descent
= FRAME_LINE_HEIGHT (it
->f
);
14184 row
->ascent
= it
->max_ascent
;
14185 row
->height
= it
->max_ascent
+ it
->max_descent
;
14186 row
->phys_ascent
= it
->max_phys_ascent
;
14187 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
14190 /* Compute the width of this line. */
14191 row
->pixel_width
= row
->x
;
14192 for (i
= 0; i
< row
->used
[TEXT_AREA
]; ++i
)
14193 row
->pixel_width
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
14195 xassert (row
->pixel_width
>= 0);
14196 xassert (row
->ascent
>= 0 && row
->height
> 0);
14198 row
->overlapping_p
= (MATRIX_ROW_OVERLAPS_SUCC_P (row
)
14199 || MATRIX_ROW_OVERLAPS_PRED_P (row
));
14201 /* If first line's physical ascent is larger than its logical
14202 ascent, use the physical ascent, and make the row taller.
14203 This makes accented characters fully visible. */
14204 if (row
== MATRIX_FIRST_TEXT_ROW (it
->w
->desired_matrix
)
14205 && row
->phys_ascent
> row
->ascent
)
14207 row
->height
+= row
->phys_ascent
- row
->ascent
;
14208 row
->ascent
= row
->phys_ascent
;
14211 /* Compute how much of the line is visible. */
14212 row
->visible_height
= row
->height
;
14214 min_y
= WINDOW_HEADER_LINE_HEIGHT (it
->w
);
14215 max_y
= WINDOW_BOX_HEIGHT_NO_MODE_LINE (it
->w
);
14217 if (row
->y
< min_y
)
14218 row
->visible_height
-= min_y
- row
->y
;
14219 if (row
->y
+ row
->height
> max_y
)
14220 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
14224 row
->pixel_width
= row
->used
[TEXT_AREA
];
14225 if (row
->continued_p
)
14226 row
->pixel_width
-= it
->continuation_pixel_width
;
14227 else if (row
->truncated_on_right_p
)
14228 row
->pixel_width
-= it
->truncation_pixel_width
;
14229 row
->ascent
= row
->phys_ascent
= 0;
14230 row
->height
= row
->phys_height
= row
->visible_height
= 1;
14233 /* Compute a hash code for this row. */
14235 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
14236 for (i
= 0; i
< row
->used
[area
]; ++i
)
14237 row
->hash
= ((((row
->hash
<< 4) + (row
->hash
>> 24)) & 0x0fffffff)
14238 + row
->glyphs
[area
][i
].u
.val
14239 + row
->glyphs
[area
][i
].face_id
14240 + row
->glyphs
[area
][i
].padding_p
14241 + (row
->glyphs
[area
][i
].type
<< 2));
14243 it
->max_ascent
= it
->max_descent
= 0;
14244 it
->max_phys_ascent
= it
->max_phys_descent
= 0;
14248 /* Append one space to the glyph row of iterator IT if doing a
14249 window-based redisplay. The space has the same face as
14250 IT->face_id. Value is non-zero if a space was added.
14252 This function is called to make sure that there is always one glyph
14253 at the end of a glyph row that the cursor can be set on under
14254 window-systems. (If there weren't such a glyph we would not know
14255 how wide and tall a box cursor should be displayed).
14257 At the same time this space let's a nicely handle clearing to the
14258 end of the line if the row ends in italic text. */
14261 append_space_for_newline (it
, default_face_p
)
14263 int default_face_p
;
14265 if (FRAME_WINDOW_P (it
->f
))
14267 int n
= it
->glyph_row
->used
[TEXT_AREA
];
14269 if (it
->glyph_row
->glyphs
[TEXT_AREA
] + n
14270 < it
->glyph_row
->glyphs
[1 + TEXT_AREA
])
14272 /* Save some values that must not be changed.
14273 Must save IT->c and IT->len because otherwise
14274 ITERATOR_AT_END_P wouldn't work anymore after
14275 append_space_for_newline has been called. */
14276 enum display_element_type saved_what
= it
->what
;
14277 int saved_c
= it
->c
, saved_len
= it
->len
;
14278 int saved_x
= it
->current_x
;
14279 int saved_face_id
= it
->face_id
;
14280 struct text_pos saved_pos
;
14281 Lisp_Object saved_object
;
14284 saved_object
= it
->object
;
14285 saved_pos
= it
->position
;
14287 it
->what
= IT_CHARACTER
;
14288 bzero (&it
->position
, sizeof it
->position
);
14289 it
->object
= make_number (0);
14293 if (default_face_p
)
14294 it
->face_id
= DEFAULT_FACE_ID
;
14295 else if (it
->face_before_selective_p
)
14296 it
->face_id
= it
->saved_face_id
;
14297 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
14298 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, 0);
14300 PRODUCE_GLYPHS (it
);
14302 it
->override_ascent
= -1;
14303 it
->constrain_row_ascent_descent_p
= 0;
14304 it
->current_x
= saved_x
;
14305 it
->object
= saved_object
;
14306 it
->position
= saved_pos
;
14307 it
->what
= saved_what
;
14308 it
->face_id
= saved_face_id
;
14309 it
->len
= saved_len
;
14319 /* Extend the face of the last glyph in the text area of IT->glyph_row
14320 to the end of the display line. Called from display_line.
14321 If the glyph row is empty, add a space glyph to it so that we
14322 know the face to draw. Set the glyph row flag fill_line_p. */
14325 extend_face_to_end_of_line (it
)
14329 struct frame
*f
= it
->f
;
14331 /* If line is already filled, do nothing. */
14332 if (it
->current_x
>= it
->last_visible_x
)
14335 /* Face extension extends the background and box of IT->face_id
14336 to the end of the line. If the background equals the background
14337 of the frame, we don't have to do anything. */
14338 if (it
->face_before_selective_p
)
14339 face
= FACE_FROM_ID (it
->f
, it
->saved_face_id
);
14341 face
= FACE_FROM_ID (f
, it
->face_id
);
14343 if (FRAME_WINDOW_P (f
)
14344 && face
->box
== FACE_NO_BOX
14345 && face
->background
== FRAME_BACKGROUND_PIXEL (f
)
14349 /* Set the glyph row flag indicating that the face of the last glyph
14350 in the text area has to be drawn to the end of the text area. */
14351 it
->glyph_row
->fill_line_p
= 1;
14353 /* If current character of IT is not ASCII, make sure we have the
14354 ASCII face. This will be automatically undone the next time
14355 get_next_display_element returns a multibyte character. Note
14356 that the character will always be single byte in unibyte text. */
14357 if (!SINGLE_BYTE_CHAR_P (it
->c
))
14359 it
->face_id
= FACE_FOR_CHAR (f
, face
, 0);
14362 if (FRAME_WINDOW_P (f
))
14364 /* If the row is empty, add a space with the current face of IT,
14365 so that we know which face to draw. */
14366 if (it
->glyph_row
->used
[TEXT_AREA
] == 0)
14368 it
->glyph_row
->glyphs
[TEXT_AREA
][0] = space_glyph
;
14369 it
->glyph_row
->glyphs
[TEXT_AREA
][0].face_id
= it
->face_id
;
14370 it
->glyph_row
->used
[TEXT_AREA
] = 1;
14375 /* Save some values that must not be changed. */
14376 int saved_x
= it
->current_x
;
14377 struct text_pos saved_pos
;
14378 Lisp_Object saved_object
;
14379 enum display_element_type saved_what
= it
->what
;
14380 int saved_face_id
= it
->face_id
;
14382 saved_object
= it
->object
;
14383 saved_pos
= it
->position
;
14385 it
->what
= IT_CHARACTER
;
14386 bzero (&it
->position
, sizeof it
->position
);
14387 it
->object
= make_number (0);
14390 it
->face_id
= face
->id
;
14392 PRODUCE_GLYPHS (it
);
14394 while (it
->current_x
<= it
->last_visible_x
)
14395 PRODUCE_GLYPHS (it
);
14397 /* Don't count these blanks really. It would let us insert a left
14398 truncation glyph below and make us set the cursor on them, maybe. */
14399 it
->current_x
= saved_x
;
14400 it
->object
= saved_object
;
14401 it
->position
= saved_pos
;
14402 it
->what
= saved_what
;
14403 it
->face_id
= saved_face_id
;
14408 /* Value is non-zero if text starting at CHARPOS in current_buffer is
14409 trailing whitespace. */
14412 trailing_whitespace_p (charpos
)
14415 int bytepos
= CHAR_TO_BYTE (charpos
);
14418 while (bytepos
< ZV_BYTE
14419 && (c
= FETCH_CHAR (bytepos
),
14420 c
== ' ' || c
== '\t'))
14423 if (bytepos
>= ZV_BYTE
|| c
== '\n' || c
== '\r')
14425 if (bytepos
!= PT_BYTE
)
14432 /* Highlight trailing whitespace, if any, in ROW. */
14435 highlight_trailing_whitespace (f
, row
)
14437 struct glyph_row
*row
;
14439 int used
= row
->used
[TEXT_AREA
];
14443 struct glyph
*start
= row
->glyphs
[TEXT_AREA
];
14444 struct glyph
*glyph
= start
+ used
- 1;
14446 /* Skip over glyphs inserted to display the cursor at the
14447 end of a line, for extending the face of the last glyph
14448 to the end of the line on terminals, and for truncation
14449 and continuation glyphs. */
14450 while (glyph
>= start
14451 && glyph
->type
== CHAR_GLYPH
14452 && INTEGERP (glyph
->object
))
14455 /* If last glyph is a space or stretch, and it's trailing
14456 whitespace, set the face of all trailing whitespace glyphs in
14457 IT->glyph_row to `trailing-whitespace'. */
14459 && BUFFERP (glyph
->object
)
14460 && (glyph
->type
== STRETCH_GLYPH
14461 || (glyph
->type
== CHAR_GLYPH
14462 && glyph
->u
.ch
== ' '))
14463 && trailing_whitespace_p (glyph
->charpos
))
14465 int face_id
= lookup_named_face (f
, Qtrailing_whitespace
, 0);
14467 while (glyph
>= start
14468 && BUFFERP (glyph
->object
)
14469 && (glyph
->type
== STRETCH_GLYPH
14470 || (glyph
->type
== CHAR_GLYPH
14471 && glyph
->u
.ch
== ' ')))
14472 (glyph
--)->face_id
= face_id
;
14478 /* Value is non-zero if glyph row ROW in window W should be
14479 used to hold the cursor. */
14482 cursor_row_p (w
, row
)
14484 struct glyph_row
*row
;
14486 int cursor_row_p
= 1;
14488 if (PT
== MATRIX_ROW_END_CHARPOS (row
))
14490 /* If the row ends with a newline from a string, we don't want
14491 the cursor there (if the row is continued it doesn't end in a
14493 if (CHARPOS (row
->end
.string_pos
) >= 0
14494 || MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
))
14495 cursor_row_p
= row
->continued_p
;
14497 /* If the row ends at ZV, display the cursor at the end of that
14498 row instead of at the start of the row below. */
14499 else if (row
->ends_at_zv_p
)
14505 return cursor_row_p
;
14509 /* Construct the glyph row IT->glyph_row in the desired matrix of
14510 IT->w from text at the current position of IT. See dispextern.h
14511 for an overview of struct it. Value is non-zero if
14512 IT->glyph_row displays text, as opposed to a line displaying ZV
14519 struct glyph_row
*row
= it
->glyph_row
;
14520 int overlay_arrow_bitmap
;
14521 Lisp_Object overlay_arrow_string
;
14523 /* We always start displaying at hpos zero even if hscrolled. */
14524 xassert (it
->hpos
== 0 && it
->current_x
== 0);
14526 if (MATRIX_ROW_VPOS (row
, it
->w
->desired_matrix
)
14527 >= it
->w
->desired_matrix
->nrows
)
14529 it
->w
->nrows_scale_factor
++;
14530 fonts_changed_p
= 1;
14534 /* Is IT->w showing the region? */
14535 it
->w
->region_showing
= it
->region_beg_charpos
> 0 ? Qt
: Qnil
;
14537 /* Clear the result glyph row and enable it. */
14538 prepare_desired_row (row
);
14540 row
->y
= it
->current_y
;
14541 row
->start
= it
->start
;
14542 row
->continuation_lines_width
= it
->continuation_lines_width
;
14543 row
->displays_text_p
= 1;
14544 row
->starts_in_middle_of_char_p
= it
->starts_in_middle_of_char_p
;
14545 it
->starts_in_middle_of_char_p
= 0;
14547 /* Arrange the overlays nicely for our purposes. Usually, we call
14548 display_line on only one line at a time, in which case this
14549 can't really hurt too much, or we call it on lines which appear
14550 one after another in the buffer, in which case all calls to
14551 recenter_overlay_lists but the first will be pretty cheap. */
14552 recenter_overlay_lists (current_buffer
, IT_CHARPOS (*it
));
14554 /* Move over display elements that are not visible because we are
14555 hscrolled. This may stop at an x-position < IT->first_visible_x
14556 if the first glyph is partially visible or if we hit a line end. */
14557 if (it
->current_x
< it
->first_visible_x
)
14558 move_it_in_display_line_to (it
, ZV
, it
->first_visible_x
,
14559 MOVE_TO_POS
| MOVE_TO_X
);
14561 /* Get the initial row height. This is either the height of the
14562 text hscrolled, if there is any, or zero. */
14563 row
->ascent
= it
->max_ascent
;
14564 row
->height
= it
->max_ascent
+ it
->max_descent
;
14565 row
->phys_ascent
= it
->max_phys_ascent
;
14566 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
14568 /* Loop generating characters. The loop is left with IT on the next
14569 character to display. */
14572 int n_glyphs_before
, hpos_before
, x_before
;
14574 int ascent
= 0, descent
= 0, phys_ascent
= 0, phys_descent
= 0;
14576 /* Retrieve the next thing to display. Value is zero if end of
14578 if (!get_next_display_element (it
))
14580 /* Maybe add a space at the end of this line that is used to
14581 display the cursor there under X. Set the charpos of the
14582 first glyph of blank lines not corresponding to any text
14584 #ifdef HAVE_WINDOW_SYSTEM
14585 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
14586 row
->exact_window_width_line_p
= 1;
14588 #endif /* HAVE_WINDOW_SYSTEM */
14589 if ((append_space_for_newline (it
, 1) && row
->used
[TEXT_AREA
] == 1)
14590 || row
->used
[TEXT_AREA
] == 0)
14592 row
->glyphs
[TEXT_AREA
]->charpos
= -1;
14593 row
->displays_text_p
= 0;
14595 if (!NILP (XBUFFER (it
->w
->buffer
)->indicate_empty_lines
)
14596 && (!MINI_WINDOW_P (it
->w
)
14597 || (minibuf_level
&& EQ (it
->window
, minibuf_window
))))
14598 row
->indicate_empty_line_p
= 1;
14601 it
->continuation_lines_width
= 0;
14602 row
->ends_at_zv_p
= 1;
14606 /* Now, get the metrics of what we want to display. This also
14607 generates glyphs in `row' (which is IT->glyph_row). */
14608 n_glyphs_before
= row
->used
[TEXT_AREA
];
14611 /* Remember the line height so far in case the next element doesn't
14612 fit on the line. */
14613 if (!it
->truncate_lines_p
)
14615 ascent
= it
->max_ascent
;
14616 descent
= it
->max_descent
;
14617 phys_ascent
= it
->max_phys_ascent
;
14618 phys_descent
= it
->max_phys_descent
;
14621 PRODUCE_GLYPHS (it
);
14623 /* If this display element was in marginal areas, continue with
14625 if (it
->area
!= TEXT_AREA
)
14627 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
14628 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
14629 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
14630 row
->phys_height
= max (row
->phys_height
,
14631 it
->max_phys_ascent
+ it
->max_phys_descent
);
14632 set_iterator_to_next (it
, 1);
14636 /* Does the display element fit on the line? If we truncate
14637 lines, we should draw past the right edge of the window. If
14638 we don't truncate, we want to stop so that we can display the
14639 continuation glyph before the right margin. If lines are
14640 continued, there are two possible strategies for characters
14641 resulting in more than 1 glyph (e.g. tabs): Display as many
14642 glyphs as possible in this line and leave the rest for the
14643 continuation line, or display the whole element in the next
14644 line. Original redisplay did the former, so we do it also. */
14645 nglyphs
= row
->used
[TEXT_AREA
] - n_glyphs_before
;
14646 hpos_before
= it
->hpos
;
14649 if (/* Not a newline. */
14651 /* Glyphs produced fit entirely in the line. */
14652 && it
->current_x
< it
->last_visible_x
)
14654 it
->hpos
+= nglyphs
;
14655 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
14656 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
14657 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
14658 row
->phys_height
= max (row
->phys_height
,
14659 it
->max_phys_ascent
+ it
->max_phys_descent
);
14660 if (it
->current_x
- it
->pixel_width
< it
->first_visible_x
)
14661 row
->x
= x
- it
->first_visible_x
;
14666 struct glyph
*glyph
;
14668 for (i
= 0; i
< nglyphs
; ++i
, x
= new_x
)
14670 glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
14671 new_x
= x
+ glyph
->pixel_width
;
14673 if (/* Lines are continued. */
14674 !it
->truncate_lines_p
14675 && (/* Glyph doesn't fit on the line. */
14676 new_x
> it
->last_visible_x
14677 /* Or it fits exactly on a window system frame. */
14678 || (new_x
== it
->last_visible_x
14679 && FRAME_WINDOW_P (it
->f
))))
14681 /* End of a continued line. */
14684 || (new_x
== it
->last_visible_x
14685 && FRAME_WINDOW_P (it
->f
)))
14687 /* Current glyph is the only one on the line or
14688 fits exactly on the line. We must continue
14689 the line because we can't draw the cursor
14690 after the glyph. */
14691 row
->continued_p
= 1;
14692 it
->current_x
= new_x
;
14693 it
->continuation_lines_width
+= new_x
;
14695 if (i
== nglyphs
- 1)
14697 set_iterator_to_next (it
, 1);
14698 #ifdef HAVE_WINDOW_SYSTEM
14699 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
14701 if (!get_next_display_element (it
))
14703 row
->exact_window_width_line_p
= 1;
14704 it
->continuation_lines_width
= 0;
14705 row
->continued_p
= 0;
14706 row
->ends_at_zv_p
= 1;
14708 else if (ITERATOR_AT_END_OF_LINE_P (it
))
14710 row
->continued_p
= 0;
14711 row
->exact_window_width_line_p
= 1;
14714 #endif /* HAVE_WINDOW_SYSTEM */
14717 else if (CHAR_GLYPH_PADDING_P (*glyph
)
14718 && !FRAME_WINDOW_P (it
->f
))
14720 /* A padding glyph that doesn't fit on this line.
14721 This means the whole character doesn't fit
14723 row
->used
[TEXT_AREA
] = n_glyphs_before
;
14725 /* Fill the rest of the row with continuation
14726 glyphs like in 20.x. */
14727 while (row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
]
14728 < row
->glyphs
[1 + TEXT_AREA
])
14729 produce_special_glyphs (it
, IT_CONTINUATION
);
14731 row
->continued_p
= 1;
14732 it
->current_x
= x_before
;
14733 it
->continuation_lines_width
+= x_before
;
14735 /* Restore the height to what it was before the
14736 element not fitting on the line. */
14737 it
->max_ascent
= ascent
;
14738 it
->max_descent
= descent
;
14739 it
->max_phys_ascent
= phys_ascent
;
14740 it
->max_phys_descent
= phys_descent
;
14742 else if (it
->c
== '\t' && FRAME_WINDOW_P (it
->f
))
14744 /* A TAB that extends past the right edge of the
14745 window. This produces a single glyph on
14746 window system frames. We leave the glyph in
14747 this row and let it fill the row, but don't
14748 consume the TAB. */
14749 it
->continuation_lines_width
+= it
->last_visible_x
;
14750 row
->ends_in_middle_of_char_p
= 1;
14751 row
->continued_p
= 1;
14752 glyph
->pixel_width
= it
->last_visible_x
- x
;
14753 it
->starts_in_middle_of_char_p
= 1;
14757 /* Something other than a TAB that draws past
14758 the right edge of the window. Restore
14759 positions to values before the element. */
14760 row
->used
[TEXT_AREA
] = n_glyphs_before
+ i
;
14762 /* Display continuation glyphs. */
14763 if (!FRAME_WINDOW_P (it
->f
))
14764 produce_special_glyphs (it
, IT_CONTINUATION
);
14765 row
->continued_p
= 1;
14767 it
->continuation_lines_width
+= x
;
14769 if (nglyphs
> 1 && i
> 0)
14771 row
->ends_in_middle_of_char_p
= 1;
14772 it
->starts_in_middle_of_char_p
= 1;
14775 /* Restore the height to what it was before the
14776 element not fitting on the line. */
14777 it
->max_ascent
= ascent
;
14778 it
->max_descent
= descent
;
14779 it
->max_phys_ascent
= phys_ascent
;
14780 it
->max_phys_descent
= phys_descent
;
14785 else if (new_x
> it
->first_visible_x
)
14787 /* Increment number of glyphs actually displayed. */
14790 if (x
< it
->first_visible_x
)
14791 /* Glyph is partially visible, i.e. row starts at
14792 negative X position. */
14793 row
->x
= x
- it
->first_visible_x
;
14797 /* Glyph is completely off the left margin of the
14798 window. This should not happen because of the
14799 move_it_in_display_line at the start of this
14800 function, unless the text display area of the
14801 window is empty. */
14802 xassert (it
->first_visible_x
<= it
->last_visible_x
);
14806 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
14807 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
14808 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
14809 row
->phys_height
= max (row
->phys_height
,
14810 it
->max_phys_ascent
+ it
->max_phys_descent
);
14812 /* End of this display line if row is continued. */
14813 if (row
->continued_p
|| row
->ends_at_zv_p
)
14818 /* Is this a line end? If yes, we're also done, after making
14819 sure that a non-default face is extended up to the right
14820 margin of the window. */
14821 if (ITERATOR_AT_END_OF_LINE_P (it
))
14823 int used_before
= row
->used
[TEXT_AREA
];
14825 row
->ends_in_newline_from_string_p
= STRINGP (it
->object
);
14827 #ifdef HAVE_WINDOW_SYSTEM
14828 /* Add a space at the end of the line that is used to
14829 display the cursor there. */
14830 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
14831 append_space_for_newline (it
, 0);
14832 #endif /* HAVE_WINDOW_SYSTEM */
14834 /* Extend the face to the end of the line. */
14835 extend_face_to_end_of_line (it
);
14837 /* Make sure we have the position. */
14838 if (used_before
== 0)
14839 row
->glyphs
[TEXT_AREA
]->charpos
= CHARPOS (it
->position
);
14841 /* Consume the line end. This skips over invisible lines. */
14842 set_iterator_to_next (it
, 1);
14843 it
->continuation_lines_width
= 0;
14847 /* Proceed with next display element. Note that this skips
14848 over lines invisible because of selective display. */
14849 set_iterator_to_next (it
, 1);
14851 /* If we truncate lines, we are done when the last displayed
14852 glyphs reach past the right margin of the window. */
14853 if (it
->truncate_lines_p
14854 && (FRAME_WINDOW_P (it
->f
)
14855 ? (it
->current_x
>= it
->last_visible_x
)
14856 : (it
->current_x
> it
->last_visible_x
)))
14858 /* Maybe add truncation glyphs. */
14859 if (!FRAME_WINDOW_P (it
->f
))
14863 for (i
= row
->used
[TEXT_AREA
] - 1; i
> 0; --i
)
14864 if (!CHAR_GLYPH_PADDING_P (row
->glyphs
[TEXT_AREA
][i
]))
14867 for (n
= row
->used
[TEXT_AREA
]; i
< n
; ++i
)
14869 row
->used
[TEXT_AREA
] = i
;
14870 produce_special_glyphs (it
, IT_TRUNCATION
);
14873 #ifdef HAVE_WINDOW_SYSTEM
14876 /* Don't truncate if we can overflow newline into fringe. */
14877 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
14879 if (!get_next_display_element (it
))
14881 #ifdef HAVE_WINDOW_SYSTEM
14882 it
->continuation_lines_width
= 0;
14883 row
->ends_at_zv_p
= 1;
14884 row
->exact_window_width_line_p
= 1;
14886 #endif /* HAVE_WINDOW_SYSTEM */
14888 if (ITERATOR_AT_END_OF_LINE_P (it
))
14890 row
->exact_window_width_line_p
= 1;
14891 goto at_end_of_line
;
14895 #endif /* HAVE_WINDOW_SYSTEM */
14897 row
->truncated_on_right_p
= 1;
14898 it
->continuation_lines_width
= 0;
14899 reseat_at_next_visible_line_start (it
, 0);
14900 row
->ends_at_zv_p
= FETCH_BYTE (IT_BYTEPOS (*it
) - 1) != '\n';
14901 it
->hpos
= hpos_before
;
14902 it
->current_x
= x_before
;
14907 /* If line is not empty and hscrolled, maybe insert truncation glyphs
14908 at the left window margin. */
14909 if (it
->first_visible_x
14910 && IT_CHARPOS (*it
) != MATRIX_ROW_START_CHARPOS (row
))
14912 if (!FRAME_WINDOW_P (it
->f
))
14913 insert_left_trunc_glyphs (it
);
14914 row
->truncated_on_left_p
= 1;
14917 /* If the start of this line is the overlay arrow-position, then
14918 mark this glyph row as the one containing the overlay arrow.
14919 This is clearly a mess with variable size fonts. It would be
14920 better to let it be displayed like cursors under X. */
14921 if (! overlay_arrow_seen
14922 && (overlay_arrow_string
14923 = overlay_arrow_at_row (it
->f
, row
, &overlay_arrow_bitmap
),
14924 !NILP (overlay_arrow_string
)))
14926 /* Overlay arrow in window redisplay is a fringe bitmap. */
14927 if (!FRAME_WINDOW_P (it
->f
))
14929 struct glyph_row
*arrow_row
14930 = get_overlay_arrow_glyph_row (it
->w
, overlay_arrow_string
);
14931 struct glyph
*glyph
= arrow_row
->glyphs
[TEXT_AREA
];
14932 struct glyph
*arrow_end
= glyph
+ arrow_row
->used
[TEXT_AREA
];
14933 struct glyph
*p
= row
->glyphs
[TEXT_AREA
];
14934 struct glyph
*p2
, *end
;
14936 /* Copy the arrow glyphs. */
14937 while (glyph
< arrow_end
)
14940 /* Throw away padding glyphs. */
14942 end
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
];
14943 while (p2
< end
&& CHAR_GLYPH_PADDING_P (*p2
))
14949 row
->used
[TEXT_AREA
] = p2
- row
->glyphs
[TEXT_AREA
];
14953 overlay_arrow_seen
= 1;
14954 it
->w
->overlay_arrow_bitmap
= overlay_arrow_bitmap
;
14955 row
->overlay_arrow_p
= 1;
14958 /* Compute pixel dimensions of this line. */
14959 compute_line_metrics (it
);
14961 /* Remember the position at which this line ends. */
14962 row
->end
= it
->current
;
14964 /* Save fringe bitmaps in this row. */
14965 row
->left_user_fringe_bitmap
= it
->left_user_fringe_bitmap
;
14966 row
->left_user_fringe_face_id
= it
->left_user_fringe_face_id
;
14967 row
->right_user_fringe_bitmap
= it
->right_user_fringe_bitmap
;
14968 row
->right_user_fringe_face_id
= it
->right_user_fringe_face_id
;
14970 it
->left_user_fringe_bitmap
= 0;
14971 it
->left_user_fringe_face_id
= 0;
14972 it
->right_user_fringe_bitmap
= 0;
14973 it
->right_user_fringe_face_id
= 0;
14975 /* Maybe set the cursor. */
14976 if (it
->w
->cursor
.vpos
< 0
14977 && PT
>= MATRIX_ROW_START_CHARPOS (row
)
14978 && PT
<= MATRIX_ROW_END_CHARPOS (row
)
14979 && cursor_row_p (it
->w
, row
))
14980 set_cursor_from_row (it
->w
, row
, it
->w
->desired_matrix
, 0, 0, 0, 0);
14982 /* Highlight trailing whitespace. */
14983 if (!NILP (Vshow_trailing_whitespace
))
14984 highlight_trailing_whitespace (it
->f
, it
->glyph_row
);
14986 /* Prepare for the next line. This line starts horizontally at (X
14987 HPOS) = (0 0). Vertical positions are incremented. As a
14988 convenience for the caller, IT->glyph_row is set to the next
14990 it
->current_x
= it
->hpos
= 0;
14991 it
->current_y
+= row
->height
;
14994 it
->start
= it
->current
;
14995 return row
->displays_text_p
;
15000 /***********************************************************************
15002 ***********************************************************************/
15004 /* Redisplay the menu bar in the frame for window W.
15006 The menu bar of X frames that don't have X toolkit support is
15007 displayed in a special window W->frame->menu_bar_window.
15009 The menu bar of terminal frames is treated specially as far as
15010 glyph matrices are concerned. Menu bar lines are not part of
15011 windows, so the update is done directly on the frame matrix rows
15012 for the menu bar. */
15015 display_menu_bar (w
)
15018 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
15023 /* Don't do all this for graphical frames. */
15025 if (!NILP (Vwindow_system
))
15028 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
15033 if (FRAME_MAC_P (f
))
15037 #ifdef USE_X_TOOLKIT
15038 xassert (!FRAME_WINDOW_P (f
));
15039 init_iterator (&it
, w
, -1, -1, f
->desired_matrix
->rows
, MENU_FACE_ID
);
15040 it
.first_visible_x
= 0;
15041 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
15042 #else /* not USE_X_TOOLKIT */
15043 if (FRAME_WINDOW_P (f
))
15045 /* Menu bar lines are displayed in the desired matrix of the
15046 dummy window menu_bar_window. */
15047 struct window
*menu_w
;
15048 xassert (WINDOWP (f
->menu_bar_window
));
15049 menu_w
= XWINDOW (f
->menu_bar_window
);
15050 init_iterator (&it
, menu_w
, -1, -1, menu_w
->desired_matrix
->rows
,
15052 it
.first_visible_x
= 0;
15053 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
15057 /* This is a TTY frame, i.e. character hpos/vpos are used as
15059 init_iterator (&it
, w
, -1, -1, f
->desired_matrix
->rows
,
15061 it
.first_visible_x
= 0;
15062 it
.last_visible_x
= FRAME_COLS (f
);
15064 #endif /* not USE_X_TOOLKIT */
15066 if (! mode_line_inverse_video
)
15067 /* Force the menu-bar to be displayed in the default face. */
15068 it
.base_face_id
= it
.face_id
= DEFAULT_FACE_ID
;
15070 /* Clear all rows of the menu bar. */
15071 for (i
= 0; i
< FRAME_MENU_BAR_LINES (f
); ++i
)
15073 struct glyph_row
*row
= it
.glyph_row
+ i
;
15074 clear_glyph_row (row
);
15075 row
->enabled_p
= 1;
15076 row
->full_width_p
= 1;
15079 /* Display all items of the menu bar. */
15080 items
= FRAME_MENU_BAR_ITEMS (it
.f
);
15081 for (i
= 0; i
< XVECTOR (items
)->size
; i
+= 4)
15083 Lisp_Object string
;
15085 /* Stop at nil string. */
15086 string
= AREF (items
, i
+ 1);
15090 /* Remember where item was displayed. */
15091 AREF (items
, i
+ 3) = make_number (it
.hpos
);
15093 /* Display the item, pad with one space. */
15094 if (it
.current_x
< it
.last_visible_x
)
15095 display_string (NULL
, string
, Qnil
, 0, 0, &it
,
15096 SCHARS (string
) + 1, 0, 0, -1);
15099 /* Fill out the line with spaces. */
15100 if (it
.current_x
< it
.last_visible_x
)
15101 display_string ("", Qnil
, Qnil
, 0, 0, &it
, -1, 0, 0, -1);
15103 /* Compute the total height of the lines. */
15104 compute_line_metrics (&it
);
15109 /***********************************************************************
15111 ***********************************************************************/
15113 /* Redisplay mode lines in the window tree whose root is WINDOW. If
15114 FORCE is non-zero, redisplay mode lines unconditionally.
15115 Otherwise, redisplay only mode lines that are garbaged. Value is
15116 the number of windows whose mode lines were redisplayed. */
15119 redisplay_mode_lines (window
, force
)
15120 Lisp_Object window
;
15125 while (!NILP (window
))
15127 struct window
*w
= XWINDOW (window
);
15129 if (WINDOWP (w
->hchild
))
15130 nwindows
+= redisplay_mode_lines (w
->hchild
, force
);
15131 else if (WINDOWP (w
->vchild
))
15132 nwindows
+= redisplay_mode_lines (w
->vchild
, force
);
15134 || FRAME_GARBAGED_P (XFRAME (w
->frame
))
15135 || !MATRIX_MODE_LINE_ROW (w
->current_matrix
)->enabled_p
)
15137 struct text_pos lpoint
;
15138 struct buffer
*old
= current_buffer
;
15140 /* Set the window's buffer for the mode line display. */
15141 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
15142 set_buffer_internal_1 (XBUFFER (w
->buffer
));
15144 /* Point refers normally to the selected window. For any
15145 other window, set up appropriate value. */
15146 if (!EQ (window
, selected_window
))
15148 struct text_pos pt
;
15150 SET_TEXT_POS_FROM_MARKER (pt
, w
->pointm
);
15151 if (CHARPOS (pt
) < BEGV
)
15152 TEMP_SET_PT_BOTH (BEGV
, BEGV_BYTE
);
15153 else if (CHARPOS (pt
) > (ZV
- 1))
15154 TEMP_SET_PT_BOTH (ZV
, ZV_BYTE
);
15156 TEMP_SET_PT_BOTH (CHARPOS (pt
), BYTEPOS (pt
));
15159 /* Display mode lines. */
15160 clear_glyph_matrix (w
->desired_matrix
);
15161 if (display_mode_lines (w
))
15164 w
->must_be_updated_p
= 1;
15167 /* Restore old settings. */
15168 set_buffer_internal_1 (old
);
15169 TEMP_SET_PT_BOTH (CHARPOS (lpoint
), BYTEPOS (lpoint
));
15179 /* Display the mode and/or top line of window W. Value is the number
15180 of mode lines displayed. */
15183 display_mode_lines (w
)
15186 Lisp_Object old_selected_window
, old_selected_frame
;
15189 old_selected_frame
= selected_frame
;
15190 selected_frame
= w
->frame
;
15191 old_selected_window
= selected_window
;
15192 XSETWINDOW (selected_window
, w
);
15194 /* These will be set while the mode line specs are processed. */
15195 line_number_displayed
= 0;
15196 w
->column_number_displayed
= Qnil
;
15198 if (WINDOW_WANTS_MODELINE_P (w
))
15200 struct window
*sel_w
= XWINDOW (old_selected_window
);
15202 /* Select mode line face based on the real selected window. */
15203 display_mode_line (w
, CURRENT_MODE_LINE_FACE_ID_3 (sel_w
, sel_w
, w
),
15204 current_buffer
->mode_line_format
);
15208 if (WINDOW_WANTS_HEADER_LINE_P (w
))
15210 display_mode_line (w
, HEADER_LINE_FACE_ID
,
15211 current_buffer
->header_line_format
);
15215 selected_frame
= old_selected_frame
;
15216 selected_window
= old_selected_window
;
15221 /* Display mode or top line of window W. FACE_ID specifies which line
15222 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
15223 FORMAT is the mode line format to display. Value is the pixel
15224 height of the mode line displayed. */
15227 display_mode_line (w
, face_id
, format
)
15229 enum face_id face_id
;
15230 Lisp_Object format
;
15235 init_iterator (&it
, w
, -1, -1, NULL
, face_id
);
15236 prepare_desired_row (it
.glyph_row
);
15238 it
.glyph_row
->mode_line_p
= 1;
15240 if (! mode_line_inverse_video
)
15241 /* Force the mode-line to be displayed in the default face. */
15242 it
.base_face_id
= it
.face_id
= DEFAULT_FACE_ID
;
15244 /* Temporarily make frame's keyboard the current kboard so that
15245 kboard-local variables in the mode_line_format will get the right
15247 push_frame_kboard (it
.f
);
15248 display_mode_element (&it
, 0, 0, 0, format
, Qnil
, 0);
15249 pop_frame_kboard ();
15251 /* Fill up with spaces. */
15252 display_string (" ", Qnil
, Qnil
, 0, 0, &it
, 10000, -1, -1, 0);
15254 compute_line_metrics (&it
);
15255 it
.glyph_row
->full_width_p
= 1;
15256 it
.glyph_row
->continued_p
= 0;
15257 it
.glyph_row
->truncated_on_left_p
= 0;
15258 it
.glyph_row
->truncated_on_right_p
= 0;
15260 /* Make a 3D mode-line have a shadow at its right end. */
15261 face
= FACE_FROM_ID (it
.f
, face_id
);
15262 extend_face_to_end_of_line (&it
);
15263 if (face
->box
!= FACE_NO_BOX
)
15265 struct glyph
*last
= (it
.glyph_row
->glyphs
[TEXT_AREA
]
15266 + it
.glyph_row
->used
[TEXT_AREA
] - 1);
15267 last
->right_box_line_p
= 1;
15270 return it
.glyph_row
->height
;
15273 /* Alist that caches the results of :propertize.
15274 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
15275 Lisp_Object mode_line_proptrans_alist
;
15277 /* List of strings making up the mode-line. */
15278 Lisp_Object mode_line_string_list
;
15280 /* Base face property when building propertized mode line string. */
15281 static Lisp_Object mode_line_string_face
;
15282 static Lisp_Object mode_line_string_face_prop
;
15285 /* Contribute ELT to the mode line for window IT->w. How it
15286 translates into text depends on its data type.
15288 IT describes the display environment in which we display, as usual.
15290 DEPTH is the depth in recursion. It is used to prevent
15291 infinite recursion here.
15293 FIELD_WIDTH is the number of characters the display of ELT should
15294 occupy in the mode line, and PRECISION is the maximum number of
15295 characters to display from ELT's representation. See
15296 display_string for details.
15298 Returns the hpos of the end of the text generated by ELT.
15300 PROPS is a property list to add to any string we encounter.
15302 If RISKY is nonzero, remove (disregard) any properties in any string
15303 we encounter, and ignore :eval and :propertize.
15305 If the global variable `frame_title_ptr' is non-NULL, then the output
15306 is passed to `store_frame_title' instead of `display_string'. */
15309 display_mode_element (it
, depth
, field_width
, precision
, elt
, props
, risky
)
15312 int field_width
, precision
;
15313 Lisp_Object elt
, props
;
15316 int n
= 0, field
, prec
;
15321 elt
= build_string ("*too-deep*");
15325 switch (SWITCH_ENUM_CAST (XTYPE (elt
)))
15329 /* A string: output it and check for %-constructs within it. */
15331 const unsigned char *this, *lisp_string
;
15333 if (!NILP (props
) || risky
)
15335 Lisp_Object oprops
, aelt
;
15336 oprops
= Ftext_properties_at (make_number (0), elt
);
15338 if (NILP (Fequal (props
, oprops
)) || risky
)
15340 /* If the starting string has properties,
15341 merge the specified ones onto the existing ones. */
15342 if (! NILP (oprops
) && !risky
)
15346 oprops
= Fcopy_sequence (oprops
);
15348 while (CONSP (tem
))
15350 oprops
= Fplist_put (oprops
, XCAR (tem
),
15351 XCAR (XCDR (tem
)));
15352 tem
= XCDR (XCDR (tem
));
15357 aelt
= Fassoc (elt
, mode_line_proptrans_alist
);
15358 if (! NILP (aelt
) && !NILP (Fequal (props
, XCDR (aelt
))))
15360 mode_line_proptrans_alist
15361 = Fcons (aelt
, Fdelq (aelt
, mode_line_proptrans_alist
));
15368 elt
= Fcopy_sequence (elt
);
15369 Fset_text_properties (make_number (0), Flength (elt
),
15371 /* Add this item to mode_line_proptrans_alist. */
15372 mode_line_proptrans_alist
15373 = Fcons (Fcons (elt
, props
),
15374 mode_line_proptrans_alist
);
15375 /* Truncate mode_line_proptrans_alist
15376 to at most 50 elements. */
15377 tem
= Fnthcdr (make_number (50),
15378 mode_line_proptrans_alist
);
15380 XSETCDR (tem
, Qnil
);
15385 this = SDATA (elt
);
15386 lisp_string
= this;
15390 prec
= precision
- n
;
15391 if (frame_title_ptr
)
15392 n
+= store_frame_title (SDATA (elt
), -1, prec
);
15393 else if (!NILP (mode_line_string_list
))
15394 n
+= store_mode_line_string (NULL
, elt
, 1, 0, prec
, Qnil
);
15396 n
+= display_string (NULL
, elt
, Qnil
, 0, 0, it
,
15397 0, prec
, 0, STRING_MULTIBYTE (elt
));
15402 while ((precision
<= 0 || n
< precision
)
15404 && (frame_title_ptr
15405 || !NILP (mode_line_string_list
)
15406 || it
->current_x
< it
->last_visible_x
))
15408 const unsigned char *last
= this;
15410 /* Advance to end of string or next format specifier. */
15411 while ((c
= *this++) != '\0' && c
!= '%')
15414 if (this - 1 != last
)
15416 /* Output to end of string or up to '%'. Field width
15417 is length of string. Don't output more than
15418 PRECISION allows us. */
15421 prec
= chars_in_text (last
, this - last
);
15422 if (precision
> 0 && prec
> precision
- n
)
15423 prec
= precision
- n
;
15425 if (frame_title_ptr
)
15426 n
+= store_frame_title (last
, 0, prec
);
15427 else if (!NILP (mode_line_string_list
))
15429 int bytepos
= last
- lisp_string
;
15430 int charpos
= string_byte_to_char (elt
, bytepos
);
15431 n
+= store_mode_line_string (NULL
,
15432 Fsubstring (elt
, make_number (charpos
),
15433 make_number (charpos
+ prec
)),
15438 int bytepos
= last
- lisp_string
;
15439 int charpos
= string_byte_to_char (elt
, bytepos
);
15440 n
+= display_string (NULL
, elt
, Qnil
, 0, charpos
,
15442 STRING_MULTIBYTE (elt
));
15445 else /* c == '%' */
15447 const unsigned char *percent_position
= this;
15449 /* Get the specified minimum width. Zero means
15452 while ((c
= *this++) >= '0' && c
<= '9')
15453 field
= field
* 10 + c
- '0';
15455 /* Don't pad beyond the total padding allowed. */
15456 if (field_width
- n
> 0 && field
> field_width
- n
)
15457 field
= field_width
- n
;
15459 /* Note that either PRECISION <= 0 or N < PRECISION. */
15460 prec
= precision
- n
;
15463 n
+= display_mode_element (it
, depth
, field
, prec
,
15464 Vglobal_mode_string
, props
,
15469 int bytepos
, charpos
;
15470 unsigned char *spec
;
15472 bytepos
= percent_position
- lisp_string
;
15473 charpos
= (STRING_MULTIBYTE (elt
)
15474 ? string_byte_to_char (elt
, bytepos
)
15478 = decode_mode_spec (it
->w
, c
, field
, prec
, &multibyte
);
15480 if (frame_title_ptr
)
15481 n
+= store_frame_title (spec
, field
, prec
);
15482 else if (!NILP (mode_line_string_list
))
15484 int len
= strlen (spec
);
15485 Lisp_Object tem
= make_string (spec
, len
);
15486 props
= Ftext_properties_at (make_number (charpos
), elt
);
15487 /* Should only keep face property in props */
15488 n
+= store_mode_line_string (NULL
, tem
, 0, field
, prec
, props
);
15492 int nglyphs_before
, nwritten
;
15494 nglyphs_before
= it
->glyph_row
->used
[TEXT_AREA
];
15495 nwritten
= display_string (spec
, Qnil
, elt
,
15500 /* Assign to the glyphs written above the
15501 string where the `%x' came from, position
15505 struct glyph
*glyph
15506 = (it
->glyph_row
->glyphs
[TEXT_AREA
]
15510 for (i
= 0; i
< nwritten
; ++i
)
15512 glyph
[i
].object
= elt
;
15513 glyph
[i
].charpos
= charpos
;
15528 /* A symbol: process the value of the symbol recursively
15529 as if it appeared here directly. Avoid error if symbol void.
15530 Special case: if value of symbol is a string, output the string
15533 register Lisp_Object tem
;
15535 /* If the variable is not marked as risky to set
15536 then its contents are risky to use. */
15537 if (NILP (Fget (elt
, Qrisky_local_variable
)))
15540 tem
= Fboundp (elt
);
15543 tem
= Fsymbol_value (elt
);
15544 /* If value is a string, output that string literally:
15545 don't check for % within it. */
15549 if (!EQ (tem
, elt
))
15551 /* Give up right away for nil or t. */
15561 register Lisp_Object car
, tem
;
15563 /* A cons cell: five distinct cases.
15564 If first element is :eval or :propertize, do something special.
15565 If first element is a string or a cons, process all the elements
15566 and effectively concatenate them.
15567 If first element is a negative number, truncate displaying cdr to
15568 at most that many characters. If positive, pad (with spaces)
15569 to at least that many characters.
15570 If first element is a symbol, process the cadr or caddr recursively
15571 according to whether the symbol's value is non-nil or nil. */
15573 if (EQ (car
, QCeval
))
15575 /* An element of the form (:eval FORM) means evaluate FORM
15576 and use the result as mode line elements. */
15581 if (CONSP (XCDR (elt
)))
15584 spec
= safe_eval (XCAR (XCDR (elt
)));
15585 n
+= display_mode_element (it
, depth
, field_width
- n
,
15586 precision
- n
, spec
, props
,
15590 else if (EQ (car
, QCpropertize
))
15592 /* An element of the form (:propertize ELT PROPS...)
15593 means display ELT but applying properties PROPS. */
15598 if (CONSP (XCDR (elt
)))
15599 n
+= display_mode_element (it
, depth
, field_width
- n
,
15600 precision
- n
, XCAR (XCDR (elt
)),
15601 XCDR (XCDR (elt
)), risky
);
15603 else if (SYMBOLP (car
))
15605 tem
= Fboundp (car
);
15609 /* elt is now the cdr, and we know it is a cons cell.
15610 Use its car if CAR has a non-nil value. */
15613 tem
= Fsymbol_value (car
);
15620 /* Symbol's value is nil (or symbol is unbound)
15621 Get the cddr of the original list
15622 and if possible find the caddr and use that. */
15626 else if (!CONSP (elt
))
15631 else if (INTEGERP (car
))
15633 register int lim
= XINT (car
);
15637 /* Negative int means reduce maximum width. */
15638 if (precision
<= 0)
15641 precision
= min (precision
, -lim
);
15645 /* Padding specified. Don't let it be more than
15646 current maximum. */
15648 lim
= min (precision
, lim
);
15650 /* If that's more padding than already wanted, queue it.
15651 But don't reduce padding already specified even if
15652 that is beyond the current truncation point. */
15653 field_width
= max (lim
, field_width
);
15657 else if (STRINGP (car
) || CONSP (car
))
15659 register int limit
= 50;
15660 /* Limit is to protect against circular lists. */
15663 && (precision
<= 0 || n
< precision
))
15665 n
+= display_mode_element (it
, depth
, field_width
- n
,
15666 precision
- n
, XCAR (elt
),
15676 elt
= build_string ("*invalid*");
15680 /* Pad to FIELD_WIDTH. */
15681 if (field_width
> 0 && n
< field_width
)
15683 if (frame_title_ptr
)
15684 n
+= store_frame_title ("", field_width
- n
, 0);
15685 else if (!NILP (mode_line_string_list
))
15686 n
+= store_mode_line_string ("", Qnil
, 0, field_width
- n
, 0, Qnil
);
15688 n
+= display_string ("", Qnil
, Qnil
, 0, 0, it
, field_width
- n
,
15695 /* Store a mode-line string element in mode_line_string_list.
15697 If STRING is non-null, display that C string. Otherwise, the Lisp
15698 string LISP_STRING is displayed.
15700 FIELD_WIDTH is the minimum number of output glyphs to produce.
15701 If STRING has fewer characters than FIELD_WIDTH, pad to the right
15702 with spaces. FIELD_WIDTH <= 0 means don't pad.
15704 PRECISION is the maximum number of characters to output from
15705 STRING. PRECISION <= 0 means don't truncate the string.
15707 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
15708 properties to the string.
15710 PROPS are the properties to add to the string.
15711 The mode_line_string_face face property is always added to the string.
15715 store_mode_line_string (string
, lisp_string
, copy_string
, field_width
, precision
, props
)
15717 Lisp_Object lisp_string
;
15726 if (string
!= NULL
)
15728 len
= strlen (string
);
15729 if (precision
> 0 && len
> precision
)
15731 lisp_string
= make_string (string
, len
);
15733 props
= mode_line_string_face_prop
;
15734 else if (!NILP (mode_line_string_face
))
15736 Lisp_Object face
= Fplist_get (props
, Qface
);
15737 props
= Fcopy_sequence (props
);
15739 face
= mode_line_string_face
;
15741 face
= Fcons (face
, Fcons (mode_line_string_face
, Qnil
));
15742 props
= Fplist_put (props
, Qface
, face
);
15744 Fadd_text_properties (make_number (0), make_number (len
),
15745 props
, lisp_string
);
15749 len
= XFASTINT (Flength (lisp_string
));
15750 if (precision
> 0 && len
> precision
)
15753 lisp_string
= Fsubstring (lisp_string
, make_number (0), make_number (len
));
15756 if (!NILP (mode_line_string_face
))
15760 props
= Ftext_properties_at (make_number (0), lisp_string
);
15761 face
= Fplist_get (props
, Qface
);
15763 face
= mode_line_string_face
;
15765 face
= Fcons (face
, Fcons (mode_line_string_face
, Qnil
));
15766 props
= Fcons (Qface
, Fcons (face
, Qnil
));
15768 lisp_string
= Fcopy_sequence (lisp_string
);
15771 Fadd_text_properties (make_number (0), make_number (len
),
15772 props
, lisp_string
);
15777 mode_line_string_list
= Fcons (lisp_string
, mode_line_string_list
);
15781 if (field_width
> len
)
15783 field_width
-= len
;
15784 lisp_string
= Fmake_string (make_number (field_width
), make_number (' '));
15786 Fadd_text_properties (make_number (0), make_number (field_width
),
15787 props
, lisp_string
);
15788 mode_line_string_list
= Fcons (lisp_string
, mode_line_string_list
);
15796 DEFUN ("format-mode-line", Fformat_mode_line
, Sformat_mode_line
,
15798 doc
: /* Return the mode-line of selected window as a string.
15799 First optional arg FORMAT specifies a different format string (see
15800 `mode-line-format' for details) to use. If FORMAT is t, return
15801 the buffer's header-line. Second optional arg WINDOW specifies a
15802 different window to use as the context for the formatting.
15803 If third optional arg NO-PROPS is non-nil, string is not propertized. */)
15804 (format
, window
, no_props
)
15805 Lisp_Object format
, window
, no_props
;
15810 struct buffer
*old_buffer
= NULL
;
15811 enum face_id face_id
= DEFAULT_FACE_ID
;
15814 window
= selected_window
;
15815 CHECK_WINDOW (window
);
15816 w
= XWINDOW (window
);
15817 CHECK_BUFFER (w
->buffer
);
15819 if (XBUFFER (w
->buffer
) != current_buffer
)
15821 old_buffer
= current_buffer
;
15822 set_buffer_internal_1 (XBUFFER (w
->buffer
));
15825 if (NILP (format
) || EQ (format
, Qt
))
15827 face_id
= (NILP (format
)
15828 ? CURRENT_MODE_LINE_FACE_ID (w
)
15829 : HEADER_LINE_FACE_ID
);
15830 format
= (NILP (format
)
15831 ? current_buffer
->mode_line_format
15832 : current_buffer
->header_line_format
);
15835 init_iterator (&it
, w
, -1, -1, NULL
, face_id
);
15837 if (NILP (no_props
))
15839 mode_line_string_face
15840 = (face_id
== MODE_LINE_FACE_ID
? Qmode_line
15841 : face_id
== MODE_LINE_INACTIVE_FACE_ID
? Qmode_line_inactive
15842 : face_id
== HEADER_LINE_FACE_ID
? Qheader_line
: Qnil
);
15844 mode_line_string_face_prop
15845 = (NILP (mode_line_string_face
) ? Qnil
15846 : Fcons (Qface
, Fcons (mode_line_string_face
, Qnil
)));
15848 /* We need a dummy last element in mode_line_string_list to
15849 indicate we are building the propertized mode-line string.
15850 Using mode_line_string_face_prop here GC protects it. */
15851 mode_line_string_list
15852 = Fcons (mode_line_string_face_prop
, Qnil
);
15853 frame_title_ptr
= NULL
;
15857 mode_line_string_face_prop
= Qnil
;
15858 mode_line_string_list
= Qnil
;
15859 frame_title_ptr
= frame_title_buf
;
15862 push_frame_kboard (it
.f
);
15863 display_mode_element (&it
, 0, 0, 0, format
, Qnil
, 0);
15864 pop_frame_kboard ();
15867 set_buffer_internal_1 (old_buffer
);
15869 if (NILP (no_props
))
15872 mode_line_string_list
= Fnreverse (mode_line_string_list
);
15873 str
= Fmapconcat (intern ("identity"), XCDR (mode_line_string_list
),
15874 make_string ("", 0));
15875 mode_line_string_face_prop
= Qnil
;
15876 mode_line_string_list
= Qnil
;
15880 len
= frame_title_ptr
- frame_title_buf
;
15881 if (len
> 0 && frame_title_ptr
[-1] == '-')
15883 /* Mode lines typically ends with numerous dashes; reduce to two dashes. */
15884 while (frame_title_ptr
> frame_title_buf
&& *--frame_title_ptr
== '-')
15886 frame_title_ptr
+= 3; /* restore last non-dash + two dashes */
15887 if (len
> frame_title_ptr
- frame_title_buf
)
15888 len
= frame_title_ptr
- frame_title_buf
;
15891 frame_title_ptr
= NULL
;
15892 return make_string (frame_title_buf
, len
);
15895 /* Write a null-terminated, right justified decimal representation of
15896 the positive integer D to BUF using a minimal field width WIDTH. */
15899 pint2str (buf
, width
, d
)
15900 register char *buf
;
15901 register int width
;
15904 register char *p
= buf
;
15912 *p
++ = d
% 10 + '0';
15917 for (width
-= (int) (p
- buf
); width
> 0; --width
)
15928 /* Write a null-terminated, right justified decimal and "human
15929 readable" representation of the nonnegative integer D to BUF using
15930 a minimal field width WIDTH. D should be smaller than 999.5e24. */
15932 static const char power_letter
[] =
15946 pint2hrstr (buf
, width
, d
)
15951 /* We aim to represent the nonnegative integer D as
15952 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
15955 /* -1 means: do not use TENTHS. */
15959 /* Length of QUOTIENT.TENTHS as a string. */
15965 if (1000 <= quotient
)
15967 /* Scale to the appropriate EXPONENT. */
15970 remainder
= quotient
% 1000;
15974 while (1000 <= quotient
);
15976 /* Round to nearest and decide whether to use TENTHS or not. */
15979 tenths
= remainder
/ 100;
15980 if (50 <= remainder
% 100)
15986 if (quotient
== 10)
15993 if (500 <= remainder
)
15994 if (quotient
< 999)
16004 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
16005 if (tenths
== -1 && quotient
<= 99)
16012 p
= psuffix
= buf
+ max (width
, length
);
16014 /* Print EXPONENT. */
16016 *psuffix
++ = power_letter
[exponent
];
16019 /* Print TENTHS. */
16022 *--p
= '0' + tenths
;
16026 /* Print QUOTIENT. */
16029 int digit
= quotient
% 10;
16030 *--p
= '0' + digit
;
16032 while ((quotient
/= 10) != 0);
16034 /* Print leading spaces. */
16039 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
16040 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
16041 type of CODING_SYSTEM. Return updated pointer into BUF. */
16043 static unsigned char invalid_eol_type
[] = "(*invalid*)";
16046 decode_mode_spec_coding (coding_system
, buf
, eol_flag
)
16047 Lisp_Object coding_system
;
16048 register char *buf
;
16052 int multibyte
= !NILP (current_buffer
->enable_multibyte_characters
);
16053 const unsigned char *eol_str
;
16055 /* The EOL conversion we are using. */
16056 Lisp_Object eoltype
;
16058 val
= Fget (coding_system
, Qcoding_system
);
16061 if (!VECTORP (val
)) /* Not yet decided. */
16066 eoltype
= eol_mnemonic_undecided
;
16067 /* Don't mention EOL conversion if it isn't decided. */
16071 Lisp_Object eolvalue
;
16073 eolvalue
= Fget (coding_system
, Qeol_type
);
16076 *buf
++ = XFASTINT (AREF (val
, 1));
16080 /* The EOL conversion that is normal on this system. */
16082 if (NILP (eolvalue
)) /* Not yet decided. */
16083 eoltype
= eol_mnemonic_undecided
;
16084 else if (VECTORP (eolvalue
)) /* Not yet decided. */
16085 eoltype
= eol_mnemonic_undecided
;
16086 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
16087 eoltype
= (XFASTINT (eolvalue
) == 0
16088 ? eol_mnemonic_unix
16089 : (XFASTINT (eolvalue
) == 1
16090 ? eol_mnemonic_dos
: eol_mnemonic_mac
));
16096 /* Mention the EOL conversion if it is not the usual one. */
16097 if (STRINGP (eoltype
))
16099 eol_str
= SDATA (eoltype
);
16100 eol_str_len
= SBYTES (eoltype
);
16102 else if (INTEGERP (eoltype
)
16103 && CHAR_VALID_P (XINT (eoltype
), 0))
16105 unsigned char *tmp
= (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH
);
16106 eol_str_len
= CHAR_STRING (XINT (eoltype
), tmp
);
16111 eol_str
= invalid_eol_type
;
16112 eol_str_len
= sizeof (invalid_eol_type
) - 1;
16114 bcopy (eol_str
, buf
, eol_str_len
);
16115 buf
+= eol_str_len
;
16121 /* Return a string for the output of a mode line %-spec for window W,
16122 generated by character C. PRECISION >= 0 means don't return a
16123 string longer than that value. FIELD_WIDTH > 0 means pad the
16124 string returned with spaces to that value. Return 1 in *MULTIBYTE
16125 if the result is multibyte text. */
16127 static char lots_of_dashes
[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
16130 decode_mode_spec (w
, c
, field_width
, precision
, multibyte
)
16133 int field_width
, precision
;
16137 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
16138 char *decode_mode_spec_buf
= f
->decode_mode_spec_buffer
;
16139 struct buffer
*b
= XBUFFER (w
->buffer
);
16147 if (!NILP (b
->read_only
))
16149 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
16154 /* This differs from %* only for a modified read-only buffer. */
16155 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
16157 if (!NILP (b
->read_only
))
16162 /* This differs from %* in ignoring read-only-ness. */
16163 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
16175 if (command_loop_level
> 5)
16177 p
= decode_mode_spec_buf
;
16178 for (i
= 0; i
< command_loop_level
; i
++)
16181 return decode_mode_spec_buf
;
16189 if (command_loop_level
> 5)
16191 p
= decode_mode_spec_buf
;
16192 for (i
= 0; i
< command_loop_level
; i
++)
16195 return decode_mode_spec_buf
;
16202 /* Let lots_of_dashes be a string of infinite length. */
16203 if (!NILP (mode_line_string_list
))
16205 if (field_width
<= 0
16206 || field_width
> sizeof (lots_of_dashes
))
16208 for (i
= 0; i
< FRAME_MESSAGE_BUF_SIZE (f
) - 1; ++i
)
16209 decode_mode_spec_buf
[i
] = '-';
16210 decode_mode_spec_buf
[i
] = '\0';
16211 return decode_mode_spec_buf
;
16214 return lots_of_dashes
;
16223 int col
= (int) current_column (); /* iftc */
16224 w
->column_number_displayed
= make_number (col
);
16225 pint2str (decode_mode_spec_buf
, field_width
, col
);
16226 return decode_mode_spec_buf
;
16230 /* %F displays the frame name. */
16231 if (!NILP (f
->title
))
16232 return (char *) SDATA (f
->title
);
16233 if (f
->explicit_name
|| ! FRAME_WINDOW_P (f
))
16234 return (char *) SDATA (f
->name
);
16243 int size
= ZV
- BEGV
;
16244 pint2str (decode_mode_spec_buf
, field_width
, size
);
16245 return decode_mode_spec_buf
;
16250 int size
= ZV
- BEGV
;
16251 pint2hrstr (decode_mode_spec_buf
, field_width
, size
);
16252 return decode_mode_spec_buf
;
16257 int startpos
= XMARKER (w
->start
)->charpos
;
16258 int startpos_byte
= marker_byte_position (w
->start
);
16259 int line
, linepos
, linepos_byte
, topline
;
16261 int height
= WINDOW_TOTAL_LINES (w
);
16263 /* If we decided that this buffer isn't suitable for line numbers,
16264 don't forget that too fast. */
16265 if (EQ (w
->base_line_pos
, w
->buffer
))
16267 /* But do forget it, if the window shows a different buffer now. */
16268 else if (BUFFERP (w
->base_line_pos
))
16269 w
->base_line_pos
= Qnil
;
16271 /* If the buffer is very big, don't waste time. */
16272 if (INTEGERP (Vline_number_display_limit
)
16273 && BUF_ZV (b
) - BUF_BEGV (b
) > XINT (Vline_number_display_limit
))
16275 w
->base_line_pos
= Qnil
;
16276 w
->base_line_number
= Qnil
;
16280 if (!NILP (w
->base_line_number
)
16281 && !NILP (w
->base_line_pos
)
16282 && XFASTINT (w
->base_line_pos
) <= startpos
)
16284 line
= XFASTINT (w
->base_line_number
);
16285 linepos
= XFASTINT (w
->base_line_pos
);
16286 linepos_byte
= buf_charpos_to_bytepos (b
, linepos
);
16291 linepos
= BUF_BEGV (b
);
16292 linepos_byte
= BUF_BEGV_BYTE (b
);
16295 /* Count lines from base line to window start position. */
16296 nlines
= display_count_lines (linepos
, linepos_byte
,
16300 topline
= nlines
+ line
;
16302 /* Determine a new base line, if the old one is too close
16303 or too far away, or if we did not have one.
16304 "Too close" means it's plausible a scroll-down would
16305 go back past it. */
16306 if (startpos
== BUF_BEGV (b
))
16308 w
->base_line_number
= make_number (topline
);
16309 w
->base_line_pos
= make_number (BUF_BEGV (b
));
16311 else if (nlines
< height
+ 25 || nlines
> height
* 3 + 50
16312 || linepos
== BUF_BEGV (b
))
16314 int limit
= BUF_BEGV (b
);
16315 int limit_byte
= BUF_BEGV_BYTE (b
);
16317 int distance
= (height
* 2 + 30) * line_number_display_limit_width
;
16319 if (startpos
- distance
> limit
)
16321 limit
= startpos
- distance
;
16322 limit_byte
= CHAR_TO_BYTE (limit
);
16325 nlines
= display_count_lines (startpos
, startpos_byte
,
16327 - (height
* 2 + 30),
16329 /* If we couldn't find the lines we wanted within
16330 line_number_display_limit_width chars per line,
16331 give up on line numbers for this window. */
16332 if (position
== limit_byte
&& limit
== startpos
- distance
)
16334 w
->base_line_pos
= w
->buffer
;
16335 w
->base_line_number
= Qnil
;
16339 w
->base_line_number
= make_number (topline
- nlines
);
16340 w
->base_line_pos
= make_number (BYTE_TO_CHAR (position
));
16343 /* Now count lines from the start pos to point. */
16344 nlines
= display_count_lines (startpos
, startpos_byte
,
16345 PT_BYTE
, PT
, &junk
);
16347 /* Record that we did display the line number. */
16348 line_number_displayed
= 1;
16350 /* Make the string to show. */
16351 pint2str (decode_mode_spec_buf
, field_width
, topline
+ nlines
);
16352 return decode_mode_spec_buf
;
16355 char* p
= decode_mode_spec_buf
;
16356 int pad
= field_width
- 2;
16362 return decode_mode_spec_buf
;
16368 obj
= b
->mode_name
;
16372 if (BUF_BEGV (b
) > BUF_BEG (b
) || BUF_ZV (b
) < BUF_Z (b
))
16378 int pos
= marker_position (w
->start
);
16379 int total
= BUF_ZV (b
) - BUF_BEGV (b
);
16381 if (XFASTINT (w
->window_end_pos
) <= BUF_Z (b
) - BUF_ZV (b
))
16383 if (pos
<= BUF_BEGV (b
))
16388 else if (pos
<= BUF_BEGV (b
))
16392 if (total
> 1000000)
16393 /* Do it differently for a large value, to avoid overflow. */
16394 total
= ((pos
- BUF_BEGV (b
)) + (total
/ 100) - 1) / (total
/ 100);
16396 total
= ((pos
- BUF_BEGV (b
)) * 100 + total
- 1) / total
;
16397 /* We can't normally display a 3-digit number,
16398 so get us a 2-digit number that is close. */
16401 sprintf (decode_mode_spec_buf
, "%2d%%", total
);
16402 return decode_mode_spec_buf
;
16406 /* Display percentage of size above the bottom of the screen. */
16409 int toppos
= marker_position (w
->start
);
16410 int botpos
= BUF_Z (b
) - XFASTINT (w
->window_end_pos
);
16411 int total
= BUF_ZV (b
) - BUF_BEGV (b
);
16413 if (botpos
>= BUF_ZV (b
))
16415 if (toppos
<= BUF_BEGV (b
))
16422 if (total
> 1000000)
16423 /* Do it differently for a large value, to avoid overflow. */
16424 total
= ((botpos
- BUF_BEGV (b
)) + (total
/ 100) - 1) / (total
/ 100);
16426 total
= ((botpos
- BUF_BEGV (b
)) * 100 + total
- 1) / total
;
16427 /* We can't normally display a 3-digit number,
16428 so get us a 2-digit number that is close. */
16431 if (toppos
<= BUF_BEGV (b
))
16432 sprintf (decode_mode_spec_buf
, "Top%2d%%", total
);
16434 sprintf (decode_mode_spec_buf
, "%2d%%", total
);
16435 return decode_mode_spec_buf
;
16440 /* status of process */
16441 obj
= Fget_buffer_process (w
->buffer
);
16443 return "no process";
16444 #ifdef subprocesses
16445 obj
= Fsymbol_name (Fprocess_status (obj
));
16449 case 't': /* indicate TEXT or BINARY */
16450 #ifdef MODE_LINE_BINARY_TEXT
16451 return MODE_LINE_BINARY_TEXT (b
);
16457 /* coding-system (not including end-of-line format) */
16459 /* coding-system (including end-of-line type) */
16461 int eol_flag
= (c
== 'Z');
16462 char *p
= decode_mode_spec_buf
;
16464 if (! FRAME_WINDOW_P (f
))
16466 /* No need to mention EOL here--the terminal never needs
16467 to do EOL conversion. */
16468 p
= decode_mode_spec_coding (keyboard_coding
.symbol
, p
, 0);
16469 p
= decode_mode_spec_coding (terminal_coding
.symbol
, p
, 0);
16471 p
= decode_mode_spec_coding (b
->buffer_file_coding_system
,
16474 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
16475 #ifdef subprocesses
16476 obj
= Fget_buffer_process (Fcurrent_buffer ());
16477 if (PROCESSP (obj
))
16479 p
= decode_mode_spec_coding (XPROCESS (obj
)->decode_coding_system
,
16481 p
= decode_mode_spec_coding (XPROCESS (obj
)->encode_coding_system
,
16484 #endif /* subprocesses */
16487 return decode_mode_spec_buf
;
16493 *multibyte
= STRING_MULTIBYTE (obj
);
16494 return (char *) SDATA (obj
);
16501 /* Count up to COUNT lines starting from START / START_BYTE.
16502 But don't go beyond LIMIT_BYTE.
16503 Return the number of lines thus found (always nonnegative).
16505 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
16508 display_count_lines (start
, start_byte
, limit_byte
, count
, byte_pos_ptr
)
16509 int start
, start_byte
, limit_byte
, count
;
16512 register unsigned char *cursor
;
16513 unsigned char *base
;
16515 register int ceiling
;
16516 register unsigned char *ceiling_addr
;
16517 int orig_count
= count
;
16519 /* If we are not in selective display mode,
16520 check only for newlines. */
16521 int selective_display
= (!NILP (current_buffer
->selective_display
)
16522 && !INTEGERP (current_buffer
->selective_display
));
16526 while (start_byte
< limit_byte
)
16528 ceiling
= BUFFER_CEILING_OF (start_byte
);
16529 ceiling
= min (limit_byte
- 1, ceiling
);
16530 ceiling_addr
= BYTE_POS_ADDR (ceiling
) + 1;
16531 base
= (cursor
= BYTE_POS_ADDR (start_byte
));
16534 if (selective_display
)
16535 while (*cursor
!= '\n' && *cursor
!= 015 && ++cursor
!= ceiling_addr
)
16538 while (*cursor
!= '\n' && ++cursor
!= ceiling_addr
)
16541 if (cursor
!= ceiling_addr
)
16545 start_byte
+= cursor
- base
+ 1;
16546 *byte_pos_ptr
= start_byte
;
16550 if (++cursor
== ceiling_addr
)
16556 start_byte
+= cursor
- base
;
16561 while (start_byte
> limit_byte
)
16563 ceiling
= BUFFER_FLOOR_OF (start_byte
- 1);
16564 ceiling
= max (limit_byte
, ceiling
);
16565 ceiling_addr
= BYTE_POS_ADDR (ceiling
) - 1;
16566 base
= (cursor
= BYTE_POS_ADDR (start_byte
- 1) + 1);
16569 if (selective_display
)
16570 while (--cursor
!= ceiling_addr
16571 && *cursor
!= '\n' && *cursor
!= 015)
16574 while (--cursor
!= ceiling_addr
&& *cursor
!= '\n')
16577 if (cursor
!= ceiling_addr
)
16581 start_byte
+= cursor
- base
+ 1;
16582 *byte_pos_ptr
= start_byte
;
16583 /* When scanning backwards, we should
16584 not count the newline posterior to which we stop. */
16585 return - orig_count
- 1;
16591 /* Here we add 1 to compensate for the last decrement
16592 of CURSOR, which took it past the valid range. */
16593 start_byte
+= cursor
- base
+ 1;
16597 *byte_pos_ptr
= limit_byte
;
16600 return - orig_count
+ count
;
16601 return orig_count
- count
;
16607 /***********************************************************************
16609 ***********************************************************************/
16611 /* Display a NUL-terminated string, starting with index START.
16613 If STRING is non-null, display that C string. Otherwise, the Lisp
16614 string LISP_STRING is displayed.
16616 If FACE_STRING is not nil, FACE_STRING_POS is a position in
16617 FACE_STRING. Display STRING or LISP_STRING with the face at
16618 FACE_STRING_POS in FACE_STRING:
16620 Display the string in the environment given by IT, but use the
16621 standard display table, temporarily.
16623 FIELD_WIDTH is the minimum number of output glyphs to produce.
16624 If STRING has fewer characters than FIELD_WIDTH, pad to the right
16625 with spaces. If STRING has more characters, more than FIELD_WIDTH
16626 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
16628 PRECISION is the maximum number of characters to output from
16629 STRING. PRECISION < 0 means don't truncate the string.
16631 This is roughly equivalent to printf format specifiers:
16633 FIELD_WIDTH PRECISION PRINTF
16634 ----------------------------------------
16640 MULTIBYTE zero means do not display multibyte chars, > 0 means do
16641 display them, and < 0 means obey the current buffer's value of
16642 enable_multibyte_characters.
16644 Value is the number of glyphs produced. */
16647 display_string (string
, lisp_string
, face_string
, face_string_pos
,
16648 start
, it
, field_width
, precision
, max_x
, multibyte
)
16649 unsigned char *string
;
16650 Lisp_Object lisp_string
;
16651 Lisp_Object face_string
;
16652 int face_string_pos
;
16655 int field_width
, precision
, max_x
;
16658 int hpos_at_start
= it
->hpos
;
16659 int saved_face_id
= it
->face_id
;
16660 struct glyph_row
*row
= it
->glyph_row
;
16662 /* Initialize the iterator IT for iteration over STRING beginning
16663 with index START. */
16664 reseat_to_string (it
, string
, lisp_string
, start
,
16665 precision
, field_width
, multibyte
);
16667 /* If displaying STRING, set up the face of the iterator
16668 from LISP_STRING, if that's given. */
16669 if (STRINGP (face_string
))
16675 = face_at_string_position (it
->w
, face_string
, face_string_pos
,
16676 0, it
->region_beg_charpos
,
16677 it
->region_end_charpos
,
16678 &endptr
, it
->base_face_id
, 0);
16679 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
16680 it
->face_box_p
= face
->box
!= FACE_NO_BOX
;
16683 /* Set max_x to the maximum allowed X position. Don't let it go
16684 beyond the right edge of the window. */
16686 max_x
= it
->last_visible_x
;
16688 max_x
= min (max_x
, it
->last_visible_x
);
16690 /* Skip over display elements that are not visible. because IT->w is
16692 if (it
->current_x
< it
->first_visible_x
)
16693 move_it_in_display_line_to (it
, 100000, it
->first_visible_x
,
16694 MOVE_TO_POS
| MOVE_TO_X
);
16696 row
->ascent
= it
->max_ascent
;
16697 row
->height
= it
->max_ascent
+ it
->max_descent
;
16698 row
->phys_ascent
= it
->max_phys_ascent
;
16699 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
16701 /* This condition is for the case that we are called with current_x
16702 past last_visible_x. */
16703 while (it
->current_x
< max_x
)
16705 int x_before
, x
, n_glyphs_before
, i
, nglyphs
;
16707 /* Get the next display element. */
16708 if (!get_next_display_element (it
))
16711 /* Produce glyphs. */
16712 x_before
= it
->current_x
;
16713 n_glyphs_before
= it
->glyph_row
->used
[TEXT_AREA
];
16714 PRODUCE_GLYPHS (it
);
16716 nglyphs
= it
->glyph_row
->used
[TEXT_AREA
] - n_glyphs_before
;
16719 while (i
< nglyphs
)
16721 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
16723 if (!it
->truncate_lines_p
16724 && x
+ glyph
->pixel_width
> max_x
)
16726 /* End of continued line or max_x reached. */
16727 if (CHAR_GLYPH_PADDING_P (*glyph
))
16729 /* A wide character is unbreakable. */
16730 it
->glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
;
16731 it
->current_x
= x_before
;
16735 it
->glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
+ i
;
16740 else if (x
+ glyph
->pixel_width
> it
->first_visible_x
)
16742 /* Glyph is at least partially visible. */
16744 if (x
< it
->first_visible_x
)
16745 it
->glyph_row
->x
= x
- it
->first_visible_x
;
16749 /* Glyph is off the left margin of the display area.
16750 Should not happen. */
16754 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
16755 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
16756 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
16757 row
->phys_height
= max (row
->phys_height
,
16758 it
->max_phys_ascent
+ it
->max_phys_descent
);
16759 x
+= glyph
->pixel_width
;
16763 /* Stop if max_x reached. */
16767 /* Stop at line ends. */
16768 if (ITERATOR_AT_END_OF_LINE_P (it
))
16770 it
->continuation_lines_width
= 0;
16774 set_iterator_to_next (it
, 1);
16776 /* Stop if truncating at the right edge. */
16777 if (it
->truncate_lines_p
16778 && it
->current_x
>= it
->last_visible_x
)
16780 /* Add truncation mark, but don't do it if the line is
16781 truncated at a padding space. */
16782 if (IT_CHARPOS (*it
) < it
->string_nchars
)
16784 if (!FRAME_WINDOW_P (it
->f
))
16788 if (it
->current_x
> it
->last_visible_x
)
16790 for (i
= row
->used
[TEXT_AREA
] - 1; i
> 0; --i
)
16791 if (!CHAR_GLYPH_PADDING_P (row
->glyphs
[TEXT_AREA
][i
]))
16793 for (n
= row
->used
[TEXT_AREA
]; i
< n
; ++i
)
16795 row
->used
[TEXT_AREA
] = i
;
16796 produce_special_glyphs (it
, IT_TRUNCATION
);
16799 produce_special_glyphs (it
, IT_TRUNCATION
);
16801 it
->glyph_row
->truncated_on_right_p
= 1;
16807 /* Maybe insert a truncation at the left. */
16808 if (it
->first_visible_x
16809 && IT_CHARPOS (*it
) > 0)
16811 if (!FRAME_WINDOW_P (it
->f
))
16812 insert_left_trunc_glyphs (it
);
16813 it
->glyph_row
->truncated_on_left_p
= 1;
16816 it
->face_id
= saved_face_id
;
16818 /* Value is number of columns displayed. */
16819 return it
->hpos
- hpos_at_start
;
16824 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
16825 appears as an element of LIST or as the car of an element of LIST.
16826 If PROPVAL is a list, compare each element against LIST in that
16827 way, and return 1/2 if any element of PROPVAL is found in LIST.
16828 Otherwise return 0. This function cannot quit.
16829 The return value is 2 if the text is invisible but with an ellipsis
16830 and 1 if it's invisible and without an ellipsis. */
16833 invisible_p (propval
, list
)
16834 register Lisp_Object propval
;
16837 register Lisp_Object tail
, proptail
;
16839 for (tail
= list
; CONSP (tail
); tail
= XCDR (tail
))
16841 register Lisp_Object tem
;
16843 if (EQ (propval
, tem
))
16845 if (CONSP (tem
) && EQ (propval
, XCAR (tem
)))
16846 return NILP (XCDR (tem
)) ? 1 : 2;
16849 if (CONSP (propval
))
16851 for (proptail
= propval
; CONSP (proptail
); proptail
= XCDR (proptail
))
16853 Lisp_Object propelt
;
16854 propelt
= XCAR (proptail
);
16855 for (tail
= list
; CONSP (tail
); tail
= XCDR (tail
))
16857 register Lisp_Object tem
;
16859 if (EQ (propelt
, tem
))
16861 if (CONSP (tem
) && EQ (propelt
, XCAR (tem
)))
16862 return NILP (XCDR (tem
)) ? 1 : 2;
16870 /* Calculate a width or height in pixels from a specification using
16871 the following elements:
16874 NUM - a (fractional) multiple of the default font width/height
16875 (NUM) - specifies exactly NUM pixels
16876 UNIT - a fixed number of pixels, see below.
16877 ELEMENT - size of a display element in pixels, see below.
16878 (NUM . SPEC) - equals NUM * SPEC
16879 (+ SPEC SPEC ...) - add pixel values
16880 (- SPEC SPEC ...) - subtract pixel values
16881 (- SPEC) - negate pixel value
16884 INT or FLOAT - a number constant
16885 SYMBOL - use symbol's (buffer local) variable binding.
16888 in - pixels per inch *)
16889 mm - pixels per 1/1000 meter *)
16890 cm - pixels per 1/100 meter *)
16891 width - width of current font in pixels.
16892 height - height of current font in pixels.
16894 *) using the ratio(s) defined in display-pixels-per-inch.
16898 left-fringe - left fringe width in pixels
16899 right-fringe - right fringe width in pixels
16901 left-margin - left margin width in pixels
16902 right-margin - right margin width in pixels
16904 scroll-bar - scroll-bar area width in pixels
16908 Pixels corresponding to 5 inches:
16911 Total width of non-text areas on left side of window (if scroll-bar is on left):
16912 '(space :width (+ left-fringe left-margin scroll-bar))
16914 Align to first text column (in header line):
16915 '(space :align-to 0)
16917 Align to middle of text area minus half the width of variable `my-image'
16918 containing a loaded image:
16919 '(space :align-to (0.5 . (- text my-image)))
16921 Width of left margin minus width of 1 character in the default font:
16922 '(space :width (- left-margin 1))
16924 Width of left margin minus width of 2 characters in the current font:
16925 '(space :width (- left-margin (2 . width)))
16927 Center 1 character over left-margin (in header line):
16928 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
16930 Different ways to express width of left fringe plus left margin minus one pixel:
16931 '(space :width (- (+ left-fringe left-margin) (1)))
16932 '(space :width (+ left-fringe left-margin (- (1))))
16933 '(space :width (+ left-fringe left-margin (-1)))
16937 #define NUMVAL(X) \
16938 ((INTEGERP (X) || FLOATP (X)) \
16943 calc_pixel_width_or_height (res
, it
, prop
, font
, width_p
, align_to
)
16948 int width_p
, *align_to
;
16952 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
16953 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
16956 return OK_PIXELS (0);
16958 if (SYMBOLP (prop
))
16960 if (SCHARS (SYMBOL_NAME (prop
)) == 2)
16962 char *unit
= SDATA (SYMBOL_NAME (prop
));
16964 if (unit
[0] == 'i' && unit
[1] == 'n')
16966 else if (unit
[0] == 'm' && unit
[1] == 'm')
16968 else if (unit
[0] == 'c' && unit
[1] == 'm')
16975 if ((ppi
= NUMVAL (Vdisplay_pixels_per_inch
), ppi
> 0)
16976 || (CONSP (Vdisplay_pixels_per_inch
)
16978 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch
))
16979 : NUMVAL (XCDR (Vdisplay_pixels_per_inch
))),
16981 return OK_PIXELS (ppi
/ pixels
);
16987 #ifdef HAVE_WINDOW_SYSTEM
16988 if (EQ (prop
, Qheight
))
16989 return OK_PIXELS (font
? FONT_HEIGHT ((XFontStruct
*)font
) : FRAME_LINE_HEIGHT (it
->f
));
16990 if (EQ (prop
, Qwidth
))
16991 return OK_PIXELS (font
? FONT_WIDTH ((XFontStruct
*)font
) : FRAME_COLUMN_WIDTH (it
->f
));
16993 if (EQ (prop
, Qheight
) || EQ (prop
, Qwidth
))
16994 return OK_PIXELS (1);
16997 if (EQ (prop
, Qtext
))
16998 return OK_PIXELS (width_p
16999 ? window_box_width (it
->w
, TEXT_AREA
)
17000 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it
->w
));
17002 if (align_to
&& *align_to
< 0)
17005 if (EQ (prop
, Qleft
))
17006 return OK_ALIGN_TO (window_box_left_offset (it
->w
, TEXT_AREA
));
17007 if (EQ (prop
, Qright
))
17008 return OK_ALIGN_TO (window_box_right_offset (it
->w
, TEXT_AREA
));
17009 if (EQ (prop
, Qcenter
))
17010 return OK_ALIGN_TO (window_box_left_offset (it
->w
, TEXT_AREA
)
17011 + window_box_width (it
->w
, TEXT_AREA
) / 2);
17012 if (EQ (prop
, Qleft_fringe
))
17013 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it
->w
)
17014 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it
->w
)
17015 : window_box_right_offset (it
->w
, LEFT_MARGIN_AREA
));
17016 if (EQ (prop
, Qright_fringe
))
17017 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it
->w
)
17018 ? window_box_right_offset (it
->w
, RIGHT_MARGIN_AREA
)
17019 : window_box_right_offset (it
->w
, TEXT_AREA
));
17020 if (EQ (prop
, Qleft_margin
))
17021 return OK_ALIGN_TO (window_box_left_offset (it
->w
, LEFT_MARGIN_AREA
));
17022 if (EQ (prop
, Qright_margin
))
17023 return OK_ALIGN_TO (window_box_left_offset (it
->w
, RIGHT_MARGIN_AREA
));
17024 if (EQ (prop
, Qscroll_bar
))
17025 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it
->w
)
17027 : (window_box_right_offset (it
->w
, RIGHT_MARGIN_AREA
)
17028 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it
->w
)
17029 ? WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)
17034 if (EQ (prop
, Qleft_fringe
))
17035 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it
->w
));
17036 if (EQ (prop
, Qright_fringe
))
17037 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it
->w
));
17038 if (EQ (prop
, Qleft_margin
))
17039 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it
->w
));
17040 if (EQ (prop
, Qright_margin
))
17041 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it
->w
));
17042 if (EQ (prop
, Qscroll_bar
))
17043 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it
->w
));
17046 prop
= Fbuffer_local_value (prop
, it
->w
->buffer
);
17049 if (INTEGERP (prop
) || FLOATP (prop
))
17051 int base_unit
= (width_p
17052 ? FRAME_COLUMN_WIDTH (it
->f
)
17053 : FRAME_LINE_HEIGHT (it
->f
));
17054 return OK_PIXELS (XFLOATINT (prop
) * base_unit
);
17059 Lisp_Object car
= XCAR (prop
);
17060 Lisp_Object cdr
= XCDR (prop
);
17064 #ifdef HAVE_WINDOW_SYSTEM
17065 if (valid_image_p (prop
))
17067 int id
= lookup_image (it
->f
, prop
);
17068 struct image
*img
= IMAGE_FROM_ID (it
->f
, id
);
17070 return OK_PIXELS (width_p
? img
->width
: img
->height
);
17073 if (EQ (car
, Qplus
) || EQ (car
, Qminus
))
17079 while (CONSP (cdr
))
17081 if (!calc_pixel_width_or_height (&px
, it
, XCAR (cdr
),
17082 font
, width_p
, align_to
))
17085 pixels
= (EQ (car
, Qplus
) ? px
: -px
), first
= 0;
17090 if (EQ (car
, Qminus
))
17092 return OK_PIXELS (pixels
);
17095 car
= Fbuffer_local_value (car
, it
->w
->buffer
);
17098 if (INTEGERP (car
) || FLOATP (car
))
17101 pixels
= XFLOATINT (car
);
17103 return OK_PIXELS (pixels
);
17104 if (calc_pixel_width_or_height (&fact
, it
, cdr
,
17105 font
, width_p
, align_to
))
17106 return OK_PIXELS (pixels
* fact
);
17117 /***********************************************************************
17119 ***********************************************************************/
17121 #ifdef HAVE_WINDOW_SYSTEM
17126 dump_glyph_string (s
)
17127 struct glyph_string
*s
;
17129 fprintf (stderr
, "glyph string\n");
17130 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
17131 s
->x
, s
->y
, s
->width
, s
->height
);
17132 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
17133 fprintf (stderr
, " hl = %d\n", s
->hl
);
17134 fprintf (stderr
, " left overhang = %d, right = %d\n",
17135 s
->left_overhang
, s
->right_overhang
);
17136 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
17137 fprintf (stderr
, " extends to end of line = %d\n",
17138 s
->extends_to_end_of_line_p
);
17139 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
17140 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
17143 #endif /* GLYPH_DEBUG */
17145 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
17146 of XChar2b structures for S; it can't be allocated in
17147 init_glyph_string because it must be allocated via `alloca'. W
17148 is the window on which S is drawn. ROW and AREA are the glyph row
17149 and area within the row from which S is constructed. START is the
17150 index of the first glyph structure covered by S. HL is a
17151 face-override for drawing S. */
17154 #define OPTIONAL_HDC(hdc) hdc,
17155 #define DECLARE_HDC(hdc) HDC hdc;
17156 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
17157 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
17160 #ifndef OPTIONAL_HDC
17161 #define OPTIONAL_HDC(hdc)
17162 #define DECLARE_HDC(hdc)
17163 #define ALLOCATE_HDC(hdc, f)
17164 #define RELEASE_HDC(hdc, f)
17168 init_glyph_string (s
, OPTIONAL_HDC (hdc
) char2b
, w
, row
, area
, start
, hl
)
17169 struct glyph_string
*s
;
17173 struct glyph_row
*row
;
17174 enum glyph_row_area area
;
17176 enum draw_glyphs_face hl
;
17178 bzero (s
, sizeof *s
);
17180 s
->f
= XFRAME (w
->frame
);
17184 s
->display
= FRAME_X_DISPLAY (s
->f
);
17185 s
->window
= FRAME_X_WINDOW (s
->f
);
17186 s
->char2b
= char2b
;
17190 s
->first_glyph
= row
->glyphs
[area
] + start
;
17191 s
->height
= row
->height
;
17192 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
17194 /* Display the internal border below the tool-bar window. */
17195 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
17196 s
->y
-= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
17198 s
->ybase
= s
->y
+ row
->ascent
;
17202 /* Append the list of glyph strings with head H and tail T to the list
17203 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
17206 append_glyph_string_lists (head
, tail
, h
, t
)
17207 struct glyph_string
**head
, **tail
;
17208 struct glyph_string
*h
, *t
;
17222 /* Prepend the list of glyph strings with head H and tail T to the
17223 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
17227 prepend_glyph_string_lists (head
, tail
, h
, t
)
17228 struct glyph_string
**head
, **tail
;
17229 struct glyph_string
*h
, *t
;
17243 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
17244 Set *HEAD and *TAIL to the resulting list. */
17247 append_glyph_string (head
, tail
, s
)
17248 struct glyph_string
**head
, **tail
;
17249 struct glyph_string
*s
;
17251 s
->next
= s
->prev
= NULL
;
17252 append_glyph_string_lists (head
, tail
, s
, s
);
17256 /* Get face and two-byte form of character glyph GLYPH on frame F.
17257 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
17258 a pointer to a realized face that is ready for display. */
17260 static INLINE
struct face
*
17261 get_glyph_face_and_encoding (f
, glyph
, char2b
, two_byte_p
)
17263 struct glyph
*glyph
;
17269 xassert (glyph
->type
== CHAR_GLYPH
);
17270 face
= FACE_FROM_ID (f
, glyph
->face_id
);
17275 if (!glyph
->multibyte_p
)
17277 /* Unibyte case. We don't have to encode, but we have to make
17278 sure to use a face suitable for unibyte. */
17279 STORE_XCHAR2B (char2b
, 0, glyph
->u
.ch
);
17281 else if (glyph
->u
.ch
< 128
17282 && glyph
->face_id
< BASIC_FACE_ID_SENTINEL
)
17284 /* Case of ASCII in a face known to fit ASCII. */
17285 STORE_XCHAR2B (char2b
, 0, glyph
->u
.ch
);
17289 int c1
, c2
, charset
;
17291 /* Split characters into bytes. If c2 is -1 afterwards, C is
17292 really a one-byte character so that byte1 is zero. */
17293 SPLIT_CHAR (glyph
->u
.ch
, charset
, c1
, c2
);
17295 STORE_XCHAR2B (char2b
, c1
, c2
);
17297 STORE_XCHAR2B (char2b
, 0, c1
);
17299 /* Maybe encode the character in *CHAR2B. */
17300 if (charset
!= CHARSET_ASCII
)
17302 struct font_info
*font_info
17303 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
17306 = rif
->encode_char (glyph
->u
.ch
, char2b
, font_info
, two_byte_p
);
17310 /* Make sure X resources of the face are allocated. */
17311 xassert (face
!= NULL
);
17312 PREPARE_FACE_FOR_DISPLAY (f
, face
);
17317 /* Fill glyph string S with composition components specified by S->cmp.
17319 FACES is an array of faces for all components of this composition.
17320 S->gidx is the index of the first component for S.
17321 OVERLAPS_P non-zero means S should draw the foreground only, and
17322 use its physical height for clipping.
17324 Value is the index of a component not in S. */
17327 fill_composite_glyph_string (s
, faces
, overlaps_p
)
17328 struct glyph_string
*s
;
17329 struct face
**faces
;
17336 s
->for_overlaps_p
= overlaps_p
;
17338 s
->face
= faces
[s
->gidx
];
17339 s
->font
= s
->face
->font
;
17340 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
17342 /* For all glyphs of this composition, starting at the offset
17343 S->gidx, until we reach the end of the definition or encounter a
17344 glyph that requires the different face, add it to S. */
17346 for (i
= s
->gidx
+ 1; i
< s
->cmp
->glyph_len
&& faces
[i
] == s
->face
; ++i
)
17349 /* All glyph strings for the same composition has the same width,
17350 i.e. the width set for the first component of the composition. */
17352 s
->width
= s
->first_glyph
->pixel_width
;
17354 /* If the specified font could not be loaded, use the frame's
17355 default font, but record the fact that we couldn't load it in
17356 the glyph string so that we can draw rectangles for the
17357 characters of the glyph string. */
17358 if (s
->font
== NULL
)
17360 s
->font_not_found_p
= 1;
17361 s
->font
= FRAME_FONT (s
->f
);
17364 /* Adjust base line for subscript/superscript text. */
17365 s
->ybase
+= s
->first_glyph
->voffset
;
17367 xassert (s
->face
&& s
->face
->gc
);
17369 /* This glyph string must always be drawn with 16-bit functions. */
17372 return s
->gidx
+ s
->nchars
;
17376 /* Fill glyph string S from a sequence of character glyphs.
17378 FACE_ID is the face id of the string. START is the index of the
17379 first glyph to consider, END is the index of the last + 1.
17380 OVERLAPS_P non-zero means S should draw the foreground only, and
17381 use its physical height for clipping.
17383 Value is the index of the first glyph not in S. */
17386 fill_glyph_string (s
, face_id
, start
, end
, overlaps_p
)
17387 struct glyph_string
*s
;
17389 int start
, end
, overlaps_p
;
17391 struct glyph
*glyph
, *last
;
17393 int glyph_not_available_p
;
17395 xassert (s
->f
== XFRAME (s
->w
->frame
));
17396 xassert (s
->nchars
== 0);
17397 xassert (start
>= 0 && end
> start
);
17399 s
->for_overlaps_p
= overlaps_p
,
17400 glyph
= s
->row
->glyphs
[s
->area
] + start
;
17401 last
= s
->row
->glyphs
[s
->area
] + end
;
17402 voffset
= glyph
->voffset
;
17404 glyph_not_available_p
= glyph
->glyph_not_available_p
;
17406 while (glyph
< last
17407 && glyph
->type
== CHAR_GLYPH
17408 && glyph
->voffset
== voffset
17409 /* Same face id implies same font, nowadays. */
17410 && glyph
->face_id
== face_id
17411 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
17415 s
->face
= get_glyph_face_and_encoding (s
->f
, glyph
,
17416 s
->char2b
+ s
->nchars
,
17418 s
->two_byte_p
= two_byte_p
;
17420 xassert (s
->nchars
<= end
- start
);
17421 s
->width
+= glyph
->pixel_width
;
17425 s
->font
= s
->face
->font
;
17426 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
17428 /* If the specified font could not be loaded, use the frame's font,
17429 but record the fact that we couldn't load it in
17430 S->font_not_found_p so that we can draw rectangles for the
17431 characters of the glyph string. */
17432 if (s
->font
== NULL
|| glyph_not_available_p
)
17434 s
->font_not_found_p
= 1;
17435 s
->font
= FRAME_FONT (s
->f
);
17438 /* Adjust base line for subscript/superscript text. */
17439 s
->ybase
+= voffset
;
17441 xassert (s
->face
&& s
->face
->gc
);
17442 return glyph
- s
->row
->glyphs
[s
->area
];
17446 /* Fill glyph string S from image glyph S->first_glyph. */
17449 fill_image_glyph_string (s
)
17450 struct glyph_string
*s
;
17452 xassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
17453 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
17455 s
->slice
= s
->first_glyph
->slice
;
17456 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
17457 s
->font
= s
->face
->font
;
17458 s
->width
= s
->first_glyph
->pixel_width
;
17460 /* Adjust base line for subscript/superscript text. */
17461 s
->ybase
+= s
->first_glyph
->voffset
;
17465 /* Fill glyph string S from a sequence of stretch glyphs.
17467 ROW is the glyph row in which the glyphs are found, AREA is the
17468 area within the row. START is the index of the first glyph to
17469 consider, END is the index of the last + 1.
17471 Value is the index of the first glyph not in S. */
17474 fill_stretch_glyph_string (s
, row
, area
, start
, end
)
17475 struct glyph_string
*s
;
17476 struct glyph_row
*row
;
17477 enum glyph_row_area area
;
17480 struct glyph
*glyph
, *last
;
17481 int voffset
, face_id
;
17483 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
17485 glyph
= s
->row
->glyphs
[s
->area
] + start
;
17486 last
= s
->row
->glyphs
[s
->area
] + end
;
17487 face_id
= glyph
->face_id
;
17488 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
17489 s
->font
= s
->face
->font
;
17490 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
17491 s
->width
= glyph
->pixel_width
;
17492 voffset
= glyph
->voffset
;
17496 && glyph
->type
== STRETCH_GLYPH
17497 && glyph
->voffset
== voffset
17498 && glyph
->face_id
== face_id
);
17500 s
->width
+= glyph
->pixel_width
;
17502 /* Adjust base line for subscript/superscript text. */
17503 s
->ybase
+= voffset
;
17505 /* The case that face->gc == 0 is handled when drawing the glyph
17506 string by calling PREPARE_FACE_FOR_DISPLAY. */
17508 return glyph
- s
->row
->glyphs
[s
->area
];
17513 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
17514 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
17515 assumed to be zero. */
17518 x_get_glyph_overhangs (glyph
, f
, left
, right
)
17519 struct glyph
*glyph
;
17523 *left
= *right
= 0;
17525 if (glyph
->type
== CHAR_GLYPH
)
17529 struct font_info
*font_info
;
17533 face
= get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
17535 font_info
= FONT_INFO_FROM_ID (f
, face
->font_info_id
);
17536 if (font
/* ++KFS: Should this be font_info ? */
17537 && (pcm
= rif
->per_char_metric (font
, &char2b
, glyph
->font_type
)))
17539 if (pcm
->rbearing
> pcm
->width
)
17540 *right
= pcm
->rbearing
- pcm
->width
;
17541 if (pcm
->lbearing
< 0)
17542 *left
= -pcm
->lbearing
;
17548 /* Return the index of the first glyph preceding glyph string S that
17549 is overwritten by S because of S's left overhang. Value is -1
17550 if no glyphs are overwritten. */
17553 left_overwritten (s
)
17554 struct glyph_string
*s
;
17558 if (s
->left_overhang
)
17561 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
17562 int first
= s
->first_glyph
- glyphs
;
17564 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
17565 x
-= glyphs
[i
].pixel_width
;
17576 /* Return the index of the first glyph preceding glyph string S that
17577 is overwriting S because of its right overhang. Value is -1 if no
17578 glyph in front of S overwrites S. */
17581 left_overwriting (s
)
17582 struct glyph_string
*s
;
17585 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
17586 int first
= s
->first_glyph
- glyphs
;
17590 for (i
= first
- 1; i
>= 0; --i
)
17593 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
17596 x
-= glyphs
[i
].pixel_width
;
17603 /* Return the index of the last glyph following glyph string S that is
17604 not overwritten by S because of S's right overhang. Value is -1 if
17605 no such glyph is found. */
17608 right_overwritten (s
)
17609 struct glyph_string
*s
;
17613 if (s
->right_overhang
)
17616 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
17617 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
17618 int end
= s
->row
->used
[s
->area
];
17620 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
17621 x
+= glyphs
[i
].pixel_width
;
17630 /* Return the index of the last glyph following glyph string S that
17631 overwrites S because of its left overhang. Value is negative
17632 if no such glyph is found. */
17635 right_overwriting (s
)
17636 struct glyph_string
*s
;
17639 int end
= s
->row
->used
[s
->area
];
17640 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
17641 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
17645 for (i
= first
; i
< end
; ++i
)
17648 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
17651 x
+= glyphs
[i
].pixel_width
;
17658 /* Get face and two-byte form of character C in face FACE_ID on frame
17659 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
17660 means we want to display multibyte text. DISPLAY_P non-zero means
17661 make sure that X resources for the face returned are allocated.
17662 Value is a pointer to a realized face that is ready for display if
17663 DISPLAY_P is non-zero. */
17665 static INLINE
struct face
*
17666 get_char_face_and_encoding (f
, c
, face_id
, char2b
, multibyte_p
, display_p
)
17670 int multibyte_p
, display_p
;
17672 struct face
*face
= FACE_FROM_ID (f
, face_id
);
17676 /* Unibyte case. We don't have to encode, but we have to make
17677 sure to use a face suitable for unibyte. */
17678 STORE_XCHAR2B (char2b
, 0, c
);
17679 face_id
= FACE_FOR_CHAR (f
, face
, c
);
17680 face
= FACE_FROM_ID (f
, face_id
);
17682 else if (c
< 128 && face_id
< BASIC_FACE_ID_SENTINEL
)
17684 /* Case of ASCII in a face known to fit ASCII. */
17685 STORE_XCHAR2B (char2b
, 0, c
);
17689 int c1
, c2
, charset
;
17691 /* Split characters into bytes. If c2 is -1 afterwards, C is
17692 really a one-byte character so that byte1 is zero. */
17693 SPLIT_CHAR (c
, charset
, c1
, c2
);
17695 STORE_XCHAR2B (char2b
, c1
, c2
);
17697 STORE_XCHAR2B (char2b
, 0, c1
);
17699 /* Maybe encode the character in *CHAR2B. */
17700 if (face
->font
!= NULL
)
17702 struct font_info
*font_info
17703 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
17705 rif
->encode_char (c
, char2b
, font_info
, 0);
17709 /* Make sure X resources of the face are allocated. */
17710 #ifdef HAVE_X_WINDOWS
17714 xassert (face
!= NULL
);
17715 PREPARE_FACE_FOR_DISPLAY (f
, face
);
17722 /* Set background width of glyph string S. START is the index of the
17723 first glyph following S. LAST_X is the right-most x-position + 1
17724 in the drawing area. */
17727 set_glyph_string_background_width (s
, start
, last_x
)
17728 struct glyph_string
*s
;
17732 /* If the face of this glyph string has to be drawn to the end of
17733 the drawing area, set S->extends_to_end_of_line_p. */
17734 struct face
*default_face
= FACE_FROM_ID (s
->f
, DEFAULT_FACE_ID
);
17736 if (start
== s
->row
->used
[s
->area
]
17737 && s
->area
== TEXT_AREA
17738 && ((s
->hl
== DRAW_NORMAL_TEXT
17739 && (s
->row
->fill_line_p
17740 || s
->face
->background
!= default_face
->background
17741 || s
->face
->stipple
!= default_face
->stipple
17742 || s
->row
->mouse_face_p
))
17743 || s
->hl
== DRAW_MOUSE_FACE
17744 || ((s
->hl
== DRAW_IMAGE_RAISED
|| s
->hl
== DRAW_IMAGE_SUNKEN
)
17745 && s
->row
->fill_line_p
)))
17746 s
->extends_to_end_of_line_p
= 1;
17748 /* If S extends its face to the end of the line, set its
17749 background_width to the distance to the right edge of the drawing
17751 if (s
->extends_to_end_of_line_p
)
17752 s
->background_width
= last_x
- s
->x
+ 1;
17754 s
->background_width
= s
->width
;
17758 /* Compute overhangs and x-positions for glyph string S and its
17759 predecessors, or successors. X is the starting x-position for S.
17760 BACKWARD_P non-zero means process predecessors. */
17763 compute_overhangs_and_x (s
, x
, backward_p
)
17764 struct glyph_string
*s
;
17772 if (rif
->compute_glyph_string_overhangs
)
17773 rif
->compute_glyph_string_overhangs (s
);
17783 if (rif
->compute_glyph_string_overhangs
)
17784 rif
->compute_glyph_string_overhangs (s
);
17794 /* The following macros are only called from draw_glyphs below.
17795 They reference the following parameters of that function directly:
17796 `w', `row', `area', and `overlap_p'
17797 as well as the following local variables:
17798 `s', `f', and `hdc' (in W32) */
17801 /* On W32, silently add local `hdc' variable to argument list of
17802 init_glyph_string. */
17803 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17804 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
17806 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17807 init_glyph_string (s, char2b, w, row, area, start, hl)
17810 /* Add a glyph string for a stretch glyph to the list of strings
17811 between HEAD and TAIL. START is the index of the stretch glyph in
17812 row area AREA of glyph row ROW. END is the index of the last glyph
17813 in that glyph row area. X is the current output position assigned
17814 to the new glyph string constructed. HL overrides that face of the
17815 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17816 is the right-most x-position of the drawing area. */
17818 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
17819 and below -- keep them on one line. */
17820 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17823 s = (struct glyph_string *) alloca (sizeof *s); \
17824 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17825 START = fill_stretch_glyph_string (s, row, area, START, END); \
17826 append_glyph_string (&HEAD, &TAIL, s); \
17832 /* Add a glyph string for an image glyph to the list of strings
17833 between HEAD and TAIL. START is the index of the image glyph in
17834 row area AREA of glyph row ROW. END is the index of the last glyph
17835 in that glyph row area. X is the current output position assigned
17836 to the new glyph string constructed. HL overrides that face of the
17837 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17838 is the right-most x-position of the drawing area. */
17840 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17843 s = (struct glyph_string *) alloca (sizeof *s); \
17844 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17845 fill_image_glyph_string (s); \
17846 append_glyph_string (&HEAD, &TAIL, s); \
17853 /* Add a glyph string for a sequence of character glyphs to the list
17854 of strings between HEAD and TAIL. START is the index of the first
17855 glyph in row area AREA of glyph row ROW that is part of the new
17856 glyph string. END is the index of the last glyph in that glyph row
17857 area. X is the current output position assigned to the new glyph
17858 string constructed. HL overrides that face of the glyph; e.g. it
17859 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
17860 right-most x-position of the drawing area. */
17862 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17868 c = (row)->glyphs[area][START].u.ch; \
17869 face_id = (row)->glyphs[area][START].face_id; \
17871 s = (struct glyph_string *) alloca (sizeof *s); \
17872 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
17873 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
17874 append_glyph_string (&HEAD, &TAIL, s); \
17876 START = fill_glyph_string (s, face_id, START, END, overlaps_p); \
17881 /* Add a glyph string for a composite sequence to the list of strings
17882 between HEAD and TAIL. START is the index of the first glyph in
17883 row area AREA of glyph row ROW that is part of the new glyph
17884 string. END is the index of the last glyph in that glyph row area.
17885 X is the current output position assigned to the new glyph string
17886 constructed. HL overrides that face of the glyph; e.g. it is
17887 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
17888 x-position of the drawing area. */
17890 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17892 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
17893 int face_id = (row)->glyphs[area][START].face_id; \
17894 struct face *base_face = FACE_FROM_ID (f, face_id); \
17895 struct composition *cmp = composition_table[cmp_id]; \
17896 int glyph_len = cmp->glyph_len; \
17898 struct face **faces; \
17899 struct glyph_string *first_s = NULL; \
17902 base_face = base_face->ascii_face; \
17903 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
17904 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
17905 /* At first, fill in `char2b' and `faces'. */ \
17906 for (n = 0; n < glyph_len; n++) \
17908 int c = COMPOSITION_GLYPH (cmp, n); \
17909 int this_face_id = FACE_FOR_CHAR (f, base_face, c); \
17910 faces[n] = FACE_FROM_ID (f, this_face_id); \
17911 get_char_face_and_encoding (f, c, this_face_id, \
17912 char2b + n, 1, 1); \
17915 /* Make glyph_strings for each glyph sequence that is drawable by \
17916 the same face, and append them to HEAD/TAIL. */ \
17917 for (n = 0; n < cmp->glyph_len;) \
17919 s = (struct glyph_string *) alloca (sizeof *s); \
17920 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \
17921 append_glyph_string (&(HEAD), &(TAIL), s); \
17929 n = fill_composite_glyph_string (s, faces, overlaps_p); \
17937 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
17938 of AREA of glyph row ROW on window W between indices START and END.
17939 HL overrides the face for drawing glyph strings, e.g. it is
17940 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
17941 x-positions of the drawing area.
17943 This is an ugly monster macro construct because we must use alloca
17944 to allocate glyph strings (because draw_glyphs can be called
17945 asynchronously). */
17947 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17950 HEAD = TAIL = NULL; \
17951 while (START < END) \
17953 struct glyph *first_glyph = (row)->glyphs[area] + START; \
17954 switch (first_glyph->type) \
17957 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
17961 case COMPOSITE_GLYPH: \
17962 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
17966 case STRETCH_GLYPH: \
17967 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
17971 case IMAGE_GLYPH: \
17972 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
17980 set_glyph_string_background_width (s, START, LAST_X); \
17987 /* Draw glyphs between START and END in AREA of ROW on window W,
17988 starting at x-position X. X is relative to AREA in W. HL is a
17989 face-override with the following meaning:
17991 DRAW_NORMAL_TEXT draw normally
17992 DRAW_CURSOR draw in cursor face
17993 DRAW_MOUSE_FACE draw in mouse face.
17994 DRAW_INVERSE_VIDEO draw in mode line face
17995 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
17996 DRAW_IMAGE_RAISED draw an image with a raised relief around it
17998 If OVERLAPS_P is non-zero, draw only the foreground of characters
17999 and clip to the physical height of ROW.
18001 Value is the x-position reached, relative to AREA of W. */
18004 draw_glyphs (w
, x
, row
, area
, start
, end
, hl
, overlaps_p
)
18007 struct glyph_row
*row
;
18008 enum glyph_row_area area
;
18010 enum draw_glyphs_face hl
;
18013 struct glyph_string
*head
, *tail
;
18014 struct glyph_string
*s
;
18015 int last_x
, area_width
;
18018 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
18021 ALLOCATE_HDC (hdc
, f
);
18023 /* Let's rather be paranoid than getting a SEGV. */
18024 end
= min (end
, row
->used
[area
]);
18025 start
= max (0, start
);
18026 start
= min (end
, start
);
18028 /* Translate X to frame coordinates. Set last_x to the right
18029 end of the drawing area. */
18030 if (row
->full_width_p
)
18032 /* X is relative to the left edge of W, without scroll bars
18034 x
+= WINDOW_LEFT_EDGE_X (w
);
18035 last_x
= WINDOW_LEFT_EDGE_X (w
) + WINDOW_TOTAL_WIDTH (w
);
18039 int area_left
= window_box_left (w
, area
);
18041 area_width
= window_box_width (w
, area
);
18042 last_x
= area_left
+ area_width
;
18045 /* Build a doubly-linked list of glyph_string structures between
18046 head and tail from what we have to draw. Note that the macro
18047 BUILD_GLYPH_STRINGS will modify its start parameter. That's
18048 the reason we use a separate variable `i'. */
18050 BUILD_GLYPH_STRINGS (i
, end
, head
, tail
, hl
, x
, last_x
);
18052 x_reached
= tail
->x
+ tail
->background_width
;
18056 /* If there are any glyphs with lbearing < 0 or rbearing > width in
18057 the row, redraw some glyphs in front or following the glyph
18058 strings built above. */
18059 if (head
&& !overlaps_p
&& row
->contains_overlapping_glyphs_p
)
18062 struct glyph_string
*h
, *t
;
18064 /* Compute overhangs for all glyph strings. */
18065 if (rif
->compute_glyph_string_overhangs
)
18066 for (s
= head
; s
; s
= s
->next
)
18067 rif
->compute_glyph_string_overhangs (s
);
18069 /* Prepend glyph strings for glyphs in front of the first glyph
18070 string that are overwritten because of the first glyph
18071 string's left overhang. The background of all strings
18072 prepended must be drawn because the first glyph string
18074 i
= left_overwritten (head
);
18078 BUILD_GLYPH_STRINGS (j
, start
, h
, t
,
18079 DRAW_NORMAL_TEXT
, dummy_x
, last_x
);
18081 compute_overhangs_and_x (t
, head
->x
, 1);
18082 prepend_glyph_string_lists (&head
, &tail
, h
, t
);
18085 /* Prepend glyph strings for glyphs in front of the first glyph
18086 string that overwrite that glyph string because of their
18087 right overhang. For these strings, only the foreground must
18088 be drawn, because it draws over the glyph string at `head'.
18089 The background must not be drawn because this would overwrite
18090 right overhangs of preceding glyphs for which no glyph
18092 i
= left_overwriting (head
);
18095 BUILD_GLYPH_STRINGS (i
, start
, h
, t
,
18096 DRAW_NORMAL_TEXT
, dummy_x
, last_x
);
18097 for (s
= h
; s
; s
= s
->next
)
18098 s
->background_filled_p
= 1;
18099 compute_overhangs_and_x (t
, head
->x
, 1);
18100 prepend_glyph_string_lists (&head
, &tail
, h
, t
);
18103 /* Append glyphs strings for glyphs following the last glyph
18104 string tail that are overwritten by tail. The background of
18105 these strings has to be drawn because tail's foreground draws
18107 i
= right_overwritten (tail
);
18110 BUILD_GLYPH_STRINGS (end
, i
, h
, t
,
18111 DRAW_NORMAL_TEXT
, x
, last_x
);
18112 compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
18113 append_glyph_string_lists (&head
, &tail
, h
, t
);
18116 /* Append glyph strings for glyphs following the last glyph
18117 string tail that overwrite tail. The foreground of such
18118 glyphs has to be drawn because it writes into the background
18119 of tail. The background must not be drawn because it could
18120 paint over the foreground of following glyphs. */
18121 i
= right_overwriting (tail
);
18124 BUILD_GLYPH_STRINGS (end
, i
, h
, t
,
18125 DRAW_NORMAL_TEXT
, x
, last_x
);
18126 for (s
= h
; s
; s
= s
->next
)
18127 s
->background_filled_p
= 1;
18128 compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
18129 append_glyph_string_lists (&head
, &tail
, h
, t
);
18133 /* Draw all strings. */
18134 for (s
= head
; s
; s
= s
->next
)
18135 rif
->draw_glyph_string (s
);
18137 if (area
== TEXT_AREA
18138 && !row
->full_width_p
18139 /* When drawing overlapping rows, only the glyph strings'
18140 foreground is drawn, which doesn't erase a cursor
18144 int x0
= head
? head
->x
: x
;
18145 int x1
= tail
? tail
->x
+ tail
->background_width
: x
;
18147 int text_left
= window_box_left (w
, TEXT_AREA
);
18151 notice_overwritten_cursor (w
, TEXT_AREA
, x0
, x1
,
18152 row
->y
, MATRIX_ROW_BOTTOM_Y (row
));
18155 /* Value is the x-position up to which drawn, relative to AREA of W.
18156 This doesn't include parts drawn because of overhangs. */
18157 if (row
->full_width_p
)
18158 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
18160 x_reached
-= window_box_left (w
, area
);
18162 RELEASE_HDC (hdc
, f
);
18168 /* Store one glyph for IT->char_to_display in IT->glyph_row.
18169 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18175 struct glyph
*glyph
;
18176 enum glyph_row_area area
= it
->area
;
18178 xassert (it
->glyph_row
);
18179 xassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
18181 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
18182 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
18184 glyph
->charpos
= CHARPOS (it
->position
);
18185 glyph
->object
= it
->object
;
18186 glyph
->pixel_width
= it
->pixel_width
;
18187 glyph
->ascent
= it
->ascent
;
18188 glyph
->descent
= it
->descent
;
18189 glyph
->voffset
= it
->voffset
;
18190 glyph
->type
= CHAR_GLYPH
;
18191 glyph
->multibyte_p
= it
->multibyte_p
;
18192 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
18193 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
18194 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
18195 || it
->phys_descent
> it
->descent
);
18196 glyph
->padding_p
= 0;
18197 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
18198 glyph
->face_id
= it
->face_id
;
18199 glyph
->u
.ch
= it
->char_to_display
;
18200 glyph
->slice
= null_glyph_slice
;
18201 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
18202 ++it
->glyph_row
->used
[area
];
18204 else if (!fonts_changed_p
)
18206 it
->w
->ncols_scale_factor
++;
18207 fonts_changed_p
= 1;
18211 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
18212 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18215 append_composite_glyph (it
)
18218 struct glyph
*glyph
;
18219 enum glyph_row_area area
= it
->area
;
18221 xassert (it
->glyph_row
);
18223 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
18224 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
18226 glyph
->charpos
= CHARPOS (it
->position
);
18227 glyph
->object
= it
->object
;
18228 glyph
->pixel_width
= it
->pixel_width
;
18229 glyph
->ascent
= it
->ascent
;
18230 glyph
->descent
= it
->descent
;
18231 glyph
->voffset
= it
->voffset
;
18232 glyph
->type
= COMPOSITE_GLYPH
;
18233 glyph
->multibyte_p
= it
->multibyte_p
;
18234 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
18235 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
18236 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
18237 || it
->phys_descent
> it
->descent
);
18238 glyph
->padding_p
= 0;
18239 glyph
->glyph_not_available_p
= 0;
18240 glyph
->face_id
= it
->face_id
;
18241 glyph
->u
.cmp_id
= it
->cmp_id
;
18242 glyph
->slice
= null_glyph_slice
;
18243 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
18244 ++it
->glyph_row
->used
[area
];
18246 else if (!fonts_changed_p
)
18248 it
->w
->ncols_scale_factor
++;
18249 fonts_changed_p
= 1;
18254 /* Change IT->ascent and IT->height according to the setting of
18258 take_vertical_position_into_account (it
)
18263 if (it
->voffset
< 0)
18264 /* Increase the ascent so that we can display the text higher
18266 it
->ascent
-= it
->voffset
;
18268 /* Increase the descent so that we can display the text lower
18270 it
->descent
+= it
->voffset
;
18275 /* Produce glyphs/get display metrics for the image IT is loaded with.
18276 See the description of struct display_iterator in dispextern.h for
18277 an overview of struct display_iterator. */
18280 produce_image_glyph (it
)
18285 int face_ascent
, glyph_ascent
;
18286 struct glyph_slice slice
;
18288 xassert (it
->what
== IT_IMAGE
);
18290 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
18292 /* Make sure X resources of the face is loaded. */
18293 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
18295 if (it
->image_id
< 0)
18297 /* Fringe bitmap. */
18298 it
->ascent
= it
->phys_ascent
= 0;
18299 it
->descent
= it
->phys_descent
= 0;
18300 it
->pixel_width
= 0;
18305 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
18307 /* Make sure X resources of the image is loaded. */
18308 prepare_image_for_display (it
->f
, img
);
18310 slice
.x
= slice
.y
= 0;
18311 slice
.width
= img
->width
;
18312 slice
.height
= img
->height
;
18314 if (INTEGERP (it
->slice
.x
))
18315 slice
.x
= XINT (it
->slice
.x
);
18316 else if (FLOATP (it
->slice
.x
))
18317 slice
.x
= XFLOAT_DATA (it
->slice
.x
) * img
->width
;
18319 if (INTEGERP (it
->slice
.y
))
18320 slice
.y
= XINT (it
->slice
.y
);
18321 else if (FLOATP (it
->slice
.y
))
18322 slice
.y
= XFLOAT_DATA (it
->slice
.y
) * img
->height
;
18324 if (INTEGERP (it
->slice
.width
))
18325 slice
.width
= XINT (it
->slice
.width
);
18326 else if (FLOATP (it
->slice
.width
))
18327 slice
.width
= XFLOAT_DATA (it
->slice
.width
) * img
->width
;
18329 if (INTEGERP (it
->slice
.height
))
18330 slice
.height
= XINT (it
->slice
.height
);
18331 else if (FLOATP (it
->slice
.height
))
18332 slice
.height
= XFLOAT_DATA (it
->slice
.height
) * img
->height
;
18334 if (slice
.x
>= img
->width
)
18335 slice
.x
= img
->width
;
18336 if (slice
.y
>= img
->height
)
18337 slice
.y
= img
->height
;
18338 if (slice
.x
+ slice
.width
>= img
->width
)
18339 slice
.width
= img
->width
- slice
.x
;
18340 if (slice
.y
+ slice
.height
> img
->height
)
18341 slice
.height
= img
->height
- slice
.y
;
18343 if (slice
.width
== 0 || slice
.height
== 0)
18346 it
->ascent
= it
->phys_ascent
= glyph_ascent
= image_ascent (img
, face
, &slice
);
18348 it
->descent
= slice
.height
- glyph_ascent
;
18350 it
->descent
+= img
->vmargin
;
18351 if (slice
.y
+ slice
.height
== img
->height
)
18352 it
->descent
+= img
->vmargin
;
18353 it
->phys_descent
= it
->descent
;
18355 it
->pixel_width
= slice
.width
;
18357 it
->pixel_width
+= img
->hmargin
;
18358 if (slice
.x
+ slice
.width
== img
->width
)
18359 it
->pixel_width
+= img
->hmargin
;
18361 /* It's quite possible for images to have an ascent greater than
18362 their height, so don't get confused in that case. */
18363 if (it
->descent
< 0)
18366 #if 0 /* this breaks image tiling */
18367 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
18368 face_ascent
= face
->font
? FONT_BASE (face
->font
) : FRAME_BASELINE_OFFSET (it
->f
);
18369 if (face_ascent
> it
->ascent
)
18370 it
->ascent
= it
->phys_ascent
= face_ascent
;
18375 if (face
->box
!= FACE_NO_BOX
)
18377 if (face
->box_line_width
> 0)
18380 it
->ascent
+= face
->box_line_width
;
18381 if (slice
.y
+ slice
.height
== img
->height
)
18382 it
->descent
+= face
->box_line_width
;
18385 if (it
->start_of_box_run_p
&& slice
.x
== 0)
18386 it
->pixel_width
+= abs (face
->box_line_width
);
18387 if (it
->end_of_box_run_p
&& slice
.x
+ slice
.width
== img
->width
)
18388 it
->pixel_width
+= abs (face
->box_line_width
);
18391 take_vertical_position_into_account (it
);
18395 struct glyph
*glyph
;
18396 enum glyph_row_area area
= it
->area
;
18398 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
18399 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
18401 glyph
->charpos
= CHARPOS (it
->position
);
18402 glyph
->object
= it
->object
;
18403 glyph
->pixel_width
= it
->pixel_width
;
18404 glyph
->ascent
= glyph_ascent
;
18405 glyph
->descent
= it
->descent
;
18406 glyph
->voffset
= it
->voffset
;
18407 glyph
->type
= IMAGE_GLYPH
;
18408 glyph
->multibyte_p
= it
->multibyte_p
;
18409 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
18410 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
18411 glyph
->overlaps_vertically_p
= 0;
18412 glyph
->padding_p
= 0;
18413 glyph
->glyph_not_available_p
= 0;
18414 glyph
->face_id
= it
->face_id
;
18415 glyph
->u
.img_id
= img
->id
;
18416 glyph
->slice
= slice
;
18417 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
18418 ++it
->glyph_row
->used
[area
];
18420 else if (!fonts_changed_p
)
18422 it
->w
->ncols_scale_factor
++;
18423 fonts_changed_p
= 1;
18429 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
18430 of the glyph, WIDTH and HEIGHT are the width and height of the
18431 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
18434 append_stretch_glyph (it
, object
, width
, height
, ascent
)
18436 Lisp_Object object
;
18440 struct glyph
*glyph
;
18441 enum glyph_row_area area
= it
->area
;
18443 xassert (ascent
>= 0 && ascent
<= height
);
18445 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
18446 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
18448 glyph
->charpos
= CHARPOS (it
->position
);
18449 glyph
->object
= object
;
18450 glyph
->pixel_width
= width
;
18451 glyph
->ascent
= ascent
;
18452 glyph
->descent
= height
- ascent
;
18453 glyph
->voffset
= it
->voffset
;
18454 glyph
->type
= STRETCH_GLYPH
;
18455 glyph
->multibyte_p
= it
->multibyte_p
;
18456 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
18457 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
18458 glyph
->overlaps_vertically_p
= 0;
18459 glyph
->padding_p
= 0;
18460 glyph
->glyph_not_available_p
= 0;
18461 glyph
->face_id
= it
->face_id
;
18462 glyph
->u
.stretch
.ascent
= ascent
;
18463 glyph
->u
.stretch
.height
= height
;
18464 glyph
->slice
= null_glyph_slice
;
18465 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
18466 ++it
->glyph_row
->used
[area
];
18468 else if (!fonts_changed_p
)
18470 it
->w
->ncols_scale_factor
++;
18471 fonts_changed_p
= 1;
18476 /* Produce a stretch glyph for iterator IT. IT->object is the value
18477 of the glyph property displayed. The value must be a list
18478 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
18481 1. `:width WIDTH' specifies that the space should be WIDTH *
18482 canonical char width wide. WIDTH may be an integer or floating
18485 2. `:relative-width FACTOR' specifies that the width of the stretch
18486 should be computed from the width of the first character having the
18487 `glyph' property, and should be FACTOR times that width.
18489 3. `:align-to HPOS' specifies that the space should be wide enough
18490 to reach HPOS, a value in canonical character units.
18492 Exactly one of the above pairs must be present.
18494 4. `:height HEIGHT' specifies that the height of the stretch produced
18495 should be HEIGHT, measured in canonical character units.
18497 5. `:relative-height FACTOR' specifies that the height of the
18498 stretch should be FACTOR times the height of the characters having
18499 the glyph property.
18501 Either none or exactly one of 4 or 5 must be present.
18503 6. `:ascent ASCENT' specifies that ASCENT percent of the height
18504 of the stretch should be used for the ascent of the stretch.
18505 ASCENT must be in the range 0 <= ASCENT <= 100. */
18508 produce_stretch_glyph (it
)
18511 /* (space :width WIDTH :height HEIGHT ...) */
18512 Lisp_Object prop
, plist
;
18513 int width
= 0, height
= 0, align_to
= -1;
18514 int zero_width_ok_p
= 0, zero_height_ok_p
= 0;
18517 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
18518 XFontStruct
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
18520 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
18522 /* List should start with `space'. */
18523 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
18524 plist
= XCDR (it
->object
);
18526 /* Compute the width of the stretch. */
18527 if ((prop
= Fplist_get (plist
, QCwidth
), !NILP (prop
))
18528 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 1, 0))
18530 /* Absolute width `:width WIDTH' specified and valid. */
18531 zero_width_ok_p
= 1;
18534 else if (prop
= Fplist_get (plist
, QCrelative_width
),
18537 /* Relative width `:relative-width FACTOR' specified and valid.
18538 Compute the width of the characters having the `glyph'
18541 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
18544 if (it
->multibyte_p
)
18546 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT
? ZV
: GPT
)
18547 - IT_BYTEPOS (*it
));
18548 it2
.c
= STRING_CHAR_AND_LENGTH (p
, maxlen
, it2
.len
);
18551 it2
.c
= *p
, it2
.len
= 1;
18553 it2
.glyph_row
= NULL
;
18554 it2
.what
= IT_CHARACTER
;
18555 x_produce_glyphs (&it2
);
18556 width
= NUMVAL (prop
) * it2
.pixel_width
;
18558 else if ((prop
= Fplist_get (plist
, QCalign_to
), !NILP (prop
))
18559 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 1, &align_to
))
18561 if (it
->glyph_row
== NULL
|| !it
->glyph_row
->mode_line_p
)
18562 align_to
= (align_to
< 0
18564 : align_to
- window_box_left_offset (it
->w
, TEXT_AREA
));
18565 else if (align_to
< 0)
18566 align_to
= window_box_left_offset (it
->w
, TEXT_AREA
);
18567 width
= max (0, (int)tem
+ align_to
- it
->current_x
);
18568 zero_width_ok_p
= 1;
18571 /* Nothing specified -> width defaults to canonical char width. */
18572 width
= FRAME_COLUMN_WIDTH (it
->f
);
18574 if (width
<= 0 && (width
< 0 || !zero_width_ok_p
))
18577 /* Compute height. */
18578 if ((prop
= Fplist_get (plist
, QCheight
), !NILP (prop
))
18579 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 0, 0))
18582 zero_height_ok_p
= 1;
18584 else if (prop
= Fplist_get (plist
, QCrelative_height
),
18586 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
18588 height
= FONT_HEIGHT (font
);
18590 if (height
<= 0 && (height
< 0 || !zero_height_ok_p
))
18593 /* Compute percentage of height used for ascent. If
18594 `:ascent ASCENT' is present and valid, use that. Otherwise,
18595 derive the ascent from the font in use. */
18596 if (prop
= Fplist_get (plist
, QCascent
),
18597 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
18598 ascent
= height
* NUMVAL (prop
) / 100.0;
18599 else if (!NILP (prop
)
18600 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 0, 0))
18601 ascent
= min (max (0, (int)tem
), height
);
18603 ascent
= (height
* FONT_BASE (font
)) / FONT_HEIGHT (font
);
18605 if (width
> 0 && height
> 0 && it
->glyph_row
)
18607 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
18608 if (!STRINGP (object
))
18609 object
= it
->w
->buffer
;
18610 append_stretch_glyph (it
, object
, width
, height
, ascent
);
18613 it
->pixel_width
= width
;
18614 it
->ascent
= it
->phys_ascent
= ascent
;
18615 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
18616 it
->nglyphs
= width
> 0 && height
> 0 ? 1 : 0;
18618 if (width
> 0 && height
> 0 && face
->box
!= FACE_NO_BOX
)
18620 if (face
->box_line_width
> 0)
18622 it
->ascent
+= face
->box_line_width
;
18623 it
->descent
+= face
->box_line_width
;
18626 if (it
->start_of_box_run_p
)
18627 it
->pixel_width
+= abs (face
->box_line_width
);
18628 if (it
->end_of_box_run_p
)
18629 it
->pixel_width
+= abs (face
->box_line_width
);
18632 take_vertical_position_into_account (it
);
18635 /* Calculate line-height and line-spacing properties.
18636 An integer value specifies explicit pixel value.
18637 A float value specifies relative value to current face height.
18638 A cons (float . face-name) specifies relative value to
18639 height of specified face font.
18641 Returns height in pixels, or nil. */
18644 calc_line_height_property (it
, prop
, font
, boff
, total
)
18650 Lisp_Object position
, val
;
18651 Lisp_Object face_name
= Qnil
;
18652 int ascent
, descent
, height
, override
;
18654 if (STRINGP (it
->object
))
18655 position
= make_number (IT_STRING_CHARPOS (*it
));
18657 position
= make_number (IT_CHARPOS (*it
));
18659 val
= Fget_char_property (position
, prop
, it
->object
);
18664 if (total
&& CONSP (val
) && EQ (XCAR (val
), Qtotal
))
18670 if (INTEGERP (val
))
18675 face_name
= XCDR (val
);
18678 else if (SYMBOLP (val
))
18684 override
= EQ (prop
, Qline_height
);
18686 if (NILP (face_name
))
18688 font
= FRAME_FONT (it
->f
);
18689 boff
= FRAME_BASELINE_OFFSET (it
->f
);
18691 else if (EQ (face_name
, Qt
))
18699 struct font_info
*font_info
;
18701 face_id
= lookup_named_face (it
->f
, face_name
, ' ');
18703 return make_number (-1);
18705 face
= FACE_FROM_ID (it
->f
, face_id
);
18708 return make_number (-1);
18710 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
18711 boff
= font_info
->baseline_offset
;
18712 if (font_info
->vertical_centering
)
18713 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
18716 ascent
= FONT_BASE (font
) + boff
;
18717 descent
= FONT_DESCENT (font
) - boff
;
18721 it
->override_ascent
= ascent
;
18722 it
->override_descent
= descent
;
18723 it
->override_boff
= boff
;
18726 height
= ascent
+ descent
;
18728 height
= (int)(XFLOAT_DATA (val
) * height
);
18729 else if (INTEGERP (val
))
18730 height
*= XINT (val
);
18732 return make_number (height
);
18737 Produce glyphs/get display metrics for the display element IT is
18738 loaded with. See the description of struct display_iterator in
18739 dispextern.h for an overview of struct display_iterator. */
18742 x_produce_glyphs (it
)
18745 int extra_line_spacing
= it
->extra_line_spacing
;
18747 it
->glyph_not_available_p
= 0;
18749 if (it
->what
== IT_CHARACTER
)
18753 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
18755 int font_not_found_p
;
18756 struct font_info
*font_info
;
18757 int boff
; /* baseline offset */
18758 /* We may change it->multibyte_p upon unibyte<->multibyte
18759 conversion. So, save the current value now and restore it
18762 Note: It seems that we don't have to record multibyte_p in
18763 struct glyph because the character code itself tells if or
18764 not the character is multibyte. Thus, in the future, we must
18765 consider eliminating the field `multibyte_p' in the struct
18767 int saved_multibyte_p
= it
->multibyte_p
;
18769 /* Maybe translate single-byte characters to multibyte, or the
18771 it
->char_to_display
= it
->c
;
18772 if (!ASCII_BYTE_P (it
->c
))
18774 if (unibyte_display_via_language_environment
18775 && SINGLE_BYTE_CHAR_P (it
->c
)
18777 || !NILP (Vnonascii_translation_table
)))
18779 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
18780 it
->multibyte_p
= 1;
18781 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
18782 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
18784 else if (!SINGLE_BYTE_CHAR_P (it
->c
)
18785 && !it
->multibyte_p
)
18787 it
->multibyte_p
= 1;
18788 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
18789 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
18793 /* Get font to use. Encode IT->char_to_display. */
18794 get_char_face_and_encoding (it
->f
, it
->char_to_display
, it
->face_id
,
18795 &char2b
, it
->multibyte_p
, 0);
18798 /* When no suitable font found, use the default font. */
18799 font_not_found_p
= font
== NULL
;
18800 if (font_not_found_p
)
18802 font
= FRAME_FONT (it
->f
);
18803 boff
= FRAME_BASELINE_OFFSET (it
->f
);
18808 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
18809 boff
= font_info
->baseline_offset
;
18810 if (font_info
->vertical_centering
)
18811 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
18814 if (it
->char_to_display
>= ' '
18815 && (!it
->multibyte_p
|| it
->char_to_display
< 128))
18817 /* Either unibyte or ASCII. */
18822 pcm
= rif
->per_char_metric (font
, &char2b
,
18823 FONT_TYPE_FOR_UNIBYTE (font
, it
->char_to_display
));
18825 if (it
->override_ascent
>= 0)
18827 it
->ascent
= it
->override_ascent
;
18828 it
->descent
= it
->override_descent
;
18829 boff
= it
->override_boff
;
18833 it
->ascent
= FONT_BASE (font
) + boff
;
18834 it
->descent
= FONT_DESCENT (font
) - boff
;
18839 it
->phys_ascent
= pcm
->ascent
+ boff
;
18840 it
->phys_descent
= pcm
->descent
- boff
;
18841 it
->pixel_width
= pcm
->width
;
18845 it
->glyph_not_available_p
= 1;
18846 it
->phys_ascent
= it
->ascent
;
18847 it
->phys_descent
= it
->descent
;
18848 it
->pixel_width
= FONT_WIDTH (font
);
18851 if (it
->constrain_row_ascent_descent_p
)
18853 if (it
->descent
> it
->max_descent
)
18855 it
->ascent
+= it
->descent
- it
->max_descent
;
18856 it
->descent
= it
->max_descent
;
18858 if (it
->ascent
> it
->max_ascent
)
18860 it
->descent
= min (it
->max_descent
, it
->descent
+ it
->ascent
- it
->max_ascent
);
18861 it
->ascent
= it
->max_ascent
;
18863 it
->phys_ascent
= min (it
->phys_ascent
, it
->ascent
);
18864 it
->phys_descent
= min (it
->phys_descent
, it
->descent
);
18865 extra_line_spacing
= 0;
18868 /* If this is a space inside a region of text with
18869 `space-width' property, change its width. */
18870 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
18872 it
->pixel_width
*= XFLOATINT (it
->space_width
);
18874 /* If face has a box, add the box thickness to the character
18875 height. If character has a box line to the left and/or
18876 right, add the box line width to the character's width. */
18877 if (face
->box
!= FACE_NO_BOX
)
18879 int thick
= face
->box_line_width
;
18883 it
->ascent
+= thick
;
18884 it
->descent
+= thick
;
18889 if (it
->start_of_box_run_p
)
18890 it
->pixel_width
+= thick
;
18891 if (it
->end_of_box_run_p
)
18892 it
->pixel_width
+= thick
;
18895 /* If face has an overline, add the height of the overline
18896 (1 pixel) and a 1 pixel margin to the character height. */
18897 if (face
->overline_p
)
18900 if (it
->constrain_row_ascent_descent_p
)
18902 if (it
->ascent
> it
->max_ascent
)
18903 it
->ascent
= it
->max_ascent
;
18904 if (it
->descent
> it
->max_descent
)
18905 it
->descent
= it
->max_descent
;
18908 take_vertical_position_into_account (it
);
18910 /* If we have to actually produce glyphs, do it. */
18915 /* Translate a space with a `space-width' property
18916 into a stretch glyph. */
18917 int ascent
= (((it
->ascent
+ it
->descent
) * FONT_BASE (font
))
18918 / FONT_HEIGHT (font
));
18919 append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
18920 it
->ascent
+ it
->descent
, ascent
);
18925 /* If characters with lbearing or rbearing are displayed
18926 in this line, record that fact in a flag of the
18927 glyph row. This is used to optimize X output code. */
18928 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
18929 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
18932 else if (it
->char_to_display
== '\n')
18934 /* A newline has no width but we need the height of the line.
18935 But if previous part of the line set a height, don't
18936 increase that height */
18938 Lisp_Object height
;
18940 it
->override_ascent
= -1;
18941 it
->pixel_width
= 0;
18944 height
= calc_line_height_property(it
, Qline_height
, font
, boff
, 0);
18946 if (it
->override_ascent
>= 0)
18948 it
->ascent
= it
->override_ascent
;
18949 it
->descent
= it
->override_descent
;
18950 boff
= it
->override_boff
;
18954 it
->ascent
= FONT_BASE (font
) + boff
;
18955 it
->descent
= FONT_DESCENT (font
) - boff
;
18958 if (EQ (height
, make_number(0)))
18960 if (it
->descent
> it
->max_descent
)
18962 it
->ascent
+= it
->descent
- it
->max_descent
;
18963 it
->descent
= it
->max_descent
;
18965 if (it
->ascent
> it
->max_ascent
)
18967 it
->descent
= min (it
->max_descent
, it
->descent
+ it
->ascent
- it
->max_ascent
);
18968 it
->ascent
= it
->max_ascent
;
18970 it
->phys_ascent
= min (it
->phys_ascent
, it
->ascent
);
18971 it
->phys_descent
= min (it
->phys_descent
, it
->descent
);
18972 it
->constrain_row_ascent_descent_p
= 1;
18973 extra_line_spacing
= 0;
18977 Lisp_Object spacing
;
18980 it
->phys_ascent
= it
->ascent
;
18981 it
->phys_descent
= it
->descent
;
18983 if ((it
->max_ascent
> 0 || it
->max_descent
> 0)
18984 && face
->box
!= FACE_NO_BOX
18985 && face
->box_line_width
> 0)
18987 it
->ascent
+= face
->box_line_width
;
18988 it
->descent
+= face
->box_line_width
;
18991 && XINT (height
) > it
->ascent
+ it
->descent
)
18992 it
->ascent
= XINT (height
) - it
->descent
;
18994 spacing
= calc_line_height_property(it
, Qline_spacing
, font
, boff
, &total
);
18995 if (INTEGERP (spacing
))
18997 extra_line_spacing
= XINT (spacing
);
18999 extra_line_spacing
-= (it
->phys_ascent
+ it
->phys_descent
);
19003 else if (it
->char_to_display
== '\t')
19005 int tab_width
= it
->tab_width
* FRAME_COLUMN_WIDTH (it
->f
);
19006 int x
= it
->current_x
+ it
->continuation_lines_width
;
19007 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
19009 /* If the distance from the current position to the next tab
19010 stop is less than a canonical character width, use the
19011 tab stop after that. */
19012 if (next_tab_x
- x
< FRAME_COLUMN_WIDTH (it
->f
))
19013 next_tab_x
+= tab_width
;
19015 it
->pixel_width
= next_tab_x
- x
;
19017 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
19018 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
19022 append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
19023 it
->ascent
+ it
->descent
, it
->ascent
);
19028 /* A multi-byte character. Assume that the display width of the
19029 character is the width of the character multiplied by the
19030 width of the font. */
19032 /* If we found a font, this font should give us the right
19033 metrics. If we didn't find a font, use the frame's
19034 default font and calculate the width of the character
19035 from the charset width; this is what old redisplay code
19038 pcm
= rif
->per_char_metric (font
, &char2b
,
19039 FONT_TYPE_FOR_MULTIBYTE (font
, it
->c
));
19041 if (font_not_found_p
|| !pcm
)
19043 int charset
= CHAR_CHARSET (it
->char_to_display
);
19045 it
->glyph_not_available_p
= 1;
19046 it
->pixel_width
= (FRAME_COLUMN_WIDTH (it
->f
)
19047 * CHARSET_WIDTH (charset
));
19048 it
->phys_ascent
= FONT_BASE (font
) + boff
;
19049 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
19053 it
->pixel_width
= pcm
->width
;
19054 it
->phys_ascent
= pcm
->ascent
+ boff
;
19055 it
->phys_descent
= pcm
->descent
- boff
;
19057 && (pcm
->lbearing
< 0
19058 || pcm
->rbearing
> pcm
->width
))
19059 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
19062 it
->ascent
= FONT_BASE (font
) + boff
;
19063 it
->descent
= FONT_DESCENT (font
) - boff
;
19064 if (face
->box
!= FACE_NO_BOX
)
19066 int thick
= face
->box_line_width
;
19070 it
->ascent
+= thick
;
19071 it
->descent
+= thick
;
19076 if (it
->start_of_box_run_p
)
19077 it
->pixel_width
+= thick
;
19078 if (it
->end_of_box_run_p
)
19079 it
->pixel_width
+= thick
;
19082 /* If face has an overline, add the height of the overline
19083 (1 pixel) and a 1 pixel margin to the character height. */
19084 if (face
->overline_p
)
19087 take_vertical_position_into_account (it
);
19092 it
->multibyte_p
= saved_multibyte_p
;
19094 else if (it
->what
== IT_COMPOSITION
)
19096 /* Note: A composition is represented as one glyph in the
19097 glyph matrix. There are no padding glyphs. */
19100 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
19102 int font_not_found_p
;
19103 struct font_info
*font_info
;
19104 int boff
; /* baseline offset */
19105 struct composition
*cmp
= composition_table
[it
->cmp_id
];
19107 /* Maybe translate single-byte characters to multibyte. */
19108 it
->char_to_display
= it
->c
;
19109 if (unibyte_display_via_language_environment
19110 && SINGLE_BYTE_CHAR_P (it
->c
)
19113 && !NILP (Vnonascii_translation_table
))))
19115 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
19118 /* Get face and font to use. Encode IT->char_to_display. */
19119 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
19120 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
19121 get_char_face_and_encoding (it
->f
, it
->char_to_display
, it
->face_id
,
19122 &char2b
, it
->multibyte_p
, 0);
19125 /* When no suitable font found, use the default font. */
19126 font_not_found_p
= font
== NULL
;
19127 if (font_not_found_p
)
19129 font
= FRAME_FONT (it
->f
);
19130 boff
= FRAME_BASELINE_OFFSET (it
->f
);
19135 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
19136 boff
= font_info
->baseline_offset
;
19137 if (font_info
->vertical_centering
)
19138 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
19141 /* There are no padding glyphs, so there is only one glyph to
19142 produce for the composition. Important is that pixel_width,
19143 ascent and descent are the values of what is drawn by
19144 draw_glyphs (i.e. the values of the overall glyphs composed). */
19147 /* If we have not yet calculated pixel size data of glyphs of
19148 the composition for the current face font, calculate them
19149 now. Theoretically, we have to check all fonts for the
19150 glyphs, but that requires much time and memory space. So,
19151 here we check only the font of the first glyph. This leads
19152 to incorrect display very rarely, and C-l (recenter) can
19153 correct the display anyway. */
19154 if (cmp
->font
!= (void *) font
)
19156 /* Ascent and descent of the font of the first character of
19157 this composition (adjusted by baseline offset). Ascent
19158 and descent of overall glyphs should not be less than
19159 them respectively. */
19160 int font_ascent
= FONT_BASE (font
) + boff
;
19161 int font_descent
= FONT_DESCENT (font
) - boff
;
19162 /* Bounding box of the overall glyphs. */
19163 int leftmost
, rightmost
, lowest
, highest
;
19164 int i
, width
, ascent
, descent
;
19166 cmp
->font
= (void *) font
;
19168 /* Initialize the bounding box. */
19170 && (pcm
= rif
->per_char_metric (font
, &char2b
,
19171 FONT_TYPE_FOR_MULTIBYTE (font
, it
->c
))))
19173 width
= pcm
->width
;
19174 ascent
= pcm
->ascent
;
19175 descent
= pcm
->descent
;
19179 width
= FONT_WIDTH (font
);
19180 ascent
= FONT_BASE (font
);
19181 descent
= FONT_DESCENT (font
);
19185 lowest
= - descent
+ boff
;
19186 highest
= ascent
+ boff
;
19190 && font_info
->default_ascent
19191 && CHAR_TABLE_P (Vuse_default_ascent
)
19192 && !NILP (Faref (Vuse_default_ascent
,
19193 make_number (it
->char_to_display
))))
19194 highest
= font_info
->default_ascent
+ boff
;
19196 /* Draw the first glyph at the normal position. It may be
19197 shifted to right later if some other glyphs are drawn at
19199 cmp
->offsets
[0] = 0;
19200 cmp
->offsets
[1] = boff
;
19202 /* Set cmp->offsets for the remaining glyphs. */
19203 for (i
= 1; i
< cmp
->glyph_len
; i
++)
19205 int left
, right
, btm
, top
;
19206 int ch
= COMPOSITION_GLYPH (cmp
, i
);
19207 int face_id
= FACE_FOR_CHAR (it
->f
, face
, ch
);
19209 face
= FACE_FROM_ID (it
->f
, face_id
);
19210 get_char_face_and_encoding (it
->f
, ch
, face
->id
,
19211 &char2b
, it
->multibyte_p
, 0);
19215 font
= FRAME_FONT (it
->f
);
19216 boff
= FRAME_BASELINE_OFFSET (it
->f
);
19222 = FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
19223 boff
= font_info
->baseline_offset
;
19224 if (font_info
->vertical_centering
)
19225 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
19229 && (pcm
= rif
->per_char_metric (font
, &char2b
,
19230 FONT_TYPE_FOR_MULTIBYTE (font
, ch
))))
19232 width
= pcm
->width
;
19233 ascent
= pcm
->ascent
;
19234 descent
= pcm
->descent
;
19238 width
= FONT_WIDTH (font
);
19243 if (cmp
->method
!= COMPOSITION_WITH_RULE_ALTCHARS
)
19245 /* Relative composition with or without
19246 alternate chars. */
19247 left
= (leftmost
+ rightmost
- width
) / 2;
19248 btm
= - descent
+ boff
;
19249 if (font_info
&& font_info
->relative_compose
19250 && (! CHAR_TABLE_P (Vignore_relative_composition
)
19251 || NILP (Faref (Vignore_relative_composition
,
19252 make_number (ch
)))))
19255 if (- descent
>= font_info
->relative_compose
)
19256 /* One extra pixel between two glyphs. */
19258 else if (ascent
<= 0)
19259 /* One extra pixel between two glyphs. */
19260 btm
= lowest
- 1 - ascent
- descent
;
19265 /* A composition rule is specified by an integer
19266 value that encodes global and new reference
19267 points (GREF and NREF). GREF and NREF are
19268 specified by numbers as below:
19270 0---1---2 -- ascent
19274 9--10--11 -- center
19276 ---3---4---5--- baseline
19278 6---7---8 -- descent
19280 int rule
= COMPOSITION_RULE (cmp
, i
);
19281 int gref
, nref
, grefx
, grefy
, nrefx
, nrefy
;
19283 COMPOSITION_DECODE_RULE (rule
, gref
, nref
);
19284 grefx
= gref
% 3, nrefx
= nref
% 3;
19285 grefy
= gref
/ 3, nrefy
= nref
/ 3;
19288 + grefx
* (rightmost
- leftmost
) / 2
19289 - nrefx
* width
/ 2);
19290 btm
= ((grefy
== 0 ? highest
19292 : grefy
== 2 ? lowest
19293 : (highest
+ lowest
) / 2)
19294 - (nrefy
== 0 ? ascent
+ descent
19295 : nrefy
== 1 ? descent
- boff
19297 : (ascent
+ descent
) / 2));
19300 cmp
->offsets
[i
* 2] = left
;
19301 cmp
->offsets
[i
* 2 + 1] = btm
+ descent
;
19303 /* Update the bounding box of the overall glyphs. */
19304 right
= left
+ width
;
19305 top
= btm
+ descent
+ ascent
;
19306 if (left
< leftmost
)
19308 if (right
> rightmost
)
19316 /* If there are glyphs whose x-offsets are negative,
19317 shift all glyphs to the right and make all x-offsets
19321 for (i
= 0; i
< cmp
->glyph_len
; i
++)
19322 cmp
->offsets
[i
* 2] -= leftmost
;
19323 rightmost
-= leftmost
;
19326 cmp
->pixel_width
= rightmost
;
19327 cmp
->ascent
= highest
;
19328 cmp
->descent
= - lowest
;
19329 if (cmp
->ascent
< font_ascent
)
19330 cmp
->ascent
= font_ascent
;
19331 if (cmp
->descent
< font_descent
)
19332 cmp
->descent
= font_descent
;
19335 it
->pixel_width
= cmp
->pixel_width
;
19336 it
->ascent
= it
->phys_ascent
= cmp
->ascent
;
19337 it
->descent
= it
->phys_descent
= cmp
->descent
;
19339 if (face
->box
!= FACE_NO_BOX
)
19341 int thick
= face
->box_line_width
;
19345 it
->ascent
+= thick
;
19346 it
->descent
+= thick
;
19351 if (it
->start_of_box_run_p
)
19352 it
->pixel_width
+= thick
;
19353 if (it
->end_of_box_run_p
)
19354 it
->pixel_width
+= thick
;
19357 /* If face has an overline, add the height of the overline
19358 (1 pixel) and a 1 pixel margin to the character height. */
19359 if (face
->overline_p
)
19362 take_vertical_position_into_account (it
);
19365 append_composite_glyph (it
);
19367 else if (it
->what
== IT_IMAGE
)
19368 produce_image_glyph (it
);
19369 else if (it
->what
== IT_STRETCH
)
19370 produce_stretch_glyph (it
);
19372 /* Accumulate dimensions. Note: can't assume that it->descent > 0
19373 because this isn't true for images with `:ascent 100'. */
19374 xassert (it
->ascent
>= 0 && it
->descent
>= 0);
19375 if (it
->area
== TEXT_AREA
)
19376 it
->current_x
+= it
->pixel_width
;
19378 if (extra_line_spacing
> 0)
19379 it
->descent
+= extra_line_spacing
;
19381 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
19382 it
->max_descent
= max (it
->max_descent
, it
->descent
);
19383 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
19384 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
19388 Output LEN glyphs starting at START at the nominal cursor position.
19389 Advance the nominal cursor over the text. The global variable
19390 updated_window contains the window being updated, updated_row is
19391 the glyph row being updated, and updated_area is the area of that
19392 row being updated. */
19395 x_write_glyphs (start
, len
)
19396 struct glyph
*start
;
19401 xassert (updated_window
&& updated_row
);
19404 /* Write glyphs. */
19406 hpos
= start
- updated_row
->glyphs
[updated_area
];
19407 x
= draw_glyphs (updated_window
, output_cursor
.x
,
19408 updated_row
, updated_area
,
19410 DRAW_NORMAL_TEXT
, 0);
19412 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
19413 if (updated_area
== TEXT_AREA
19414 && updated_window
->phys_cursor_on_p
19415 && updated_window
->phys_cursor
.vpos
== output_cursor
.vpos
19416 && updated_window
->phys_cursor
.hpos
>= hpos
19417 && updated_window
->phys_cursor
.hpos
< hpos
+ len
)
19418 updated_window
->phys_cursor_on_p
= 0;
19422 /* Advance the output cursor. */
19423 output_cursor
.hpos
+= len
;
19424 output_cursor
.x
= x
;
19429 Insert LEN glyphs from START at the nominal cursor position. */
19432 x_insert_glyphs (start
, len
)
19433 struct glyph
*start
;
19438 int line_height
, shift_by_width
, shifted_region_width
;
19439 struct glyph_row
*row
;
19440 struct glyph
*glyph
;
19441 int frame_x
, frame_y
, hpos
;
19443 xassert (updated_window
&& updated_row
);
19445 w
= updated_window
;
19446 f
= XFRAME (WINDOW_FRAME (w
));
19448 /* Get the height of the line we are in. */
19450 line_height
= row
->height
;
19452 /* Get the width of the glyphs to insert. */
19453 shift_by_width
= 0;
19454 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
19455 shift_by_width
+= glyph
->pixel_width
;
19457 /* Get the width of the region to shift right. */
19458 shifted_region_width
= (window_box_width (w
, updated_area
)
19463 frame_x
= window_box_left (w
, updated_area
) + output_cursor
.x
;
19464 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
19466 rif
->shift_glyphs_for_insert (f
, frame_x
, frame_y
, shifted_region_width
,
19467 line_height
, shift_by_width
);
19469 /* Write the glyphs. */
19470 hpos
= start
- row
->glyphs
[updated_area
];
19471 draw_glyphs (w
, output_cursor
.x
, row
, updated_area
,
19473 DRAW_NORMAL_TEXT
, 0);
19475 /* Advance the output cursor. */
19476 output_cursor
.hpos
+= len
;
19477 output_cursor
.x
+= shift_by_width
;
19483 Erase the current text line from the nominal cursor position
19484 (inclusive) to pixel column TO_X (exclusive). The idea is that
19485 everything from TO_X onward is already erased.
19487 TO_X is a pixel position relative to updated_area of
19488 updated_window. TO_X == -1 means clear to the end of this area. */
19491 x_clear_end_of_line (to_x
)
19495 struct window
*w
= updated_window
;
19496 int max_x
, min_y
, max_y
;
19497 int from_x
, from_y
, to_y
;
19499 xassert (updated_window
&& updated_row
);
19500 f
= XFRAME (w
->frame
);
19502 if (updated_row
->full_width_p
)
19503 max_x
= WINDOW_TOTAL_WIDTH (w
);
19505 max_x
= window_box_width (w
, updated_area
);
19506 max_y
= window_text_bottom_y (w
);
19508 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
19509 of window. For TO_X > 0, truncate to end of drawing area. */
19515 to_x
= min (to_x
, max_x
);
19517 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
19519 /* Notice if the cursor will be cleared by this operation. */
19520 if (!updated_row
->full_width_p
)
19521 notice_overwritten_cursor (w
, updated_area
,
19522 output_cursor
.x
, -1,
19524 MATRIX_ROW_BOTTOM_Y (updated_row
));
19526 from_x
= output_cursor
.x
;
19528 /* Translate to frame coordinates. */
19529 if (updated_row
->full_width_p
)
19531 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
19532 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
19536 int area_left
= window_box_left (w
, updated_area
);
19537 from_x
+= area_left
;
19541 min_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
19542 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
19543 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
19545 /* Prevent inadvertently clearing to end of the X window. */
19546 if (to_x
> from_x
&& to_y
> from_y
)
19549 rif
->clear_frame_area (f
, from_x
, from_y
,
19550 to_x
- from_x
, to_y
- from_y
);
19555 #endif /* HAVE_WINDOW_SYSTEM */
19559 /***********************************************************************
19561 ***********************************************************************/
19563 /* Value is the internal representation of the specified cursor type
19564 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
19565 of the bar cursor. */
19567 static enum text_cursor_kinds
19568 get_specified_cursor_type (arg
, width
)
19572 enum text_cursor_kinds type
;
19577 if (EQ (arg
, Qbox
))
19578 return FILLED_BOX_CURSOR
;
19580 if (EQ (arg
, Qhollow
))
19581 return HOLLOW_BOX_CURSOR
;
19583 if (EQ (arg
, Qbar
))
19590 && EQ (XCAR (arg
), Qbar
)
19591 && INTEGERP (XCDR (arg
))
19592 && XINT (XCDR (arg
)) >= 0)
19594 *width
= XINT (XCDR (arg
));
19598 if (EQ (arg
, Qhbar
))
19601 return HBAR_CURSOR
;
19605 && EQ (XCAR (arg
), Qhbar
)
19606 && INTEGERP (XCDR (arg
))
19607 && XINT (XCDR (arg
)) >= 0)
19609 *width
= XINT (XCDR (arg
));
19610 return HBAR_CURSOR
;
19613 /* Treat anything unknown as "hollow box cursor".
19614 It was bad to signal an error; people have trouble fixing
19615 .Xdefaults with Emacs, when it has something bad in it. */
19616 type
= HOLLOW_BOX_CURSOR
;
19621 /* Set the default cursor types for specified frame. */
19623 set_frame_cursor_types (f
, arg
)
19630 FRAME_DESIRED_CURSOR (f
) = get_specified_cursor_type (arg
, &width
);
19631 FRAME_CURSOR_WIDTH (f
) = width
;
19633 /* By default, set up the blink-off state depending on the on-state. */
19635 tem
= Fassoc (arg
, Vblink_cursor_alist
);
19638 FRAME_BLINK_OFF_CURSOR (f
)
19639 = get_specified_cursor_type (XCDR (tem
), &width
);
19640 FRAME_BLINK_OFF_CURSOR_WIDTH (f
) = width
;
19643 FRAME_BLINK_OFF_CURSOR (f
) = DEFAULT_CURSOR
;
19647 /* Return the cursor we want to be displayed in window W. Return
19648 width of bar/hbar cursor through WIDTH arg. Return with
19649 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
19650 (i.e. if the `system caret' should track this cursor).
19652 In a mini-buffer window, we want the cursor only to appear if we
19653 are reading input from this window. For the selected window, we
19654 want the cursor type given by the frame parameter or buffer local
19655 setting of cursor-type. If explicitly marked off, draw no cursor.
19656 In all other cases, we want a hollow box cursor. */
19658 static enum text_cursor_kinds
19659 get_window_cursor_type (w
, glyph
, width
, active_cursor
)
19661 struct glyph
*glyph
;
19663 int *active_cursor
;
19665 struct frame
*f
= XFRAME (w
->frame
);
19666 struct buffer
*b
= XBUFFER (w
->buffer
);
19667 int cursor_type
= DEFAULT_CURSOR
;
19668 Lisp_Object alt_cursor
;
19669 int non_selected
= 0;
19671 *active_cursor
= 1;
19674 if (cursor_in_echo_area
19675 && FRAME_HAS_MINIBUF_P (f
)
19676 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
19678 if (w
== XWINDOW (echo_area_window
))
19680 *width
= FRAME_CURSOR_WIDTH (f
);
19681 return FRAME_DESIRED_CURSOR (f
);
19684 *active_cursor
= 0;
19688 /* Nonselected window or nonselected frame. */
19689 else if (w
!= XWINDOW (f
->selected_window
)
19690 #ifdef HAVE_WINDOW_SYSTEM
19691 || f
!= FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
19695 *active_cursor
= 0;
19697 if (MINI_WINDOW_P (w
) && minibuf_level
== 0)
19703 /* Never display a cursor in a window in which cursor-type is nil. */
19704 if (NILP (b
->cursor_type
))
19707 /* Use cursor-in-non-selected-windows for non-selected window or frame. */
19710 alt_cursor
= Fbuffer_local_value (Qcursor_in_non_selected_windows
, w
->buffer
);
19711 return get_specified_cursor_type (alt_cursor
, width
);
19714 /* Get the normal cursor type for this window. */
19715 if (EQ (b
->cursor_type
, Qt
))
19717 cursor_type
= FRAME_DESIRED_CURSOR (f
);
19718 *width
= FRAME_CURSOR_WIDTH (f
);
19721 cursor_type
= get_specified_cursor_type (b
->cursor_type
, width
);
19723 /* Use normal cursor if not blinked off. */
19724 if (!w
->cursor_off_p
)
19726 if (glyph
!= NULL
&& glyph
->type
== IMAGE_GLYPH
) {
19727 if (cursor_type
== FILLED_BOX_CURSOR
)
19728 cursor_type
= HOLLOW_BOX_CURSOR
;
19730 return cursor_type
;
19733 /* Cursor is blinked off, so determine how to "toggle" it. */
19735 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
19736 if ((alt_cursor
= Fassoc (b
->cursor_type
, Vblink_cursor_alist
), !NILP (alt_cursor
)))
19737 return get_specified_cursor_type (XCDR (alt_cursor
), width
);
19739 /* Then see if frame has specified a specific blink off cursor type. */
19740 if (FRAME_BLINK_OFF_CURSOR (f
) != DEFAULT_CURSOR
)
19742 *width
= FRAME_BLINK_OFF_CURSOR_WIDTH (f
);
19743 return FRAME_BLINK_OFF_CURSOR (f
);
19747 /* Some people liked having a permanently visible blinking cursor,
19748 while others had very strong opinions against it. So it was
19749 decided to remove it. KFS 2003-09-03 */
19751 /* Finally perform built-in cursor blinking:
19752 filled box <-> hollow box
19753 wide [h]bar <-> narrow [h]bar
19754 narrow [h]bar <-> no cursor
19755 other type <-> no cursor */
19757 if (cursor_type
== FILLED_BOX_CURSOR
)
19758 return HOLLOW_BOX_CURSOR
;
19760 if ((cursor_type
== BAR_CURSOR
|| cursor_type
== HBAR_CURSOR
) && *width
> 1)
19763 return cursor_type
;
19771 #ifdef HAVE_WINDOW_SYSTEM
19773 /* Notice when the text cursor of window W has been completely
19774 overwritten by a drawing operation that outputs glyphs in AREA
19775 starting at X0 and ending at X1 in the line starting at Y0 and
19776 ending at Y1. X coordinates are area-relative. X1 < 0 means all
19777 the rest of the line after X0 has been written. Y coordinates
19778 are window-relative. */
19781 notice_overwritten_cursor (w
, area
, x0
, x1
, y0
, y1
)
19783 enum glyph_row_area area
;
19784 int x0
, y0
, x1
, y1
;
19786 int cx0
, cx1
, cy0
, cy1
;
19787 struct glyph_row
*row
;
19789 if (!w
->phys_cursor_on_p
)
19791 if (area
!= TEXT_AREA
)
19794 row
= w
->current_matrix
->rows
+ w
->phys_cursor
.vpos
;
19795 if (!row
->displays_text_p
)
19798 if (row
->cursor_in_fringe_p
)
19800 row
->cursor_in_fringe_p
= 0;
19801 draw_fringe_bitmap (w
, row
, 0);
19802 w
->phys_cursor_on_p
= 0;
19806 cx0
= w
->phys_cursor
.x
;
19807 cx1
= cx0
+ w
->phys_cursor_width
;
19808 if (x0
> cx0
|| (x1
>= 0 && x1
< cx1
))
19811 /* The cursor image will be completely removed from the
19812 screen if the output area intersects the cursor area in
19813 y-direction. When we draw in [y0 y1[, and some part of
19814 the cursor is at y < y0, that part must have been drawn
19815 before. When scrolling, the cursor is erased before
19816 actually scrolling, so we don't come here. When not
19817 scrolling, the rows above the old cursor row must have
19818 changed, and in this case these rows must have written
19819 over the cursor image.
19821 Likewise if part of the cursor is below y1, with the
19822 exception of the cursor being in the first blank row at
19823 the buffer and window end because update_text_area
19824 doesn't draw that row. (Except when it does, but
19825 that's handled in update_text_area.) */
19827 cy0
= w
->phys_cursor
.y
;
19828 cy1
= cy0
+ w
->phys_cursor_height
;
19829 if ((y0
< cy0
|| y0
>= cy1
) && (y1
<= cy0
|| y1
>= cy1
))
19832 w
->phys_cursor_on_p
= 0;
19835 #endif /* HAVE_WINDOW_SYSTEM */
19838 /************************************************************************
19840 ************************************************************************/
19842 #ifdef HAVE_WINDOW_SYSTEM
19845 Fix the display of area AREA of overlapping row ROW in window W. */
19848 x_fix_overlapping_area (w
, row
, area
)
19850 struct glyph_row
*row
;
19851 enum glyph_row_area area
;
19858 for (i
= 0; i
< row
->used
[area
];)
19860 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
19862 int start
= i
, start_x
= x
;
19866 x
+= row
->glyphs
[area
][i
].pixel_width
;
19869 while (i
< row
->used
[area
]
19870 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
19872 draw_glyphs (w
, start_x
, row
, area
,
19874 DRAW_NORMAL_TEXT
, 1);
19878 x
+= row
->glyphs
[area
][i
].pixel_width
;
19888 Draw the cursor glyph of window W in glyph row ROW. See the
19889 comment of draw_glyphs for the meaning of HL. */
19892 draw_phys_cursor_glyph (w
, row
, hl
)
19894 struct glyph_row
*row
;
19895 enum draw_glyphs_face hl
;
19897 /* If cursor hpos is out of bounds, don't draw garbage. This can
19898 happen in mini-buffer windows when switching between echo area
19899 glyphs and mini-buffer. */
19900 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
19902 int on_p
= w
->phys_cursor_on_p
;
19904 x1
= draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
19905 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
19907 w
->phys_cursor_on_p
= on_p
;
19909 if (hl
== DRAW_CURSOR
)
19910 w
->phys_cursor_width
= x1
- w
->phys_cursor
.x
;
19911 /* When we erase the cursor, and ROW is overlapped by other
19912 rows, make sure that these overlapping parts of other rows
19914 else if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
19916 if (row
> w
->current_matrix
->rows
19917 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
19918 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
);
19920 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
19921 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
19922 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
);
19929 Erase the image of a cursor of window W from the screen. */
19932 erase_phys_cursor (w
)
19935 struct frame
*f
= XFRAME (w
->frame
);
19936 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
19937 int hpos
= w
->phys_cursor
.hpos
;
19938 int vpos
= w
->phys_cursor
.vpos
;
19939 int mouse_face_here_p
= 0;
19940 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
19941 struct glyph_row
*cursor_row
;
19942 struct glyph
*cursor_glyph
;
19943 enum draw_glyphs_face hl
;
19945 /* No cursor displayed or row invalidated => nothing to do on the
19947 if (w
->phys_cursor_type
== NO_CURSOR
)
19948 goto mark_cursor_off
;
19950 /* VPOS >= active_glyphs->nrows means that window has been resized.
19951 Don't bother to erase the cursor. */
19952 if (vpos
>= active_glyphs
->nrows
)
19953 goto mark_cursor_off
;
19955 /* If row containing cursor is marked invalid, there is nothing we
19957 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
19958 if (!cursor_row
->enabled_p
)
19959 goto mark_cursor_off
;
19961 /* If row is completely invisible, don't attempt to delete a cursor which
19962 isn't there. This can happen if cursor is at top of a window, and
19963 we switch to a buffer with a header line in that window. */
19964 if (cursor_row
->visible_height
<= 0)
19965 goto mark_cursor_off
;
19967 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
19968 if (cursor_row
->cursor_in_fringe_p
)
19970 cursor_row
->cursor_in_fringe_p
= 0;
19971 draw_fringe_bitmap (w
, cursor_row
, 0);
19972 goto mark_cursor_off
;
19975 /* This can happen when the new row is shorter than the old one.
19976 In this case, either draw_glyphs or clear_end_of_line
19977 should have cleared the cursor. Note that we wouldn't be
19978 able to erase the cursor in this case because we don't have a
19979 cursor glyph at hand. */
19980 if (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])
19981 goto mark_cursor_off
;
19983 /* If the cursor is in the mouse face area, redisplay that when
19984 we clear the cursor. */
19985 if (! NILP (dpyinfo
->mouse_face_window
)
19986 && w
== XWINDOW (dpyinfo
->mouse_face_window
)
19987 && (vpos
> dpyinfo
->mouse_face_beg_row
19988 || (vpos
== dpyinfo
->mouse_face_beg_row
19989 && hpos
>= dpyinfo
->mouse_face_beg_col
))
19990 && (vpos
< dpyinfo
->mouse_face_end_row
19991 || (vpos
== dpyinfo
->mouse_face_end_row
19992 && hpos
< dpyinfo
->mouse_face_end_col
))
19993 /* Don't redraw the cursor's spot in mouse face if it is at the
19994 end of a line (on a newline). The cursor appears there, but
19995 mouse highlighting does not. */
19996 && cursor_row
->used
[TEXT_AREA
] > hpos
)
19997 mouse_face_here_p
= 1;
19999 /* Maybe clear the display under the cursor. */
20000 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
20003 int header_line_height
= WINDOW_HEADER_LINE_HEIGHT (w
);
20005 cursor_glyph
= get_phys_cursor_glyph (w
);
20006 if (cursor_glyph
== NULL
)
20007 goto mark_cursor_off
;
20009 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
20010 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
, cursor_row
->y
));
20012 rif
->clear_frame_area (f
, x
, y
,
20013 cursor_glyph
->pixel_width
, cursor_row
->visible_height
);
20016 /* Erase the cursor by redrawing the character underneath it. */
20017 if (mouse_face_here_p
)
20018 hl
= DRAW_MOUSE_FACE
;
20020 hl
= DRAW_NORMAL_TEXT
;
20021 draw_phys_cursor_glyph (w
, cursor_row
, hl
);
20024 w
->phys_cursor_on_p
= 0;
20025 w
->phys_cursor_type
= NO_CURSOR
;
20030 Display or clear cursor of window W. If ON is zero, clear the
20031 cursor. If it is non-zero, display the cursor. If ON is nonzero,
20032 where to put the cursor is specified by HPOS, VPOS, X and Y. */
20035 display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
)
20037 int on
, hpos
, vpos
, x
, y
;
20039 struct frame
*f
= XFRAME (w
->frame
);
20040 int new_cursor_type
;
20041 int new_cursor_width
;
20043 struct glyph_row
*glyph_row
;
20044 struct glyph
*glyph
;
20046 /* This is pointless on invisible frames, and dangerous on garbaged
20047 windows and frames; in the latter case, the frame or window may
20048 be in the midst of changing its size, and x and y may be off the
20050 if (! FRAME_VISIBLE_P (f
)
20051 || FRAME_GARBAGED_P (f
)
20052 || vpos
>= w
->current_matrix
->nrows
20053 || hpos
>= w
->current_matrix
->matrix_w
)
20056 /* If cursor is off and we want it off, return quickly. */
20057 if (!on
&& !w
->phys_cursor_on_p
)
20060 glyph_row
= MATRIX_ROW (w
->current_matrix
, vpos
);
20061 /* If cursor row is not enabled, we don't really know where to
20062 display the cursor. */
20063 if (!glyph_row
->enabled_p
)
20065 w
->phys_cursor_on_p
= 0;
20070 if (!glyph_row
->exact_window_width_line_p
20071 || hpos
< glyph_row
->used
[TEXT_AREA
])
20072 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
20074 xassert (interrupt_input_blocked
);
20076 /* Set new_cursor_type to the cursor we want to be displayed. */
20077 new_cursor_type
= get_window_cursor_type (w
, glyph
,
20078 &new_cursor_width
, &active_cursor
);
20080 /* If cursor is currently being shown and we don't want it to be or
20081 it is in the wrong place, or the cursor type is not what we want,
20083 if (w
->phys_cursor_on_p
20085 || w
->phys_cursor
.x
!= x
20086 || w
->phys_cursor
.y
!= y
20087 || new_cursor_type
!= w
->phys_cursor_type
20088 || ((new_cursor_type
== BAR_CURSOR
|| new_cursor_type
== HBAR_CURSOR
)
20089 && new_cursor_width
!= w
->phys_cursor_width
)))
20090 erase_phys_cursor (w
);
20092 /* Don't check phys_cursor_on_p here because that flag is only set
20093 to zero in some cases where we know that the cursor has been
20094 completely erased, to avoid the extra work of erasing the cursor
20095 twice. In other words, phys_cursor_on_p can be 1 and the cursor
20096 still not be visible, or it has only been partly erased. */
20099 w
->phys_cursor_ascent
= glyph_row
->ascent
;
20100 w
->phys_cursor_height
= glyph_row
->height
;
20102 /* Set phys_cursor_.* before x_draw_.* is called because some
20103 of them may need the information. */
20104 w
->phys_cursor
.x
= x
;
20105 w
->phys_cursor
.y
= glyph_row
->y
;
20106 w
->phys_cursor
.hpos
= hpos
;
20107 w
->phys_cursor
.vpos
= vpos
;
20110 rif
->draw_window_cursor (w
, glyph_row
, x
, y
,
20111 new_cursor_type
, new_cursor_width
,
20112 on
, active_cursor
);
20116 /* Switch the display of W's cursor on or off, according to the value
20120 update_window_cursor (w
, on
)
20124 /* Don't update cursor in windows whose frame is in the process
20125 of being deleted. */
20126 if (w
->current_matrix
)
20129 display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
20130 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
20136 /* Call update_window_cursor with parameter ON_P on all leaf windows
20137 in the window tree rooted at W. */
20140 update_cursor_in_window_tree (w
, on_p
)
20146 if (!NILP (w
->hchild
))
20147 update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
20148 else if (!NILP (w
->vchild
))
20149 update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
20151 update_window_cursor (w
, on_p
);
20153 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
20159 Display the cursor on window W, or clear it, according to ON_P.
20160 Don't change the cursor's position. */
20163 x_update_cursor (f
, on_p
)
20167 update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
20172 Clear the cursor of window W to background color, and mark the
20173 cursor as not shown. This is used when the text where the cursor
20174 is is about to be rewritten. */
20180 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
20181 update_window_cursor (w
, 0);
20186 Display the active region described by mouse_face_* according to DRAW. */
20189 show_mouse_face (dpyinfo
, draw
)
20190 Display_Info
*dpyinfo
;
20191 enum draw_glyphs_face draw
;
20193 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
20194 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
20196 if (/* If window is in the process of being destroyed, don't bother
20198 w
->current_matrix
!= NULL
20199 /* Don't update mouse highlight if hidden */
20200 && (draw
!= DRAW_MOUSE_FACE
|| !dpyinfo
->mouse_face_hidden
)
20201 /* Recognize when we are called to operate on rows that don't exist
20202 anymore. This can happen when a window is split. */
20203 && dpyinfo
->mouse_face_end_row
< w
->current_matrix
->nrows
)
20205 int phys_cursor_on_p
= w
->phys_cursor_on_p
;
20206 struct glyph_row
*row
, *first
, *last
;
20208 first
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_beg_row
);
20209 last
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_end_row
);
20211 for (row
= first
; row
<= last
&& row
->enabled_p
; ++row
)
20213 int start_hpos
, end_hpos
, start_x
;
20215 /* For all but the first row, the highlight starts at column 0. */
20218 start_hpos
= dpyinfo
->mouse_face_beg_col
;
20219 start_x
= dpyinfo
->mouse_face_beg_x
;
20228 end_hpos
= dpyinfo
->mouse_face_end_col
;
20230 end_hpos
= row
->used
[TEXT_AREA
];
20232 if (end_hpos
> start_hpos
)
20234 draw_glyphs (w
, start_x
, row
, TEXT_AREA
,
20235 start_hpos
, end_hpos
,
20239 = draw
== DRAW_MOUSE_FACE
|| draw
== DRAW_IMAGE_RAISED
;
20243 /* When we've written over the cursor, arrange for it to
20244 be displayed again. */
20245 if (phys_cursor_on_p
&& !w
->phys_cursor_on_p
)
20248 display_and_set_cursor (w
, 1,
20249 w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
20250 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
20255 /* Change the mouse cursor. */
20256 if (draw
== DRAW_NORMAL_TEXT
)
20257 rif
->define_frame_cursor (f
, FRAME_X_OUTPUT (f
)->text_cursor
);
20258 else if (draw
== DRAW_MOUSE_FACE
)
20259 rif
->define_frame_cursor (f
, FRAME_X_OUTPUT (f
)->hand_cursor
);
20261 rif
->define_frame_cursor (f
, FRAME_X_OUTPUT (f
)->nontext_cursor
);
20265 Clear out the mouse-highlighted active region.
20266 Redraw it un-highlighted first. Value is non-zero if mouse
20267 face was actually drawn unhighlighted. */
20270 clear_mouse_face (dpyinfo
)
20271 Display_Info
*dpyinfo
;
20275 if (!dpyinfo
->mouse_face_hidden
&& !NILP (dpyinfo
->mouse_face_window
))
20277 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
20281 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
20282 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
20283 dpyinfo
->mouse_face_window
= Qnil
;
20284 dpyinfo
->mouse_face_overlay
= Qnil
;
20290 Non-zero if physical cursor of window W is within mouse face. */
20293 cursor_in_mouse_face_p (w
)
20296 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (XFRAME (w
->frame
));
20297 int in_mouse_face
= 0;
20299 if (WINDOWP (dpyinfo
->mouse_face_window
)
20300 && XWINDOW (dpyinfo
->mouse_face_window
) == w
)
20302 int hpos
= w
->phys_cursor
.hpos
;
20303 int vpos
= w
->phys_cursor
.vpos
;
20305 if (vpos
>= dpyinfo
->mouse_face_beg_row
20306 && vpos
<= dpyinfo
->mouse_face_end_row
20307 && (vpos
> dpyinfo
->mouse_face_beg_row
20308 || hpos
>= dpyinfo
->mouse_face_beg_col
)
20309 && (vpos
< dpyinfo
->mouse_face_end_row
20310 || hpos
< dpyinfo
->mouse_face_end_col
20311 || dpyinfo
->mouse_face_past_end
))
20315 return in_mouse_face
;
20321 /* Find the glyph matrix position of buffer position CHARPOS in window
20322 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
20323 current glyphs must be up to date. If CHARPOS is above window
20324 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
20325 of last line in W. In the row containing CHARPOS, stop before glyphs
20326 having STOP as object. */
20328 #if 1 /* This is a version of fast_find_position that's more correct
20329 in the presence of hscrolling, for example. I didn't install
20330 it right away because the problem fixed is minor, it failed
20331 in 20.x as well, and I think it's too risky to install
20332 so near the release of 21.1. 2001-09-25 gerd. */
20335 fast_find_position (w
, charpos
, hpos
, vpos
, x
, y
, stop
)
20338 int *hpos
, *vpos
, *x
, *y
;
20341 struct glyph_row
*row
, *first
;
20342 struct glyph
*glyph
, *end
;
20345 first
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
20346 row
= row_containing_pos (w
, charpos
, first
, NULL
, 0);
20349 if (charpos
< MATRIX_ROW_START_CHARPOS (first
))
20351 *x
= *y
= *hpos
= *vpos
= 0;
20356 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
20363 *vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
20365 glyph
= row
->glyphs
[TEXT_AREA
];
20366 end
= glyph
+ row
->used
[TEXT_AREA
];
20368 /* Skip over glyphs not having an object at the start of the row.
20369 These are special glyphs like truncation marks on terminal
20371 if (row
->displays_text_p
)
20373 && INTEGERP (glyph
->object
)
20374 && !EQ (stop
, glyph
->object
)
20375 && glyph
->charpos
< 0)
20377 *x
+= glyph
->pixel_width
;
20382 && !INTEGERP (glyph
->object
)
20383 && !EQ (stop
, glyph
->object
)
20384 && (!BUFFERP (glyph
->object
)
20385 || glyph
->charpos
< charpos
))
20387 *x
+= glyph
->pixel_width
;
20391 *hpos
= glyph
- row
->glyphs
[TEXT_AREA
];
20398 fast_find_position (w
, pos
, hpos
, vpos
, x
, y
, stop
)
20401 int *hpos
, *vpos
, *x
, *y
;
20406 int maybe_next_line_p
= 0;
20407 int line_start_position
;
20408 int yb
= window_text_bottom_y (w
);
20409 struct glyph_row
*row
, *best_row
;
20410 int row_vpos
, best_row_vpos
;
20413 row
= best_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
20414 row_vpos
= best_row_vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
20416 while (row
->y
< yb
)
20418 if (row
->used
[TEXT_AREA
])
20419 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
20421 line_start_position
= 0;
20423 if (line_start_position
> pos
)
20425 /* If the position sought is the end of the buffer,
20426 don't include the blank lines at the bottom of the window. */
20427 else if (line_start_position
== pos
20428 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
20430 maybe_next_line_p
= 1;
20433 else if (line_start_position
> 0)
20436 best_row_vpos
= row_vpos
;
20439 if (row
->y
+ row
->height
>= yb
)
20446 /* Find the right column within BEST_ROW. */
20448 current_x
= best_row
->x
;
20449 for (i
= 0; i
< best_row
->used
[TEXT_AREA
]; i
++)
20451 struct glyph
*glyph
= best_row
->glyphs
[TEXT_AREA
] + i
;
20452 int charpos
= glyph
->charpos
;
20454 if (BUFFERP (glyph
->object
))
20456 if (charpos
== pos
)
20459 *vpos
= best_row_vpos
;
20464 else if (charpos
> pos
)
20467 else if (EQ (glyph
->object
, stop
))
20472 current_x
+= glyph
->pixel_width
;
20475 /* If we're looking for the end of the buffer,
20476 and we didn't find it in the line we scanned,
20477 use the start of the following line. */
20478 if (maybe_next_line_p
)
20483 current_x
= best_row
->x
;
20486 *vpos
= best_row_vpos
;
20487 *hpos
= lastcol
+ 1;
20496 /* Find the position of the glyph for position POS in OBJECT in
20497 window W's current matrix, and return in *X, *Y the pixel
20498 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
20500 RIGHT_P non-zero means return the position of the right edge of the
20501 glyph, RIGHT_P zero means return the left edge position.
20503 If no glyph for POS exists in the matrix, return the position of
20504 the glyph with the next smaller position that is in the matrix, if
20505 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
20506 exists in the matrix, return the position of the glyph with the
20507 next larger position in OBJECT.
20509 Value is non-zero if a glyph was found. */
20512 fast_find_string_pos (w
, pos
, object
, hpos
, vpos
, x
, y
, right_p
)
20515 Lisp_Object object
;
20516 int *hpos
, *vpos
, *x
, *y
;
20519 int yb
= window_text_bottom_y (w
);
20520 struct glyph_row
*r
;
20521 struct glyph
*best_glyph
= NULL
;
20522 struct glyph_row
*best_row
= NULL
;
20525 for (r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
20526 r
->enabled_p
&& r
->y
< yb
;
20529 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
20530 struct glyph
*e
= g
+ r
->used
[TEXT_AREA
];
20533 for (gx
= r
->x
; g
< e
; gx
+= g
->pixel_width
, ++g
)
20534 if (EQ (g
->object
, object
))
20536 if (g
->charpos
== pos
)
20543 else if (best_glyph
== NULL
20544 || ((abs (g
->charpos
- pos
)
20545 < abs (best_glyph
->charpos
- pos
))
20548 : g
->charpos
> pos
)))
20562 *hpos
= best_glyph
- best_row
->glyphs
[TEXT_AREA
];
20566 *x
+= best_glyph
->pixel_width
;
20571 *vpos
= best_row
- w
->current_matrix
->rows
;
20574 return best_glyph
!= NULL
;
20578 /* See if position X, Y is within a hot-spot of an image. */
20581 on_hot_spot_p (hot_spot
, x
, y
)
20582 Lisp_Object hot_spot
;
20585 if (!CONSP (hot_spot
))
20588 if (EQ (XCAR (hot_spot
), Qrect
))
20590 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
20591 Lisp_Object rect
= XCDR (hot_spot
);
20595 if (!CONSP (XCAR (rect
)))
20597 if (!CONSP (XCDR (rect
)))
20599 if (!(tem
= XCAR (XCAR (rect
)), INTEGERP (tem
) && x
>= XINT (tem
)))
20601 if (!(tem
= XCDR (XCAR (rect
)), INTEGERP (tem
) && y
>= XINT (tem
)))
20603 if (!(tem
= XCAR (XCDR (rect
)), INTEGERP (tem
) && x
<= XINT (tem
)))
20605 if (!(tem
= XCDR (XCDR (rect
)), INTEGERP (tem
) && y
<= XINT (tem
)))
20609 else if (EQ (XCAR (hot_spot
), Qcircle
))
20611 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
20612 Lisp_Object circ
= XCDR (hot_spot
);
20613 Lisp_Object lr
, lx0
, ly0
;
20615 && CONSP (XCAR (circ
))
20616 && (lr
= XCDR (circ
), INTEGERP (lr
) || FLOATP (lr
))
20617 && (lx0
= XCAR (XCAR (circ
)), INTEGERP (lx0
))
20618 && (ly0
= XCDR (XCAR (circ
)), INTEGERP (ly0
)))
20620 double r
= XFLOATINT (lr
);
20621 double dx
= XINT (lx0
) - x
;
20622 double dy
= XINT (ly0
) - y
;
20623 return (dx
* dx
+ dy
* dy
<= r
* r
);
20626 else if (EQ (XCAR (hot_spot
), Qpoly
))
20628 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
20629 if (VECTORP (XCDR (hot_spot
)))
20631 struct Lisp_Vector
*v
= XVECTOR (XCDR (hot_spot
));
20632 Lisp_Object
*poly
= v
->contents
;
20636 Lisp_Object lx
, ly
;
20639 /* Need an even number of coordinates, and at least 3 edges. */
20640 if (n
< 6 || n
& 1)
20643 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
20644 If count is odd, we are inside polygon. Pixels on edges
20645 may or may not be included depending on actual geometry of the
20647 if ((lx
= poly
[n
-2], !INTEGERP (lx
))
20648 || (ly
= poly
[n
-1], !INTEGERP (lx
)))
20650 x0
= XINT (lx
), y0
= XINT (ly
);
20651 for (i
= 0; i
< n
; i
+= 2)
20653 int x1
= x0
, y1
= y0
;
20654 if ((lx
= poly
[i
], !INTEGERP (lx
))
20655 || (ly
= poly
[i
+1], !INTEGERP (ly
)))
20657 x0
= XINT (lx
), y0
= XINT (ly
);
20659 /* Does this segment cross the X line? */
20667 if (y
> y0
&& y
> y1
)
20669 if (y
< y0
+ ((y1
- y0
) * (x
- x0
)) / (x1
- x0
))
20675 /* If we don't understand the format, pretend we're not in the hot-spot. */
20680 find_hot_spot (map
, x
, y
)
20684 while (CONSP (map
))
20686 if (CONSP (XCAR (map
))
20687 && on_hot_spot_p (XCAR (XCAR (map
)), x
, y
))
20695 DEFUN ("lookup-image-map", Flookup_image_map
, Slookup_image_map
,
20697 doc
: /* Lookup in image map MAP coordinates X and Y.
20698 An image map is an alist where each element has the format (AREA ID PLIST).
20699 An AREA is specified as either a rectangle, a circle, or a polygon:
20700 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
20701 pixel coordinates of the upper left and bottom right corners.
20702 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
20703 and the radius of the circle; r may be a float or integer.
20704 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
20705 vector describes one corner in the polygon.
20706 Returns the alist element for the first matching AREA in MAP. */)
20717 return find_hot_spot (map
, XINT (x
), XINT (y
));
20721 /* Display frame CURSOR, optionally using shape defined by POINTER. */
20723 define_frame_cursor1 (f
, cursor
, pointer
)
20726 Lisp_Object pointer
;
20728 if (!NILP (pointer
))
20730 if (EQ (pointer
, Qarrow
))
20731 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
20732 else if (EQ (pointer
, Qhand
))
20733 cursor
= FRAME_X_OUTPUT (f
)->hand_cursor
;
20734 else if (EQ (pointer
, Qtext
))
20735 cursor
= FRAME_X_OUTPUT (f
)->text_cursor
;
20736 else if (EQ (pointer
, intern ("hdrag")))
20737 cursor
= FRAME_X_OUTPUT (f
)->horizontal_drag_cursor
;
20738 #ifdef HAVE_X_WINDOWS
20739 else if (EQ (pointer
, intern ("vdrag")))
20740 cursor
= FRAME_X_DISPLAY_INFO (f
)->vertical_scroll_bar_cursor
;
20742 else if (EQ (pointer
, intern ("hourglass")))
20743 cursor
= FRAME_X_OUTPUT (f
)->hourglass_cursor
;
20744 else if (EQ (pointer
, Qmodeline
))
20745 cursor
= FRAME_X_OUTPUT (f
)->modeline_cursor
;
20747 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
20750 if (cursor
!= No_Cursor
)
20751 rif
->define_frame_cursor (f
, cursor
);
20754 /* Take proper action when mouse has moved to the mode or header line
20755 or marginal area AREA of window W, x-position X and y-position Y.
20756 X is relative to the start of the text display area of W, so the
20757 width of bitmap areas and scroll bars must be subtracted to get a
20758 position relative to the start of the mode line. */
20761 note_mode_line_or_margin_highlight (w
, x
, y
, area
)
20764 enum window_part area
;
20766 struct frame
*f
= XFRAME (w
->frame
);
20767 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
20768 Cursor cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
20769 Lisp_Object pointer
= Qnil
;
20770 int charpos
, dx
, dy
, width
, height
;
20771 Lisp_Object string
, object
= Qnil
;
20772 Lisp_Object pos
, help
;
20774 if (area
== ON_MODE_LINE
|| area
== ON_HEADER_LINE
)
20775 string
= mode_line_string (w
, area
, &x
, &y
, &charpos
,
20776 &object
, &dx
, &dy
, &width
, &height
);
20779 x
-= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w
);
20780 string
= marginal_area_string (w
, area
, &x
, &y
, &charpos
,
20781 &object
, &dx
, &dy
, &width
, &height
);
20786 if (IMAGEP (object
))
20788 Lisp_Object image_map
, hotspot
;
20789 if ((image_map
= Fplist_get (XCDR (object
), QCmap
),
20791 && (hotspot
= find_hot_spot (image_map
, dx
, dy
),
20793 && (hotspot
= XCDR (hotspot
), CONSP (hotspot
)))
20795 Lisp_Object area_id
, plist
;
20797 area_id
= XCAR (hotspot
);
20798 /* Could check AREA_ID to see if we enter/leave this hot-spot.
20799 If so, we could look for mouse-enter, mouse-leave
20800 properties in PLIST (and do something...). */
20801 if ((plist
= XCDR (hotspot
), CONSP (plist
)))
20803 pointer
= Fplist_get (plist
, Qpointer
);
20804 if (NILP (pointer
))
20806 help
= Fplist_get (plist
, Qhelp_echo
);
20809 help_echo_string
= help
;
20810 /* Is this correct? ++kfs */
20811 XSETWINDOW (help_echo_window
, w
);
20812 help_echo_object
= w
->buffer
;
20813 help_echo_pos
= charpos
;
20816 if (NILP (pointer
))
20817 pointer
= Fplist_get (XCDR (object
), QCpointer
);
20821 if (STRINGP (string
))
20823 pos
= make_number (charpos
);
20824 /* If we're on a string with `help-echo' text property, arrange
20825 for the help to be displayed. This is done by setting the
20826 global variable help_echo_string to the help string. */
20827 help
= Fget_text_property (pos
, Qhelp_echo
, string
);
20830 help_echo_string
= help
;
20831 XSETWINDOW (help_echo_window
, w
);
20832 help_echo_object
= string
;
20833 help_echo_pos
= charpos
;
20836 if (NILP (pointer
))
20837 pointer
= Fget_text_property (pos
, Qpointer
, string
);
20839 /* Change the mouse pointer according to what is under X/Y. */
20840 if (NILP (pointer
) && ((area
== ON_MODE_LINE
) || (area
== ON_HEADER_LINE
)))
20843 map
= Fget_text_property (pos
, Qlocal_map
, string
);
20844 if (!KEYMAPP (map
))
20845 map
= Fget_text_property (pos
, Qkeymap
, string
);
20846 if (!KEYMAPP (map
))
20847 cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
20851 define_frame_cursor1 (f
, cursor
, pointer
);
20856 Take proper action when the mouse has moved to position X, Y on
20857 frame F as regards highlighting characters that have mouse-face
20858 properties. Also de-highlighting chars where the mouse was before.
20859 X and Y can be negative or out of range. */
20862 note_mouse_highlight (f
, x
, y
)
20866 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
20867 enum window_part part
;
20868 Lisp_Object window
;
20870 Cursor cursor
= No_Cursor
;
20871 Lisp_Object pointer
= Qnil
; /* Takes precedence over cursor! */
20874 /* When a menu is active, don't highlight because this looks odd. */
20875 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
20876 if (popup_activated ())
20880 if (NILP (Vmouse_highlight
)
20881 || !f
->glyphs_initialized_p
)
20884 dpyinfo
->mouse_face_mouse_x
= x
;
20885 dpyinfo
->mouse_face_mouse_y
= y
;
20886 dpyinfo
->mouse_face_mouse_frame
= f
;
20888 if (dpyinfo
->mouse_face_defer
)
20891 if (gc_in_progress
)
20893 dpyinfo
->mouse_face_deferred_gc
= 1;
20897 /* Which window is that in? */
20898 window
= window_from_coordinates (f
, x
, y
, &part
, 0, 0, 1);
20900 /* If we were displaying active text in another window, clear that. */
20901 if (! EQ (window
, dpyinfo
->mouse_face_window
))
20902 clear_mouse_face (dpyinfo
);
20904 /* Not on a window -> return. */
20905 if (!WINDOWP (window
))
20908 /* Reset help_echo_string. It will get recomputed below. */
20909 help_echo_string
= Qnil
;
20911 /* Convert to window-relative pixel coordinates. */
20912 w
= XWINDOW (window
);
20913 frame_to_window_pixel_xy (w
, &x
, &y
);
20915 /* Handle tool-bar window differently since it doesn't display a
20917 if (EQ (window
, f
->tool_bar_window
))
20919 note_tool_bar_highlight (f
, x
, y
);
20923 /* Mouse is on the mode, header line or margin? */
20924 if (part
== ON_MODE_LINE
|| part
== ON_HEADER_LINE
20925 || part
== ON_LEFT_MARGIN
|| part
== ON_RIGHT_MARGIN
)
20927 note_mode_line_or_margin_highlight (w
, x
, y
, part
);
20931 if (part
== ON_VERTICAL_BORDER
)
20932 cursor
= FRAME_X_OUTPUT (f
)->horizontal_drag_cursor
;
20933 else if (part
== ON_LEFT_FRINGE
|| part
== ON_RIGHT_FRINGE
20934 || part
== ON_SCROLL_BAR
)
20935 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
20937 cursor
= FRAME_X_OUTPUT (f
)->text_cursor
;
20939 /* Are we in a window whose display is up to date?
20940 And verify the buffer's text has not changed. */
20941 b
= XBUFFER (w
->buffer
);
20942 if (part
== ON_TEXT
20943 && EQ (w
->window_end_valid
, w
->buffer
)
20944 && XFASTINT (w
->last_modified
) == BUF_MODIFF (b
)
20945 && XFASTINT (w
->last_overlay_modified
) == BUF_OVERLAY_MODIFF (b
))
20947 int hpos
, vpos
, pos
, i
, dx
, dy
, area
;
20948 struct glyph
*glyph
;
20949 Lisp_Object object
;
20950 Lisp_Object mouse_face
= Qnil
, overlay
= Qnil
, position
;
20951 Lisp_Object
*overlay_vec
= NULL
;
20953 struct buffer
*obuf
;
20954 int obegv
, ozv
, same_region
;
20956 /* Find the glyph under X/Y. */
20957 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &dx
, &dy
, &area
);
20959 /* Look for :pointer property on image. */
20960 if (glyph
!= NULL
&& glyph
->type
== IMAGE_GLYPH
)
20962 struct image
*img
= IMAGE_FROM_ID (f
, glyph
->u
.img_id
);
20963 if (img
!= NULL
&& IMAGEP (img
->spec
))
20965 Lisp_Object image_map
, hotspot
;
20966 if ((image_map
= Fplist_get (XCDR (img
->spec
), QCmap
),
20968 && (hotspot
= find_hot_spot (image_map
,
20969 glyph
->slice
.x
+ dx
,
20970 glyph
->slice
.y
+ dy
),
20972 && (hotspot
= XCDR (hotspot
), CONSP (hotspot
)))
20974 Lisp_Object area_id
, plist
;
20976 area_id
= XCAR (hotspot
);
20977 /* Could check AREA_ID to see if we enter/leave this hot-spot.
20978 If so, we could look for mouse-enter, mouse-leave
20979 properties in PLIST (and do something...). */
20980 if ((plist
= XCDR (hotspot
), CONSP (plist
)))
20982 pointer
= Fplist_get (plist
, Qpointer
);
20983 if (NILP (pointer
))
20985 help_echo_string
= Fplist_get (plist
, Qhelp_echo
);
20986 if (!NILP (help_echo_string
))
20988 help_echo_window
= window
;
20989 help_echo_object
= glyph
->object
;
20990 help_echo_pos
= glyph
->charpos
;
20994 if (NILP (pointer
))
20995 pointer
= Fplist_get (XCDR (img
->spec
), QCpointer
);
20999 /* Clear mouse face if X/Y not over text. */
21001 || area
!= TEXT_AREA
21002 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
)
21004 if (clear_mouse_face (dpyinfo
))
21005 cursor
= No_Cursor
;
21006 if (NILP (pointer
))
21008 if (area
!= TEXT_AREA
)
21009 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
21011 pointer
= Vvoid_text_area_pointer
;
21016 pos
= glyph
->charpos
;
21017 object
= glyph
->object
;
21018 if (!STRINGP (object
) && !BUFFERP (object
))
21021 /* If we get an out-of-range value, return now; avoid an error. */
21022 if (BUFFERP (object
) && pos
> BUF_Z (b
))
21025 /* Make the window's buffer temporarily current for
21026 overlays_at and compute_char_face. */
21027 obuf
= current_buffer
;
21028 current_buffer
= b
;
21034 /* Is this char mouse-active or does it have help-echo? */
21035 position
= make_number (pos
);
21037 if (BUFFERP (object
))
21039 /* Put all the overlays we want in a vector in overlay_vec. */
21040 GET_OVERLAYS_AT (pos
, overlay_vec
, noverlays
, NULL
, 0);
21041 /* Sort overlays into increasing priority order. */
21042 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
21047 same_region
= (EQ (window
, dpyinfo
->mouse_face_window
)
21048 && vpos
>= dpyinfo
->mouse_face_beg_row
21049 && vpos
<= dpyinfo
->mouse_face_end_row
21050 && (vpos
> dpyinfo
->mouse_face_beg_row
21051 || hpos
>= dpyinfo
->mouse_face_beg_col
)
21052 && (vpos
< dpyinfo
->mouse_face_end_row
21053 || hpos
< dpyinfo
->mouse_face_end_col
21054 || dpyinfo
->mouse_face_past_end
));
21057 cursor
= No_Cursor
;
21059 /* Check mouse-face highlighting. */
21061 /* If there exists an overlay with mouse-face overlapping
21062 the one we are currently highlighting, we have to
21063 check if we enter the overlapping overlay, and then
21064 highlight only that. */
21065 || (OVERLAYP (dpyinfo
->mouse_face_overlay
)
21066 && mouse_face_overlay_overlaps (dpyinfo
->mouse_face_overlay
)))
21068 /* Find the highest priority overlay that has a mouse-face
21071 for (i
= noverlays
- 1; i
>= 0 && NILP (overlay
); --i
)
21073 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
21074 if (!NILP (mouse_face
))
21075 overlay
= overlay_vec
[i
];
21078 /* If we're actually highlighting the same overlay as
21079 before, there's no need to do that again. */
21080 if (!NILP (overlay
)
21081 && EQ (overlay
, dpyinfo
->mouse_face_overlay
))
21082 goto check_help_echo
;
21084 dpyinfo
->mouse_face_overlay
= overlay
;
21086 /* Clear the display of the old active region, if any. */
21087 if (clear_mouse_face (dpyinfo
))
21088 cursor
= No_Cursor
;
21090 /* If no overlay applies, get a text property. */
21091 if (NILP (overlay
))
21092 mouse_face
= Fget_text_property (position
, Qmouse_face
, object
);
21094 /* Handle the overlay case. */
21095 if (!NILP (overlay
))
21097 /* Find the range of text around this char that
21098 should be active. */
21099 Lisp_Object before
, after
;
21102 before
= Foverlay_start (overlay
);
21103 after
= Foverlay_end (overlay
);
21104 /* Record this as the current active region. */
21105 fast_find_position (w
, XFASTINT (before
),
21106 &dpyinfo
->mouse_face_beg_col
,
21107 &dpyinfo
->mouse_face_beg_row
,
21108 &dpyinfo
->mouse_face_beg_x
,
21109 &dpyinfo
->mouse_face_beg_y
, Qnil
);
21111 dpyinfo
->mouse_face_past_end
21112 = !fast_find_position (w
, XFASTINT (after
),
21113 &dpyinfo
->mouse_face_end_col
,
21114 &dpyinfo
->mouse_face_end_row
,
21115 &dpyinfo
->mouse_face_end_x
,
21116 &dpyinfo
->mouse_face_end_y
, Qnil
);
21117 dpyinfo
->mouse_face_window
= window
;
21119 dpyinfo
->mouse_face_face_id
21120 = face_at_buffer_position (w
, pos
, 0, 0,
21122 !dpyinfo
->mouse_face_hidden
);
21124 /* Display it as active. */
21125 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
21126 cursor
= No_Cursor
;
21128 /* Handle the text property case. */
21129 else if (!NILP (mouse_face
) && BUFFERP (object
))
21131 /* Find the range of text around this char that
21132 should be active. */
21133 Lisp_Object before
, after
, beginning
, end
;
21136 beginning
= Fmarker_position (w
->start
);
21137 end
= make_number (BUF_Z (XBUFFER (object
))
21138 - XFASTINT (w
->window_end_pos
));
21140 = Fprevious_single_property_change (make_number (pos
+ 1),
21142 object
, beginning
);
21144 = Fnext_single_property_change (position
, Qmouse_face
,
21147 /* Record this as the current active region. */
21148 fast_find_position (w
, XFASTINT (before
),
21149 &dpyinfo
->mouse_face_beg_col
,
21150 &dpyinfo
->mouse_face_beg_row
,
21151 &dpyinfo
->mouse_face_beg_x
,
21152 &dpyinfo
->mouse_face_beg_y
, Qnil
);
21153 dpyinfo
->mouse_face_past_end
21154 = !fast_find_position (w
, XFASTINT (after
),
21155 &dpyinfo
->mouse_face_end_col
,
21156 &dpyinfo
->mouse_face_end_row
,
21157 &dpyinfo
->mouse_face_end_x
,
21158 &dpyinfo
->mouse_face_end_y
, Qnil
);
21159 dpyinfo
->mouse_face_window
= window
;
21161 if (BUFFERP (object
))
21162 dpyinfo
->mouse_face_face_id
21163 = face_at_buffer_position (w
, pos
, 0, 0,
21165 !dpyinfo
->mouse_face_hidden
);
21167 /* Display it as active. */
21168 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
21169 cursor
= No_Cursor
;
21171 else if (!NILP (mouse_face
) && STRINGP (object
))
21176 b
= Fprevious_single_property_change (make_number (pos
+ 1),
21179 e
= Fnext_single_property_change (position
, Qmouse_face
,
21182 b
= make_number (0);
21184 e
= make_number (SCHARS (object
) - 1);
21185 fast_find_string_pos (w
, XINT (b
), object
,
21186 &dpyinfo
->mouse_face_beg_col
,
21187 &dpyinfo
->mouse_face_beg_row
,
21188 &dpyinfo
->mouse_face_beg_x
,
21189 &dpyinfo
->mouse_face_beg_y
, 0);
21190 fast_find_string_pos (w
, XINT (e
), object
,
21191 &dpyinfo
->mouse_face_end_col
,
21192 &dpyinfo
->mouse_face_end_row
,
21193 &dpyinfo
->mouse_face_end_x
,
21194 &dpyinfo
->mouse_face_end_y
, 1);
21195 dpyinfo
->mouse_face_past_end
= 0;
21196 dpyinfo
->mouse_face_window
= window
;
21197 dpyinfo
->mouse_face_face_id
21198 = face_at_string_position (w
, object
, pos
, 0, 0, 0, &ignore
,
21199 glyph
->face_id
, 1);
21200 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
21201 cursor
= No_Cursor
;
21203 else if (STRINGP (object
) && NILP (mouse_face
))
21205 /* A string which doesn't have mouse-face, but
21206 the text ``under'' it might have. */
21207 struct glyph_row
*r
= MATRIX_ROW (w
->current_matrix
, vpos
);
21208 int start
= MATRIX_ROW_START_CHARPOS (r
);
21210 pos
= string_buffer_position (w
, object
, start
);
21212 mouse_face
= get_char_property_and_overlay (make_number (pos
),
21216 if (!NILP (mouse_face
) && !NILP (overlay
))
21218 Lisp_Object before
= Foverlay_start (overlay
);
21219 Lisp_Object after
= Foverlay_end (overlay
);
21222 /* Note that we might not be able to find position
21223 BEFORE in the glyph matrix if the overlay is
21224 entirely covered by a `display' property. In
21225 this case, we overshoot. So let's stop in
21226 the glyph matrix before glyphs for OBJECT. */
21227 fast_find_position (w
, XFASTINT (before
),
21228 &dpyinfo
->mouse_face_beg_col
,
21229 &dpyinfo
->mouse_face_beg_row
,
21230 &dpyinfo
->mouse_face_beg_x
,
21231 &dpyinfo
->mouse_face_beg_y
,
21234 dpyinfo
->mouse_face_past_end
21235 = !fast_find_position (w
, XFASTINT (after
),
21236 &dpyinfo
->mouse_face_end_col
,
21237 &dpyinfo
->mouse_face_end_row
,
21238 &dpyinfo
->mouse_face_end_x
,
21239 &dpyinfo
->mouse_face_end_y
,
21241 dpyinfo
->mouse_face_window
= window
;
21242 dpyinfo
->mouse_face_face_id
21243 = face_at_buffer_position (w
, pos
, 0, 0,
21245 !dpyinfo
->mouse_face_hidden
);
21247 /* Display it as active. */
21248 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
21249 cursor
= No_Cursor
;
21256 /* Look for a `help-echo' property. */
21257 if (NILP (help_echo_string
)) {
21258 Lisp_Object help
, overlay
;
21260 /* Check overlays first. */
21261 help
= overlay
= Qnil
;
21262 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
21264 overlay
= overlay_vec
[i
];
21265 help
= Foverlay_get (overlay
, Qhelp_echo
);
21270 help_echo_string
= help
;
21271 help_echo_window
= window
;
21272 help_echo_object
= overlay
;
21273 help_echo_pos
= pos
;
21277 Lisp_Object object
= glyph
->object
;
21278 int charpos
= glyph
->charpos
;
21280 /* Try text properties. */
21281 if (STRINGP (object
)
21283 && charpos
< SCHARS (object
))
21285 help
= Fget_text_property (make_number (charpos
),
21286 Qhelp_echo
, object
);
21289 /* If the string itself doesn't specify a help-echo,
21290 see if the buffer text ``under'' it does. */
21291 struct glyph_row
*r
21292 = MATRIX_ROW (w
->current_matrix
, vpos
);
21293 int start
= MATRIX_ROW_START_CHARPOS (r
);
21294 int pos
= string_buffer_position (w
, object
, start
);
21297 help
= Fget_char_property (make_number (pos
),
21298 Qhelp_echo
, w
->buffer
);
21302 object
= w
->buffer
;
21307 else if (BUFFERP (object
)
21310 help
= Fget_text_property (make_number (charpos
), Qhelp_echo
,
21315 help_echo_string
= help
;
21316 help_echo_window
= window
;
21317 help_echo_object
= object
;
21318 help_echo_pos
= charpos
;
21323 /* Look for a `pointer' property. */
21324 if (NILP (pointer
))
21326 /* Check overlays first. */
21327 for (i
= noverlays
- 1; i
>= 0 && NILP (pointer
); --i
)
21328 pointer
= Foverlay_get (overlay_vec
[i
], Qpointer
);
21330 if (NILP (pointer
))
21332 Lisp_Object object
= glyph
->object
;
21333 int charpos
= glyph
->charpos
;
21335 /* Try text properties. */
21336 if (STRINGP (object
)
21338 && charpos
< SCHARS (object
))
21340 pointer
= Fget_text_property (make_number (charpos
),
21342 if (NILP (pointer
))
21344 /* If the string itself doesn't specify a pointer,
21345 see if the buffer text ``under'' it does. */
21346 struct glyph_row
*r
21347 = MATRIX_ROW (w
->current_matrix
, vpos
);
21348 int start
= MATRIX_ROW_START_CHARPOS (r
);
21349 int pos
= string_buffer_position (w
, object
, start
);
21351 pointer
= Fget_char_property (make_number (pos
),
21352 Qpointer
, w
->buffer
);
21355 else if (BUFFERP (object
)
21358 pointer
= Fget_text_property (make_number (charpos
),
21365 current_buffer
= obuf
;
21370 define_frame_cursor1 (f
, cursor
, pointer
);
21375 Clear any mouse-face on window W. This function is part of the
21376 redisplay interface, and is called from try_window_id and similar
21377 functions to ensure the mouse-highlight is off. */
21380 x_clear_window_mouse_face (w
)
21383 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (XFRAME (w
->frame
));
21384 Lisp_Object window
;
21387 XSETWINDOW (window
, w
);
21388 if (EQ (window
, dpyinfo
->mouse_face_window
))
21389 clear_mouse_face (dpyinfo
);
21395 Just discard the mouse face information for frame F, if any.
21396 This is used when the size of F is changed. */
21399 cancel_mouse_face (f
)
21402 Lisp_Object window
;
21403 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
21405 window
= dpyinfo
->mouse_face_window
;
21406 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
21408 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
21409 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
21410 dpyinfo
->mouse_face_window
= Qnil
;
21415 #endif /* HAVE_WINDOW_SYSTEM */
21418 /***********************************************************************
21420 ***********************************************************************/
21422 #ifdef HAVE_WINDOW_SYSTEM
21424 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
21425 which intersects rectangle R. R is in window-relative coordinates. */
21428 expose_area (w
, row
, r
, area
)
21430 struct glyph_row
*row
;
21432 enum glyph_row_area area
;
21434 struct glyph
*first
= row
->glyphs
[area
];
21435 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
21436 struct glyph
*last
;
21437 int first_x
, start_x
, x
;
21439 if (area
== TEXT_AREA
&& row
->fill_line_p
)
21440 /* If row extends face to end of line write the whole line. */
21441 draw_glyphs (w
, 0, row
, area
,
21442 0, row
->used
[area
],
21443 DRAW_NORMAL_TEXT
, 0);
21446 /* Set START_X to the window-relative start position for drawing glyphs of
21447 AREA. The first glyph of the text area can be partially visible.
21448 The first glyphs of other areas cannot. */
21449 start_x
= window_box_left_offset (w
, area
);
21451 if (area
== TEXT_AREA
)
21454 /* Find the first glyph that must be redrawn. */
21456 && x
+ first
->pixel_width
< r
->x
)
21458 x
+= first
->pixel_width
;
21462 /* Find the last one. */
21466 && x
< r
->x
+ r
->width
)
21468 x
+= last
->pixel_width
;
21474 draw_glyphs (w
, first_x
- start_x
, row
, area
,
21475 first
- row
->glyphs
[area
], last
- row
->glyphs
[area
],
21476 DRAW_NORMAL_TEXT
, 0);
21481 /* Redraw the parts of the glyph row ROW on window W intersecting
21482 rectangle R. R is in window-relative coordinates. Value is
21483 non-zero if mouse-face was overwritten. */
21486 expose_line (w
, row
, r
)
21488 struct glyph_row
*row
;
21491 xassert (row
->enabled_p
);
21493 if (row
->mode_line_p
|| w
->pseudo_window_p
)
21494 draw_glyphs (w
, 0, row
, TEXT_AREA
,
21495 0, row
->used
[TEXT_AREA
],
21496 DRAW_NORMAL_TEXT
, 0);
21499 if (row
->used
[LEFT_MARGIN_AREA
])
21500 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
21501 if (row
->used
[TEXT_AREA
])
21502 expose_area (w
, row
, r
, TEXT_AREA
);
21503 if (row
->used
[RIGHT_MARGIN_AREA
])
21504 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
21505 draw_row_fringe_bitmaps (w
, row
);
21508 return row
->mouse_face_p
;
21512 /* Redraw those parts of glyphs rows during expose event handling that
21513 overlap other rows. Redrawing of an exposed line writes over parts
21514 of lines overlapping that exposed line; this function fixes that.
21516 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
21517 row in W's current matrix that is exposed and overlaps other rows.
21518 LAST_OVERLAPPING_ROW is the last such row. */
21521 expose_overlaps (w
, first_overlapping_row
, last_overlapping_row
)
21523 struct glyph_row
*first_overlapping_row
;
21524 struct glyph_row
*last_overlapping_row
;
21526 struct glyph_row
*row
;
21528 for (row
= first_overlapping_row
; row
<= last_overlapping_row
; ++row
)
21529 if (row
->overlapping_p
)
21531 xassert (row
->enabled_p
&& !row
->mode_line_p
);
21533 if (row
->used
[LEFT_MARGIN_AREA
])
21534 x_fix_overlapping_area (w
, row
, LEFT_MARGIN_AREA
);
21536 if (row
->used
[TEXT_AREA
])
21537 x_fix_overlapping_area (w
, row
, TEXT_AREA
);
21539 if (row
->used
[RIGHT_MARGIN_AREA
])
21540 x_fix_overlapping_area (w
, row
, RIGHT_MARGIN_AREA
);
21545 /* Return non-zero if W's cursor intersects rectangle R. */
21548 phys_cursor_in_rect_p (w
, r
)
21552 XRectangle cr
, result
;
21553 struct glyph
*cursor_glyph
;
21555 cursor_glyph
= get_phys_cursor_glyph (w
);
21558 /* r is relative to W's box, but w->phys_cursor.x is relative
21559 to left edge of W's TEXT area. Adjust it. */
21560 cr
.x
= window_box_left_offset (w
, TEXT_AREA
) + w
->phys_cursor
.x
;
21561 cr
.y
= w
->phys_cursor
.y
;
21562 cr
.width
= cursor_glyph
->pixel_width
;
21563 cr
.height
= w
->phys_cursor_height
;
21564 /* ++KFS: W32 version used W32-specific IntersectRect here, but
21565 I assume the effect is the same -- and this is portable. */
21566 return x_intersect_rectangles (&cr
, r
, &result
);
21574 Draw a vertical window border to the right of window W if W doesn't
21575 have vertical scroll bars. */
21578 x_draw_vertical_border (w
)
21581 /* We could do better, if we knew what type of scroll-bar the adjacent
21582 windows (on either side) have... But we don't :-(
21583 However, I think this works ok. ++KFS 2003-04-25 */
21585 /* Redraw borders between horizontally adjacent windows. Don't
21586 do it for frames with vertical scroll bars because either the
21587 right scroll bar of a window, or the left scroll bar of its
21588 neighbor will suffice as a border. */
21589 if (!WINDOW_RIGHTMOST_P (w
)
21590 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w
))
21592 int x0
, x1
, y0
, y1
;
21594 window_box_edges (w
, -1, &x0
, &y0
, &x1
, &y1
);
21597 rif
->draw_vertical_window_border (w
, x1
, y0
, y1
);
21599 else if (!WINDOW_LEFTMOST_P (w
)
21600 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w
))
21602 int x0
, x1
, y0
, y1
;
21604 window_box_edges (w
, -1, &x0
, &y0
, &x1
, &y1
);
21607 rif
->draw_vertical_window_border (w
, x0
, y0
, y1
);
21612 /* Redraw the part of window W intersection rectangle FR. Pixel
21613 coordinates in FR are frame-relative. Call this function with
21614 input blocked. Value is non-zero if the exposure overwrites
21618 expose_window (w
, fr
)
21622 struct frame
*f
= XFRAME (w
->frame
);
21624 int mouse_face_overwritten_p
= 0;
21626 /* If window is not yet fully initialized, do nothing. This can
21627 happen when toolkit scroll bars are used and a window is split.
21628 Reconfiguring the scroll bar will generate an expose for a newly
21630 if (w
->current_matrix
== NULL
)
21633 /* When we're currently updating the window, display and current
21634 matrix usually don't agree. Arrange for a thorough display
21636 if (w
== updated_window
)
21638 SET_FRAME_GARBAGED (f
);
21642 /* Frame-relative pixel rectangle of W. */
21643 wr
.x
= WINDOW_LEFT_EDGE_X (w
);
21644 wr
.y
= WINDOW_TOP_EDGE_Y (w
);
21645 wr
.width
= WINDOW_TOTAL_WIDTH (w
);
21646 wr
.height
= WINDOW_TOTAL_HEIGHT (w
);
21648 if (x_intersect_rectangles (fr
, &wr
, &r
))
21650 int yb
= window_text_bottom_y (w
);
21651 struct glyph_row
*row
;
21652 int cursor_cleared_p
;
21653 struct glyph_row
*first_overlapping_row
, *last_overlapping_row
;
21655 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
21656 r
.x
, r
.y
, r
.width
, r
.height
));
21658 /* Convert to window coordinates. */
21659 r
.x
-= WINDOW_LEFT_EDGE_X (w
);
21660 r
.y
-= WINDOW_TOP_EDGE_Y (w
);
21662 /* Turn off the cursor. */
21663 if (!w
->pseudo_window_p
21664 && phys_cursor_in_rect_p (w
, &r
))
21666 x_clear_cursor (w
);
21667 cursor_cleared_p
= 1;
21670 cursor_cleared_p
= 0;
21672 /* Update lines intersecting rectangle R. */
21673 first_overlapping_row
= last_overlapping_row
= NULL
;
21674 for (row
= w
->current_matrix
->rows
;
21679 int y1
= MATRIX_ROW_BOTTOM_Y (row
);
21681 if ((y0
>= r
.y
&& y0
< r
.y
+ r
.height
)
21682 || (y1
> r
.y
&& y1
< r
.y
+ r
.height
)
21683 || (r
.y
>= y0
&& r
.y
< y1
)
21684 || (r
.y
+ r
.height
> y0
&& r
.y
+ r
.height
< y1
))
21686 if (row
->overlapping_p
)
21688 if (first_overlapping_row
== NULL
)
21689 first_overlapping_row
= row
;
21690 last_overlapping_row
= row
;
21693 if (expose_line (w
, row
, &r
))
21694 mouse_face_overwritten_p
= 1;
21701 /* Display the mode line if there is one. */
21702 if (WINDOW_WANTS_MODELINE_P (w
)
21703 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
21705 && row
->y
< r
.y
+ r
.height
)
21707 if (expose_line (w
, row
, &r
))
21708 mouse_face_overwritten_p
= 1;
21711 if (!w
->pseudo_window_p
)
21713 /* Fix the display of overlapping rows. */
21714 if (first_overlapping_row
)
21715 expose_overlaps (w
, first_overlapping_row
, last_overlapping_row
);
21717 /* Draw border between windows. */
21718 x_draw_vertical_border (w
);
21720 /* Turn the cursor on again. */
21721 if (cursor_cleared_p
)
21722 update_window_cursor (w
, 1);
21727 /* Display scroll bar for this window. */
21728 if (!NILP (w
->vertical_scroll_bar
))
21731 If this doesn't work here (maybe some header files are missing),
21732 make a function in macterm.c and call it to do the job! */
21734 = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (w
->vertical_scroll_bar
));
21740 return mouse_face_overwritten_p
;
21745 /* Redraw (parts) of all windows in the window tree rooted at W that
21746 intersect R. R contains frame pixel coordinates. Value is
21747 non-zero if the exposure overwrites mouse-face. */
21750 expose_window_tree (w
, r
)
21754 struct frame
*f
= XFRAME (w
->frame
);
21755 int mouse_face_overwritten_p
= 0;
21757 while (w
&& !FRAME_GARBAGED_P (f
))
21759 if (!NILP (w
->hchild
))
21760 mouse_face_overwritten_p
21761 |= expose_window_tree (XWINDOW (w
->hchild
), r
);
21762 else if (!NILP (w
->vchild
))
21763 mouse_face_overwritten_p
21764 |= expose_window_tree (XWINDOW (w
->vchild
), r
);
21766 mouse_face_overwritten_p
|= expose_window (w
, r
);
21768 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
21771 return mouse_face_overwritten_p
;
21776 Redisplay an exposed area of frame F. X and Y are the upper-left
21777 corner of the exposed rectangle. W and H are width and height of
21778 the exposed area. All are pixel values. W or H zero means redraw
21779 the entire frame. */
21782 expose_frame (f
, x
, y
, w
, h
)
21787 int mouse_face_overwritten_p
= 0;
21789 TRACE ((stderr
, "expose_frame "));
21791 /* No need to redraw if frame will be redrawn soon. */
21792 if (FRAME_GARBAGED_P (f
))
21794 TRACE ((stderr
, " garbaged\n"));
21799 /* MAC_TODO: this is a kludge, but if scroll bars are not activated
21800 or deactivated here, for unknown reasons, activated scroll bars
21801 are shown in deactivated frames in some instances. */
21802 if (f
== FRAME_MAC_DISPLAY_INFO (f
)->x_focus_frame
)
21803 activate_scroll_bars (f
);
21805 deactivate_scroll_bars (f
);
21808 /* If basic faces haven't been realized yet, there is no point in
21809 trying to redraw anything. This can happen when we get an expose
21810 event while Emacs is starting, e.g. by moving another window. */
21811 if (FRAME_FACE_CACHE (f
) == NULL
21812 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
21814 TRACE ((stderr
, " no faces\n"));
21818 if (w
== 0 || h
== 0)
21821 r
.width
= FRAME_COLUMN_WIDTH (f
) * FRAME_COLS (f
);
21822 r
.height
= FRAME_LINE_HEIGHT (f
) * FRAME_LINES (f
);
21832 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.x
, r
.y
, r
.width
, r
.height
));
21833 mouse_face_overwritten_p
= expose_window_tree (XWINDOW (f
->root_window
), &r
);
21835 if (WINDOWP (f
->tool_bar_window
))
21836 mouse_face_overwritten_p
21837 |= expose_window (XWINDOW (f
->tool_bar_window
), &r
);
21839 #ifdef HAVE_X_WINDOWS
21841 #ifndef USE_X_TOOLKIT
21842 if (WINDOWP (f
->menu_bar_window
))
21843 mouse_face_overwritten_p
21844 |= expose_window (XWINDOW (f
->menu_bar_window
), &r
);
21845 #endif /* not USE_X_TOOLKIT */
21849 /* Some window managers support a focus-follows-mouse style with
21850 delayed raising of frames. Imagine a partially obscured frame,
21851 and moving the mouse into partially obscured mouse-face on that
21852 frame. The visible part of the mouse-face will be highlighted,
21853 then the WM raises the obscured frame. With at least one WM, KDE
21854 2.1, Emacs is not getting any event for the raising of the frame
21855 (even tried with SubstructureRedirectMask), only Expose events.
21856 These expose events will draw text normally, i.e. not
21857 highlighted. Which means we must redo the highlight here.
21858 Subsume it under ``we love X''. --gerd 2001-08-15 */
21859 /* Included in Windows version because Windows most likely does not
21860 do the right thing if any third party tool offers
21861 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
21862 if (mouse_face_overwritten_p
&& !FRAME_GARBAGED_P (f
))
21864 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
21865 if (f
== dpyinfo
->mouse_face_mouse_frame
)
21867 int x
= dpyinfo
->mouse_face_mouse_x
;
21868 int y
= dpyinfo
->mouse_face_mouse_y
;
21869 clear_mouse_face (dpyinfo
);
21870 note_mouse_highlight (f
, x
, y
);
21877 Determine the intersection of two rectangles R1 and R2. Return
21878 the intersection in *RESULT. Value is non-zero if RESULT is not
21882 x_intersect_rectangles (r1
, r2
, result
)
21883 XRectangle
*r1
, *r2
, *result
;
21885 XRectangle
*left
, *right
;
21886 XRectangle
*upper
, *lower
;
21887 int intersection_p
= 0;
21889 /* Rearrange so that R1 is the left-most rectangle. */
21891 left
= r1
, right
= r2
;
21893 left
= r2
, right
= r1
;
21895 /* X0 of the intersection is right.x0, if this is inside R1,
21896 otherwise there is no intersection. */
21897 if (right
->x
<= left
->x
+ left
->width
)
21899 result
->x
= right
->x
;
21901 /* The right end of the intersection is the minimum of the
21902 the right ends of left and right. */
21903 result
->width
= (min (left
->x
+ left
->width
, right
->x
+ right
->width
)
21906 /* Same game for Y. */
21908 upper
= r1
, lower
= r2
;
21910 upper
= r2
, lower
= r1
;
21912 /* The upper end of the intersection is lower.y0, if this is inside
21913 of upper. Otherwise, there is no intersection. */
21914 if (lower
->y
<= upper
->y
+ upper
->height
)
21916 result
->y
= lower
->y
;
21918 /* The lower end of the intersection is the minimum of the lower
21919 ends of upper and lower. */
21920 result
->height
= (min (lower
->y
+ lower
->height
,
21921 upper
->y
+ upper
->height
)
21923 intersection_p
= 1;
21927 return intersection_p
;
21930 #endif /* HAVE_WINDOW_SYSTEM */
21933 /***********************************************************************
21935 ***********************************************************************/
21940 Vwith_echo_area_save_vector
= Qnil
;
21941 staticpro (&Vwith_echo_area_save_vector
);
21943 Vmessage_stack
= Qnil
;
21944 staticpro (&Vmessage_stack
);
21946 Qinhibit_redisplay
= intern ("inhibit-redisplay");
21947 staticpro (&Qinhibit_redisplay
);
21949 message_dolog_marker1
= Fmake_marker ();
21950 staticpro (&message_dolog_marker1
);
21951 message_dolog_marker2
= Fmake_marker ();
21952 staticpro (&message_dolog_marker2
);
21953 message_dolog_marker3
= Fmake_marker ();
21954 staticpro (&message_dolog_marker3
);
21957 defsubr (&Sdump_frame_glyph_matrix
);
21958 defsubr (&Sdump_glyph_matrix
);
21959 defsubr (&Sdump_glyph_row
);
21960 defsubr (&Sdump_tool_bar_row
);
21961 defsubr (&Strace_redisplay
);
21962 defsubr (&Strace_to_stderr
);
21964 #ifdef HAVE_WINDOW_SYSTEM
21965 defsubr (&Stool_bar_lines_needed
);
21966 defsubr (&Slookup_image_map
);
21968 defsubr (&Sformat_mode_line
);
21970 staticpro (&Qmenu_bar_update_hook
);
21971 Qmenu_bar_update_hook
= intern ("menu-bar-update-hook");
21973 staticpro (&Qoverriding_terminal_local_map
);
21974 Qoverriding_terminal_local_map
= intern ("overriding-terminal-local-map");
21976 staticpro (&Qoverriding_local_map
);
21977 Qoverriding_local_map
= intern ("overriding-local-map");
21979 staticpro (&Qwindow_scroll_functions
);
21980 Qwindow_scroll_functions
= intern ("window-scroll-functions");
21982 staticpro (&Qredisplay_end_trigger_functions
);
21983 Qredisplay_end_trigger_functions
= intern ("redisplay-end-trigger-functions");
21985 staticpro (&Qinhibit_point_motion_hooks
);
21986 Qinhibit_point_motion_hooks
= intern ("inhibit-point-motion-hooks");
21988 QCdata
= intern (":data");
21989 staticpro (&QCdata
);
21990 Qdisplay
= intern ("display");
21991 staticpro (&Qdisplay
);
21992 Qspace_width
= intern ("space-width");
21993 staticpro (&Qspace_width
);
21994 Qraise
= intern ("raise");
21995 staticpro (&Qraise
);
21996 Qslice
= intern ("slice");
21997 staticpro (&Qslice
);
21998 Qspace
= intern ("space");
21999 staticpro (&Qspace
);
22000 Qmargin
= intern ("margin");
22001 staticpro (&Qmargin
);
22002 Qpointer
= intern ("pointer");
22003 staticpro (&Qpointer
);
22004 Qleft_margin
= intern ("left-margin");
22005 staticpro (&Qleft_margin
);
22006 Qright_margin
= intern ("right-margin");
22007 staticpro (&Qright_margin
);
22008 Qcenter
= intern ("center");
22009 staticpro (&Qcenter
);
22010 Qline_height
= intern ("line-height");
22011 staticpro (&Qline_height
);
22012 Qtotal
= intern ("total");
22013 staticpro (&Qtotal
);
22014 QCalign_to
= intern (":align-to");
22015 staticpro (&QCalign_to
);
22016 QCrelative_width
= intern (":relative-width");
22017 staticpro (&QCrelative_width
);
22018 QCrelative_height
= intern (":relative-height");
22019 staticpro (&QCrelative_height
);
22020 QCeval
= intern (":eval");
22021 staticpro (&QCeval
);
22022 QCpropertize
= intern (":propertize");
22023 staticpro (&QCpropertize
);
22024 QCfile
= intern (":file");
22025 staticpro (&QCfile
);
22026 Qfontified
= intern ("fontified");
22027 staticpro (&Qfontified
);
22028 Qfontification_functions
= intern ("fontification-functions");
22029 staticpro (&Qfontification_functions
);
22030 Qtrailing_whitespace
= intern ("trailing-whitespace");
22031 staticpro (&Qtrailing_whitespace
);
22032 Qimage
= intern ("image");
22033 staticpro (&Qimage
);
22034 QCmap
= intern (":map");
22035 staticpro (&QCmap
);
22036 QCpointer
= intern (":pointer");
22037 staticpro (&QCpointer
);
22038 Qrect
= intern ("rect");
22039 staticpro (&Qrect
);
22040 Qcircle
= intern ("circle");
22041 staticpro (&Qcircle
);
22042 Qpoly
= intern ("poly");
22043 staticpro (&Qpoly
);
22044 Qmessage_truncate_lines
= intern ("message-truncate-lines");
22045 staticpro (&Qmessage_truncate_lines
);
22046 Qcursor_in_non_selected_windows
= intern ("cursor-in-non-selected-windows");
22047 staticpro (&Qcursor_in_non_selected_windows
);
22048 Qgrow_only
= intern ("grow-only");
22049 staticpro (&Qgrow_only
);
22050 Qinhibit_menubar_update
= intern ("inhibit-menubar-update");
22051 staticpro (&Qinhibit_menubar_update
);
22052 Qinhibit_eval_during_redisplay
= intern ("inhibit-eval-during-redisplay");
22053 staticpro (&Qinhibit_eval_during_redisplay
);
22054 Qposition
= intern ("position");
22055 staticpro (&Qposition
);
22056 Qbuffer_position
= intern ("buffer-position");
22057 staticpro (&Qbuffer_position
);
22058 Qobject
= intern ("object");
22059 staticpro (&Qobject
);
22060 Qbar
= intern ("bar");
22062 Qhbar
= intern ("hbar");
22063 staticpro (&Qhbar
);
22064 Qbox
= intern ("box");
22066 Qhollow
= intern ("hollow");
22067 staticpro (&Qhollow
);
22068 Qhand
= intern ("hand");
22069 staticpro (&Qhand
);
22070 Qarrow
= intern ("arrow");
22071 staticpro (&Qarrow
);
22072 Qtext
= intern ("text");
22073 staticpro (&Qtext
);
22074 Qrisky_local_variable
= intern ("risky-local-variable");
22075 staticpro (&Qrisky_local_variable
);
22076 Qinhibit_free_realized_faces
= intern ("inhibit-free-realized-faces");
22077 staticpro (&Qinhibit_free_realized_faces
);
22079 list_of_error
= Fcons (Fcons (intern ("error"),
22080 Fcons (intern ("void-variable"), Qnil
)),
22082 staticpro (&list_of_error
);
22084 Qlast_arrow_position
= intern ("last-arrow-position");
22085 staticpro (&Qlast_arrow_position
);
22086 Qlast_arrow_string
= intern ("last-arrow-string");
22087 staticpro (&Qlast_arrow_string
);
22089 Qoverlay_arrow_string
= intern ("overlay-arrow-string");
22090 staticpro (&Qoverlay_arrow_string
);
22091 Qoverlay_arrow_bitmap
= intern ("overlay-arrow-bitmap");
22092 staticpro (&Qoverlay_arrow_bitmap
);
22094 echo_buffer
[0] = echo_buffer
[1] = Qnil
;
22095 staticpro (&echo_buffer
[0]);
22096 staticpro (&echo_buffer
[1]);
22098 echo_area_buffer
[0] = echo_area_buffer
[1] = Qnil
;
22099 staticpro (&echo_area_buffer
[0]);
22100 staticpro (&echo_area_buffer
[1]);
22102 Vmessages_buffer_name
= build_string ("*Messages*");
22103 staticpro (&Vmessages_buffer_name
);
22105 mode_line_proptrans_alist
= Qnil
;
22106 staticpro (&mode_line_proptrans_alist
);
22108 mode_line_string_list
= Qnil
;
22109 staticpro (&mode_line_string_list
);
22111 help_echo_string
= Qnil
;
22112 staticpro (&help_echo_string
);
22113 help_echo_object
= Qnil
;
22114 staticpro (&help_echo_object
);
22115 help_echo_window
= Qnil
;
22116 staticpro (&help_echo_window
);
22117 previous_help_echo_string
= Qnil
;
22118 staticpro (&previous_help_echo_string
);
22119 help_echo_pos
= -1;
22121 #ifdef HAVE_WINDOW_SYSTEM
22122 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
22123 doc
: /* *Non-nil means draw block cursor as wide as the glyph under it.
22124 For example, if a block cursor is over a tab, it will be drawn as
22125 wide as that tab on the display. */);
22126 x_stretch_cursor_p
= 0;
22129 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace
,
22130 doc
: /* *Non-nil means highlight trailing whitespace.
22131 The face used for trailing whitespace is `trailing-whitespace'. */);
22132 Vshow_trailing_whitespace
= Qnil
;
22134 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer
,
22135 doc
: /* *The pointer shape to show in void text areas.
22136 Nil means to show the text pointer. Other options are `arrow', `text',
22137 `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
22138 Vvoid_text_area_pointer
= Qarrow
;
22140 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay
,
22141 doc
: /* Non-nil means don't actually do any redisplay.
22142 This is used for internal purposes. */);
22143 Vinhibit_redisplay
= Qnil
;
22145 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string
,
22146 doc
: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
22147 Vglobal_mode_string
= Qnil
;
22149 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position
,
22150 doc
: /* Marker for where to display an arrow on top of the buffer text.
22151 This must be the beginning of a line in order to work.
22152 See also `overlay-arrow-string'. */);
22153 Voverlay_arrow_position
= Qnil
;
22155 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string
,
22156 doc
: /* String to display as an arrow in non-window frames.
22157 See also `overlay-arrow-position'. */);
22158 Voverlay_arrow_string
= Qnil
;
22160 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list
,
22161 doc
: /* List of variables (symbols) which hold markers for overlay arrows.
22162 The symbols on this list are examined during redisplay to determine
22163 where to display overlay arrows. */);
22164 Voverlay_arrow_variable_list
22165 = Fcons (intern ("overlay-arrow-position"), Qnil
);
22167 DEFVAR_INT ("scroll-step", &scroll_step
,
22168 doc
: /* *The number of lines to try scrolling a window by when point moves out.
22169 If that fails to bring point back on frame, point is centered instead.
22170 If this is zero, point is always centered after it moves off frame.
22171 If you want scrolling to always be a line at a time, you should set
22172 `scroll-conservatively' to a large value rather than set this to 1. */);
22174 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively
,
22175 doc
: /* *Scroll up to this many lines, to bring point back on screen.
22176 A value of zero means to scroll the text to center point vertically
22177 in the window. */);
22178 scroll_conservatively
= 0;
22180 DEFVAR_INT ("scroll-margin", &scroll_margin
,
22181 doc
: /* *Number of lines of margin at the top and bottom of a window.
22182 Recenter the window whenever point gets within this many lines
22183 of the top or bottom of the window. */);
22186 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch
,
22187 doc
: /* Pixels per inch on current display.
22188 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
22189 Vdisplay_pixels_per_inch
= make_float (72.0);
22192 DEFVAR_INT ("debug-end-pos", &debug_end_pos
, doc
: /* Don't ask. */);
22195 DEFVAR_BOOL ("truncate-partial-width-windows",
22196 &truncate_partial_width_windows
,
22197 doc
: /* *Non-nil means truncate lines in all windows less than full frame wide. */);
22198 truncate_partial_width_windows
= 1;
22200 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video
,
22201 doc
: /* nil means display the mode-line/header-line/menu-bar in the default face.
22202 Any other value means to use the appropriate face, `mode-line',
22203 `header-line', or `menu' respectively. */);
22204 mode_line_inverse_video
= 1;
22206 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit
,
22207 doc
: /* *Maximum buffer size for which line number should be displayed.
22208 If the buffer is bigger than this, the line number does not appear
22209 in the mode line. A value of nil means no limit. */);
22210 Vline_number_display_limit
= Qnil
;
22212 DEFVAR_INT ("line-number-display-limit-width",
22213 &line_number_display_limit_width
,
22214 doc
: /* *Maximum line width (in characters) for line number display.
22215 If the average length of the lines near point is bigger than this, then the
22216 line number may be omitted from the mode line. */);
22217 line_number_display_limit_width
= 200;
22219 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows
,
22220 doc
: /* *Non-nil means highlight region even in nonselected windows. */);
22221 highlight_nonselected_windows
= 0;
22223 DEFVAR_BOOL ("multiple-frames", &multiple_frames
,
22224 doc
: /* Non-nil if more than one frame is visible on this display.
22225 Minibuffer-only frames don't count, but iconified frames do.
22226 This variable is not guaranteed to be accurate except while processing
22227 `frame-title-format' and `icon-title-format'. */);
22229 DEFVAR_LISP ("frame-title-format", &Vframe_title_format
,
22230 doc
: /* Template for displaying the title bar of visible frames.
22231 \(Assuming the window manager supports this feature.)
22232 This variable has the same structure as `mode-line-format' (which see),
22233 and is used only on frames for which no explicit name has been set
22234 \(see `modify-frame-parameters'). */);
22236 DEFVAR_LISP ("icon-title-format", &Vicon_title_format
,
22237 doc
: /* Template for displaying the title bar of an iconified frame.
22238 \(Assuming the window manager supports this feature.)
22239 This variable has the same structure as `mode-line-format' (which see),
22240 and is used only on frames for which no explicit name has been set
22241 \(see `modify-frame-parameters'). */);
22243 = Vframe_title_format
22244 = Fcons (intern ("multiple-frames"),
22245 Fcons (build_string ("%b"),
22246 Fcons (Fcons (empty_string
,
22247 Fcons (intern ("invocation-name"),
22248 Fcons (build_string ("@"),
22249 Fcons (intern ("system-name"),
22253 DEFVAR_LISP ("message-log-max", &Vmessage_log_max
,
22254 doc
: /* Maximum number of lines to keep in the message log buffer.
22255 If nil, disable message logging. If t, log messages but don't truncate
22256 the buffer when it becomes large. */);
22257 Vmessage_log_max
= make_number (50);
22259 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions
,
22260 doc
: /* Functions called before redisplay, if window sizes have changed.
22261 The value should be a list of functions that take one argument.
22262 Just before redisplay, for each frame, if any of its windows have changed
22263 size since the last redisplay, or have been split or deleted,
22264 all the functions in the list are called, with the frame as argument. */);
22265 Vwindow_size_change_functions
= Qnil
;
22267 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions
,
22268 doc
: /* List of functions to call before redisplaying a window with scrolling.
22269 Each function is called with two arguments, the window
22270 and its new display-start position. Note that the value of `window-end'
22271 is not valid when these functions are called. */);
22272 Vwindow_scroll_functions
= Qnil
;
22274 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window
,
22275 doc
: /* *Non-nil means autoselect window with mouse pointer. */);
22276 mouse_autoselect_window
= 0;
22278 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p
,
22279 doc
: /* *Non-nil means automatically resize tool-bars.
22280 This increases a tool-bar's height if not all tool-bar items are visible.
22281 It decreases a tool-bar's height when it would display blank lines
22283 auto_resize_tool_bars_p
= 1;
22285 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p
,
22286 doc
: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
22287 auto_raise_tool_bar_buttons_p
= 1;
22289 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin
,
22290 doc
: /* *Margin around tool-bar buttons in pixels.
22291 If an integer, use that for both horizontal and vertical margins.
22292 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
22293 HORZ specifying the horizontal margin, and VERT specifying the
22294 vertical margin. */);
22295 Vtool_bar_button_margin
= make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN
);
22297 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief
,
22298 doc
: /* *Relief thickness of tool-bar buttons. */);
22299 tool_bar_button_relief
= DEFAULT_TOOL_BAR_BUTTON_RELIEF
;
22301 DEFVAR_LISP ("fontification-functions", &Vfontification_functions
,
22302 doc
: /* List of functions to call to fontify regions of text.
22303 Each function is called with one argument POS. Functions must
22304 fontify a region starting at POS in the current buffer, and give
22305 fontified regions the property `fontified'. */);
22306 Vfontification_functions
= Qnil
;
22307 Fmake_variable_buffer_local (Qfontification_functions
);
22309 DEFVAR_BOOL ("unibyte-display-via-language-environment",
22310 &unibyte_display_via_language_environment
,
22311 doc
: /* *Non-nil means display unibyte text according to language environment.
22312 Specifically this means that unibyte non-ASCII characters
22313 are displayed by converting them to the equivalent multibyte characters
22314 according to the current language environment. As a result, they are
22315 displayed according to the current fontset. */);
22316 unibyte_display_via_language_environment
= 0;
22318 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height
,
22319 doc
: /* *Maximum height for resizing mini-windows.
22320 If a float, it specifies a fraction of the mini-window frame's height.
22321 If an integer, it specifies a number of lines. */);
22322 Vmax_mini_window_height
= make_float (0.25);
22324 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows
,
22325 doc
: /* *How to resize mini-windows.
22326 A value of nil means don't automatically resize mini-windows.
22327 A value of t means resize them to fit the text displayed in them.
22328 A value of `grow-only', the default, means let mini-windows grow
22329 only, until their display becomes empty, at which point the windows
22330 go back to their normal size. */);
22331 Vresize_mini_windows
= Qgrow_only
;
22333 DEFVAR_LISP ("cursor-in-non-selected-windows",
22334 &Vcursor_in_non_selected_windows
,
22335 doc
: /* *Cursor type to display in non-selected windows.
22336 t means to use hollow box cursor. See `cursor-type' for other values. */);
22337 Vcursor_in_non_selected_windows
= Qt
;
22339 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist
,
22340 doc
: /* Alist specifying how to blink the cursor off.
22341 Each element has the form (ON-STATE . OFF-STATE). Whenever the
22342 `cursor-type' frame-parameter or variable equals ON-STATE,
22343 comparing using `equal', Emacs uses OFF-STATE to specify
22344 how to blink it off. */);
22345 Vblink_cursor_alist
= Qnil
;
22347 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p
,
22348 doc
: /* *Non-nil means scroll the display automatically to make point visible. */);
22349 automatic_hscrolling_p
= 1;
22351 DEFVAR_INT ("hscroll-margin", &hscroll_margin
,
22352 doc
: /* *How many columns away from the window edge point is allowed to get
22353 before automatic hscrolling will horizontally scroll the window. */);
22354 hscroll_margin
= 5;
22356 DEFVAR_LISP ("hscroll-step", &Vhscroll_step
,
22357 doc
: /* *How many columns to scroll the window when point gets too close to the edge.
22358 When point is less than `automatic-hscroll-margin' columns from the window
22359 edge, automatic hscrolling will scroll the window by the amount of columns
22360 determined by this variable. If its value is a positive integer, scroll that
22361 many columns. If it's a positive floating-point number, it specifies the
22362 fraction of the window's width to scroll. If it's nil or zero, point will be
22363 centered horizontally after the scroll. Any other value, including negative
22364 numbers, are treated as if the value were zero.
22366 Automatic hscrolling always moves point outside the scroll margin, so if
22367 point was more than scroll step columns inside the margin, the window will
22368 scroll more than the value given by the scroll step.
22370 Note that the lower bound for automatic hscrolling specified by `scroll-left'
22371 and `scroll-right' overrides this variable's effect. */);
22372 Vhscroll_step
= make_number (0);
22374 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines
,
22375 doc
: /* If non-nil, messages are truncated instead of resizing the echo area.
22376 Bind this around calls to `message' to let it take effect. */);
22377 message_truncate_lines
= 0;
22379 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook
,
22380 doc
: /* Normal hook run for clicks on menu bar, before displaying a submenu.
22381 Can be used to update submenus whose contents should vary. */);
22382 Vmenu_bar_update_hook
= Qnil
;
22384 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update
,
22385 doc
: /* Non-nil means don't update menu bars. Internal use only. */);
22386 inhibit_menubar_update
= 0;
22388 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay
,
22389 doc
: /* Non-nil means don't eval Lisp during redisplay. */);
22390 inhibit_eval_during_redisplay
= 0;
22392 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces
,
22393 doc
: /* Non-nil means don't free realized faces. Internal use only. */);
22394 inhibit_free_realized_faces
= 0;
22397 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id
,
22398 doc
: /* Inhibit try_window_id display optimization. */);
22399 inhibit_try_window_id
= 0;
22401 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing
,
22402 doc
: /* Inhibit try_window_reusing display optimization. */);
22403 inhibit_try_window_reusing
= 0;
22405 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement
,
22406 doc
: /* Inhibit try_cursor_movement display optimization. */);
22407 inhibit_try_cursor_movement
= 0;
22408 #endif /* GLYPH_DEBUG */
22412 /* Initialize this module when Emacs starts. */
22417 Lisp_Object root_window
;
22418 struct window
*mini_w
;
22420 current_header_line_height
= current_mode_line_height
= -1;
22422 CHARPOS (this_line_start_pos
) = 0;
22424 mini_w
= XWINDOW (minibuf_window
);
22425 root_window
= FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w
)));
22427 if (!noninteractive
)
22429 struct frame
*f
= XFRAME (WINDOW_FRAME (XWINDOW (root_window
)));
22432 XWINDOW (root_window
)->top_line
= make_number (FRAME_TOP_MARGIN (f
));
22433 set_window_height (root_window
,
22434 FRAME_LINES (f
) - 1 - FRAME_TOP_MARGIN (f
),
22436 mini_w
->top_line
= make_number (FRAME_LINES (f
) - 1);
22437 set_window_height (minibuf_window
, 1, 0);
22439 XWINDOW (root_window
)->total_cols
= make_number (FRAME_COLS (f
));
22440 mini_w
->total_cols
= make_number (FRAME_COLS (f
));
22442 scratch_glyph_row
.glyphs
[TEXT_AREA
] = scratch_glyphs
;
22443 scratch_glyph_row
.glyphs
[TEXT_AREA
+ 1]
22444 = scratch_glyphs
+ MAX_SCRATCH_GLYPHS
;
22446 /* The default ellipsis glyphs `...'. */
22447 for (i
= 0; i
< 3; ++i
)
22448 default_invis_vector
[i
] = make_number ('.');
22452 /* Allocate the buffer for frame titles.
22453 Also used for `format-mode-line'. */
22455 frame_title_buf
= (char *) xmalloc (size
);
22456 frame_title_buf_end
= frame_title_buf
+ size
;
22457 frame_title_ptr
= NULL
;
22460 help_echo_showing_p
= 0;
22464 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
22465 (do not change this comment) */