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
205 #ifndef FRAME_X_OUTPUT
206 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
209 #define INFINITY 10000000
211 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
213 extern void set_frame_menubar
P_ ((struct frame
*f
, int, int));
214 extern int pending_menu_activation
;
217 extern int interrupt_input
;
218 extern int command_loop_level
;
220 extern int minibuffer_auto_raise
;
221 extern Lisp_Object Vminibuffer_list
;
223 extern Lisp_Object Qface
;
224 extern Lisp_Object Qmode_line
, Qmode_line_inactive
, Qheader_line
;
226 extern Lisp_Object Voverriding_local_map
;
227 extern Lisp_Object Voverriding_local_map_menu_flag
;
228 extern Lisp_Object Qmenu_item
;
229 extern Lisp_Object Qwhen
;
230 extern Lisp_Object Qhelp_echo
;
232 Lisp_Object Qoverriding_local_map
, Qoverriding_terminal_local_map
;
233 Lisp_Object Qwindow_scroll_functions
, Vwindow_scroll_functions
;
234 Lisp_Object Qredisplay_end_trigger_functions
;
235 Lisp_Object Qinhibit_point_motion_hooks
;
236 Lisp_Object QCeval
, QCfile
, QCdata
, QCpropertize
;
237 Lisp_Object Qfontified
;
238 Lisp_Object Qgrow_only
;
239 Lisp_Object Qinhibit_eval_during_redisplay
;
240 Lisp_Object Qbuffer_position
, Qposition
, Qobject
;
243 Lisp_Object Qbar
, Qhbar
, Qbox
, Qhollow
;
246 Lisp_Object Qarrow
, Qhand
, Qtext
;
248 Lisp_Object Qrisky_local_variable
;
250 /* Holds the list (error). */
251 Lisp_Object list_of_error
;
253 /* Functions called to fontify regions of text. */
255 Lisp_Object Vfontification_functions
;
256 Lisp_Object Qfontification_functions
;
258 /* Non-zero means automatically select any window when the mouse
259 cursor moves into it. */
260 int mouse_autoselect_window
;
262 /* Non-zero means draw tool bar buttons raised when the mouse moves
265 int auto_raise_tool_bar_buttons_p
;
267 /* Margin around tool bar buttons in pixels. */
269 Lisp_Object Vtool_bar_button_margin
;
271 /* Thickness of shadow to draw around tool bar buttons. */
273 EMACS_INT tool_bar_button_relief
;
275 /* Non-zero means automatically resize tool-bars so that all tool-bar
276 items are visible, and no blank lines remain. */
278 int auto_resize_tool_bars_p
;
280 /* Non-zero means draw block and hollow cursor as wide as the glyph
281 under it. For example, if a block cursor is over a tab, it will be
282 drawn as wide as that tab on the display. */
284 int x_stretch_cursor_p
;
286 /* Non-nil means don't actually do any redisplay. */
288 Lisp_Object Vinhibit_redisplay
, Qinhibit_redisplay
;
290 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
292 int inhibit_eval_during_redisplay
;
294 /* Names of text properties relevant for redisplay. */
296 Lisp_Object Qdisplay
;
297 extern Lisp_Object Qface
, Qinvisible
, Qwidth
;
299 /* Symbols used in text property values. */
301 Lisp_Object Vdisplay_pixels_per_inch
;
302 Lisp_Object Qspace
, QCalign_to
, QCrelative_width
, QCrelative_height
;
303 Lisp_Object Qleft_margin
, Qright_margin
, Qspace_width
, Qraise
;
306 Lisp_Object Qmargin
, Qpointer
;
307 Lisp_Object Qline_height
, Qtotal
;
308 extern Lisp_Object Qheight
;
309 extern Lisp_Object QCwidth
, QCheight
, QCascent
;
310 extern Lisp_Object Qscroll_bar
;
312 /* Non-nil means highlight trailing whitespace. */
314 Lisp_Object Vshow_trailing_whitespace
;
316 #ifdef HAVE_WINDOW_SYSTEM
317 extern Lisp_Object Voverflow_newline_into_fringe
;
319 /* Test if overflow newline into fringe. Called with iterator IT
320 at or past right window margin, and with IT->current_x set. */
322 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) \
323 (!NILP (Voverflow_newline_into_fringe) \
324 && FRAME_WINDOW_P (it->f) \
325 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
326 && it->current_x == it->last_visible_x)
328 #endif /* HAVE_WINDOW_SYSTEM */
330 /* Non-nil means show the text cursor in void text areas
331 i.e. in blank areas after eol and eob. This used to be
332 the default in 21.3. */
334 Lisp_Object Vvoid_text_area_pointer
;
336 /* Name of the face used to highlight trailing whitespace. */
338 Lisp_Object Qtrailing_whitespace
;
340 /* The symbol `image' which is the car of the lists used to represent
345 /* The image map types. */
346 Lisp_Object QCmap
, QCpointer
;
347 Lisp_Object Qrect
, Qcircle
, Qpoly
;
349 /* Non-zero means print newline to stdout before next mini-buffer
352 int noninteractive_need_newline
;
354 /* Non-zero means print newline to message log before next message. */
356 static int message_log_need_newline
;
358 /* Three markers that message_dolog uses.
359 It could allocate them itself, but that causes trouble
360 in handling memory-full errors. */
361 static Lisp_Object message_dolog_marker1
;
362 static Lisp_Object message_dolog_marker2
;
363 static Lisp_Object message_dolog_marker3
;
365 /* The buffer position of the first character appearing entirely or
366 partially on the line of the selected window which contains the
367 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
368 redisplay optimization in redisplay_internal. */
370 static struct text_pos this_line_start_pos
;
372 /* Number of characters past the end of the line above, including the
373 terminating newline. */
375 static struct text_pos this_line_end_pos
;
377 /* The vertical positions and the height of this line. */
379 static int this_line_vpos
;
380 static int this_line_y
;
381 static int this_line_pixel_height
;
383 /* X position at which this display line starts. Usually zero;
384 negative if first character is partially visible. */
386 static int this_line_start_x
;
388 /* Buffer that this_line_.* variables are referring to. */
390 static struct buffer
*this_line_buffer
;
392 /* Nonzero means truncate lines in all windows less wide than the
395 int truncate_partial_width_windows
;
397 /* A flag to control how to display unibyte 8-bit character. */
399 int unibyte_display_via_language_environment
;
401 /* Nonzero means we have more than one non-mini-buffer-only frame.
402 Not guaranteed to be accurate except while parsing
403 frame-title-format. */
407 Lisp_Object Vglobal_mode_string
;
410 /* List of variables (symbols) which hold markers for overlay arrows.
411 The symbols on this list are examined during redisplay to determine
412 where to display overlay arrows. */
414 Lisp_Object Voverlay_arrow_variable_list
;
416 /* Marker for where to display an arrow on top of the buffer text. */
418 Lisp_Object Voverlay_arrow_position
;
420 /* String to display for the arrow. Only used on terminal frames. */
422 Lisp_Object Voverlay_arrow_string
;
424 /* Values of those variables at last redisplay are stored as
425 properties on `overlay-arrow-position' symbol. However, if
426 Voverlay_arrow_position is a marker, last-arrow-position is its
427 numerical position. */
429 Lisp_Object Qlast_arrow_position
, Qlast_arrow_string
;
431 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
432 properties on a symbol in overlay-arrow-variable-list. */
434 Lisp_Object Qoverlay_arrow_string
, Qoverlay_arrow_bitmap
;
436 /* Like mode-line-format, but for the title bar on a visible frame. */
438 Lisp_Object Vframe_title_format
;
440 /* Like mode-line-format, but for the title bar on an iconified frame. */
442 Lisp_Object Vicon_title_format
;
444 /* List of functions to call when a window's size changes. These
445 functions get one arg, a frame on which one or more windows' sizes
448 static Lisp_Object Vwindow_size_change_functions
;
450 Lisp_Object Qmenu_bar_update_hook
, Vmenu_bar_update_hook
;
452 /* Nonzero if overlay arrow has been displayed once in this window. */
454 static int overlay_arrow_seen
;
456 /* Nonzero means highlight the region even in nonselected windows. */
458 int highlight_nonselected_windows
;
460 /* If cursor motion alone moves point off frame, try scrolling this
461 many lines up or down if that will bring it back. */
463 static EMACS_INT scroll_step
;
465 /* Nonzero means scroll just far enough to bring point back on the
466 screen, when appropriate. */
468 static EMACS_INT scroll_conservatively
;
470 /* Recenter the window whenever point gets within this many lines of
471 the top or bottom of the window. This value is translated into a
472 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
473 that there is really a fixed pixel height scroll margin. */
475 EMACS_INT scroll_margin
;
477 /* Number of windows showing the buffer of the selected window (or
478 another buffer with the same base buffer). keyboard.c refers to
483 /* Vector containing glyphs for an ellipsis `...'. */
485 static Lisp_Object default_invis_vector
[3];
487 /* Zero means display the mode-line/header-line/menu-bar in the default face
488 (this slightly odd definition is for compatibility with previous versions
489 of emacs), non-zero means display them using their respective faces.
491 This variable is deprecated. */
493 int mode_line_inverse_video
;
495 /* Prompt to display in front of the mini-buffer contents. */
497 Lisp_Object minibuf_prompt
;
499 /* Width of current mini-buffer prompt. Only set after display_line
500 of the line that contains the prompt. */
502 int minibuf_prompt_width
;
504 /* This is the window where the echo area message was displayed. It
505 is always a mini-buffer window, but it may not be the same window
506 currently active as a mini-buffer. */
508 Lisp_Object echo_area_window
;
510 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
511 pushes the current message and the value of
512 message_enable_multibyte on the stack, the function restore_message
513 pops the stack and displays MESSAGE again. */
515 Lisp_Object Vmessage_stack
;
517 /* Nonzero means multibyte characters were enabled when the echo area
518 message was specified. */
520 int message_enable_multibyte
;
522 /* Nonzero if we should redraw the mode lines on the next redisplay. */
524 int update_mode_lines
;
526 /* Nonzero if window sizes or contents have changed since last
527 redisplay that finished. */
529 int windows_or_buffers_changed
;
531 /* Nonzero means a frame's cursor type has been changed. */
533 int cursor_type_changed
;
535 /* Nonzero after display_mode_line if %l was used and it displayed a
538 int line_number_displayed
;
540 /* Maximum buffer size for which to display line numbers. */
542 Lisp_Object Vline_number_display_limit
;
544 /* Line width to consider when repositioning for line number display. */
546 static EMACS_INT line_number_display_limit_width
;
548 /* Number of lines to keep in the message log buffer. t means
549 infinite. nil means don't log at all. */
551 Lisp_Object Vmessage_log_max
;
553 /* The name of the *Messages* buffer, a string. */
555 static Lisp_Object Vmessages_buffer_name
;
557 /* Current, index 0, and last displayed echo area message. Either
558 buffers from echo_buffers, or nil to indicate no message. */
560 Lisp_Object echo_area_buffer
[2];
562 /* The buffers referenced from echo_area_buffer. */
564 static Lisp_Object echo_buffer
[2];
566 /* A vector saved used in with_area_buffer to reduce consing. */
568 static Lisp_Object Vwith_echo_area_save_vector
;
570 /* Non-zero means display_echo_area should display the last echo area
571 message again. Set by redisplay_preserve_echo_area. */
573 static int display_last_displayed_message_p
;
575 /* Nonzero if echo area is being used by print; zero if being used by
578 int message_buf_print
;
580 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
582 Lisp_Object Qinhibit_menubar_update
;
583 int inhibit_menubar_update
;
585 /* Maximum height for resizing mini-windows. Either a float
586 specifying a fraction of the available height, or an integer
587 specifying a number of lines. */
589 Lisp_Object Vmax_mini_window_height
;
591 /* Non-zero means messages should be displayed with truncated
592 lines instead of being continued. */
594 int message_truncate_lines
;
595 Lisp_Object Qmessage_truncate_lines
;
597 /* Set to 1 in clear_message to make redisplay_internal aware
598 of an emptied echo area. */
600 static int message_cleared_p
;
602 /* Non-zero means we want a hollow cursor in windows that are not
603 selected. Zero means there's no cursor in such windows. */
605 Lisp_Object Vcursor_in_non_selected_windows
;
606 Lisp_Object Qcursor_in_non_selected_windows
;
608 /* How to blink the default frame cursor off. */
609 Lisp_Object Vblink_cursor_alist
;
611 /* A scratch glyph row with contents used for generating truncation
612 glyphs. Also used in direct_output_for_insert. */
614 #define MAX_SCRATCH_GLYPHS 100
615 struct glyph_row scratch_glyph_row
;
616 static struct glyph scratch_glyphs
[MAX_SCRATCH_GLYPHS
];
618 /* Ascent and height of the last line processed by move_it_to. */
620 static int last_max_ascent
, last_height
;
622 /* Non-zero if there's a help-echo in the echo area. */
624 int help_echo_showing_p
;
626 /* If >= 0, computed, exact values of mode-line and header-line height
627 to use in the macros CURRENT_MODE_LINE_HEIGHT and
628 CURRENT_HEADER_LINE_HEIGHT. */
630 int current_mode_line_height
, current_header_line_height
;
632 /* The maximum distance to look ahead for text properties. Values
633 that are too small let us call compute_char_face and similar
634 functions too often which is expensive. Values that are too large
635 let us call compute_char_face and alike too often because we
636 might not be interested in text properties that far away. */
638 #define TEXT_PROP_DISTANCE_LIMIT 100
642 /* Variables to turn off display optimizations from Lisp. */
644 int inhibit_try_window_id
, inhibit_try_window_reusing
;
645 int inhibit_try_cursor_movement
;
647 /* Non-zero means print traces of redisplay if compiled with
650 int trace_redisplay_p
;
652 #endif /* GLYPH_DEBUG */
654 #ifdef DEBUG_TRACE_MOVE
655 /* Non-zero means trace with TRACE_MOVE to stderr. */
658 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
660 #define TRACE_MOVE(x) (void) 0
663 /* Non-zero means automatically scroll windows horizontally to make
666 int automatic_hscrolling_p
;
668 /* How close to the margin can point get before the window is scrolled
670 EMACS_INT hscroll_margin
;
672 /* How much to scroll horizontally when point is inside the above margin. */
673 Lisp_Object Vhscroll_step
;
675 /* A list of symbols, one for each supported image type. */
677 Lisp_Object Vimage_types
;
679 /* The variable `resize-mini-windows'. If nil, don't resize
680 mini-windows. If t, always resize them to fit the text they
681 display. If `grow-only', let mini-windows grow only until they
684 Lisp_Object Vresize_mini_windows
;
686 /* Buffer being redisplayed -- for redisplay_window_error. */
688 struct buffer
*displayed_buffer
;
690 /* Value returned from text property handlers (see below). */
695 HANDLED_RECOMPUTE_PROPS
,
696 HANDLED_OVERLAY_STRING_CONSUMED
,
700 /* A description of text properties that redisplay is interested
705 /* The name of the property. */
708 /* A unique index for the property. */
711 /* A handler function called to set up iterator IT from the property
712 at IT's current position. Value is used to steer handle_stop. */
713 enum prop_handled (*handler
) P_ ((struct it
*it
));
716 static enum prop_handled handle_face_prop
P_ ((struct it
*));
717 static enum prop_handled handle_invisible_prop
P_ ((struct it
*));
718 static enum prop_handled handle_display_prop
P_ ((struct it
*));
719 static enum prop_handled handle_composition_prop
P_ ((struct it
*));
720 static enum prop_handled handle_overlay_change
P_ ((struct it
*));
721 static enum prop_handled handle_fontified_prop
P_ ((struct it
*));
723 /* Properties handled by iterators. */
725 static struct props it_props
[] =
727 {&Qfontified
, FONTIFIED_PROP_IDX
, handle_fontified_prop
},
728 /* Handle `face' before `display' because some sub-properties of
729 `display' need to know the face. */
730 {&Qface
, FACE_PROP_IDX
, handle_face_prop
},
731 {&Qdisplay
, DISPLAY_PROP_IDX
, handle_display_prop
},
732 {&Qinvisible
, INVISIBLE_PROP_IDX
, handle_invisible_prop
},
733 {&Qcomposition
, COMPOSITION_PROP_IDX
, handle_composition_prop
},
737 /* Value is the position described by X. If X is a marker, value is
738 the marker_position of X. Otherwise, value is X. */
740 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
742 /* Enumeration returned by some move_it_.* functions internally. */
746 /* Not used. Undefined value. */
749 /* Move ended at the requested buffer position or ZV. */
750 MOVE_POS_MATCH_OR_ZV
,
752 /* Move ended at the requested X pixel position. */
755 /* Move within a line ended at the end of a line that must be
759 /* Move within a line ended at the end of a line that would
760 be displayed truncated. */
763 /* Move within a line ended at a line end. */
767 /* This counter is used to clear the face cache every once in a while
768 in redisplay_internal. It is incremented for each redisplay.
769 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
772 #define CLEAR_FACE_CACHE_COUNT 500
773 static int clear_face_cache_count
;
775 /* Record the previous terminal frame we displayed. */
777 static struct frame
*previous_terminal_frame
;
779 /* Non-zero while redisplay_internal is in progress. */
783 /* Non-zero means don't free realized faces. Bound while freeing
784 realized faces is dangerous because glyph matrices might still
787 int inhibit_free_realized_faces
;
788 Lisp_Object Qinhibit_free_realized_faces
;
790 /* If a string, XTread_socket generates an event to display that string.
791 (The display is done in read_char.) */
793 Lisp_Object help_echo_string
;
794 Lisp_Object help_echo_window
;
795 Lisp_Object help_echo_object
;
798 /* Temporary variable for XTread_socket. */
800 Lisp_Object previous_help_echo_string
;
802 /* Null glyph slice */
804 static struct glyph_slice null_glyph_slice
= { 0, 0, 0, 0 };
807 /* Function prototypes. */
809 static void setup_for_ellipsis
P_ ((struct it
*));
810 static void mark_window_display_accurate_1
P_ ((struct window
*, int));
811 static int single_display_prop_string_p
P_ ((Lisp_Object
, Lisp_Object
));
812 static int display_prop_string_p
P_ ((Lisp_Object
, Lisp_Object
));
813 static int cursor_row_p
P_ ((struct window
*, struct glyph_row
*));
814 static int redisplay_mode_lines
P_ ((Lisp_Object
, int));
815 static char *decode_mode_spec_coding
P_ ((Lisp_Object
, char *, int));
818 static int invisible_text_between_p
P_ ((struct it
*, int, int));
821 static int next_element_from_ellipsis
P_ ((struct it
*));
822 static void pint2str
P_ ((char *, int, int));
823 static void pint2hrstr
P_ ((char *, int, int));
824 static struct text_pos run_window_scroll_functions
P_ ((Lisp_Object
,
826 static void reconsider_clip_changes
P_ ((struct window
*, struct buffer
*));
827 static int text_outside_line_unchanged_p
P_ ((struct window
*, int, int));
828 static void store_frame_title_char
P_ ((char));
829 static int store_frame_title
P_ ((const unsigned char *, int, int));
830 static void x_consider_frame_title
P_ ((Lisp_Object
));
831 static void handle_stop
P_ ((struct it
*));
832 static int tool_bar_lines_needed
P_ ((struct frame
*));
833 static int single_display_prop_intangible_p
P_ ((Lisp_Object
));
834 static void ensure_echo_area_buffers
P_ ((void));
835 static Lisp_Object unwind_with_echo_area_buffer
P_ ((Lisp_Object
));
836 static Lisp_Object with_echo_area_buffer_unwind_data
P_ ((struct window
*));
837 static int with_echo_area_buffer
P_ ((struct window
*, int,
838 int (*) (EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
),
839 EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
840 static void clear_garbaged_frames
P_ ((void));
841 static int current_message_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
842 static int truncate_message_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
843 static int set_message_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
844 static int display_echo_area
P_ ((struct window
*));
845 static int display_echo_area_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
846 static int resize_mini_window_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
847 static Lisp_Object unwind_redisplay
P_ ((Lisp_Object
));
848 static int string_char_and_length
P_ ((const unsigned char *, int, int *));
849 static struct text_pos display_prop_end
P_ ((struct it
*, Lisp_Object
,
851 static int compute_window_start_on_continuation_line
P_ ((struct window
*));
852 static Lisp_Object safe_eval_handler
P_ ((Lisp_Object
));
853 static void insert_left_trunc_glyphs
P_ ((struct it
*));
854 static struct glyph_row
*get_overlay_arrow_glyph_row
P_ ((struct window
*,
856 static void extend_face_to_end_of_line
P_ ((struct it
*));
857 static int append_space_for_newline
P_ ((struct it
*, int));
858 static int make_cursor_line_fully_visible
P_ ((struct window
*, int));
859 static int try_scrolling
P_ ((Lisp_Object
, int, EMACS_INT
, EMACS_INT
, int, int));
860 static int try_cursor_movement
P_ ((Lisp_Object
, struct text_pos
, int *));
861 static int trailing_whitespace_p
P_ ((int));
862 static int message_log_check_duplicate
P_ ((int, int, int, int));
863 static void push_it
P_ ((struct it
*));
864 static void pop_it
P_ ((struct it
*));
865 static void sync_frame_with_window_matrix_rows
P_ ((struct window
*));
866 static void select_frame_for_redisplay
P_ ((Lisp_Object
));
867 static void redisplay_internal
P_ ((int));
868 static int echo_area_display
P_ ((int));
869 static void redisplay_windows
P_ ((Lisp_Object
));
870 static void redisplay_window
P_ ((Lisp_Object
, int));
871 static Lisp_Object
redisplay_window_error ();
872 static Lisp_Object redisplay_window_0
P_ ((Lisp_Object
));
873 static Lisp_Object redisplay_window_1
P_ ((Lisp_Object
));
874 static void update_menu_bar
P_ ((struct frame
*, int));
875 static int try_window_reusing_current_matrix
P_ ((struct window
*));
876 static int try_window_id
P_ ((struct window
*));
877 static int display_line
P_ ((struct it
*));
878 static int display_mode_lines
P_ ((struct window
*));
879 static int display_mode_line
P_ ((struct window
*, enum face_id
, Lisp_Object
));
880 static int display_mode_element
P_ ((struct it
*, int, int, int, Lisp_Object
, Lisp_Object
, int));
881 static int store_mode_line_string
P_ ((char *, Lisp_Object
, int, int, int, Lisp_Object
));
882 static char *decode_mode_spec
P_ ((struct window
*, int, int, int, int *));
883 static void display_menu_bar
P_ ((struct window
*));
884 static int display_count_lines
P_ ((int, int, int, int, int *));
885 static int display_string
P_ ((unsigned char *, Lisp_Object
, Lisp_Object
,
886 int, int, struct it
*, int, int, int, int));
887 static void compute_line_metrics
P_ ((struct it
*));
888 static void run_redisplay_end_trigger_hook
P_ ((struct it
*));
889 static int get_overlay_strings
P_ ((struct it
*, int));
890 static void next_overlay_string
P_ ((struct it
*));
891 static void reseat
P_ ((struct it
*, struct text_pos
, int));
892 static void reseat_1
P_ ((struct it
*, struct text_pos
, int));
893 static void back_to_previous_visible_line_start
P_ ((struct it
*));
894 static void reseat_at_previous_visible_line_start
P_ ((struct it
*));
895 static void reseat_at_next_visible_line_start
P_ ((struct it
*, int));
896 static int next_element_from_display_vector
P_ ((struct it
*));
897 static int next_element_from_string
P_ ((struct it
*));
898 static int next_element_from_c_string
P_ ((struct it
*));
899 static int next_element_from_buffer
P_ ((struct it
*));
900 static int next_element_from_composition
P_ ((struct it
*));
901 static int next_element_from_image
P_ ((struct it
*));
902 static int next_element_from_stretch
P_ ((struct it
*));
903 static void load_overlay_strings
P_ ((struct it
*, int));
904 static int init_from_display_pos
P_ ((struct it
*, struct window
*,
905 struct display_pos
*));
906 static void reseat_to_string
P_ ((struct it
*, unsigned char *,
907 Lisp_Object
, int, int, int, int));
908 static enum move_it_result move_it_in_display_line_to
P_ ((struct it
*,
910 void move_it_vertically_backward
P_ ((struct it
*, int));
911 static void init_to_row_start
P_ ((struct it
*, struct window
*,
912 struct glyph_row
*));
913 static int init_to_row_end
P_ ((struct it
*, struct window
*,
914 struct glyph_row
*));
915 static void back_to_previous_line_start
P_ ((struct it
*));
916 static int forward_to_next_line_start
P_ ((struct it
*, int *));
917 static struct text_pos string_pos_nchars_ahead
P_ ((struct text_pos
,
919 static struct text_pos string_pos
P_ ((int, Lisp_Object
));
920 static struct text_pos c_string_pos
P_ ((int, unsigned char *, int));
921 static int number_of_chars
P_ ((unsigned char *, int));
922 static void compute_stop_pos
P_ ((struct it
*));
923 static void compute_string_pos
P_ ((struct text_pos
*, struct text_pos
,
925 static int face_before_or_after_it_pos
P_ ((struct it
*, int));
926 static int next_overlay_change
P_ ((int));
927 static int handle_single_display_prop
P_ ((struct it
*, Lisp_Object
,
928 Lisp_Object
, struct text_pos
*,
930 static int underlying_face_id
P_ ((struct it
*));
931 static int in_ellipses_for_invisible_text_p
P_ ((struct display_pos
*,
934 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
935 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
937 #ifdef HAVE_WINDOW_SYSTEM
939 static void update_tool_bar
P_ ((struct frame
*, int));
940 static void build_desired_tool_bar_string
P_ ((struct frame
*f
));
941 static int redisplay_tool_bar
P_ ((struct frame
*));
942 static void display_tool_bar_line
P_ ((struct it
*));
943 static void notice_overwritten_cursor
P_ ((struct window
*,
945 int, int, int, int));
949 #endif /* HAVE_WINDOW_SYSTEM */
952 /***********************************************************************
953 Window display dimensions
954 ***********************************************************************/
956 /* Return the bottom boundary y-position for text lines in window W.
957 This is the first y position at which a line cannot start.
958 It is relative to the top of the window.
960 This is the height of W minus the height of a mode line, if any. */
963 window_text_bottom_y (w
)
966 int height
= WINDOW_TOTAL_HEIGHT (w
);
968 if (WINDOW_WANTS_MODELINE_P (w
))
969 height
-= CURRENT_MODE_LINE_HEIGHT (w
);
973 /* Return the pixel width of display area AREA of window W. AREA < 0
974 means return the total width of W, not including fringes to
975 the left and right of the window. */
978 window_box_width (w
, area
)
982 int cols
= XFASTINT (w
->total_cols
);
985 if (!w
->pseudo_window_p
)
987 cols
-= WINDOW_SCROLL_BAR_COLS (w
);
989 if (area
== TEXT_AREA
)
991 if (INTEGERP (w
->left_margin_cols
))
992 cols
-= XFASTINT (w
->left_margin_cols
);
993 if (INTEGERP (w
->right_margin_cols
))
994 cols
-= XFASTINT (w
->right_margin_cols
);
995 pixels
= -WINDOW_TOTAL_FRINGE_WIDTH (w
);
997 else if (area
== LEFT_MARGIN_AREA
)
999 cols
= (INTEGERP (w
->left_margin_cols
)
1000 ? XFASTINT (w
->left_margin_cols
) : 0);
1003 else if (area
== RIGHT_MARGIN_AREA
)
1005 cols
= (INTEGERP (w
->right_margin_cols
)
1006 ? XFASTINT (w
->right_margin_cols
) : 0);
1011 return cols
* WINDOW_FRAME_COLUMN_WIDTH (w
) + pixels
;
1015 /* Return the pixel height of the display area of window W, not
1016 including mode lines of W, if any. */
1019 window_box_height (w
)
1022 struct frame
*f
= XFRAME (w
->frame
);
1023 int height
= WINDOW_TOTAL_HEIGHT (w
);
1025 xassert (height
>= 0);
1027 /* Note: the code below that determines the mode-line/header-line
1028 height is essentially the same as that contained in the macro
1029 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1030 the appropriate glyph row has its `mode_line_p' flag set,
1031 and if it doesn't, uses estimate_mode_line_height instead. */
1033 if (WINDOW_WANTS_MODELINE_P (w
))
1035 struct glyph_row
*ml_row
1036 = (w
->current_matrix
&& w
->current_matrix
->rows
1037 ? MATRIX_MODE_LINE_ROW (w
->current_matrix
)
1039 if (ml_row
&& ml_row
->mode_line_p
)
1040 height
-= ml_row
->height
;
1042 height
-= estimate_mode_line_height (f
, CURRENT_MODE_LINE_FACE_ID (w
));
1045 if (WINDOW_WANTS_HEADER_LINE_P (w
))
1047 struct glyph_row
*hl_row
1048 = (w
->current_matrix
&& w
->current_matrix
->rows
1049 ? MATRIX_HEADER_LINE_ROW (w
->current_matrix
)
1051 if (hl_row
&& hl_row
->mode_line_p
)
1052 height
-= hl_row
->height
;
1054 height
-= estimate_mode_line_height (f
, HEADER_LINE_FACE_ID
);
1057 /* With a very small font and a mode-line that's taller than
1058 default, we might end up with a negative height. */
1059 return max (0, height
);
1062 /* Return the window-relative coordinate of the left edge of display
1063 area AREA of window W. AREA < 0 means return the left edge of the
1064 whole window, to the right of the left fringe of W. */
1067 window_box_left_offset (w
, area
)
1073 if (w
->pseudo_window_p
)
1076 x
= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w
);
1078 if (area
== TEXT_AREA
)
1079 x
+= (WINDOW_LEFT_FRINGE_WIDTH (w
)
1080 + window_box_width (w
, LEFT_MARGIN_AREA
));
1081 else if (area
== RIGHT_MARGIN_AREA
)
1082 x
+= (WINDOW_LEFT_FRINGE_WIDTH (w
)
1083 + window_box_width (w
, LEFT_MARGIN_AREA
)
1084 + window_box_width (w
, TEXT_AREA
)
1085 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
1087 : WINDOW_RIGHT_FRINGE_WIDTH (w
)));
1088 else if (area
== LEFT_MARGIN_AREA
1089 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
))
1090 x
+= WINDOW_LEFT_FRINGE_WIDTH (w
);
1096 /* Return the window-relative coordinate of the right edge of display
1097 area AREA of window W. AREA < 0 means return the left edge of the
1098 whole window, to the left of the right fringe of W. */
1101 window_box_right_offset (w
, area
)
1105 return window_box_left_offset (w
, area
) + window_box_width (w
, area
);
1108 /* Return the frame-relative coordinate of the left edge of display
1109 area AREA of window W. AREA < 0 means return the left edge of the
1110 whole window, to the right of the left fringe of W. */
1113 window_box_left (w
, area
)
1117 struct frame
*f
= XFRAME (w
->frame
);
1120 if (w
->pseudo_window_p
)
1121 return FRAME_INTERNAL_BORDER_WIDTH (f
);
1123 x
= (WINDOW_LEFT_EDGE_X (w
)
1124 + window_box_left_offset (w
, area
));
1130 /* Return the frame-relative coordinate of the right edge of display
1131 area AREA of window W. AREA < 0 means return the left edge of the
1132 whole window, to the left of the right fringe of W. */
1135 window_box_right (w
, area
)
1139 return window_box_left (w
, area
) + window_box_width (w
, area
);
1142 /* Get the bounding box of the display area AREA of window W, without
1143 mode lines, in frame-relative coordinates. AREA < 0 means the
1144 whole window, not including the left and right fringes of
1145 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1146 coordinates of the upper-left corner of the box. Return in
1147 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1150 window_box (w
, area
, box_x
, box_y
, box_width
, box_height
)
1153 int *box_x
, *box_y
, *box_width
, *box_height
;
1156 *box_width
= window_box_width (w
, area
);
1158 *box_height
= window_box_height (w
);
1160 *box_x
= window_box_left (w
, area
);
1163 *box_y
= WINDOW_TOP_EDGE_Y (w
);
1164 if (WINDOW_WANTS_HEADER_LINE_P (w
))
1165 *box_y
+= CURRENT_HEADER_LINE_HEIGHT (w
);
1170 /* Get the bounding box of the display area AREA of window W, without
1171 mode lines. AREA < 0 means the whole window, not including the
1172 left and right fringe of the window. Return in *TOP_LEFT_X
1173 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1174 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1175 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1179 window_box_edges (w
, area
, top_left_x
, top_left_y
,
1180 bottom_right_x
, bottom_right_y
)
1183 int *top_left_x
, *top_left_y
, *bottom_right_x
, *bottom_right_y
;
1185 window_box (w
, area
, top_left_x
, top_left_y
, bottom_right_x
,
1187 *bottom_right_x
+= *top_left_x
;
1188 *bottom_right_y
+= *top_left_y
;
1193 /***********************************************************************
1195 ***********************************************************************/
1197 /* Return the bottom y-position of the line the iterator IT is in.
1198 This can modify IT's settings. */
1204 int line_height
= it
->max_ascent
+ it
->max_descent
;
1205 int line_top_y
= it
->current_y
;
1207 if (line_height
== 0)
1210 line_height
= last_height
;
1211 else if (IT_CHARPOS (*it
) < ZV
)
1213 move_it_by_lines (it
, 1, 1);
1214 line_height
= (it
->max_ascent
|| it
->max_descent
1215 ? it
->max_ascent
+ it
->max_descent
1220 struct glyph_row
*row
= it
->glyph_row
;
1222 /* Use the default character height. */
1223 it
->glyph_row
= NULL
;
1224 it
->what
= IT_CHARACTER
;
1227 PRODUCE_GLYPHS (it
);
1228 line_height
= it
->ascent
+ it
->descent
;
1229 it
->glyph_row
= row
;
1233 return line_top_y
+ line_height
;
1237 /* Return 1 if position CHARPOS is visible in window W. Set *FULLY to
1238 1 if POS is visible and the line containing POS is fully visible.
1239 EXACT_MODE_LINE_HEIGHTS_P non-zero means compute exact mode-line
1240 and header-lines heights. */
1243 pos_visible_p (w
, charpos
, fully
, x
, y
, exact_mode_line_heights_p
)
1245 int charpos
, *fully
, *x
, *y
, exact_mode_line_heights_p
;
1248 struct text_pos top
;
1250 struct buffer
*old_buffer
= NULL
;
1252 if (XBUFFER (w
->buffer
) != current_buffer
)
1254 old_buffer
= current_buffer
;
1255 set_buffer_internal_1 (XBUFFER (w
->buffer
));
1258 *fully
= visible_p
= 0;
1259 SET_TEXT_POS_FROM_MARKER (top
, w
->start
);
1261 /* Compute exact mode line heights, if requested. */
1262 if (exact_mode_line_heights_p
)
1264 if (WINDOW_WANTS_MODELINE_P (w
))
1265 current_mode_line_height
1266 = display_mode_line (w
, CURRENT_MODE_LINE_FACE_ID (w
),
1267 current_buffer
->mode_line_format
);
1269 if (WINDOW_WANTS_HEADER_LINE_P (w
))
1270 current_header_line_height
1271 = display_mode_line (w
, HEADER_LINE_FACE_ID
,
1272 current_buffer
->header_line_format
);
1275 start_display (&it
, w
, top
);
1276 move_it_to (&it
, charpos
, 0, it
.last_visible_y
, -1,
1277 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
1279 /* Note that we may overshoot because of invisible text. */
1280 if (IT_CHARPOS (it
) >= charpos
)
1282 int top_y
= it
.current_y
;
1283 int bottom_y
= line_bottom_y (&it
);
1284 int window_top_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
1286 if (top_y
< window_top_y
)
1287 visible_p
= bottom_y
> window_top_y
;
1288 else if (top_y
< it
.last_visible_y
)
1291 *fully
= bottom_y
<= it
.last_visible_y
;
1296 *y
= max (top_y
+ it
.max_ascent
- it
.ascent
, window_top_y
);
1299 else if (it
.current_y
+ it
.max_ascent
+ it
.max_descent
> it
.last_visible_y
)
1304 move_it_by_lines (&it
, 1, 0);
1305 if (charpos
< IT_CHARPOS (it
))
1310 move_it_to (&it2
, charpos
, -1, -1, -1, MOVE_TO_POS
);
1312 *y
= it2
.current_y
+ it2
.max_ascent
- it2
.ascent
;
1318 set_buffer_internal_1 (old_buffer
);
1320 current_header_line_height
= current_mode_line_height
= -1;
1326 /* Return the next character from STR which is MAXLEN bytes long.
1327 Return in *LEN the length of the character. This is like
1328 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1329 we find one, we return a `?', but with the length of the invalid
1333 string_char_and_length (str
, maxlen
, len
)
1334 const unsigned char *str
;
1339 c
= STRING_CHAR_AND_LENGTH (str
, maxlen
, *len
);
1340 if (!CHAR_VALID_P (c
, 1))
1341 /* We may not change the length here because other places in Emacs
1342 don't use this function, i.e. they silently accept invalid
1351 /* Given a position POS containing a valid character and byte position
1352 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1354 static struct text_pos
1355 string_pos_nchars_ahead (pos
, string
, nchars
)
1356 struct text_pos pos
;
1360 xassert (STRINGP (string
) && nchars
>= 0);
1362 if (STRING_MULTIBYTE (string
))
1364 int rest
= SBYTES (string
) - BYTEPOS (pos
);
1365 const unsigned char *p
= SDATA (string
) + BYTEPOS (pos
);
1370 string_char_and_length (p
, rest
, &len
);
1371 p
+= len
, rest
-= len
;
1372 xassert (rest
>= 0);
1374 BYTEPOS (pos
) += len
;
1378 SET_TEXT_POS (pos
, CHARPOS (pos
) + nchars
, BYTEPOS (pos
) + nchars
);
1384 /* Value is the text position, i.e. character and byte position,
1385 for character position CHARPOS in STRING. */
1387 static INLINE
struct text_pos
1388 string_pos (charpos
, string
)
1392 struct text_pos pos
;
1393 xassert (STRINGP (string
));
1394 xassert (charpos
>= 0);
1395 SET_TEXT_POS (pos
, charpos
, string_char_to_byte (string
, charpos
));
1400 /* Value is a text position, i.e. character and byte position, for
1401 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1402 means recognize multibyte characters. */
1404 static struct text_pos
1405 c_string_pos (charpos
, s
, multibyte_p
)
1410 struct text_pos pos
;
1412 xassert (s
!= NULL
);
1413 xassert (charpos
>= 0);
1417 int rest
= strlen (s
), len
;
1419 SET_TEXT_POS (pos
, 0, 0);
1422 string_char_and_length (s
, rest
, &len
);
1423 s
+= len
, rest
-= len
;
1424 xassert (rest
>= 0);
1426 BYTEPOS (pos
) += len
;
1430 SET_TEXT_POS (pos
, charpos
, charpos
);
1436 /* Value is the number of characters in C string S. MULTIBYTE_P
1437 non-zero means recognize multibyte characters. */
1440 number_of_chars (s
, multibyte_p
)
1448 int rest
= strlen (s
), len
;
1449 unsigned char *p
= (unsigned char *) s
;
1451 for (nchars
= 0; rest
> 0; ++nchars
)
1453 string_char_and_length (p
, rest
, &len
);
1454 rest
-= len
, p
+= len
;
1458 nchars
= strlen (s
);
1464 /* Compute byte position NEWPOS->bytepos corresponding to
1465 NEWPOS->charpos. POS is a known position in string STRING.
1466 NEWPOS->charpos must be >= POS.charpos. */
1469 compute_string_pos (newpos
, pos
, string
)
1470 struct text_pos
*newpos
, pos
;
1473 xassert (STRINGP (string
));
1474 xassert (CHARPOS (*newpos
) >= CHARPOS (pos
));
1476 if (STRING_MULTIBYTE (string
))
1477 *newpos
= string_pos_nchars_ahead (pos
, string
,
1478 CHARPOS (*newpos
) - CHARPOS (pos
));
1480 BYTEPOS (*newpos
) = CHARPOS (*newpos
);
1484 Return an estimation of the pixel height of mode or top lines on
1485 frame F. FACE_ID specifies what line's height to estimate. */
1488 estimate_mode_line_height (f
, face_id
)
1490 enum face_id face_id
;
1492 #ifdef HAVE_WINDOW_SYSTEM
1493 if (FRAME_WINDOW_P (f
))
1495 int height
= FONT_HEIGHT (FRAME_FONT (f
));
1497 /* This function is called so early when Emacs starts that the face
1498 cache and mode line face are not yet initialized. */
1499 if (FRAME_FACE_CACHE (f
))
1501 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1505 height
= FONT_HEIGHT (face
->font
);
1506 if (face
->box_line_width
> 0)
1507 height
+= 2 * face
->box_line_width
;
1518 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1519 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1520 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1521 not force the value into range. */
1524 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
, noclip
)
1526 register int pix_x
, pix_y
;
1528 NativeRectangle
*bounds
;
1532 #ifdef HAVE_WINDOW_SYSTEM
1533 if (FRAME_WINDOW_P (f
))
1535 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1536 even for negative values. */
1538 pix_x
-= FRAME_COLUMN_WIDTH (f
) - 1;
1540 pix_y
-= FRAME_LINE_HEIGHT (f
) - 1;
1542 pix_x
= FRAME_PIXEL_X_TO_COL (f
, pix_x
);
1543 pix_y
= FRAME_PIXEL_Y_TO_LINE (f
, pix_y
);
1546 STORE_NATIVE_RECT (*bounds
,
1547 FRAME_COL_TO_PIXEL_X (f
, pix_x
),
1548 FRAME_LINE_TO_PIXEL_Y (f
, pix_y
),
1549 FRAME_COLUMN_WIDTH (f
) - 1,
1550 FRAME_LINE_HEIGHT (f
) - 1);
1556 else if (pix_x
> FRAME_TOTAL_COLS (f
))
1557 pix_x
= FRAME_TOTAL_COLS (f
);
1561 else if (pix_y
> FRAME_LINES (f
))
1562 pix_y
= FRAME_LINES (f
);
1572 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1573 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1574 can't tell the positions because W's display is not up to date,
1578 glyph_to_pixel_coords (w
, hpos
, vpos
, frame_x
, frame_y
)
1581 int *frame_x
, *frame_y
;
1583 #ifdef HAVE_WINDOW_SYSTEM
1584 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w
))))
1588 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
1589 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
1591 if (display_completed
)
1593 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
1594 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
1595 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
1601 hpos
+= glyph
->pixel_width
;
1605 /* If first glyph is partially visible, its first visible position is still 0. */
1617 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, hpos
);
1618 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, vpos
);
1629 #ifdef HAVE_WINDOW_SYSTEM
1631 /* Find the glyph under window-relative coordinates X/Y in window W.
1632 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1633 strings. Return in *HPOS and *VPOS the row and column number of
1634 the glyph found. Return in *AREA the glyph area containing X.
1635 Value is a pointer to the glyph found or null if X/Y is not on
1636 text, or we can't tell because W's current matrix is not up to
1639 static struct glyph
*
1640 x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, dx
, dy
, area
)
1643 int *hpos
, *vpos
, *dx
, *dy
, *area
;
1645 struct glyph
*glyph
, *end
;
1646 struct glyph_row
*row
= NULL
;
1649 /* Find row containing Y. Give up if some row is not enabled. */
1650 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
1652 row
= MATRIX_ROW (w
->current_matrix
, i
);
1653 if (!row
->enabled_p
)
1655 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
1662 /* Give up if Y is not in the window. */
1663 if (i
== w
->current_matrix
->nrows
)
1666 /* Get the glyph area containing X. */
1667 if (w
->pseudo_window_p
)
1674 if (x
< window_box_left_offset (w
, TEXT_AREA
))
1676 *area
= LEFT_MARGIN_AREA
;
1677 x0
= window_box_left_offset (w
, LEFT_MARGIN_AREA
);
1679 else if (x
< window_box_right_offset (w
, TEXT_AREA
))
1682 x0
= window_box_left_offset (w
, TEXT_AREA
) + min (row
->x
, 0);
1686 *area
= RIGHT_MARGIN_AREA
;
1687 x0
= window_box_left_offset (w
, RIGHT_MARGIN_AREA
);
1691 /* Find glyph containing X. */
1692 glyph
= row
->glyphs
[*area
];
1693 end
= glyph
+ row
->used
[*area
];
1695 while (glyph
< end
&& x
>= glyph
->pixel_width
)
1697 x
-= glyph
->pixel_width
;
1707 *dy
= y
- (row
->y
+ row
->ascent
- glyph
->ascent
);
1710 *hpos
= glyph
- row
->glyphs
[*area
];
1716 Convert frame-relative x/y to coordinates relative to window W.
1717 Takes pseudo-windows into account. */
1720 frame_to_window_pixel_xy (w
, x
, y
)
1724 if (w
->pseudo_window_p
)
1726 /* A pseudo-window is always full-width, and starts at the
1727 left edge of the frame, plus a frame border. */
1728 struct frame
*f
= XFRAME (w
->frame
);
1729 *x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
1730 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
1734 *x
-= WINDOW_LEFT_EDGE_X (w
);
1735 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
1740 Return in *R the clipping rectangle for glyph string S. */
1743 get_glyph_string_clip_rect (s
, nr
)
1744 struct glyph_string
*s
;
1745 NativeRectangle
*nr
;
1749 if (s
->row
->full_width_p
)
1751 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1752 r
.x
= WINDOW_LEFT_EDGE_X (s
->w
);
1753 r
.width
= WINDOW_TOTAL_WIDTH (s
->w
);
1755 /* Unless displaying a mode or menu bar line, which are always
1756 fully visible, clip to the visible part of the row. */
1757 if (s
->w
->pseudo_window_p
)
1758 r
.height
= s
->row
->visible_height
;
1760 r
.height
= s
->height
;
1764 /* This is a text line that may be partially visible. */
1765 r
.x
= window_box_left (s
->w
, s
->area
);
1766 r
.width
= window_box_width (s
->w
, s
->area
);
1767 r
.height
= s
->row
->visible_height
;
1770 /* If S draws overlapping rows, it's sufficient to use the top and
1771 bottom of the window for clipping because this glyph string
1772 intentionally draws over other lines. */
1773 if (s
->for_overlaps_p
)
1775 r
.y
= WINDOW_HEADER_LINE_HEIGHT (s
->w
);
1776 r
.height
= window_text_bottom_y (s
->w
) - r
.y
;
1780 /* Don't use S->y for clipping because it doesn't take partially
1781 visible lines into account. For example, it can be negative for
1782 partially visible lines at the top of a window. */
1783 if (!s
->row
->full_width_p
1784 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
1785 r
.y
= WINDOW_HEADER_LINE_HEIGHT (s
->w
);
1787 r
.y
= max (0, s
->row
->y
);
1789 /* If drawing a tool-bar window, draw it over the internal border
1790 at the top of the window. */
1791 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
1792 r
.y
-= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
1795 r
.y
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
.y
);
1797 /* If drawing the cursor, don't let glyph draw outside its
1798 advertised boundaries. Cleartype does this under some circumstances. */
1799 if (s
->hl
== DRAW_CURSOR
)
1801 struct glyph
*glyph
= s
->first_glyph
;
1806 r
.width
-= s
->x
- r
.x
;
1809 r
.width
= min (r
.width
, glyph
->pixel_width
);
1811 /* Don't draw cursor glyph taller than our actual glyph. */
1812 height
= max (FRAME_LINE_HEIGHT (s
->f
), glyph
->ascent
+ glyph
->descent
);
1813 if (height
< r
.height
)
1815 int max_y
= r
.y
+ r
.height
;
1816 r
.y
= min (max_y
, s
->ybase
+ glyph
->descent
- height
);
1817 r
.height
= min (max_y
- r
.y
, height
);
1821 #ifdef CONVERT_FROM_XRECT
1822 CONVERT_FROM_XRECT (r
, *nr
);
1828 #endif /* HAVE_WINDOW_SYSTEM */
1831 /***********************************************************************
1832 Lisp form evaluation
1833 ***********************************************************************/
1835 /* Error handler for safe_eval and safe_call. */
1838 safe_eval_handler (arg
)
1841 add_to_log ("Error during redisplay: %s", arg
, Qnil
);
1846 /* Evaluate SEXPR and return the result, or nil if something went
1847 wrong. Prevent redisplay during the evaluation. */
1855 if (inhibit_eval_during_redisplay
)
1859 int count
= SPECPDL_INDEX ();
1860 struct gcpro gcpro1
;
1863 specbind (Qinhibit_redisplay
, Qt
);
1864 /* Use Qt to ensure debugger does not run,
1865 so there is no possibility of wanting to redisplay. */
1866 val
= internal_condition_case_1 (Feval
, sexpr
, Qt
,
1869 val
= unbind_to (count
, val
);
1876 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
1877 Return the result, or nil if something went wrong. Prevent
1878 redisplay during the evaluation. */
1881 safe_call (nargs
, args
)
1887 if (inhibit_eval_during_redisplay
)
1891 int count
= SPECPDL_INDEX ();
1892 struct gcpro gcpro1
;
1895 gcpro1
.nvars
= nargs
;
1896 specbind (Qinhibit_redisplay
, Qt
);
1897 /* Use Qt to ensure debugger does not run,
1898 so there is no possibility of wanting to redisplay. */
1899 val
= internal_condition_case_2 (Ffuncall
, nargs
, args
, Qt
,
1902 val
= unbind_to (count
, val
);
1909 /* Call function FN with one argument ARG.
1910 Return the result, or nil if something went wrong. */
1913 safe_call1 (fn
, arg
)
1914 Lisp_Object fn
, arg
;
1916 Lisp_Object args
[2];
1919 return safe_call (2, args
);
1924 /***********************************************************************
1926 ***********************************************************************/
1930 /* Define CHECK_IT to perform sanity checks on iterators.
1931 This is for debugging. It is too slow to do unconditionally. */
1937 if (it
->method
== next_element_from_string
)
1939 xassert (STRINGP (it
->string
));
1940 xassert (IT_STRING_CHARPOS (*it
) >= 0);
1944 xassert (IT_STRING_CHARPOS (*it
) < 0);
1945 if (it
->method
== next_element_from_buffer
)
1947 /* Check that character and byte positions agree. */
1948 xassert (IT_CHARPOS (*it
) == BYTE_TO_CHAR (IT_BYTEPOS (*it
)));
1953 xassert (it
->current
.dpvec_index
>= 0);
1955 xassert (it
->current
.dpvec_index
< 0);
1958 #define CHECK_IT(IT) check_it ((IT))
1962 #define CHECK_IT(IT) (void) 0
1969 /* Check that the window end of window W is what we expect it
1970 to be---the last row in the current matrix displaying text. */
1973 check_window_end (w
)
1976 if (!MINI_WINDOW_P (w
)
1977 && !NILP (w
->window_end_valid
))
1979 struct glyph_row
*row
;
1980 xassert ((row
= MATRIX_ROW (w
->current_matrix
,
1981 XFASTINT (w
->window_end_vpos
)),
1983 || MATRIX_ROW_DISPLAYS_TEXT_P (row
)
1984 || MATRIX_ROW_VPOS (row
, w
->current_matrix
) == 0));
1988 #define CHECK_WINDOW_END(W) check_window_end ((W))
1990 #else /* not GLYPH_DEBUG */
1992 #define CHECK_WINDOW_END(W) (void) 0
1994 #endif /* not GLYPH_DEBUG */
1998 /***********************************************************************
1999 Iterator initialization
2000 ***********************************************************************/
2002 /* Initialize IT for displaying current_buffer in window W, starting
2003 at character position CHARPOS. CHARPOS < 0 means that no buffer
2004 position is specified which is useful when the iterator is assigned
2005 a position later. BYTEPOS is the byte position corresponding to
2006 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2008 If ROW is not null, calls to produce_glyphs with IT as parameter
2009 will produce glyphs in that row.
2011 BASE_FACE_ID is the id of a base face to use. It must be one of
2012 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2013 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2014 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2016 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2017 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2018 will be initialized to use the corresponding mode line glyph row of
2019 the desired matrix of W. */
2022 init_iterator (it
, w
, charpos
, bytepos
, row
, base_face_id
)
2025 int charpos
, bytepos
;
2026 struct glyph_row
*row
;
2027 enum face_id base_face_id
;
2029 int highlight_region_p
;
2031 /* Some precondition checks. */
2032 xassert (w
!= NULL
&& it
!= NULL
);
2033 xassert (charpos
< 0 || (charpos
>= BUF_BEG (current_buffer
)
2036 /* If face attributes have been changed since the last redisplay,
2037 free realized faces now because they depend on face definitions
2038 that might have changed. Don't free faces while there might be
2039 desired matrices pending which reference these faces. */
2040 if (face_change_count
&& !inhibit_free_realized_faces
)
2042 face_change_count
= 0;
2043 free_all_realized_faces (Qnil
);
2046 /* Use one of the mode line rows of W's desired matrix if
2050 if (base_face_id
== MODE_LINE_FACE_ID
2051 || base_face_id
== MODE_LINE_INACTIVE_FACE_ID
)
2052 row
= MATRIX_MODE_LINE_ROW (w
->desired_matrix
);
2053 else if (base_face_id
== HEADER_LINE_FACE_ID
)
2054 row
= MATRIX_HEADER_LINE_ROW (w
->desired_matrix
);
2058 bzero (it
, sizeof *it
);
2059 it
->current
.overlay_string_index
= -1;
2060 it
->current
.dpvec_index
= -1;
2061 it
->base_face_id
= base_face_id
;
2063 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = -1;
2065 /* The window in which we iterate over current_buffer: */
2066 XSETWINDOW (it
->window
, w
);
2068 it
->f
= XFRAME (w
->frame
);
2070 /* Extra space between lines (on window systems only). */
2071 if (base_face_id
== DEFAULT_FACE_ID
2072 && FRAME_WINDOW_P (it
->f
))
2074 if (NATNUMP (current_buffer
->extra_line_spacing
))
2075 it
->extra_line_spacing
= XFASTINT (current_buffer
->extra_line_spacing
);
2076 else if (FLOATP (current_buffer
->extra_line_spacing
))
2077 it
->extra_line_spacing
= (XFLOAT_DATA (current_buffer
->extra_line_spacing
)
2078 * FRAME_LINE_HEIGHT (it
->f
));
2079 else if (it
->f
->extra_line_spacing
> 0)
2080 it
->extra_line_spacing
= it
->f
->extra_line_spacing
;
2083 /* If realized faces have been removed, e.g. because of face
2084 attribute changes of named faces, recompute them. When running
2085 in batch mode, the face cache of Vterminal_frame is null. If
2086 we happen to get called, make a dummy face cache. */
2087 if (noninteractive
&& FRAME_FACE_CACHE (it
->f
) == NULL
)
2088 init_frame_faces (it
->f
);
2089 if (FRAME_FACE_CACHE (it
->f
)->used
== 0)
2090 recompute_basic_faces (it
->f
);
2092 /* Current value of the `slice', `space-width', and 'height' properties. */
2093 it
->slice
.x
= it
->slice
.y
= it
->slice
.width
= it
->slice
.height
= Qnil
;
2094 it
->space_width
= Qnil
;
2095 it
->font_height
= Qnil
;
2096 it
->override_ascent
= -1;
2098 /* Are control characters displayed as `^C'? */
2099 it
->ctl_arrow_p
= !NILP (current_buffer
->ctl_arrow
);
2101 /* -1 means everything between a CR and the following line end
2102 is invisible. >0 means lines indented more than this value are
2104 it
->selective
= (INTEGERP (current_buffer
->selective_display
)
2105 ? XFASTINT (current_buffer
->selective_display
)
2106 : (!NILP (current_buffer
->selective_display
)
2108 it
->selective_display_ellipsis_p
2109 = !NILP (current_buffer
->selective_display_ellipses
);
2111 /* Display table to use. */
2112 it
->dp
= window_display_table (w
);
2114 /* Are multibyte characters enabled in current_buffer? */
2115 it
->multibyte_p
= !NILP (current_buffer
->enable_multibyte_characters
);
2117 /* Non-zero if we should highlight the region. */
2119 = (!NILP (Vtransient_mark_mode
)
2120 && !NILP (current_buffer
->mark_active
)
2121 && XMARKER (current_buffer
->mark
)->buffer
!= 0);
2123 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2124 start and end of a visible region in window IT->w. Set both to
2125 -1 to indicate no region. */
2126 if (highlight_region_p
2127 /* Maybe highlight only in selected window. */
2128 && (/* Either show region everywhere. */
2129 highlight_nonselected_windows
2130 /* Or show region in the selected window. */
2131 || w
== XWINDOW (selected_window
)
2132 /* Or show the region if we are in the mini-buffer and W is
2133 the window the mini-buffer refers to. */
2134 || (MINI_WINDOW_P (XWINDOW (selected_window
))
2135 && WINDOWP (minibuf_selected_window
)
2136 && w
== XWINDOW (minibuf_selected_window
))))
2138 int charpos
= marker_position (current_buffer
->mark
);
2139 it
->region_beg_charpos
= min (PT
, charpos
);
2140 it
->region_end_charpos
= max (PT
, charpos
);
2143 it
->region_beg_charpos
= it
->region_end_charpos
= -1;
2145 /* Get the position at which the redisplay_end_trigger hook should
2146 be run, if it is to be run at all. */
2147 if (MARKERP (w
->redisplay_end_trigger
)
2148 && XMARKER (w
->redisplay_end_trigger
)->buffer
!= 0)
2149 it
->redisplay_end_trigger_charpos
2150 = marker_position (w
->redisplay_end_trigger
);
2151 else if (INTEGERP (w
->redisplay_end_trigger
))
2152 it
->redisplay_end_trigger_charpos
= XINT (w
->redisplay_end_trigger
);
2154 /* Correct bogus values of tab_width. */
2155 it
->tab_width
= XINT (current_buffer
->tab_width
);
2156 if (it
->tab_width
<= 0 || it
->tab_width
> 1000)
2159 /* Are lines in the display truncated? */
2160 it
->truncate_lines_p
2161 = (base_face_id
!= DEFAULT_FACE_ID
2162 || XINT (it
->w
->hscroll
)
2163 || (truncate_partial_width_windows
2164 && !WINDOW_FULL_WIDTH_P (it
->w
))
2165 || !NILP (current_buffer
->truncate_lines
));
2167 /* Get dimensions of truncation and continuation glyphs. These are
2168 displayed as fringe bitmaps under X, so we don't need them for such
2170 if (!FRAME_WINDOW_P (it
->f
))
2172 if (it
->truncate_lines_p
)
2174 /* We will need the truncation glyph. */
2175 xassert (it
->glyph_row
== NULL
);
2176 produce_special_glyphs (it
, IT_TRUNCATION
);
2177 it
->truncation_pixel_width
= it
->pixel_width
;
2181 /* We will need the continuation glyph. */
2182 xassert (it
->glyph_row
== NULL
);
2183 produce_special_glyphs (it
, IT_CONTINUATION
);
2184 it
->continuation_pixel_width
= it
->pixel_width
;
2187 /* Reset these values to zero because the produce_special_glyphs
2188 above has changed them. */
2189 it
->pixel_width
= it
->ascent
= it
->descent
= 0;
2190 it
->phys_ascent
= it
->phys_descent
= 0;
2193 /* Set this after getting the dimensions of truncation and
2194 continuation glyphs, so that we don't produce glyphs when calling
2195 produce_special_glyphs, above. */
2196 it
->glyph_row
= row
;
2197 it
->area
= TEXT_AREA
;
2199 /* Get the dimensions of the display area. The display area
2200 consists of the visible window area plus a horizontally scrolled
2201 part to the left of the window. All x-values are relative to the
2202 start of this total display area. */
2203 if (base_face_id
!= DEFAULT_FACE_ID
)
2205 /* Mode lines, menu bar in terminal frames. */
2206 it
->first_visible_x
= 0;
2207 it
->last_visible_x
= WINDOW_TOTAL_WIDTH (w
);
2212 = XFASTINT (it
->w
->hscroll
) * FRAME_COLUMN_WIDTH (it
->f
);
2213 it
->last_visible_x
= (it
->first_visible_x
2214 + window_box_width (w
, TEXT_AREA
));
2216 /* If we truncate lines, leave room for the truncator glyph(s) at
2217 the right margin. Otherwise, leave room for the continuation
2218 glyph(s). Truncation and continuation glyphs are not inserted
2219 for window-based redisplay. */
2220 if (!FRAME_WINDOW_P (it
->f
))
2222 if (it
->truncate_lines_p
)
2223 it
->last_visible_x
-= it
->truncation_pixel_width
;
2225 it
->last_visible_x
-= it
->continuation_pixel_width
;
2228 it
->header_line_p
= WINDOW_WANTS_HEADER_LINE_P (w
);
2229 it
->current_y
= WINDOW_HEADER_LINE_HEIGHT (w
) + w
->vscroll
;
2232 /* Leave room for a border glyph. */
2233 if (!FRAME_WINDOW_P (it
->f
)
2234 && !WINDOW_RIGHTMOST_P (it
->w
))
2235 it
->last_visible_x
-= 1;
2237 it
->last_visible_y
= window_text_bottom_y (w
);
2239 /* For mode lines and alike, arrange for the first glyph having a
2240 left box line if the face specifies a box. */
2241 if (base_face_id
!= DEFAULT_FACE_ID
)
2245 it
->face_id
= base_face_id
;
2247 /* If we have a boxed mode line, make the first character appear
2248 with a left box line. */
2249 face
= FACE_FROM_ID (it
->f
, base_face_id
);
2250 if (face
->box
!= FACE_NO_BOX
)
2251 it
->start_of_box_run_p
= 1;
2254 /* If a buffer position was specified, set the iterator there,
2255 getting overlays and face properties from that position. */
2256 if (charpos
>= BUF_BEG (current_buffer
))
2258 it
->end_charpos
= ZV
;
2260 IT_CHARPOS (*it
) = charpos
;
2262 /* Compute byte position if not specified. */
2263 if (bytepos
< charpos
)
2264 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (charpos
);
2266 IT_BYTEPOS (*it
) = bytepos
;
2268 it
->start
= it
->current
;
2270 /* Compute faces etc. */
2271 reseat (it
, it
->current
.pos
, 1);
2278 /* Initialize IT for the display of window W with window start POS. */
2281 start_display (it
, w
, pos
)
2284 struct text_pos pos
;
2286 struct glyph_row
*row
;
2287 int first_vpos
= WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0;
2289 row
= w
->desired_matrix
->rows
+ first_vpos
;
2290 init_iterator (it
, w
, CHARPOS (pos
), BYTEPOS (pos
), row
, DEFAULT_FACE_ID
);
2291 it
->first_vpos
= first_vpos
;
2293 if (!it
->truncate_lines_p
)
2295 int start_at_line_beg_p
;
2296 int first_y
= it
->current_y
;
2298 /* If window start is not at a line start, skip forward to POS to
2299 get the correct continuation lines width. */
2300 start_at_line_beg_p
= (CHARPOS (pos
) == BEGV
2301 || FETCH_BYTE (BYTEPOS (pos
) - 1) == '\n');
2302 if (!start_at_line_beg_p
)
2306 reseat_at_previous_visible_line_start (it
);
2307 move_it_to (it
, CHARPOS (pos
), -1, -1, -1, MOVE_TO_POS
);
2309 new_x
= it
->current_x
+ it
->pixel_width
;
2311 /* If lines are continued, this line may end in the middle
2312 of a multi-glyph character (e.g. a control character
2313 displayed as \003, or in the middle of an overlay
2314 string). In this case move_it_to above will not have
2315 taken us to the start of the continuation line but to the
2316 end of the continued line. */
2317 if (it
->current_x
> 0
2318 && !it
->truncate_lines_p
/* Lines are continued. */
2319 && (/* And glyph doesn't fit on the line. */
2320 new_x
> it
->last_visible_x
2321 /* Or it fits exactly and we're on a window
2323 || (new_x
== it
->last_visible_x
2324 && FRAME_WINDOW_P (it
->f
))))
2326 if (it
->current
.dpvec_index
>= 0
2327 || it
->current
.overlay_string_index
>= 0)
2329 set_iterator_to_next (it
, 1);
2330 move_it_in_display_line_to (it
, -1, -1, 0);
2333 it
->continuation_lines_width
+= it
->current_x
;
2336 /* We're starting a new display line, not affected by the
2337 height of the continued line, so clear the appropriate
2338 fields in the iterator structure. */
2339 it
->max_ascent
= it
->max_descent
= 0;
2340 it
->max_phys_ascent
= it
->max_phys_descent
= 0;
2342 it
->current_y
= first_y
;
2344 it
->current_x
= it
->hpos
= 0;
2348 #if 0 /* Don't assert the following because start_display is sometimes
2349 called intentionally with a window start that is not at a
2350 line start. Please leave this code in as a comment. */
2352 /* Window start should be on a line start, now. */
2353 xassert (it
->continuation_lines_width
2354 || IT_CHARPOS (it
) == BEGV
2355 || FETCH_BYTE (IT_BYTEPOS (it
) - 1) == '\n');
2360 /* Return 1 if POS is a position in ellipses displayed for invisible
2361 text. W is the window we display, for text property lookup. */
2364 in_ellipses_for_invisible_text_p (pos
, w
)
2365 struct display_pos
*pos
;
2368 Lisp_Object prop
, window
;
2370 int charpos
= CHARPOS (pos
->pos
);
2372 /* If POS specifies a position in a display vector, this might
2373 be for an ellipsis displayed for invisible text. We won't
2374 get the iterator set up for delivering that ellipsis unless
2375 we make sure that it gets aware of the invisible text. */
2376 if (pos
->dpvec_index
>= 0
2377 && pos
->overlay_string_index
< 0
2378 && CHARPOS (pos
->string_pos
) < 0
2380 && (XSETWINDOW (window
, w
),
2381 prop
= Fget_char_property (make_number (charpos
),
2382 Qinvisible
, window
),
2383 !TEXT_PROP_MEANS_INVISIBLE (prop
)))
2385 prop
= Fget_char_property (make_number (charpos
- 1), Qinvisible
,
2387 ellipses_p
= 2 == TEXT_PROP_MEANS_INVISIBLE (prop
);
2394 /* Initialize IT for stepping through current_buffer in window W,
2395 starting at position POS that includes overlay string and display
2396 vector/ control character translation position information. Value
2397 is zero if there are overlay strings with newlines at POS. */
2400 init_from_display_pos (it
, w
, pos
)
2403 struct display_pos
*pos
;
2405 int charpos
= CHARPOS (pos
->pos
), bytepos
= BYTEPOS (pos
->pos
);
2406 int i
, overlay_strings_with_newlines
= 0;
2408 /* If POS specifies a position in a display vector, this might
2409 be for an ellipsis displayed for invisible text. We won't
2410 get the iterator set up for delivering that ellipsis unless
2411 we make sure that it gets aware of the invisible text. */
2412 if (in_ellipses_for_invisible_text_p (pos
, w
))
2418 /* Keep in mind: the call to reseat in init_iterator skips invisible
2419 text, so we might end up at a position different from POS. This
2420 is only a problem when POS is a row start after a newline and an
2421 overlay starts there with an after-string, and the overlay has an
2422 invisible property. Since we don't skip invisible text in
2423 display_line and elsewhere immediately after consuming the
2424 newline before the row start, such a POS will not be in a string,
2425 but the call to init_iterator below will move us to the
2427 init_iterator (it
, w
, charpos
, bytepos
, NULL
, DEFAULT_FACE_ID
);
2429 for (i
= 0; i
< it
->n_overlay_strings
; ++i
)
2431 const char *s
= SDATA (it
->overlay_strings
[i
]);
2432 const char *e
= s
+ SBYTES (it
->overlay_strings
[i
]);
2434 while (s
< e
&& *s
!= '\n')
2439 overlay_strings_with_newlines
= 1;
2444 /* If position is within an overlay string, set up IT to the right
2446 if (pos
->overlay_string_index
>= 0)
2450 /* If the first overlay string happens to have a `display'
2451 property for an image, the iterator will be set up for that
2452 image, and we have to undo that setup first before we can
2453 correct the overlay string index. */
2454 if (it
->method
== next_element_from_image
)
2457 /* We already have the first chunk of overlay strings in
2458 IT->overlay_strings. Load more until the one for
2459 pos->overlay_string_index is in IT->overlay_strings. */
2460 if (pos
->overlay_string_index
>= OVERLAY_STRING_CHUNK_SIZE
)
2462 int n
= pos
->overlay_string_index
/ OVERLAY_STRING_CHUNK_SIZE
;
2463 it
->current
.overlay_string_index
= 0;
2466 load_overlay_strings (it
, 0);
2467 it
->current
.overlay_string_index
+= OVERLAY_STRING_CHUNK_SIZE
;
2471 it
->current
.overlay_string_index
= pos
->overlay_string_index
;
2472 relative_index
= (it
->current
.overlay_string_index
2473 % OVERLAY_STRING_CHUNK_SIZE
);
2474 it
->string
= it
->overlay_strings
[relative_index
];
2475 xassert (STRINGP (it
->string
));
2476 it
->current
.string_pos
= pos
->string_pos
;
2477 it
->method
= next_element_from_string
;
2480 #if 0 /* This is bogus because POS not having an overlay string
2481 position does not mean it's after the string. Example: A
2482 line starting with a before-string and initialization of IT
2483 to the previous row's end position. */
2484 else if (it
->current
.overlay_string_index
>= 0)
2486 /* If POS says we're already after an overlay string ending at
2487 POS, make sure to pop the iterator because it will be in
2488 front of that overlay string. When POS is ZV, we've thereby
2489 also ``processed'' overlay strings at ZV. */
2492 it
->current
.overlay_string_index
= -1;
2493 it
->method
= next_element_from_buffer
;
2494 if (CHARPOS (pos
->pos
) == ZV
)
2495 it
->overlay_strings_at_end_processed_p
= 1;
2499 if (CHARPOS (pos
->string_pos
) >= 0)
2501 /* Recorded position is not in an overlay string, but in another
2502 string. This can only be a string from a `display' property.
2503 IT should already be filled with that string. */
2504 it
->current
.string_pos
= pos
->string_pos
;
2505 xassert (STRINGP (it
->string
));
2508 /* Restore position in display vector translations, control
2509 character translations or ellipses. */
2510 if (pos
->dpvec_index
>= 0)
2512 if (it
->dpvec
== NULL
)
2513 get_next_display_element (it
);
2514 xassert (it
->dpvec
&& it
->current
.dpvec_index
== 0);
2515 it
->current
.dpvec_index
= pos
->dpvec_index
;
2519 return !overlay_strings_with_newlines
;
2523 /* Initialize IT for stepping through current_buffer in window W
2524 starting at ROW->start. */
2527 init_to_row_start (it
, w
, row
)
2530 struct glyph_row
*row
;
2532 init_from_display_pos (it
, w
, &row
->start
);
2533 it
->start
= row
->start
;
2534 it
->continuation_lines_width
= row
->continuation_lines_width
;
2539 /* Initialize IT for stepping through current_buffer in window W
2540 starting in the line following ROW, i.e. starting at ROW->end.
2541 Value is zero if there are overlay strings with newlines at ROW's
2545 init_to_row_end (it
, w
, row
)
2548 struct glyph_row
*row
;
2552 if (init_from_display_pos (it
, w
, &row
->end
))
2554 if (row
->continued_p
)
2555 it
->continuation_lines_width
2556 = row
->continuation_lines_width
+ row
->pixel_width
;
2567 /***********************************************************************
2569 ***********************************************************************/
2571 /* Called when IT reaches IT->stop_charpos. Handle text property and
2572 overlay changes. Set IT->stop_charpos to the next position where
2579 enum prop_handled handled
;
2580 int handle_overlay_change_p
= 1;
2584 it
->current
.dpvec_index
= -1;
2588 handled
= HANDLED_NORMALLY
;
2590 /* Call text property handlers. */
2591 for (p
= it_props
; p
->handler
; ++p
)
2593 handled
= p
->handler (it
);
2595 if (handled
== HANDLED_RECOMPUTE_PROPS
)
2597 else if (handled
== HANDLED_RETURN
)
2599 else if (handled
== HANDLED_OVERLAY_STRING_CONSUMED
)
2600 handle_overlay_change_p
= 0;
2603 if (handled
!= HANDLED_RECOMPUTE_PROPS
)
2605 /* Don't check for overlay strings below when set to deliver
2606 characters from a display vector. */
2607 if (it
->method
== next_element_from_display_vector
)
2608 handle_overlay_change_p
= 0;
2610 /* Handle overlay changes. */
2611 if (handle_overlay_change_p
)
2612 handled
= handle_overlay_change (it
);
2614 /* Determine where to stop next. */
2615 if (handled
== HANDLED_NORMALLY
)
2616 compute_stop_pos (it
);
2619 while (handled
== HANDLED_RECOMPUTE_PROPS
);
2623 /* Compute IT->stop_charpos from text property and overlay change
2624 information for IT's current position. */
2627 compute_stop_pos (it
)
2630 register INTERVAL iv
, next_iv
;
2631 Lisp_Object object
, limit
, position
;
2633 /* If nowhere else, stop at the end. */
2634 it
->stop_charpos
= it
->end_charpos
;
2636 if (STRINGP (it
->string
))
2638 /* Strings are usually short, so don't limit the search for
2640 object
= it
->string
;
2642 position
= make_number (IT_STRING_CHARPOS (*it
));
2648 /* If next overlay change is in front of the current stop pos
2649 (which is IT->end_charpos), stop there. Note: value of
2650 next_overlay_change is point-max if no overlay change
2652 charpos
= next_overlay_change (IT_CHARPOS (*it
));
2653 if (charpos
< it
->stop_charpos
)
2654 it
->stop_charpos
= charpos
;
2656 /* If showing the region, we have to stop at the region
2657 start or end because the face might change there. */
2658 if (it
->region_beg_charpos
> 0)
2660 if (IT_CHARPOS (*it
) < it
->region_beg_charpos
)
2661 it
->stop_charpos
= min (it
->stop_charpos
, it
->region_beg_charpos
);
2662 else if (IT_CHARPOS (*it
) < it
->region_end_charpos
)
2663 it
->stop_charpos
= min (it
->stop_charpos
, it
->region_end_charpos
);
2666 /* Set up variables for computing the stop position from text
2667 property changes. */
2668 XSETBUFFER (object
, current_buffer
);
2669 limit
= make_number (IT_CHARPOS (*it
) + TEXT_PROP_DISTANCE_LIMIT
);
2670 position
= make_number (IT_CHARPOS (*it
));
2674 /* Get the interval containing IT's position. Value is a null
2675 interval if there isn't such an interval. */
2676 iv
= validate_interval_range (object
, &position
, &position
, 0);
2677 if (!NULL_INTERVAL_P (iv
))
2679 Lisp_Object values_here
[LAST_PROP_IDX
];
2682 /* Get properties here. */
2683 for (p
= it_props
; p
->handler
; ++p
)
2684 values_here
[p
->idx
] = textget (iv
->plist
, *p
->name
);
2686 /* Look for an interval following iv that has different
2688 for (next_iv
= next_interval (iv
);
2689 (!NULL_INTERVAL_P (next_iv
)
2691 || XFASTINT (limit
) > next_iv
->position
));
2692 next_iv
= next_interval (next_iv
))
2694 for (p
= it_props
; p
->handler
; ++p
)
2696 Lisp_Object new_value
;
2698 new_value
= textget (next_iv
->plist
, *p
->name
);
2699 if (!EQ (values_here
[p
->idx
], new_value
))
2707 if (!NULL_INTERVAL_P (next_iv
))
2709 if (INTEGERP (limit
)
2710 && next_iv
->position
>= XFASTINT (limit
))
2711 /* No text property change up to limit. */
2712 it
->stop_charpos
= min (XFASTINT (limit
), it
->stop_charpos
);
2714 /* Text properties change in next_iv. */
2715 it
->stop_charpos
= min (it
->stop_charpos
, next_iv
->position
);
2719 xassert (STRINGP (it
->string
)
2720 || (it
->stop_charpos
>= BEGV
2721 && it
->stop_charpos
>= IT_CHARPOS (*it
)));
2725 /* Return the position of the next overlay change after POS in
2726 current_buffer. Value is point-max if no overlay change
2727 follows. This is like `next-overlay-change' but doesn't use
2731 next_overlay_change (pos
)
2736 Lisp_Object
*overlays
;
2739 /* Get all overlays at the given position. */
2740 GET_OVERLAYS_AT (pos
, overlays
, noverlays
, &endpos
, 1);
2742 /* If any of these overlays ends before endpos,
2743 use its ending point instead. */
2744 for (i
= 0; i
< noverlays
; ++i
)
2749 oend
= OVERLAY_END (overlays
[i
]);
2750 oendpos
= OVERLAY_POSITION (oend
);
2751 endpos
= min (endpos
, oendpos
);
2759 /***********************************************************************
2761 ***********************************************************************/
2763 /* Handle changes in the `fontified' property of the current buffer by
2764 calling hook functions from Qfontification_functions to fontify
2767 static enum prop_handled
2768 handle_fontified_prop (it
)
2771 Lisp_Object prop
, pos
;
2772 enum prop_handled handled
= HANDLED_NORMALLY
;
2774 /* Get the value of the `fontified' property at IT's current buffer
2775 position. (The `fontified' property doesn't have a special
2776 meaning in strings.) If the value is nil, call functions from
2777 Qfontification_functions. */
2778 if (!STRINGP (it
->string
)
2780 && !NILP (Vfontification_functions
)
2781 && !NILP (Vrun_hooks
)
2782 && (pos
= make_number (IT_CHARPOS (*it
)),
2783 prop
= Fget_char_property (pos
, Qfontified
, Qnil
),
2786 int count
= SPECPDL_INDEX ();
2789 val
= Vfontification_functions
;
2790 specbind (Qfontification_functions
, Qnil
);
2792 if (!CONSP (val
) || EQ (XCAR (val
), Qlambda
))
2793 safe_call1 (val
, pos
);
2796 Lisp_Object globals
, fn
;
2797 struct gcpro gcpro1
, gcpro2
;
2800 GCPRO2 (val
, globals
);
2802 for (; CONSP (val
); val
= XCDR (val
))
2808 /* A value of t indicates this hook has a local
2809 binding; it means to run the global binding too.
2810 In a global value, t should not occur. If it
2811 does, we must ignore it to avoid an endless
2813 for (globals
= Fdefault_value (Qfontification_functions
);
2815 globals
= XCDR (globals
))
2817 fn
= XCAR (globals
);
2819 safe_call1 (fn
, pos
);
2823 safe_call1 (fn
, pos
);
2829 unbind_to (count
, Qnil
);
2831 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
2832 something. This avoids an endless loop if they failed to
2833 fontify the text for which reason ever. */
2834 if (!NILP (Fget_char_property (pos
, Qfontified
, Qnil
)))
2835 handled
= HANDLED_RECOMPUTE_PROPS
;
2843 /***********************************************************************
2845 ***********************************************************************/
2847 /* Set up iterator IT from face properties at its current position.
2848 Called from handle_stop. */
2850 static enum prop_handled
2851 handle_face_prop (it
)
2854 int new_face_id
, next_stop
;
2856 if (!STRINGP (it
->string
))
2859 = face_at_buffer_position (it
->w
,
2861 it
->region_beg_charpos
,
2862 it
->region_end_charpos
,
2865 + TEXT_PROP_DISTANCE_LIMIT
),
2868 /* Is this a start of a run of characters with box face?
2869 Caveat: this can be called for a freshly initialized
2870 iterator; face_id is -1 in this case. We know that the new
2871 face will not change until limit, i.e. if the new face has a
2872 box, all characters up to limit will have one. But, as
2873 usual, we don't know whether limit is really the end. */
2874 if (new_face_id
!= it
->face_id
)
2876 struct face
*new_face
= FACE_FROM_ID (it
->f
, new_face_id
);
2878 /* If new face has a box but old face has not, this is
2879 the start of a run of characters with box, i.e. it has
2880 a shadow on the left side. The value of face_id of the
2881 iterator will be -1 if this is the initial call that gets
2882 the face. In this case, we have to look in front of IT's
2883 position and see whether there is a face != new_face_id. */
2884 it
->start_of_box_run_p
2885 = (new_face
->box
!= FACE_NO_BOX
2886 && (it
->face_id
>= 0
2887 || IT_CHARPOS (*it
) == BEG
2888 || new_face_id
!= face_before_it_pos (it
)));
2889 it
->face_box_p
= new_face
->box
!= FACE_NO_BOX
;
2894 int base_face_id
, bufpos
;
2896 if (it
->current
.overlay_string_index
>= 0)
2897 bufpos
= IT_CHARPOS (*it
);
2901 /* For strings from a buffer, i.e. overlay strings or strings
2902 from a `display' property, use the face at IT's current
2903 buffer position as the base face to merge with, so that
2904 overlay strings appear in the same face as surrounding
2905 text, unless they specify their own faces. */
2906 base_face_id
= underlying_face_id (it
);
2908 new_face_id
= face_at_string_position (it
->w
,
2910 IT_STRING_CHARPOS (*it
),
2912 it
->region_beg_charpos
,
2913 it
->region_end_charpos
,
2917 #if 0 /* This shouldn't be neccessary. Let's check it. */
2918 /* If IT is used to display a mode line we would really like to
2919 use the mode line face instead of the frame's default face. */
2920 if (it
->glyph_row
== MATRIX_MODE_LINE_ROW (it
->w
->desired_matrix
)
2921 && new_face_id
== DEFAULT_FACE_ID
)
2922 new_face_id
= CURRENT_MODE_LINE_FACE_ID (it
->w
);
2925 /* Is this a start of a run of characters with box? Caveat:
2926 this can be called for a freshly allocated iterator; face_id
2927 is -1 is this case. We know that the new face will not
2928 change until the next check pos, i.e. if the new face has a
2929 box, all characters up to that position will have a
2930 box. But, as usual, we don't know whether that position
2931 is really the end. */
2932 if (new_face_id
!= it
->face_id
)
2934 struct face
*new_face
= FACE_FROM_ID (it
->f
, new_face_id
);
2935 struct face
*old_face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2937 /* If new face has a box but old face hasn't, this is the
2938 start of a run of characters with box, i.e. it has a
2939 shadow on the left side. */
2940 it
->start_of_box_run_p
2941 = new_face
->box
&& (old_face
== NULL
|| !old_face
->box
);
2942 it
->face_box_p
= new_face
->box
!= FACE_NO_BOX
;
2946 it
->face_id
= new_face_id
;
2947 return HANDLED_NORMALLY
;
2951 /* Return the ID of the face ``underlying'' IT's current position,
2952 which is in a string. If the iterator is associated with a
2953 buffer, return the face at IT's current buffer position.
2954 Otherwise, use the iterator's base_face_id. */
2957 underlying_face_id (it
)
2960 int face_id
= it
->base_face_id
, i
;
2962 xassert (STRINGP (it
->string
));
2964 for (i
= it
->sp
- 1; i
>= 0; --i
)
2965 if (NILP (it
->stack
[i
].string
))
2966 face_id
= it
->stack
[i
].face_id
;
2972 /* Compute the face one character before or after the current position
2973 of IT. BEFORE_P non-zero means get the face in front of IT's
2974 position. Value is the id of the face. */
2977 face_before_or_after_it_pos (it
, before_p
)
2982 int next_check_charpos
;
2983 struct text_pos pos
;
2985 xassert (it
->s
== NULL
);
2987 if (STRINGP (it
->string
))
2989 int bufpos
, base_face_id
;
2991 /* No face change past the end of the string (for the case
2992 we are padding with spaces). No face change before the
2994 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
)
2995 || (IT_STRING_CHARPOS (*it
) == 0 && before_p
))
2998 /* Set pos to the position before or after IT's current position. */
3000 pos
= string_pos (IT_STRING_CHARPOS (*it
) - 1, it
->string
);
3002 /* For composition, we must check the character after the
3004 pos
= (it
->what
== IT_COMPOSITION
3005 ? string_pos (IT_STRING_CHARPOS (*it
) + it
->cmp_len
, it
->string
)
3006 : string_pos (IT_STRING_CHARPOS (*it
) + 1, it
->string
));
3008 if (it
->current
.overlay_string_index
>= 0)
3009 bufpos
= IT_CHARPOS (*it
);
3013 base_face_id
= underlying_face_id (it
);
3015 /* Get the face for ASCII, or unibyte. */
3016 face_id
= face_at_string_position (it
->w
,
3020 it
->region_beg_charpos
,
3021 it
->region_end_charpos
,
3022 &next_check_charpos
,
3025 /* Correct the face for charsets different from ASCII. Do it
3026 for the multibyte case only. The face returned above is
3027 suitable for unibyte text if IT->string is unibyte. */
3028 if (STRING_MULTIBYTE (it
->string
))
3030 const unsigned char *p
= SDATA (it
->string
) + BYTEPOS (pos
);
3031 int rest
= SBYTES (it
->string
) - BYTEPOS (pos
);
3033 struct face
*face
= FACE_FROM_ID (it
->f
, face_id
);
3035 c
= string_char_and_length (p
, rest
, &len
);
3036 face_id
= FACE_FOR_CHAR (it
->f
, face
, c
);
3041 if ((IT_CHARPOS (*it
) >= ZV
&& !before_p
)
3042 || (IT_CHARPOS (*it
) <= BEGV
&& before_p
))
3045 limit
= IT_CHARPOS (*it
) + TEXT_PROP_DISTANCE_LIMIT
;
3046 pos
= it
->current
.pos
;
3049 DEC_TEXT_POS (pos
, it
->multibyte_p
);
3052 if (it
->what
== IT_COMPOSITION
)
3053 /* For composition, we must check the position after the
3055 pos
.charpos
+= it
->cmp_len
, pos
.bytepos
+= it
->len
;
3057 INC_TEXT_POS (pos
, it
->multibyte_p
);
3060 /* Determine face for CHARSET_ASCII, or unibyte. */
3061 face_id
= face_at_buffer_position (it
->w
,
3063 it
->region_beg_charpos
,
3064 it
->region_end_charpos
,
3065 &next_check_charpos
,
3068 /* Correct the face for charsets different from ASCII. Do it
3069 for the multibyte case only. The face returned above is
3070 suitable for unibyte text if current_buffer is unibyte. */
3071 if (it
->multibyte_p
)
3073 int c
= FETCH_MULTIBYTE_CHAR (BYTEPOS (pos
));
3074 struct face
*face
= FACE_FROM_ID (it
->f
, face_id
);
3075 face_id
= FACE_FOR_CHAR (it
->f
, face
, c
);
3084 /***********************************************************************
3086 ***********************************************************************/
3088 /* Set up iterator IT from invisible properties at its current
3089 position. Called from handle_stop. */
3091 static enum prop_handled
3092 handle_invisible_prop (it
)
3095 enum prop_handled handled
= HANDLED_NORMALLY
;
3097 if (STRINGP (it
->string
))
3099 extern Lisp_Object Qinvisible
;
3100 Lisp_Object prop
, end_charpos
, limit
, charpos
;
3102 /* Get the value of the invisible text property at the
3103 current position. Value will be nil if there is no such
3105 charpos
= make_number (IT_STRING_CHARPOS (*it
));
3106 prop
= Fget_text_property (charpos
, Qinvisible
, it
->string
);
3109 && IT_STRING_CHARPOS (*it
) < it
->end_charpos
)
3111 handled
= HANDLED_RECOMPUTE_PROPS
;
3113 /* Get the position at which the next change of the
3114 invisible text property can be found in IT->string.
3115 Value will be nil if the property value is the same for
3116 all the rest of IT->string. */
3117 XSETINT (limit
, SCHARS (it
->string
));
3118 end_charpos
= Fnext_single_property_change (charpos
, Qinvisible
,
3121 /* Text at current position is invisible. The next
3122 change in the property is at position end_charpos.
3123 Move IT's current position to that position. */
3124 if (INTEGERP (end_charpos
)
3125 && XFASTINT (end_charpos
) < XFASTINT (limit
))
3127 struct text_pos old
;
3128 old
= it
->current
.string_pos
;
3129 IT_STRING_CHARPOS (*it
) = XFASTINT (end_charpos
);
3130 compute_string_pos (&it
->current
.string_pos
, old
, it
->string
);
3134 /* The rest of the string is invisible. If this is an
3135 overlay string, proceed with the next overlay string
3136 or whatever comes and return a character from there. */
3137 if (it
->current
.overlay_string_index
>= 0)
3139 next_overlay_string (it
);
3140 /* Don't check for overlay strings when we just
3141 finished processing them. */
3142 handled
= HANDLED_OVERLAY_STRING_CONSUMED
;
3146 IT_STRING_CHARPOS (*it
) = SCHARS (it
->string
);
3147 IT_STRING_BYTEPOS (*it
) = SBYTES (it
->string
);
3154 int invis_p
, newpos
, next_stop
, start_charpos
;
3155 Lisp_Object pos
, prop
, overlay
;
3157 /* First of all, is there invisible text at this position? */
3158 start_charpos
= IT_CHARPOS (*it
);
3159 pos
= make_number (IT_CHARPOS (*it
));
3160 prop
= get_char_property_and_overlay (pos
, Qinvisible
, it
->window
,
3162 invis_p
= TEXT_PROP_MEANS_INVISIBLE (prop
);
3164 /* If we are on invisible text, skip over it. */
3165 if (invis_p
&& IT_CHARPOS (*it
) < it
->end_charpos
)
3167 /* Record whether we have to display an ellipsis for the
3169 int display_ellipsis_p
= invis_p
== 2;
3171 handled
= HANDLED_RECOMPUTE_PROPS
;
3173 /* Loop skipping over invisible text. The loop is left at
3174 ZV or with IT on the first char being visible again. */
3177 /* Try to skip some invisible text. Return value is the
3178 position reached which can be equal to IT's position
3179 if there is nothing invisible here. This skips both
3180 over invisible text properties and overlays with
3181 invisible property. */
3182 newpos
= skip_invisible (IT_CHARPOS (*it
),
3183 &next_stop
, ZV
, it
->window
);
3185 /* If we skipped nothing at all we weren't at invisible
3186 text in the first place. If everything to the end of
3187 the buffer was skipped, end the loop. */
3188 if (newpos
== IT_CHARPOS (*it
) || newpos
>= ZV
)
3192 /* We skipped some characters but not necessarily
3193 all there are. Check if we ended up on visible
3194 text. Fget_char_property returns the property of
3195 the char before the given position, i.e. if we
3196 get invis_p = 0, this means that the char at
3197 newpos is visible. */
3198 pos
= make_number (newpos
);
3199 prop
= Fget_char_property (pos
, Qinvisible
, it
->window
);
3200 invis_p
= TEXT_PROP_MEANS_INVISIBLE (prop
);
3203 /* If we ended up on invisible text, proceed to
3204 skip starting with next_stop. */
3206 IT_CHARPOS (*it
) = next_stop
;
3210 /* The position newpos is now either ZV or on visible text. */
3211 IT_CHARPOS (*it
) = newpos
;
3212 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (newpos
);
3214 /* If there are before-strings at the start of invisible
3215 text, and the text is invisible because of a text
3216 property, arrange to show before-strings because 20.x did
3217 it that way. (If the text is invisible because of an
3218 overlay property instead of a text property, this is
3219 already handled in the overlay code.) */
3221 && get_overlay_strings (it
, start_charpos
))
3223 handled
= HANDLED_RECOMPUTE_PROPS
;
3224 it
->stack
[it
->sp
- 1].display_ellipsis_p
= display_ellipsis_p
;
3226 else if (display_ellipsis_p
)
3227 setup_for_ellipsis (it
);
3235 /* Make iterator IT return `...' next. */
3238 setup_for_ellipsis (it
)
3242 && VECTORP (DISP_INVIS_VECTOR (it
->dp
)))
3244 struct Lisp_Vector
*v
= XVECTOR (DISP_INVIS_VECTOR (it
->dp
));
3245 it
->dpvec
= v
->contents
;
3246 it
->dpend
= v
->contents
+ v
->size
;
3250 /* Default `...'. */
3251 it
->dpvec
= default_invis_vector
;
3252 it
->dpend
= default_invis_vector
+ 3;
3255 /* The ellipsis display does not replace the display of the
3256 character at the new position. Indicate this by setting
3257 IT->dpvec_char_len to zero. */
3258 it
->dpvec_char_len
= 0;
3260 it
->current
.dpvec_index
= 0;
3261 it
->method
= next_element_from_display_vector
;
3266 /***********************************************************************
3268 ***********************************************************************/
3270 /* Set up iterator IT from `display' property at its current position.
3271 Called from handle_stop. */
3273 static enum prop_handled
3274 handle_display_prop (it
)
3277 Lisp_Object prop
, object
;
3278 struct text_pos
*position
;
3279 int display_replaced_p
= 0;
3281 if (STRINGP (it
->string
))
3283 object
= it
->string
;
3284 position
= &it
->current
.string_pos
;
3288 object
= it
->w
->buffer
;
3289 position
= &it
->current
.pos
;
3292 /* Reset those iterator values set from display property values. */
3293 it
->slice
.x
= it
->slice
.y
= it
->slice
.width
= it
->slice
.height
= Qnil
;
3294 it
->space_width
= Qnil
;
3295 it
->font_height
= Qnil
;
3298 /* We don't support recursive `display' properties, i.e. string
3299 values that have a string `display' property, that have a string
3300 `display' property etc. */
3301 if (!it
->string_from_display_prop_p
)
3302 it
->area
= TEXT_AREA
;
3304 prop
= Fget_char_property (make_number (position
->charpos
),
3307 return HANDLED_NORMALLY
;
3310 /* Simple properties. */
3311 && !EQ (XCAR (prop
), Qimage
)
3312 && !EQ (XCAR (prop
), Qspace
)
3313 && !EQ (XCAR (prop
), Qwhen
)
3314 && !EQ (XCAR (prop
), Qslice
)
3315 && !EQ (XCAR (prop
), Qspace_width
)
3316 && !EQ (XCAR (prop
), Qheight
)
3317 && !EQ (XCAR (prop
), Qraise
)
3318 /* Marginal area specifications. */
3319 && !(CONSP (XCAR (prop
)) && EQ (XCAR (XCAR (prop
)), Qmargin
))
3320 && !EQ (XCAR (prop
), Qleft_fringe
)
3321 && !EQ (XCAR (prop
), Qright_fringe
)
3322 && !NILP (XCAR (prop
)))
3324 for (; CONSP (prop
); prop
= XCDR (prop
))
3326 if (handle_single_display_prop (it
, XCAR (prop
), object
,
3327 position
, display_replaced_p
))
3328 display_replaced_p
= 1;
3331 else if (VECTORP (prop
))
3334 for (i
= 0; i
< ASIZE (prop
); ++i
)
3335 if (handle_single_display_prop (it
, AREF (prop
, i
), object
,
3336 position
, display_replaced_p
))
3337 display_replaced_p
= 1;
3341 if (handle_single_display_prop (it
, prop
, object
, position
, 0))
3342 display_replaced_p
= 1;
3345 return display_replaced_p
? HANDLED_RETURN
: HANDLED_NORMALLY
;
3349 /* Value is the position of the end of the `display' property starting
3350 at START_POS in OBJECT. */
3352 static struct text_pos
3353 display_prop_end (it
, object
, start_pos
)
3356 struct text_pos start_pos
;
3359 struct text_pos end_pos
;
3361 end
= Fnext_single_char_property_change (make_number (CHARPOS (start_pos
)),
3362 Qdisplay
, object
, Qnil
);
3363 CHARPOS (end_pos
) = XFASTINT (end
);
3364 if (STRINGP (object
))
3365 compute_string_pos (&end_pos
, start_pos
, it
->string
);
3367 BYTEPOS (end_pos
) = CHAR_TO_BYTE (XFASTINT (end
));
3373 /* Set up IT from a single `display' sub-property value PROP. OBJECT
3374 is the object in which the `display' property was found. *POSITION
3375 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3376 means that we previously saw a display sub-property which already
3377 replaced text display with something else, for example an image;
3378 ignore such properties after the first one has been processed.
3380 If PROP is a `space' or `image' sub-property, set *POSITION to the
3381 end position of the `display' property.
3383 Value is non-zero if something was found which replaces the display
3384 of buffer or string text. */
3387 handle_single_display_prop (it
, prop
, object
, position
,
3388 display_replaced_before_p
)
3392 struct text_pos
*position
;
3393 int display_replaced_before_p
;
3396 int replaces_text_display_p
= 0;
3399 /* If PROP is a list of the form `(when FORM . VALUE)', FORM is
3400 evaluated. If the result is nil, VALUE is ignored. */
3402 if (CONSP (prop
) && EQ (XCAR (prop
), Qwhen
))
3411 if (!NILP (form
) && !EQ (form
, Qt
))
3413 int count
= SPECPDL_INDEX ();
3414 struct gcpro gcpro1
;
3416 /* Bind `object' to the object having the `display' property, a
3417 buffer or string. Bind `position' to the position in the
3418 object where the property was found, and `buffer-position'
3419 to the current position in the buffer. */
3420 specbind (Qobject
, object
);
3421 specbind (Qposition
, make_number (CHARPOS (*position
)));
3422 specbind (Qbuffer_position
,
3423 make_number (STRINGP (object
)
3424 ? IT_CHARPOS (*it
) : CHARPOS (*position
)));
3426 form
= safe_eval (form
);
3428 unbind_to (count
, Qnil
);
3435 && EQ (XCAR (prop
), Qheight
)
3436 && CONSP (XCDR (prop
)))
3438 if (FRAME_TERMCAP_P (it
->f
) || FRAME_MSDOS_P (it
->f
))
3441 /* `(height HEIGHT)'. */
3442 it
->font_height
= XCAR (XCDR (prop
));
3443 if (!NILP (it
->font_height
))
3445 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
3446 int new_height
= -1;
3448 if (CONSP (it
->font_height
)
3449 && (EQ (XCAR (it
->font_height
), Qplus
)
3450 || EQ (XCAR (it
->font_height
), Qminus
))
3451 && CONSP (XCDR (it
->font_height
))
3452 && INTEGERP (XCAR (XCDR (it
->font_height
))))
3454 /* `(+ N)' or `(- N)' where N is an integer. */
3455 int steps
= XINT (XCAR (XCDR (it
->font_height
)));
3456 if (EQ (XCAR (it
->font_height
), Qplus
))
3458 it
->face_id
= smaller_face (it
->f
, it
->face_id
, steps
);
3460 else if (FUNCTIONP (it
->font_height
))
3462 /* Call function with current height as argument.
3463 Value is the new height. */
3465 height
= safe_call1 (it
->font_height
,
3466 face
->lface
[LFACE_HEIGHT_INDEX
]);
3467 if (NUMBERP (height
))
3468 new_height
= XFLOATINT (height
);
3470 else if (NUMBERP (it
->font_height
))
3472 /* Value is a multiple of the canonical char height. */
3475 face
= FACE_FROM_ID (it
->f
, DEFAULT_FACE_ID
);
3476 new_height
= (XFLOATINT (it
->font_height
)
3477 * XINT (face
->lface
[LFACE_HEIGHT_INDEX
]));
3481 /* Evaluate IT->font_height with `height' bound to the
3482 current specified height to get the new height. */
3484 int count
= SPECPDL_INDEX ();
3486 specbind (Qheight
, face
->lface
[LFACE_HEIGHT_INDEX
]);
3487 value
= safe_eval (it
->font_height
);
3488 unbind_to (count
, Qnil
);
3490 if (NUMBERP (value
))
3491 new_height
= XFLOATINT (value
);
3495 it
->face_id
= face_with_height (it
->f
, it
->face_id
, new_height
);
3498 else if (CONSP (prop
)
3499 && EQ (XCAR (prop
), Qspace_width
)
3500 && CONSP (XCDR (prop
)))
3502 /* `(space_width WIDTH)'. */
3503 if (FRAME_TERMCAP_P (it
->f
) || FRAME_MSDOS_P (it
->f
))
3506 value
= XCAR (XCDR (prop
));
3507 if (NUMBERP (value
) && XFLOATINT (value
) > 0)
3508 it
->space_width
= value
;
3510 else if (CONSP (prop
)
3511 && EQ (XCAR (prop
), Qslice
))
3513 /* `(slice X Y WIDTH HEIGHT)'. */
3516 if (FRAME_TERMCAP_P (it
->f
) || FRAME_MSDOS_P (it
->f
))
3519 if (tem
= XCDR (prop
), CONSP (tem
))
3521 it
->slice
.x
= XCAR (tem
);
3522 if (tem
= XCDR (tem
), CONSP (tem
))
3524 it
->slice
.y
= XCAR (tem
);
3525 if (tem
= XCDR (tem
), CONSP (tem
))
3527 it
->slice
.width
= XCAR (tem
);
3528 if (tem
= XCDR (tem
), CONSP (tem
))
3529 it
->slice
.height
= XCAR (tem
);
3534 else if (CONSP (prop
)
3535 && EQ (XCAR (prop
), Qraise
)
3536 && CONSP (XCDR (prop
)))
3538 /* `(raise FACTOR)'. */
3539 if (FRAME_TERMCAP_P (it
->f
) || FRAME_MSDOS_P (it
->f
))
3542 #ifdef HAVE_WINDOW_SYSTEM
3543 value
= XCAR (XCDR (prop
));
3544 if (NUMBERP (value
))
3546 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
3547 it
->voffset
= - (XFLOATINT (value
)
3548 * (FONT_HEIGHT (face
->font
)));
3550 #endif /* HAVE_WINDOW_SYSTEM */
3552 else if (!it
->string_from_display_prop_p
)
3554 /* `((margin left-margin) VALUE)' or `((margin right-margin)
3555 VALUE) or `((margin nil) VALUE)' or VALUE. */
3556 Lisp_Object location
, value
;
3557 struct text_pos start_pos
;
3560 /* Characters having this form of property are not displayed, so
3561 we have to find the end of the property. */
3562 start_pos
= *position
;
3563 *position
= display_prop_end (it
, object
, start_pos
);
3566 /* Let's stop at the new position and assume that all
3567 text properties change there. */
3568 it
->stop_charpos
= position
->charpos
;
3571 && (EQ (XCAR (prop
), Qleft_fringe
)
3572 || EQ (XCAR (prop
), Qright_fringe
))
3573 && CONSP (XCDR (prop
)))
3575 unsigned face_id
= DEFAULT_FACE_ID
;
3577 /* Save current settings of IT so that we can restore them
3578 when we are finished with the glyph property value. */
3580 /* `(left-fringe BITMAP FACE)'. */
3581 if (FRAME_TERMCAP_P (it
->f
) || FRAME_MSDOS_P (it
->f
))
3584 #ifdef HAVE_WINDOW_SYSTEM
3585 value
= XCAR (XCDR (prop
));
3586 if (!NUMBERP (value
)
3587 || !valid_fringe_bitmap_id_p (XINT (value
)))
3590 if (CONSP (XCDR (XCDR (prop
))))
3592 Lisp_Object face_name
= XCAR (XCDR (XCDR (prop
)));
3594 face_id
= lookup_named_face (it
->f
, face_name
, 'A');
3601 it
->area
= TEXT_AREA
;
3602 it
->what
= IT_IMAGE
;
3603 it
->image_id
= -1; /* no image */
3604 it
->position
= start_pos
;
3605 it
->object
= NILP (object
) ? it
->w
->buffer
: object
;
3606 it
->method
= next_element_from_image
;
3607 it
->face_id
= face_id
;
3609 /* Say that we haven't consumed the characters with
3610 `display' property yet. The call to pop_it in
3611 set_iterator_to_next will clean this up. */
3612 *position
= start_pos
;
3614 if (EQ (XCAR (prop
), Qleft_fringe
))
3616 it
->left_user_fringe_bitmap
= XINT (value
);
3617 it
->left_user_fringe_face_id
= face_id
;
3621 it
->right_user_fringe_bitmap
= XINT (value
);
3622 it
->right_user_fringe_face_id
= face_id
;
3624 #endif /* HAVE_WINDOW_SYSTEM */
3628 location
= Qunbound
;
3629 if (CONSP (prop
) && CONSP (XCAR (prop
)))
3633 value
= XCDR (prop
);
3635 value
= XCAR (value
);
3638 if (EQ (XCAR (tem
), Qmargin
)
3639 && (tem
= XCDR (tem
),
3640 tem
= CONSP (tem
) ? XCAR (tem
) : Qnil
,
3642 || EQ (tem
, Qleft_margin
)
3643 || EQ (tem
, Qright_margin
))))
3647 if (EQ (location
, Qunbound
))
3653 valid_p
= (STRINGP (value
)
3654 #ifdef HAVE_WINDOW_SYSTEM
3655 || (!FRAME_TERMCAP_P (it
->f
) && valid_image_p (value
))
3656 #endif /* not HAVE_WINDOW_SYSTEM */
3657 || (CONSP (value
) && EQ (XCAR (value
), Qspace
)));
3659 if ((EQ (location
, Qleft_margin
)
3660 || EQ (location
, Qright_margin
)
3663 && !display_replaced_before_p
)
3665 replaces_text_display_p
= 1;
3667 /* Save current settings of IT so that we can restore them
3668 when we are finished with the glyph property value. */
3671 if (NILP (location
))
3672 it
->area
= TEXT_AREA
;
3673 else if (EQ (location
, Qleft_margin
))
3674 it
->area
= LEFT_MARGIN_AREA
;
3676 it
->area
= RIGHT_MARGIN_AREA
;
3678 if (STRINGP (value
))
3681 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
3682 it
->current
.overlay_string_index
= -1;
3683 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = 0;
3684 it
->end_charpos
= it
->string_nchars
= SCHARS (it
->string
);
3685 it
->method
= next_element_from_string
;
3686 it
->stop_charpos
= 0;
3687 it
->string_from_display_prop_p
= 1;
3688 /* Say that we haven't consumed the characters with
3689 `display' property yet. The call to pop_it in
3690 set_iterator_to_next will clean this up. */
3691 *position
= start_pos
;
3693 else if (CONSP (value
) && EQ (XCAR (value
), Qspace
))
3695 it
->method
= next_element_from_stretch
;
3697 it
->current
.pos
= it
->position
= start_pos
;
3699 #ifdef HAVE_WINDOW_SYSTEM
3702 it
->what
= IT_IMAGE
;
3703 it
->image_id
= lookup_image (it
->f
, value
);
3704 it
->position
= start_pos
;
3705 it
->object
= NILP (object
) ? it
->w
->buffer
: object
;
3706 it
->method
= next_element_from_image
;
3708 /* Say that we haven't consumed the characters with
3709 `display' property yet. The call to pop_it in
3710 set_iterator_to_next will clean this up. */
3711 *position
= start_pos
;
3713 #endif /* HAVE_WINDOW_SYSTEM */
3716 /* Invalid property or property not supported. Restore
3717 the position to what it was before. */
3718 *position
= start_pos
;
3721 return replaces_text_display_p
;
3725 /* Check if PROP is a display sub-property value whose text should be
3726 treated as intangible. */
3729 single_display_prop_intangible_p (prop
)
3732 /* Skip over `when FORM'. */
3733 if (CONSP (prop
) && EQ (XCAR (prop
), Qwhen
))
3747 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
3748 we don't need to treat text as intangible. */
3749 if (EQ (XCAR (prop
), Qmargin
))
3757 || EQ (XCAR (prop
), Qleft_margin
)
3758 || EQ (XCAR (prop
), Qright_margin
))
3762 return (CONSP (prop
)
3763 && (EQ (XCAR (prop
), Qimage
)
3764 || EQ (XCAR (prop
), Qspace
)));
3768 /* Check if PROP is a display property value whose text should be
3769 treated as intangible. */
3772 display_prop_intangible_p (prop
)
3776 && CONSP (XCAR (prop
))
3777 && !EQ (Qmargin
, XCAR (XCAR (prop
))))
3779 /* A list of sub-properties. */
3780 while (CONSP (prop
))
3782 if (single_display_prop_intangible_p (XCAR (prop
)))
3787 else if (VECTORP (prop
))
3789 /* A vector of sub-properties. */
3791 for (i
= 0; i
< ASIZE (prop
); ++i
)
3792 if (single_display_prop_intangible_p (AREF (prop
, i
)))
3796 return single_display_prop_intangible_p (prop
);
3802 /* Return 1 if PROP is a display sub-property value containing STRING. */
3805 single_display_prop_string_p (prop
, string
)
3806 Lisp_Object prop
, string
;
3808 if (EQ (string
, prop
))
3811 /* Skip over `when FORM'. */
3812 if (CONSP (prop
) && EQ (XCAR (prop
), Qwhen
))
3821 /* Skip over `margin LOCATION'. */
3822 if (EQ (XCAR (prop
), Qmargin
))
3833 return CONSP (prop
) && EQ (XCAR (prop
), string
);
3837 /* Return 1 if STRING appears in the `display' property PROP. */
3840 display_prop_string_p (prop
, string
)
3841 Lisp_Object prop
, string
;
3844 && CONSP (XCAR (prop
))
3845 && !EQ (Qmargin
, XCAR (XCAR (prop
))))
3847 /* A list of sub-properties. */
3848 while (CONSP (prop
))
3850 if (single_display_prop_string_p (XCAR (prop
), string
))
3855 else if (VECTORP (prop
))
3857 /* A vector of sub-properties. */
3859 for (i
= 0; i
< ASIZE (prop
); ++i
)
3860 if (single_display_prop_string_p (AREF (prop
, i
), string
))
3864 return single_display_prop_string_p (prop
, string
);
3870 /* Determine from which buffer position in W's buffer STRING comes
3871 from. AROUND_CHARPOS is an approximate position where it could
3872 be from. Value is the buffer position or 0 if it couldn't be
3875 W's buffer must be current.
3877 This function is necessary because we don't record buffer positions
3878 in glyphs generated from strings (to keep struct glyph small).
3879 This function may only use code that doesn't eval because it is
3880 called asynchronously from note_mouse_highlight. */
3883 string_buffer_position (w
, string
, around_charpos
)
3888 Lisp_Object limit
, prop
, pos
;
3889 const int MAX_DISTANCE
= 1000;
3892 pos
= make_number (around_charpos
);
3893 limit
= make_number (min (XINT (pos
) + MAX_DISTANCE
, ZV
));
3894 while (!found
&& !EQ (pos
, limit
))
3896 prop
= Fget_char_property (pos
, Qdisplay
, Qnil
);
3897 if (!NILP (prop
) && display_prop_string_p (prop
, string
))
3900 pos
= Fnext_single_char_property_change (pos
, Qdisplay
, Qnil
, limit
);
3905 pos
= make_number (around_charpos
);
3906 limit
= make_number (max (XINT (pos
) - MAX_DISTANCE
, BEGV
));
3907 while (!found
&& !EQ (pos
, limit
))
3909 prop
= Fget_char_property (pos
, Qdisplay
, Qnil
);
3910 if (!NILP (prop
) && display_prop_string_p (prop
, string
))
3913 pos
= Fprevious_single_char_property_change (pos
, Qdisplay
, Qnil
,
3918 return found
? XINT (pos
) : 0;
3923 /***********************************************************************
3924 `composition' property
3925 ***********************************************************************/
3927 /* Set up iterator IT from `composition' property at its current
3928 position. Called from handle_stop. */
3930 static enum prop_handled
3931 handle_composition_prop (it
)
3934 Lisp_Object prop
, string
;
3935 int pos
, pos_byte
, end
;
3936 enum prop_handled handled
= HANDLED_NORMALLY
;
3938 if (STRINGP (it
->string
))
3940 pos
= IT_STRING_CHARPOS (*it
);
3941 pos_byte
= IT_STRING_BYTEPOS (*it
);
3942 string
= it
->string
;
3946 pos
= IT_CHARPOS (*it
);
3947 pos_byte
= IT_BYTEPOS (*it
);
3951 /* If there's a valid composition and point is not inside of the
3952 composition (in the case that the composition is from the current
3953 buffer), draw a glyph composed from the composition components. */
3954 if (find_composition (pos
, -1, &pos
, &end
, &prop
, string
)
3955 && COMPOSITION_VALID_P (pos
, end
, prop
)
3956 && (STRINGP (it
->string
) || (PT
<= pos
|| PT
>= end
)))
3958 int id
= get_composition_id (pos
, pos_byte
, end
- pos
, prop
, string
);
3962 it
->method
= next_element_from_composition
;
3964 it
->cmp_len
= COMPOSITION_LENGTH (prop
);
3965 /* For a terminal, draw only the first character of the
3967 it
->c
= COMPOSITION_GLYPH (composition_table
[id
], 0);
3968 it
->len
= (STRINGP (it
->string
)
3969 ? string_char_to_byte (it
->string
, end
)
3970 : CHAR_TO_BYTE (end
)) - pos_byte
;
3971 it
->stop_charpos
= end
;
3972 handled
= HANDLED_RETURN
;
3981 /***********************************************************************
3983 ***********************************************************************/
3985 /* The following structure is used to record overlay strings for
3986 later sorting in load_overlay_strings. */
3988 struct overlay_entry
3990 Lisp_Object overlay
;
3997 /* Set up iterator IT from overlay strings at its current position.
3998 Called from handle_stop. */
4000 static enum prop_handled
4001 handle_overlay_change (it
)
4004 if (!STRINGP (it
->string
) && get_overlay_strings (it
, 0))
4005 return HANDLED_RECOMPUTE_PROPS
;
4007 return HANDLED_NORMALLY
;
4011 /* Set up the next overlay string for delivery by IT, if there is an
4012 overlay string to deliver. Called by set_iterator_to_next when the
4013 end of the current overlay string is reached. If there are more
4014 overlay strings to display, IT->string and
4015 IT->current.overlay_string_index are set appropriately here.
4016 Otherwise IT->string is set to nil. */
4019 next_overlay_string (it
)
4022 ++it
->current
.overlay_string_index
;
4023 if (it
->current
.overlay_string_index
== it
->n_overlay_strings
)
4025 /* No more overlay strings. Restore IT's settings to what
4026 they were before overlay strings were processed, and
4027 continue to deliver from current_buffer. */
4028 int display_ellipsis_p
= it
->stack
[it
->sp
- 1].display_ellipsis_p
;
4031 xassert (it
->stop_charpos
>= BEGV
4032 && it
->stop_charpos
<= it
->end_charpos
);
4034 it
->current
.overlay_string_index
= -1;
4035 SET_TEXT_POS (it
->current
.string_pos
, -1, -1);
4036 it
->n_overlay_strings
= 0;
4037 it
->method
= next_element_from_buffer
;
4039 /* If we're at the end of the buffer, record that we have
4040 processed the overlay strings there already, so that
4041 next_element_from_buffer doesn't try it again. */
4042 if (IT_CHARPOS (*it
) >= it
->end_charpos
)
4043 it
->overlay_strings_at_end_processed_p
= 1;
4045 /* If we have to display `...' for invisible text, set
4046 the iterator up for that. */
4047 if (display_ellipsis_p
)
4048 setup_for_ellipsis (it
);
4052 /* There are more overlay strings to process. If
4053 IT->current.overlay_string_index has advanced to a position
4054 where we must load IT->overlay_strings with more strings, do
4056 int i
= it
->current
.overlay_string_index
% OVERLAY_STRING_CHUNK_SIZE
;
4058 if (it
->current
.overlay_string_index
&& i
== 0)
4059 load_overlay_strings (it
, 0);
4061 /* Initialize IT to deliver display elements from the overlay
4063 it
->string
= it
->overlay_strings
[i
];
4064 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
4065 SET_TEXT_POS (it
->current
.string_pos
, 0, 0);
4066 it
->method
= next_element_from_string
;
4067 it
->stop_charpos
= 0;
4074 /* Compare two overlay_entry structures E1 and E2. Used as a
4075 comparison function for qsort in load_overlay_strings. Overlay
4076 strings for the same position are sorted so that
4078 1. All after-strings come in front of before-strings, except
4079 when they come from the same overlay.
4081 2. Within after-strings, strings are sorted so that overlay strings
4082 from overlays with higher priorities come first.
4084 2. Within before-strings, strings are sorted so that overlay
4085 strings from overlays with higher priorities come last.
4087 Value is analogous to strcmp. */
4091 compare_overlay_entries (e1
, e2
)
4094 struct overlay_entry
*entry1
= (struct overlay_entry
*) e1
;
4095 struct overlay_entry
*entry2
= (struct overlay_entry
*) e2
;
4098 if (entry1
->after_string_p
!= entry2
->after_string_p
)
4100 /* Let after-strings appear in front of before-strings if
4101 they come from different overlays. */
4102 if (EQ (entry1
->overlay
, entry2
->overlay
))
4103 result
= entry1
->after_string_p
? 1 : -1;
4105 result
= entry1
->after_string_p
? -1 : 1;
4107 else if (entry1
->after_string_p
)
4108 /* After-strings sorted in order of decreasing priority. */
4109 result
= entry2
->priority
- entry1
->priority
;
4111 /* Before-strings sorted in order of increasing priority. */
4112 result
= entry1
->priority
- entry2
->priority
;
4118 /* Load the vector IT->overlay_strings with overlay strings from IT's
4119 current buffer position, or from CHARPOS if that is > 0. Set
4120 IT->n_overlays to the total number of overlay strings found.
4122 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4123 a time. On entry into load_overlay_strings,
4124 IT->current.overlay_string_index gives the number of overlay
4125 strings that have already been loaded by previous calls to this
4128 IT->add_overlay_start contains an additional overlay start
4129 position to consider for taking overlay strings from, if non-zero.
4130 This position comes into play when the overlay has an `invisible'
4131 property, and both before and after-strings. When we've skipped to
4132 the end of the overlay, because of its `invisible' property, we
4133 nevertheless want its before-string to appear.
4134 IT->add_overlay_start will contain the overlay start position
4137 Overlay strings are sorted so that after-string strings come in
4138 front of before-string strings. Within before and after-strings,
4139 strings are sorted by overlay priority. See also function
4140 compare_overlay_entries. */
4143 load_overlay_strings (it
, charpos
)
4147 extern Lisp_Object Qafter_string
, Qbefore_string
, Qwindow
, Qpriority
;
4148 Lisp_Object overlay
, window
, str
, invisible
;
4149 struct Lisp_Overlay
*ov
;
4152 int n
= 0, i
, j
, invis_p
;
4153 struct overlay_entry
*entries
4154 = (struct overlay_entry
*) alloca (size
* sizeof *entries
);
4157 charpos
= IT_CHARPOS (*it
);
4159 /* Append the overlay string STRING of overlay OVERLAY to vector
4160 `entries' which has size `size' and currently contains `n'
4161 elements. AFTER_P non-zero means STRING is an after-string of
4163 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4166 Lisp_Object priority; \
4170 int new_size = 2 * size; \
4171 struct overlay_entry *old = entries; \
4173 (struct overlay_entry *) alloca (new_size \
4174 * sizeof *entries); \
4175 bcopy (old, entries, size * sizeof *entries); \
4179 entries[n].string = (STRING); \
4180 entries[n].overlay = (OVERLAY); \
4181 priority = Foverlay_get ((OVERLAY), Qpriority); \
4182 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4183 entries[n].after_string_p = (AFTER_P); \
4188 /* Process overlay before the overlay center. */
4189 for (ov
= current_buffer
->overlays_before
; ov
; ov
= ov
->next
)
4191 XSETMISC (overlay
, ov
);
4192 xassert (OVERLAYP (overlay
));
4193 start
= OVERLAY_POSITION (OVERLAY_START (overlay
));
4194 end
= OVERLAY_POSITION (OVERLAY_END (overlay
));
4199 /* Skip this overlay if it doesn't start or end at IT's current
4201 if (end
!= charpos
&& start
!= charpos
)
4204 /* Skip this overlay if it doesn't apply to IT->w. */
4205 window
= Foverlay_get (overlay
, Qwindow
);
4206 if (WINDOWP (window
) && XWINDOW (window
) != it
->w
)
4209 /* If the text ``under'' the overlay is invisible, both before-
4210 and after-strings from this overlay are visible; start and
4211 end position are indistinguishable. */
4212 invisible
= Foverlay_get (overlay
, Qinvisible
);
4213 invis_p
= TEXT_PROP_MEANS_INVISIBLE (invisible
);
4215 /* If overlay has a non-empty before-string, record it. */
4216 if ((start
== charpos
|| (end
== charpos
&& invis_p
))
4217 && (str
= Foverlay_get (overlay
, Qbefore_string
), STRINGP (str
))
4219 RECORD_OVERLAY_STRING (overlay
, str
, 0);
4221 /* If overlay has a non-empty after-string, record it. */
4222 if ((end
== charpos
|| (start
== charpos
&& invis_p
))
4223 && (str
= Foverlay_get (overlay
, Qafter_string
), STRINGP (str
))
4225 RECORD_OVERLAY_STRING (overlay
, str
, 1);
4228 /* Process overlays after the overlay center. */
4229 for (ov
= current_buffer
->overlays_after
; ov
; ov
= ov
->next
)
4231 XSETMISC (overlay
, ov
);
4232 xassert (OVERLAYP (overlay
));
4233 start
= OVERLAY_POSITION (OVERLAY_START (overlay
));
4234 end
= OVERLAY_POSITION (OVERLAY_END (overlay
));
4236 if (start
> charpos
)
4239 /* Skip this overlay if it doesn't start or end at IT's current
4241 if (end
!= charpos
&& start
!= charpos
)
4244 /* Skip this overlay if it doesn't apply to IT->w. */
4245 window
= Foverlay_get (overlay
, Qwindow
);
4246 if (WINDOWP (window
) && XWINDOW (window
) != it
->w
)
4249 /* If the text ``under'' the overlay is invisible, it has a zero
4250 dimension, and both before- and after-strings apply. */
4251 invisible
= Foverlay_get (overlay
, Qinvisible
);
4252 invis_p
= TEXT_PROP_MEANS_INVISIBLE (invisible
);
4254 /* If overlay has a non-empty before-string, record it. */
4255 if ((start
== charpos
|| (end
== charpos
&& invis_p
))
4256 && (str
= Foverlay_get (overlay
, Qbefore_string
), STRINGP (str
))
4258 RECORD_OVERLAY_STRING (overlay
, str
, 0);
4260 /* If overlay has a non-empty after-string, record it. */
4261 if ((end
== charpos
|| (start
== charpos
&& invis_p
))
4262 && (str
= Foverlay_get (overlay
, Qafter_string
), STRINGP (str
))
4264 RECORD_OVERLAY_STRING (overlay
, str
, 1);
4267 #undef RECORD_OVERLAY_STRING
4271 qsort (entries
, n
, sizeof *entries
, compare_overlay_entries
);
4273 /* Record the total number of strings to process. */
4274 it
->n_overlay_strings
= n
;
4276 /* IT->current.overlay_string_index is the number of overlay strings
4277 that have already been consumed by IT. Copy some of the
4278 remaining overlay strings to IT->overlay_strings. */
4280 j
= it
->current
.overlay_string_index
;
4281 while (i
< OVERLAY_STRING_CHUNK_SIZE
&& j
< n
)
4282 it
->overlay_strings
[i
++] = entries
[j
++].string
;
4288 /* Get the first chunk of overlay strings at IT's current buffer
4289 position, or at CHARPOS if that is > 0. Value is non-zero if at
4290 least one overlay string was found. */
4293 get_overlay_strings (it
, charpos
)
4297 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4298 process. This fills IT->overlay_strings with strings, and sets
4299 IT->n_overlay_strings to the total number of strings to process.
4300 IT->pos.overlay_string_index has to be set temporarily to zero
4301 because load_overlay_strings needs this; it must be set to -1
4302 when no overlay strings are found because a zero value would
4303 indicate a position in the first overlay string. */
4304 it
->current
.overlay_string_index
= 0;
4305 load_overlay_strings (it
, charpos
);
4307 /* If we found overlay strings, set up IT to deliver display
4308 elements from the first one. Otherwise set up IT to deliver
4309 from current_buffer. */
4310 if (it
->n_overlay_strings
)
4312 /* Make sure we know settings in current_buffer, so that we can
4313 restore meaningful values when we're done with the overlay
4315 compute_stop_pos (it
);
4316 xassert (it
->face_id
>= 0);
4318 /* Save IT's settings. They are restored after all overlay
4319 strings have been processed. */
4320 xassert (it
->sp
== 0);
4323 /* Set up IT to deliver display elements from the first overlay
4325 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = 0;
4326 it
->string
= it
->overlay_strings
[0];
4327 it
->stop_charpos
= 0;
4328 xassert (STRINGP (it
->string
));
4329 it
->end_charpos
= SCHARS (it
->string
);
4330 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
4331 it
->method
= next_element_from_string
;
4336 it
->current
.overlay_string_index
= -1;
4337 it
->method
= next_element_from_buffer
;
4342 /* Value is non-zero if we found at least one overlay string. */
4343 return STRINGP (it
->string
);
4348 /***********************************************************************
4349 Saving and restoring state
4350 ***********************************************************************/
4352 /* Save current settings of IT on IT->stack. Called, for example,
4353 before setting up IT for an overlay string, to be able to restore
4354 IT's settings to what they were after the overlay string has been
4361 struct iterator_stack_entry
*p
;
4363 xassert (it
->sp
< 2);
4364 p
= it
->stack
+ it
->sp
;
4366 p
->stop_charpos
= it
->stop_charpos
;
4367 xassert (it
->face_id
>= 0);
4368 p
->face_id
= it
->face_id
;
4369 p
->string
= it
->string
;
4370 p
->pos
= it
->current
;
4371 p
->end_charpos
= it
->end_charpos
;
4372 p
->string_nchars
= it
->string_nchars
;
4374 p
->multibyte_p
= it
->multibyte_p
;
4375 p
->slice
= it
->slice
;
4376 p
->space_width
= it
->space_width
;
4377 p
->font_height
= it
->font_height
;
4378 p
->voffset
= it
->voffset
;
4379 p
->string_from_display_prop_p
= it
->string_from_display_prop_p
;
4380 p
->display_ellipsis_p
= 0;
4385 /* Restore IT's settings from IT->stack. Called, for example, when no
4386 more overlay strings must be processed, and we return to delivering
4387 display elements from a buffer, or when the end of a string from a
4388 `display' property is reached and we return to delivering display
4389 elements from an overlay string, or from a buffer. */
4395 struct iterator_stack_entry
*p
;
4397 xassert (it
->sp
> 0);
4399 p
= it
->stack
+ it
->sp
;
4400 it
->stop_charpos
= p
->stop_charpos
;
4401 it
->face_id
= p
->face_id
;
4402 it
->string
= p
->string
;
4403 it
->current
= p
->pos
;
4404 it
->end_charpos
= p
->end_charpos
;
4405 it
->string_nchars
= p
->string_nchars
;
4407 it
->multibyte_p
= p
->multibyte_p
;
4408 it
->slice
= p
->slice
;
4409 it
->space_width
= p
->space_width
;
4410 it
->font_height
= p
->font_height
;
4411 it
->voffset
= p
->voffset
;
4412 it
->string_from_display_prop_p
= p
->string_from_display_prop_p
;
4417 /***********************************************************************
4419 ***********************************************************************/
4421 /* Set IT's current position to the previous line start. */
4424 back_to_previous_line_start (it
)
4427 IT_CHARPOS (*it
) = find_next_newline_no_quit (IT_CHARPOS (*it
) - 1, -1);
4428 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (IT_CHARPOS (*it
));
4432 /* Move IT to the next line start.
4434 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
4435 we skipped over part of the text (as opposed to moving the iterator
4436 continuously over the text). Otherwise, don't change the value
4439 Newlines may come from buffer text, overlay strings, or strings
4440 displayed via the `display' property. That's the reason we can't
4441 simply use find_next_newline_no_quit.
4443 Note that this function may not skip over invisible text that is so
4444 because of text properties and immediately follows a newline. If
4445 it would, function reseat_at_next_visible_line_start, when called
4446 from set_iterator_to_next, would effectively make invisible
4447 characters following a newline part of the wrong glyph row, which
4448 leads to wrong cursor motion. */
4451 forward_to_next_line_start (it
, skipped_p
)
4455 int old_selective
, newline_found_p
, n
;
4456 const int MAX_NEWLINE_DISTANCE
= 500;
4458 /* If already on a newline, just consume it to avoid unintended
4459 skipping over invisible text below. */
4460 if (it
->what
== IT_CHARACTER
4462 && CHARPOS (it
->position
) == IT_CHARPOS (*it
))
4464 set_iterator_to_next (it
, 0);
4469 /* Don't handle selective display in the following. It's (a)
4470 unnecessary because it's done by the caller, and (b) leads to an
4471 infinite recursion because next_element_from_ellipsis indirectly
4472 calls this function. */
4473 old_selective
= it
->selective
;
4476 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
4477 from buffer text. */
4478 for (n
= newline_found_p
= 0;
4479 !newline_found_p
&& n
< MAX_NEWLINE_DISTANCE
;
4480 n
+= STRINGP (it
->string
) ? 0 : 1)
4482 if (!get_next_display_element (it
))
4484 newline_found_p
= it
->what
== IT_CHARACTER
&& it
->c
== '\n';
4485 set_iterator_to_next (it
, 0);
4488 /* If we didn't find a newline near enough, see if we can use a
4490 if (!newline_found_p
)
4492 int start
= IT_CHARPOS (*it
);
4493 int limit
= find_next_newline_no_quit (start
, 1);
4496 xassert (!STRINGP (it
->string
));
4498 /* If there isn't any `display' property in sight, and no
4499 overlays, we can just use the position of the newline in
4501 if (it
->stop_charpos
>= limit
4502 || ((pos
= Fnext_single_property_change (make_number (start
),
4504 Qnil
, make_number (limit
)),
4506 && next_overlay_change (start
) == ZV
))
4508 IT_CHARPOS (*it
) = limit
;
4509 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (limit
);
4510 *skipped_p
= newline_found_p
= 1;
4514 while (get_next_display_element (it
)
4515 && !newline_found_p
)
4517 newline_found_p
= ITERATOR_AT_END_OF_LINE_P (it
);
4518 set_iterator_to_next (it
, 0);
4523 it
->selective
= old_selective
;
4524 return newline_found_p
;
4528 /* Set IT's current position to the previous visible line start. Skip
4529 invisible text that is so either due to text properties or due to
4530 selective display. Caution: this does not change IT->current_x and
4534 back_to_previous_visible_line_start (it
)
4539 /* Go back one newline if not on BEGV already. */
4540 if (IT_CHARPOS (*it
) > BEGV
)
4541 back_to_previous_line_start (it
);
4543 /* Move over lines that are invisible because of selective display
4544 or text properties. */
4545 while (IT_CHARPOS (*it
) > BEGV
4550 /* If selective > 0, then lines indented more than that values
4552 if (it
->selective
> 0
4553 && indented_beyond_p (IT_CHARPOS (*it
), IT_BYTEPOS (*it
),
4554 (double) it
->selective
)) /* iftc */
4560 prop
= Fget_char_property (make_number (IT_CHARPOS (*it
)),
4561 Qinvisible
, it
->window
);
4562 if (TEXT_PROP_MEANS_INVISIBLE (prop
))
4566 /* Back one more newline if the current one is invisible. */
4568 back_to_previous_line_start (it
);
4571 xassert (IT_CHARPOS (*it
) >= BEGV
);
4572 xassert (IT_CHARPOS (*it
) == BEGV
4573 || FETCH_BYTE (IT_BYTEPOS (*it
) - 1) == '\n');
4578 /* Reseat iterator IT at the previous visible line start. Skip
4579 invisible text that is so either due to text properties or due to
4580 selective display. At the end, update IT's overlay information,
4581 face information etc. */
4584 reseat_at_previous_visible_line_start (it
)
4587 back_to_previous_visible_line_start (it
);
4588 reseat (it
, it
->current
.pos
, 1);
4593 /* Reseat iterator IT on the next visible line start in the current
4594 buffer. ON_NEWLINE_P non-zero means position IT on the newline
4595 preceding the line start. Skip over invisible text that is so
4596 because of selective display. Compute faces, overlays etc at the
4597 new position. Note that this function does not skip over text that
4598 is invisible because of text properties. */
4601 reseat_at_next_visible_line_start (it
, on_newline_p
)
4605 int newline_found_p
, skipped_p
= 0;
4607 newline_found_p
= forward_to_next_line_start (it
, &skipped_p
);
4609 /* Skip over lines that are invisible because they are indented
4610 more than the value of IT->selective. */
4611 if (it
->selective
> 0)
4612 while (IT_CHARPOS (*it
) < ZV
4613 && indented_beyond_p (IT_CHARPOS (*it
), IT_BYTEPOS (*it
),
4614 (double) it
->selective
)) /* iftc */
4616 xassert (FETCH_BYTE (IT_BYTEPOS (*it
) - 1) == '\n');
4617 newline_found_p
= forward_to_next_line_start (it
, &skipped_p
);
4620 /* Position on the newline if that's what's requested. */
4621 if (on_newline_p
&& newline_found_p
)
4623 if (STRINGP (it
->string
))
4625 if (IT_STRING_CHARPOS (*it
) > 0)
4627 --IT_STRING_CHARPOS (*it
);
4628 --IT_STRING_BYTEPOS (*it
);
4631 else if (IT_CHARPOS (*it
) > BEGV
)
4635 reseat (it
, it
->current
.pos
, 0);
4639 reseat (it
, it
->current
.pos
, 0);
4646 /***********************************************************************
4647 Changing an iterator's position
4648 ***********************************************************************/
4650 /* Change IT's current position to POS in current_buffer. If FORCE_P
4651 is non-zero, always check for text properties at the new position.
4652 Otherwise, text properties are only looked up if POS >=
4653 IT->check_charpos of a property. */
4656 reseat (it
, pos
, force_p
)
4658 struct text_pos pos
;
4661 int original_pos
= IT_CHARPOS (*it
);
4663 reseat_1 (it
, pos
, 0);
4665 /* Determine where to check text properties. Avoid doing it
4666 where possible because text property lookup is very expensive. */
4668 || CHARPOS (pos
) > it
->stop_charpos
4669 || CHARPOS (pos
) < original_pos
)
4676 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
4677 IT->stop_pos to POS, also. */
4680 reseat_1 (it
, pos
, set_stop_p
)
4682 struct text_pos pos
;
4685 /* Don't call this function when scanning a C string. */
4686 xassert (it
->s
== NULL
);
4688 /* POS must be a reasonable value. */
4689 xassert (CHARPOS (pos
) >= BEGV
&& CHARPOS (pos
) <= ZV
);
4691 it
->current
.pos
= it
->position
= pos
;
4692 XSETBUFFER (it
->object
, current_buffer
);
4693 it
->end_charpos
= ZV
;
4695 it
->current
.dpvec_index
= -1;
4696 it
->current
.overlay_string_index
= -1;
4697 IT_STRING_CHARPOS (*it
) = -1;
4698 IT_STRING_BYTEPOS (*it
) = -1;
4700 it
->method
= next_element_from_buffer
;
4701 /* RMS: I added this to fix a bug in move_it_vertically_backward
4702 where it->area continued to relate to the starting point
4703 for the backward motion. Bug report from
4704 Nick Roberts <nick@nick.uklinux.net> on 19 May 2003.
4705 However, I am not sure whether reseat still does the right thing
4706 in general after this change. */
4707 it
->area
= TEXT_AREA
;
4708 it
->multibyte_p
= !NILP (current_buffer
->enable_multibyte_characters
);
4710 it
->face_before_selective_p
= 0;
4713 it
->stop_charpos
= CHARPOS (pos
);
4717 /* Set up IT for displaying a string, starting at CHARPOS in window W.
4718 If S is non-null, it is a C string to iterate over. Otherwise,
4719 STRING gives a Lisp string to iterate over.
4721 If PRECISION > 0, don't return more then PRECISION number of
4722 characters from the string.
4724 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
4725 characters have been returned. FIELD_WIDTH < 0 means an infinite
4728 MULTIBYTE = 0 means disable processing of multibyte characters,
4729 MULTIBYTE > 0 means enable it,
4730 MULTIBYTE < 0 means use IT->multibyte_p.
4732 IT must be initialized via a prior call to init_iterator before
4733 calling this function. */
4736 reseat_to_string (it
, s
, string
, charpos
, precision
, field_width
, multibyte
)
4741 int precision
, field_width
, multibyte
;
4743 /* No region in strings. */
4744 it
->region_beg_charpos
= it
->region_end_charpos
= -1;
4746 /* No text property checks performed by default, but see below. */
4747 it
->stop_charpos
= -1;
4749 /* Set iterator position and end position. */
4750 bzero (&it
->current
, sizeof it
->current
);
4751 it
->current
.overlay_string_index
= -1;
4752 it
->current
.dpvec_index
= -1;
4753 xassert (charpos
>= 0);
4755 /* If STRING is specified, use its multibyteness, otherwise use the
4756 setting of MULTIBYTE, if specified. */
4758 it
->multibyte_p
= multibyte
> 0;
4762 xassert (STRINGP (string
));
4763 it
->string
= string
;
4765 it
->end_charpos
= it
->string_nchars
= SCHARS (string
);
4766 it
->method
= next_element_from_string
;
4767 it
->current
.string_pos
= string_pos (charpos
, string
);
4774 /* Note that we use IT->current.pos, not it->current.string_pos,
4775 for displaying C strings. */
4776 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = -1;
4777 if (it
->multibyte_p
)
4779 it
->current
.pos
= c_string_pos (charpos
, s
, 1);
4780 it
->end_charpos
= it
->string_nchars
= number_of_chars (s
, 1);
4784 IT_CHARPOS (*it
) = IT_BYTEPOS (*it
) = charpos
;
4785 it
->end_charpos
= it
->string_nchars
= strlen (s
);
4788 it
->method
= next_element_from_c_string
;
4791 /* PRECISION > 0 means don't return more than PRECISION characters
4793 if (precision
> 0 && it
->end_charpos
- charpos
> precision
)
4794 it
->end_charpos
= it
->string_nchars
= charpos
+ precision
;
4796 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
4797 characters have been returned. FIELD_WIDTH == 0 means don't pad,
4798 FIELD_WIDTH < 0 means infinite field width. This is useful for
4799 padding with `-' at the end of a mode line. */
4800 if (field_width
< 0)
4801 field_width
= INFINITY
;
4802 if (field_width
> it
->end_charpos
- charpos
)
4803 it
->end_charpos
= charpos
+ field_width
;
4805 /* Use the standard display table for displaying strings. */
4806 if (DISP_TABLE_P (Vstandard_display_table
))
4807 it
->dp
= XCHAR_TABLE (Vstandard_display_table
);
4809 it
->stop_charpos
= charpos
;
4815 /***********************************************************************
4817 ***********************************************************************/
4819 /* Load IT's display element fields with information about the next
4820 display element from the current position of IT. Value is zero if
4821 end of buffer (or C string) is reached. */
4824 get_next_display_element (it
)
4827 /* Non-zero means that we found a display element. Zero means that
4828 we hit the end of what we iterate over. Performance note: the
4829 function pointer `method' used here turns out to be faster than
4830 using a sequence of if-statements. */
4831 int success_p
= (*it
->method
) (it
);
4833 if (it
->what
== IT_CHARACTER
)
4835 /* Map via display table or translate control characters.
4836 IT->c, IT->len etc. have been set to the next character by
4837 the function call above. If we have a display table, and it
4838 contains an entry for IT->c, translate it. Don't do this if
4839 IT->c itself comes from a display table, otherwise we could
4840 end up in an infinite recursion. (An alternative could be to
4841 count the recursion depth of this function and signal an
4842 error when a certain maximum depth is reached.) Is it worth
4844 if (success_p
&& it
->dpvec
== NULL
)
4849 && (dv
= DISP_CHAR_VECTOR (it
->dp
, it
->c
),
4852 struct Lisp_Vector
*v
= XVECTOR (dv
);
4854 /* Return the first character from the display table
4855 entry, if not empty. If empty, don't display the
4856 current character. */
4859 it
->dpvec_char_len
= it
->len
;
4860 it
->dpvec
= v
->contents
;
4861 it
->dpend
= v
->contents
+ v
->size
;
4862 it
->current
.dpvec_index
= 0;
4863 it
->method
= next_element_from_display_vector
;
4864 success_p
= get_next_display_element (it
);
4868 set_iterator_to_next (it
, 0);
4869 success_p
= get_next_display_element (it
);
4873 /* Translate control characters into `\003' or `^C' form.
4874 Control characters coming from a display table entry are
4875 currently not translated because we use IT->dpvec to hold
4876 the translation. This could easily be changed but I
4877 don't believe that it is worth doing.
4879 If it->multibyte_p is nonzero, eight-bit characters and
4880 non-printable multibyte characters are also translated to
4883 If it->multibyte_p is zero, eight-bit characters that
4884 don't have corresponding multibyte char code are also
4885 translated to octal form. */
4886 else if ((it
->c
< ' '
4887 && (it
->area
!= TEXT_AREA
4888 || (it
->c
!= '\n' && it
->c
!= '\t')))
4892 || !CHAR_PRINTABLE_P (it
->c
))
4894 && it
->c
== unibyte_char_to_multibyte (it
->c
))))
4896 /* IT->c is a control character which must be displayed
4897 either as '\003' or as `^C' where the '\\' and '^'
4898 can be defined in the display table. Fill
4899 IT->ctl_chars with glyphs for what we have to
4900 display. Then, set IT->dpvec to these glyphs. */
4903 if (it
->c
< 128 && it
->ctl_arrow_p
)
4905 /* Set IT->ctl_chars[0] to the glyph for `^'. */
4907 && INTEGERP (DISP_CTRL_GLYPH (it
->dp
))
4908 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it
->dp
))))
4909 g
= XINT (DISP_CTRL_GLYPH (it
->dp
));
4911 g
= FAST_MAKE_GLYPH ('^', 0);
4912 XSETINT (it
->ctl_chars
[0], g
);
4914 g
= FAST_MAKE_GLYPH (it
->c
^ 0100, 0);
4915 XSETINT (it
->ctl_chars
[1], g
);
4917 /* Set up IT->dpvec and return first character from it. */
4918 it
->dpvec_char_len
= it
->len
;
4919 it
->dpvec
= it
->ctl_chars
;
4920 it
->dpend
= it
->dpvec
+ 2;
4921 it
->current
.dpvec_index
= 0;
4922 it
->method
= next_element_from_display_vector
;
4923 get_next_display_element (it
);
4927 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
4932 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
4934 && INTEGERP (DISP_ESCAPE_GLYPH (it
->dp
))
4935 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it
->dp
))))
4936 escape_glyph
= XFASTINT (DISP_ESCAPE_GLYPH (it
->dp
));
4938 escape_glyph
= FAST_MAKE_GLYPH ('\\', 0);
4940 if (SINGLE_BYTE_CHAR_P (it
->c
))
4941 str
[0] = it
->c
, len
= 1;
4944 len
= CHAR_STRING_NO_SIGNAL (it
->c
, str
);
4947 /* It's an invalid character, which
4948 shouldn't happen actually, but due to
4949 bugs it may happen. Let's print the char
4950 as is, there's not much meaningful we can
4953 str
[1] = it
->c
>> 8;
4954 str
[2] = it
->c
>> 16;
4955 str
[3] = it
->c
>> 24;
4960 for (i
= 0; i
< len
; i
++)
4962 XSETINT (it
->ctl_chars
[i
* 4], escape_glyph
);
4963 /* Insert three more glyphs into IT->ctl_chars for
4964 the octal display of the character. */
4965 g
= FAST_MAKE_GLYPH (((str
[i
] >> 6) & 7) + '0', 0);
4966 XSETINT (it
->ctl_chars
[i
* 4 + 1], g
);
4967 g
= FAST_MAKE_GLYPH (((str
[i
] >> 3) & 7) + '0', 0);
4968 XSETINT (it
->ctl_chars
[i
* 4 + 2], g
);
4969 g
= FAST_MAKE_GLYPH ((str
[i
] & 7) + '0', 0);
4970 XSETINT (it
->ctl_chars
[i
* 4 + 3], g
);
4973 /* Set up IT->dpvec and return the first character
4975 it
->dpvec_char_len
= it
->len
;
4976 it
->dpvec
= it
->ctl_chars
;
4977 it
->dpend
= it
->dpvec
+ len
* 4;
4978 it
->current
.dpvec_index
= 0;
4979 it
->method
= next_element_from_display_vector
;
4980 get_next_display_element (it
);
4985 /* Adjust face id for a multibyte character. There are no
4986 multibyte character in unibyte text. */
4989 && FRAME_WINDOW_P (it
->f
))
4991 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
4992 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->c
);
4996 /* Is this character the last one of a run of characters with
4997 box? If yes, set IT->end_of_box_run_p to 1. */
5004 it
->end_of_box_run_p
5005 = ((face_id
= face_after_it_pos (it
),
5006 face_id
!= it
->face_id
)
5007 && (face
= FACE_FROM_ID (it
->f
, face_id
),
5008 face
->box
== FACE_NO_BOX
));
5011 /* Value is 0 if end of buffer or string reached. */
5016 /* Move IT to the next display element.
5018 RESEAT_P non-zero means if called on a newline in buffer text,
5019 skip to the next visible line start.
5021 Functions get_next_display_element and set_iterator_to_next are
5022 separate because I find this arrangement easier to handle than a
5023 get_next_display_element function that also increments IT's
5024 position. The way it is we can first look at an iterator's current
5025 display element, decide whether it fits on a line, and if it does,
5026 increment the iterator position. The other way around we probably
5027 would either need a flag indicating whether the iterator has to be
5028 incremented the next time, or we would have to implement a
5029 decrement position function which would not be easy to write. */
5032 set_iterator_to_next (it
, reseat_p
)
5036 /* Reset flags indicating start and end of a sequence of characters
5037 with box. Reset them at the start of this function because
5038 moving the iterator to a new position might set them. */
5039 it
->start_of_box_run_p
= it
->end_of_box_run_p
= 0;
5041 if (it
->method
== next_element_from_buffer
)
5043 /* The current display element of IT is a character from
5044 current_buffer. Advance in the buffer, and maybe skip over
5045 invisible lines that are so because of selective display. */
5046 if (ITERATOR_AT_END_OF_LINE_P (it
) && reseat_p
)
5047 reseat_at_next_visible_line_start (it
, 0);
5050 xassert (it
->len
!= 0);
5051 IT_BYTEPOS (*it
) += it
->len
;
5052 IT_CHARPOS (*it
) += 1;
5053 xassert (IT_BYTEPOS (*it
) == CHAR_TO_BYTE (IT_CHARPOS (*it
)));
5056 else if (it
->method
== next_element_from_composition
)
5058 xassert (it
->cmp_id
>= 0 && it
->cmp_id
< n_compositions
);
5059 if (STRINGP (it
->string
))
5061 IT_STRING_BYTEPOS (*it
) += it
->len
;
5062 IT_STRING_CHARPOS (*it
) += it
->cmp_len
;
5063 it
->method
= next_element_from_string
;
5064 goto consider_string_end
;
5068 IT_BYTEPOS (*it
) += it
->len
;
5069 IT_CHARPOS (*it
) += it
->cmp_len
;
5070 it
->method
= next_element_from_buffer
;
5073 else if (it
->method
== next_element_from_c_string
)
5075 /* Current display element of IT is from a C string. */
5076 IT_BYTEPOS (*it
) += it
->len
;
5077 IT_CHARPOS (*it
) += 1;
5079 else if (it
->method
== next_element_from_display_vector
)
5081 /* Current display element of IT is from a display table entry.
5082 Advance in the display table definition. Reset it to null if
5083 end reached, and continue with characters from buffers/
5085 ++it
->current
.dpvec_index
;
5087 /* Restore face of the iterator to what they were before the
5088 display vector entry (these entries may contain faces). */
5089 it
->face_id
= it
->saved_face_id
;
5091 if (it
->dpvec
+ it
->current
.dpvec_index
== it
->dpend
)
5094 it
->method
= next_element_from_c_string
;
5095 else if (STRINGP (it
->string
))
5096 it
->method
= next_element_from_string
;
5098 it
->method
= next_element_from_buffer
;
5101 it
->current
.dpvec_index
= -1;
5103 /* Skip over characters which were displayed via IT->dpvec. */
5104 if (it
->dpvec_char_len
< 0)
5105 reseat_at_next_visible_line_start (it
, 1);
5106 else if (it
->dpvec_char_len
> 0)
5108 it
->len
= it
->dpvec_char_len
;
5109 set_iterator_to_next (it
, reseat_p
);
5113 else if (it
->method
== next_element_from_string
)
5115 /* Current display element is a character from a Lisp string. */
5116 xassert (it
->s
== NULL
&& STRINGP (it
->string
));
5117 IT_STRING_BYTEPOS (*it
) += it
->len
;
5118 IT_STRING_CHARPOS (*it
) += 1;
5120 consider_string_end
:
5122 if (it
->current
.overlay_string_index
>= 0)
5124 /* IT->string is an overlay string. Advance to the
5125 next, if there is one. */
5126 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
))
5127 next_overlay_string (it
);
5131 /* IT->string is not an overlay string. If we reached
5132 its end, and there is something on IT->stack, proceed
5133 with what is on the stack. This can be either another
5134 string, this time an overlay string, or a buffer. */
5135 if (IT_STRING_CHARPOS (*it
) == SCHARS (it
->string
)
5139 if (!STRINGP (it
->string
))
5140 it
->method
= next_element_from_buffer
;
5142 goto consider_string_end
;
5146 else if (it
->method
== next_element_from_image
5147 || it
->method
== next_element_from_stretch
)
5149 /* The position etc with which we have to proceed are on
5150 the stack. The position may be at the end of a string,
5151 if the `display' property takes up the whole string. */
5154 if (STRINGP (it
->string
))
5156 it
->method
= next_element_from_string
;
5157 goto consider_string_end
;
5160 it
->method
= next_element_from_buffer
;
5163 /* There are no other methods defined, so this should be a bug. */
5166 xassert (it
->method
!= next_element_from_string
5167 || (STRINGP (it
->string
)
5168 && IT_STRING_CHARPOS (*it
) >= 0));
5172 /* Load IT's display element fields with information about the next
5173 display element which comes from a display table entry or from the
5174 result of translating a control character to one of the forms `^C'
5175 or `\003'. IT->dpvec holds the glyphs to return as characters. */
5178 next_element_from_display_vector (it
)
5182 xassert (it
->dpvec
&& it
->current
.dpvec_index
>= 0);
5184 /* Remember the current face id in case glyphs specify faces.
5185 IT's face is restored in set_iterator_to_next. */
5186 it
->saved_face_id
= it
->face_id
;
5188 if (INTEGERP (*it
->dpvec
)
5189 && GLYPH_CHAR_VALID_P (XFASTINT (*it
->dpvec
)))
5194 g
= XFASTINT (it
->dpvec
[it
->current
.dpvec_index
]);
5195 it
->c
= FAST_GLYPH_CHAR (g
);
5196 it
->len
= CHAR_BYTES (it
->c
);
5198 /* The entry may contain a face id to use. Such a face id is
5199 the id of a Lisp face, not a realized face. A face id of
5200 zero means no face is specified. */
5201 lface_id
= FAST_GLYPH_FACE (g
);
5204 /* The function returns -1 if lface_id is invalid. */
5205 int face_id
= ascii_face_of_lisp_face (it
->f
, lface_id
);
5207 it
->face_id
= face_id
;
5211 /* Display table entry is invalid. Return a space. */
5212 it
->c
= ' ', it
->len
= 1;
5214 /* Don't change position and object of the iterator here. They are
5215 still the values of the character that had this display table
5216 entry or was translated, and that's what we want. */
5217 it
->what
= IT_CHARACTER
;
5222 /* Load IT with the next display element from Lisp string IT->string.
5223 IT->current.string_pos is the current position within the string.
5224 If IT->current.overlay_string_index >= 0, the Lisp string is an
5228 next_element_from_string (it
)
5231 struct text_pos position
;
5233 xassert (STRINGP (it
->string
));
5234 xassert (IT_STRING_CHARPOS (*it
) >= 0);
5235 position
= it
->current
.string_pos
;
5237 /* Time to check for invisible text? */
5238 if (IT_STRING_CHARPOS (*it
) < it
->end_charpos
5239 && IT_STRING_CHARPOS (*it
) == it
->stop_charpos
)
5243 /* Since a handler may have changed IT->method, we must
5245 return get_next_display_element (it
);
5248 if (it
->current
.overlay_string_index
>= 0)
5250 /* Get the next character from an overlay string. In overlay
5251 strings, There is no field width or padding with spaces to
5253 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
))
5258 else if (STRING_MULTIBYTE (it
->string
))
5260 int remaining
= SBYTES (it
->string
) - IT_STRING_BYTEPOS (*it
);
5261 const unsigned char *s
= (SDATA (it
->string
)
5262 + IT_STRING_BYTEPOS (*it
));
5263 it
->c
= string_char_and_length (s
, remaining
, &it
->len
);
5267 it
->c
= SREF (it
->string
, IT_STRING_BYTEPOS (*it
));
5273 /* Get the next character from a Lisp string that is not an
5274 overlay string. Such strings come from the mode line, for
5275 example. We may have to pad with spaces, or truncate the
5276 string. See also next_element_from_c_string. */
5277 if (IT_STRING_CHARPOS (*it
) >= it
->end_charpos
)
5282 else if (IT_STRING_CHARPOS (*it
) >= it
->string_nchars
)
5284 /* Pad with spaces. */
5285 it
->c
= ' ', it
->len
= 1;
5286 CHARPOS (position
) = BYTEPOS (position
) = -1;
5288 else if (STRING_MULTIBYTE (it
->string
))
5290 int maxlen
= SBYTES (it
->string
) - IT_STRING_BYTEPOS (*it
);
5291 const unsigned char *s
= (SDATA (it
->string
)
5292 + IT_STRING_BYTEPOS (*it
));
5293 it
->c
= string_char_and_length (s
, maxlen
, &it
->len
);
5297 it
->c
= SREF (it
->string
, IT_STRING_BYTEPOS (*it
));
5302 /* Record what we have and where it came from. Note that we store a
5303 buffer position in IT->position although it could arguably be a
5305 it
->what
= IT_CHARACTER
;
5306 it
->object
= it
->string
;
5307 it
->position
= position
;
5312 /* Load IT with next display element from C string IT->s.
5313 IT->string_nchars is the maximum number of characters to return
5314 from the string. IT->end_charpos may be greater than
5315 IT->string_nchars when this function is called, in which case we
5316 may have to return padding spaces. Value is zero if end of string
5317 reached, including padding spaces. */
5320 next_element_from_c_string (it
)
5326 it
->what
= IT_CHARACTER
;
5327 BYTEPOS (it
->position
) = CHARPOS (it
->position
) = 0;
5330 /* IT's position can be greater IT->string_nchars in case a field
5331 width or precision has been specified when the iterator was
5333 if (IT_CHARPOS (*it
) >= it
->end_charpos
)
5335 /* End of the game. */
5339 else if (IT_CHARPOS (*it
) >= it
->string_nchars
)
5341 /* Pad with spaces. */
5342 it
->c
= ' ', it
->len
= 1;
5343 BYTEPOS (it
->position
) = CHARPOS (it
->position
) = -1;
5345 else if (it
->multibyte_p
)
5347 /* Implementation note: The calls to strlen apparently aren't a
5348 performance problem because there is no noticeable performance
5349 difference between Emacs running in unibyte or multibyte mode. */
5350 int maxlen
= strlen (it
->s
) - IT_BYTEPOS (*it
);
5351 it
->c
= string_char_and_length (it
->s
+ IT_BYTEPOS (*it
),
5355 it
->c
= it
->s
[IT_BYTEPOS (*it
)], it
->len
= 1;
5361 /* Set up IT to return characters from an ellipsis, if appropriate.
5362 The definition of the ellipsis glyphs may come from a display table
5363 entry. This function Fills IT with the first glyph from the
5364 ellipsis if an ellipsis is to be displayed. */
5367 next_element_from_ellipsis (it
)
5370 if (it
->selective_display_ellipsis_p
)
5372 if (it
->dp
&& VECTORP (DISP_INVIS_VECTOR (it
->dp
)))
5374 /* Use the display table definition for `...'. Invalid glyphs
5375 will be handled by the method returning elements from dpvec. */
5376 struct Lisp_Vector
*v
= XVECTOR (DISP_INVIS_VECTOR (it
->dp
));
5377 it
->dpvec_char_len
= it
->len
;
5378 it
->dpvec
= v
->contents
;
5379 it
->dpend
= v
->contents
+ v
->size
;
5380 it
->current
.dpvec_index
= 0;
5381 it
->method
= next_element_from_display_vector
;
5385 /* Use default `...' which is stored in default_invis_vector. */
5386 it
->dpvec_char_len
= it
->len
;
5387 it
->dpvec
= default_invis_vector
;
5388 it
->dpend
= default_invis_vector
+ 3;
5389 it
->current
.dpvec_index
= 0;
5390 it
->method
= next_element_from_display_vector
;
5395 /* The face at the current position may be different from the
5396 face we find after the invisible text. Remember what it
5397 was in IT->saved_face_id, and signal that it's there by
5398 setting face_before_selective_p. */
5399 it
->saved_face_id
= it
->face_id
;
5400 it
->method
= next_element_from_buffer
;
5401 reseat_at_next_visible_line_start (it
, 1);
5402 it
->face_before_selective_p
= 1;
5405 return get_next_display_element (it
);
5409 /* Deliver an image display element. The iterator IT is already
5410 filled with image information (done in handle_display_prop). Value
5415 next_element_from_image (it
)
5418 it
->what
= IT_IMAGE
;
5423 /* Fill iterator IT with next display element from a stretch glyph
5424 property. IT->object is the value of the text property. Value is
5428 next_element_from_stretch (it
)
5431 it
->what
= IT_STRETCH
;
5436 /* Load IT with the next display element from current_buffer. Value
5437 is zero if end of buffer reached. IT->stop_charpos is the next
5438 position at which to stop and check for text properties or buffer
5442 next_element_from_buffer (it
)
5447 /* Check this assumption, otherwise, we would never enter the
5448 if-statement, below. */
5449 xassert (IT_CHARPOS (*it
) >= BEGV
5450 && IT_CHARPOS (*it
) <= it
->stop_charpos
);
5452 if (IT_CHARPOS (*it
) >= it
->stop_charpos
)
5454 if (IT_CHARPOS (*it
) >= it
->end_charpos
)
5456 int overlay_strings_follow_p
;
5458 /* End of the game, except when overlay strings follow that
5459 haven't been returned yet. */
5460 if (it
->overlay_strings_at_end_processed_p
)
5461 overlay_strings_follow_p
= 0;
5464 it
->overlay_strings_at_end_processed_p
= 1;
5465 overlay_strings_follow_p
= get_overlay_strings (it
, 0);
5468 if (overlay_strings_follow_p
)
5469 success_p
= get_next_display_element (it
);
5473 it
->position
= it
->current
.pos
;
5480 return get_next_display_element (it
);
5485 /* No face changes, overlays etc. in sight, so just return a
5486 character from current_buffer. */
5489 /* Maybe run the redisplay end trigger hook. Performance note:
5490 This doesn't seem to cost measurable time. */
5491 if (it
->redisplay_end_trigger_charpos
5493 && IT_CHARPOS (*it
) >= it
->redisplay_end_trigger_charpos
)
5494 run_redisplay_end_trigger_hook (it
);
5496 /* Get the next character, maybe multibyte. */
5497 p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
5498 if (it
->multibyte_p
&& !ASCII_BYTE_P (*p
))
5500 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT_BYTE
? ZV_BYTE
: GPT_BYTE
)
5501 - IT_BYTEPOS (*it
));
5502 it
->c
= string_char_and_length (p
, maxlen
, &it
->len
);
5505 it
->c
= *p
, it
->len
= 1;
5507 /* Record what we have and where it came from. */
5508 it
->what
= IT_CHARACTER
;;
5509 it
->object
= it
->w
->buffer
;
5510 it
->position
= it
->current
.pos
;
5512 /* Normally we return the character found above, except when we
5513 really want to return an ellipsis for selective display. */
5518 /* A value of selective > 0 means hide lines indented more
5519 than that number of columns. */
5520 if (it
->selective
> 0
5521 && IT_CHARPOS (*it
) + 1 < ZV
5522 && indented_beyond_p (IT_CHARPOS (*it
) + 1,
5523 IT_BYTEPOS (*it
) + 1,
5524 (double) it
->selective
)) /* iftc */
5526 success_p
= next_element_from_ellipsis (it
);
5527 it
->dpvec_char_len
= -1;
5530 else if (it
->c
== '\r' && it
->selective
== -1)
5532 /* A value of selective == -1 means that everything from the
5533 CR to the end of the line is invisible, with maybe an
5534 ellipsis displayed for it. */
5535 success_p
= next_element_from_ellipsis (it
);
5536 it
->dpvec_char_len
= -1;
5541 /* Value is zero if end of buffer reached. */
5542 xassert (!success_p
|| it
->what
!= IT_CHARACTER
|| it
->len
> 0);
5547 /* Run the redisplay end trigger hook for IT. */
5550 run_redisplay_end_trigger_hook (it
)
5553 Lisp_Object args
[3];
5555 /* IT->glyph_row should be non-null, i.e. we should be actually
5556 displaying something, or otherwise we should not run the hook. */
5557 xassert (it
->glyph_row
);
5559 /* Set up hook arguments. */
5560 args
[0] = Qredisplay_end_trigger_functions
;
5561 args
[1] = it
->window
;
5562 XSETINT (args
[2], it
->redisplay_end_trigger_charpos
);
5563 it
->redisplay_end_trigger_charpos
= 0;
5565 /* Since we are *trying* to run these functions, don't try to run
5566 them again, even if they get an error. */
5567 it
->w
->redisplay_end_trigger
= Qnil
;
5568 Frun_hook_with_args (3, args
);
5570 /* Notice if it changed the face of the character we are on. */
5571 handle_face_prop (it
);
5575 /* Deliver a composition display element. The iterator IT is already
5576 filled with composition information (done in
5577 handle_composition_prop). Value is always 1. */
5580 next_element_from_composition (it
)
5583 it
->what
= IT_COMPOSITION
;
5584 it
->position
= (STRINGP (it
->string
)
5585 ? it
->current
.string_pos
5592 /***********************************************************************
5593 Moving an iterator without producing glyphs
5594 ***********************************************************************/
5596 /* Move iterator IT to a specified buffer or X position within one
5597 line on the display without producing glyphs.
5599 OP should be a bit mask including some or all of these bits:
5600 MOVE_TO_X: Stop on reaching x-position TO_X.
5601 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
5602 Regardless of OP's value, stop in reaching the end of the display line.
5604 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
5605 This means, in particular, that TO_X includes window's horizontal
5608 The return value has several possible values that
5609 say what condition caused the scan to stop:
5611 MOVE_POS_MATCH_OR_ZV
5612 - when TO_POS or ZV was reached.
5615 -when TO_X was reached before TO_POS or ZV were reached.
5618 - when we reached the end of the display area and the line must
5622 - when we reached the end of the display area and the line is
5626 - when we stopped at a line end, i.e. a newline or a CR and selective
5629 static enum move_it_result
5630 move_it_in_display_line_to (it
, to_charpos
, to_x
, op
)
5632 int to_charpos
, to_x
, op
;
5634 enum move_it_result result
= MOVE_UNDEFINED
;
5635 struct glyph_row
*saved_glyph_row
;
5637 /* Don't produce glyphs in produce_glyphs. */
5638 saved_glyph_row
= it
->glyph_row
;
5639 it
->glyph_row
= NULL
;
5641 #define BUFFER_POS_REACHED_P() \
5642 ((op & MOVE_TO_POS) != 0 \
5643 && BUFFERP (it->object) \
5644 && IT_CHARPOS (*it) >= to_charpos)
5648 int x
, i
, ascent
= 0, descent
= 0;
5650 /* Stop when ZV or TO_CHARPOS reached. */
5651 if (!get_next_display_element (it
)
5652 || BUFFER_POS_REACHED_P ())
5654 result
= MOVE_POS_MATCH_OR_ZV
;
5658 /* The call to produce_glyphs will get the metrics of the
5659 display element IT is loaded with. We record in x the
5660 x-position before this display element in case it does not
5664 /* Remember the line height so far in case the next element doesn't
5666 if (!it
->truncate_lines_p
)
5668 ascent
= it
->max_ascent
;
5669 descent
= it
->max_descent
;
5672 PRODUCE_GLYPHS (it
);
5674 if (it
->area
!= TEXT_AREA
)
5676 set_iterator_to_next (it
, 1);
5680 /* The number of glyphs we get back in IT->nglyphs will normally
5681 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
5682 character on a terminal frame, or (iii) a line end. For the
5683 second case, IT->nglyphs - 1 padding glyphs will be present
5684 (on X frames, there is only one glyph produced for a
5685 composite character.
5687 The behavior implemented below means, for continuation lines,
5688 that as many spaces of a TAB as fit on the current line are
5689 displayed there. For terminal frames, as many glyphs of a
5690 multi-glyph character are displayed in the current line, too.
5691 This is what the old redisplay code did, and we keep it that
5692 way. Under X, the whole shape of a complex character must
5693 fit on the line or it will be completely displayed in the
5696 Note that both for tabs and padding glyphs, all glyphs have
5700 /* More than one glyph or glyph doesn't fit on line. All
5701 glyphs have the same width. */
5702 int single_glyph_width
= it
->pixel_width
/ it
->nglyphs
;
5705 for (i
= 0; i
< it
->nglyphs
; ++i
, x
= new_x
)
5707 new_x
= x
+ single_glyph_width
;
5709 /* We want to leave anything reaching TO_X to the caller. */
5710 if ((op
& MOVE_TO_X
) && new_x
> to_x
)
5713 result
= MOVE_X_REACHED
;
5716 else if (/* Lines are continued. */
5717 !it
->truncate_lines_p
5718 && (/* And glyph doesn't fit on the line. */
5719 new_x
> it
->last_visible_x
5720 /* Or it fits exactly and we're on a window
5722 || (new_x
== it
->last_visible_x
5723 && FRAME_WINDOW_P (it
->f
))))
5725 if (/* IT->hpos == 0 means the very first glyph
5726 doesn't fit on the line, e.g. a wide image. */
5728 || (new_x
== it
->last_visible_x
5729 && FRAME_WINDOW_P (it
->f
)))
5732 it
->current_x
= new_x
;
5733 if (i
== it
->nglyphs
- 1)
5735 set_iterator_to_next (it
, 1);
5736 #ifdef HAVE_WINDOW_SYSTEM
5737 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
5739 if (!get_next_display_element (it
)
5740 || BUFFER_POS_REACHED_P ())
5742 result
= MOVE_POS_MATCH_OR_ZV
;
5745 if (ITERATOR_AT_END_OF_LINE_P (it
))
5747 result
= MOVE_NEWLINE_OR_CR
;
5751 #endif /* HAVE_WINDOW_SYSTEM */
5757 it
->max_ascent
= ascent
;
5758 it
->max_descent
= descent
;
5761 TRACE_MOVE ((stderr
, "move_it_in: continued at %d\n",
5763 result
= MOVE_LINE_CONTINUED
;
5766 else if (new_x
> it
->first_visible_x
)
5768 /* Glyph is visible. Increment number of glyphs that
5769 would be displayed. */
5774 /* Glyph is completely off the left margin of the display
5775 area. Nothing to do. */
5779 if (result
!= MOVE_UNDEFINED
)
5782 else if ((op
& MOVE_TO_X
) && it
->current_x
>= to_x
)
5784 /* Stop when TO_X specified and reached. This check is
5785 necessary here because of lines consisting of a line end,
5786 only. The line end will not produce any glyphs and we
5787 would never get MOVE_X_REACHED. */
5788 xassert (it
->nglyphs
== 0);
5789 result
= MOVE_X_REACHED
;
5793 /* Is this a line end? If yes, we're done. */
5794 if (ITERATOR_AT_END_OF_LINE_P (it
))
5796 result
= MOVE_NEWLINE_OR_CR
;
5800 /* The current display element has been consumed. Advance
5802 set_iterator_to_next (it
, 1);
5804 /* Stop if lines are truncated and IT's current x-position is
5805 past the right edge of the window now. */
5806 if (it
->truncate_lines_p
5807 && it
->current_x
>= it
->last_visible_x
)
5809 #ifdef HAVE_WINDOW_SYSTEM
5810 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
5812 if (!get_next_display_element (it
)
5813 || BUFFER_POS_REACHED_P ())
5815 result
= MOVE_POS_MATCH_OR_ZV
;
5818 if (ITERATOR_AT_END_OF_LINE_P (it
))
5820 result
= MOVE_NEWLINE_OR_CR
;
5824 #endif /* HAVE_WINDOW_SYSTEM */
5825 result
= MOVE_LINE_TRUNCATED
;
5830 #undef BUFFER_POS_REACHED_P
5832 /* Restore the iterator settings altered at the beginning of this
5834 it
->glyph_row
= saved_glyph_row
;
5839 /* Move IT forward until it satisfies one or more of the criteria in
5840 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
5842 OP is a bit-mask that specifies where to stop, and in particular,
5843 which of those four position arguments makes a difference. See the
5844 description of enum move_operation_enum.
5846 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
5847 screen line, this function will set IT to the next position >
5851 move_it_to (it
, to_charpos
, to_x
, to_y
, to_vpos
, op
)
5853 int to_charpos
, to_x
, to_y
, to_vpos
;
5856 enum move_it_result skip
, skip2
= MOVE_X_REACHED
;
5862 if (op
& MOVE_TO_VPOS
)
5864 /* If no TO_CHARPOS and no TO_X specified, stop at the
5865 start of the line TO_VPOS. */
5866 if ((op
& (MOVE_TO_X
| MOVE_TO_POS
)) == 0)
5868 if (it
->vpos
== to_vpos
)
5874 skip
= move_it_in_display_line_to (it
, -1, -1, 0);
5878 /* TO_VPOS >= 0 means stop at TO_X in the line at
5879 TO_VPOS, or at TO_POS, whichever comes first. */
5880 if (it
->vpos
== to_vpos
)
5886 skip
= move_it_in_display_line_to (it
, to_charpos
, to_x
, op
);
5888 if (skip
== MOVE_POS_MATCH_OR_ZV
|| it
->vpos
== to_vpos
)
5893 else if (skip
== MOVE_X_REACHED
&& it
->vpos
!= to_vpos
)
5895 /* We have reached TO_X but not in the line we want. */
5896 skip
= move_it_in_display_line_to (it
, to_charpos
,
5898 if (skip
== MOVE_POS_MATCH_OR_ZV
)
5906 else if (op
& MOVE_TO_Y
)
5908 struct it it_backup
;
5910 /* TO_Y specified means stop at TO_X in the line containing
5911 TO_Y---or at TO_CHARPOS if this is reached first. The
5912 problem is that we can't really tell whether the line
5913 contains TO_Y before we have completely scanned it, and
5914 this may skip past TO_X. What we do is to first scan to
5917 If TO_X is not specified, use a TO_X of zero. The reason
5918 is to make the outcome of this function more predictable.
5919 If we didn't use TO_X == 0, we would stop at the end of
5920 the line which is probably not what a caller would expect
5922 skip
= move_it_in_display_line_to (it
, to_charpos
,
5926 | (op
& MOVE_TO_POS
)));
5928 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
5929 if (skip
== MOVE_POS_MATCH_OR_ZV
)
5935 /* If TO_X was reached, we would like to know whether TO_Y
5936 is in the line. This can only be said if we know the
5937 total line height which requires us to scan the rest of
5939 if (skip
== MOVE_X_REACHED
)
5942 TRACE_MOVE ((stderr
, "move_it: from %d\n", IT_CHARPOS (*it
)));
5943 skip2
= move_it_in_display_line_to (it
, to_charpos
, -1,
5945 TRACE_MOVE ((stderr
, "move_it: to %d\n", IT_CHARPOS (*it
)));
5948 /* Now, decide whether TO_Y is in this line. */
5949 line_height
= it
->max_ascent
+ it
->max_descent
;
5950 TRACE_MOVE ((stderr
, "move_it: line_height = %d\n", line_height
));
5952 if (to_y
>= it
->current_y
5953 && to_y
< it
->current_y
+ line_height
)
5955 if (skip
== MOVE_X_REACHED
)
5956 /* If TO_Y is in this line and TO_X was reached above,
5957 we scanned too far. We have to restore IT's settings
5958 to the ones before skipping. */
5962 else if (skip
== MOVE_X_REACHED
)
5965 if (skip
== MOVE_POS_MATCH_OR_ZV
)
5973 skip
= move_it_in_display_line_to (it
, to_charpos
, -1, MOVE_TO_POS
);
5977 case MOVE_POS_MATCH_OR_ZV
:
5981 case MOVE_NEWLINE_OR_CR
:
5982 set_iterator_to_next (it
, 1);
5983 it
->continuation_lines_width
= 0;
5986 case MOVE_LINE_TRUNCATED
:
5987 it
->continuation_lines_width
= 0;
5988 reseat_at_next_visible_line_start (it
, 0);
5989 if ((op
& MOVE_TO_POS
) != 0
5990 && IT_CHARPOS (*it
) > to_charpos
)
5997 case MOVE_LINE_CONTINUED
:
5998 it
->continuation_lines_width
+= it
->current_x
;
6005 /* Reset/increment for the next run. */
6006 recenter_overlay_lists (current_buffer
, IT_CHARPOS (*it
));
6007 it
->current_x
= it
->hpos
= 0;
6008 it
->current_y
+= it
->max_ascent
+ it
->max_descent
;
6010 last_height
= it
->max_ascent
+ it
->max_descent
;
6011 last_max_ascent
= it
->max_ascent
;
6012 it
->max_ascent
= it
->max_descent
= 0;
6017 TRACE_MOVE ((stderr
, "move_it_to: reached %d\n", reached
));
6021 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
6023 If DY > 0, move IT backward at least that many pixels. DY = 0
6024 means move IT backward to the preceding line start or BEGV. This
6025 function may move over more than DY pixels if IT->current_y - DY
6026 ends up in the middle of a line; in this case IT->current_y will be
6027 set to the top of the line moved to. */
6030 move_it_vertically_backward (it
, dy
)
6036 int start_pos
= IT_CHARPOS (*it
);
6040 /* Estimate how many newlines we must move back. */
6041 nlines
= max (1, dy
/ FRAME_LINE_HEIGHT (it
->f
));
6043 /* Set the iterator's position that many lines back. */
6044 while (nlines
-- && IT_CHARPOS (*it
) > BEGV
)
6045 back_to_previous_visible_line_start (it
);
6047 /* Reseat the iterator here. When moving backward, we don't want
6048 reseat to skip forward over invisible text, set up the iterator
6049 to deliver from overlay strings at the new position etc. So,
6050 use reseat_1 here. */
6051 reseat_1 (it
, it
->current
.pos
, 1);
6053 /* We are now surely at a line start. */
6054 it
->current_x
= it
->hpos
= 0;
6055 it
->continuation_lines_width
= 0;
6057 /* Move forward and see what y-distance we moved. First move to the
6058 start of the next line so that we get its height. We need this
6059 height to be able to tell whether we reached the specified
6062 it2
.max_ascent
= it2
.max_descent
= 0;
6063 move_it_to (&it2
, start_pos
, -1, -1, it2
.vpos
+ 1,
6064 MOVE_TO_POS
| MOVE_TO_VPOS
);
6065 xassert (IT_CHARPOS (*it
) >= BEGV
);
6068 move_it_to (&it2
, start_pos
, -1, -1, -1, MOVE_TO_POS
);
6069 xassert (IT_CHARPOS (*it
) >= BEGV
);
6070 /* H is the actual vertical distance from the position in *IT
6071 and the starting position. */
6072 h
= it2
.current_y
- it
->current_y
;
6073 /* NLINES is the distance in number of lines. */
6074 nlines
= it2
.vpos
- it
->vpos
;
6076 /* Correct IT's y and vpos position
6077 so that they are relative to the starting point. */
6083 /* DY == 0 means move to the start of the screen line. The
6084 value of nlines is > 0 if continuation lines were involved. */
6086 move_it_by_lines (it
, nlines
, 1);
6087 xassert (IT_CHARPOS (*it
) <= start_pos
);
6091 /* The y-position we try to reach, relative to *IT.
6092 Note that H has been subtracted in front of the if-statement. */
6093 int target_y
= it
->current_y
+ h
- dy
;
6094 int y0
= it3
.current_y
;
6095 int y1
= line_bottom_y (&it3
);
6096 int line_height
= y1
- y0
;
6098 /* If we did not reach target_y, try to move further backward if
6099 we can. If we moved too far backward, try to move forward. */
6100 if (target_y
< it
->current_y
6101 /* This is heuristic. In a window that's 3 lines high, with
6102 a line height of 13 pixels each, recentering with point
6103 on the bottom line will try to move -39/2 = 19 pixels
6104 backward. Try to avoid moving into the first line. */
6105 && it
->current_y
- target_y
> line_height
/ 3 * 2
6106 && IT_CHARPOS (*it
) > BEGV
)
6108 TRACE_MOVE ((stderr
, " not far enough -> move_vert %d\n",
6109 target_y
- it
->current_y
));
6110 move_it_vertically (it
, target_y
- it
->current_y
);
6111 xassert (IT_CHARPOS (*it
) >= BEGV
);
6113 else if (target_y
>= it
->current_y
+ line_height
6114 && IT_CHARPOS (*it
) < ZV
)
6116 /* Should move forward by at least one line, maybe more.
6118 Note: Calling move_it_by_lines can be expensive on
6119 terminal frames, where compute_motion is used (via
6120 vmotion) to do the job, when there are very long lines
6121 and truncate-lines is nil. That's the reason for
6122 treating terminal frames specially here. */
6124 if (!FRAME_WINDOW_P (it
->f
))
6125 move_it_vertically (it
, target_y
- (it
->current_y
+ line_height
));
6130 move_it_by_lines (it
, 1, 1);
6132 while (target_y
>= line_bottom_y (it
) && IT_CHARPOS (*it
) < ZV
);
6135 xassert (IT_CHARPOS (*it
) >= BEGV
);
6141 /* Move IT by a specified amount of pixel lines DY. DY negative means
6142 move backwards. DY = 0 means move to start of screen line. At the
6143 end, IT will be on the start of a screen line. */
6146 move_it_vertically (it
, dy
)
6151 move_it_vertically_backward (it
, -dy
);
6154 TRACE_MOVE ((stderr
, "move_it_v: from %d, %d\n", IT_CHARPOS (*it
), dy
));
6155 move_it_to (it
, ZV
, -1, it
->current_y
+ dy
, -1,
6156 MOVE_TO_POS
| MOVE_TO_Y
);
6157 TRACE_MOVE ((stderr
, "move_it_v: to %d\n", IT_CHARPOS (*it
)));
6159 /* If buffer ends in ZV without a newline, move to the start of
6160 the line to satisfy the post-condition. */
6161 if (IT_CHARPOS (*it
) == ZV
6162 && FETCH_BYTE (IT_BYTEPOS (*it
) - 1) != '\n')
6163 move_it_by_lines (it
, 0, 0);
6168 /* Move iterator IT past the end of the text line it is in. */
6171 move_it_past_eol (it
)
6174 enum move_it_result rc
;
6176 rc
= move_it_in_display_line_to (it
, Z
, 0, MOVE_TO_POS
);
6177 if (rc
== MOVE_NEWLINE_OR_CR
)
6178 set_iterator_to_next (it
, 0);
6182 #if 0 /* Currently not used. */
6184 /* Return non-zero if some text between buffer positions START_CHARPOS
6185 and END_CHARPOS is invisible. IT->window is the window for text
6189 invisible_text_between_p (it
, start_charpos
, end_charpos
)
6191 int start_charpos
, end_charpos
;
6193 Lisp_Object prop
, limit
;
6194 int invisible_found_p
;
6196 xassert (it
!= NULL
&& start_charpos
<= end_charpos
);
6198 /* Is text at START invisible? */
6199 prop
= Fget_char_property (make_number (start_charpos
), Qinvisible
,
6201 if (TEXT_PROP_MEANS_INVISIBLE (prop
))
6202 invisible_found_p
= 1;
6205 limit
= Fnext_single_char_property_change (make_number (start_charpos
),
6207 make_number (end_charpos
));
6208 invisible_found_p
= XFASTINT (limit
) < end_charpos
;
6211 return invisible_found_p
;
6217 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
6218 negative means move up. DVPOS == 0 means move to the start of the
6219 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
6220 NEED_Y_P is zero, IT->current_y will be left unchanged.
6222 Further optimization ideas: If we would know that IT->f doesn't use
6223 a face with proportional font, we could be faster for
6224 truncate-lines nil. */
6227 move_it_by_lines (it
, dvpos
, need_y_p
)
6229 int dvpos
, need_y_p
;
6231 struct position pos
;
6233 if (!FRAME_WINDOW_P (it
->f
))
6235 struct text_pos textpos
;
6237 /* We can use vmotion on frames without proportional fonts. */
6238 pos
= *vmotion (IT_CHARPOS (*it
), dvpos
, it
->w
);
6239 SET_TEXT_POS (textpos
, pos
.bufpos
, pos
.bytepos
);
6240 reseat (it
, textpos
, 1);
6241 it
->vpos
+= pos
.vpos
;
6242 it
->current_y
+= pos
.vpos
;
6244 else if (dvpos
== 0)
6246 /* DVPOS == 0 means move to the start of the screen line. */
6247 move_it_vertically_backward (it
, 0);
6248 xassert (it
->current_x
== 0 && it
->hpos
== 0);
6251 move_it_to (it
, -1, -1, -1, it
->vpos
+ dvpos
, MOVE_TO_VPOS
);
6255 int start_charpos
, i
;
6257 /* Start at the beginning of the screen line containing IT's
6259 move_it_vertically_backward (it
, 0);
6261 /* Go back -DVPOS visible lines and reseat the iterator there. */
6262 start_charpos
= IT_CHARPOS (*it
);
6263 for (i
= -dvpos
; i
&& IT_CHARPOS (*it
) > BEGV
; --i
)
6264 back_to_previous_visible_line_start (it
);
6265 reseat (it
, it
->current
.pos
, 1);
6266 it
->current_x
= it
->hpos
= 0;
6268 /* Above call may have moved too far if continuation lines
6269 are involved. Scan forward and see if it did. */
6271 it2
.vpos
= it2
.current_y
= 0;
6272 move_it_to (&it2
, start_charpos
, -1, -1, -1, MOVE_TO_POS
);
6273 it
->vpos
-= it2
.vpos
;
6274 it
->current_y
-= it2
.current_y
;
6275 it
->current_x
= it
->hpos
= 0;
6277 /* If we moved too far, move IT some lines forward. */
6278 if (it2
.vpos
> -dvpos
)
6280 int delta
= it2
.vpos
+ dvpos
;
6281 move_it_to (it
, -1, -1, -1, it
->vpos
+ delta
, MOVE_TO_VPOS
);
6286 /* Return 1 if IT points into the middle of a display vector. */
6289 in_display_vector_p (it
)
6292 return (it
->method
== next_element_from_display_vector
6293 && it
->current
.dpvec_index
> 0
6294 && it
->dpvec
+ it
->current
.dpvec_index
!= it
->dpend
);
6298 /***********************************************************************
6300 ***********************************************************************/
6303 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
6307 add_to_log (format
, arg1
, arg2
)
6309 Lisp_Object arg1
, arg2
;
6311 Lisp_Object args
[3];
6312 Lisp_Object msg
, fmt
;
6315 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
6317 /* Do nothing if called asynchronously. Inserting text into
6318 a buffer may call after-change-functions and alike and
6319 that would means running Lisp asynchronously. */
6320 if (handling_signal
)
6324 GCPRO4 (fmt
, msg
, arg1
, arg2
);
6326 args
[0] = fmt
= build_string (format
);
6329 msg
= Fformat (3, args
);
6331 len
= SBYTES (msg
) + 1;
6332 buffer
= (char *) alloca (len
);
6333 bcopy (SDATA (msg
), buffer
, len
);
6335 message_dolog (buffer
, len
- 1, 1, 0);
6340 /* Output a newline in the *Messages* buffer if "needs" one. */
6343 message_log_maybe_newline ()
6345 if (message_log_need_newline
)
6346 message_dolog ("", 0, 1, 0);
6350 /* Add a string M of length NBYTES to the message log, optionally
6351 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
6352 nonzero, means interpret the contents of M as multibyte. This
6353 function calls low-level routines in order to bypass text property
6354 hooks, etc. which might not be safe to run. */
6357 message_dolog (m
, nbytes
, nlflag
, multibyte
)
6359 int nbytes
, nlflag
, multibyte
;
6361 if (!NILP (Vmemory_full
))
6364 if (!NILP (Vmessage_log_max
))
6366 struct buffer
*oldbuf
;
6367 Lisp_Object oldpoint
, oldbegv
, oldzv
;
6368 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
6369 int point_at_end
= 0;
6371 Lisp_Object old_deactivate_mark
, tem
;
6372 struct gcpro gcpro1
;
6374 old_deactivate_mark
= Vdeactivate_mark
;
6375 oldbuf
= current_buffer
;
6376 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name
));
6377 current_buffer
->undo_list
= Qt
;
6379 oldpoint
= message_dolog_marker1
;
6380 set_marker_restricted (oldpoint
, make_number (PT
), Qnil
);
6381 oldbegv
= message_dolog_marker2
;
6382 set_marker_restricted (oldbegv
, make_number (BEGV
), Qnil
);
6383 oldzv
= message_dolog_marker3
;
6384 set_marker_restricted (oldzv
, make_number (ZV
), Qnil
);
6385 GCPRO1 (old_deactivate_mark
);
6393 BEGV_BYTE
= BEG_BYTE
;
6396 TEMP_SET_PT_BOTH (Z
, Z_BYTE
);
6398 /* Insert the string--maybe converting multibyte to single byte
6399 or vice versa, so that all the text fits the buffer. */
6401 && NILP (current_buffer
->enable_multibyte_characters
))
6403 int i
, c
, char_bytes
;
6404 unsigned char work
[1];
6406 /* Convert a multibyte string to single-byte
6407 for the *Message* buffer. */
6408 for (i
= 0; i
< nbytes
; i
+= char_bytes
)
6410 c
= string_char_and_length (m
+ i
, nbytes
- i
, &char_bytes
);
6411 work
[0] = (SINGLE_BYTE_CHAR_P (c
)
6413 : multibyte_char_to_unibyte (c
, Qnil
));
6414 insert_1_both (work
, 1, 1, 1, 0, 0);
6417 else if (! multibyte
6418 && ! NILP (current_buffer
->enable_multibyte_characters
))
6420 int i
, c
, char_bytes
;
6421 unsigned char *msg
= (unsigned char *) m
;
6422 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
6423 /* Convert a single-byte string to multibyte
6424 for the *Message* buffer. */
6425 for (i
= 0; i
< nbytes
; i
++)
6427 c
= unibyte_char_to_multibyte (msg
[i
]);
6428 char_bytes
= CHAR_STRING (c
, str
);
6429 insert_1_both (str
, 1, char_bytes
, 1, 0, 0);
6433 insert_1 (m
, nbytes
, 1, 0, 0);
6437 int this_bol
, this_bol_byte
, prev_bol
, prev_bol_byte
, dup
;
6438 insert_1 ("\n", 1, 1, 0, 0);
6440 scan_newline (Z
, Z_BYTE
, BEG
, BEG_BYTE
, -2, 0);
6442 this_bol_byte
= PT_BYTE
;
6444 /* See if this line duplicates the previous one.
6445 If so, combine duplicates. */
6448 scan_newline (PT
, PT_BYTE
, BEG
, BEG_BYTE
, -2, 0);
6450 prev_bol_byte
= PT_BYTE
;
6452 dup
= message_log_check_duplicate (prev_bol
, prev_bol_byte
,
6453 this_bol
, this_bol_byte
);
6456 del_range_both (prev_bol
, prev_bol_byte
,
6457 this_bol
, this_bol_byte
, 0);
6463 /* If you change this format, don't forget to also
6464 change message_log_check_duplicate. */
6465 sprintf (dupstr
, " [%d times]", dup
);
6466 duplen
= strlen (dupstr
);
6467 TEMP_SET_PT_BOTH (Z
- 1, Z_BYTE
- 1);
6468 insert_1 (dupstr
, duplen
, 1, 0, 1);
6473 /* If we have more than the desired maximum number of lines
6474 in the *Messages* buffer now, delete the oldest ones.
6475 This is safe because we don't have undo in this buffer. */
6477 if (NATNUMP (Vmessage_log_max
))
6479 scan_newline (Z
, Z_BYTE
, BEG
, BEG_BYTE
,
6480 -XFASTINT (Vmessage_log_max
) - 1, 0);
6481 del_range_both (BEG
, BEG_BYTE
, PT
, PT_BYTE
, 0);
6484 BEGV
= XMARKER (oldbegv
)->charpos
;
6485 BEGV_BYTE
= marker_byte_position (oldbegv
);
6494 ZV
= XMARKER (oldzv
)->charpos
;
6495 ZV_BYTE
= marker_byte_position (oldzv
);
6499 TEMP_SET_PT_BOTH (Z
, Z_BYTE
);
6501 /* We can't do Fgoto_char (oldpoint) because it will run some
6503 TEMP_SET_PT_BOTH (XMARKER (oldpoint
)->charpos
,
6504 XMARKER (oldpoint
)->bytepos
);
6507 unchain_marker (XMARKER (oldpoint
));
6508 unchain_marker (XMARKER (oldbegv
));
6509 unchain_marker (XMARKER (oldzv
));
6511 tem
= Fget_buffer_window (Fcurrent_buffer (), Qt
);
6512 set_buffer_internal (oldbuf
);
6514 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
6515 message_log_need_newline
= !nlflag
;
6516 Vdeactivate_mark
= old_deactivate_mark
;
6521 /* We are at the end of the buffer after just having inserted a newline.
6522 (Note: We depend on the fact we won't be crossing the gap.)
6523 Check to see if the most recent message looks a lot like the previous one.
6524 Return 0 if different, 1 if the new one should just replace it, or a
6525 value N > 1 if we should also append " [N times]". */
6528 message_log_check_duplicate (prev_bol
, prev_bol_byte
, this_bol
, this_bol_byte
)
6529 int prev_bol
, this_bol
;
6530 int prev_bol_byte
, this_bol_byte
;
6533 int len
= Z_BYTE
- 1 - this_bol_byte
;
6535 unsigned char *p1
= BUF_BYTE_ADDRESS (current_buffer
, prev_bol_byte
);
6536 unsigned char *p2
= BUF_BYTE_ADDRESS (current_buffer
, this_bol_byte
);
6538 for (i
= 0; i
< len
; i
++)
6540 if (i
>= 3 && p1
[i
-3] == '.' && p1
[i
-2] == '.' && p1
[i
-1] == '.')
6548 if (*p1
++ == ' ' && *p1
++ == '[')
6551 while (*p1
>= '0' && *p1
<= '9')
6552 n
= n
* 10 + *p1
++ - '0';
6553 if (strncmp (p1
, " times]\n", 8) == 0)
6560 /* Display an echo area message M with a specified length of NBYTES
6561 bytes. The string may include null characters. If M is 0, clear
6562 out any existing message, and let the mini-buffer text show
6565 The buffer M must continue to exist until after the echo area gets
6566 cleared or some other message gets displayed there. This means do
6567 not pass text that is stored in a Lisp string; do not pass text in
6568 a buffer that was alloca'd. */
6571 message2 (m
, nbytes
, multibyte
)
6576 /* First flush out any partial line written with print. */
6577 message_log_maybe_newline ();
6579 message_dolog (m
, nbytes
, 1, multibyte
);
6580 message2_nolog (m
, nbytes
, multibyte
);
6584 /* The non-logging counterpart of message2. */
6587 message2_nolog (m
, nbytes
, multibyte
)
6589 int nbytes
, multibyte
;
6591 struct frame
*sf
= SELECTED_FRAME ();
6592 message_enable_multibyte
= multibyte
;
6596 if (noninteractive_need_newline
)
6597 putc ('\n', stderr
);
6598 noninteractive_need_newline
= 0;
6600 fwrite (m
, nbytes
, 1, stderr
);
6601 if (cursor_in_echo_area
== 0)
6602 fprintf (stderr
, "\n");
6605 /* A null message buffer means that the frame hasn't really been
6606 initialized yet. Error messages get reported properly by
6607 cmd_error, so this must be just an informative message; toss it. */
6608 else if (INTERACTIVE
6609 && sf
->glyphs_initialized_p
6610 && FRAME_MESSAGE_BUF (sf
))
6612 Lisp_Object mini_window
;
6615 /* Get the frame containing the mini-buffer
6616 that the selected frame is using. */
6617 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
6618 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
6620 FRAME_SAMPLE_VISIBILITY (f
);
6621 if (FRAME_VISIBLE_P (sf
)
6622 && ! FRAME_VISIBLE_P (f
))
6623 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window
)));
6627 set_message (m
, Qnil
, nbytes
, multibyte
);
6628 if (minibuffer_auto_raise
)
6629 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window
)));
6632 clear_message (1, 1);
6634 do_pending_window_change (0);
6635 echo_area_display (1);
6636 do_pending_window_change (0);
6637 if (frame_up_to_date_hook
!= 0 && ! gc_in_progress
)
6638 (*frame_up_to_date_hook
) (f
);
6643 /* Display an echo area message M with a specified length of NBYTES
6644 bytes. The string may include null characters. If M is not a
6645 string, clear out any existing message, and let the mini-buffer
6646 text show through. */
6649 message3 (m
, nbytes
, multibyte
)
6654 struct gcpro gcpro1
;
6658 /* First flush out any partial line written with print. */
6659 message_log_maybe_newline ();
6661 message_dolog (SDATA (m
), nbytes
, 1, multibyte
);
6662 message3_nolog (m
, nbytes
, multibyte
);
6668 /* The non-logging version of message3. */
6671 message3_nolog (m
, nbytes
, multibyte
)
6673 int nbytes
, multibyte
;
6675 struct frame
*sf
= SELECTED_FRAME ();
6676 message_enable_multibyte
= multibyte
;
6680 if (noninteractive_need_newline
)
6681 putc ('\n', stderr
);
6682 noninteractive_need_newline
= 0;
6684 fwrite (SDATA (m
), nbytes
, 1, stderr
);
6685 if (cursor_in_echo_area
== 0)
6686 fprintf (stderr
, "\n");
6689 /* A null message buffer means that the frame hasn't really been
6690 initialized yet. Error messages get reported properly by
6691 cmd_error, so this must be just an informative message; toss it. */
6692 else if (INTERACTIVE
6693 && sf
->glyphs_initialized_p
6694 && FRAME_MESSAGE_BUF (sf
))
6696 Lisp_Object mini_window
;
6700 /* Get the frame containing the mini-buffer
6701 that the selected frame is using. */
6702 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
6703 frame
= XWINDOW (mini_window
)->frame
;
6706 FRAME_SAMPLE_VISIBILITY (f
);
6707 if (FRAME_VISIBLE_P (sf
)
6708 && !FRAME_VISIBLE_P (f
))
6709 Fmake_frame_visible (frame
);
6711 if (STRINGP (m
) && SCHARS (m
) > 0)
6713 set_message (NULL
, m
, nbytes
, multibyte
);
6714 if (minibuffer_auto_raise
)
6715 Fraise_frame (frame
);
6718 clear_message (1, 1);
6720 do_pending_window_change (0);
6721 echo_area_display (1);
6722 do_pending_window_change (0);
6723 if (frame_up_to_date_hook
!= 0 && ! gc_in_progress
)
6724 (*frame_up_to_date_hook
) (f
);
6729 /* Display a null-terminated echo area message M. If M is 0, clear
6730 out any existing message, and let the mini-buffer text show through.
6732 The buffer M must continue to exist until after the echo area gets
6733 cleared or some other message gets displayed there. Do not pass
6734 text that is stored in a Lisp string. Do not pass text in a buffer
6735 that was alloca'd. */
6741 message2 (m
, (m
? strlen (m
) : 0), 0);
6745 /* The non-logging counterpart of message1. */
6751 message2_nolog (m
, (m
? strlen (m
) : 0), 0);
6754 /* Display a message M which contains a single %s
6755 which gets replaced with STRING. */
6758 message_with_string (m
, string
, log
)
6763 CHECK_STRING (string
);
6769 if (noninteractive_need_newline
)
6770 putc ('\n', stderr
);
6771 noninteractive_need_newline
= 0;
6772 fprintf (stderr
, m
, SDATA (string
));
6773 if (cursor_in_echo_area
== 0)
6774 fprintf (stderr
, "\n");
6778 else if (INTERACTIVE
)
6780 /* The frame whose minibuffer we're going to display the message on.
6781 It may be larger than the selected frame, so we need
6782 to use its buffer, not the selected frame's buffer. */
6783 Lisp_Object mini_window
;
6784 struct frame
*f
, *sf
= SELECTED_FRAME ();
6786 /* Get the frame containing the minibuffer
6787 that the selected frame is using. */
6788 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
6789 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
6791 /* A null message buffer means that the frame hasn't really been
6792 initialized yet. Error messages get reported properly by
6793 cmd_error, so this must be just an informative message; toss it. */
6794 if (FRAME_MESSAGE_BUF (f
))
6796 Lisp_Object args
[2], message
;
6797 struct gcpro gcpro1
, gcpro2
;
6799 args
[0] = build_string (m
);
6800 args
[1] = message
= string
;
6801 GCPRO2 (args
[0], message
);
6804 message
= Fformat (2, args
);
6807 message3 (message
, SBYTES (message
), STRING_MULTIBYTE (message
));
6809 message3_nolog (message
, SBYTES (message
), STRING_MULTIBYTE (message
));
6813 /* Print should start at the beginning of the message
6814 buffer next time. */
6815 message_buf_print
= 0;
6821 /* Dump an informative message to the minibuf. If M is 0, clear out
6822 any existing message, and let the mini-buffer text show through. */
6826 message (m
, a1
, a2
, a3
)
6828 EMACS_INT a1
, a2
, a3
;
6834 if (noninteractive_need_newline
)
6835 putc ('\n', stderr
);
6836 noninteractive_need_newline
= 0;
6837 fprintf (stderr
, m
, a1
, a2
, a3
);
6838 if (cursor_in_echo_area
== 0)
6839 fprintf (stderr
, "\n");
6843 else if (INTERACTIVE
)
6845 /* The frame whose mini-buffer we're going to display the message
6846 on. It may be larger than the selected frame, so we need to
6847 use its buffer, not the selected frame's buffer. */
6848 Lisp_Object mini_window
;
6849 struct frame
*f
, *sf
= SELECTED_FRAME ();
6851 /* Get the frame containing the mini-buffer
6852 that the selected frame is using. */
6853 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
6854 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
6856 /* A null message buffer means that the frame hasn't really been
6857 initialized yet. Error messages get reported properly by
6858 cmd_error, so this must be just an informative message; toss
6860 if (FRAME_MESSAGE_BUF (f
))
6871 len
= doprnt (FRAME_MESSAGE_BUF (f
),
6872 FRAME_MESSAGE_BUF_SIZE (f
), m
, (char *)0, 3, a
);
6874 len
= doprnt (FRAME_MESSAGE_BUF (f
),
6875 FRAME_MESSAGE_BUF_SIZE (f
), m
, (char *)0, 3,
6877 #endif /* NO_ARG_ARRAY */
6879 message2 (FRAME_MESSAGE_BUF (f
), len
, 0);
6884 /* Print should start at the beginning of the message
6885 buffer next time. */
6886 message_buf_print
= 0;
6892 /* The non-logging version of message. */
6895 message_nolog (m
, a1
, a2
, a3
)
6897 EMACS_INT a1
, a2
, a3
;
6899 Lisp_Object old_log_max
;
6900 old_log_max
= Vmessage_log_max
;
6901 Vmessage_log_max
= Qnil
;
6902 message (m
, a1
, a2
, a3
);
6903 Vmessage_log_max
= old_log_max
;
6907 /* Display the current message in the current mini-buffer. This is
6908 only called from error handlers in process.c, and is not time
6914 if (!NILP (echo_area_buffer
[0]))
6917 string
= Fcurrent_message ();
6918 message3 (string
, SBYTES (string
),
6919 !NILP (current_buffer
->enable_multibyte_characters
));
6924 /* Make sure echo area buffers in `echo_buffers' are live.
6925 If they aren't, make new ones. */
6928 ensure_echo_area_buffers ()
6932 for (i
= 0; i
< 2; ++i
)
6933 if (!BUFFERP (echo_buffer
[i
])
6934 || NILP (XBUFFER (echo_buffer
[i
])->name
))
6937 Lisp_Object old_buffer
;
6940 old_buffer
= echo_buffer
[i
];
6941 sprintf (name
, " *Echo Area %d*", i
);
6942 echo_buffer
[i
] = Fget_buffer_create (build_string (name
));
6943 XBUFFER (echo_buffer
[i
])->truncate_lines
= Qnil
;
6945 for (j
= 0; j
< 2; ++j
)
6946 if (EQ (old_buffer
, echo_area_buffer
[j
]))
6947 echo_area_buffer
[j
] = echo_buffer
[i
];
6952 /* Call FN with args A1..A4 with either the current or last displayed
6953 echo_area_buffer as current buffer.
6955 WHICH zero means use the current message buffer
6956 echo_area_buffer[0]. If that is nil, choose a suitable buffer
6957 from echo_buffer[] and clear it.
6959 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
6960 suitable buffer from echo_buffer[] and clear it.
6962 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
6963 that the current message becomes the last displayed one, make
6964 choose a suitable buffer for echo_area_buffer[0], and clear it.
6966 Value is what FN returns. */
6969 with_echo_area_buffer (w
, which
, fn
, a1
, a2
, a3
, a4
)
6972 int (*fn
) P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
6978 int this_one
, the_other
, clear_buffer_p
, rc
;
6979 int count
= SPECPDL_INDEX ();
6981 /* If buffers aren't live, make new ones. */
6982 ensure_echo_area_buffers ();
6987 this_one
= 0, the_other
= 1;
6989 this_one
= 1, the_other
= 0;
6992 this_one
= 0, the_other
= 1;
6995 /* We need a fresh one in case the current echo buffer equals
6996 the one containing the last displayed echo area message. */
6997 if (!NILP (echo_area_buffer
[this_one
])
6998 && EQ (echo_area_buffer
[this_one
], echo_area_buffer
[the_other
]))
6999 echo_area_buffer
[this_one
] = Qnil
;
7002 /* Choose a suitable buffer from echo_buffer[] is we don't
7004 if (NILP (echo_area_buffer
[this_one
]))
7006 echo_area_buffer
[this_one
]
7007 = (EQ (echo_area_buffer
[the_other
], echo_buffer
[this_one
])
7008 ? echo_buffer
[the_other
]
7009 : echo_buffer
[this_one
]);
7013 buffer
= echo_area_buffer
[this_one
];
7015 /* Don't get confused by reusing the buffer used for echoing
7016 for a different purpose. */
7017 if (echo_kboard
== NULL
&& EQ (buffer
, echo_message_buffer
))
7020 record_unwind_protect (unwind_with_echo_area_buffer
,
7021 with_echo_area_buffer_unwind_data (w
));
7023 /* Make the echo area buffer current. Note that for display
7024 purposes, it is not necessary that the displayed window's buffer
7025 == current_buffer, except for text property lookup. So, let's
7026 only set that buffer temporarily here without doing a full
7027 Fset_window_buffer. We must also change w->pointm, though,
7028 because otherwise an assertions in unshow_buffer fails, and Emacs
7030 set_buffer_internal_1 (XBUFFER (buffer
));
7034 set_marker_both (w
->pointm
, buffer
, BEG
, BEG_BYTE
);
7037 current_buffer
->undo_list
= Qt
;
7038 current_buffer
->read_only
= Qnil
;
7039 specbind (Qinhibit_read_only
, Qt
);
7040 specbind (Qinhibit_modification_hooks
, Qt
);
7042 if (clear_buffer_p
&& Z
> BEG
)
7045 xassert (BEGV
>= BEG
);
7046 xassert (ZV
<= Z
&& ZV
>= BEGV
);
7048 rc
= fn (a1
, a2
, a3
, a4
);
7050 xassert (BEGV
>= BEG
);
7051 xassert (ZV
<= Z
&& ZV
>= BEGV
);
7053 unbind_to (count
, Qnil
);
7058 /* Save state that should be preserved around the call to the function
7059 FN called in with_echo_area_buffer. */
7062 with_echo_area_buffer_unwind_data (w
)
7068 /* Reduce consing by keeping one vector in
7069 Vwith_echo_area_save_vector. */
7070 vector
= Vwith_echo_area_save_vector
;
7071 Vwith_echo_area_save_vector
= Qnil
;
7074 vector
= Fmake_vector (make_number (7), Qnil
);
7076 XSETBUFFER (AREF (vector
, i
), current_buffer
); ++i
;
7077 AREF (vector
, i
) = Vdeactivate_mark
, ++i
;
7078 AREF (vector
, i
) = make_number (windows_or_buffers_changed
), ++i
;
7082 XSETWINDOW (AREF (vector
, i
), w
); ++i
;
7083 AREF (vector
, i
) = w
->buffer
; ++i
;
7084 AREF (vector
, i
) = make_number (XMARKER (w
->pointm
)->charpos
); ++i
;
7085 AREF (vector
, i
) = make_number (XMARKER (w
->pointm
)->bytepos
); ++i
;
7090 for (; i
< end
; ++i
)
7091 AREF (vector
, i
) = Qnil
;
7094 xassert (i
== ASIZE (vector
));
7099 /* Restore global state from VECTOR which was created by
7100 with_echo_area_buffer_unwind_data. */
7103 unwind_with_echo_area_buffer (vector
)
7106 set_buffer_internal_1 (XBUFFER (AREF (vector
, 0)));
7107 Vdeactivate_mark
= AREF (vector
, 1);
7108 windows_or_buffers_changed
= XFASTINT (AREF (vector
, 2));
7110 if (WINDOWP (AREF (vector
, 3)))
7113 Lisp_Object buffer
, charpos
, bytepos
;
7115 w
= XWINDOW (AREF (vector
, 3));
7116 buffer
= AREF (vector
, 4);
7117 charpos
= AREF (vector
, 5);
7118 bytepos
= AREF (vector
, 6);
7121 set_marker_both (w
->pointm
, buffer
,
7122 XFASTINT (charpos
), XFASTINT (bytepos
));
7125 Vwith_echo_area_save_vector
= vector
;
7130 /* Set up the echo area for use by print functions. MULTIBYTE_P
7131 non-zero means we will print multibyte. */
7134 setup_echo_area_for_printing (multibyte_p
)
7137 /* If we can't find an echo area any more, exit. */
7138 if (! FRAME_LIVE_P (XFRAME (selected_frame
)))
7141 ensure_echo_area_buffers ();
7143 if (!message_buf_print
)
7145 /* A message has been output since the last time we printed.
7146 Choose a fresh echo area buffer. */
7147 if (EQ (echo_area_buffer
[1], echo_buffer
[0]))
7148 echo_area_buffer
[0] = echo_buffer
[1];
7150 echo_area_buffer
[0] = echo_buffer
[0];
7152 /* Switch to that buffer and clear it. */
7153 set_buffer_internal (XBUFFER (echo_area_buffer
[0]));
7154 current_buffer
->truncate_lines
= Qnil
;
7158 int count
= SPECPDL_INDEX ();
7159 specbind (Qinhibit_read_only
, Qt
);
7160 /* Note that undo recording is always disabled. */
7162 unbind_to (count
, Qnil
);
7164 TEMP_SET_PT_BOTH (BEG
, BEG_BYTE
);
7166 /* Set up the buffer for the multibyteness we need. */
7168 != !NILP (current_buffer
->enable_multibyte_characters
))
7169 Fset_buffer_multibyte (multibyte_p
? Qt
: Qnil
);
7171 /* Raise the frame containing the echo area. */
7172 if (minibuffer_auto_raise
)
7174 struct frame
*sf
= SELECTED_FRAME ();
7175 Lisp_Object mini_window
;
7176 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
7177 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window
)));
7180 message_log_maybe_newline ();
7181 message_buf_print
= 1;
7185 if (NILP (echo_area_buffer
[0]))
7187 if (EQ (echo_area_buffer
[1], echo_buffer
[0]))
7188 echo_area_buffer
[0] = echo_buffer
[1];
7190 echo_area_buffer
[0] = echo_buffer
[0];
7193 if (current_buffer
!= XBUFFER (echo_area_buffer
[0]))
7195 /* Someone switched buffers between print requests. */
7196 set_buffer_internal (XBUFFER (echo_area_buffer
[0]));
7197 current_buffer
->truncate_lines
= Qnil
;
7203 /* Display an echo area message in window W. Value is non-zero if W's
7204 height is changed. If display_last_displayed_message_p is
7205 non-zero, display the message that was last displayed, otherwise
7206 display the current message. */
7209 display_echo_area (w
)
7212 int i
, no_message_p
, window_height_changed_p
, count
;
7214 /* Temporarily disable garbage collections while displaying the echo
7215 area. This is done because a GC can print a message itself.
7216 That message would modify the echo area buffer's contents while a
7217 redisplay of the buffer is going on, and seriously confuse
7219 count
= inhibit_garbage_collection ();
7221 /* If there is no message, we must call display_echo_area_1
7222 nevertheless because it resizes the window. But we will have to
7223 reset the echo_area_buffer in question to nil at the end because
7224 with_echo_area_buffer will sets it to an empty buffer. */
7225 i
= display_last_displayed_message_p
? 1 : 0;
7226 no_message_p
= NILP (echo_area_buffer
[i
]);
7228 window_height_changed_p
7229 = with_echo_area_buffer (w
, display_last_displayed_message_p
,
7230 display_echo_area_1
,
7231 (EMACS_INT
) w
, Qnil
, 0, 0);
7234 echo_area_buffer
[i
] = Qnil
;
7236 unbind_to (count
, Qnil
);
7237 return window_height_changed_p
;
7241 /* Helper for display_echo_area. Display the current buffer which
7242 contains the current echo area message in window W, a mini-window,
7243 a pointer to which is passed in A1. A2..A4 are currently not used.
7244 Change the height of W so that all of the message is displayed.
7245 Value is non-zero if height of W was changed. */
7248 display_echo_area_1 (a1
, a2
, a3
, a4
)
7253 struct window
*w
= (struct window
*) a1
;
7255 struct text_pos start
;
7256 int window_height_changed_p
= 0;
7258 /* Do this before displaying, so that we have a large enough glyph
7259 matrix for the display. */
7260 window_height_changed_p
= resize_mini_window (w
, 0);
7263 clear_glyph_matrix (w
->desired_matrix
);
7264 XSETWINDOW (window
, w
);
7265 SET_TEXT_POS (start
, BEG
, BEG_BYTE
);
7266 try_window (window
, start
);
7268 return window_height_changed_p
;
7272 /* Resize the echo area window to exactly the size needed for the
7273 currently displayed message, if there is one. If a mini-buffer
7274 is active, don't shrink it. */
7277 resize_echo_area_exactly ()
7279 if (BUFFERP (echo_area_buffer
[0])
7280 && WINDOWP (echo_area_window
))
7282 struct window
*w
= XWINDOW (echo_area_window
);
7284 Lisp_Object resize_exactly
;
7286 if (minibuf_level
== 0)
7287 resize_exactly
= Qt
;
7289 resize_exactly
= Qnil
;
7291 resized_p
= with_echo_area_buffer (w
, 0, resize_mini_window_1
,
7292 (EMACS_INT
) w
, resize_exactly
, 0, 0);
7295 ++windows_or_buffers_changed
;
7296 ++update_mode_lines
;
7297 redisplay_internal (0);
7303 /* Callback function for with_echo_area_buffer, when used from
7304 resize_echo_area_exactly. A1 contains a pointer to the window to
7305 resize, EXACTLY non-nil means resize the mini-window exactly to the
7306 size of the text displayed. A3 and A4 are not used. Value is what
7307 resize_mini_window returns. */
7310 resize_mini_window_1 (a1
, exactly
, a3
, a4
)
7312 Lisp_Object exactly
;
7315 return resize_mini_window ((struct window
*) a1
, !NILP (exactly
));
7319 /* Resize mini-window W to fit the size of its contents. EXACT:P
7320 means size the window exactly to the size needed. Otherwise, it's
7321 only enlarged until W's buffer is empty. Value is non-zero if
7322 the window height has been changed. */
7325 resize_mini_window (w
, exact_p
)
7329 struct frame
*f
= XFRAME (w
->frame
);
7330 int window_height_changed_p
= 0;
7332 xassert (MINI_WINDOW_P (w
));
7334 /* Don't resize windows while redisplaying a window; it would
7335 confuse redisplay functions when the size of the window they are
7336 displaying changes from under them. Such a resizing can happen,
7337 for instance, when which-func prints a long message while
7338 we are running fontification-functions. We're running these
7339 functions with safe_call which binds inhibit-redisplay to t. */
7340 if (!NILP (Vinhibit_redisplay
))
7343 /* Nil means don't try to resize. */
7344 if (NILP (Vresize_mini_windows
)
7345 || (FRAME_X_P (f
) && FRAME_X_OUTPUT (f
) == NULL
))
7348 if (!FRAME_MINIBUF_ONLY_P (f
))
7351 struct window
*root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
7352 int total_height
= WINDOW_TOTAL_LINES (root
) + WINDOW_TOTAL_LINES (w
);
7353 int height
, max_height
;
7354 int unit
= FRAME_LINE_HEIGHT (f
);
7355 struct text_pos start
;
7356 struct buffer
*old_current_buffer
= NULL
;
7358 if (current_buffer
!= XBUFFER (w
->buffer
))
7360 old_current_buffer
= current_buffer
;
7361 set_buffer_internal (XBUFFER (w
->buffer
));
7364 init_iterator (&it
, w
, BEGV
, BEGV_BYTE
, NULL
, DEFAULT_FACE_ID
);
7366 /* Compute the max. number of lines specified by the user. */
7367 if (FLOATP (Vmax_mini_window_height
))
7368 max_height
= XFLOATINT (Vmax_mini_window_height
) * FRAME_LINES (f
);
7369 else if (INTEGERP (Vmax_mini_window_height
))
7370 max_height
= XINT (Vmax_mini_window_height
);
7372 max_height
= total_height
/ 4;
7374 /* Correct that max. height if it's bogus. */
7375 max_height
= max (1, max_height
);
7376 max_height
= min (total_height
, max_height
);
7378 /* Find out the height of the text in the window. */
7379 if (it
.truncate_lines_p
)
7384 move_it_to (&it
, ZV
, -1, -1, -1, MOVE_TO_POS
);
7385 if (it
.max_ascent
== 0 && it
.max_descent
== 0)
7386 height
= it
.current_y
+ last_height
;
7388 height
= it
.current_y
+ it
.max_ascent
+ it
.max_descent
;
7389 height
-= it
.extra_line_spacing
;
7390 height
= (height
+ unit
- 1) / unit
;
7393 /* Compute a suitable window start. */
7394 if (height
> max_height
)
7396 height
= max_height
;
7397 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
7398 move_it_vertically_backward (&it
, (height
- 1) * unit
);
7399 start
= it
.current
.pos
;
7402 SET_TEXT_POS (start
, BEGV
, BEGV_BYTE
);
7403 SET_MARKER_FROM_TEXT_POS (w
->start
, start
);
7405 if (EQ (Vresize_mini_windows
, Qgrow_only
))
7407 /* Let it grow only, until we display an empty message, in which
7408 case the window shrinks again. */
7409 if (height
> WINDOW_TOTAL_LINES (w
))
7411 int old_height
= WINDOW_TOTAL_LINES (w
);
7412 freeze_window_starts (f
, 1);
7413 grow_mini_window (w
, height
- WINDOW_TOTAL_LINES (w
));
7414 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
7416 else if (height
< WINDOW_TOTAL_LINES (w
)
7417 && (exact_p
|| BEGV
== ZV
))
7419 int old_height
= WINDOW_TOTAL_LINES (w
);
7420 freeze_window_starts (f
, 0);
7421 shrink_mini_window (w
);
7422 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
7427 /* Always resize to exact size needed. */
7428 if (height
> WINDOW_TOTAL_LINES (w
))
7430 int old_height
= WINDOW_TOTAL_LINES (w
);
7431 freeze_window_starts (f
, 1);
7432 grow_mini_window (w
, height
- WINDOW_TOTAL_LINES (w
));
7433 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
7435 else if (height
< WINDOW_TOTAL_LINES (w
))
7437 int old_height
= WINDOW_TOTAL_LINES (w
);
7438 freeze_window_starts (f
, 0);
7439 shrink_mini_window (w
);
7443 freeze_window_starts (f
, 1);
7444 grow_mini_window (w
, height
- WINDOW_TOTAL_LINES (w
));
7447 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
7451 if (old_current_buffer
)
7452 set_buffer_internal (old_current_buffer
);
7455 return window_height_changed_p
;
7459 /* Value is the current message, a string, or nil if there is no
7467 if (NILP (echo_area_buffer
[0]))
7471 with_echo_area_buffer (0, 0, current_message_1
,
7472 (EMACS_INT
) &msg
, Qnil
, 0, 0);
7474 echo_area_buffer
[0] = Qnil
;
7482 current_message_1 (a1
, a2
, a3
, a4
)
7487 Lisp_Object
*msg
= (Lisp_Object
*) a1
;
7490 *msg
= make_buffer_string (BEG
, Z
, 1);
7497 /* Push the current message on Vmessage_stack for later restauration
7498 by restore_message. Value is non-zero if the current message isn't
7499 empty. This is a relatively infrequent operation, so it's not
7500 worth optimizing. */
7506 msg
= current_message ();
7507 Vmessage_stack
= Fcons (msg
, Vmessage_stack
);
7508 return STRINGP (msg
);
7512 /* Restore message display from the top of Vmessage_stack. */
7519 xassert (CONSP (Vmessage_stack
));
7520 msg
= XCAR (Vmessage_stack
);
7522 message3_nolog (msg
, SBYTES (msg
), STRING_MULTIBYTE (msg
));
7524 message3_nolog (msg
, 0, 0);
7528 /* Handler for record_unwind_protect calling pop_message. */
7531 pop_message_unwind (dummy
)
7538 /* Pop the top-most entry off Vmessage_stack. */
7543 xassert (CONSP (Vmessage_stack
));
7544 Vmessage_stack
= XCDR (Vmessage_stack
);
7548 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
7549 exits. If the stack is not empty, we have a missing pop_message
7553 check_message_stack ()
7555 if (!NILP (Vmessage_stack
))
7560 /* Truncate to NCHARS what will be displayed in the echo area the next
7561 time we display it---but don't redisplay it now. */
7564 truncate_echo_area (nchars
)
7568 echo_area_buffer
[0] = Qnil
;
7569 /* A null message buffer means that the frame hasn't really been
7570 initialized yet. Error messages get reported properly by
7571 cmd_error, so this must be just an informative message; toss it. */
7572 else if (!noninteractive
7574 && !NILP (echo_area_buffer
[0]))
7576 struct frame
*sf
= SELECTED_FRAME ();
7577 if (FRAME_MESSAGE_BUF (sf
))
7578 with_echo_area_buffer (0, 0, truncate_message_1
, nchars
, Qnil
, 0, 0);
7583 /* Helper function for truncate_echo_area. Truncate the current
7584 message to at most NCHARS characters. */
7587 truncate_message_1 (nchars
, a2
, a3
, a4
)
7592 if (BEG
+ nchars
< Z
)
7593 del_range (BEG
+ nchars
, Z
);
7595 echo_area_buffer
[0] = Qnil
;
7600 /* Set the current message to a substring of S or STRING.
7602 If STRING is a Lisp string, set the message to the first NBYTES
7603 bytes from STRING. NBYTES zero means use the whole string. If
7604 STRING is multibyte, the message will be displayed multibyte.
7606 If S is not null, set the message to the first LEN bytes of S. LEN
7607 zero means use the whole string. MULTIBYTE_P non-zero means S is
7608 multibyte. Display the message multibyte in that case. */
7611 set_message (s
, string
, nbytes
, multibyte_p
)
7614 int nbytes
, multibyte_p
;
7616 message_enable_multibyte
7617 = ((s
&& multibyte_p
)
7618 || (STRINGP (string
) && STRING_MULTIBYTE (string
)));
7620 with_echo_area_buffer (0, -1, set_message_1
,
7621 (EMACS_INT
) s
, string
, nbytes
, multibyte_p
);
7622 message_buf_print
= 0;
7623 help_echo_showing_p
= 0;
7627 /* Helper function for set_message. Arguments have the same meaning
7628 as there, with A1 corresponding to S and A2 corresponding to STRING
7629 This function is called with the echo area buffer being
7633 set_message_1 (a1
, a2
, nbytes
, multibyte_p
)
7636 EMACS_INT nbytes
, multibyte_p
;
7638 const char *s
= (const char *) a1
;
7639 Lisp_Object string
= a2
;
7643 /* Change multibyteness of the echo buffer appropriately. */
7644 if (message_enable_multibyte
7645 != !NILP (current_buffer
->enable_multibyte_characters
))
7646 Fset_buffer_multibyte (message_enable_multibyte
? Qt
: Qnil
);
7648 current_buffer
->truncate_lines
= message_truncate_lines
? Qt
: Qnil
;
7650 /* Insert new message at BEG. */
7651 TEMP_SET_PT_BOTH (BEG
, BEG_BYTE
);
7653 if (STRINGP (string
))
7658 nbytes
= SBYTES (string
);
7659 nchars
= string_byte_to_char (string
, nbytes
);
7661 /* This function takes care of single/multibyte conversion. We
7662 just have to ensure that the echo area buffer has the right
7663 setting of enable_multibyte_characters. */
7664 insert_from_string (string
, 0, 0, nchars
, nbytes
, 1);
7669 nbytes
= strlen (s
);
7671 if (multibyte_p
&& NILP (current_buffer
->enable_multibyte_characters
))
7673 /* Convert from multi-byte to single-byte. */
7675 unsigned char work
[1];
7677 /* Convert a multibyte string to single-byte. */
7678 for (i
= 0; i
< nbytes
; i
+= n
)
7680 c
= string_char_and_length (s
+ i
, nbytes
- i
, &n
);
7681 work
[0] = (SINGLE_BYTE_CHAR_P (c
)
7683 : multibyte_char_to_unibyte (c
, Qnil
));
7684 insert_1_both (work
, 1, 1, 1, 0, 0);
7687 else if (!multibyte_p
7688 && !NILP (current_buffer
->enable_multibyte_characters
))
7690 /* Convert from single-byte to multi-byte. */
7692 const unsigned char *msg
= (const unsigned char *) s
;
7693 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
7695 /* Convert a single-byte string to multibyte. */
7696 for (i
= 0; i
< nbytes
; i
++)
7698 c
= unibyte_char_to_multibyte (msg
[i
]);
7699 n
= CHAR_STRING (c
, str
);
7700 insert_1_both (str
, 1, n
, 1, 0, 0);
7704 insert_1 (s
, nbytes
, 1, 0, 0);
7711 /* Clear messages. CURRENT_P non-zero means clear the current
7712 message. LAST_DISPLAYED_P non-zero means clear the message
7716 clear_message (current_p
, last_displayed_p
)
7717 int current_p
, last_displayed_p
;
7721 echo_area_buffer
[0] = Qnil
;
7722 message_cleared_p
= 1;
7725 if (last_displayed_p
)
7726 echo_area_buffer
[1] = Qnil
;
7728 message_buf_print
= 0;
7731 /* Clear garbaged frames.
7733 This function is used where the old redisplay called
7734 redraw_garbaged_frames which in turn called redraw_frame which in
7735 turn called clear_frame. The call to clear_frame was a source of
7736 flickering. I believe a clear_frame is not necessary. It should
7737 suffice in the new redisplay to invalidate all current matrices,
7738 and ensure a complete redisplay of all windows. */
7741 clear_garbaged_frames ()
7745 Lisp_Object tail
, frame
;
7746 int changed_count
= 0;
7748 FOR_EACH_FRAME (tail
, frame
)
7750 struct frame
*f
= XFRAME (frame
);
7752 if (FRAME_VISIBLE_P (f
) && FRAME_GARBAGED_P (f
))
7756 Fredraw_frame (frame
);
7757 f
->force_flush_display_p
= 1;
7759 clear_current_matrices (f
);
7768 ++windows_or_buffers_changed
;
7773 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
7774 is non-zero update selected_frame. Value is non-zero if the
7775 mini-windows height has been changed. */
7778 echo_area_display (update_frame_p
)
7781 Lisp_Object mini_window
;
7784 int window_height_changed_p
= 0;
7785 struct frame
*sf
= SELECTED_FRAME ();
7787 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
7788 w
= XWINDOW (mini_window
);
7789 f
= XFRAME (WINDOW_FRAME (w
));
7791 /* Don't display if frame is invisible or not yet initialized. */
7792 if (!FRAME_VISIBLE_P (f
) || !f
->glyphs_initialized_p
)
7795 /* The terminal frame is used as the first Emacs frame on the Mac OS. */
7797 #ifdef HAVE_WINDOW_SYSTEM
7798 /* When Emacs starts, selected_frame may be a visible terminal
7799 frame, even if we run under a window system. If we let this
7800 through, a message would be displayed on the terminal. */
7801 if (EQ (selected_frame
, Vterminal_frame
)
7802 && !NILP (Vwindow_system
))
7804 #endif /* HAVE_WINDOW_SYSTEM */
7807 /* Redraw garbaged frames. */
7809 clear_garbaged_frames ();
7811 if (!NILP (echo_area_buffer
[0]) || minibuf_level
== 0)
7813 echo_area_window
= mini_window
;
7814 window_height_changed_p
= display_echo_area (w
);
7815 w
->must_be_updated_p
= 1;
7817 /* Update the display, unless called from redisplay_internal.
7818 Also don't update the screen during redisplay itself. The
7819 update will happen at the end of redisplay, and an update
7820 here could cause confusion. */
7821 if (update_frame_p
&& !redisplaying_p
)
7825 /* If the display update has been interrupted by pending
7826 input, update mode lines in the frame. Due to the
7827 pending input, it might have been that redisplay hasn't
7828 been called, so that mode lines above the echo area are
7829 garbaged. This looks odd, so we prevent it here. */
7830 if (!display_completed
)
7831 n
= redisplay_mode_lines (FRAME_ROOT_WINDOW (f
), 0);
7833 if (window_height_changed_p
7834 /* Don't do this if Emacs is shutting down. Redisplay
7835 needs to run hooks. */
7836 && !NILP (Vrun_hooks
))
7838 /* Must update other windows. Likewise as in other
7839 cases, don't let this update be interrupted by
7841 int count
= SPECPDL_INDEX ();
7842 specbind (Qredisplay_dont_pause
, Qt
);
7843 windows_or_buffers_changed
= 1;
7844 redisplay_internal (0);
7845 unbind_to (count
, Qnil
);
7847 else if (FRAME_WINDOW_P (f
) && n
== 0)
7849 /* Window configuration is the same as before.
7850 Can do with a display update of the echo area,
7851 unless we displayed some mode lines. */
7852 update_single_window (w
, 1);
7853 rif
->flush_display (f
);
7856 update_frame (f
, 1, 1);
7858 /* If cursor is in the echo area, make sure that the next
7859 redisplay displays the minibuffer, so that the cursor will
7860 be replaced with what the minibuffer wants. */
7861 if (cursor_in_echo_area
)
7862 ++windows_or_buffers_changed
;
7865 else if (!EQ (mini_window
, selected_window
))
7866 windows_or_buffers_changed
++;
7868 /* Last displayed message is now the current message. */
7869 echo_area_buffer
[1] = echo_area_buffer
[0];
7871 /* Prevent redisplay optimization in redisplay_internal by resetting
7872 this_line_start_pos. This is done because the mini-buffer now
7873 displays the message instead of its buffer text. */
7874 if (EQ (mini_window
, selected_window
))
7875 CHARPOS (this_line_start_pos
) = 0;
7877 return window_height_changed_p
;
7882 /***********************************************************************
7884 ***********************************************************************/
7887 /* The frame title buffering code is also used by Fformat_mode_line.
7888 So it is not conditioned by HAVE_WINDOW_SYSTEM. */
7890 /* A buffer for constructing frame titles in it; allocated from the
7891 heap in init_xdisp and resized as needed in store_frame_title_char. */
7893 static char *frame_title_buf
;
7895 /* The buffer's end, and a current output position in it. */
7897 static char *frame_title_buf_end
;
7898 static char *frame_title_ptr
;
7901 /* Store a single character C for the frame title in frame_title_buf.
7902 Re-allocate frame_title_buf if necessary. */
7906 store_frame_title_char (char c
)
7908 store_frame_title_char (c
)
7912 /* If output position has reached the end of the allocated buffer,
7913 double the buffer's size. */
7914 if (frame_title_ptr
== frame_title_buf_end
)
7916 int len
= frame_title_ptr
- frame_title_buf
;
7917 int new_size
= 2 * len
* sizeof *frame_title_buf
;
7918 frame_title_buf
= (char *) xrealloc (frame_title_buf
, new_size
);
7919 frame_title_buf_end
= frame_title_buf
+ new_size
;
7920 frame_title_ptr
= frame_title_buf
+ len
;
7923 *frame_title_ptr
++ = c
;
7927 /* Store part of a frame title in frame_title_buf, beginning at
7928 frame_title_ptr. STR is the string to store. Do not copy
7929 characters that yield more columns than PRECISION; PRECISION <= 0
7930 means copy the whole string. Pad with spaces until FIELD_WIDTH
7931 number of characters have been copied; FIELD_WIDTH <= 0 means don't
7932 pad. Called from display_mode_element when it is used to build a
7936 store_frame_title (str
, field_width
, precision
)
7937 const unsigned char *str
;
7938 int field_width
, precision
;
7943 /* Copy at most PRECISION chars from STR. */
7944 nbytes
= strlen (str
);
7945 n
+= c_string_width (str
, nbytes
, precision
, &dummy
, &nbytes
);
7947 store_frame_title_char (*str
++);
7949 /* Fill up with spaces until FIELD_WIDTH reached. */
7950 while (field_width
> 0
7953 store_frame_title_char (' ');
7960 #ifdef HAVE_WINDOW_SYSTEM
7962 /* Set the title of FRAME, if it has changed. The title format is
7963 Vicon_title_format if FRAME is iconified, otherwise it is
7964 frame_title_format. */
7967 x_consider_frame_title (frame
)
7970 struct frame
*f
= XFRAME (frame
);
7972 if (FRAME_WINDOW_P (f
)
7973 || FRAME_MINIBUF_ONLY_P (f
)
7974 || f
->explicit_name
)
7976 /* Do we have more than one visible frame on this X display? */
7979 struct buffer
*obuf
;
7983 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCDR (tail
))
7985 Lisp_Object other_frame
= XCAR (tail
);
7986 struct frame
*tf
= XFRAME (other_frame
);
7989 && FRAME_KBOARD (tf
) == FRAME_KBOARD (f
)
7990 && !FRAME_MINIBUF_ONLY_P (tf
)
7991 && !EQ (other_frame
, tip_frame
)
7992 && (FRAME_VISIBLE_P (tf
) || FRAME_ICONIFIED_P (tf
)))
7996 /* Set global variable indicating that multiple frames exist. */
7997 multiple_frames
= CONSP (tail
);
7999 /* Switch to the buffer of selected window of the frame. Set up
8000 frame_title_ptr so that display_mode_element will output into it;
8001 then display the title. */
8002 obuf
= current_buffer
;
8003 set_buffer_internal_1 (XBUFFER (XWINDOW (f
->selected_window
)->buffer
));
8004 fmt
= FRAME_ICONIFIED_P (f
) ? Vicon_title_format
: Vframe_title_format
;
8005 frame_title_ptr
= frame_title_buf
;
8006 init_iterator (&it
, XWINDOW (f
->selected_window
), -1, -1,
8007 NULL
, DEFAULT_FACE_ID
);
8008 display_mode_element (&it
, 0, -1, -1, fmt
, Qnil
, 0);
8009 len
= frame_title_ptr
- frame_title_buf
;
8010 frame_title_ptr
= NULL
;
8011 set_buffer_internal_1 (obuf
);
8013 /* Set the title only if it's changed. This avoids consing in
8014 the common case where it hasn't. (If it turns out that we've
8015 already wasted too much time by walking through the list with
8016 display_mode_element, then we might need to optimize at a
8017 higher level than this.) */
8018 if (! STRINGP (f
->name
)
8019 || SBYTES (f
->name
) != len
8020 || bcmp (frame_title_buf
, SDATA (f
->name
), len
) != 0)
8021 x_implicitly_set_name (f
, make_string (frame_title_buf
, len
), Qnil
);
8025 #endif /* not HAVE_WINDOW_SYSTEM */
8030 /***********************************************************************
8032 ***********************************************************************/
8035 /* Prepare for redisplay by updating menu-bar item lists when
8036 appropriate. This can call eval. */
8039 prepare_menu_bars ()
8042 struct gcpro gcpro1
, gcpro2
;
8044 Lisp_Object tooltip_frame
;
8046 #ifdef HAVE_WINDOW_SYSTEM
8047 tooltip_frame
= tip_frame
;
8049 tooltip_frame
= Qnil
;
8052 /* Update all frame titles based on their buffer names, etc. We do
8053 this before the menu bars so that the buffer-menu will show the
8054 up-to-date frame titles. */
8055 #ifdef HAVE_WINDOW_SYSTEM
8056 if (windows_or_buffers_changed
|| update_mode_lines
)
8058 Lisp_Object tail
, frame
;
8060 FOR_EACH_FRAME (tail
, frame
)
8063 if (!EQ (frame
, tooltip_frame
)
8064 && (FRAME_VISIBLE_P (f
) || FRAME_ICONIFIED_P (f
)))
8065 x_consider_frame_title (frame
);
8068 #endif /* HAVE_WINDOW_SYSTEM */
8070 /* Update the menu bar item lists, if appropriate. This has to be
8071 done before any actual redisplay or generation of display lines. */
8072 all_windows
= (update_mode_lines
8073 || buffer_shared
> 1
8074 || windows_or_buffers_changed
);
8077 Lisp_Object tail
, frame
;
8078 int count
= SPECPDL_INDEX ();
8080 record_unwind_protect (Fset_match_data
, Fmatch_data (Qnil
, Qnil
));
8082 FOR_EACH_FRAME (tail
, frame
)
8086 /* Ignore tooltip frame. */
8087 if (EQ (frame
, tooltip_frame
))
8090 /* If a window on this frame changed size, report that to
8091 the user and clear the size-change flag. */
8092 if (FRAME_WINDOW_SIZES_CHANGED (f
))
8094 Lisp_Object functions
;
8096 /* Clear flag first in case we get an error below. */
8097 FRAME_WINDOW_SIZES_CHANGED (f
) = 0;
8098 functions
= Vwindow_size_change_functions
;
8099 GCPRO2 (tail
, functions
);
8101 while (CONSP (functions
))
8103 call1 (XCAR (functions
), frame
);
8104 functions
= XCDR (functions
);
8110 update_menu_bar (f
, 0);
8111 #ifdef HAVE_WINDOW_SYSTEM
8112 update_tool_bar (f
, 0);
8117 unbind_to (count
, Qnil
);
8121 struct frame
*sf
= SELECTED_FRAME ();
8122 update_menu_bar (sf
, 1);
8123 #ifdef HAVE_WINDOW_SYSTEM
8124 update_tool_bar (sf
, 1);
8128 /* Motif needs this. See comment in xmenu.c. Turn it off when
8129 pending_menu_activation is not defined. */
8130 #ifdef USE_X_TOOLKIT
8131 pending_menu_activation
= 0;
8136 /* Update the menu bar item list for frame F. This has to be done
8137 before we start to fill in any display lines, because it can call
8140 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
8143 update_menu_bar (f
, save_match_data
)
8145 int save_match_data
;
8148 register struct window
*w
;
8150 /* If called recursively during a menu update, do nothing. This can
8151 happen when, for instance, an activate-menubar-hook causes a
8153 if (inhibit_menubar_update
)
8156 window
= FRAME_SELECTED_WINDOW (f
);
8157 w
= XWINDOW (window
);
8159 #if 0 /* The if statement below this if statement used to include the
8160 condition !NILP (w->update_mode_line), rather than using
8161 update_mode_lines directly, and this if statement may have
8162 been added to make that condition work. Now the if
8163 statement below matches its comment, this isn't needed. */
8164 if (update_mode_lines
)
8165 w
->update_mode_line
= Qt
;
8168 if (FRAME_WINDOW_P (f
)
8170 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8171 || defined (USE_GTK)
8172 FRAME_EXTERNAL_MENU_BAR (f
)
8174 FRAME_MENU_BAR_LINES (f
) > 0
8176 : FRAME_MENU_BAR_LINES (f
) > 0)
8178 /* If the user has switched buffers or windows, we need to
8179 recompute to reflect the new bindings. But we'll
8180 recompute when update_mode_lines is set too; that means
8181 that people can use force-mode-line-update to request
8182 that the menu bar be recomputed. The adverse effect on
8183 the rest of the redisplay algorithm is about the same as
8184 windows_or_buffers_changed anyway. */
8185 if (windows_or_buffers_changed
8186 /* This used to test w->update_mode_line, but we believe
8187 there is no need to recompute the menu in that case. */
8188 || update_mode_lines
8189 || ((BUF_SAVE_MODIFF (XBUFFER (w
->buffer
))
8190 < BUF_MODIFF (XBUFFER (w
->buffer
)))
8191 != !NILP (w
->last_had_star
))
8192 || ((!NILP (Vtransient_mark_mode
)
8193 && !NILP (XBUFFER (w
->buffer
)->mark_active
))
8194 != !NILP (w
->region_showing
)))
8196 struct buffer
*prev
= current_buffer
;
8197 int count
= SPECPDL_INDEX ();
8199 specbind (Qinhibit_menubar_update
, Qt
);
8201 set_buffer_internal_1 (XBUFFER (w
->buffer
));
8202 if (save_match_data
)
8203 record_unwind_protect (Fset_match_data
, Fmatch_data (Qnil
, Qnil
));
8204 if (NILP (Voverriding_local_map_menu_flag
))
8206 specbind (Qoverriding_terminal_local_map
, Qnil
);
8207 specbind (Qoverriding_local_map
, Qnil
);
8210 /* Run the Lucid hook. */
8211 safe_run_hooks (Qactivate_menubar_hook
);
8213 /* If it has changed current-menubar from previous value,
8214 really recompute the menu-bar from the value. */
8215 if (! NILP (Vlucid_menu_bar_dirty_flag
))
8216 call0 (Qrecompute_lucid_menubar
);
8218 safe_run_hooks (Qmenu_bar_update_hook
);
8219 FRAME_MENU_BAR_ITEMS (f
) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f
));
8221 /* Redisplay the menu bar in case we changed it. */
8222 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8223 || defined (USE_GTK)
8224 if (FRAME_WINDOW_P (f
)
8225 #if defined (MAC_OS)
8226 /* All frames on Mac OS share the same menubar. So only the
8227 selected frame should be allowed to set it. */
8228 && f
== SELECTED_FRAME ()
8231 set_frame_menubar (f
, 0, 0);
8233 /* On a terminal screen, the menu bar is an ordinary screen
8234 line, and this makes it get updated. */
8235 w
->update_mode_line
= Qt
;
8236 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8237 /* In the non-toolkit version, the menu bar is an ordinary screen
8238 line, and this makes it get updated. */
8239 w
->update_mode_line
= Qt
;
8240 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8242 unbind_to (count
, Qnil
);
8243 set_buffer_internal_1 (prev
);
8250 /***********************************************************************
8252 ***********************************************************************/
8254 #ifdef HAVE_WINDOW_SYSTEM
8257 Nominal cursor position -- where to draw output.
8258 HPOS and VPOS are window relative glyph matrix coordinates.
8259 X and Y are window relative pixel coordinates. */
8261 struct cursor_pos output_cursor
;
8265 Set the global variable output_cursor to CURSOR. All cursor
8266 positions are relative to updated_window. */
8269 set_output_cursor (cursor
)
8270 struct cursor_pos
*cursor
;
8272 output_cursor
.hpos
= cursor
->hpos
;
8273 output_cursor
.vpos
= cursor
->vpos
;
8274 output_cursor
.x
= cursor
->x
;
8275 output_cursor
.y
= cursor
->y
;
8280 Set a nominal cursor position.
8282 HPOS and VPOS are column/row positions in a window glyph matrix. X
8283 and Y are window text area relative pixel positions.
8285 If this is done during an update, updated_window will contain the
8286 window that is being updated and the position is the future output
8287 cursor position for that window. If updated_window is null, use
8288 selected_window and display the cursor at the given position. */
8291 x_cursor_to (vpos
, hpos
, y
, x
)
8292 int vpos
, hpos
, y
, x
;
8296 /* If updated_window is not set, work on selected_window. */
8300 w
= XWINDOW (selected_window
);
8302 /* Set the output cursor. */
8303 output_cursor
.hpos
= hpos
;
8304 output_cursor
.vpos
= vpos
;
8305 output_cursor
.x
= x
;
8306 output_cursor
.y
= y
;
8308 /* If not called as part of an update, really display the cursor.
8309 This will also set the cursor position of W. */
8310 if (updated_window
== NULL
)
8313 display_and_set_cursor (w
, 1, hpos
, vpos
, x
, y
);
8314 if (rif
->flush_display_optional
)
8315 rif
->flush_display_optional (SELECTED_FRAME ());
8320 #endif /* HAVE_WINDOW_SYSTEM */
8323 /***********************************************************************
8325 ***********************************************************************/
8327 #ifdef HAVE_WINDOW_SYSTEM
8329 /* Where the mouse was last time we reported a mouse event. */
8331 FRAME_PTR last_mouse_frame
;
8333 /* Tool-bar item index of the item on which a mouse button was pressed
8336 int last_tool_bar_item
;
8339 /* Update the tool-bar item list for frame F. This has to be done
8340 before we start to fill in any display lines. Called from
8341 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
8342 and restore it here. */
8345 update_tool_bar (f
, save_match_data
)
8347 int save_match_data
;
8350 int do_update
= FRAME_EXTERNAL_TOOL_BAR (f
);
8352 int do_update
= WINDOWP (f
->tool_bar_window
)
8353 && WINDOW_TOTAL_LINES (XWINDOW (f
->tool_bar_window
)) > 0;
8361 window
= FRAME_SELECTED_WINDOW (f
);
8362 w
= XWINDOW (window
);
8364 /* If the user has switched buffers or windows, we need to
8365 recompute to reflect the new bindings. But we'll
8366 recompute when update_mode_lines is set too; that means
8367 that people can use force-mode-line-update to request
8368 that the menu bar be recomputed. The adverse effect on
8369 the rest of the redisplay algorithm is about the same as
8370 windows_or_buffers_changed anyway. */
8371 if (windows_or_buffers_changed
8372 || !NILP (w
->update_mode_line
)
8373 || update_mode_lines
8374 || ((BUF_SAVE_MODIFF (XBUFFER (w
->buffer
))
8375 < BUF_MODIFF (XBUFFER (w
->buffer
)))
8376 != !NILP (w
->last_had_star
))
8377 || ((!NILP (Vtransient_mark_mode
)
8378 && !NILP (XBUFFER (w
->buffer
)->mark_active
))
8379 != !NILP (w
->region_showing
)))
8381 struct buffer
*prev
= current_buffer
;
8382 int count
= SPECPDL_INDEX ();
8383 Lisp_Object old_tool_bar
;
8384 struct gcpro gcpro1
;
8386 /* Set current_buffer to the buffer of the selected
8387 window of the frame, so that we get the right local
8389 set_buffer_internal_1 (XBUFFER (w
->buffer
));
8391 /* Save match data, if we must. */
8392 if (save_match_data
)
8393 record_unwind_protect (Fset_match_data
, Fmatch_data (Qnil
, Qnil
));
8395 /* Make sure that we don't accidentally use bogus keymaps. */
8396 if (NILP (Voverriding_local_map_menu_flag
))
8398 specbind (Qoverriding_terminal_local_map
, Qnil
);
8399 specbind (Qoverriding_local_map
, Qnil
);
8402 old_tool_bar
= f
->tool_bar_items
;
8403 GCPRO1 (old_tool_bar
);
8405 /* Build desired tool-bar items from keymaps. */
8408 = tool_bar_items (f
->tool_bar_items
, &f
->n_tool_bar_items
);
8411 /* Redisplay the tool-bar if we changed it. */
8412 if (! NILP (Fequal (old_tool_bar
, f
->tool_bar_items
)))
8413 w
->update_mode_line
= Qt
;
8417 unbind_to (count
, Qnil
);
8418 set_buffer_internal_1 (prev
);
8424 /* Set F->desired_tool_bar_string to a Lisp string representing frame
8425 F's desired tool-bar contents. F->tool_bar_items must have
8426 been set up previously by calling prepare_menu_bars. */
8429 build_desired_tool_bar_string (f
)
8432 int i
, size
, size_needed
;
8433 struct gcpro gcpro1
, gcpro2
, gcpro3
;
8434 Lisp_Object image
, plist
, props
;
8436 image
= plist
= props
= Qnil
;
8437 GCPRO3 (image
, plist
, props
);
8439 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
8440 Otherwise, make a new string. */
8442 /* The size of the string we might be able to reuse. */
8443 size
= (STRINGP (f
->desired_tool_bar_string
)
8444 ? SCHARS (f
->desired_tool_bar_string
)
8447 /* We need one space in the string for each image. */
8448 size_needed
= f
->n_tool_bar_items
;
8450 /* Reuse f->desired_tool_bar_string, if possible. */
8451 if (size
< size_needed
|| NILP (f
->desired_tool_bar_string
))
8452 f
->desired_tool_bar_string
= Fmake_string (make_number (size_needed
),
8456 props
= list4 (Qdisplay
, Qnil
, Qmenu_item
, Qnil
);
8457 Fremove_text_properties (make_number (0), make_number (size
),
8458 props
, f
->desired_tool_bar_string
);
8461 /* Put a `display' property on the string for the images to display,
8462 put a `menu_item' property on tool-bar items with a value that
8463 is the index of the item in F's tool-bar item vector. */
8464 for (i
= 0; i
< f
->n_tool_bar_items
; ++i
)
8466 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
8468 int enabled_p
= !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P
));
8469 int selected_p
= !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P
));
8470 int hmargin
, vmargin
, relief
, idx
, end
;
8471 extern Lisp_Object QCrelief
, QCmargin
, QCconversion
;
8473 /* If image is a vector, choose the image according to the
8475 image
= PROP (TOOL_BAR_ITEM_IMAGES
);
8476 if (VECTORP (image
))
8480 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
8481 : TOOL_BAR_IMAGE_ENABLED_DESELECTED
);
8484 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
8485 : TOOL_BAR_IMAGE_DISABLED_DESELECTED
);
8487 xassert (ASIZE (image
) >= idx
);
8488 image
= AREF (image
, idx
);
8493 /* Ignore invalid image specifications. */
8494 if (!valid_image_p (image
))
8497 /* Display the tool-bar button pressed, or depressed. */
8498 plist
= Fcopy_sequence (XCDR (image
));
8500 /* Compute margin and relief to draw. */
8501 relief
= (tool_bar_button_relief
>= 0
8502 ? tool_bar_button_relief
8503 : DEFAULT_TOOL_BAR_BUTTON_RELIEF
);
8504 hmargin
= vmargin
= relief
;
8506 if (INTEGERP (Vtool_bar_button_margin
)
8507 && XINT (Vtool_bar_button_margin
) > 0)
8509 hmargin
+= XFASTINT (Vtool_bar_button_margin
);
8510 vmargin
+= XFASTINT (Vtool_bar_button_margin
);
8512 else if (CONSP (Vtool_bar_button_margin
))
8514 if (INTEGERP (XCAR (Vtool_bar_button_margin
))
8515 && XINT (XCAR (Vtool_bar_button_margin
)) > 0)
8516 hmargin
+= XFASTINT (XCAR (Vtool_bar_button_margin
));
8518 if (INTEGERP (XCDR (Vtool_bar_button_margin
))
8519 && XINT (XCDR (Vtool_bar_button_margin
)) > 0)
8520 vmargin
+= XFASTINT (XCDR (Vtool_bar_button_margin
));
8523 if (auto_raise_tool_bar_buttons_p
)
8525 /* Add a `:relief' property to the image spec if the item is
8529 plist
= Fplist_put (plist
, QCrelief
, make_number (-relief
));
8536 /* If image is selected, display it pressed, i.e. with a
8537 negative relief. If it's not selected, display it with a
8539 plist
= Fplist_put (plist
, QCrelief
,
8541 ? make_number (-relief
)
8542 : make_number (relief
)));
8547 /* Put a margin around the image. */
8548 if (hmargin
|| vmargin
)
8550 if (hmargin
== vmargin
)
8551 plist
= Fplist_put (plist
, QCmargin
, make_number (hmargin
));
8553 plist
= Fplist_put (plist
, QCmargin
,
8554 Fcons (make_number (hmargin
),
8555 make_number (vmargin
)));
8558 /* If button is not enabled, and we don't have special images
8559 for the disabled state, make the image appear disabled by
8560 applying an appropriate algorithm to it. */
8561 if (!enabled_p
&& idx
< 0)
8562 plist
= Fplist_put (plist
, QCconversion
, Qdisabled
);
8564 /* Put a `display' text property on the string for the image to
8565 display. Put a `menu-item' property on the string that gives
8566 the start of this item's properties in the tool-bar items
8568 image
= Fcons (Qimage
, plist
);
8569 props
= list4 (Qdisplay
, image
,
8570 Qmenu_item
, make_number (i
* TOOL_BAR_ITEM_NSLOTS
));
8572 /* Let the last image hide all remaining spaces in the tool bar
8573 string. The string can be longer than needed when we reuse a
8575 if (i
+ 1 == f
->n_tool_bar_items
)
8576 end
= SCHARS (f
->desired_tool_bar_string
);
8579 Fadd_text_properties (make_number (i
), make_number (end
),
8580 props
, f
->desired_tool_bar_string
);
8588 /* Display one line of the tool-bar of frame IT->f. */
8591 display_tool_bar_line (it
)
8594 struct glyph_row
*row
= it
->glyph_row
;
8595 int max_x
= it
->last_visible_x
;
8598 prepare_desired_row (row
);
8599 row
->y
= it
->current_y
;
8601 /* Note that this isn't made use of if the face hasn't a box,
8602 so there's no need to check the face here. */
8603 it
->start_of_box_run_p
= 1;
8605 while (it
->current_x
< max_x
)
8607 int x_before
, x
, n_glyphs_before
, i
, nglyphs
;
8609 /* Get the next display element. */
8610 if (!get_next_display_element (it
))
8613 /* Produce glyphs. */
8614 x_before
= it
->current_x
;
8615 n_glyphs_before
= it
->glyph_row
->used
[TEXT_AREA
];
8616 PRODUCE_GLYPHS (it
);
8618 nglyphs
= it
->glyph_row
->used
[TEXT_AREA
] - n_glyphs_before
;
8623 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
8625 if (x
+ glyph
->pixel_width
> max_x
)
8627 /* Glyph doesn't fit on line. */
8628 it
->glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
+ i
;
8634 x
+= glyph
->pixel_width
;
8638 /* Stop at line ends. */
8639 if (ITERATOR_AT_END_OF_LINE_P (it
))
8642 set_iterator_to_next (it
, 1);
8647 row
->displays_text_p
= row
->used
[TEXT_AREA
] != 0;
8648 extend_face_to_end_of_line (it
);
8649 last
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
] - 1;
8650 last
->right_box_line_p
= 1;
8651 if (last
== row
->glyphs
[TEXT_AREA
])
8652 last
->left_box_line_p
= 1;
8653 compute_line_metrics (it
);
8655 /* If line is empty, make it occupy the rest of the tool-bar. */
8656 if (!row
->displays_text_p
)
8658 row
->height
= row
->phys_height
= it
->last_visible_y
- row
->y
;
8659 row
->ascent
= row
->phys_ascent
= 0;
8662 row
->full_width_p
= 1;
8663 row
->continued_p
= 0;
8664 row
->truncated_on_left_p
= 0;
8665 row
->truncated_on_right_p
= 0;
8667 it
->current_x
= it
->hpos
= 0;
8668 it
->current_y
+= row
->height
;
8674 /* Value is the number of screen lines needed to make all tool-bar
8675 items of frame F visible. */
8678 tool_bar_lines_needed (f
)
8681 struct window
*w
= XWINDOW (f
->tool_bar_window
);
8684 /* Initialize an iterator for iteration over
8685 F->desired_tool_bar_string in the tool-bar window of frame F. */
8686 init_iterator (&it
, w
, -1, -1, w
->desired_matrix
->rows
, TOOL_BAR_FACE_ID
);
8687 it
.first_visible_x
= 0;
8688 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
8689 reseat_to_string (&it
, NULL
, f
->desired_tool_bar_string
, 0, 0, 0, -1);
8691 while (!ITERATOR_AT_END_P (&it
))
8693 it
.glyph_row
= w
->desired_matrix
->rows
;
8694 clear_glyph_row (it
.glyph_row
);
8695 display_tool_bar_line (&it
);
8698 return (it
.current_y
+ FRAME_LINE_HEIGHT (f
) - 1) / FRAME_LINE_HEIGHT (f
);
8702 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed
, Stool_bar_lines_needed
,
8704 doc
: /* Return the number of lines occupied by the tool bar of FRAME. */)
8713 frame
= selected_frame
;
8715 CHECK_FRAME (frame
);
8718 if (WINDOWP (f
->tool_bar_window
)
8719 || (w
= XWINDOW (f
->tool_bar_window
),
8720 WINDOW_TOTAL_LINES (w
) > 0))
8722 update_tool_bar (f
, 1);
8723 if (f
->n_tool_bar_items
)
8725 build_desired_tool_bar_string (f
);
8726 nlines
= tool_bar_lines_needed (f
);
8730 return make_number (nlines
);
8734 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
8735 height should be changed. */
8738 redisplay_tool_bar (f
)
8743 struct glyph_row
*row
;
8744 int change_height_p
= 0;
8747 if (FRAME_EXTERNAL_TOOL_BAR (f
))
8748 update_frame_tool_bar (f
);
8752 /* If frame hasn't a tool-bar window or if it is zero-height, don't
8753 do anything. This means you must start with tool-bar-lines
8754 non-zero to get the auto-sizing effect. Or in other words, you
8755 can turn off tool-bars by specifying tool-bar-lines zero. */
8756 if (!WINDOWP (f
->tool_bar_window
)
8757 || (w
= XWINDOW (f
->tool_bar_window
),
8758 WINDOW_TOTAL_LINES (w
) == 0))
8761 /* Set up an iterator for the tool-bar window. */
8762 init_iterator (&it
, w
, -1, -1, w
->desired_matrix
->rows
, TOOL_BAR_FACE_ID
);
8763 it
.first_visible_x
= 0;
8764 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
8767 /* Build a string that represents the contents of the tool-bar. */
8768 build_desired_tool_bar_string (f
);
8769 reseat_to_string (&it
, NULL
, f
->desired_tool_bar_string
, 0, 0, 0, -1);
8771 /* Display as many lines as needed to display all tool-bar items. */
8772 while (it
.current_y
< it
.last_visible_y
)
8773 display_tool_bar_line (&it
);
8775 /* It doesn't make much sense to try scrolling in the tool-bar
8776 window, so don't do it. */
8777 w
->desired_matrix
->no_scrolling_p
= 1;
8778 w
->must_be_updated_p
= 1;
8780 if (auto_resize_tool_bars_p
)
8784 /* If we couldn't display everything, change the tool-bar's
8786 if (IT_STRING_CHARPOS (it
) < it
.end_charpos
)
8787 change_height_p
= 1;
8789 /* If there are blank lines at the end, except for a partially
8790 visible blank line at the end that is smaller than
8791 FRAME_LINE_HEIGHT, change the tool-bar's height. */
8792 row
= it
.glyph_row
- 1;
8793 if (!row
->displays_text_p
8794 && row
->height
>= FRAME_LINE_HEIGHT (f
))
8795 change_height_p
= 1;
8797 /* If row displays tool-bar items, but is partially visible,
8798 change the tool-bar's height. */
8799 if (row
->displays_text_p
8800 && MATRIX_ROW_BOTTOM_Y (row
) > it
.last_visible_y
)
8801 change_height_p
= 1;
8803 /* Resize windows as needed by changing the `tool-bar-lines'
8806 && (nlines
= tool_bar_lines_needed (f
),
8807 nlines
!= WINDOW_TOTAL_LINES (w
)))
8809 extern Lisp_Object Qtool_bar_lines
;
8811 int old_height
= WINDOW_TOTAL_LINES (w
);
8813 XSETFRAME (frame
, f
);
8814 clear_glyph_matrix (w
->desired_matrix
);
8815 Fmodify_frame_parameters (frame
,
8816 Fcons (Fcons (Qtool_bar_lines
,
8817 make_number (nlines
)),
8819 if (WINDOW_TOTAL_LINES (w
) != old_height
)
8820 fonts_changed_p
= 1;
8824 return change_height_p
;
8828 /* Get information about the tool-bar item which is displayed in GLYPH
8829 on frame F. Return in *PROP_IDX the index where tool-bar item
8830 properties start in F->tool_bar_items. Value is zero if
8831 GLYPH doesn't display a tool-bar item. */
8834 tool_bar_item_info (f
, glyph
, prop_idx
)
8836 struct glyph
*glyph
;
8843 /* This function can be called asynchronously, which means we must
8844 exclude any possibility that Fget_text_property signals an
8846 charpos
= min (SCHARS (f
->current_tool_bar_string
), glyph
->charpos
);
8847 charpos
= max (0, charpos
);
8849 /* Get the text property `menu-item' at pos. The value of that
8850 property is the start index of this item's properties in
8851 F->tool_bar_items. */
8852 prop
= Fget_text_property (make_number (charpos
),
8853 Qmenu_item
, f
->current_tool_bar_string
);
8854 if (INTEGERP (prop
))
8856 *prop_idx
= XINT (prop
);
8866 /* Get information about the tool-bar item at position X/Y on frame F.
8867 Return in *GLYPH a pointer to the glyph of the tool-bar item in
8868 the current matrix of the tool-bar window of F, or NULL if not
8869 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
8870 item in F->tool_bar_items. Value is
8872 -1 if X/Y is not on a tool-bar item
8873 0 if X/Y is on the same item that was highlighted before.
8877 get_tool_bar_item (f
, x
, y
, glyph
, hpos
, vpos
, prop_idx
)
8880 struct glyph
**glyph
;
8881 int *hpos
, *vpos
, *prop_idx
;
8883 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
8884 struct window
*w
= XWINDOW (f
->tool_bar_window
);
8887 /* Find the glyph under X/Y. */
8888 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, 0, 0, &area
);
8892 /* Get the start of this tool-bar item's properties in
8893 f->tool_bar_items. */
8894 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
8897 /* Is mouse on the highlighted item? */
8898 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
8899 && *vpos
>= dpyinfo
->mouse_face_beg_row
8900 && *vpos
<= dpyinfo
->mouse_face_end_row
8901 && (*vpos
> dpyinfo
->mouse_face_beg_row
8902 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
8903 && (*vpos
< dpyinfo
->mouse_face_end_row
8904 || *hpos
< dpyinfo
->mouse_face_end_col
8905 || dpyinfo
->mouse_face_past_end
))
8913 Handle mouse button event on the tool-bar of frame F, at
8914 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
8915 0 for button release. MODIFIERS is event modifiers for button
8919 handle_tool_bar_click (f
, x
, y
, down_p
, modifiers
)
8922 unsigned int modifiers
;
8924 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
8925 struct window
*w
= XWINDOW (f
->tool_bar_window
);
8926 int hpos
, vpos
, prop_idx
;
8927 struct glyph
*glyph
;
8928 Lisp_Object enabled_p
;
8930 /* If not on the highlighted tool-bar item, return. */
8931 frame_to_window_pixel_xy (w
, &x
, &y
);
8932 if (get_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
8935 /* If item is disabled, do nothing. */
8936 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
8937 if (NILP (enabled_p
))
8942 /* Show item in pressed state. */
8943 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
8944 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
8945 last_tool_bar_item
= prop_idx
;
8949 Lisp_Object key
, frame
;
8950 struct input_event event
;
8953 /* Show item in released state. */
8954 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
8955 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
8957 key
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_KEY
);
8959 XSETFRAME (frame
, f
);
8960 event
.kind
= TOOL_BAR_EVENT
;
8961 event
.frame_or_window
= frame
;
8963 kbd_buffer_store_event (&event
);
8965 event
.kind
= TOOL_BAR_EVENT
;
8966 event
.frame_or_window
= frame
;
8968 event
.modifiers
= modifiers
;
8969 kbd_buffer_store_event (&event
);
8970 last_tool_bar_item
= -1;
8975 /* Possibly highlight a tool-bar item on frame F when mouse moves to
8976 tool-bar window-relative coordinates X/Y. Called from
8977 note_mouse_highlight. */
8980 note_tool_bar_highlight (f
, x
, y
)
8984 Lisp_Object window
= f
->tool_bar_window
;
8985 struct window
*w
= XWINDOW (window
);
8986 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
8988 struct glyph
*glyph
;
8989 struct glyph_row
*row
;
8991 Lisp_Object enabled_p
;
8993 enum draw_glyphs_face draw
= DRAW_IMAGE_RAISED
;
8994 int mouse_down_p
, rc
;
8996 /* Function note_mouse_highlight is called with negative x(y
8997 values when mouse moves outside of the frame. */
8998 if (x
<= 0 || y
<= 0)
9000 clear_mouse_face (dpyinfo
);
9004 rc
= get_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
9007 /* Not on tool-bar item. */
9008 clear_mouse_face (dpyinfo
);
9012 /* On same tool-bar item as before. */
9015 clear_mouse_face (dpyinfo
);
9017 /* Mouse is down, but on different tool-bar item? */
9018 mouse_down_p
= (dpyinfo
->grabbed
9019 && f
== last_mouse_frame
9020 && FRAME_LIVE_P (f
));
9022 && last_tool_bar_item
!= prop_idx
)
9025 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
9026 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
9028 /* If tool-bar item is not enabled, don't highlight it. */
9029 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
9030 if (!NILP (enabled_p
))
9032 /* Compute the x-position of the glyph. In front and past the
9033 image is a space. We include this in the highlighted area. */
9034 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
9035 for (i
= x
= 0; i
< hpos
; ++i
)
9036 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
9038 /* Record this as the current active region. */
9039 dpyinfo
->mouse_face_beg_col
= hpos
;
9040 dpyinfo
->mouse_face_beg_row
= vpos
;
9041 dpyinfo
->mouse_face_beg_x
= x
;
9042 dpyinfo
->mouse_face_beg_y
= row
->y
;
9043 dpyinfo
->mouse_face_past_end
= 0;
9045 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
9046 dpyinfo
->mouse_face_end_row
= vpos
;
9047 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
9048 dpyinfo
->mouse_face_end_y
= row
->y
;
9049 dpyinfo
->mouse_face_window
= window
;
9050 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
9052 /* Display it as active. */
9053 show_mouse_face (dpyinfo
, draw
);
9054 dpyinfo
->mouse_face_image_state
= draw
;
9059 /* Set help_echo_string to a help string to display for this tool-bar item.
9060 XTread_socket does the rest. */
9061 help_echo_object
= help_echo_window
= Qnil
;
9063 help_echo_string
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_HELP
);
9064 if (NILP (help_echo_string
))
9065 help_echo_string
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_CAPTION
);
9068 #endif /* HAVE_WINDOW_SYSTEM */
9072 /************************************************************************
9073 Horizontal scrolling
9074 ************************************************************************/
9076 static int hscroll_window_tree
P_ ((Lisp_Object
));
9077 static int hscroll_windows
P_ ((Lisp_Object
));
9079 /* For all leaf windows in the window tree rooted at WINDOW, set their
9080 hscroll value so that PT is (i) visible in the window, and (ii) so
9081 that it is not within a certain margin at the window's left and
9082 right border. Value is non-zero if any window's hscroll has been
9086 hscroll_window_tree (window
)
9089 int hscrolled_p
= 0;
9090 int hscroll_relative_p
= FLOATP (Vhscroll_step
);
9091 int hscroll_step_abs
= 0;
9092 double hscroll_step_rel
= 0;
9094 if (hscroll_relative_p
)
9096 hscroll_step_rel
= XFLOAT_DATA (Vhscroll_step
);
9097 if (hscroll_step_rel
< 0)
9099 hscroll_relative_p
= 0;
9100 hscroll_step_abs
= 0;
9103 else if (INTEGERP (Vhscroll_step
))
9105 hscroll_step_abs
= XINT (Vhscroll_step
);
9106 if (hscroll_step_abs
< 0)
9107 hscroll_step_abs
= 0;
9110 hscroll_step_abs
= 0;
9112 while (WINDOWP (window
))
9114 struct window
*w
= XWINDOW (window
);
9116 if (WINDOWP (w
->hchild
))
9117 hscrolled_p
|= hscroll_window_tree (w
->hchild
);
9118 else if (WINDOWP (w
->vchild
))
9119 hscrolled_p
|= hscroll_window_tree (w
->vchild
);
9120 else if (w
->cursor
.vpos
>= 0)
9123 int text_area_width
;
9124 struct glyph_row
*current_cursor_row
9125 = MATRIX_ROW (w
->current_matrix
, w
->cursor
.vpos
);
9126 struct glyph_row
*desired_cursor_row
9127 = MATRIX_ROW (w
->desired_matrix
, w
->cursor
.vpos
);
9128 struct glyph_row
*cursor_row
9129 = (desired_cursor_row
->enabled_p
9130 ? desired_cursor_row
9131 : current_cursor_row
);
9133 text_area_width
= window_box_width (w
, TEXT_AREA
);
9135 /* Scroll when cursor is inside this scroll margin. */
9136 h_margin
= hscroll_margin
* WINDOW_FRAME_COLUMN_WIDTH (w
);
9138 if ((XFASTINT (w
->hscroll
)
9139 && w
->cursor
.x
<= h_margin
)
9140 || (cursor_row
->enabled_p
9141 && cursor_row
->truncated_on_right_p
9142 && (w
->cursor
.x
>= text_area_width
- h_margin
)))
9146 struct buffer
*saved_current_buffer
;
9150 /* Find point in a display of infinite width. */
9151 saved_current_buffer
= current_buffer
;
9152 current_buffer
= XBUFFER (w
->buffer
);
9154 if (w
== XWINDOW (selected_window
))
9155 pt
= BUF_PT (current_buffer
);
9158 pt
= marker_position (w
->pointm
);
9159 pt
= max (BEGV
, pt
);
9163 /* Move iterator to pt starting at cursor_row->start in
9164 a line with infinite width. */
9165 init_to_row_start (&it
, w
, cursor_row
);
9166 it
.last_visible_x
= INFINITY
;
9167 move_it_in_display_line_to (&it
, pt
, -1, MOVE_TO_POS
);
9168 current_buffer
= saved_current_buffer
;
9170 /* Position cursor in window. */
9171 if (!hscroll_relative_p
&& hscroll_step_abs
== 0)
9172 hscroll
= max (0, (it
.current_x
9173 - (ITERATOR_AT_END_OF_LINE_P (&it
)
9174 ? (text_area_width
- 4 * FRAME_COLUMN_WIDTH (it
.f
))
9175 : (text_area_width
/ 2))))
9176 / FRAME_COLUMN_WIDTH (it
.f
);
9177 else if (w
->cursor
.x
>= text_area_width
- h_margin
)
9179 if (hscroll_relative_p
)
9180 wanted_x
= text_area_width
* (1 - hscroll_step_rel
)
9183 wanted_x
= text_area_width
9184 - hscroll_step_abs
* FRAME_COLUMN_WIDTH (it
.f
)
9187 = max (0, it
.current_x
- wanted_x
) / FRAME_COLUMN_WIDTH (it
.f
);
9191 if (hscroll_relative_p
)
9192 wanted_x
= text_area_width
* hscroll_step_rel
9195 wanted_x
= hscroll_step_abs
* FRAME_COLUMN_WIDTH (it
.f
)
9198 = max (0, it
.current_x
- wanted_x
) / FRAME_COLUMN_WIDTH (it
.f
);
9200 hscroll
= max (hscroll
, XFASTINT (w
->min_hscroll
));
9202 /* Don't call Fset_window_hscroll if value hasn't
9203 changed because it will prevent redisplay
9205 if (XFASTINT (w
->hscroll
) != hscroll
)
9207 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
9208 w
->hscroll
= make_number (hscroll
);
9217 /* Value is non-zero if hscroll of any leaf window has been changed. */
9222 /* Set hscroll so that cursor is visible and not inside horizontal
9223 scroll margins for all windows in the tree rooted at WINDOW. See
9224 also hscroll_window_tree above. Value is non-zero if any window's
9225 hscroll has been changed. If it has, desired matrices on the frame
9226 of WINDOW are cleared. */
9229 hscroll_windows (window
)
9234 if (automatic_hscrolling_p
)
9236 hscrolled_p
= hscroll_window_tree (window
);
9238 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window
))));
9247 /************************************************************************
9249 ************************************************************************/
9251 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
9252 to a non-zero value. This is sometimes handy to have in a debugger
9257 /* First and last unchanged row for try_window_id. */
9259 int debug_first_unchanged_at_end_vpos
;
9260 int debug_last_unchanged_at_beg_vpos
;
9262 /* Delta vpos and y. */
9264 int debug_dvpos
, debug_dy
;
9266 /* Delta in characters and bytes for try_window_id. */
9268 int debug_delta
, debug_delta_bytes
;
9270 /* Values of window_end_pos and window_end_vpos at the end of
9273 EMACS_INT debug_end_pos
, debug_end_vpos
;
9275 /* Append a string to W->desired_matrix->method. FMT is a printf
9276 format string. A1...A9 are a supplement for a variable-length
9277 argument list. If trace_redisplay_p is non-zero also printf the
9278 resulting string to stderr. */
9281 debug_method_add (w
, fmt
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
)
9284 int a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
;
9287 char *method
= w
->desired_matrix
->method
;
9288 int len
= strlen (method
);
9289 int size
= sizeof w
->desired_matrix
->method
;
9290 int remaining
= size
- len
- 1;
9292 sprintf (buffer
, fmt
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
);
9293 if (len
&& remaining
)
9299 strncpy (method
+ len
, buffer
, remaining
);
9301 if (trace_redisplay_p
)
9302 fprintf (stderr
, "%p (%s): %s\n",
9304 ((BUFFERP (w
->buffer
)
9305 && STRINGP (XBUFFER (w
->buffer
)->name
))
9306 ? (char *) SDATA (XBUFFER (w
->buffer
)->name
)
9311 #endif /* GLYPH_DEBUG */
9314 /* Value is non-zero if all changes in window W, which displays
9315 current_buffer, are in the text between START and END. START is a
9316 buffer position, END is given as a distance from Z. Used in
9317 redisplay_internal for display optimization. */
9320 text_outside_line_unchanged_p (w
, start
, end
)
9324 int unchanged_p
= 1;
9326 /* If text or overlays have changed, see where. */
9327 if (XFASTINT (w
->last_modified
) < MODIFF
9328 || XFASTINT (w
->last_overlay_modified
) < OVERLAY_MODIFF
)
9330 /* Gap in the line? */
9331 if (GPT
< start
|| Z
- GPT
< end
)
9334 /* Changes start in front of the line, or end after it? */
9336 && (BEG_UNCHANGED
< start
- 1
9337 || END_UNCHANGED
< end
))
9340 /* If selective display, can't optimize if changes start at the
9341 beginning of the line. */
9343 && INTEGERP (current_buffer
->selective_display
)
9344 && XINT (current_buffer
->selective_display
) > 0
9345 && (BEG_UNCHANGED
< start
|| GPT
<= start
))
9348 /* If there are overlays at the start or end of the line, these
9349 may have overlay strings with newlines in them. A change at
9350 START, for instance, may actually concern the display of such
9351 overlay strings as well, and they are displayed on different
9352 lines. So, quickly rule out this case. (For the future, it
9353 might be desirable to implement something more telling than
9354 just BEG/END_UNCHANGED.) */
9357 if (BEG
+ BEG_UNCHANGED
== start
9358 && overlay_touches_p (start
))
9360 if (END_UNCHANGED
== end
9361 && overlay_touches_p (Z
- end
))
9370 /* Do a frame update, taking possible shortcuts into account. This is
9371 the main external entry point for redisplay.
9373 If the last redisplay displayed an echo area message and that message
9374 is no longer requested, we clear the echo area or bring back the
9375 mini-buffer if that is in use. */
9380 redisplay_internal (0);
9385 overlay_arrow_string_or_property (var
, pbitmap
)
9389 Lisp_Object pstr
= Fget (var
, Qoverlay_arrow_string
);
9395 if (bitmap
= Fget (var
, Qoverlay_arrow_bitmap
), INTEGERP (bitmap
))
9396 *pbitmap
= XINT (bitmap
);
9401 return Voverlay_arrow_string
;
9404 /* Return 1 if there are any overlay-arrows in current_buffer. */
9406 overlay_arrow_in_current_buffer_p ()
9410 for (vlist
= Voverlay_arrow_variable_list
;
9412 vlist
= XCDR (vlist
))
9414 Lisp_Object var
= XCAR (vlist
);
9419 val
= find_symbol_value (var
);
9421 && current_buffer
== XMARKER (val
)->buffer
)
9428 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
9432 overlay_arrows_changed_p ()
9436 for (vlist
= Voverlay_arrow_variable_list
;
9438 vlist
= XCDR (vlist
))
9440 Lisp_Object var
= XCAR (vlist
);
9441 Lisp_Object val
, pstr
;
9445 val
= find_symbol_value (var
);
9448 if (! EQ (COERCE_MARKER (val
),
9449 Fget (var
, Qlast_arrow_position
))
9450 || ! (pstr
= overlay_arrow_string_or_property (var
, 0),
9451 EQ (pstr
, Fget (var
, Qlast_arrow_string
))))
9457 /* Mark overlay arrows to be updated on next redisplay. */
9460 update_overlay_arrows (up_to_date
)
9465 for (vlist
= Voverlay_arrow_variable_list
;
9467 vlist
= XCDR (vlist
))
9469 Lisp_Object var
= XCAR (vlist
);
9476 Lisp_Object val
= find_symbol_value (var
);
9477 Fput (var
, Qlast_arrow_position
,
9478 COERCE_MARKER (val
));
9479 Fput (var
, Qlast_arrow_string
,
9480 overlay_arrow_string_or_property (var
, 0));
9482 else if (up_to_date
< 0
9483 || !NILP (Fget (var
, Qlast_arrow_position
)))
9485 Fput (var
, Qlast_arrow_position
, Qt
);
9486 Fput (var
, Qlast_arrow_string
, Qt
);
9492 /* Return overlay arrow string at row, or nil. */
9495 overlay_arrow_at_row (f
, row
, pbitmap
)
9497 struct glyph_row
*row
;
9502 for (vlist
= Voverlay_arrow_variable_list
;
9504 vlist
= XCDR (vlist
))
9506 Lisp_Object var
= XCAR (vlist
);
9512 val
= find_symbol_value (var
);
9515 && current_buffer
== XMARKER (val
)->buffer
9516 && (MATRIX_ROW_START_CHARPOS (row
) == marker_position (val
)))
9518 val
= overlay_arrow_string_or_property (var
, pbitmap
);
9519 if (FRAME_WINDOW_P (f
))
9521 else if (STRINGP (val
))
9531 /* Return 1 if point moved out of or into a composition. Otherwise
9532 return 0. PREV_BUF and PREV_PT are the last point buffer and
9533 position. BUF and PT are the current point buffer and position. */
9536 check_point_in_composition (prev_buf
, prev_pt
, buf
, pt
)
9537 struct buffer
*prev_buf
, *buf
;
9544 XSETBUFFER (buffer
, buf
);
9545 /* Check a composition at the last point if point moved within the
9547 if (prev_buf
== buf
)
9550 /* Point didn't move. */
9553 if (prev_pt
> BUF_BEGV (buf
) && prev_pt
< BUF_ZV (buf
)
9554 && find_composition (prev_pt
, -1, &start
, &end
, &prop
, buffer
)
9555 && COMPOSITION_VALID_P (start
, end
, prop
)
9556 && start
< prev_pt
&& end
> prev_pt
)
9557 /* The last point was within the composition. Return 1 iff
9558 point moved out of the composition. */
9559 return (pt
<= start
|| pt
>= end
);
9562 /* Check a composition at the current point. */
9563 return (pt
> BUF_BEGV (buf
) && pt
< BUF_ZV (buf
)
9564 && find_composition (pt
, -1, &start
, &end
, &prop
, buffer
)
9565 && COMPOSITION_VALID_P (start
, end
, prop
)
9566 && start
< pt
&& end
> pt
);
9570 /* Reconsider the setting of B->clip_changed which is displayed
9574 reconsider_clip_changes (w
, b
)
9579 && !NILP (w
->window_end_valid
)
9580 && w
->current_matrix
->buffer
== b
9581 && w
->current_matrix
->zv
== BUF_ZV (b
)
9582 && w
->current_matrix
->begv
== BUF_BEGV (b
))
9583 b
->clip_changed
= 0;
9585 /* If display wasn't paused, and W is not a tool bar window, see if
9586 point has been moved into or out of a composition. In that case,
9587 we set b->clip_changed to 1 to force updating the screen. If
9588 b->clip_changed has already been set to 1, we can skip this
9590 if (!b
->clip_changed
9591 && BUFFERP (w
->buffer
) && !NILP (w
->window_end_valid
))
9595 if (w
== XWINDOW (selected_window
))
9596 pt
= BUF_PT (current_buffer
);
9598 pt
= marker_position (w
->pointm
);
9600 if ((w
->current_matrix
->buffer
!= XBUFFER (w
->buffer
)
9601 || pt
!= XINT (w
->last_point
))
9602 && check_point_in_composition (w
->current_matrix
->buffer
,
9603 XINT (w
->last_point
),
9604 XBUFFER (w
->buffer
), pt
))
9605 b
->clip_changed
= 1;
9610 /* Select FRAME to forward the values of frame-local variables into C
9611 variables so that the redisplay routines can access those values
9615 select_frame_for_redisplay (frame
)
9618 Lisp_Object tail
, sym
, val
;
9619 Lisp_Object old
= selected_frame
;
9621 selected_frame
= frame
;
9623 for (tail
= XFRAME (frame
)->param_alist
; CONSP (tail
); tail
= XCDR (tail
))
9624 if (CONSP (XCAR (tail
))
9625 && (sym
= XCAR (XCAR (tail
)),
9627 && (sym
= indirect_variable (sym
),
9628 val
= SYMBOL_VALUE (sym
),
9629 (BUFFER_LOCAL_VALUEP (val
)
9630 || SOME_BUFFER_LOCAL_VALUEP (val
)))
9631 && XBUFFER_LOCAL_VALUE (val
)->check_frame
)
9632 Fsymbol_value (sym
);
9634 for (tail
= XFRAME (old
)->param_alist
; CONSP (tail
); tail
= XCDR (tail
))
9635 if (CONSP (XCAR (tail
))
9636 && (sym
= XCAR (XCAR (tail
)),
9638 && (sym
= indirect_variable (sym
),
9639 val
= SYMBOL_VALUE (sym
),
9640 (BUFFER_LOCAL_VALUEP (val
)
9641 || SOME_BUFFER_LOCAL_VALUEP (val
)))
9642 && XBUFFER_LOCAL_VALUE (val
)->check_frame
)
9643 Fsymbol_value (sym
);
9647 #define STOP_POLLING \
9648 do { if (! polling_stopped_here) stop_polling (); \
9649 polling_stopped_here = 1; } while (0)
9651 #define RESUME_POLLING \
9652 do { if (polling_stopped_here) start_polling (); \
9653 polling_stopped_here = 0; } while (0)
9656 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
9657 response to any user action; therefore, we should preserve the echo
9658 area. (Actually, our caller does that job.) Perhaps in the future
9659 avoid recentering windows if it is not necessary; currently that
9660 causes some problems. */
9663 redisplay_internal (preserve_echo_area
)
9664 int preserve_echo_area
;
9666 struct window
*w
= XWINDOW (selected_window
);
9667 struct frame
*f
= XFRAME (w
->frame
);
9669 int must_finish
= 0;
9670 struct text_pos tlbufpos
, tlendpos
;
9671 int number_of_visible_frames
;
9673 struct frame
*sf
= SELECTED_FRAME ();
9674 int polling_stopped_here
= 0;
9676 /* Non-zero means redisplay has to consider all windows on all
9677 frames. Zero means, only selected_window is considered. */
9678 int consider_all_windows_p
;
9680 TRACE ((stderr
, "redisplay_internal %d\n", redisplaying_p
));
9682 /* No redisplay if running in batch mode or frame is not yet fully
9683 initialized, or redisplay is explicitly turned off by setting
9684 Vinhibit_redisplay. */
9686 || !NILP (Vinhibit_redisplay
)
9687 || !f
->glyphs_initialized_p
)
9690 /* The flag redisplay_performed_directly_p is set by
9691 direct_output_for_insert when it already did the whole screen
9692 update necessary. */
9693 if (redisplay_performed_directly_p
)
9695 redisplay_performed_directly_p
= 0;
9696 if (!hscroll_windows (selected_window
))
9700 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
9701 if (popup_activated ())
9705 /* I don't think this happens but let's be paranoid. */
9709 /* Record a function that resets redisplaying_p to its old value
9710 when we leave this function. */
9711 count
= SPECPDL_INDEX ();
9712 record_unwind_protect (unwind_redisplay
,
9713 Fcons (make_number (redisplaying_p
), selected_frame
));
9715 specbind (Qinhibit_free_realized_faces
, Qnil
);
9719 reconsider_clip_changes (w
, current_buffer
);
9721 /* If new fonts have been loaded that make a glyph matrix adjustment
9722 necessary, do it. */
9723 if (fonts_changed_p
)
9725 adjust_glyphs (NULL
);
9726 ++windows_or_buffers_changed
;
9727 fonts_changed_p
= 0;
9730 /* If face_change_count is non-zero, init_iterator will free all
9731 realized faces, which includes the faces referenced from current
9732 matrices. So, we can't reuse current matrices in this case. */
9733 if (face_change_count
)
9734 ++windows_or_buffers_changed
;
9736 if (! FRAME_WINDOW_P (sf
)
9737 && previous_terminal_frame
!= sf
)
9739 /* Since frames on an ASCII terminal share the same display
9740 area, displaying a different frame means redisplay the whole
9742 windows_or_buffers_changed
++;
9743 SET_FRAME_GARBAGED (sf
);
9744 XSETFRAME (Vterminal_frame
, sf
);
9746 previous_terminal_frame
= sf
;
9748 /* Set the visible flags for all frames. Do this before checking
9749 for resized or garbaged frames; they want to know if their frames
9750 are visible. See the comment in frame.h for
9751 FRAME_SAMPLE_VISIBILITY. */
9753 Lisp_Object tail
, frame
;
9755 number_of_visible_frames
= 0;
9757 FOR_EACH_FRAME (tail
, frame
)
9759 struct frame
*f
= XFRAME (frame
);
9761 FRAME_SAMPLE_VISIBILITY (f
);
9762 if (FRAME_VISIBLE_P (f
))
9763 ++number_of_visible_frames
;
9764 clear_desired_matrices (f
);
9768 /* Notice any pending interrupt request to change frame size. */
9769 do_pending_window_change (1);
9771 /* Clear frames marked as garbaged. */
9773 clear_garbaged_frames ();
9775 /* Build menubar and tool-bar items. */
9776 prepare_menu_bars ();
9778 if (windows_or_buffers_changed
)
9779 update_mode_lines
++;
9781 /* Detect case that we need to write or remove a star in the mode line. */
9782 if ((SAVE_MODIFF
< MODIFF
) != !NILP (w
->last_had_star
))
9784 w
->update_mode_line
= Qt
;
9785 if (buffer_shared
> 1)
9786 update_mode_lines
++;
9789 /* If %c is in the mode line, update it if needed. */
9790 if (!NILP (w
->column_number_displayed
)
9791 /* This alternative quickly identifies a common case
9792 where no change is needed. */
9793 && !(PT
== XFASTINT (w
->last_point
)
9794 && XFASTINT (w
->last_modified
) >= MODIFF
9795 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
)
9796 && (XFASTINT (w
->column_number_displayed
)
9797 != (int) current_column ())) /* iftc */
9798 w
->update_mode_line
= Qt
;
9800 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w
->frame
)) = -1;
9802 /* The variable buffer_shared is set in redisplay_window and
9803 indicates that we redisplay a buffer in different windows. See
9805 consider_all_windows_p
= (update_mode_lines
|| buffer_shared
> 1
9806 || cursor_type_changed
);
9808 /* If specs for an arrow have changed, do thorough redisplay
9809 to ensure we remove any arrow that should no longer exist. */
9810 if (overlay_arrows_changed_p ())
9811 consider_all_windows_p
= windows_or_buffers_changed
= 1;
9813 /* Normally the message* functions will have already displayed and
9814 updated the echo area, but the frame may have been trashed, or
9815 the update may have been preempted, so display the echo area
9816 again here. Checking message_cleared_p captures the case that
9817 the echo area should be cleared. */
9818 if ((!NILP (echo_area_buffer
[0]) && !display_last_displayed_message_p
)
9819 || (!NILP (echo_area_buffer
[1]) && display_last_displayed_message_p
)
9820 || (message_cleared_p
9821 && minibuf_level
== 0
9822 /* If the mini-window is currently selected, this means the
9823 echo-area doesn't show through. */
9824 && !MINI_WINDOW_P (XWINDOW (selected_window
))))
9826 int window_height_changed_p
= echo_area_display (0);
9829 /* If we don't display the current message, don't clear the
9830 message_cleared_p flag, because, if we did, we wouldn't clear
9831 the echo area in the next redisplay which doesn't preserve
9833 if (!display_last_displayed_message_p
)
9834 message_cleared_p
= 0;
9836 if (fonts_changed_p
)
9838 else if (window_height_changed_p
)
9840 consider_all_windows_p
= 1;
9841 ++update_mode_lines
;
9842 ++windows_or_buffers_changed
;
9844 /* If window configuration was changed, frames may have been
9845 marked garbaged. Clear them or we will experience
9846 surprises wrt scrolling. */
9848 clear_garbaged_frames ();
9851 else if (EQ (selected_window
, minibuf_window
)
9852 && (current_buffer
->clip_changed
9853 || XFASTINT (w
->last_modified
) < MODIFF
9854 || XFASTINT (w
->last_overlay_modified
) < OVERLAY_MODIFF
)
9855 && resize_mini_window (w
, 0))
9857 /* Resized active mini-window to fit the size of what it is
9858 showing if its contents might have changed. */
9860 consider_all_windows_p
= 1;
9861 ++windows_or_buffers_changed
;
9862 ++update_mode_lines
;
9864 /* If window configuration was changed, frames may have been
9865 marked garbaged. Clear them or we will experience
9866 surprises wrt scrolling. */
9868 clear_garbaged_frames ();
9872 /* If showing the region, and mark has changed, we must redisplay
9873 the whole window. The assignment to this_line_start_pos prevents
9874 the optimization directly below this if-statement. */
9875 if (((!NILP (Vtransient_mark_mode
)
9876 && !NILP (XBUFFER (w
->buffer
)->mark_active
))
9877 != !NILP (w
->region_showing
))
9878 || (!NILP (w
->region_showing
)
9879 && !EQ (w
->region_showing
,
9880 Fmarker_position (XBUFFER (w
->buffer
)->mark
))))
9881 CHARPOS (this_line_start_pos
) = 0;
9883 /* Optimize the case that only the line containing the cursor in the
9884 selected window has changed. Variables starting with this_ are
9885 set in display_line and record information about the line
9886 containing the cursor. */
9887 tlbufpos
= this_line_start_pos
;
9888 tlendpos
= this_line_end_pos
;
9889 if (!consider_all_windows_p
9890 && CHARPOS (tlbufpos
) > 0
9891 && NILP (w
->update_mode_line
)
9892 && !current_buffer
->clip_changed
9893 && !current_buffer
->prevent_redisplay_optimizations_p
9894 && FRAME_VISIBLE_P (XFRAME (w
->frame
))
9895 && !FRAME_OBSCURED_P (XFRAME (w
->frame
))
9896 /* Make sure recorded data applies to current buffer, etc. */
9897 && this_line_buffer
== current_buffer
9898 && current_buffer
== XBUFFER (w
->buffer
)
9899 && NILP (w
->force_start
)
9900 && NILP (w
->optional_new_start
)
9901 /* Point must be on the line that we have info recorded about. */
9902 && PT
>= CHARPOS (tlbufpos
)
9903 && PT
<= Z
- CHARPOS (tlendpos
)
9904 /* All text outside that line, including its final newline,
9905 must be unchanged */
9906 && text_outside_line_unchanged_p (w
, CHARPOS (tlbufpos
),
9907 CHARPOS (tlendpos
)))
9909 if (CHARPOS (tlbufpos
) > BEGV
9910 && FETCH_BYTE (BYTEPOS (tlbufpos
) - 1) != '\n'
9911 && (CHARPOS (tlbufpos
) == ZV
9912 || FETCH_BYTE (BYTEPOS (tlbufpos
)) == '\n'))
9913 /* Former continuation line has disappeared by becoming empty */
9915 else if (XFASTINT (w
->last_modified
) < MODIFF
9916 || XFASTINT (w
->last_overlay_modified
) < OVERLAY_MODIFF
9917 || MINI_WINDOW_P (w
))
9919 /* We have to handle the case of continuation around a
9920 wide-column character (See the comment in indent.c around
9923 For instance, in the following case:
9925 -------- Insert --------
9926 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
9927 J_I_ ==> J_I_ `^^' are cursors.
9931 As we have to redraw the line above, we should goto cancel. */
9934 int line_height_before
= this_line_pixel_height
;
9936 /* Note that start_display will handle the case that the
9937 line starting at tlbufpos is a continuation lines. */
9938 start_display (&it
, w
, tlbufpos
);
9940 /* Implementation note: It this still necessary? */
9941 if (it
.current_x
!= this_line_start_x
)
9944 TRACE ((stderr
, "trying display optimization 1\n"));
9945 w
->cursor
.vpos
= -1;
9946 overlay_arrow_seen
= 0;
9947 it
.vpos
= this_line_vpos
;
9948 it
.current_y
= this_line_y
;
9949 it
.glyph_row
= MATRIX_ROW (w
->desired_matrix
, this_line_vpos
);
9952 /* If line contains point, is not continued,
9953 and ends at same distance from eob as before, we win */
9954 if (w
->cursor
.vpos
>= 0
9955 /* Line is not continued, otherwise this_line_start_pos
9956 would have been set to 0 in display_line. */
9957 && CHARPOS (this_line_start_pos
)
9958 /* Line ends as before. */
9959 && CHARPOS (this_line_end_pos
) == CHARPOS (tlendpos
)
9960 /* Line has same height as before. Otherwise other lines
9961 would have to be shifted up or down. */
9962 && this_line_pixel_height
== line_height_before
)
9964 /* If this is not the window's last line, we must adjust
9965 the charstarts of the lines below. */
9966 if (it
.current_y
< it
.last_visible_y
)
9968 struct glyph_row
*row
9969 = MATRIX_ROW (w
->current_matrix
, this_line_vpos
+ 1);
9970 int delta
, delta_bytes
;
9972 if (Z
- CHARPOS (tlendpos
) == ZV
)
9974 /* This line ends at end of (accessible part of)
9975 buffer. There is no newline to count. */
9977 - CHARPOS (tlendpos
)
9978 - MATRIX_ROW_START_CHARPOS (row
));
9979 delta_bytes
= (Z_BYTE
9980 - BYTEPOS (tlendpos
)
9981 - MATRIX_ROW_START_BYTEPOS (row
));
9985 /* This line ends in a newline. Must take
9986 account of the newline and the rest of the
9987 text that follows. */
9989 - CHARPOS (tlendpos
)
9990 - MATRIX_ROW_START_CHARPOS (row
));
9991 delta_bytes
= (Z_BYTE
9992 - BYTEPOS (tlendpos
)
9993 - MATRIX_ROW_START_BYTEPOS (row
));
9996 increment_matrix_positions (w
->current_matrix
,
9998 w
->current_matrix
->nrows
,
9999 delta
, delta_bytes
);
10002 /* If this row displays text now but previously didn't,
10003 or vice versa, w->window_end_vpos may have to be
10005 if ((it
.glyph_row
- 1)->displays_text_p
)
10007 if (XFASTINT (w
->window_end_vpos
) < this_line_vpos
)
10008 XSETINT (w
->window_end_vpos
, this_line_vpos
);
10010 else if (XFASTINT (w
->window_end_vpos
) == this_line_vpos
10011 && this_line_vpos
> 0)
10012 XSETINT (w
->window_end_vpos
, this_line_vpos
- 1);
10013 w
->window_end_valid
= Qnil
;
10015 /* Update hint: No need to try to scroll in update_window. */
10016 w
->desired_matrix
->no_scrolling_p
= 1;
10019 *w
->desired_matrix
->method
= 0;
10020 debug_method_add (w
, "optimization 1");
10022 #ifdef HAVE_WINDOW_SYSTEM
10023 update_window_fringes (w
, 0);
10030 else if (/* Cursor position hasn't changed. */
10031 PT
== XFASTINT (w
->last_point
)
10032 /* Make sure the cursor was last displayed
10033 in this window. Otherwise we have to reposition it. */
10034 && 0 <= w
->cursor
.vpos
10035 && WINDOW_TOTAL_LINES (w
) > w
->cursor
.vpos
)
10039 do_pending_window_change (1);
10041 /* We used to always goto end_of_redisplay here, but this
10042 isn't enough if we have a blinking cursor. */
10043 if (w
->cursor_off_p
== w
->last_cursor_off_p
)
10044 goto end_of_redisplay
;
10048 /* If highlighting the region, or if the cursor is in the echo area,
10049 then we can't just move the cursor. */
10050 else if (! (!NILP (Vtransient_mark_mode
)
10051 && !NILP (current_buffer
->mark_active
))
10052 && (EQ (selected_window
, current_buffer
->last_selected_window
)
10053 || highlight_nonselected_windows
)
10054 && NILP (w
->region_showing
)
10055 && NILP (Vshow_trailing_whitespace
)
10056 && !cursor_in_echo_area
)
10059 struct glyph_row
*row
;
10061 /* Skip from tlbufpos to PT and see where it is. Note that
10062 PT may be in invisible text. If so, we will end at the
10063 next visible position. */
10064 init_iterator (&it
, w
, CHARPOS (tlbufpos
), BYTEPOS (tlbufpos
),
10065 NULL
, DEFAULT_FACE_ID
);
10066 it
.current_x
= this_line_start_x
;
10067 it
.current_y
= this_line_y
;
10068 it
.vpos
= this_line_vpos
;
10070 /* The call to move_it_to stops in front of PT, but
10071 moves over before-strings. */
10072 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
10074 if (it
.vpos
== this_line_vpos
10075 && (row
= MATRIX_ROW (w
->current_matrix
, this_line_vpos
),
10078 xassert (this_line_vpos
== it
.vpos
);
10079 xassert (this_line_y
== it
.current_y
);
10080 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
10082 *w
->desired_matrix
->method
= 0;
10083 debug_method_add (w
, "optimization 3");
10092 /* Text changed drastically or point moved off of line. */
10093 SET_MATRIX_ROW_ENABLED_P (w
->desired_matrix
, this_line_vpos
, 0);
10096 CHARPOS (this_line_start_pos
) = 0;
10097 consider_all_windows_p
|= buffer_shared
> 1;
10098 ++clear_face_cache_count
;
10101 /* Build desired matrices, and update the display. If
10102 consider_all_windows_p is non-zero, do it for all windows on all
10103 frames. Otherwise do it for selected_window, only. */
10105 if (consider_all_windows_p
)
10107 Lisp_Object tail
, frame
;
10108 int i
, n
= 0, size
= 50;
10109 struct frame
**updated
10110 = (struct frame
**) alloca (size
* sizeof *updated
);
10112 /* Clear the face cache eventually. */
10113 if (clear_face_cache_count
> CLEAR_FACE_CACHE_COUNT
)
10115 clear_face_cache (0);
10116 clear_face_cache_count
= 0;
10119 /* Recompute # windows showing selected buffer. This will be
10120 incremented each time such a window is displayed. */
10123 FOR_EACH_FRAME (tail
, frame
)
10125 struct frame
*f
= XFRAME (frame
);
10127 if (FRAME_WINDOW_P (f
) || f
== sf
)
10129 if (! EQ (frame
, selected_frame
))
10130 /* Select the frame, for the sake of frame-local
10132 select_frame_for_redisplay (frame
);
10134 #ifdef HAVE_WINDOW_SYSTEM
10135 if (clear_face_cache_count
% 50 == 0
10136 && FRAME_WINDOW_P (f
))
10137 clear_image_cache (f
, 0);
10138 #endif /* HAVE_WINDOW_SYSTEM */
10140 /* Mark all the scroll bars to be removed; we'll redeem
10141 the ones we want when we redisplay their windows. */
10142 if (condemn_scroll_bars_hook
)
10143 condemn_scroll_bars_hook (f
);
10145 if (FRAME_VISIBLE_P (f
) && !FRAME_OBSCURED_P (f
))
10146 redisplay_windows (FRAME_ROOT_WINDOW (f
));
10148 /* Any scroll bars which redisplay_windows should have
10149 nuked should now go away. */
10150 if (judge_scroll_bars_hook
)
10151 judge_scroll_bars_hook (f
);
10153 /* If fonts changed, display again. */
10154 /* ??? rms: I suspect it is a mistake to jump all the way
10155 back to retry here. It should just retry this frame. */
10156 if (fonts_changed_p
)
10159 if (FRAME_VISIBLE_P (f
) && !FRAME_OBSCURED_P (f
))
10161 /* See if we have to hscroll. */
10162 if (hscroll_windows (f
->root_window
))
10165 /* Prevent various kinds of signals during display
10166 update. stdio is not robust about handling
10167 signals, which can cause an apparent I/O
10169 if (interrupt_input
)
10170 unrequest_sigio ();
10173 /* Update the display. */
10174 set_window_update_flags (XWINDOW (f
->root_window
), 1);
10175 pause
|= update_frame (f
, 0, 0);
10176 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
10183 int nbytes
= size
* sizeof *updated
;
10184 struct frame
**p
= (struct frame
**) alloca (2 * nbytes
);
10185 bcopy (updated
, p
, nbytes
);
10196 /* Do the mark_window_display_accurate after all windows have
10197 been redisplayed because this call resets flags in buffers
10198 which are needed for proper redisplay. */
10199 for (i
= 0; i
< n
; ++i
)
10201 struct frame
*f
= updated
[i
];
10202 mark_window_display_accurate (f
->root_window
, 1);
10203 if (frame_up_to_date_hook
)
10204 frame_up_to_date_hook (f
);
10208 else if (FRAME_VISIBLE_P (sf
) && !FRAME_OBSCURED_P (sf
))
10210 Lisp_Object mini_window
;
10211 struct frame
*mini_frame
;
10213 displayed_buffer
= XBUFFER (XWINDOW (selected_window
)->buffer
);
10214 /* Use list_of_error, not Qerror, so that
10215 we catch only errors and don't run the debugger. */
10216 internal_condition_case_1 (redisplay_window_1
, selected_window
,
10218 redisplay_window_error
);
10220 /* Compare desired and current matrices, perform output. */
10223 /* If fonts changed, display again. */
10224 if (fonts_changed_p
)
10227 /* Prevent various kinds of signals during display update.
10228 stdio is not robust about handling signals,
10229 which can cause an apparent I/O error. */
10230 if (interrupt_input
)
10231 unrequest_sigio ();
10234 if (FRAME_VISIBLE_P (sf
) && !FRAME_OBSCURED_P (sf
))
10236 if (hscroll_windows (selected_window
))
10239 XWINDOW (selected_window
)->must_be_updated_p
= 1;
10240 pause
= update_frame (sf
, 0, 0);
10243 /* We may have called echo_area_display at the top of this
10244 function. If the echo area is on another frame, that may
10245 have put text on a frame other than the selected one, so the
10246 above call to update_frame would not have caught it. Catch
10248 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
10249 mini_frame
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
10251 if (mini_frame
!= sf
&& FRAME_WINDOW_P (mini_frame
))
10253 XWINDOW (mini_window
)->must_be_updated_p
= 1;
10254 pause
|= update_frame (mini_frame
, 0, 0);
10255 if (!pause
&& hscroll_windows (mini_window
))
10260 /* If display was paused because of pending input, make sure we do a
10261 thorough update the next time. */
10264 /* Prevent the optimization at the beginning of
10265 redisplay_internal that tries a single-line update of the
10266 line containing the cursor in the selected window. */
10267 CHARPOS (this_line_start_pos
) = 0;
10269 /* Let the overlay arrow be updated the next time. */
10270 update_overlay_arrows (0);
10272 /* If we pause after scrolling, some rows in the current
10273 matrices of some windows are not valid. */
10274 if (!WINDOW_FULL_WIDTH_P (w
)
10275 && !FRAME_WINDOW_P (XFRAME (w
->frame
)))
10276 update_mode_lines
= 1;
10280 if (!consider_all_windows_p
)
10282 /* This has already been done above if
10283 consider_all_windows_p is set. */
10284 mark_window_display_accurate_1 (w
, 1);
10286 /* Say overlay arrows are up to date. */
10287 update_overlay_arrows (1);
10289 if (frame_up_to_date_hook
!= 0)
10290 frame_up_to_date_hook (sf
);
10293 update_mode_lines
= 0;
10294 windows_or_buffers_changed
= 0;
10295 cursor_type_changed
= 0;
10298 /* Start SIGIO interrupts coming again. Having them off during the
10299 code above makes it less likely one will discard output, but not
10300 impossible, since there might be stuff in the system buffer here.
10301 But it is much hairier to try to do anything about that. */
10302 if (interrupt_input
)
10306 /* If a frame has become visible which was not before, redisplay
10307 again, so that we display it. Expose events for such a frame
10308 (which it gets when becoming visible) don't call the parts of
10309 redisplay constructing glyphs, so simply exposing a frame won't
10310 display anything in this case. So, we have to display these
10311 frames here explicitly. */
10314 Lisp_Object tail
, frame
;
10317 FOR_EACH_FRAME (tail
, frame
)
10319 int this_is_visible
= 0;
10321 if (XFRAME (frame
)->visible
)
10322 this_is_visible
= 1;
10323 FRAME_SAMPLE_VISIBILITY (XFRAME (frame
));
10324 if (XFRAME (frame
)->visible
)
10325 this_is_visible
= 1;
10327 if (this_is_visible
)
10331 if (new_count
!= number_of_visible_frames
)
10332 windows_or_buffers_changed
++;
10335 /* Change frame size now if a change is pending. */
10336 do_pending_window_change (1);
10338 /* If we just did a pending size change, or have additional
10339 visible frames, redisplay again. */
10340 if (windows_or_buffers_changed
&& !pause
)
10344 unbind_to (count
, Qnil
);
10349 /* Redisplay, but leave alone any recent echo area message unless
10350 another message has been requested in its place.
10352 This is useful in situations where you need to redisplay but no
10353 user action has occurred, making it inappropriate for the message
10354 area to be cleared. See tracking_off and
10355 wait_reading_process_input for examples of these situations.
10357 FROM_WHERE is an integer saying from where this function was
10358 called. This is useful for debugging. */
10361 redisplay_preserve_echo_area (from_where
)
10364 TRACE ((stderr
, "redisplay_preserve_echo_area (%d)\n", from_where
));
10366 if (!NILP (echo_area_buffer
[1]))
10368 /* We have a previously displayed message, but no current
10369 message. Redisplay the previous message. */
10370 display_last_displayed_message_p
= 1;
10371 redisplay_internal (1);
10372 display_last_displayed_message_p
= 0;
10375 redisplay_internal (1);
10379 /* Function registered with record_unwind_protect in
10380 redisplay_internal. Reset redisplaying_p to the value it had
10381 before redisplay_internal was called, and clear
10382 prevent_freeing_realized_faces_p. It also selects the previously
10386 unwind_redisplay (val
)
10389 Lisp_Object old_redisplaying_p
, old_frame
;
10391 old_redisplaying_p
= XCAR (val
);
10392 redisplaying_p
= XFASTINT (old_redisplaying_p
);
10393 old_frame
= XCDR (val
);
10394 if (! EQ (old_frame
, selected_frame
))
10395 select_frame_for_redisplay (old_frame
);
10400 /* Mark the display of window W as accurate or inaccurate. If
10401 ACCURATE_P is non-zero mark display of W as accurate. If
10402 ACCURATE_P is zero, arrange for W to be redisplayed the next time
10403 redisplay_internal is called. */
10406 mark_window_display_accurate_1 (w
, accurate_p
)
10410 if (BUFFERP (w
->buffer
))
10412 struct buffer
*b
= XBUFFER (w
->buffer
);
10415 = make_number (accurate_p
? BUF_MODIFF (b
) : 0);
10416 w
->last_overlay_modified
10417 = make_number (accurate_p
? BUF_OVERLAY_MODIFF (b
) : 0);
10419 = BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
) ? Qt
: Qnil
;
10423 b
->clip_changed
= 0;
10424 b
->prevent_redisplay_optimizations_p
= 0;
10426 BUF_UNCHANGED_MODIFIED (b
) = BUF_MODIFF (b
);
10427 BUF_OVERLAY_UNCHANGED_MODIFIED (b
) = BUF_OVERLAY_MODIFF (b
);
10428 BUF_BEG_UNCHANGED (b
) = BUF_GPT (b
) - BUF_BEG (b
);
10429 BUF_END_UNCHANGED (b
) = BUF_Z (b
) - BUF_GPT (b
);
10431 w
->current_matrix
->buffer
= b
;
10432 w
->current_matrix
->begv
= BUF_BEGV (b
);
10433 w
->current_matrix
->zv
= BUF_ZV (b
);
10435 w
->last_cursor
= w
->cursor
;
10436 w
->last_cursor_off_p
= w
->cursor_off_p
;
10438 if (w
== XWINDOW (selected_window
))
10439 w
->last_point
= make_number (BUF_PT (b
));
10441 w
->last_point
= make_number (XMARKER (w
->pointm
)->charpos
);
10447 w
->window_end_valid
= w
->buffer
;
10448 #if 0 /* This is incorrect with variable-height lines. */
10449 xassert (XINT (w
->window_end_vpos
)
10450 < (WINDOW_TOTAL_LINES (w
)
10451 - (WINDOW_WANTS_MODELINE_P (w
) ? 1 : 0)));
10453 w
->update_mode_line
= Qnil
;
10458 /* Mark the display of windows in the window tree rooted at WINDOW as
10459 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
10460 windows as accurate. If ACCURATE_P is zero, arrange for windows to
10461 be redisplayed the next time redisplay_internal is called. */
10464 mark_window_display_accurate (window
, accurate_p
)
10465 Lisp_Object window
;
10470 for (; !NILP (window
); window
= w
->next
)
10472 w
= XWINDOW (window
);
10473 mark_window_display_accurate_1 (w
, accurate_p
);
10475 if (!NILP (w
->vchild
))
10476 mark_window_display_accurate (w
->vchild
, accurate_p
);
10477 if (!NILP (w
->hchild
))
10478 mark_window_display_accurate (w
->hchild
, accurate_p
);
10483 update_overlay_arrows (1);
10487 /* Force a thorough redisplay the next time by setting
10488 last_arrow_position and last_arrow_string to t, which is
10489 unequal to any useful value of Voverlay_arrow_... */
10490 update_overlay_arrows (-1);
10495 /* Return value in display table DP (Lisp_Char_Table *) for character
10496 C. Since a display table doesn't have any parent, we don't have to
10497 follow parent. Do not call this function directly but use the
10498 macro DISP_CHAR_VECTOR. */
10501 disp_char_vector (dp
, c
)
10502 struct Lisp_Char_Table
*dp
;
10508 if (SINGLE_BYTE_CHAR_P (c
))
10509 return (dp
->contents
[c
]);
10511 SPLIT_CHAR (c
, code
[0], code
[1], code
[2]);
10514 else if (code
[2] < 32)
10517 /* Here, the possible range of code[0] (== charset ID) is
10518 128..max_charset. Since the top level char table contains data
10519 for multibyte characters after 256th element, we must increment
10520 code[0] by 128 to get a correct index. */
10522 code
[3] = -1; /* anchor */
10524 for (i
= 0; code
[i
] >= 0; i
++, dp
= XCHAR_TABLE (val
))
10526 val
= dp
->contents
[code
[i
]];
10527 if (!SUB_CHAR_TABLE_P (val
))
10528 return (NILP (val
) ? dp
->defalt
: val
);
10531 /* Here, val is a sub char table. We return the default value of
10533 return (dp
->defalt
);
10538 /***********************************************************************
10540 ***********************************************************************/
10542 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
10545 redisplay_windows (window
)
10546 Lisp_Object window
;
10548 while (!NILP (window
))
10550 struct window
*w
= XWINDOW (window
);
10552 if (!NILP (w
->hchild
))
10553 redisplay_windows (w
->hchild
);
10554 else if (!NILP (w
->vchild
))
10555 redisplay_windows (w
->vchild
);
10558 displayed_buffer
= XBUFFER (w
->buffer
);
10559 /* Use list_of_error, not Qerror, so that
10560 we catch only errors and don't run the debugger. */
10561 internal_condition_case_1 (redisplay_window_0
, window
,
10563 redisplay_window_error
);
10571 redisplay_window_error ()
10573 displayed_buffer
->display_error_modiff
= BUF_MODIFF (displayed_buffer
);
10578 redisplay_window_0 (window
)
10579 Lisp_Object window
;
10581 if (displayed_buffer
->display_error_modiff
< BUF_MODIFF (displayed_buffer
))
10582 redisplay_window (window
, 0);
10587 redisplay_window_1 (window
)
10588 Lisp_Object window
;
10590 if (displayed_buffer
->display_error_modiff
< BUF_MODIFF (displayed_buffer
))
10591 redisplay_window (window
, 1);
10596 /* Increment GLYPH until it reaches END or CONDITION fails while
10597 adding (GLYPH)->pixel_width to X. */
10599 #define SKIP_GLYPHS(glyph, end, x, condition) \
10602 (x) += (glyph)->pixel_width; \
10605 while ((glyph) < (end) && (condition))
10608 /* Set cursor position of W. PT is assumed to be displayed in ROW.
10609 DELTA is the number of bytes by which positions recorded in ROW
10610 differ from current buffer positions. */
10613 set_cursor_from_row (w
, row
, matrix
, delta
, delta_bytes
, dy
, dvpos
)
10615 struct glyph_row
*row
;
10616 struct glyph_matrix
*matrix
;
10617 int delta
, delta_bytes
, dy
, dvpos
;
10619 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
10620 struct glyph
*end
= glyph
+ row
->used
[TEXT_AREA
];
10621 /* The first glyph that starts a sequence of glyphs from string. */
10622 struct glyph
*string_start
;
10623 /* The X coordinate of string_start. */
10624 int string_start_x
;
10625 /* The last known character position. */
10626 int last_pos
= MATRIX_ROW_START_CHARPOS (row
) + delta
;
10627 /* The last known character position before string_start. */
10628 int string_before_pos
;
10630 int pt_old
= PT
- delta
;
10632 /* Skip over glyphs not having an object at the start of the row.
10633 These are special glyphs like truncation marks on terminal
10635 if (row
->displays_text_p
)
10637 && INTEGERP (glyph
->object
)
10638 && glyph
->charpos
< 0)
10640 x
+= glyph
->pixel_width
;
10644 string_start
= NULL
;
10646 && !INTEGERP (glyph
->object
)
10647 && (!BUFFERP (glyph
->object
)
10648 || (last_pos
= glyph
->charpos
) < pt_old
))
10650 if (! STRINGP (glyph
->object
))
10652 string_start
= NULL
;
10653 x
+= glyph
->pixel_width
;
10658 string_before_pos
= last_pos
;
10659 string_start
= glyph
;
10660 string_start_x
= x
;
10661 /* Skip all glyphs from string. */
10662 SKIP_GLYPHS (glyph
, end
, x
, STRINGP (glyph
->object
));
10667 && (glyph
== end
|| !BUFFERP (glyph
->object
) || last_pos
> pt_old
))
10669 /* We may have skipped over point because the previous glyphs
10670 are from string. As there's no easy way to know the
10671 character position of the current glyph, find the correct
10672 glyph on point by scanning from string_start again. */
10674 Lisp_Object string
;
10677 limit
= make_number (pt_old
+ 1);
10679 glyph
= string_start
;
10680 x
= string_start_x
;
10681 string
= glyph
->object
;
10682 pos
= string_buffer_position (w
, string
, string_before_pos
);
10683 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
10684 because we always put cursor after overlay strings. */
10685 while (pos
== 0 && glyph
< end
)
10687 string
= glyph
->object
;
10688 SKIP_GLYPHS (glyph
, end
, x
, EQ (glyph
->object
, string
));
10690 pos
= string_buffer_position (w
, glyph
->object
, string_before_pos
);
10693 while (glyph
< end
)
10695 pos
= XINT (Fnext_single_char_property_change
10696 (make_number (pos
), Qdisplay
, Qnil
, limit
));
10699 /* Skip glyphs from the same string. */
10700 string
= glyph
->object
;
10701 SKIP_GLYPHS (glyph
, end
, x
, EQ (glyph
->object
, string
));
10702 /* Skip glyphs from an overlay. */
10704 && ! string_buffer_position (w
, glyph
->object
, pos
))
10706 string
= glyph
->object
;
10707 SKIP_GLYPHS (glyph
, end
, x
, EQ (glyph
->object
, string
));
10712 w
->cursor
.hpos
= glyph
- row
->glyphs
[TEXT_AREA
];
10714 w
->cursor
.vpos
= MATRIX_ROW_VPOS (row
, matrix
) + dvpos
;
10715 w
->cursor
.y
= row
->y
+ dy
;
10717 if (w
== XWINDOW (selected_window
))
10719 if (!row
->continued_p
10720 && !MATRIX_ROW_CONTINUATION_LINE_P (row
)
10723 this_line_buffer
= XBUFFER (w
->buffer
);
10725 CHARPOS (this_line_start_pos
)
10726 = MATRIX_ROW_START_CHARPOS (row
) + delta
;
10727 BYTEPOS (this_line_start_pos
)
10728 = MATRIX_ROW_START_BYTEPOS (row
) + delta_bytes
;
10730 CHARPOS (this_line_end_pos
)
10731 = Z
- (MATRIX_ROW_END_CHARPOS (row
) + delta
);
10732 BYTEPOS (this_line_end_pos
)
10733 = Z_BYTE
- (MATRIX_ROW_END_BYTEPOS (row
) + delta_bytes
);
10735 this_line_y
= w
->cursor
.y
;
10736 this_line_pixel_height
= row
->height
;
10737 this_line_vpos
= w
->cursor
.vpos
;
10738 this_line_start_x
= row
->x
;
10741 CHARPOS (this_line_start_pos
) = 0;
10746 /* Run window scroll functions, if any, for WINDOW with new window
10747 start STARTP. Sets the window start of WINDOW to that position.
10749 We assume that the window's buffer is really current. */
10751 static INLINE
struct text_pos
10752 run_window_scroll_functions (window
, startp
)
10753 Lisp_Object window
;
10754 struct text_pos startp
;
10756 struct window
*w
= XWINDOW (window
);
10757 SET_MARKER_FROM_TEXT_POS (w
->start
, startp
);
10759 if (current_buffer
!= XBUFFER (w
->buffer
))
10762 if (!NILP (Vwindow_scroll_functions
))
10764 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
10765 make_number (CHARPOS (startp
)));
10766 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
10767 /* In case the hook functions switch buffers. */
10768 if (current_buffer
!= XBUFFER (w
->buffer
))
10769 set_buffer_internal_1 (XBUFFER (w
->buffer
));
10776 /* Make sure the line containing the cursor is fully visible.
10777 A value of 1 means there is nothing to be done.
10778 (Either the line is fully visible, or it cannot be made so,
10779 or we cannot tell.)
10781 If FORCE_P is non-zero, return 0 even if partial visible cursor row
10782 is higher than window.
10784 A value of 0 means the caller should do scrolling
10785 as if point had gone off the screen. */
10788 make_cursor_line_fully_visible (w
, force_p
)
10792 struct glyph_matrix
*matrix
;
10793 struct glyph_row
*row
;
10796 /* It's not always possible to find the cursor, e.g, when a window
10797 is full of overlay strings. Don't do anything in that case. */
10798 if (w
->cursor
.vpos
< 0)
10801 matrix
= w
->desired_matrix
;
10802 row
= MATRIX_ROW (matrix
, w
->cursor
.vpos
);
10804 /* If the cursor row is not partially visible, there's nothing to do. */
10805 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (row
))
10808 /* If the row the cursor is in is taller than the window's height,
10809 it's not clear what to do, so do nothing. */
10810 window_height
= window_box_height (w
);
10811 if (row
->height
>= window_height
)
10813 if (!force_p
|| w
->vscroll
)
10819 /* This code used to try to scroll the window just enough to make
10820 the line visible. It returned 0 to say that the caller should
10821 allocate larger glyph matrices. */
10823 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w
, row
))
10825 int dy
= row
->height
- row
->visible_height
;
10828 shift_glyph_matrix (w
, matrix
, 0, matrix
->nrows
, dy
);
10830 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
10832 int dy
= - (row
->height
- row
->visible_height
);
10835 shift_glyph_matrix (w
, matrix
, 0, matrix
->nrows
, dy
);
10838 /* When we change the cursor y-position of the selected window,
10839 change this_line_y as well so that the display optimization for
10840 the cursor line of the selected window in redisplay_internal uses
10841 the correct y-position. */
10842 if (w
== XWINDOW (selected_window
))
10843 this_line_y
= w
->cursor
.y
;
10845 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
10846 redisplay with larger matrices. */
10847 if (matrix
->nrows
< required_matrix_height (w
))
10849 fonts_changed_p
= 1;
10858 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
10859 non-zero means only WINDOW is redisplayed in redisplay_internal.
10860 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
10861 in redisplay_window to bring a partially visible line into view in
10862 the case that only the cursor has moved.
10864 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
10865 last screen line's vertical height extends past the end of the screen.
10869 1 if scrolling succeeded
10871 0 if scrolling didn't find point.
10873 -1 if new fonts have been loaded so that we must interrupt
10874 redisplay, adjust glyph matrices, and try again. */
10880 SCROLLING_NEED_LARGER_MATRICES
10884 try_scrolling (window
, just_this_one_p
, scroll_conservatively
,
10885 scroll_step
, temp_scroll_step
, last_line_misfit
)
10886 Lisp_Object window
;
10887 int just_this_one_p
;
10888 EMACS_INT scroll_conservatively
, scroll_step
;
10889 int temp_scroll_step
;
10890 int last_line_misfit
;
10892 struct window
*w
= XWINDOW (window
);
10893 struct frame
*f
= XFRAME (w
->frame
);
10894 struct text_pos scroll_margin_pos
;
10895 struct text_pos pos
;
10896 struct text_pos startp
;
10898 Lisp_Object window_end
;
10899 int this_scroll_margin
;
10903 int amount_to_scroll
= 0;
10904 Lisp_Object aggressive
;
10906 int extra_scroll_margin_lines
= last_line_misfit
? 1 : 0;
10909 debug_method_add (w
, "try_scrolling");
10912 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
10914 /* Compute scroll margin height in pixels. We scroll when point is
10915 within this distance from the top or bottom of the window. */
10916 if (scroll_margin
> 0)
10918 this_scroll_margin
= min (scroll_margin
, WINDOW_TOTAL_LINES (w
) / 4);
10919 this_scroll_margin
*= FRAME_LINE_HEIGHT (f
);
10922 this_scroll_margin
= 0;
10924 /* Force scroll_conservatively to have a reasonable value so it doesn't
10925 cause an overflow while computing how much to scroll. */
10926 if (scroll_conservatively
)
10927 scroll_conservatively
= min (scroll_conservatively
,
10928 MOST_POSITIVE_FIXNUM
/ FRAME_LINE_HEIGHT (f
));
10930 /* Compute how much we should try to scroll maximally to bring point
10932 if (scroll_step
|| scroll_conservatively
|| temp_scroll_step
)
10933 scroll_max
= max (scroll_step
,
10934 max (scroll_conservatively
, temp_scroll_step
));
10935 else if (NUMBERP (current_buffer
->scroll_down_aggressively
)
10936 || NUMBERP (current_buffer
->scroll_up_aggressively
))
10937 /* We're trying to scroll because of aggressive scrolling
10938 but no scroll_step is set. Choose an arbitrary one. Maybe
10939 there should be a variable for this. */
10943 scroll_max
*= FRAME_LINE_HEIGHT (f
);
10945 /* Decide whether we have to scroll down. Start at the window end
10946 and move this_scroll_margin up to find the position of the scroll
10948 window_end
= Fwindow_end (window
, Qt
);
10952 CHARPOS (scroll_margin_pos
) = XINT (window_end
);
10953 BYTEPOS (scroll_margin_pos
) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos
));
10955 if (this_scroll_margin
|| extra_scroll_margin_lines
)
10957 start_display (&it
, w
, scroll_margin_pos
);
10958 if (this_scroll_margin
)
10959 move_it_vertically (&it
, - this_scroll_margin
);
10960 if (extra_scroll_margin_lines
)
10961 move_it_by_lines (&it
, - extra_scroll_margin_lines
, 0);
10962 scroll_margin_pos
= it
.current
.pos
;
10965 if (PT
>= CHARPOS (scroll_margin_pos
))
10969 /* Point is in the scroll margin at the bottom of the window, or
10970 below. Compute a new window start that makes point visible. */
10972 /* Compute the distance from the scroll margin to PT.
10973 Give up if the distance is greater than scroll_max. */
10974 start_display (&it
, w
, scroll_margin_pos
);
10976 move_it_to (&it
, PT
, 0, it
.last_visible_y
, -1,
10977 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
10979 /* To make point visible, we have to move the window start
10980 down so that the line the cursor is in is visible, which
10981 means we have to add in the height of the cursor line. */
10982 dy
= line_bottom_y (&it
) - y0
;
10984 if (dy
> scroll_max
)
10985 return SCROLLING_FAILED
;
10987 /* Move the window start down. If scrolling conservatively,
10988 move it just enough down to make point visible. If
10989 scroll_step is set, move it down by scroll_step. */
10990 start_display (&it
, w
, startp
);
10992 if (scroll_conservatively
)
10993 /* Set AMOUNT_TO_SCROLL to at least one line,
10994 and at most scroll_conservatively lines. */
10996 = min (max (dy
, FRAME_LINE_HEIGHT (f
)),
10997 FRAME_LINE_HEIGHT (f
) * scroll_conservatively
);
10998 else if (scroll_step
|| temp_scroll_step
)
10999 amount_to_scroll
= scroll_max
;
11002 aggressive
= current_buffer
->scroll_up_aggressively
;
11003 height
= WINDOW_BOX_TEXT_HEIGHT (w
);
11004 if (NUMBERP (aggressive
))
11006 double float_amount
= XFLOATINT (aggressive
) * height
;
11007 amount_to_scroll
= float_amount
;
11008 if (amount_to_scroll
== 0 && float_amount
> 0)
11009 amount_to_scroll
= 1;
11013 if (amount_to_scroll
<= 0)
11014 return SCROLLING_FAILED
;
11016 /* If moving by amount_to_scroll leaves STARTP unchanged,
11017 move it down one screen line. */
11019 move_it_vertically (&it
, amount_to_scroll
);
11020 if (CHARPOS (it
.current
.pos
) == CHARPOS (startp
))
11021 move_it_by_lines (&it
, 1, 1);
11022 startp
= it
.current
.pos
;
11026 /* See if point is inside the scroll margin at the top of the
11028 scroll_margin_pos
= startp
;
11029 if (this_scroll_margin
)
11031 start_display (&it
, w
, startp
);
11032 move_it_vertically (&it
, this_scroll_margin
);
11033 scroll_margin_pos
= it
.current
.pos
;
11036 if (PT
< CHARPOS (scroll_margin_pos
))
11038 /* Point is in the scroll margin at the top of the window or
11039 above what is displayed in the window. */
11042 /* Compute the vertical distance from PT to the scroll
11043 margin position. Give up if distance is greater than
11045 SET_TEXT_POS (pos
, PT
, PT_BYTE
);
11046 start_display (&it
, w
, pos
);
11048 move_it_to (&it
, CHARPOS (scroll_margin_pos
), 0,
11049 it
.last_visible_y
, -1,
11050 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
11051 dy
= it
.current_y
- y0
;
11052 if (dy
> scroll_max
)
11053 return SCROLLING_FAILED
;
11055 /* Compute new window start. */
11056 start_display (&it
, w
, startp
);
11058 if (scroll_conservatively
)
11060 max (dy
, FRAME_LINE_HEIGHT (f
) * max (scroll_step
, temp_scroll_step
));
11061 else if (scroll_step
|| temp_scroll_step
)
11062 amount_to_scroll
= scroll_max
;
11065 aggressive
= current_buffer
->scroll_down_aggressively
;
11066 height
= WINDOW_BOX_TEXT_HEIGHT (w
);
11067 if (NUMBERP (aggressive
))
11069 double float_amount
= XFLOATINT (aggressive
) * height
;
11070 amount_to_scroll
= float_amount
;
11071 if (amount_to_scroll
== 0 && float_amount
> 0)
11072 amount_to_scroll
= 1;
11076 if (amount_to_scroll
<= 0)
11077 return SCROLLING_FAILED
;
11079 move_it_vertically (&it
, - amount_to_scroll
);
11080 startp
= it
.current
.pos
;
11084 /* Run window scroll functions. */
11085 startp
= run_window_scroll_functions (window
, startp
);
11087 /* Display the window. Give up if new fonts are loaded, or if point
11089 if (!try_window (window
, startp
))
11090 rc
= SCROLLING_NEED_LARGER_MATRICES
;
11091 else if (w
->cursor
.vpos
< 0)
11093 clear_glyph_matrix (w
->desired_matrix
);
11094 rc
= SCROLLING_FAILED
;
11098 /* Maybe forget recorded base line for line number display. */
11099 if (!just_this_one_p
11100 || current_buffer
->clip_changed
11101 || BEG_UNCHANGED
< CHARPOS (startp
))
11102 w
->base_line_number
= Qnil
;
11104 /* If cursor ends up on a partially visible line,
11105 treat that as being off the bottom of the screen. */
11106 if (! make_cursor_line_fully_visible (w
, extra_scroll_margin_lines
<= 1))
11108 clear_glyph_matrix (w
->desired_matrix
);
11109 ++extra_scroll_margin_lines
;
11112 rc
= SCROLLING_SUCCESS
;
11119 /* Compute a suitable window start for window W if display of W starts
11120 on a continuation line. Value is non-zero if a new window start
11123 The new window start will be computed, based on W's width, starting
11124 from the start of the continued line. It is the start of the
11125 screen line with the minimum distance from the old start W->start. */
11128 compute_window_start_on_continuation_line (w
)
11131 struct text_pos pos
, start_pos
;
11132 int window_start_changed_p
= 0;
11134 SET_TEXT_POS_FROM_MARKER (start_pos
, w
->start
);
11136 /* If window start is on a continuation line... Window start may be
11137 < BEGV in case there's invisible text at the start of the
11138 buffer (M-x rmail, for example). */
11139 if (CHARPOS (start_pos
) > BEGV
11140 && FETCH_BYTE (BYTEPOS (start_pos
) - 1) != '\n')
11143 struct glyph_row
*row
;
11145 /* Handle the case that the window start is out of range. */
11146 if (CHARPOS (start_pos
) < BEGV
)
11147 SET_TEXT_POS (start_pos
, BEGV
, BEGV_BYTE
);
11148 else if (CHARPOS (start_pos
) > ZV
)
11149 SET_TEXT_POS (start_pos
, ZV
, ZV_BYTE
);
11151 /* Find the start of the continued line. This should be fast
11152 because scan_buffer is fast (newline cache). */
11153 row
= w
->desired_matrix
->rows
+ (WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0);
11154 init_iterator (&it
, w
, CHARPOS (start_pos
), BYTEPOS (start_pos
),
11155 row
, DEFAULT_FACE_ID
);
11156 reseat_at_previous_visible_line_start (&it
);
11158 /* If the line start is "too far" away from the window start,
11159 say it takes too much time to compute a new window start. */
11160 if (CHARPOS (start_pos
) - IT_CHARPOS (it
)
11161 < WINDOW_TOTAL_LINES (w
) * WINDOW_TOTAL_COLS (w
))
11163 int min_distance
, distance
;
11165 /* Move forward by display lines to find the new window
11166 start. If window width was enlarged, the new start can
11167 be expected to be > the old start. If window width was
11168 decreased, the new window start will be < the old start.
11169 So, we're looking for the display line start with the
11170 minimum distance from the old window start. */
11171 pos
= it
.current
.pos
;
11172 min_distance
= INFINITY
;
11173 while ((distance
= abs (CHARPOS (start_pos
) - IT_CHARPOS (it
))),
11174 distance
< min_distance
)
11176 min_distance
= distance
;
11177 pos
= it
.current
.pos
;
11178 move_it_by_lines (&it
, 1, 0);
11181 /* Set the window start there. */
11182 SET_MARKER_FROM_TEXT_POS (w
->start
, pos
);
11183 window_start_changed_p
= 1;
11187 return window_start_changed_p
;
11191 /* Try cursor movement in case text has not changed in window WINDOW,
11192 with window start STARTP. Value is
11194 CURSOR_MOVEMENT_SUCCESS if successful
11196 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
11198 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
11199 display. *SCROLL_STEP is set to 1, under certain circumstances, if
11200 we want to scroll as if scroll-step were set to 1. See the code.
11202 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
11203 which case we have to abort this redisplay, and adjust matrices
11208 CURSOR_MOVEMENT_SUCCESS
,
11209 CURSOR_MOVEMENT_CANNOT_BE_USED
,
11210 CURSOR_MOVEMENT_MUST_SCROLL
,
11211 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
11215 try_cursor_movement (window
, startp
, scroll_step
)
11216 Lisp_Object window
;
11217 struct text_pos startp
;
11220 struct window
*w
= XWINDOW (window
);
11221 struct frame
*f
= XFRAME (w
->frame
);
11222 int rc
= CURSOR_MOVEMENT_CANNOT_BE_USED
;
11225 if (inhibit_try_cursor_movement
)
11229 /* Handle case where text has not changed, only point, and it has
11230 not moved off the frame. */
11231 if (/* Point may be in this window. */
11232 PT
>= CHARPOS (startp
)
11233 /* Selective display hasn't changed. */
11234 && !current_buffer
->clip_changed
11235 /* Function force-mode-line-update is used to force a thorough
11236 redisplay. It sets either windows_or_buffers_changed or
11237 update_mode_lines. So don't take a shortcut here for these
11239 && !update_mode_lines
11240 && !windows_or_buffers_changed
11241 && !cursor_type_changed
11242 /* Can't use this case if highlighting a region. When a
11243 region exists, cursor movement has to do more than just
11245 && !(!NILP (Vtransient_mark_mode
)
11246 && !NILP (current_buffer
->mark_active
))
11247 && NILP (w
->region_showing
)
11248 && NILP (Vshow_trailing_whitespace
)
11249 /* Right after splitting windows, last_point may be nil. */
11250 && INTEGERP (w
->last_point
)
11251 /* This code is not used for mini-buffer for the sake of the case
11252 of redisplaying to replace an echo area message; since in
11253 that case the mini-buffer contents per se are usually
11254 unchanged. This code is of no real use in the mini-buffer
11255 since the handling of this_line_start_pos, etc., in redisplay
11256 handles the same cases. */
11257 && !EQ (window
, minibuf_window
)
11258 /* When splitting windows or for new windows, it happens that
11259 redisplay is called with a nil window_end_vpos or one being
11260 larger than the window. This should really be fixed in
11261 window.c. I don't have this on my list, now, so we do
11262 approximately the same as the old redisplay code. --gerd. */
11263 && INTEGERP (w
->window_end_vpos
)
11264 && XFASTINT (w
->window_end_vpos
) < w
->current_matrix
->nrows
11265 && (FRAME_WINDOW_P (f
)
11266 || !overlay_arrow_in_current_buffer_p ()))
11268 int this_scroll_margin
;
11269 struct glyph_row
*row
= NULL
;
11272 debug_method_add (w
, "cursor movement");
11275 /* Scroll if point within this distance from the top or bottom
11276 of the window. This is a pixel value. */
11277 this_scroll_margin
= max (0, scroll_margin
);
11278 this_scroll_margin
= min (this_scroll_margin
, WINDOW_TOTAL_LINES (w
) / 4);
11279 this_scroll_margin
*= FRAME_LINE_HEIGHT (f
);
11281 /* Start with the row the cursor was displayed during the last
11282 not paused redisplay. Give up if that row is not valid. */
11283 if (w
->last_cursor
.vpos
< 0
11284 || w
->last_cursor
.vpos
>= w
->current_matrix
->nrows
)
11285 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11288 row
= MATRIX_ROW (w
->current_matrix
, w
->last_cursor
.vpos
);
11289 if (row
->mode_line_p
)
11291 if (!row
->enabled_p
)
11292 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11295 if (rc
== CURSOR_MOVEMENT_CANNOT_BE_USED
)
11298 int last_y
= window_text_bottom_y (w
) - this_scroll_margin
;
11300 if (PT
> XFASTINT (w
->last_point
))
11302 /* Point has moved forward. */
11303 while (MATRIX_ROW_END_CHARPOS (row
) < PT
11304 && MATRIX_ROW_BOTTOM_Y (row
) < last_y
)
11306 xassert (row
->enabled_p
);
11310 /* The end position of a row equals the start position
11311 of the next row. If PT is there, we would rather
11312 display it in the next line. */
11313 while (MATRIX_ROW_BOTTOM_Y (row
) < last_y
11314 && MATRIX_ROW_END_CHARPOS (row
) == PT
11315 && !cursor_row_p (w
, row
))
11318 /* If within the scroll margin, scroll. Note that
11319 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
11320 the next line would be drawn, and that
11321 this_scroll_margin can be zero. */
11322 if (MATRIX_ROW_BOTTOM_Y (row
) > last_y
11323 || PT
> MATRIX_ROW_END_CHARPOS (row
)
11324 /* Line is completely visible last line in window
11325 and PT is to be set in the next line. */
11326 || (MATRIX_ROW_BOTTOM_Y (row
) == last_y
11327 && PT
== MATRIX_ROW_END_CHARPOS (row
)
11328 && !row
->ends_at_zv_p
11329 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
)))
11332 else if (PT
< XFASTINT (w
->last_point
))
11334 /* Cursor has to be moved backward. Note that PT >=
11335 CHARPOS (startp) because of the outer
11337 while (!row
->mode_line_p
11338 && (MATRIX_ROW_START_CHARPOS (row
) > PT
11339 || (MATRIX_ROW_START_CHARPOS (row
) == PT
11340 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row
)))
11341 && (row
->y
> this_scroll_margin
11342 || CHARPOS (startp
) == BEGV
))
11344 xassert (row
->enabled_p
);
11348 /* Consider the following case: Window starts at BEGV,
11349 there is invisible, intangible text at BEGV, so that
11350 display starts at some point START > BEGV. It can
11351 happen that we are called with PT somewhere between
11352 BEGV and START. Try to handle that case. */
11353 if (row
< w
->current_matrix
->rows
11354 || row
->mode_line_p
)
11356 row
= w
->current_matrix
->rows
;
11357 if (row
->mode_line_p
)
11361 /* Due to newlines in overlay strings, we may have to
11362 skip forward over overlay strings. */
11363 while (MATRIX_ROW_BOTTOM_Y (row
) < last_y
11364 && MATRIX_ROW_END_CHARPOS (row
) == PT
11365 && !cursor_row_p (w
, row
))
11368 /* If within the scroll margin, scroll. */
11369 if (row
->y
< this_scroll_margin
11370 && CHARPOS (startp
) != BEGV
)
11374 if (PT
< MATRIX_ROW_START_CHARPOS (row
)
11375 || PT
> MATRIX_ROW_END_CHARPOS (row
))
11377 /* if PT is not in the glyph row, give up. */
11378 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11380 else if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row
))
11382 if (PT
== MATRIX_ROW_END_CHARPOS (row
)
11383 && !row
->ends_at_zv_p
11384 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
))
11385 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11386 else if (row
->height
> window_box_height (w
))
11388 /* If we end up in a partially visible line, let's
11389 make it fully visible, except when it's taller
11390 than the window, in which case we can't do much
11393 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11397 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
11398 if (!make_cursor_line_fully_visible (w
, 0))
11399 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11401 rc
= CURSOR_MOVEMENT_SUCCESS
;
11405 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11408 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
11409 rc
= CURSOR_MOVEMENT_SUCCESS
;
11418 set_vertical_scroll_bar (w
)
11421 int start
, end
, whole
;
11423 /* Calculate the start and end positions for the current window.
11424 At some point, it would be nice to choose between scrollbars
11425 which reflect the whole buffer size, with special markers
11426 indicating narrowing, and scrollbars which reflect only the
11429 Note that mini-buffers sometimes aren't displaying any text. */
11430 if (!MINI_WINDOW_P (w
)
11431 || (w
== XWINDOW (minibuf_window
)
11432 && NILP (echo_area_buffer
[0])))
11434 struct buffer
*buf
= XBUFFER (w
->buffer
);
11435 whole
= BUF_ZV (buf
) - BUF_BEGV (buf
);
11436 start
= marker_position (w
->start
) - BUF_BEGV (buf
);
11437 /* I don't think this is guaranteed to be right. For the
11438 moment, we'll pretend it is. */
11439 end
= BUF_Z (buf
) - XFASTINT (w
->window_end_pos
) - BUF_BEGV (buf
);
11443 if (whole
< (end
- start
))
11444 whole
= end
- start
;
11447 start
= end
= whole
= 0;
11449 /* Indicate what this scroll bar ought to be displaying now. */
11450 set_vertical_scroll_bar_hook (w
, end
- start
, whole
, start
);
11454 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
11455 selected_window is redisplayed.
11457 We can return without actually redisplaying the window if
11458 fonts_changed_p is nonzero. In that case, redisplay_internal will
11462 redisplay_window (window
, just_this_one_p
)
11463 Lisp_Object window
;
11464 int just_this_one_p
;
11466 struct window
*w
= XWINDOW (window
);
11467 struct frame
*f
= XFRAME (w
->frame
);
11468 struct buffer
*buffer
= XBUFFER (w
->buffer
);
11469 struct buffer
*old
= current_buffer
;
11470 struct text_pos lpoint
, opoint
, startp
;
11471 int update_mode_line
;
11474 /* Record it now because it's overwritten. */
11475 int current_matrix_up_to_date_p
= 0;
11476 int used_current_matrix_p
= 0;
11477 /* This is less strict than current_matrix_up_to_date_p.
11478 It indictes that the buffer contents and narrowing are unchanged. */
11479 int buffer_unchanged_p
= 0;
11480 int temp_scroll_step
= 0;
11481 int count
= SPECPDL_INDEX ();
11483 int centering_position
;
11484 int last_line_misfit
= 0;
11486 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
11489 /* W must be a leaf window here. */
11490 xassert (!NILP (w
->buffer
));
11492 *w
->desired_matrix
->method
= 0;
11495 specbind (Qinhibit_point_motion_hooks
, Qt
);
11497 reconsider_clip_changes (w
, buffer
);
11499 /* Has the mode line to be updated? */
11500 update_mode_line
= (!NILP (w
->update_mode_line
)
11501 || update_mode_lines
11502 || buffer
->clip_changed
11503 || buffer
->prevent_redisplay_optimizations_p
);
11505 if (MINI_WINDOW_P (w
))
11507 if (w
== XWINDOW (echo_area_window
)
11508 && !NILP (echo_area_buffer
[0]))
11510 if (update_mode_line
)
11511 /* We may have to update a tty frame's menu bar or a
11512 tool-bar. Example `M-x C-h C-h C-g'. */
11513 goto finish_menu_bars
;
11515 /* We've already displayed the echo area glyphs in this window. */
11516 goto finish_scroll_bars
;
11518 else if ((w
!= XWINDOW (minibuf_window
)
11519 || minibuf_level
== 0)
11520 /* When buffer is nonempty, redisplay window normally. */
11521 && BUF_Z (XBUFFER (w
->buffer
)) == BUF_BEG (XBUFFER (w
->buffer
))
11522 /* Quail displays non-mini buffers in minibuffer window.
11523 In that case, redisplay the window normally. */
11524 && !NILP (Fmemq (w
->buffer
, Vminibuffer_list
)))
11526 /* W is a mini-buffer window, but it's not active, so clear
11528 int yb
= window_text_bottom_y (w
);
11529 struct glyph_row
*row
;
11532 for (y
= 0, row
= w
->desired_matrix
->rows
;
11534 y
+= row
->height
, ++row
)
11535 blank_row (w
, row
, y
);
11536 goto finish_scroll_bars
;
11539 clear_glyph_matrix (w
->desired_matrix
);
11542 /* Otherwise set up data on this window; select its buffer and point
11544 /* Really select the buffer, for the sake of buffer-local
11546 set_buffer_internal_1 (XBUFFER (w
->buffer
));
11547 SET_TEXT_POS (opoint
, PT
, PT_BYTE
);
11549 current_matrix_up_to_date_p
11550 = (!NILP (w
->window_end_valid
)
11551 && !current_buffer
->clip_changed
11552 && !current_buffer
->prevent_redisplay_optimizations_p
11553 && XFASTINT (w
->last_modified
) >= MODIFF
11554 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
);
11557 = (!NILP (w
->window_end_valid
)
11558 && !current_buffer
->clip_changed
11559 && XFASTINT (w
->last_modified
) >= MODIFF
11560 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
);
11562 /* When windows_or_buffers_changed is non-zero, we can't rely on
11563 the window end being valid, so set it to nil there. */
11564 if (windows_or_buffers_changed
)
11566 /* If window starts on a continuation line, maybe adjust the
11567 window start in case the window's width changed. */
11568 if (XMARKER (w
->start
)->buffer
== current_buffer
)
11569 compute_window_start_on_continuation_line (w
);
11571 w
->window_end_valid
= Qnil
;
11574 /* Some sanity checks. */
11575 CHECK_WINDOW_END (w
);
11576 if (Z
== Z_BYTE
&& CHARPOS (opoint
) != BYTEPOS (opoint
))
11578 if (BYTEPOS (opoint
) < CHARPOS (opoint
))
11581 /* If %c is in mode line, update it if needed. */
11582 if (!NILP (w
->column_number_displayed
)
11583 /* This alternative quickly identifies a common case
11584 where no change is needed. */
11585 && !(PT
== XFASTINT (w
->last_point
)
11586 && XFASTINT (w
->last_modified
) >= MODIFF
11587 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
)
11588 && (XFASTINT (w
->column_number_displayed
)
11589 != (int) current_column ())) /* iftc */
11590 update_mode_line
= 1;
11592 /* Count number of windows showing the selected buffer. An indirect
11593 buffer counts as its base buffer. */
11594 if (!just_this_one_p
)
11596 struct buffer
*current_base
, *window_base
;
11597 current_base
= current_buffer
;
11598 window_base
= XBUFFER (XWINDOW (selected_window
)->buffer
);
11599 if (current_base
->base_buffer
)
11600 current_base
= current_base
->base_buffer
;
11601 if (window_base
->base_buffer
)
11602 window_base
= window_base
->base_buffer
;
11603 if (current_base
== window_base
)
11607 /* Point refers normally to the selected window. For any other
11608 window, set up appropriate value. */
11609 if (!EQ (window
, selected_window
))
11611 int new_pt
= XMARKER (w
->pointm
)->charpos
;
11612 int new_pt_byte
= marker_byte_position (w
->pointm
);
11616 new_pt_byte
= BEGV_BYTE
;
11617 set_marker_both (w
->pointm
, Qnil
, BEGV
, BEGV_BYTE
);
11619 else if (new_pt
> (ZV
- 1))
11622 new_pt_byte
= ZV_BYTE
;
11623 set_marker_both (w
->pointm
, Qnil
, ZV
, ZV_BYTE
);
11626 /* We don't use SET_PT so that the point-motion hooks don't run. */
11627 TEMP_SET_PT_BOTH (new_pt
, new_pt_byte
);
11630 /* If any of the character widths specified in the display table
11631 have changed, invalidate the width run cache. It's true that
11632 this may be a bit late to catch such changes, but the rest of
11633 redisplay goes (non-fatally) haywire when the display table is
11634 changed, so why should we worry about doing any better? */
11635 if (current_buffer
->width_run_cache
)
11637 struct Lisp_Char_Table
*disptab
= buffer_display_table ();
11639 if (! disptab_matches_widthtab (disptab
,
11640 XVECTOR (current_buffer
->width_table
)))
11642 invalidate_region_cache (current_buffer
,
11643 current_buffer
->width_run_cache
,
11645 recompute_width_table (current_buffer
, disptab
);
11649 /* If window-start is screwed up, choose a new one. */
11650 if (XMARKER (w
->start
)->buffer
!= current_buffer
)
11653 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
11655 /* If someone specified a new starting point but did not insist,
11656 check whether it can be used. */
11657 if (!NILP (w
->optional_new_start
)
11658 && CHARPOS (startp
) >= BEGV
11659 && CHARPOS (startp
) <= ZV
)
11661 w
->optional_new_start
= Qnil
;
11662 start_display (&it
, w
, startp
);
11663 move_it_to (&it
, PT
, 0, it
.last_visible_y
, -1,
11664 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
11665 if (IT_CHARPOS (it
) == PT
)
11666 w
->force_start
= Qt
;
11667 /* IT may overshoot PT if text at PT is invisible. */
11668 else if (IT_CHARPOS (it
) > PT
&& CHARPOS (startp
) <= PT
)
11669 w
->force_start
= Qt
;
11674 /* Handle case where place to start displaying has been specified,
11675 unless the specified location is outside the accessible range. */
11676 if (!NILP (w
->force_start
)
11677 || w
->frozen_window_start_p
)
11679 /* We set this later on if we have to adjust point. */
11682 w
->force_start
= Qnil
;
11684 w
->window_end_valid
= Qnil
;
11686 /* Forget any recorded base line for line number display. */
11687 if (!buffer_unchanged_p
)
11688 w
->base_line_number
= Qnil
;
11690 /* Redisplay the mode line. Select the buffer properly for that.
11691 Also, run the hook window-scroll-functions
11692 because we have scrolled. */
11693 /* Note, we do this after clearing force_start because
11694 if there's an error, it is better to forget about force_start
11695 than to get into an infinite loop calling the hook functions
11696 and having them get more errors. */
11697 if (!update_mode_line
11698 || ! NILP (Vwindow_scroll_functions
))
11700 update_mode_line
= 1;
11701 w
->update_mode_line
= Qt
;
11702 startp
= run_window_scroll_functions (window
, startp
);
11705 w
->last_modified
= make_number (0);
11706 w
->last_overlay_modified
= make_number (0);
11707 if (CHARPOS (startp
) < BEGV
)
11708 SET_TEXT_POS (startp
, BEGV
, BEGV_BYTE
);
11709 else if (CHARPOS (startp
) > ZV
)
11710 SET_TEXT_POS (startp
, ZV
, ZV_BYTE
);
11712 /* Redisplay, then check if cursor has been set during the
11713 redisplay. Give up if new fonts were loaded. */
11714 if (!try_window (window
, startp
))
11716 w
->force_start
= Qt
;
11717 clear_glyph_matrix (w
->desired_matrix
);
11718 goto need_larger_matrices
;
11721 if (w
->cursor
.vpos
< 0 && !w
->frozen_window_start_p
)
11723 /* If point does not appear, try to move point so it does
11724 appear. The desired matrix has been built above, so we
11725 can use it here. */
11726 new_vpos
= window_box_height (w
) / 2;
11729 if (!make_cursor_line_fully_visible (w
, 0))
11731 /* Point does appear, but on a line partly visible at end of window.
11732 Move it back to a fully-visible line. */
11733 new_vpos
= window_box_height (w
);
11736 /* If we need to move point for either of the above reasons,
11737 now actually do it. */
11740 struct glyph_row
*row
;
11742 row
= MATRIX_FIRST_TEXT_ROW (w
->desired_matrix
);
11743 while (MATRIX_ROW_BOTTOM_Y (row
) < new_vpos
)
11746 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row
),
11747 MATRIX_ROW_START_BYTEPOS (row
));
11749 if (w
!= XWINDOW (selected_window
))
11750 set_marker_both (w
->pointm
, Qnil
, PT
, PT_BYTE
);
11751 else if (current_buffer
== old
)
11752 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
11754 set_cursor_from_row (w
, row
, w
->desired_matrix
, 0, 0, 0, 0);
11756 /* If we are highlighting the region, then we just changed
11757 the region, so redisplay to show it. */
11758 if (!NILP (Vtransient_mark_mode
)
11759 && !NILP (current_buffer
->mark_active
))
11761 clear_glyph_matrix (w
->desired_matrix
);
11762 if (!try_window (window
, startp
))
11763 goto need_larger_matrices
;
11768 debug_method_add (w
, "forced window start");
11773 /* Handle case where text has not changed, only point, and it has
11774 not moved off the frame, and we are not retrying after hscroll.
11775 (current_matrix_up_to_date_p is nonzero when retrying.) */
11776 if (current_matrix_up_to_date_p
11777 && (rc
= try_cursor_movement (window
, startp
, &temp_scroll_step
),
11778 rc
!= CURSOR_MOVEMENT_CANNOT_BE_USED
))
11782 case CURSOR_MOVEMENT_SUCCESS
:
11783 used_current_matrix_p
= 1;
11786 #if 0 /* try_cursor_movement never returns this value. */
11787 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES
:
11788 goto need_larger_matrices
;
11791 case CURSOR_MOVEMENT_MUST_SCROLL
:
11792 goto try_to_scroll
;
11798 /* If current starting point was originally the beginning of a line
11799 but no longer is, find a new starting point. */
11800 else if (!NILP (w
->start_at_line_beg
)
11801 && !(CHARPOS (startp
) <= BEGV
11802 || FETCH_BYTE (BYTEPOS (startp
) - 1) == '\n'))
11805 debug_method_add (w
, "recenter 1");
11810 /* Try scrolling with try_window_id. Value is > 0 if update has
11811 been done, it is -1 if we know that the same window start will
11812 not work. It is 0 if unsuccessful for some other reason. */
11813 else if ((tem
= try_window_id (w
)) != 0)
11816 debug_method_add (w
, "try_window_id %d", tem
);
11819 if (fonts_changed_p
)
11820 goto need_larger_matrices
;
11824 /* Otherwise try_window_id has returned -1 which means that we
11825 don't want the alternative below this comment to execute. */
11827 else if (CHARPOS (startp
) >= BEGV
11828 && CHARPOS (startp
) <= ZV
11829 && PT
>= CHARPOS (startp
)
11830 && (CHARPOS (startp
) < ZV
11831 /* Avoid starting at end of buffer. */
11832 || CHARPOS (startp
) == BEGV
11833 || (XFASTINT (w
->last_modified
) >= MODIFF
11834 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
)))
11837 debug_method_add (w
, "same window start");
11840 /* Try to redisplay starting at same place as before.
11841 If point has not moved off frame, accept the results. */
11842 if (!current_matrix_up_to_date_p
11843 /* Don't use try_window_reusing_current_matrix in this case
11844 because a window scroll function can have changed the
11846 || !NILP (Vwindow_scroll_functions
)
11847 || MINI_WINDOW_P (w
)
11848 || !(used_current_matrix_p
=
11849 try_window_reusing_current_matrix (w
)))
11851 IF_DEBUG (debug_method_add (w
, "1"));
11852 try_window (window
, startp
);
11855 if (fonts_changed_p
)
11856 goto need_larger_matrices
;
11858 if (w
->cursor
.vpos
>= 0)
11860 if (!just_this_one_p
11861 || current_buffer
->clip_changed
11862 || BEG_UNCHANGED
< CHARPOS (startp
))
11863 /* Forget any recorded base line for line number display. */
11864 w
->base_line_number
= Qnil
;
11866 if (!make_cursor_line_fully_visible (w
, 1))
11868 clear_glyph_matrix (w
->desired_matrix
);
11869 last_line_misfit
= 1;
11871 /* Drop through and scroll. */
11876 clear_glyph_matrix (w
->desired_matrix
);
11881 w
->last_modified
= make_number (0);
11882 w
->last_overlay_modified
= make_number (0);
11884 /* Redisplay the mode line. Select the buffer properly for that. */
11885 if (!update_mode_line
)
11887 update_mode_line
= 1;
11888 w
->update_mode_line
= Qt
;
11891 /* Try to scroll by specified few lines. */
11892 if ((scroll_conservatively
11894 || temp_scroll_step
11895 || NUMBERP (current_buffer
->scroll_up_aggressively
)
11896 || NUMBERP (current_buffer
->scroll_down_aggressively
))
11897 && !current_buffer
->clip_changed
11898 && CHARPOS (startp
) >= BEGV
11899 && CHARPOS (startp
) <= ZV
)
11901 /* The function returns -1 if new fonts were loaded, 1 if
11902 successful, 0 if not successful. */
11903 int rc
= try_scrolling (window
, just_this_one_p
,
11904 scroll_conservatively
,
11906 temp_scroll_step
, last_line_misfit
);
11909 case SCROLLING_SUCCESS
:
11912 case SCROLLING_NEED_LARGER_MATRICES
:
11913 goto need_larger_matrices
;
11915 case SCROLLING_FAILED
:
11923 /* Finally, just choose place to start which centers point */
11926 centering_position
= window_box_height (w
) / 2;
11929 /* Jump here with centering_position already set to 0. */
11932 debug_method_add (w
, "recenter");
11935 /* w->vscroll = 0; */
11937 /* Forget any previously recorded base line for line number display. */
11938 if (!buffer_unchanged_p
)
11939 w
->base_line_number
= Qnil
;
11941 /* Move backward half the height of the window. */
11942 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
11943 it
.current_y
= it
.last_visible_y
;
11944 move_it_vertically_backward (&it
, centering_position
);
11945 xassert (IT_CHARPOS (it
) >= BEGV
);
11947 /* The function move_it_vertically_backward may move over more
11948 than the specified y-distance. If it->w is small, e.g. a
11949 mini-buffer window, we may end up in front of the window's
11950 display area. Start displaying at the start of the line
11951 containing PT in this case. */
11952 if (it
.current_y
<= 0)
11954 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
11955 move_it_vertically (&it
, 0);
11956 xassert (IT_CHARPOS (it
) <= PT
);
11960 it
.current_x
= it
.hpos
= 0;
11962 /* Set startp here explicitly in case that helps avoid an infinite loop
11963 in case the window-scroll-functions functions get errors. */
11964 set_marker_both (w
->start
, Qnil
, IT_CHARPOS (it
), IT_BYTEPOS (it
));
11966 /* Run scroll hooks. */
11967 startp
= run_window_scroll_functions (window
, it
.current
.pos
);
11969 /* Redisplay the window. */
11970 if (!current_matrix_up_to_date_p
11971 || windows_or_buffers_changed
11972 || cursor_type_changed
11973 /* Don't use try_window_reusing_current_matrix in this case
11974 because it can have changed the buffer. */
11975 || !NILP (Vwindow_scroll_functions
)
11976 || !just_this_one_p
11977 || MINI_WINDOW_P (w
)
11978 || !(used_current_matrix_p
=
11979 try_window_reusing_current_matrix (w
)))
11980 try_window (window
, startp
);
11982 /* If new fonts have been loaded (due to fontsets), give up. We
11983 have to start a new redisplay since we need to re-adjust glyph
11985 if (fonts_changed_p
)
11986 goto need_larger_matrices
;
11988 /* If cursor did not appear assume that the middle of the window is
11989 in the first line of the window. Do it again with the next line.
11990 (Imagine a window of height 100, displaying two lines of height
11991 60. Moving back 50 from it->last_visible_y will end in the first
11993 if (w
->cursor
.vpos
< 0)
11995 if (!NILP (w
->window_end_valid
)
11996 && PT
>= Z
- XFASTINT (w
->window_end_pos
))
11998 clear_glyph_matrix (w
->desired_matrix
);
11999 move_it_by_lines (&it
, 1, 0);
12000 try_window (window
, it
.current
.pos
);
12002 else if (PT
< IT_CHARPOS (it
))
12004 clear_glyph_matrix (w
->desired_matrix
);
12005 move_it_by_lines (&it
, -1, 0);
12006 try_window (window
, it
.current
.pos
);
12010 /* Not much we can do about it. */
12014 /* Consider the following case: Window starts at BEGV, there is
12015 invisible, intangible text at BEGV, so that display starts at
12016 some point START > BEGV. It can happen that we are called with
12017 PT somewhere between BEGV and START. Try to handle that case. */
12018 if (w
->cursor
.vpos
< 0)
12020 struct glyph_row
*row
= w
->current_matrix
->rows
;
12021 if (row
->mode_line_p
)
12023 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
12026 if (!make_cursor_line_fully_visible (w
, centering_position
> 0))
12028 /* If vscroll is enabled, disable it and try again. */
12032 clear_glyph_matrix (w
->desired_matrix
);
12036 /* If centering point failed to make the whole line visible,
12037 put point at the top instead. That has to make the whole line
12038 visible, if it can be done. */
12039 clear_glyph_matrix (w
->desired_matrix
);
12040 centering_position
= 0;
12046 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
12047 w
->start_at_line_beg
= ((CHARPOS (startp
) == BEGV
12048 || FETCH_BYTE (BYTEPOS (startp
) - 1) == '\n')
12051 /* Display the mode line, if we must. */
12052 if ((update_mode_line
12053 /* If window not full width, must redo its mode line
12054 if (a) the window to its side is being redone and
12055 (b) we do a frame-based redisplay. This is a consequence
12056 of how inverted lines are drawn in frame-based redisplay. */
12057 || (!just_this_one_p
12058 && !FRAME_WINDOW_P (f
)
12059 && !WINDOW_FULL_WIDTH_P (w
))
12060 /* Line number to display. */
12061 || INTEGERP (w
->base_line_pos
)
12062 /* Column number is displayed and different from the one displayed. */
12063 || (!NILP (w
->column_number_displayed
)
12064 && (XFASTINT (w
->column_number_displayed
)
12065 != (int) current_column ()))) /* iftc */
12066 /* This means that the window has a mode line. */
12067 && (WINDOW_WANTS_MODELINE_P (w
)
12068 || WINDOW_WANTS_HEADER_LINE_P (w
)))
12070 display_mode_lines (w
);
12072 /* If mode line height has changed, arrange for a thorough
12073 immediate redisplay using the correct mode line height. */
12074 if (WINDOW_WANTS_MODELINE_P (w
)
12075 && CURRENT_MODE_LINE_HEIGHT (w
) != DESIRED_MODE_LINE_HEIGHT (w
))
12077 fonts_changed_p
= 1;
12078 MATRIX_MODE_LINE_ROW (w
->current_matrix
)->height
12079 = DESIRED_MODE_LINE_HEIGHT (w
);
12082 /* If top line height has changed, arrange for a thorough
12083 immediate redisplay using the correct mode line height. */
12084 if (WINDOW_WANTS_HEADER_LINE_P (w
)
12085 && CURRENT_HEADER_LINE_HEIGHT (w
) != DESIRED_HEADER_LINE_HEIGHT (w
))
12087 fonts_changed_p
= 1;
12088 MATRIX_HEADER_LINE_ROW (w
->current_matrix
)->height
12089 = DESIRED_HEADER_LINE_HEIGHT (w
);
12092 if (fonts_changed_p
)
12093 goto need_larger_matrices
;
12096 if (!line_number_displayed
12097 && !BUFFERP (w
->base_line_pos
))
12099 w
->base_line_pos
= Qnil
;
12100 w
->base_line_number
= Qnil
;
12105 /* When we reach a frame's selected window, redo the frame's menu bar. */
12106 if (update_mode_line
12107 && EQ (FRAME_SELECTED_WINDOW (f
), window
))
12109 int redisplay_menu_p
= 0;
12110 int redisplay_tool_bar_p
= 0;
12112 if (FRAME_WINDOW_P (f
))
12114 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
12115 || defined (USE_GTK)
12116 redisplay_menu_p
= FRAME_EXTERNAL_MENU_BAR (f
);
12118 redisplay_menu_p
= FRAME_MENU_BAR_LINES (f
) > 0;
12122 redisplay_menu_p
= FRAME_MENU_BAR_LINES (f
) > 0;
12124 if (redisplay_menu_p
)
12125 display_menu_bar (w
);
12127 #ifdef HAVE_WINDOW_SYSTEM
12129 redisplay_tool_bar_p
= FRAME_EXTERNAL_TOOL_BAR (f
);
12131 redisplay_tool_bar_p
= WINDOWP (f
->tool_bar_window
)
12132 && (FRAME_TOOL_BAR_LINES (f
) > 0
12133 || auto_resize_tool_bars_p
);
12137 if (redisplay_tool_bar_p
)
12138 redisplay_tool_bar (f
);
12142 #ifdef HAVE_WINDOW_SYSTEM
12143 if (update_window_fringes (w
, 0)
12144 && !just_this_one_p
12145 && (used_current_matrix_p
|| overlay_arrow_seen
)
12146 && !w
->pseudo_window_p
)
12150 draw_window_fringes (w
);
12154 #endif /* HAVE_WINDOW_SYSTEM */
12156 /* We go to this label, with fonts_changed_p nonzero,
12157 if it is necessary to try again using larger glyph matrices.
12158 We have to redeem the scroll bar even in this case,
12159 because the loop in redisplay_internal expects that. */
12160 need_larger_matrices
:
12162 finish_scroll_bars
:
12164 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w
))
12166 /* Set the thumb's position and size. */
12167 set_vertical_scroll_bar (w
);
12169 /* Note that we actually used the scroll bar attached to this
12170 window, so it shouldn't be deleted at the end of redisplay. */
12171 redeem_scroll_bar_hook (w
);
12174 /* Restore current_buffer and value of point in it. */
12175 TEMP_SET_PT_BOTH (CHARPOS (opoint
), BYTEPOS (opoint
));
12176 set_buffer_internal_1 (old
);
12177 TEMP_SET_PT_BOTH (CHARPOS (lpoint
), BYTEPOS (lpoint
));
12179 unbind_to (count
, Qnil
);
12183 /* Build the complete desired matrix of WINDOW with a window start
12184 buffer position POS. Value is non-zero if successful. It is zero
12185 if fonts were loaded during redisplay which makes re-adjusting
12186 glyph matrices necessary. */
12189 try_window (window
, pos
)
12190 Lisp_Object window
;
12191 struct text_pos pos
;
12193 struct window
*w
= XWINDOW (window
);
12195 struct glyph_row
*last_text_row
= NULL
;
12197 /* Make POS the new window start. */
12198 set_marker_both (w
->start
, Qnil
, CHARPOS (pos
), BYTEPOS (pos
));
12200 /* Mark cursor position as unknown. No overlay arrow seen. */
12201 w
->cursor
.vpos
= -1;
12202 overlay_arrow_seen
= 0;
12204 /* Initialize iterator and info to start at POS. */
12205 start_display (&it
, w
, pos
);
12207 /* Display all lines of W. */
12208 while (it
.current_y
< it
.last_visible_y
)
12210 if (display_line (&it
))
12211 last_text_row
= it
.glyph_row
- 1;
12212 if (fonts_changed_p
)
12216 /* If bottom moved off end of frame, change mode line percentage. */
12217 if (XFASTINT (w
->window_end_pos
) <= 0
12218 && Z
!= IT_CHARPOS (it
))
12219 w
->update_mode_line
= Qt
;
12221 /* Set window_end_pos to the offset of the last character displayed
12222 on the window from the end of current_buffer. Set
12223 window_end_vpos to its row number. */
12226 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row
));
12227 w
->window_end_bytepos
12228 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
12230 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
12232 = make_number (MATRIX_ROW_VPOS (last_text_row
, w
->desired_matrix
));
12233 xassert (MATRIX_ROW (w
->desired_matrix
, XFASTINT (w
->window_end_vpos
))
12234 ->displays_text_p
);
12238 w
->window_end_bytepos
= Z_BYTE
- ZV_BYTE
;
12239 w
->window_end_pos
= make_number (Z
- ZV
);
12240 w
->window_end_vpos
= make_number (0);
12243 /* But that is not valid info until redisplay finishes. */
12244 w
->window_end_valid
= Qnil
;
12250 /************************************************************************
12251 Window redisplay reusing current matrix when buffer has not changed
12252 ************************************************************************/
12254 /* Try redisplay of window W showing an unchanged buffer with a
12255 different window start than the last time it was displayed by
12256 reusing its current matrix. Value is non-zero if successful.
12257 W->start is the new window start. */
12260 try_window_reusing_current_matrix (w
)
12263 struct frame
*f
= XFRAME (w
->frame
);
12264 struct glyph_row
*row
, *bottom_row
;
12267 struct text_pos start
, new_start
;
12268 int nrows_scrolled
, i
;
12269 struct glyph_row
*last_text_row
;
12270 struct glyph_row
*last_reused_text_row
;
12271 struct glyph_row
*start_row
;
12272 int start_vpos
, min_y
, max_y
;
12275 if (inhibit_try_window_reusing
)
12279 if (/* This function doesn't handle terminal frames. */
12280 !FRAME_WINDOW_P (f
)
12281 /* Don't try to reuse the display if windows have been split
12283 || windows_or_buffers_changed
12284 || cursor_type_changed
)
12287 /* Can't do this if region may have changed. */
12288 if ((!NILP (Vtransient_mark_mode
)
12289 && !NILP (current_buffer
->mark_active
))
12290 || !NILP (w
->region_showing
)
12291 || !NILP (Vshow_trailing_whitespace
))
12294 /* If top-line visibility has changed, give up. */
12295 if (WINDOW_WANTS_HEADER_LINE_P (w
)
12296 != MATRIX_HEADER_LINE_ROW (w
->current_matrix
)->mode_line_p
)
12299 /* Give up if old or new display is scrolled vertically. We could
12300 make this function handle this, but right now it doesn't. */
12301 start_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
12302 if (w
->vscroll
|| MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row
))
12305 /* The variable new_start now holds the new window start. The old
12306 start `start' can be determined from the current matrix. */
12307 SET_TEXT_POS_FROM_MARKER (new_start
, w
->start
);
12308 start
= start_row
->start
.pos
;
12309 start_vpos
= MATRIX_ROW_VPOS (start_row
, w
->current_matrix
);
12311 /* Clear the desired matrix for the display below. */
12312 clear_glyph_matrix (w
->desired_matrix
);
12314 if (CHARPOS (new_start
) <= CHARPOS (start
))
12318 /* Don't use this method if the display starts with an ellipsis
12319 displayed for invisible text. It's not easy to handle that case
12320 below, and it's certainly not worth the effort since this is
12321 not a frequent case. */
12322 if (in_ellipses_for_invisible_text_p (&start_row
->start
, w
))
12325 IF_DEBUG (debug_method_add (w
, "twu1"));
12327 /* Display up to a row that can be reused. The variable
12328 last_text_row is set to the last row displayed that displays
12329 text. Note that it.vpos == 0 if or if not there is a
12330 header-line; it's not the same as the MATRIX_ROW_VPOS! */
12331 start_display (&it
, w
, new_start
);
12332 first_row_y
= it
.current_y
;
12333 w
->cursor
.vpos
= -1;
12334 last_text_row
= last_reused_text_row
= NULL
;
12336 while (it
.current_y
< it
.last_visible_y
12337 && IT_CHARPOS (it
) < CHARPOS (start
)
12338 && !fonts_changed_p
)
12339 if (display_line (&it
))
12340 last_text_row
= it
.glyph_row
- 1;
12342 /* A value of current_y < last_visible_y means that we stopped
12343 at the previous window start, which in turn means that we
12344 have at least one reusable row. */
12345 if (it
.current_y
< it
.last_visible_y
)
12347 /* IT.vpos always starts from 0; it counts text lines. */
12348 nrows_scrolled
= it
.vpos
;
12350 /* Find PT if not already found in the lines displayed. */
12351 if (w
->cursor
.vpos
< 0)
12353 int dy
= it
.current_y
- first_row_y
;
12355 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
12356 row
= row_containing_pos (w
, PT
, row
, NULL
, dy
);
12358 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0,
12359 dy
, nrows_scrolled
);
12362 clear_glyph_matrix (w
->desired_matrix
);
12367 /* Scroll the display. Do it before the current matrix is
12368 changed. The problem here is that update has not yet
12369 run, i.e. part of the current matrix is not up to date.
12370 scroll_run_hook will clear the cursor, and use the
12371 current matrix to get the height of the row the cursor is
12373 run
.current_y
= first_row_y
;
12374 run
.desired_y
= it
.current_y
;
12375 run
.height
= it
.last_visible_y
- it
.current_y
;
12377 if (run
.height
> 0 && run
.current_y
!= run
.desired_y
)
12380 rif
->update_window_begin_hook (w
);
12381 rif
->clear_window_mouse_face (w
);
12382 rif
->scroll_run_hook (w
, &run
);
12383 rif
->update_window_end_hook (w
, 0, 0);
12387 /* Shift current matrix down by nrows_scrolled lines. */
12388 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
12389 rotate_matrix (w
->current_matrix
,
12391 MATRIX_ROW_VPOS (bottom_row
, w
->current_matrix
),
12394 /* Disable lines that must be updated. */
12395 for (i
= 0; i
< it
.vpos
; ++i
)
12396 (start_row
+ i
)->enabled_p
= 0;
12398 /* Re-compute Y positions. */
12399 min_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
12400 max_y
= it
.last_visible_y
;
12401 for (row
= start_row
+ nrows_scrolled
;
12405 row
->y
= it
.current_y
;
12406 row
->visible_height
= row
->height
;
12408 if (row
->y
< min_y
)
12409 row
->visible_height
-= min_y
- row
->y
;
12410 if (row
->y
+ row
->height
> max_y
)
12411 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
12412 row
->redraw_fringe_bitmaps_p
= 1;
12414 it
.current_y
+= row
->height
;
12416 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
12417 last_reused_text_row
= row
;
12418 if (MATRIX_ROW_BOTTOM_Y (row
) >= it
.last_visible_y
)
12422 /* Disable lines in the current matrix which are now
12423 below the window. */
12424 for (++row
; row
< bottom_row
; ++row
)
12425 row
->enabled_p
= 0;
12428 /* Update window_end_pos etc.; last_reused_text_row is the last
12429 reused row from the current matrix containing text, if any.
12430 The value of last_text_row is the last displayed line
12431 containing text. */
12432 if (last_reused_text_row
)
12434 w
->window_end_bytepos
12435 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_reused_text_row
);
12437 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_reused_text_row
));
12439 = make_number (MATRIX_ROW_VPOS (last_reused_text_row
,
12440 w
->current_matrix
));
12442 else if (last_text_row
)
12444 w
->window_end_bytepos
12445 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
12447 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
12449 = make_number (MATRIX_ROW_VPOS (last_text_row
, w
->desired_matrix
));
12453 /* This window must be completely empty. */
12454 w
->window_end_bytepos
= Z_BYTE
- ZV_BYTE
;
12455 w
->window_end_pos
= make_number (Z
- ZV
);
12456 w
->window_end_vpos
= make_number (0);
12458 w
->window_end_valid
= Qnil
;
12460 /* Update hint: don't try scrolling again in update_window. */
12461 w
->desired_matrix
->no_scrolling_p
= 1;
12464 debug_method_add (w
, "try_window_reusing_current_matrix 1");
12468 else if (CHARPOS (new_start
) > CHARPOS (start
))
12470 struct glyph_row
*pt_row
, *row
;
12471 struct glyph_row
*first_reusable_row
;
12472 struct glyph_row
*first_row_to_display
;
12474 int yb
= window_text_bottom_y (w
);
12476 /* Find the row starting at new_start, if there is one. Don't
12477 reuse a partially visible line at the end. */
12478 first_reusable_row
= start_row
;
12479 while (first_reusable_row
->enabled_p
12480 && MATRIX_ROW_BOTTOM_Y (first_reusable_row
) < yb
12481 && (MATRIX_ROW_START_CHARPOS (first_reusable_row
)
12482 < CHARPOS (new_start
)))
12483 ++first_reusable_row
;
12485 /* Give up if there is no row to reuse. */
12486 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row
) >= yb
12487 || !first_reusable_row
->enabled_p
12488 || (MATRIX_ROW_START_CHARPOS (first_reusable_row
)
12489 != CHARPOS (new_start
)))
12492 /* We can reuse fully visible rows beginning with
12493 first_reusable_row to the end of the window. Set
12494 first_row_to_display to the first row that cannot be reused.
12495 Set pt_row to the row containing point, if there is any. */
12497 for (first_row_to_display
= first_reusable_row
;
12498 MATRIX_ROW_BOTTOM_Y (first_row_to_display
) < yb
;
12499 ++first_row_to_display
)
12501 if (PT
>= MATRIX_ROW_START_CHARPOS (first_row_to_display
)
12502 && PT
< MATRIX_ROW_END_CHARPOS (first_row_to_display
))
12503 pt_row
= first_row_to_display
;
12506 /* Start displaying at the start of first_row_to_display. */
12507 xassert (first_row_to_display
->y
< yb
);
12508 init_to_row_start (&it
, w
, first_row_to_display
);
12510 nrows_scrolled
= (MATRIX_ROW_VPOS (first_reusable_row
, w
->current_matrix
)
12512 it
.vpos
= (MATRIX_ROW_VPOS (first_row_to_display
, w
->current_matrix
)
12514 it
.current_y
= (first_row_to_display
->y
- first_reusable_row
->y
12515 + WINDOW_HEADER_LINE_HEIGHT (w
));
12517 /* Display lines beginning with first_row_to_display in the
12518 desired matrix. Set last_text_row to the last row displayed
12519 that displays text. */
12520 it
.glyph_row
= MATRIX_ROW (w
->desired_matrix
, it
.vpos
);
12521 if (pt_row
== NULL
)
12522 w
->cursor
.vpos
= -1;
12523 last_text_row
= NULL
;
12524 while (it
.current_y
< it
.last_visible_y
&& !fonts_changed_p
)
12525 if (display_line (&it
))
12526 last_text_row
= it
.glyph_row
- 1;
12528 /* Give up If point isn't in a row displayed or reused. */
12529 if (w
->cursor
.vpos
< 0)
12531 clear_glyph_matrix (w
->desired_matrix
);
12535 /* If point is in a reused row, adjust y and vpos of the cursor
12539 w
->cursor
.vpos
-= MATRIX_ROW_VPOS (first_reusable_row
,
12540 w
->current_matrix
);
12541 w
->cursor
.y
-= first_reusable_row
->y
;
12544 /* Scroll the display. */
12545 run
.current_y
= first_reusable_row
->y
;
12546 run
.desired_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
12547 run
.height
= it
.last_visible_y
- run
.current_y
;
12548 dy
= run
.current_y
- run
.desired_y
;
12553 rif
->update_window_begin_hook (w
);
12554 rif
->clear_window_mouse_face (w
);
12555 rif
->scroll_run_hook (w
, &run
);
12556 rif
->update_window_end_hook (w
, 0, 0);
12560 /* Adjust Y positions of reused rows. */
12561 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
12562 min_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
12563 max_y
= it
.last_visible_y
;
12564 for (row
= first_reusable_row
; row
< first_row_to_display
; ++row
)
12567 row
->visible_height
= row
->height
;
12568 if (row
->y
< min_y
)
12569 row
->visible_height
-= min_y
- row
->y
;
12570 if (row
->y
+ row
->height
> max_y
)
12571 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
12572 row
->redraw_fringe_bitmaps_p
= 1;
12575 /* Scroll the current matrix. */
12576 xassert (nrows_scrolled
> 0);
12577 rotate_matrix (w
->current_matrix
,
12579 MATRIX_ROW_VPOS (bottom_row
, w
->current_matrix
),
12582 /* Disable rows not reused. */
12583 for (row
-= nrows_scrolled
; row
< bottom_row
; ++row
)
12584 row
->enabled_p
= 0;
12586 /* Adjust window end. A null value of last_text_row means that
12587 the window end is in reused rows which in turn means that
12588 only its vpos can have changed. */
12591 w
->window_end_bytepos
12592 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
12594 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
12596 = make_number (MATRIX_ROW_VPOS (last_text_row
, w
->desired_matrix
));
12601 = make_number (XFASTINT (w
->window_end_vpos
) - nrows_scrolled
);
12604 w
->window_end_valid
= Qnil
;
12605 w
->desired_matrix
->no_scrolling_p
= 1;
12608 debug_method_add (w
, "try_window_reusing_current_matrix 2");
12618 /************************************************************************
12619 Window redisplay reusing current matrix when buffer has changed
12620 ************************************************************************/
12622 static struct glyph_row
*find_last_unchanged_at_beg_row
P_ ((struct window
*));
12623 static struct glyph_row
*find_first_unchanged_at_end_row
P_ ((struct window
*,
12625 static struct glyph_row
*
12626 find_last_row_displaying_text
P_ ((struct glyph_matrix
*, struct it
*,
12627 struct glyph_row
*));
12630 /* Return the last row in MATRIX displaying text. If row START is
12631 non-null, start searching with that row. IT gives the dimensions
12632 of the display. Value is null if matrix is empty; otherwise it is
12633 a pointer to the row found. */
12635 static struct glyph_row
*
12636 find_last_row_displaying_text (matrix
, it
, start
)
12637 struct glyph_matrix
*matrix
;
12639 struct glyph_row
*start
;
12641 struct glyph_row
*row
, *row_found
;
12643 /* Set row_found to the last row in IT->w's current matrix
12644 displaying text. The loop looks funny but think of partially
12647 row
= start
? start
: MATRIX_FIRST_TEXT_ROW (matrix
);
12648 while (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
12650 xassert (row
->enabled_p
);
12652 if (MATRIX_ROW_BOTTOM_Y (row
) >= it
->last_visible_y
)
12661 /* Return the last row in the current matrix of W that is not affected
12662 by changes at the start of current_buffer that occurred since W's
12663 current matrix was built. Value is null if no such row exists.
12665 BEG_UNCHANGED us the number of characters unchanged at the start of
12666 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
12667 first changed character in current_buffer. Characters at positions <
12668 BEG + BEG_UNCHANGED are at the same buffer positions as they were
12669 when the current matrix was built. */
12671 static struct glyph_row
*
12672 find_last_unchanged_at_beg_row (w
)
12675 int first_changed_pos
= BEG
+ BEG_UNCHANGED
;
12676 struct glyph_row
*row
;
12677 struct glyph_row
*row_found
= NULL
;
12678 int yb
= window_text_bottom_y (w
);
12680 /* Find the last row displaying unchanged text. */
12681 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
12682 while (MATRIX_ROW_DISPLAYS_TEXT_P (row
)
12683 && MATRIX_ROW_START_CHARPOS (row
) < first_changed_pos
)
12685 if (/* If row ends before first_changed_pos, it is unchanged,
12686 except in some case. */
12687 MATRIX_ROW_END_CHARPOS (row
) <= first_changed_pos
12688 /* When row ends in ZV and we write at ZV it is not
12690 && !row
->ends_at_zv_p
12691 /* When first_changed_pos is the end of a continued line,
12692 row is not unchanged because it may be no longer
12694 && !(MATRIX_ROW_END_CHARPOS (row
) == first_changed_pos
12695 && (row
->continued_p
12696 || row
->exact_window_width_line_p
)))
12699 /* Stop if last visible row. */
12700 if (MATRIX_ROW_BOTTOM_Y (row
) >= yb
)
12710 /* Find the first glyph row in the current matrix of W that is not
12711 affected by changes at the end of current_buffer since the
12712 time W's current matrix was built.
12714 Return in *DELTA the number of chars by which buffer positions in
12715 unchanged text at the end of current_buffer must be adjusted.
12717 Return in *DELTA_BYTES the corresponding number of bytes.
12719 Value is null if no such row exists, i.e. all rows are affected by
12722 static struct glyph_row
*
12723 find_first_unchanged_at_end_row (w
, delta
, delta_bytes
)
12725 int *delta
, *delta_bytes
;
12727 struct glyph_row
*row
;
12728 struct glyph_row
*row_found
= NULL
;
12730 *delta
= *delta_bytes
= 0;
12732 /* Display must not have been paused, otherwise the current matrix
12733 is not up to date. */
12734 if (NILP (w
->window_end_valid
))
12737 /* A value of window_end_pos >= END_UNCHANGED means that the window
12738 end is in the range of changed text. If so, there is no
12739 unchanged row at the end of W's current matrix. */
12740 if (XFASTINT (w
->window_end_pos
) >= END_UNCHANGED
)
12743 /* Set row to the last row in W's current matrix displaying text. */
12744 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
12746 /* If matrix is entirely empty, no unchanged row exists. */
12747 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
12749 /* The value of row is the last glyph row in the matrix having a
12750 meaningful buffer position in it. The end position of row
12751 corresponds to window_end_pos. This allows us to translate
12752 buffer positions in the current matrix to current buffer
12753 positions for characters not in changed text. */
12754 int Z_old
= MATRIX_ROW_END_CHARPOS (row
) + XFASTINT (w
->window_end_pos
);
12755 int Z_BYTE_old
= MATRIX_ROW_END_BYTEPOS (row
) + w
->window_end_bytepos
;
12756 int last_unchanged_pos
, last_unchanged_pos_old
;
12757 struct glyph_row
*first_text_row
12758 = MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
12760 *delta
= Z
- Z_old
;
12761 *delta_bytes
= Z_BYTE
- Z_BYTE_old
;
12763 /* Set last_unchanged_pos to the buffer position of the last
12764 character in the buffer that has not been changed. Z is the
12765 index + 1 of the last character in current_buffer, i.e. by
12766 subtracting END_UNCHANGED we get the index of the last
12767 unchanged character, and we have to add BEG to get its buffer
12769 last_unchanged_pos
= Z
- END_UNCHANGED
+ BEG
;
12770 last_unchanged_pos_old
= last_unchanged_pos
- *delta
;
12772 /* Search backward from ROW for a row displaying a line that
12773 starts at a minimum position >= last_unchanged_pos_old. */
12774 for (; row
> first_text_row
; --row
)
12776 if (!row
->enabled_p
|| !MATRIX_ROW_DISPLAYS_TEXT_P (row
))
12779 if (MATRIX_ROW_START_CHARPOS (row
) >= last_unchanged_pos_old
)
12784 if (row_found
&& !MATRIX_ROW_DISPLAYS_TEXT_P (row_found
))
12791 /* Make sure that glyph rows in the current matrix of window W
12792 reference the same glyph memory as corresponding rows in the
12793 frame's frame matrix. This function is called after scrolling W's
12794 current matrix on a terminal frame in try_window_id and
12795 try_window_reusing_current_matrix. */
12798 sync_frame_with_window_matrix_rows (w
)
12801 struct frame
*f
= XFRAME (w
->frame
);
12802 struct glyph_row
*window_row
, *window_row_end
, *frame_row
;
12804 /* Preconditions: W must be a leaf window and full-width. Its frame
12805 must have a frame matrix. */
12806 xassert (NILP (w
->hchild
) && NILP (w
->vchild
));
12807 xassert (WINDOW_FULL_WIDTH_P (w
));
12808 xassert (!FRAME_WINDOW_P (f
));
12810 /* If W is a full-width window, glyph pointers in W's current matrix
12811 have, by definition, to be the same as glyph pointers in the
12812 corresponding frame matrix. Note that frame matrices have no
12813 marginal areas (see build_frame_matrix). */
12814 window_row
= w
->current_matrix
->rows
;
12815 window_row_end
= window_row
+ w
->current_matrix
->nrows
;
12816 frame_row
= f
->current_matrix
->rows
+ WINDOW_TOP_EDGE_LINE (w
);
12817 while (window_row
< window_row_end
)
12819 struct glyph
*start
= window_row
->glyphs
[LEFT_MARGIN_AREA
];
12820 struct glyph
*end
= window_row
->glyphs
[LAST_AREA
];
12822 frame_row
->glyphs
[LEFT_MARGIN_AREA
] = start
;
12823 frame_row
->glyphs
[TEXT_AREA
] = start
;
12824 frame_row
->glyphs
[RIGHT_MARGIN_AREA
] = end
;
12825 frame_row
->glyphs
[LAST_AREA
] = end
;
12827 /* Disable frame rows whose corresponding window rows have
12828 been disabled in try_window_id. */
12829 if (!window_row
->enabled_p
)
12830 frame_row
->enabled_p
= 0;
12832 ++window_row
, ++frame_row
;
12837 /* Find the glyph row in window W containing CHARPOS. Consider all
12838 rows between START and END (not inclusive). END null means search
12839 all rows to the end of the display area of W. Value is the row
12840 containing CHARPOS or null. */
12843 row_containing_pos (w
, charpos
, start
, end
, dy
)
12846 struct glyph_row
*start
, *end
;
12849 struct glyph_row
*row
= start
;
12852 /* If we happen to start on a header-line, skip that. */
12853 if (row
->mode_line_p
)
12856 if ((end
&& row
>= end
) || !row
->enabled_p
)
12859 last_y
= window_text_bottom_y (w
) - dy
;
12863 /* Give up if we have gone too far. */
12864 if (end
&& row
>= end
)
12866 /* This formerly returned if they were equal.
12867 I think that both quantities are of a "last plus one" type;
12868 if so, when they are equal, the row is within the screen. -- rms. */
12869 if (MATRIX_ROW_BOTTOM_Y (row
) > last_y
)
12872 /* If it is in this row, return this row. */
12873 if (! (MATRIX_ROW_END_CHARPOS (row
) < charpos
12874 || (MATRIX_ROW_END_CHARPOS (row
) == charpos
12875 /* The end position of a row equals the start
12876 position of the next row. If CHARPOS is there, we
12877 would rather display it in the next line, except
12878 when this line ends in ZV. */
12879 && !row
->ends_at_zv_p
12880 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
)))
12881 && charpos
>= MATRIX_ROW_START_CHARPOS (row
))
12888 /* Try to redisplay window W by reusing its existing display. W's
12889 current matrix must be up to date when this function is called,
12890 i.e. window_end_valid must not be nil.
12894 1 if display has been updated
12895 0 if otherwise unsuccessful
12896 -1 if redisplay with same window start is known not to succeed
12898 The following steps are performed:
12900 1. Find the last row in the current matrix of W that is not
12901 affected by changes at the start of current_buffer. If no such row
12904 2. Find the first row in W's current matrix that is not affected by
12905 changes at the end of current_buffer. Maybe there is no such row.
12907 3. Display lines beginning with the row + 1 found in step 1 to the
12908 row found in step 2 or, if step 2 didn't find a row, to the end of
12911 4. If cursor is not known to appear on the window, give up.
12913 5. If display stopped at the row found in step 2, scroll the
12914 display and current matrix as needed.
12916 6. Maybe display some lines at the end of W, if we must. This can
12917 happen under various circumstances, like a partially visible line
12918 becoming fully visible, or because newly displayed lines are displayed
12919 in smaller font sizes.
12921 7. Update W's window end information. */
12927 struct frame
*f
= XFRAME (w
->frame
);
12928 struct glyph_matrix
*current_matrix
= w
->current_matrix
;
12929 struct glyph_matrix
*desired_matrix
= w
->desired_matrix
;
12930 struct glyph_row
*last_unchanged_at_beg_row
;
12931 struct glyph_row
*first_unchanged_at_end_row
;
12932 struct glyph_row
*row
;
12933 struct glyph_row
*bottom_row
;
12936 int delta
= 0, delta_bytes
= 0, stop_pos
, dvpos
, dy
;
12937 struct text_pos start_pos
;
12939 int first_unchanged_at_end_vpos
= 0;
12940 struct glyph_row
*last_text_row
, *last_text_row_at_end
;
12941 struct text_pos start
;
12942 int first_changed_charpos
, last_changed_charpos
;
12945 if (inhibit_try_window_id
)
12949 /* This is handy for debugging. */
12951 #define GIVE_UP(X) \
12953 fprintf (stderr, "try_window_id give up %d\n", (X)); \
12957 #define GIVE_UP(X) return 0
12960 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
12962 /* Don't use this for mini-windows because these can show
12963 messages and mini-buffers, and we don't handle that here. */
12964 if (MINI_WINDOW_P (w
))
12967 /* This flag is used to prevent redisplay optimizations. */
12968 if (windows_or_buffers_changed
|| cursor_type_changed
)
12971 /* Verify that narrowing has not changed.
12972 Also verify that we were not told to prevent redisplay optimizations.
12973 It would be nice to further
12974 reduce the number of cases where this prevents try_window_id. */
12975 if (current_buffer
->clip_changed
12976 || current_buffer
->prevent_redisplay_optimizations_p
)
12979 /* Window must either use window-based redisplay or be full width. */
12980 if (!FRAME_WINDOW_P (f
)
12981 && (!line_ins_del_ok
12982 || !WINDOW_FULL_WIDTH_P (w
)))
12985 /* Give up if point is not known NOT to appear in W. */
12986 if (PT
< CHARPOS (start
))
12989 /* Another way to prevent redisplay optimizations. */
12990 if (XFASTINT (w
->last_modified
) == 0)
12993 /* Verify that window is not hscrolled. */
12994 if (XFASTINT (w
->hscroll
) != 0)
12997 /* Verify that display wasn't paused. */
12998 if (NILP (w
->window_end_valid
))
13001 /* Can't use this if highlighting a region because a cursor movement
13002 will do more than just set the cursor. */
13003 if (!NILP (Vtransient_mark_mode
)
13004 && !NILP (current_buffer
->mark_active
))
13007 /* Likewise if highlighting trailing whitespace. */
13008 if (!NILP (Vshow_trailing_whitespace
))
13011 /* Likewise if showing a region. */
13012 if (!NILP (w
->region_showing
))
13015 /* Can use this if overlay arrow position and or string have changed. */
13016 if (overlay_arrows_changed_p ())
13020 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
13021 only if buffer has really changed. The reason is that the gap is
13022 initially at Z for freshly visited files. The code below would
13023 set end_unchanged to 0 in that case. */
13024 if (MODIFF
> SAVE_MODIFF
13025 /* This seems to happen sometimes after saving a buffer. */
13026 || BEG_UNCHANGED
+ END_UNCHANGED
> Z_BYTE
)
13028 if (GPT
- BEG
< BEG_UNCHANGED
)
13029 BEG_UNCHANGED
= GPT
- BEG
;
13030 if (Z
- GPT
< END_UNCHANGED
)
13031 END_UNCHANGED
= Z
- GPT
;
13034 /* The position of the first and last character that has been changed. */
13035 first_changed_charpos
= BEG
+ BEG_UNCHANGED
;
13036 last_changed_charpos
= Z
- END_UNCHANGED
;
13038 /* If window starts after a line end, and the last change is in
13039 front of that newline, then changes don't affect the display.
13040 This case happens with stealth-fontification. Note that although
13041 the display is unchanged, glyph positions in the matrix have to
13042 be adjusted, of course. */
13043 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
13044 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
)
13045 && ((last_changed_charpos
< CHARPOS (start
)
13046 && CHARPOS (start
) == BEGV
)
13047 || (last_changed_charpos
< CHARPOS (start
) - 1
13048 && FETCH_BYTE (BYTEPOS (start
) - 1) == '\n')))
13050 int Z_old
, delta
, Z_BYTE_old
, delta_bytes
;
13051 struct glyph_row
*r0
;
13053 /* Compute how many chars/bytes have been added to or removed
13054 from the buffer. */
13055 Z_old
= MATRIX_ROW_END_CHARPOS (row
) + XFASTINT (w
->window_end_pos
);
13056 Z_BYTE_old
= MATRIX_ROW_END_BYTEPOS (row
) + w
->window_end_bytepos
;
13058 delta_bytes
= Z_BYTE
- Z_BYTE_old
;
13060 /* Give up if PT is not in the window. Note that it already has
13061 been checked at the start of try_window_id that PT is not in
13062 front of the window start. */
13063 if (PT
>= MATRIX_ROW_END_CHARPOS (row
) + delta
)
13066 /* If window start is unchanged, we can reuse the whole matrix
13067 as is, after adjusting glyph positions. No need to compute
13068 the window end again, since its offset from Z hasn't changed. */
13069 r0
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
13070 if (CHARPOS (start
) == MATRIX_ROW_START_CHARPOS (r0
) + delta
13071 && BYTEPOS (start
) == MATRIX_ROW_START_BYTEPOS (r0
) + delta_bytes
13072 /* PT must not be in a partially visible line. */
13073 && !(PT
>= MATRIX_ROW_START_CHARPOS (row
) + delta
13074 && MATRIX_ROW_BOTTOM_Y (row
) > window_text_bottom_y (w
)))
13076 /* Adjust positions in the glyph matrix. */
13077 if (delta
|| delta_bytes
)
13079 struct glyph_row
*r1
13080 = MATRIX_BOTTOM_TEXT_ROW (current_matrix
, w
);
13081 increment_matrix_positions (w
->current_matrix
,
13082 MATRIX_ROW_VPOS (r0
, current_matrix
),
13083 MATRIX_ROW_VPOS (r1
, current_matrix
),
13084 delta
, delta_bytes
);
13087 /* Set the cursor. */
13088 row
= row_containing_pos (w
, PT
, r0
, NULL
, 0);
13090 set_cursor_from_row (w
, row
, current_matrix
, 0, 0, 0, 0);
13097 /* Handle the case that changes are all below what is displayed in
13098 the window, and that PT is in the window. This shortcut cannot
13099 be taken if ZV is visible in the window, and text has been added
13100 there that is visible in the window. */
13101 if (first_changed_charpos
>= MATRIX_ROW_END_CHARPOS (row
)
13102 /* ZV is not visible in the window, or there are no
13103 changes at ZV, actually. */
13104 && (current_matrix
->zv
> MATRIX_ROW_END_CHARPOS (row
)
13105 || first_changed_charpos
== last_changed_charpos
))
13107 struct glyph_row
*r0
;
13109 /* Give up if PT is not in the window. Note that it already has
13110 been checked at the start of try_window_id that PT is not in
13111 front of the window start. */
13112 if (PT
>= MATRIX_ROW_END_CHARPOS (row
))
13115 /* If window start is unchanged, we can reuse the whole matrix
13116 as is, without changing glyph positions since no text has
13117 been added/removed in front of the window end. */
13118 r0
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
13119 if (TEXT_POS_EQUAL_P (start
, r0
->start
.pos
)
13120 /* PT must not be in a partially visible line. */
13121 && !(PT
>= MATRIX_ROW_START_CHARPOS (row
)
13122 && MATRIX_ROW_BOTTOM_Y (row
) > window_text_bottom_y (w
)))
13124 /* We have to compute the window end anew since text
13125 can have been added/removed after it. */
13127 = make_number (Z
- MATRIX_ROW_END_CHARPOS (row
));
13128 w
->window_end_bytepos
13129 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
13131 /* Set the cursor. */
13132 row
= row_containing_pos (w
, PT
, r0
, NULL
, 0);
13134 set_cursor_from_row (w
, row
, current_matrix
, 0, 0, 0, 0);
13141 /* Give up if window start is in the changed area.
13143 The condition used to read
13145 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
13147 but why that was tested escapes me at the moment. */
13148 if (CHARPOS (start
) >= first_changed_charpos
13149 && CHARPOS (start
) <= last_changed_charpos
)
13152 /* Check that window start agrees with the start of the first glyph
13153 row in its current matrix. Check this after we know the window
13154 start is not in changed text, otherwise positions would not be
13156 row
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
13157 if (!TEXT_POS_EQUAL_P (start
, row
->start
.pos
))
13160 /* Give up if the window ends in strings. Overlay strings
13161 at the end are difficult to handle, so don't try. */
13162 row
= MATRIX_ROW (current_matrix
, XFASTINT (w
->window_end_vpos
));
13163 if (MATRIX_ROW_START_CHARPOS (row
) == MATRIX_ROW_END_CHARPOS (row
))
13166 /* Compute the position at which we have to start displaying new
13167 lines. Some of the lines at the top of the window might be
13168 reusable because they are not displaying changed text. Find the
13169 last row in W's current matrix not affected by changes at the
13170 start of current_buffer. Value is null if changes start in the
13171 first line of window. */
13172 last_unchanged_at_beg_row
= find_last_unchanged_at_beg_row (w
);
13173 if (last_unchanged_at_beg_row
)
13175 /* Avoid starting to display in the moddle of a character, a TAB
13176 for instance. This is easier than to set up the iterator
13177 exactly, and it's not a frequent case, so the additional
13178 effort wouldn't really pay off. */
13179 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row
)
13180 || last_unchanged_at_beg_row
->ends_in_newline_from_string_p
)
13181 && last_unchanged_at_beg_row
> w
->current_matrix
->rows
)
13182 --last_unchanged_at_beg_row
;
13184 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row
))
13187 if (init_to_row_end (&it
, w
, last_unchanged_at_beg_row
) == 0)
13189 start_pos
= it
.current
.pos
;
13191 /* Start displaying new lines in the desired matrix at the same
13192 vpos we would use in the current matrix, i.e. below
13193 last_unchanged_at_beg_row. */
13194 it
.vpos
= 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row
,
13196 it
.glyph_row
= MATRIX_ROW (desired_matrix
, it
.vpos
);
13197 it
.current_y
= MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row
);
13199 xassert (it
.hpos
== 0 && it
.current_x
== 0);
13203 /* There are no reusable lines at the start of the window.
13204 Start displaying in the first text line. */
13205 start_display (&it
, w
, start
);
13206 it
.vpos
= it
.first_vpos
;
13207 start_pos
= it
.current
.pos
;
13210 /* Find the first row that is not affected by changes at the end of
13211 the buffer. Value will be null if there is no unchanged row, in
13212 which case we must redisplay to the end of the window. delta
13213 will be set to the value by which buffer positions beginning with
13214 first_unchanged_at_end_row have to be adjusted due to text
13216 first_unchanged_at_end_row
13217 = find_first_unchanged_at_end_row (w
, &delta
, &delta_bytes
);
13218 IF_DEBUG (debug_delta
= delta
);
13219 IF_DEBUG (debug_delta_bytes
= delta_bytes
);
13221 /* Set stop_pos to the buffer position up to which we will have to
13222 display new lines. If first_unchanged_at_end_row != NULL, this
13223 is the buffer position of the start of the line displayed in that
13224 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
13225 that we don't stop at a buffer position. */
13227 if (first_unchanged_at_end_row
)
13229 xassert (last_unchanged_at_beg_row
== NULL
13230 || first_unchanged_at_end_row
>= last_unchanged_at_beg_row
);
13232 /* If this is a continuation line, move forward to the next one
13233 that isn't. Changes in lines above affect this line.
13234 Caution: this may move first_unchanged_at_end_row to a row
13235 not displaying text. */
13236 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row
)
13237 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
)
13238 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row
)
13239 < it
.last_visible_y
))
13240 ++first_unchanged_at_end_row
;
13242 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
)
13243 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row
)
13244 >= it
.last_visible_y
))
13245 first_unchanged_at_end_row
= NULL
;
13248 stop_pos
= (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row
)
13250 first_unchanged_at_end_vpos
13251 = MATRIX_ROW_VPOS (first_unchanged_at_end_row
, current_matrix
);
13252 xassert (stop_pos
>= Z
- END_UNCHANGED
);
13255 else if (last_unchanged_at_beg_row
== NULL
)
13261 /* Either there is no unchanged row at the end, or the one we have
13262 now displays text. This is a necessary condition for the window
13263 end pos calculation at the end of this function. */
13264 xassert (first_unchanged_at_end_row
== NULL
13265 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
));
13267 debug_last_unchanged_at_beg_vpos
13268 = (last_unchanged_at_beg_row
13269 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row
, current_matrix
)
13271 debug_first_unchanged_at_end_vpos
= first_unchanged_at_end_vpos
;
13273 #endif /* GLYPH_DEBUG != 0 */
13276 /* Display new lines. Set last_text_row to the last new line
13277 displayed which has text on it, i.e. might end up as being the
13278 line where the window_end_vpos is. */
13279 w
->cursor
.vpos
= -1;
13280 last_text_row
= NULL
;
13281 overlay_arrow_seen
= 0;
13282 while (it
.current_y
< it
.last_visible_y
13283 && !fonts_changed_p
13284 && (first_unchanged_at_end_row
== NULL
13285 || IT_CHARPOS (it
) < stop_pos
))
13287 if (display_line (&it
))
13288 last_text_row
= it
.glyph_row
- 1;
13291 if (fonts_changed_p
)
13295 /* Compute differences in buffer positions, y-positions etc. for
13296 lines reused at the bottom of the window. Compute what we can
13298 if (first_unchanged_at_end_row
13299 /* No lines reused because we displayed everything up to the
13300 bottom of the window. */
13301 && it
.current_y
< it
.last_visible_y
)
13304 - MATRIX_ROW_VPOS (first_unchanged_at_end_row
,
13306 dy
= it
.current_y
- first_unchanged_at_end_row
->y
;
13307 run
.current_y
= first_unchanged_at_end_row
->y
;
13308 run
.desired_y
= run
.current_y
+ dy
;
13309 run
.height
= it
.last_visible_y
- max (run
.current_y
, run
.desired_y
);
13313 delta
= dvpos
= dy
= run
.current_y
= run
.desired_y
= run
.height
= 0;
13314 first_unchanged_at_end_row
= NULL
;
13316 IF_DEBUG (debug_dvpos
= dvpos
; debug_dy
= dy
);
13319 /* Find the cursor if not already found. We have to decide whether
13320 PT will appear on this window (it sometimes doesn't, but this is
13321 not a very frequent case.) This decision has to be made before
13322 the current matrix is altered. A value of cursor.vpos < 0 means
13323 that PT is either in one of the lines beginning at
13324 first_unchanged_at_end_row or below the window. Don't care for
13325 lines that might be displayed later at the window end; as
13326 mentioned, this is not a frequent case. */
13327 if (w
->cursor
.vpos
< 0)
13329 /* Cursor in unchanged rows at the top? */
13330 if (PT
< CHARPOS (start_pos
)
13331 && last_unchanged_at_beg_row
)
13333 row
= row_containing_pos (w
, PT
,
13334 MATRIX_FIRST_TEXT_ROW (w
->current_matrix
),
13335 last_unchanged_at_beg_row
+ 1, 0);
13337 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
13340 /* Start from first_unchanged_at_end_row looking for PT. */
13341 else if (first_unchanged_at_end_row
)
13343 row
= row_containing_pos (w
, PT
- delta
,
13344 first_unchanged_at_end_row
, NULL
, 0);
13346 set_cursor_from_row (w
, row
, w
->current_matrix
, delta
,
13347 delta_bytes
, dy
, dvpos
);
13350 /* Give up if cursor was not found. */
13351 if (w
->cursor
.vpos
< 0)
13353 clear_glyph_matrix (w
->desired_matrix
);
13358 /* Don't let the cursor end in the scroll margins. */
13360 int this_scroll_margin
, cursor_height
;
13362 this_scroll_margin
= max (0, scroll_margin
);
13363 this_scroll_margin
= min (this_scroll_margin
, WINDOW_TOTAL_LINES (w
) / 4);
13364 this_scroll_margin
*= FRAME_LINE_HEIGHT (it
.f
);
13365 cursor_height
= MATRIX_ROW (w
->desired_matrix
, w
->cursor
.vpos
)->height
;
13367 if ((w
->cursor
.y
< this_scroll_margin
13368 && CHARPOS (start
) > BEGV
)
13369 /* Don't take scroll margin into account at the bottom because
13370 old redisplay didn't do it either. */
13371 || w
->cursor
.y
+ cursor_height
> it
.last_visible_y
)
13373 w
->cursor
.vpos
= -1;
13374 clear_glyph_matrix (w
->desired_matrix
);
13379 /* Scroll the display. Do it before changing the current matrix so
13380 that xterm.c doesn't get confused about where the cursor glyph is
13382 if (dy
&& run
.height
)
13386 if (FRAME_WINDOW_P (f
))
13388 rif
->update_window_begin_hook (w
);
13389 rif
->clear_window_mouse_face (w
);
13390 rif
->scroll_run_hook (w
, &run
);
13391 rif
->update_window_end_hook (w
, 0, 0);
13395 /* Terminal frame. In this case, dvpos gives the number of
13396 lines to scroll by; dvpos < 0 means scroll up. */
13397 int first_unchanged_at_end_vpos
13398 = MATRIX_ROW_VPOS (first_unchanged_at_end_row
, w
->current_matrix
);
13399 int from
= WINDOW_TOP_EDGE_LINE (w
) + first_unchanged_at_end_vpos
;
13400 int end
= (WINDOW_TOP_EDGE_LINE (w
)
13401 + (WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0)
13402 + window_internal_height (w
));
13404 /* Perform the operation on the screen. */
13407 /* Scroll last_unchanged_at_beg_row to the end of the
13408 window down dvpos lines. */
13409 set_terminal_window (end
);
13411 /* On dumb terminals delete dvpos lines at the end
13412 before inserting dvpos empty lines. */
13413 if (!scroll_region_ok
)
13414 ins_del_lines (end
- dvpos
, -dvpos
);
13416 /* Insert dvpos empty lines in front of
13417 last_unchanged_at_beg_row. */
13418 ins_del_lines (from
, dvpos
);
13420 else if (dvpos
< 0)
13422 /* Scroll up last_unchanged_at_beg_vpos to the end of
13423 the window to last_unchanged_at_beg_vpos - |dvpos|. */
13424 set_terminal_window (end
);
13426 /* Delete dvpos lines in front of
13427 last_unchanged_at_beg_vpos. ins_del_lines will set
13428 the cursor to the given vpos and emit |dvpos| delete
13430 ins_del_lines (from
+ dvpos
, dvpos
);
13432 /* On a dumb terminal insert dvpos empty lines at the
13434 if (!scroll_region_ok
)
13435 ins_del_lines (end
+ dvpos
, -dvpos
);
13438 set_terminal_window (0);
13444 /* Shift reused rows of the current matrix to the right position.
13445 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
13447 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (current_matrix
, w
);
13448 bottom_vpos
= MATRIX_ROW_VPOS (bottom_row
, current_matrix
);
13451 rotate_matrix (current_matrix
, first_unchanged_at_end_vpos
+ dvpos
,
13452 bottom_vpos
, dvpos
);
13453 enable_glyph_matrix_rows (current_matrix
, bottom_vpos
+ dvpos
,
13456 else if (dvpos
> 0)
13458 rotate_matrix (current_matrix
, first_unchanged_at_end_vpos
,
13459 bottom_vpos
, dvpos
);
13460 enable_glyph_matrix_rows (current_matrix
, first_unchanged_at_end_vpos
,
13461 first_unchanged_at_end_vpos
+ dvpos
, 0);
13464 /* For frame-based redisplay, make sure that current frame and window
13465 matrix are in sync with respect to glyph memory. */
13466 if (!FRAME_WINDOW_P (f
))
13467 sync_frame_with_window_matrix_rows (w
);
13469 /* Adjust buffer positions in reused rows. */
13471 increment_matrix_positions (current_matrix
,
13472 first_unchanged_at_end_vpos
+ dvpos
,
13473 bottom_vpos
, delta
, delta_bytes
);
13475 /* Adjust Y positions. */
13477 shift_glyph_matrix (w
, current_matrix
,
13478 first_unchanged_at_end_vpos
+ dvpos
,
13481 if (first_unchanged_at_end_row
)
13482 first_unchanged_at_end_row
+= dvpos
;
13484 /* If scrolling up, there may be some lines to display at the end of
13486 last_text_row_at_end
= NULL
;
13489 /* Scrolling up can leave for example a partially visible line
13490 at the end of the window to be redisplayed. */
13491 /* Set last_row to the glyph row in the current matrix where the
13492 window end line is found. It has been moved up or down in
13493 the matrix by dvpos. */
13494 int last_vpos
= XFASTINT (w
->window_end_vpos
) + dvpos
;
13495 struct glyph_row
*last_row
= MATRIX_ROW (current_matrix
, last_vpos
);
13497 /* If last_row is the window end line, it should display text. */
13498 xassert (last_row
->displays_text_p
);
13500 /* If window end line was partially visible before, begin
13501 displaying at that line. Otherwise begin displaying with the
13502 line following it. */
13503 if (MATRIX_ROW_BOTTOM_Y (last_row
) - dy
>= it
.last_visible_y
)
13505 init_to_row_start (&it
, w
, last_row
);
13506 it
.vpos
= last_vpos
;
13507 it
.current_y
= last_row
->y
;
13511 init_to_row_end (&it
, w
, last_row
);
13512 it
.vpos
= 1 + last_vpos
;
13513 it
.current_y
= MATRIX_ROW_BOTTOM_Y (last_row
);
13517 /* We may start in a continuation line. If so, we have to
13518 get the right continuation_lines_width and current_x. */
13519 it
.continuation_lines_width
= last_row
->continuation_lines_width
;
13520 it
.hpos
= it
.current_x
= 0;
13522 /* Display the rest of the lines at the window end. */
13523 it
.glyph_row
= MATRIX_ROW (desired_matrix
, it
.vpos
);
13524 while (it
.current_y
< it
.last_visible_y
13525 && !fonts_changed_p
)
13527 /* Is it always sure that the display agrees with lines in
13528 the current matrix? I don't think so, so we mark rows
13529 displayed invalid in the current matrix by setting their
13530 enabled_p flag to zero. */
13531 MATRIX_ROW (w
->current_matrix
, it
.vpos
)->enabled_p
= 0;
13532 if (display_line (&it
))
13533 last_text_row_at_end
= it
.glyph_row
- 1;
13537 /* Update window_end_pos and window_end_vpos. */
13538 if (first_unchanged_at_end_row
13539 && first_unchanged_at_end_row
->y
< it
.last_visible_y
13540 && !last_text_row_at_end
)
13542 /* Window end line if one of the preserved rows from the current
13543 matrix. Set row to the last row displaying text in current
13544 matrix starting at first_unchanged_at_end_row, after
13546 xassert (first_unchanged_at_end_row
->displays_text_p
);
13547 row
= find_last_row_displaying_text (w
->current_matrix
, &it
,
13548 first_unchanged_at_end_row
);
13549 xassert (row
&& MATRIX_ROW_DISPLAYS_TEXT_P (row
));
13551 w
->window_end_pos
= make_number (Z
- MATRIX_ROW_END_CHARPOS (row
));
13552 w
->window_end_bytepos
= Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
13554 = make_number (MATRIX_ROW_VPOS (row
, w
->current_matrix
));
13555 xassert (w
->window_end_bytepos
>= 0);
13556 IF_DEBUG (debug_method_add (w
, "A"));
13558 else if (last_text_row_at_end
)
13561 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row_at_end
));
13562 w
->window_end_bytepos
13563 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row_at_end
);
13565 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end
, desired_matrix
));
13566 xassert (w
->window_end_bytepos
>= 0);
13567 IF_DEBUG (debug_method_add (w
, "B"));
13569 else if (last_text_row
)
13571 /* We have displayed either to the end of the window or at the
13572 end of the window, i.e. the last row with text is to be found
13573 in the desired matrix. */
13575 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
13576 w
->window_end_bytepos
13577 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
13579 = make_number (MATRIX_ROW_VPOS (last_text_row
, desired_matrix
));
13580 xassert (w
->window_end_bytepos
>= 0);
13582 else if (first_unchanged_at_end_row
== NULL
13583 && last_text_row
== NULL
13584 && last_text_row_at_end
== NULL
)
13586 /* Displayed to end of window, but no line containing text was
13587 displayed. Lines were deleted at the end of the window. */
13588 int first_vpos
= WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0;
13589 int vpos
= XFASTINT (w
->window_end_vpos
);
13590 struct glyph_row
*current_row
= current_matrix
->rows
+ vpos
;
13591 struct glyph_row
*desired_row
= desired_matrix
->rows
+ vpos
;
13594 row
== NULL
&& vpos
>= first_vpos
;
13595 --vpos
, --current_row
, --desired_row
)
13597 if (desired_row
->enabled_p
)
13599 if (desired_row
->displays_text_p
)
13602 else if (current_row
->displays_text_p
)
13606 xassert (row
!= NULL
);
13607 w
->window_end_vpos
= make_number (vpos
+ 1);
13608 w
->window_end_pos
= make_number (Z
- MATRIX_ROW_END_CHARPOS (row
));
13609 w
->window_end_bytepos
= Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
13610 xassert (w
->window_end_bytepos
>= 0);
13611 IF_DEBUG (debug_method_add (w
, "C"));
13616 #if 0 /* This leads to problems, for instance when the cursor is
13617 at ZV, and the cursor line displays no text. */
13618 /* Disable rows below what's displayed in the window. This makes
13619 debugging easier. */
13620 enable_glyph_matrix_rows (current_matrix
,
13621 XFASTINT (w
->window_end_vpos
) + 1,
13625 IF_DEBUG (debug_end_pos
= XFASTINT (w
->window_end_pos
);
13626 debug_end_vpos
= XFASTINT (w
->window_end_vpos
));
13628 /* Record that display has not been completed. */
13629 w
->window_end_valid
= Qnil
;
13630 w
->desired_matrix
->no_scrolling_p
= 1;
13638 /***********************************************************************
13639 More debugging support
13640 ***********************************************************************/
13644 void dump_glyph_row
P_ ((struct glyph_row
*, int, int));
13645 void dump_glyph_matrix
P_ ((struct glyph_matrix
*, int));
13646 void dump_glyph
P_ ((struct glyph_row
*, struct glyph
*, int));
13649 /* Dump the contents of glyph matrix MATRIX on stderr.
13651 GLYPHS 0 means don't show glyph contents.
13652 GLYPHS 1 means show glyphs in short form
13653 GLYPHS > 1 means show glyphs in long form. */
13656 dump_glyph_matrix (matrix
, glyphs
)
13657 struct glyph_matrix
*matrix
;
13661 for (i
= 0; i
< matrix
->nrows
; ++i
)
13662 dump_glyph_row (MATRIX_ROW (matrix
, i
), i
, glyphs
);
13666 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
13667 the glyph row and area where the glyph comes from. */
13670 dump_glyph (row
, glyph
, area
)
13671 struct glyph_row
*row
;
13672 struct glyph
*glyph
;
13675 if (glyph
->type
== CHAR_GLYPH
)
13678 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13679 glyph
- row
->glyphs
[TEXT_AREA
],
13682 (BUFFERP (glyph
->object
)
13684 : (STRINGP (glyph
->object
)
13687 glyph
->pixel_width
,
13689 (glyph
->u
.ch
< 0x80 && glyph
->u
.ch
>= ' '
13693 glyph
->left_box_line_p
,
13694 glyph
->right_box_line_p
);
13696 else if (glyph
->type
== STRETCH_GLYPH
)
13699 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13700 glyph
- row
->glyphs
[TEXT_AREA
],
13703 (BUFFERP (glyph
->object
)
13705 : (STRINGP (glyph
->object
)
13708 glyph
->pixel_width
,
13712 glyph
->left_box_line_p
,
13713 glyph
->right_box_line_p
);
13715 else if (glyph
->type
== IMAGE_GLYPH
)
13718 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13719 glyph
- row
->glyphs
[TEXT_AREA
],
13722 (BUFFERP (glyph
->object
)
13724 : (STRINGP (glyph
->object
)
13727 glyph
->pixel_width
,
13731 glyph
->left_box_line_p
,
13732 glyph
->right_box_line_p
);
13737 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
13738 GLYPHS 0 means don't show glyph contents.
13739 GLYPHS 1 means show glyphs in short form
13740 GLYPHS > 1 means show glyphs in long form. */
13743 dump_glyph_row (row
, vpos
, glyphs
)
13744 struct glyph_row
*row
;
13749 fprintf (stderr
, "Row Start End Used oEI><O\\CTZFesm X Y W H V A P\n");
13750 fprintf (stderr
, "=======================================================================\n");
13752 fprintf (stderr
, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d%1.1d\
13753 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
13755 MATRIX_ROW_START_CHARPOS (row
),
13756 MATRIX_ROW_END_CHARPOS (row
),
13757 row
->used
[TEXT_AREA
],
13758 row
->contains_overlapping_glyphs_p
,
13760 row
->truncated_on_left_p
,
13761 row
->truncated_on_right_p
,
13762 row
->overlay_arrow_p
,
13764 MATRIX_ROW_CONTINUATION_LINE_P (row
),
13765 row
->displays_text_p
,
13768 row
->ends_in_middle_of_char_p
,
13769 row
->starts_in_middle_of_char_p
,
13775 row
->visible_height
,
13778 fprintf (stderr
, "%9d %5d\t%5d\n", row
->start
.overlay_string_index
,
13779 row
->end
.overlay_string_index
,
13780 row
->continuation_lines_width
);
13781 fprintf (stderr
, "%9d %5d\n",
13782 CHARPOS (row
->start
.string_pos
),
13783 CHARPOS (row
->end
.string_pos
));
13784 fprintf (stderr
, "%9d %5d\n", row
->start
.dpvec_index
,
13785 row
->end
.dpvec_index
);
13792 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
13794 struct glyph
*glyph
= row
->glyphs
[area
];
13795 struct glyph
*glyph_end
= glyph
+ row
->used
[area
];
13797 /* Glyph for a line end in text. */
13798 if (area
== TEXT_AREA
&& glyph
== glyph_end
&& glyph
->charpos
> 0)
13801 if (glyph
< glyph_end
)
13802 fprintf (stderr
, " Glyph Type Pos O W Code C Face LR\n");
13804 for (; glyph
< glyph_end
; ++glyph
)
13805 dump_glyph (row
, glyph
, area
);
13808 else if (glyphs
== 1)
13812 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
13814 char *s
= (char *) alloca (row
->used
[area
] + 1);
13817 for (i
= 0; i
< row
->used
[area
]; ++i
)
13819 struct glyph
*glyph
= row
->glyphs
[area
] + i
;
13820 if (glyph
->type
== CHAR_GLYPH
13821 && glyph
->u
.ch
< 0x80
13822 && glyph
->u
.ch
>= ' ')
13823 s
[i
] = glyph
->u
.ch
;
13829 fprintf (stderr
, "%3d: (%d) '%s'\n", vpos
, row
->enabled_p
, s
);
13835 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix
,
13836 Sdump_glyph_matrix
, 0, 1, "p",
13837 doc
: /* Dump the current matrix of the selected window to stderr.
13838 Shows contents of glyph row structures. With non-nil
13839 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
13840 glyphs in short form, otherwise show glyphs in long form. */)
13842 Lisp_Object glyphs
;
13844 struct window
*w
= XWINDOW (selected_window
);
13845 struct buffer
*buffer
= XBUFFER (w
->buffer
);
13847 fprintf (stderr
, "PT = %d, BEGV = %d. ZV = %d\n",
13848 BUF_PT (buffer
), BUF_BEGV (buffer
), BUF_ZV (buffer
));
13849 fprintf (stderr
, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
13850 w
->cursor
.x
, w
->cursor
.y
, w
->cursor
.hpos
, w
->cursor
.vpos
);
13851 fprintf (stderr
, "=============================================\n");
13852 dump_glyph_matrix (w
->current_matrix
,
13853 NILP (glyphs
) ? 0 : XINT (glyphs
));
13858 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix
,
13859 Sdump_frame_glyph_matrix
, 0, 0, "", doc
: /* */)
13862 struct frame
*f
= XFRAME (selected_frame
);
13863 dump_glyph_matrix (f
->current_matrix
, 1);
13868 DEFUN ("dump-glyph-row", Fdump_glyph_row
, Sdump_glyph_row
, 1, 2, "",
13869 doc
: /* Dump glyph row ROW to stderr.
13870 GLYPH 0 means don't dump glyphs.
13871 GLYPH 1 means dump glyphs in short form.
13872 GLYPH > 1 or omitted means dump glyphs in long form. */)
13874 Lisp_Object row
, glyphs
;
13876 struct glyph_matrix
*matrix
;
13879 CHECK_NUMBER (row
);
13880 matrix
= XWINDOW (selected_window
)->current_matrix
;
13882 if (vpos
>= 0 && vpos
< matrix
->nrows
)
13883 dump_glyph_row (MATRIX_ROW (matrix
, vpos
),
13885 INTEGERP (glyphs
) ? XINT (glyphs
) : 2);
13890 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row
, Sdump_tool_bar_row
, 1, 2, "",
13891 doc
: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
13892 GLYPH 0 means don't dump glyphs.
13893 GLYPH 1 means dump glyphs in short form.
13894 GLYPH > 1 or omitted means dump glyphs in long form. */)
13896 Lisp_Object row
, glyphs
;
13898 struct frame
*sf
= SELECTED_FRAME ();
13899 struct glyph_matrix
*m
= XWINDOW (sf
->tool_bar_window
)->current_matrix
;
13902 CHECK_NUMBER (row
);
13904 if (vpos
>= 0 && vpos
< m
->nrows
)
13905 dump_glyph_row (MATRIX_ROW (m
, vpos
), vpos
,
13906 INTEGERP (glyphs
) ? XINT (glyphs
) : 2);
13911 DEFUN ("trace-redisplay", Ftrace_redisplay
, Strace_redisplay
, 0, 1, "P",
13912 doc
: /* Toggle tracing of redisplay.
13913 With ARG, turn tracing on if and only if ARG is positive. */)
13918 trace_redisplay_p
= !trace_redisplay_p
;
13921 arg
= Fprefix_numeric_value (arg
);
13922 trace_redisplay_p
= XINT (arg
) > 0;
13929 DEFUN ("trace-to-stderr", Ftrace_to_stderr
, Strace_to_stderr
, 1, MANY
, "",
13930 doc
: /* Like `format', but print result to stderr.
13931 usage: (trace-to-stderr STRING &rest OBJECTS) */)
13936 Lisp_Object s
= Fformat (nargs
, args
);
13937 fprintf (stderr
, "%s", SDATA (s
));
13941 #endif /* GLYPH_DEBUG */
13945 /***********************************************************************
13946 Building Desired Matrix Rows
13947 ***********************************************************************/
13949 /* Return a temporary glyph row holding the glyphs of an overlay
13950 arrow. Only used for non-window-redisplay windows. */
13952 static struct glyph_row
*
13953 get_overlay_arrow_glyph_row (w
, overlay_arrow_string
)
13955 Lisp_Object overlay_arrow_string
;
13957 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
13958 struct buffer
*buffer
= XBUFFER (w
->buffer
);
13959 struct buffer
*old
= current_buffer
;
13960 const unsigned char *arrow_string
= SDATA (overlay_arrow_string
);
13961 int arrow_len
= SCHARS (overlay_arrow_string
);
13962 const unsigned char *arrow_end
= arrow_string
+ arrow_len
;
13963 const unsigned char *p
;
13966 int n_glyphs_before
;
13968 set_buffer_temp (buffer
);
13969 init_iterator (&it
, w
, -1, -1, &scratch_glyph_row
, DEFAULT_FACE_ID
);
13970 it
.glyph_row
->used
[TEXT_AREA
] = 0;
13971 SET_TEXT_POS (it
.position
, 0, 0);
13973 multibyte_p
= !NILP (buffer
->enable_multibyte_characters
);
13975 while (p
< arrow_end
)
13977 Lisp_Object face
, ilisp
;
13979 /* Get the next character. */
13981 it
.c
= string_char_and_length (p
, arrow_len
, &it
.len
);
13983 it
.c
= *p
, it
.len
= 1;
13986 /* Get its face. */
13987 ilisp
= make_number (p
- arrow_string
);
13988 face
= Fget_text_property (ilisp
, Qface
, overlay_arrow_string
);
13989 it
.face_id
= compute_char_face (f
, it
.c
, face
);
13991 /* Compute its width, get its glyphs. */
13992 n_glyphs_before
= it
.glyph_row
->used
[TEXT_AREA
];
13993 SET_TEXT_POS (it
.position
, -1, -1);
13994 PRODUCE_GLYPHS (&it
);
13996 /* If this character doesn't fit any more in the line, we have
13997 to remove some glyphs. */
13998 if (it
.current_x
> it
.last_visible_x
)
14000 it
.glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
;
14005 set_buffer_temp (old
);
14006 return it
.glyph_row
;
14010 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
14011 glyphs are only inserted for terminal frames since we can't really
14012 win with truncation glyphs when partially visible glyphs are
14013 involved. Which glyphs to insert is determined by
14014 produce_special_glyphs. */
14017 insert_left_trunc_glyphs (it
)
14020 struct it truncate_it
;
14021 struct glyph
*from
, *end
, *to
, *toend
;
14023 xassert (!FRAME_WINDOW_P (it
->f
));
14025 /* Get the truncation glyphs. */
14027 truncate_it
.current_x
= 0;
14028 truncate_it
.face_id
= DEFAULT_FACE_ID
;
14029 truncate_it
.glyph_row
= &scratch_glyph_row
;
14030 truncate_it
.glyph_row
->used
[TEXT_AREA
] = 0;
14031 CHARPOS (truncate_it
.position
) = BYTEPOS (truncate_it
.position
) = -1;
14032 truncate_it
.object
= make_number (0);
14033 produce_special_glyphs (&truncate_it
, IT_TRUNCATION
);
14035 /* Overwrite glyphs from IT with truncation glyphs. */
14036 from
= truncate_it
.glyph_row
->glyphs
[TEXT_AREA
];
14037 end
= from
+ truncate_it
.glyph_row
->used
[TEXT_AREA
];
14038 to
= it
->glyph_row
->glyphs
[TEXT_AREA
];
14039 toend
= to
+ it
->glyph_row
->used
[TEXT_AREA
];
14044 /* There may be padding glyphs left over. Overwrite them too. */
14045 while (to
< toend
&& CHAR_GLYPH_PADDING_P (*to
))
14047 from
= truncate_it
.glyph_row
->glyphs
[TEXT_AREA
];
14053 it
->glyph_row
->used
[TEXT_AREA
] = to
- it
->glyph_row
->glyphs
[TEXT_AREA
];
14057 /* Compute the pixel height and width of IT->glyph_row.
14059 Most of the time, ascent and height of a display line will be equal
14060 to the max_ascent and max_height values of the display iterator
14061 structure. This is not the case if
14063 1. We hit ZV without displaying anything. In this case, max_ascent
14064 and max_height will be zero.
14066 2. We have some glyphs that don't contribute to the line height.
14067 (The glyph row flag contributes_to_line_height_p is for future
14068 pixmap extensions).
14070 The first case is easily covered by using default values because in
14071 these cases, the line height does not really matter, except that it
14072 must not be zero. */
14075 compute_line_metrics (it
)
14078 struct glyph_row
*row
= it
->glyph_row
;
14081 if (FRAME_WINDOW_P (it
->f
))
14083 int i
, min_y
, max_y
;
14085 /* The line may consist of one space only, that was added to
14086 place the cursor on it. If so, the row's height hasn't been
14088 if (row
->height
== 0)
14090 if (it
->max_ascent
+ it
->max_descent
== 0)
14091 it
->max_descent
= it
->max_phys_descent
= FRAME_LINE_HEIGHT (it
->f
);
14092 row
->ascent
= it
->max_ascent
;
14093 row
->height
= it
->max_ascent
+ it
->max_descent
;
14094 row
->phys_ascent
= it
->max_phys_ascent
;
14095 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
14098 /* Compute the width of this line. */
14099 row
->pixel_width
= row
->x
;
14100 for (i
= 0; i
< row
->used
[TEXT_AREA
]; ++i
)
14101 row
->pixel_width
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
14103 xassert (row
->pixel_width
>= 0);
14104 xassert (row
->ascent
>= 0 && row
->height
> 0);
14106 row
->overlapping_p
= (MATRIX_ROW_OVERLAPS_SUCC_P (row
)
14107 || MATRIX_ROW_OVERLAPS_PRED_P (row
));
14109 /* If first line's physical ascent is larger than its logical
14110 ascent, use the physical ascent, and make the row taller.
14111 This makes accented characters fully visible. */
14112 if (row
== MATRIX_FIRST_TEXT_ROW (it
->w
->desired_matrix
)
14113 && row
->phys_ascent
> row
->ascent
)
14115 row
->height
+= row
->phys_ascent
- row
->ascent
;
14116 row
->ascent
= row
->phys_ascent
;
14119 /* Compute how much of the line is visible. */
14120 row
->visible_height
= row
->height
;
14122 min_y
= WINDOW_HEADER_LINE_HEIGHT (it
->w
);
14123 max_y
= WINDOW_BOX_HEIGHT_NO_MODE_LINE (it
->w
);
14125 if (row
->y
< min_y
)
14126 row
->visible_height
-= min_y
- row
->y
;
14127 if (row
->y
+ row
->height
> max_y
)
14128 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
14132 row
->pixel_width
= row
->used
[TEXT_AREA
];
14133 if (row
->continued_p
)
14134 row
->pixel_width
-= it
->continuation_pixel_width
;
14135 else if (row
->truncated_on_right_p
)
14136 row
->pixel_width
-= it
->truncation_pixel_width
;
14137 row
->ascent
= row
->phys_ascent
= 0;
14138 row
->height
= row
->phys_height
= row
->visible_height
= 1;
14141 /* Compute a hash code for this row. */
14143 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
14144 for (i
= 0; i
< row
->used
[area
]; ++i
)
14145 row
->hash
= ((((row
->hash
<< 4) + (row
->hash
>> 24)) & 0x0fffffff)
14146 + row
->glyphs
[area
][i
].u
.val
14147 + row
->glyphs
[area
][i
].face_id
14148 + row
->glyphs
[area
][i
].padding_p
14149 + (row
->glyphs
[area
][i
].type
<< 2));
14151 it
->max_ascent
= it
->max_descent
= 0;
14152 it
->max_phys_ascent
= it
->max_phys_descent
= 0;
14156 /* Append one space to the glyph row of iterator IT if doing a
14157 window-based redisplay. The space has the same face as
14158 IT->face_id. Value is non-zero if a space was added.
14160 This function is called to make sure that there is always one glyph
14161 at the end of a glyph row that the cursor can be set on under
14162 window-systems. (If there weren't such a glyph we would not know
14163 how wide and tall a box cursor should be displayed).
14165 At the same time this space let's a nicely handle clearing to the
14166 end of the line if the row ends in italic text. */
14169 append_space_for_newline (it
, default_face_p
)
14171 int default_face_p
;
14173 if (FRAME_WINDOW_P (it
->f
))
14175 int n
= it
->glyph_row
->used
[TEXT_AREA
];
14177 if (it
->glyph_row
->glyphs
[TEXT_AREA
] + n
14178 < it
->glyph_row
->glyphs
[1 + TEXT_AREA
])
14180 /* Save some values that must not be changed.
14181 Must save IT->c and IT->len because otherwise
14182 ITERATOR_AT_END_P wouldn't work anymore after
14183 append_space_for_newline has been called. */
14184 enum display_element_type saved_what
= it
->what
;
14185 int saved_c
= it
->c
, saved_len
= it
->len
;
14186 int saved_x
= it
->current_x
;
14187 int saved_face_id
= it
->face_id
;
14188 struct text_pos saved_pos
;
14189 Lisp_Object saved_object
;
14192 saved_object
= it
->object
;
14193 saved_pos
= it
->position
;
14195 it
->what
= IT_CHARACTER
;
14196 bzero (&it
->position
, sizeof it
->position
);
14197 it
->object
= make_number (0);
14201 if (default_face_p
)
14202 it
->face_id
= DEFAULT_FACE_ID
;
14203 else if (it
->face_before_selective_p
)
14204 it
->face_id
= it
->saved_face_id
;
14205 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
14206 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, 0);
14208 PRODUCE_GLYPHS (it
);
14210 it
->override_ascent
= -1;
14211 it
->constrain_row_ascent_descent_p
= 0;
14212 it
->current_x
= saved_x
;
14213 it
->object
= saved_object
;
14214 it
->position
= saved_pos
;
14215 it
->what
= saved_what
;
14216 it
->face_id
= saved_face_id
;
14217 it
->len
= saved_len
;
14227 /* Extend the face of the last glyph in the text area of IT->glyph_row
14228 to the end of the display line. Called from display_line.
14229 If the glyph row is empty, add a space glyph to it so that we
14230 know the face to draw. Set the glyph row flag fill_line_p. */
14233 extend_face_to_end_of_line (it
)
14237 struct frame
*f
= it
->f
;
14239 /* If line is already filled, do nothing. */
14240 if (it
->current_x
>= it
->last_visible_x
)
14243 /* Face extension extends the background and box of IT->face_id
14244 to the end of the line. If the background equals the background
14245 of the frame, we don't have to do anything. */
14246 if (it
->face_before_selective_p
)
14247 face
= FACE_FROM_ID (it
->f
, it
->saved_face_id
);
14249 face
= FACE_FROM_ID (f
, it
->face_id
);
14251 if (FRAME_WINDOW_P (f
)
14252 && face
->box
== FACE_NO_BOX
14253 && face
->background
== FRAME_BACKGROUND_PIXEL (f
)
14257 /* Set the glyph row flag indicating that the face of the last glyph
14258 in the text area has to be drawn to the end of the text area. */
14259 it
->glyph_row
->fill_line_p
= 1;
14261 /* If current character of IT is not ASCII, make sure we have the
14262 ASCII face. This will be automatically undone the next time
14263 get_next_display_element returns a multibyte character. Note
14264 that the character will always be single byte in unibyte text. */
14265 if (!SINGLE_BYTE_CHAR_P (it
->c
))
14267 it
->face_id
= FACE_FOR_CHAR (f
, face
, 0);
14270 if (FRAME_WINDOW_P (f
))
14272 /* If the row is empty, add a space with the current face of IT,
14273 so that we know which face to draw. */
14274 if (it
->glyph_row
->used
[TEXT_AREA
] == 0)
14276 it
->glyph_row
->glyphs
[TEXT_AREA
][0] = space_glyph
;
14277 it
->glyph_row
->glyphs
[TEXT_AREA
][0].face_id
= it
->face_id
;
14278 it
->glyph_row
->used
[TEXT_AREA
] = 1;
14283 /* Save some values that must not be changed. */
14284 int saved_x
= it
->current_x
;
14285 struct text_pos saved_pos
;
14286 Lisp_Object saved_object
;
14287 enum display_element_type saved_what
= it
->what
;
14288 int saved_face_id
= it
->face_id
;
14290 saved_object
= it
->object
;
14291 saved_pos
= it
->position
;
14293 it
->what
= IT_CHARACTER
;
14294 bzero (&it
->position
, sizeof it
->position
);
14295 it
->object
= make_number (0);
14298 it
->face_id
= face
->id
;
14300 PRODUCE_GLYPHS (it
);
14302 while (it
->current_x
<= it
->last_visible_x
)
14303 PRODUCE_GLYPHS (it
);
14305 /* Don't count these blanks really. It would let us insert a left
14306 truncation glyph below and make us set the cursor on them, maybe. */
14307 it
->current_x
= saved_x
;
14308 it
->object
= saved_object
;
14309 it
->position
= saved_pos
;
14310 it
->what
= saved_what
;
14311 it
->face_id
= saved_face_id
;
14316 /* Value is non-zero if text starting at CHARPOS in current_buffer is
14317 trailing whitespace. */
14320 trailing_whitespace_p (charpos
)
14323 int bytepos
= CHAR_TO_BYTE (charpos
);
14326 while (bytepos
< ZV_BYTE
14327 && (c
= FETCH_CHAR (bytepos
),
14328 c
== ' ' || c
== '\t'))
14331 if (bytepos
>= ZV_BYTE
|| c
== '\n' || c
== '\r')
14333 if (bytepos
!= PT_BYTE
)
14340 /* Highlight trailing whitespace, if any, in ROW. */
14343 highlight_trailing_whitespace (f
, row
)
14345 struct glyph_row
*row
;
14347 int used
= row
->used
[TEXT_AREA
];
14351 struct glyph
*start
= row
->glyphs
[TEXT_AREA
];
14352 struct glyph
*glyph
= start
+ used
- 1;
14354 /* Skip over glyphs inserted to display the cursor at the
14355 end of a line, for extending the face of the last glyph
14356 to the end of the line on terminals, and for truncation
14357 and continuation glyphs. */
14358 while (glyph
>= start
14359 && glyph
->type
== CHAR_GLYPH
14360 && INTEGERP (glyph
->object
))
14363 /* If last glyph is a space or stretch, and it's trailing
14364 whitespace, set the face of all trailing whitespace glyphs in
14365 IT->glyph_row to `trailing-whitespace'. */
14367 && BUFFERP (glyph
->object
)
14368 && (glyph
->type
== STRETCH_GLYPH
14369 || (glyph
->type
== CHAR_GLYPH
14370 && glyph
->u
.ch
== ' '))
14371 && trailing_whitespace_p (glyph
->charpos
))
14373 int face_id
= lookup_named_face (f
, Qtrailing_whitespace
, 0);
14375 while (glyph
>= start
14376 && BUFFERP (glyph
->object
)
14377 && (glyph
->type
== STRETCH_GLYPH
14378 || (glyph
->type
== CHAR_GLYPH
14379 && glyph
->u
.ch
== ' ')))
14380 (glyph
--)->face_id
= face_id
;
14386 /* Value is non-zero if glyph row ROW in window W should be
14387 used to hold the cursor. */
14390 cursor_row_p (w
, row
)
14392 struct glyph_row
*row
;
14394 int cursor_row_p
= 1;
14396 if (PT
== MATRIX_ROW_END_CHARPOS (row
))
14398 /* If the row ends with a newline from a string, we don't want
14399 the cursor there (if the row is continued it doesn't end in a
14401 if (CHARPOS (row
->end
.string_pos
) >= 0
14402 || MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
))
14403 cursor_row_p
= row
->continued_p
;
14405 /* If the row ends at ZV, display the cursor at the end of that
14406 row instead of at the start of the row below. */
14407 else if (row
->ends_at_zv_p
)
14413 return cursor_row_p
;
14417 /* Construct the glyph row IT->glyph_row in the desired matrix of
14418 IT->w from text at the current position of IT. See dispextern.h
14419 for an overview of struct it. Value is non-zero if
14420 IT->glyph_row displays text, as opposed to a line displaying ZV
14427 struct glyph_row
*row
= it
->glyph_row
;
14428 int overlay_arrow_bitmap
;
14429 Lisp_Object overlay_arrow_string
;
14431 /* We always start displaying at hpos zero even if hscrolled. */
14432 xassert (it
->hpos
== 0 && it
->current_x
== 0);
14434 /* We must not display in a row that's not a text row. */
14435 xassert (MATRIX_ROW_VPOS (row
, it
->w
->desired_matrix
)
14436 < it
->w
->desired_matrix
->nrows
);
14438 /* Is IT->w showing the region? */
14439 it
->w
->region_showing
= it
->region_beg_charpos
> 0 ? Qt
: Qnil
;
14441 /* Clear the result glyph row and enable it. */
14442 prepare_desired_row (row
);
14444 row
->y
= it
->current_y
;
14445 row
->start
= it
->start
;
14446 row
->continuation_lines_width
= it
->continuation_lines_width
;
14447 row
->displays_text_p
= 1;
14448 row
->starts_in_middle_of_char_p
= it
->starts_in_middle_of_char_p
;
14449 it
->starts_in_middle_of_char_p
= 0;
14451 /* Arrange the overlays nicely for our purposes. Usually, we call
14452 display_line on only one line at a time, in which case this
14453 can't really hurt too much, or we call it on lines which appear
14454 one after another in the buffer, in which case all calls to
14455 recenter_overlay_lists but the first will be pretty cheap. */
14456 recenter_overlay_lists (current_buffer
, IT_CHARPOS (*it
));
14458 /* Move over display elements that are not visible because we are
14459 hscrolled. This may stop at an x-position < IT->first_visible_x
14460 if the first glyph is partially visible or if we hit a line end. */
14461 if (it
->current_x
< it
->first_visible_x
)
14462 move_it_in_display_line_to (it
, ZV
, it
->first_visible_x
,
14463 MOVE_TO_POS
| MOVE_TO_X
);
14465 /* Get the initial row height. This is either the height of the
14466 text hscrolled, if there is any, or zero. */
14467 row
->ascent
= it
->max_ascent
;
14468 row
->height
= it
->max_ascent
+ it
->max_descent
;
14469 row
->phys_ascent
= it
->max_phys_ascent
;
14470 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
14472 /* Loop generating characters. The loop is left with IT on the next
14473 character to display. */
14476 int n_glyphs_before
, hpos_before
, x_before
;
14478 int ascent
= 0, descent
= 0, phys_ascent
= 0, phys_descent
= 0;
14480 /* Retrieve the next thing to display. Value is zero if end of
14482 if (!get_next_display_element (it
))
14484 /* Maybe add a space at the end of this line that is used to
14485 display the cursor there under X. Set the charpos of the
14486 first glyph of blank lines not corresponding to any text
14488 #ifdef HAVE_WINDOW_SYSTEM
14489 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
14490 row
->exact_window_width_line_p
= 1;
14492 #endif /* HAVE_WINDOW_SYSTEM */
14493 if ((append_space_for_newline (it
, 1) && row
->used
[TEXT_AREA
] == 1)
14494 || row
->used
[TEXT_AREA
] == 0)
14496 row
->glyphs
[TEXT_AREA
]->charpos
= -1;
14497 row
->displays_text_p
= 0;
14499 if (!NILP (XBUFFER (it
->w
->buffer
)->indicate_empty_lines
)
14500 && (!MINI_WINDOW_P (it
->w
)
14501 || (minibuf_level
&& EQ (it
->window
, minibuf_window
))))
14502 row
->indicate_empty_line_p
= 1;
14505 it
->continuation_lines_width
= 0;
14506 row
->ends_at_zv_p
= 1;
14510 /* Now, get the metrics of what we want to display. This also
14511 generates glyphs in `row' (which is IT->glyph_row). */
14512 n_glyphs_before
= row
->used
[TEXT_AREA
];
14515 /* Remember the line height so far in case the next element doesn't
14516 fit on the line. */
14517 if (!it
->truncate_lines_p
)
14519 ascent
= it
->max_ascent
;
14520 descent
= it
->max_descent
;
14521 phys_ascent
= it
->max_phys_ascent
;
14522 phys_descent
= it
->max_phys_descent
;
14525 PRODUCE_GLYPHS (it
);
14527 /* If this display element was in marginal areas, continue with
14529 if (it
->area
!= TEXT_AREA
)
14531 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
14532 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
14533 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
14534 row
->phys_height
= max (row
->phys_height
,
14535 it
->max_phys_ascent
+ it
->max_phys_descent
);
14536 set_iterator_to_next (it
, 1);
14540 /* Does the display element fit on the line? If we truncate
14541 lines, we should draw past the right edge of the window. If
14542 we don't truncate, we want to stop so that we can display the
14543 continuation glyph before the right margin. If lines are
14544 continued, there are two possible strategies for characters
14545 resulting in more than 1 glyph (e.g. tabs): Display as many
14546 glyphs as possible in this line and leave the rest for the
14547 continuation line, or display the whole element in the next
14548 line. Original redisplay did the former, so we do it also. */
14549 nglyphs
= row
->used
[TEXT_AREA
] - n_glyphs_before
;
14550 hpos_before
= it
->hpos
;
14553 if (/* Not a newline. */
14555 /* Glyphs produced fit entirely in the line. */
14556 && it
->current_x
< it
->last_visible_x
)
14558 it
->hpos
+= nglyphs
;
14559 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
14560 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
14561 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
14562 row
->phys_height
= max (row
->phys_height
,
14563 it
->max_phys_ascent
+ it
->max_phys_descent
);
14564 if (it
->current_x
- it
->pixel_width
< it
->first_visible_x
)
14565 row
->x
= x
- it
->first_visible_x
;
14570 struct glyph
*glyph
;
14572 for (i
= 0; i
< nglyphs
; ++i
, x
= new_x
)
14574 glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
14575 new_x
= x
+ glyph
->pixel_width
;
14577 if (/* Lines are continued. */
14578 !it
->truncate_lines_p
14579 && (/* Glyph doesn't fit on the line. */
14580 new_x
> it
->last_visible_x
14581 /* Or it fits exactly on a window system frame. */
14582 || (new_x
== it
->last_visible_x
14583 && FRAME_WINDOW_P (it
->f
))))
14585 /* End of a continued line. */
14588 || (new_x
== it
->last_visible_x
14589 && FRAME_WINDOW_P (it
->f
)))
14591 /* Current glyph is the only one on the line or
14592 fits exactly on the line. We must continue
14593 the line because we can't draw the cursor
14594 after the glyph. */
14595 row
->continued_p
= 1;
14596 it
->current_x
= new_x
;
14597 it
->continuation_lines_width
+= new_x
;
14599 if (i
== nglyphs
- 1)
14601 set_iterator_to_next (it
, 1);
14602 #ifdef HAVE_WINDOW_SYSTEM
14603 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
14605 if (!get_next_display_element (it
))
14607 row
->exact_window_width_line_p
= 1;
14608 it
->continuation_lines_width
= 0;
14609 row
->continued_p
= 0;
14610 row
->ends_at_zv_p
= 1;
14612 else if (ITERATOR_AT_END_OF_LINE_P (it
))
14614 row
->continued_p
= 0;
14615 row
->exact_window_width_line_p
= 1;
14618 #endif /* HAVE_WINDOW_SYSTEM */
14621 else if (CHAR_GLYPH_PADDING_P (*glyph
)
14622 && !FRAME_WINDOW_P (it
->f
))
14624 /* A padding glyph that doesn't fit on this line.
14625 This means the whole character doesn't fit
14627 row
->used
[TEXT_AREA
] = n_glyphs_before
;
14629 /* Fill the rest of the row with continuation
14630 glyphs like in 20.x. */
14631 while (row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
]
14632 < row
->glyphs
[1 + TEXT_AREA
])
14633 produce_special_glyphs (it
, IT_CONTINUATION
);
14635 row
->continued_p
= 1;
14636 it
->current_x
= x_before
;
14637 it
->continuation_lines_width
+= x_before
;
14639 /* Restore the height to what it was before the
14640 element not fitting on the line. */
14641 it
->max_ascent
= ascent
;
14642 it
->max_descent
= descent
;
14643 it
->max_phys_ascent
= phys_ascent
;
14644 it
->max_phys_descent
= phys_descent
;
14646 else if (it
->c
== '\t' && FRAME_WINDOW_P (it
->f
))
14648 /* A TAB that extends past the right edge of the
14649 window. This produces a single glyph on
14650 window system frames. We leave the glyph in
14651 this row and let it fill the row, but don't
14652 consume the TAB. */
14653 it
->continuation_lines_width
+= it
->last_visible_x
;
14654 row
->ends_in_middle_of_char_p
= 1;
14655 row
->continued_p
= 1;
14656 glyph
->pixel_width
= it
->last_visible_x
- x
;
14657 it
->starts_in_middle_of_char_p
= 1;
14661 /* Something other than a TAB that draws past
14662 the right edge of the window. Restore
14663 positions to values before the element. */
14664 row
->used
[TEXT_AREA
] = n_glyphs_before
+ i
;
14666 /* Display continuation glyphs. */
14667 if (!FRAME_WINDOW_P (it
->f
))
14668 produce_special_glyphs (it
, IT_CONTINUATION
);
14669 row
->continued_p
= 1;
14671 it
->continuation_lines_width
+= x
;
14673 if (nglyphs
> 1 && i
> 0)
14675 row
->ends_in_middle_of_char_p
= 1;
14676 it
->starts_in_middle_of_char_p
= 1;
14679 /* Restore the height to what it was before the
14680 element not fitting on the line. */
14681 it
->max_ascent
= ascent
;
14682 it
->max_descent
= descent
;
14683 it
->max_phys_ascent
= phys_ascent
;
14684 it
->max_phys_descent
= phys_descent
;
14689 else if (new_x
> it
->first_visible_x
)
14691 /* Increment number of glyphs actually displayed. */
14694 if (x
< it
->first_visible_x
)
14695 /* Glyph is partially visible, i.e. row starts at
14696 negative X position. */
14697 row
->x
= x
- it
->first_visible_x
;
14701 /* Glyph is completely off the left margin of the
14702 window. This should not happen because of the
14703 move_it_in_display_line at the start of this
14704 function, unless the text display area of the
14705 window is empty. */
14706 xassert (it
->first_visible_x
<= it
->last_visible_x
);
14710 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
14711 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
14712 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
14713 row
->phys_height
= max (row
->phys_height
,
14714 it
->max_phys_ascent
+ it
->max_phys_descent
);
14716 /* End of this display line if row is continued. */
14717 if (row
->continued_p
|| row
->ends_at_zv_p
)
14722 /* Is this a line end? If yes, we're also done, after making
14723 sure that a non-default face is extended up to the right
14724 margin of the window. */
14725 if (ITERATOR_AT_END_OF_LINE_P (it
))
14727 int used_before
= row
->used
[TEXT_AREA
];
14729 row
->ends_in_newline_from_string_p
= STRINGP (it
->object
);
14731 #ifdef HAVE_WINDOW_SYSTEM
14732 /* Add a space at the end of the line that is used to
14733 display the cursor there. */
14734 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
14735 append_space_for_newline (it
, 0);
14736 #endif /* HAVE_WINDOW_SYSTEM */
14738 /* Extend the face to the end of the line. */
14739 extend_face_to_end_of_line (it
);
14741 /* Make sure we have the position. */
14742 if (used_before
== 0)
14743 row
->glyphs
[TEXT_AREA
]->charpos
= CHARPOS (it
->position
);
14745 /* Consume the line end. This skips over invisible lines. */
14746 set_iterator_to_next (it
, 1);
14747 it
->continuation_lines_width
= 0;
14751 /* Proceed with next display element. Note that this skips
14752 over lines invisible because of selective display. */
14753 set_iterator_to_next (it
, 1);
14755 /* If we truncate lines, we are done when the last displayed
14756 glyphs reach past the right margin of the window. */
14757 if (it
->truncate_lines_p
14758 && (FRAME_WINDOW_P (it
->f
)
14759 ? (it
->current_x
>= it
->last_visible_x
)
14760 : (it
->current_x
> it
->last_visible_x
)))
14762 /* Maybe add truncation glyphs. */
14763 if (!FRAME_WINDOW_P (it
->f
))
14767 for (i
= row
->used
[TEXT_AREA
] - 1; i
> 0; --i
)
14768 if (!CHAR_GLYPH_PADDING_P (row
->glyphs
[TEXT_AREA
][i
]))
14771 for (n
= row
->used
[TEXT_AREA
]; i
< n
; ++i
)
14773 row
->used
[TEXT_AREA
] = i
;
14774 produce_special_glyphs (it
, IT_TRUNCATION
);
14777 #ifdef HAVE_WINDOW_SYSTEM
14780 /* Don't truncate if we can overflow newline into fringe. */
14781 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
14783 if (!get_next_display_element (it
))
14785 #ifdef HAVE_WINDOW_SYSTEM
14786 it
->continuation_lines_width
= 0;
14787 row
->ends_at_zv_p
= 1;
14788 row
->exact_window_width_line_p
= 1;
14790 #endif /* HAVE_WINDOW_SYSTEM */
14792 if (ITERATOR_AT_END_OF_LINE_P (it
))
14794 row
->exact_window_width_line_p
= 1;
14795 goto at_end_of_line
;
14799 #endif /* HAVE_WINDOW_SYSTEM */
14801 row
->truncated_on_right_p
= 1;
14802 it
->continuation_lines_width
= 0;
14803 reseat_at_next_visible_line_start (it
, 0);
14804 row
->ends_at_zv_p
= FETCH_BYTE (IT_BYTEPOS (*it
) - 1) != '\n';
14805 it
->hpos
= hpos_before
;
14806 it
->current_x
= x_before
;
14811 /* If line is not empty and hscrolled, maybe insert truncation glyphs
14812 at the left window margin. */
14813 if (it
->first_visible_x
14814 && IT_CHARPOS (*it
) != MATRIX_ROW_START_CHARPOS (row
))
14816 if (!FRAME_WINDOW_P (it
->f
))
14817 insert_left_trunc_glyphs (it
);
14818 row
->truncated_on_left_p
= 1;
14821 /* If the start of this line is the overlay arrow-position, then
14822 mark this glyph row as the one containing the overlay arrow.
14823 This is clearly a mess with variable size fonts. It would be
14824 better to let it be displayed like cursors under X. */
14825 if (! overlay_arrow_seen
14826 && (overlay_arrow_string
14827 = overlay_arrow_at_row (it
->f
, row
, &overlay_arrow_bitmap
),
14828 !NILP (overlay_arrow_string
)))
14830 /* Overlay arrow in window redisplay is a fringe bitmap. */
14831 if (!FRAME_WINDOW_P (it
->f
))
14833 struct glyph_row
*arrow_row
14834 = get_overlay_arrow_glyph_row (it
->w
, overlay_arrow_string
);
14835 struct glyph
*glyph
= arrow_row
->glyphs
[TEXT_AREA
];
14836 struct glyph
*arrow_end
= glyph
+ arrow_row
->used
[TEXT_AREA
];
14837 struct glyph
*p
= row
->glyphs
[TEXT_AREA
];
14838 struct glyph
*p2
, *end
;
14840 /* Copy the arrow glyphs. */
14841 while (glyph
< arrow_end
)
14844 /* Throw away padding glyphs. */
14846 end
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
];
14847 while (p2
< end
&& CHAR_GLYPH_PADDING_P (*p2
))
14853 row
->used
[TEXT_AREA
] = p2
- row
->glyphs
[TEXT_AREA
];
14857 overlay_arrow_seen
= 1;
14858 it
->w
->overlay_arrow_bitmap
= overlay_arrow_bitmap
;
14859 row
->overlay_arrow_p
= 1;
14862 /* Compute pixel dimensions of this line. */
14863 compute_line_metrics (it
);
14865 /* Remember the position at which this line ends. */
14866 row
->end
= it
->current
;
14868 /* Save fringe bitmaps in this row. */
14869 row
->left_user_fringe_bitmap
= it
->left_user_fringe_bitmap
;
14870 row
->left_user_fringe_face_id
= it
->left_user_fringe_face_id
;
14871 row
->right_user_fringe_bitmap
= it
->right_user_fringe_bitmap
;
14872 row
->right_user_fringe_face_id
= it
->right_user_fringe_face_id
;
14874 it
->left_user_fringe_bitmap
= 0;
14875 it
->left_user_fringe_face_id
= 0;
14876 it
->right_user_fringe_bitmap
= 0;
14877 it
->right_user_fringe_face_id
= 0;
14879 /* Maybe set the cursor. */
14880 if (it
->w
->cursor
.vpos
< 0
14881 && PT
>= MATRIX_ROW_START_CHARPOS (row
)
14882 && PT
<= MATRIX_ROW_END_CHARPOS (row
)
14883 && cursor_row_p (it
->w
, row
))
14884 set_cursor_from_row (it
->w
, row
, it
->w
->desired_matrix
, 0, 0, 0, 0);
14886 /* Highlight trailing whitespace. */
14887 if (!NILP (Vshow_trailing_whitespace
))
14888 highlight_trailing_whitespace (it
->f
, it
->glyph_row
);
14890 /* Prepare for the next line. This line starts horizontally at (X
14891 HPOS) = (0 0). Vertical positions are incremented. As a
14892 convenience for the caller, IT->glyph_row is set to the next
14894 it
->current_x
= it
->hpos
= 0;
14895 it
->current_y
+= row
->height
;
14898 it
->start
= it
->current
;
14899 return row
->displays_text_p
;
14904 /***********************************************************************
14906 ***********************************************************************/
14908 /* Redisplay the menu bar in the frame for window W.
14910 The menu bar of X frames that don't have X toolkit support is
14911 displayed in a special window W->frame->menu_bar_window.
14913 The menu bar of terminal frames is treated specially as far as
14914 glyph matrices are concerned. Menu bar lines are not part of
14915 windows, so the update is done directly on the frame matrix rows
14916 for the menu bar. */
14919 display_menu_bar (w
)
14922 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
14927 /* Don't do all this for graphical frames. */
14929 if (!NILP (Vwindow_system
))
14932 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
14937 if (FRAME_MAC_P (f
))
14941 #ifdef USE_X_TOOLKIT
14942 xassert (!FRAME_WINDOW_P (f
));
14943 init_iterator (&it
, w
, -1, -1, f
->desired_matrix
->rows
, MENU_FACE_ID
);
14944 it
.first_visible_x
= 0;
14945 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
14946 #else /* not USE_X_TOOLKIT */
14947 if (FRAME_WINDOW_P (f
))
14949 /* Menu bar lines are displayed in the desired matrix of the
14950 dummy window menu_bar_window. */
14951 struct window
*menu_w
;
14952 xassert (WINDOWP (f
->menu_bar_window
));
14953 menu_w
= XWINDOW (f
->menu_bar_window
);
14954 init_iterator (&it
, menu_w
, -1, -1, menu_w
->desired_matrix
->rows
,
14956 it
.first_visible_x
= 0;
14957 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
14961 /* This is a TTY frame, i.e. character hpos/vpos are used as
14963 init_iterator (&it
, w
, -1, -1, f
->desired_matrix
->rows
,
14965 it
.first_visible_x
= 0;
14966 it
.last_visible_x
= FRAME_COLS (f
);
14968 #endif /* not USE_X_TOOLKIT */
14970 if (! mode_line_inverse_video
)
14971 /* Force the menu-bar to be displayed in the default face. */
14972 it
.base_face_id
= it
.face_id
= DEFAULT_FACE_ID
;
14974 /* Clear all rows of the menu bar. */
14975 for (i
= 0; i
< FRAME_MENU_BAR_LINES (f
); ++i
)
14977 struct glyph_row
*row
= it
.glyph_row
+ i
;
14978 clear_glyph_row (row
);
14979 row
->enabled_p
= 1;
14980 row
->full_width_p
= 1;
14983 /* Display all items of the menu bar. */
14984 items
= FRAME_MENU_BAR_ITEMS (it
.f
);
14985 for (i
= 0; i
< XVECTOR (items
)->size
; i
+= 4)
14987 Lisp_Object string
;
14989 /* Stop at nil string. */
14990 string
= AREF (items
, i
+ 1);
14994 /* Remember where item was displayed. */
14995 AREF (items
, i
+ 3) = make_number (it
.hpos
);
14997 /* Display the item, pad with one space. */
14998 if (it
.current_x
< it
.last_visible_x
)
14999 display_string (NULL
, string
, Qnil
, 0, 0, &it
,
15000 SCHARS (string
) + 1, 0, 0, -1);
15003 /* Fill out the line with spaces. */
15004 if (it
.current_x
< it
.last_visible_x
)
15005 display_string ("", Qnil
, Qnil
, 0, 0, &it
, -1, 0, 0, -1);
15007 /* Compute the total height of the lines. */
15008 compute_line_metrics (&it
);
15013 /***********************************************************************
15015 ***********************************************************************/
15017 /* Redisplay mode lines in the window tree whose root is WINDOW. If
15018 FORCE is non-zero, redisplay mode lines unconditionally.
15019 Otherwise, redisplay only mode lines that are garbaged. Value is
15020 the number of windows whose mode lines were redisplayed. */
15023 redisplay_mode_lines (window
, force
)
15024 Lisp_Object window
;
15029 while (!NILP (window
))
15031 struct window
*w
= XWINDOW (window
);
15033 if (WINDOWP (w
->hchild
))
15034 nwindows
+= redisplay_mode_lines (w
->hchild
, force
);
15035 else if (WINDOWP (w
->vchild
))
15036 nwindows
+= redisplay_mode_lines (w
->vchild
, force
);
15038 || FRAME_GARBAGED_P (XFRAME (w
->frame
))
15039 || !MATRIX_MODE_LINE_ROW (w
->current_matrix
)->enabled_p
)
15041 struct text_pos lpoint
;
15042 struct buffer
*old
= current_buffer
;
15044 /* Set the window's buffer for the mode line display. */
15045 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
15046 set_buffer_internal_1 (XBUFFER (w
->buffer
));
15048 /* Point refers normally to the selected window. For any
15049 other window, set up appropriate value. */
15050 if (!EQ (window
, selected_window
))
15052 struct text_pos pt
;
15054 SET_TEXT_POS_FROM_MARKER (pt
, w
->pointm
);
15055 if (CHARPOS (pt
) < BEGV
)
15056 TEMP_SET_PT_BOTH (BEGV
, BEGV_BYTE
);
15057 else if (CHARPOS (pt
) > (ZV
- 1))
15058 TEMP_SET_PT_BOTH (ZV
, ZV_BYTE
);
15060 TEMP_SET_PT_BOTH (CHARPOS (pt
), BYTEPOS (pt
));
15063 /* Display mode lines. */
15064 clear_glyph_matrix (w
->desired_matrix
);
15065 if (display_mode_lines (w
))
15068 w
->must_be_updated_p
= 1;
15071 /* Restore old settings. */
15072 set_buffer_internal_1 (old
);
15073 TEMP_SET_PT_BOTH (CHARPOS (lpoint
), BYTEPOS (lpoint
));
15083 /* Display the mode and/or top line of window W. Value is the number
15084 of mode lines displayed. */
15087 display_mode_lines (w
)
15090 Lisp_Object old_selected_window
, old_selected_frame
;
15093 old_selected_frame
= selected_frame
;
15094 selected_frame
= w
->frame
;
15095 old_selected_window
= selected_window
;
15096 XSETWINDOW (selected_window
, w
);
15098 /* These will be set while the mode line specs are processed. */
15099 line_number_displayed
= 0;
15100 w
->column_number_displayed
= Qnil
;
15102 if (WINDOW_WANTS_MODELINE_P (w
))
15104 struct window
*sel_w
= XWINDOW (old_selected_window
);
15106 /* Select mode line face based on the real selected window. */
15107 display_mode_line (w
, CURRENT_MODE_LINE_FACE_ID_3 (sel_w
, sel_w
, w
),
15108 current_buffer
->mode_line_format
);
15112 if (WINDOW_WANTS_HEADER_LINE_P (w
))
15114 display_mode_line (w
, HEADER_LINE_FACE_ID
,
15115 current_buffer
->header_line_format
);
15119 selected_frame
= old_selected_frame
;
15120 selected_window
= old_selected_window
;
15125 /* Display mode or top line of window W. FACE_ID specifies which line
15126 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
15127 FORMAT is the mode line format to display. Value is the pixel
15128 height of the mode line displayed. */
15131 display_mode_line (w
, face_id
, format
)
15133 enum face_id face_id
;
15134 Lisp_Object format
;
15139 init_iterator (&it
, w
, -1, -1, NULL
, face_id
);
15140 prepare_desired_row (it
.glyph_row
);
15142 it
.glyph_row
->mode_line_p
= 1;
15144 if (! mode_line_inverse_video
)
15145 /* Force the mode-line to be displayed in the default face. */
15146 it
.base_face_id
= it
.face_id
= DEFAULT_FACE_ID
;
15148 /* Temporarily make frame's keyboard the current kboard so that
15149 kboard-local variables in the mode_line_format will get the right
15151 push_frame_kboard (it
.f
);
15152 display_mode_element (&it
, 0, 0, 0, format
, Qnil
, 0);
15153 pop_frame_kboard ();
15155 /* Fill up with spaces. */
15156 display_string (" ", Qnil
, Qnil
, 0, 0, &it
, 10000, -1, -1, 0);
15158 compute_line_metrics (&it
);
15159 it
.glyph_row
->full_width_p
= 1;
15160 it
.glyph_row
->continued_p
= 0;
15161 it
.glyph_row
->truncated_on_left_p
= 0;
15162 it
.glyph_row
->truncated_on_right_p
= 0;
15164 /* Make a 3D mode-line have a shadow at its right end. */
15165 face
= FACE_FROM_ID (it
.f
, face_id
);
15166 extend_face_to_end_of_line (&it
);
15167 if (face
->box
!= FACE_NO_BOX
)
15169 struct glyph
*last
= (it
.glyph_row
->glyphs
[TEXT_AREA
]
15170 + it
.glyph_row
->used
[TEXT_AREA
] - 1);
15171 last
->right_box_line_p
= 1;
15174 return it
.glyph_row
->height
;
15177 /* Alist that caches the results of :propertize.
15178 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
15179 Lisp_Object mode_line_proptrans_alist
;
15181 /* List of strings making up the mode-line. */
15182 Lisp_Object mode_line_string_list
;
15184 /* Base face property when building propertized mode line string. */
15185 static Lisp_Object mode_line_string_face
;
15186 static Lisp_Object mode_line_string_face_prop
;
15189 /* Contribute ELT to the mode line for window IT->w. How it
15190 translates into text depends on its data type.
15192 IT describes the display environment in which we display, as usual.
15194 DEPTH is the depth in recursion. It is used to prevent
15195 infinite recursion here.
15197 FIELD_WIDTH is the number of characters the display of ELT should
15198 occupy in the mode line, and PRECISION is the maximum number of
15199 characters to display from ELT's representation. See
15200 display_string for details.
15202 Returns the hpos of the end of the text generated by ELT.
15204 PROPS is a property list to add to any string we encounter.
15206 If RISKY is nonzero, remove (disregard) any properties in any string
15207 we encounter, and ignore :eval and :propertize.
15209 If the global variable `frame_title_ptr' is non-NULL, then the output
15210 is passed to `store_frame_title' instead of `display_string'. */
15213 display_mode_element (it
, depth
, field_width
, precision
, elt
, props
, risky
)
15216 int field_width
, precision
;
15217 Lisp_Object elt
, props
;
15220 int n
= 0, field
, prec
;
15225 elt
= build_string ("*too-deep*");
15229 switch (SWITCH_ENUM_CAST (XTYPE (elt
)))
15233 /* A string: output it and check for %-constructs within it. */
15235 const unsigned char *this, *lisp_string
;
15237 if (!NILP (props
) || risky
)
15239 Lisp_Object oprops
, aelt
;
15240 oprops
= Ftext_properties_at (make_number (0), elt
);
15242 if (NILP (Fequal (props
, oprops
)) || risky
)
15244 /* If the starting string has properties,
15245 merge the specified ones onto the existing ones. */
15246 if (! NILP (oprops
) && !risky
)
15250 oprops
= Fcopy_sequence (oprops
);
15252 while (CONSP (tem
))
15254 oprops
= Fplist_put (oprops
, XCAR (tem
),
15255 XCAR (XCDR (tem
)));
15256 tem
= XCDR (XCDR (tem
));
15261 aelt
= Fassoc (elt
, mode_line_proptrans_alist
);
15262 if (! NILP (aelt
) && !NILP (Fequal (props
, XCDR (aelt
))))
15264 mode_line_proptrans_alist
15265 = Fcons (aelt
, Fdelq (aelt
, mode_line_proptrans_alist
));
15272 elt
= Fcopy_sequence (elt
);
15273 Fset_text_properties (make_number (0), Flength (elt
),
15275 /* Add this item to mode_line_proptrans_alist. */
15276 mode_line_proptrans_alist
15277 = Fcons (Fcons (elt
, props
),
15278 mode_line_proptrans_alist
);
15279 /* Truncate mode_line_proptrans_alist
15280 to at most 50 elements. */
15281 tem
= Fnthcdr (make_number (50),
15282 mode_line_proptrans_alist
);
15284 XSETCDR (tem
, Qnil
);
15289 this = SDATA (elt
);
15290 lisp_string
= this;
15294 prec
= precision
- n
;
15295 if (frame_title_ptr
)
15296 n
+= store_frame_title (SDATA (elt
), -1, prec
);
15297 else if (!NILP (mode_line_string_list
))
15298 n
+= store_mode_line_string (NULL
, elt
, 1, 0, prec
, Qnil
);
15300 n
+= display_string (NULL
, elt
, Qnil
, 0, 0, it
,
15301 0, prec
, 0, STRING_MULTIBYTE (elt
));
15306 while ((precision
<= 0 || n
< precision
)
15308 && (frame_title_ptr
15309 || !NILP (mode_line_string_list
)
15310 || it
->current_x
< it
->last_visible_x
))
15312 const unsigned char *last
= this;
15314 /* Advance to end of string or next format specifier. */
15315 while ((c
= *this++) != '\0' && c
!= '%')
15318 if (this - 1 != last
)
15320 /* Output to end of string or up to '%'. Field width
15321 is length of string. Don't output more than
15322 PRECISION allows us. */
15325 prec
= chars_in_text (last
, this - last
);
15326 if (precision
> 0 && prec
> precision
- n
)
15327 prec
= precision
- n
;
15329 if (frame_title_ptr
)
15330 n
+= store_frame_title (last
, 0, prec
);
15331 else if (!NILP (mode_line_string_list
))
15333 int bytepos
= last
- lisp_string
;
15334 int charpos
= string_byte_to_char (elt
, bytepos
);
15335 n
+= store_mode_line_string (NULL
,
15336 Fsubstring (elt
, make_number (charpos
),
15337 make_number (charpos
+ prec
)),
15342 int bytepos
= last
- lisp_string
;
15343 int charpos
= string_byte_to_char (elt
, bytepos
);
15344 n
+= display_string (NULL
, elt
, Qnil
, 0, charpos
,
15346 STRING_MULTIBYTE (elt
));
15349 else /* c == '%' */
15351 const unsigned char *percent_position
= this;
15353 /* Get the specified minimum width. Zero means
15356 while ((c
= *this++) >= '0' && c
<= '9')
15357 field
= field
* 10 + c
- '0';
15359 /* Don't pad beyond the total padding allowed. */
15360 if (field_width
- n
> 0 && field
> field_width
- n
)
15361 field
= field_width
- n
;
15363 /* Note that either PRECISION <= 0 or N < PRECISION. */
15364 prec
= precision
- n
;
15367 n
+= display_mode_element (it
, depth
, field
, prec
,
15368 Vglobal_mode_string
, props
,
15373 int bytepos
, charpos
;
15374 unsigned char *spec
;
15376 bytepos
= percent_position
- lisp_string
;
15377 charpos
= (STRING_MULTIBYTE (elt
)
15378 ? string_byte_to_char (elt
, bytepos
)
15382 = decode_mode_spec (it
->w
, c
, field
, prec
, &multibyte
);
15384 if (frame_title_ptr
)
15385 n
+= store_frame_title (spec
, field
, prec
);
15386 else if (!NILP (mode_line_string_list
))
15388 int len
= strlen (spec
);
15389 Lisp_Object tem
= make_string (spec
, len
);
15390 props
= Ftext_properties_at (make_number (charpos
), elt
);
15391 /* Should only keep face property in props */
15392 n
+= store_mode_line_string (NULL
, tem
, 0, field
, prec
, props
);
15396 int nglyphs_before
, nwritten
;
15398 nglyphs_before
= it
->glyph_row
->used
[TEXT_AREA
];
15399 nwritten
= display_string (spec
, Qnil
, elt
,
15404 /* Assign to the glyphs written above the
15405 string where the `%x' came from, position
15409 struct glyph
*glyph
15410 = (it
->glyph_row
->glyphs
[TEXT_AREA
]
15414 for (i
= 0; i
< nwritten
; ++i
)
15416 glyph
[i
].object
= elt
;
15417 glyph
[i
].charpos
= charpos
;
15432 /* A symbol: process the value of the symbol recursively
15433 as if it appeared here directly. Avoid error if symbol void.
15434 Special case: if value of symbol is a string, output the string
15437 register Lisp_Object tem
;
15439 /* If the variable is not marked as risky to set
15440 then its contents are risky to use. */
15441 if (NILP (Fget (elt
, Qrisky_local_variable
)))
15444 tem
= Fboundp (elt
);
15447 tem
= Fsymbol_value (elt
);
15448 /* If value is a string, output that string literally:
15449 don't check for % within it. */
15453 if (!EQ (tem
, elt
))
15455 /* Give up right away for nil or t. */
15465 register Lisp_Object car
, tem
;
15467 /* A cons cell: five distinct cases.
15468 If first element is :eval or :propertize, do something special.
15469 If first element is a string or a cons, process all the elements
15470 and effectively concatenate them.
15471 If first element is a negative number, truncate displaying cdr to
15472 at most that many characters. If positive, pad (with spaces)
15473 to at least that many characters.
15474 If first element is a symbol, process the cadr or caddr recursively
15475 according to whether the symbol's value is non-nil or nil. */
15477 if (EQ (car
, QCeval
))
15479 /* An element of the form (:eval FORM) means evaluate FORM
15480 and use the result as mode line elements. */
15485 if (CONSP (XCDR (elt
)))
15488 spec
= safe_eval (XCAR (XCDR (elt
)));
15489 n
+= display_mode_element (it
, depth
, field_width
- n
,
15490 precision
- n
, spec
, props
,
15494 else if (EQ (car
, QCpropertize
))
15496 /* An element of the form (:propertize ELT PROPS...)
15497 means display ELT but applying properties PROPS. */
15502 if (CONSP (XCDR (elt
)))
15503 n
+= display_mode_element (it
, depth
, field_width
- n
,
15504 precision
- n
, XCAR (XCDR (elt
)),
15505 XCDR (XCDR (elt
)), risky
);
15507 else if (SYMBOLP (car
))
15509 tem
= Fboundp (car
);
15513 /* elt is now the cdr, and we know it is a cons cell.
15514 Use its car if CAR has a non-nil value. */
15517 tem
= Fsymbol_value (car
);
15524 /* Symbol's value is nil (or symbol is unbound)
15525 Get the cddr of the original list
15526 and if possible find the caddr and use that. */
15530 else if (!CONSP (elt
))
15535 else if (INTEGERP (car
))
15537 register int lim
= XINT (car
);
15541 /* Negative int means reduce maximum width. */
15542 if (precision
<= 0)
15545 precision
= min (precision
, -lim
);
15549 /* Padding specified. Don't let it be more than
15550 current maximum. */
15552 lim
= min (precision
, lim
);
15554 /* If that's more padding than already wanted, queue it.
15555 But don't reduce padding already specified even if
15556 that is beyond the current truncation point. */
15557 field_width
= max (lim
, field_width
);
15561 else if (STRINGP (car
) || CONSP (car
))
15563 register int limit
= 50;
15564 /* Limit is to protect against circular lists. */
15567 && (precision
<= 0 || n
< precision
))
15569 n
+= display_mode_element (it
, depth
, field_width
- n
,
15570 precision
- n
, XCAR (elt
),
15580 elt
= build_string ("*invalid*");
15584 /* Pad to FIELD_WIDTH. */
15585 if (field_width
> 0 && n
< field_width
)
15587 if (frame_title_ptr
)
15588 n
+= store_frame_title ("", field_width
- n
, 0);
15589 else if (!NILP (mode_line_string_list
))
15590 n
+= store_mode_line_string ("", Qnil
, 0, field_width
- n
, 0, Qnil
);
15592 n
+= display_string ("", Qnil
, Qnil
, 0, 0, it
, field_width
- n
,
15599 /* Store a mode-line string element in mode_line_string_list.
15601 If STRING is non-null, display that C string. Otherwise, the Lisp
15602 string LISP_STRING is displayed.
15604 FIELD_WIDTH is the minimum number of output glyphs to produce.
15605 If STRING has fewer characters than FIELD_WIDTH, pad to the right
15606 with spaces. FIELD_WIDTH <= 0 means don't pad.
15608 PRECISION is the maximum number of characters to output from
15609 STRING. PRECISION <= 0 means don't truncate the string.
15611 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
15612 properties to the string.
15614 PROPS are the properties to add to the string.
15615 The mode_line_string_face face property is always added to the string.
15618 static int store_mode_line_string (string
, lisp_string
, copy_string
, field_width
, precision
, props
)
15620 Lisp_Object lisp_string
;
15629 if (string
!= NULL
)
15631 len
= strlen (string
);
15632 if (precision
> 0 && len
> precision
)
15634 lisp_string
= make_string (string
, len
);
15636 props
= mode_line_string_face_prop
;
15637 else if (!NILP (mode_line_string_face
))
15639 Lisp_Object face
= Fplist_get (props
, Qface
);
15640 props
= Fcopy_sequence (props
);
15642 face
= mode_line_string_face
;
15644 face
= Fcons (face
, Fcons (mode_line_string_face
, Qnil
));
15645 props
= Fplist_put (props
, Qface
, face
);
15647 Fadd_text_properties (make_number (0), make_number (len
),
15648 props
, lisp_string
);
15652 len
= XFASTINT (Flength (lisp_string
));
15653 if (precision
> 0 && len
> precision
)
15656 lisp_string
= Fsubstring (lisp_string
, make_number (0), make_number (len
));
15659 if (!NILP (mode_line_string_face
))
15663 props
= Ftext_properties_at (make_number (0), lisp_string
);
15664 face
= Fplist_get (props
, Qface
);
15666 face
= mode_line_string_face
;
15668 face
= Fcons (face
, Fcons (mode_line_string_face
, Qnil
));
15669 props
= Fcons (Qface
, Fcons (face
, Qnil
));
15671 lisp_string
= Fcopy_sequence (lisp_string
);
15674 Fadd_text_properties (make_number (0), make_number (len
),
15675 props
, lisp_string
);
15680 mode_line_string_list
= Fcons (lisp_string
, mode_line_string_list
);
15684 if (field_width
> len
)
15686 field_width
-= len
;
15687 lisp_string
= Fmake_string (make_number (field_width
), make_number (' '));
15689 Fadd_text_properties (make_number (0), make_number (field_width
),
15690 props
, lisp_string
);
15691 mode_line_string_list
= Fcons (lisp_string
, mode_line_string_list
);
15699 DEFUN ("format-mode-line", Fformat_mode_line
, Sformat_mode_line
,
15701 doc
: /* Return the mode-line of selected window as a string.
15702 First optional arg FORMAT specifies a different format string (see
15703 `mode-line-format' for details) to use. If FORMAT is t, return
15704 the buffer's header-line. Second optional arg WINDOW specifies a
15705 different window to use as the context for the formatting.
15706 If third optional arg NO-PROPS is non-nil, string is not propertized. */)
15707 (format
, window
, no_props
)
15708 Lisp_Object format
, window
, no_props
;
15713 struct buffer
*old_buffer
= NULL
;
15714 enum face_id face_id
= DEFAULT_FACE_ID
;
15717 window
= selected_window
;
15718 CHECK_WINDOW (window
);
15719 w
= XWINDOW (window
);
15720 CHECK_BUFFER (w
->buffer
);
15722 if (XBUFFER (w
->buffer
) != current_buffer
)
15724 old_buffer
= current_buffer
;
15725 set_buffer_internal_1 (XBUFFER (w
->buffer
));
15728 if (NILP (format
) || EQ (format
, Qt
))
15730 face_id
= NILP (format
)
15731 ? CURRENT_MODE_LINE_FACE_ID (w
) :
15732 HEADER_LINE_FACE_ID
;
15733 format
= NILP (format
)
15734 ? current_buffer
->mode_line_format
15735 : current_buffer
->header_line_format
;
15738 init_iterator (&it
, w
, -1, -1, NULL
, face_id
);
15740 if (NILP (no_props
))
15742 mode_line_string_face
=
15743 (face_id
== MODE_LINE_FACE_ID
? Qmode_line
:
15744 face_id
== MODE_LINE_INACTIVE_FACE_ID
? Qmode_line_inactive
:
15745 face_id
== HEADER_LINE_FACE_ID
? Qheader_line
: Qnil
);
15747 mode_line_string_face_prop
=
15748 NILP (mode_line_string_face
) ? Qnil
:
15749 Fcons (Qface
, Fcons (mode_line_string_face
, Qnil
));
15751 /* We need a dummy last element in mode_line_string_list to
15752 indicate we are building the propertized mode-line string.
15753 Using mode_line_string_face_prop here GC protects it. */
15754 mode_line_string_list
=
15755 Fcons (mode_line_string_face_prop
, Qnil
);
15756 frame_title_ptr
= NULL
;
15760 mode_line_string_face_prop
= Qnil
;
15761 mode_line_string_list
= Qnil
;
15762 frame_title_ptr
= frame_title_buf
;
15765 push_frame_kboard (it
.f
);
15766 display_mode_element (&it
, 0, 0, 0, format
, Qnil
, 0);
15767 pop_frame_kboard ();
15770 set_buffer_internal_1 (old_buffer
);
15772 if (NILP (no_props
))
15775 mode_line_string_list
= Fnreverse (mode_line_string_list
);
15776 str
= Fmapconcat (intern ("identity"), XCDR (mode_line_string_list
),
15777 make_string ("", 0));
15778 mode_line_string_face_prop
= Qnil
;
15779 mode_line_string_list
= Qnil
;
15783 len
= frame_title_ptr
- frame_title_buf
;
15784 if (len
> 0 && frame_title_ptr
[-1] == '-')
15786 /* Mode lines typically ends with numerous dashes; reduce to two dashes. */
15787 while (frame_title_ptr
> frame_title_buf
&& *--frame_title_ptr
== '-')
15789 frame_title_ptr
+= 3; /* restore last non-dash + two dashes */
15790 if (len
> frame_title_ptr
- frame_title_buf
)
15791 len
= frame_title_ptr
- frame_title_buf
;
15794 frame_title_ptr
= NULL
;
15795 return make_string (frame_title_buf
, len
);
15798 /* Write a null-terminated, right justified decimal representation of
15799 the positive integer D to BUF using a minimal field width WIDTH. */
15802 pint2str (buf
, width
, d
)
15803 register char *buf
;
15804 register int width
;
15807 register char *p
= buf
;
15815 *p
++ = d
% 10 + '0';
15820 for (width
-= (int) (p
- buf
); width
> 0; --width
)
15831 /* Write a null-terminated, right justified decimal and "human
15832 readable" representation of the nonnegative integer D to BUF using
15833 a minimal field width WIDTH. D should be smaller than 999.5e24. */
15835 static const char power_letter
[] =
15849 pint2hrstr (buf
, width
, d
)
15854 /* We aim to represent the nonnegative integer D as
15855 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
15858 /* -1 means: do not use TENTHS. */
15862 /* Length of QUOTIENT.TENTHS as a string. */
15868 if (1000 <= quotient
)
15870 /* Scale to the appropriate EXPONENT. */
15873 remainder
= quotient
% 1000;
15877 while (1000 <= quotient
);
15879 /* Round to nearest and decide whether to use TENTHS or not. */
15882 tenths
= remainder
/ 100;
15883 if (50 <= remainder
% 100)
15889 if (quotient
== 10)
15896 if (500 <= remainder
)
15897 if (quotient
< 999)
15907 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
15908 if (tenths
== -1 && quotient
<= 99)
15915 p
= psuffix
= buf
+ max (width
, length
);
15917 /* Print EXPONENT. */
15919 *psuffix
++ = power_letter
[exponent
];
15922 /* Print TENTHS. */
15925 *--p
= '0' + tenths
;
15929 /* Print QUOTIENT. */
15932 int digit
= quotient
% 10;
15933 *--p
= '0' + digit
;
15935 while ((quotient
/= 10) != 0);
15937 /* Print leading spaces. */
15942 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
15943 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
15944 type of CODING_SYSTEM. Return updated pointer into BUF. */
15946 static unsigned char invalid_eol_type
[] = "(*invalid*)";
15949 decode_mode_spec_coding (coding_system
, buf
, eol_flag
)
15950 Lisp_Object coding_system
;
15951 register char *buf
;
15955 int multibyte
= !NILP (current_buffer
->enable_multibyte_characters
);
15956 const unsigned char *eol_str
;
15958 /* The EOL conversion we are using. */
15959 Lisp_Object eoltype
;
15961 val
= Fget (coding_system
, Qcoding_system
);
15964 if (!VECTORP (val
)) /* Not yet decided. */
15969 eoltype
= eol_mnemonic_undecided
;
15970 /* Don't mention EOL conversion if it isn't decided. */
15974 Lisp_Object eolvalue
;
15976 eolvalue
= Fget (coding_system
, Qeol_type
);
15979 *buf
++ = XFASTINT (AREF (val
, 1));
15983 /* The EOL conversion that is normal on this system. */
15985 if (NILP (eolvalue
)) /* Not yet decided. */
15986 eoltype
= eol_mnemonic_undecided
;
15987 else if (VECTORP (eolvalue
)) /* Not yet decided. */
15988 eoltype
= eol_mnemonic_undecided
;
15989 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
15990 eoltype
= (XFASTINT (eolvalue
) == 0
15991 ? eol_mnemonic_unix
15992 : (XFASTINT (eolvalue
) == 1
15993 ? eol_mnemonic_dos
: eol_mnemonic_mac
));
15999 /* Mention the EOL conversion if it is not the usual one. */
16000 if (STRINGP (eoltype
))
16002 eol_str
= SDATA (eoltype
);
16003 eol_str_len
= SBYTES (eoltype
);
16005 else if (INTEGERP (eoltype
)
16006 && CHAR_VALID_P (XINT (eoltype
), 0))
16008 unsigned char *tmp
= (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH
);
16009 eol_str_len
= CHAR_STRING (XINT (eoltype
), tmp
);
16014 eol_str
= invalid_eol_type
;
16015 eol_str_len
= sizeof (invalid_eol_type
) - 1;
16017 bcopy (eol_str
, buf
, eol_str_len
);
16018 buf
+= eol_str_len
;
16024 /* Return a string for the output of a mode line %-spec for window W,
16025 generated by character C. PRECISION >= 0 means don't return a
16026 string longer than that value. FIELD_WIDTH > 0 means pad the
16027 string returned with spaces to that value. Return 1 in *MULTIBYTE
16028 if the result is multibyte text. */
16030 static char lots_of_dashes
[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
16033 decode_mode_spec (w
, c
, field_width
, precision
, multibyte
)
16036 int field_width
, precision
;
16040 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
16041 char *decode_mode_spec_buf
= f
->decode_mode_spec_buffer
;
16042 struct buffer
*b
= XBUFFER (w
->buffer
);
16050 if (!NILP (b
->read_only
))
16052 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
16057 /* This differs from %* only for a modified read-only buffer. */
16058 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
16060 if (!NILP (b
->read_only
))
16065 /* This differs from %* in ignoring read-only-ness. */
16066 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
16078 if (command_loop_level
> 5)
16080 p
= decode_mode_spec_buf
;
16081 for (i
= 0; i
< command_loop_level
; i
++)
16084 return decode_mode_spec_buf
;
16092 if (command_loop_level
> 5)
16094 p
= decode_mode_spec_buf
;
16095 for (i
= 0; i
< command_loop_level
; i
++)
16098 return decode_mode_spec_buf
;
16105 /* Let lots_of_dashes be a string of infinite length. */
16106 if (!NILP (mode_line_string_list
))
16108 if (field_width
<= 0
16109 || field_width
> sizeof (lots_of_dashes
))
16111 for (i
= 0; i
< FRAME_MESSAGE_BUF_SIZE (f
) - 1; ++i
)
16112 decode_mode_spec_buf
[i
] = '-';
16113 decode_mode_spec_buf
[i
] = '\0';
16114 return decode_mode_spec_buf
;
16117 return lots_of_dashes
;
16126 int col
= (int) current_column (); /* iftc */
16127 w
->column_number_displayed
= make_number (col
);
16128 pint2str (decode_mode_spec_buf
, field_width
, col
);
16129 return decode_mode_spec_buf
;
16133 /* %F displays the frame name. */
16134 if (!NILP (f
->title
))
16135 return (char *) SDATA (f
->title
);
16136 if (f
->explicit_name
|| ! FRAME_WINDOW_P (f
))
16137 return (char *) SDATA (f
->name
);
16146 int size
= ZV
- BEGV
;
16147 pint2str (decode_mode_spec_buf
, field_width
, size
);
16148 return decode_mode_spec_buf
;
16153 int size
= ZV
- BEGV
;
16154 pint2hrstr (decode_mode_spec_buf
, field_width
, size
);
16155 return decode_mode_spec_buf
;
16160 int startpos
= XMARKER (w
->start
)->charpos
;
16161 int startpos_byte
= marker_byte_position (w
->start
);
16162 int line
, linepos
, linepos_byte
, topline
;
16164 int height
= WINDOW_TOTAL_LINES (w
);
16166 /* If we decided that this buffer isn't suitable for line numbers,
16167 don't forget that too fast. */
16168 if (EQ (w
->base_line_pos
, w
->buffer
))
16170 /* But do forget it, if the window shows a different buffer now. */
16171 else if (BUFFERP (w
->base_line_pos
))
16172 w
->base_line_pos
= Qnil
;
16174 /* If the buffer is very big, don't waste time. */
16175 if (INTEGERP (Vline_number_display_limit
)
16176 && BUF_ZV (b
) - BUF_BEGV (b
) > XINT (Vline_number_display_limit
))
16178 w
->base_line_pos
= Qnil
;
16179 w
->base_line_number
= Qnil
;
16183 if (!NILP (w
->base_line_number
)
16184 && !NILP (w
->base_line_pos
)
16185 && XFASTINT (w
->base_line_pos
) <= startpos
)
16187 line
= XFASTINT (w
->base_line_number
);
16188 linepos
= XFASTINT (w
->base_line_pos
);
16189 linepos_byte
= buf_charpos_to_bytepos (b
, linepos
);
16194 linepos
= BUF_BEGV (b
);
16195 linepos_byte
= BUF_BEGV_BYTE (b
);
16198 /* Count lines from base line to window start position. */
16199 nlines
= display_count_lines (linepos
, linepos_byte
,
16203 topline
= nlines
+ line
;
16205 /* Determine a new base line, if the old one is too close
16206 or too far away, or if we did not have one.
16207 "Too close" means it's plausible a scroll-down would
16208 go back past it. */
16209 if (startpos
== BUF_BEGV (b
))
16211 w
->base_line_number
= make_number (topline
);
16212 w
->base_line_pos
= make_number (BUF_BEGV (b
));
16214 else if (nlines
< height
+ 25 || nlines
> height
* 3 + 50
16215 || linepos
== BUF_BEGV (b
))
16217 int limit
= BUF_BEGV (b
);
16218 int limit_byte
= BUF_BEGV_BYTE (b
);
16220 int distance
= (height
* 2 + 30) * line_number_display_limit_width
;
16222 if (startpos
- distance
> limit
)
16224 limit
= startpos
- distance
;
16225 limit_byte
= CHAR_TO_BYTE (limit
);
16228 nlines
= display_count_lines (startpos
, startpos_byte
,
16230 - (height
* 2 + 30),
16232 /* If we couldn't find the lines we wanted within
16233 line_number_display_limit_width chars per line,
16234 give up on line numbers for this window. */
16235 if (position
== limit_byte
&& limit
== startpos
- distance
)
16237 w
->base_line_pos
= w
->buffer
;
16238 w
->base_line_number
= Qnil
;
16242 w
->base_line_number
= make_number (topline
- nlines
);
16243 w
->base_line_pos
= make_number (BYTE_TO_CHAR (position
));
16246 /* Now count lines from the start pos to point. */
16247 nlines
= display_count_lines (startpos
, startpos_byte
,
16248 PT_BYTE
, PT
, &junk
);
16250 /* Record that we did display the line number. */
16251 line_number_displayed
= 1;
16253 /* Make the string to show. */
16254 pint2str (decode_mode_spec_buf
, field_width
, topline
+ nlines
);
16255 return decode_mode_spec_buf
;
16258 char* p
= decode_mode_spec_buf
;
16259 int pad
= field_width
- 2;
16265 return decode_mode_spec_buf
;
16271 obj
= b
->mode_name
;
16275 if (BUF_BEGV (b
) > BUF_BEG (b
) || BUF_ZV (b
) < BUF_Z (b
))
16281 int pos
= marker_position (w
->start
);
16282 int total
= BUF_ZV (b
) - BUF_BEGV (b
);
16284 if (XFASTINT (w
->window_end_pos
) <= BUF_Z (b
) - BUF_ZV (b
))
16286 if (pos
<= BUF_BEGV (b
))
16291 else if (pos
<= BUF_BEGV (b
))
16295 if (total
> 1000000)
16296 /* Do it differently for a large value, to avoid overflow. */
16297 total
= ((pos
- BUF_BEGV (b
)) + (total
/ 100) - 1) / (total
/ 100);
16299 total
= ((pos
- BUF_BEGV (b
)) * 100 + total
- 1) / total
;
16300 /* We can't normally display a 3-digit number,
16301 so get us a 2-digit number that is close. */
16304 sprintf (decode_mode_spec_buf
, "%2d%%", total
);
16305 return decode_mode_spec_buf
;
16309 /* Display percentage of size above the bottom of the screen. */
16312 int toppos
= marker_position (w
->start
);
16313 int botpos
= BUF_Z (b
) - XFASTINT (w
->window_end_pos
);
16314 int total
= BUF_ZV (b
) - BUF_BEGV (b
);
16316 if (botpos
>= BUF_ZV (b
))
16318 if (toppos
<= BUF_BEGV (b
))
16325 if (total
> 1000000)
16326 /* Do it differently for a large value, to avoid overflow. */
16327 total
= ((botpos
- BUF_BEGV (b
)) + (total
/ 100) - 1) / (total
/ 100);
16329 total
= ((botpos
- BUF_BEGV (b
)) * 100 + total
- 1) / total
;
16330 /* We can't normally display a 3-digit number,
16331 so get us a 2-digit number that is close. */
16334 if (toppos
<= BUF_BEGV (b
))
16335 sprintf (decode_mode_spec_buf
, "Top%2d%%", total
);
16337 sprintf (decode_mode_spec_buf
, "%2d%%", total
);
16338 return decode_mode_spec_buf
;
16343 /* status of process */
16344 obj
= Fget_buffer_process (w
->buffer
);
16346 return "no process";
16347 #ifdef subprocesses
16348 obj
= Fsymbol_name (Fprocess_status (obj
));
16352 case 't': /* indicate TEXT or BINARY */
16353 #ifdef MODE_LINE_BINARY_TEXT
16354 return MODE_LINE_BINARY_TEXT (b
);
16360 /* coding-system (not including end-of-line format) */
16362 /* coding-system (including end-of-line type) */
16364 int eol_flag
= (c
== 'Z');
16365 char *p
= decode_mode_spec_buf
;
16367 if (! FRAME_WINDOW_P (f
))
16369 /* No need to mention EOL here--the terminal never needs
16370 to do EOL conversion. */
16371 p
= decode_mode_spec_coding (keyboard_coding
.symbol
, p
, 0);
16372 p
= decode_mode_spec_coding (terminal_coding
.symbol
, p
, 0);
16374 p
= decode_mode_spec_coding (b
->buffer_file_coding_system
,
16377 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
16378 #ifdef subprocesses
16379 obj
= Fget_buffer_process (Fcurrent_buffer ());
16380 if (PROCESSP (obj
))
16382 p
= decode_mode_spec_coding (XPROCESS (obj
)->decode_coding_system
,
16384 p
= decode_mode_spec_coding (XPROCESS (obj
)->encode_coding_system
,
16387 #endif /* subprocesses */
16390 return decode_mode_spec_buf
;
16396 *multibyte
= STRING_MULTIBYTE (obj
);
16397 return (char *) SDATA (obj
);
16404 /* Count up to COUNT lines starting from START / START_BYTE.
16405 But don't go beyond LIMIT_BYTE.
16406 Return the number of lines thus found (always nonnegative).
16408 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
16411 display_count_lines (start
, start_byte
, limit_byte
, count
, byte_pos_ptr
)
16412 int start
, start_byte
, limit_byte
, count
;
16415 register unsigned char *cursor
;
16416 unsigned char *base
;
16418 register int ceiling
;
16419 register unsigned char *ceiling_addr
;
16420 int orig_count
= count
;
16422 /* If we are not in selective display mode,
16423 check only for newlines. */
16424 int selective_display
= (!NILP (current_buffer
->selective_display
)
16425 && !INTEGERP (current_buffer
->selective_display
));
16429 while (start_byte
< limit_byte
)
16431 ceiling
= BUFFER_CEILING_OF (start_byte
);
16432 ceiling
= min (limit_byte
- 1, ceiling
);
16433 ceiling_addr
= BYTE_POS_ADDR (ceiling
) + 1;
16434 base
= (cursor
= BYTE_POS_ADDR (start_byte
));
16437 if (selective_display
)
16438 while (*cursor
!= '\n' && *cursor
!= 015 && ++cursor
!= ceiling_addr
)
16441 while (*cursor
!= '\n' && ++cursor
!= ceiling_addr
)
16444 if (cursor
!= ceiling_addr
)
16448 start_byte
+= cursor
- base
+ 1;
16449 *byte_pos_ptr
= start_byte
;
16453 if (++cursor
== ceiling_addr
)
16459 start_byte
+= cursor
- base
;
16464 while (start_byte
> limit_byte
)
16466 ceiling
= BUFFER_FLOOR_OF (start_byte
- 1);
16467 ceiling
= max (limit_byte
, ceiling
);
16468 ceiling_addr
= BYTE_POS_ADDR (ceiling
) - 1;
16469 base
= (cursor
= BYTE_POS_ADDR (start_byte
- 1) + 1);
16472 if (selective_display
)
16473 while (--cursor
!= ceiling_addr
16474 && *cursor
!= '\n' && *cursor
!= 015)
16477 while (--cursor
!= ceiling_addr
&& *cursor
!= '\n')
16480 if (cursor
!= ceiling_addr
)
16484 start_byte
+= cursor
- base
+ 1;
16485 *byte_pos_ptr
= start_byte
;
16486 /* When scanning backwards, we should
16487 not count the newline posterior to which we stop. */
16488 return - orig_count
- 1;
16494 /* Here we add 1 to compensate for the last decrement
16495 of CURSOR, which took it past the valid range. */
16496 start_byte
+= cursor
- base
+ 1;
16500 *byte_pos_ptr
= limit_byte
;
16503 return - orig_count
+ count
;
16504 return orig_count
- count
;
16510 /***********************************************************************
16512 ***********************************************************************/
16514 /* Display a NUL-terminated string, starting with index START.
16516 If STRING is non-null, display that C string. Otherwise, the Lisp
16517 string LISP_STRING is displayed.
16519 If FACE_STRING is not nil, FACE_STRING_POS is a position in
16520 FACE_STRING. Display STRING or LISP_STRING with the face at
16521 FACE_STRING_POS in FACE_STRING:
16523 Display the string in the environment given by IT, but use the
16524 standard display table, temporarily.
16526 FIELD_WIDTH is the minimum number of output glyphs to produce.
16527 If STRING has fewer characters than FIELD_WIDTH, pad to the right
16528 with spaces. If STRING has more characters, more than FIELD_WIDTH
16529 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
16531 PRECISION is the maximum number of characters to output from
16532 STRING. PRECISION < 0 means don't truncate the string.
16534 This is roughly equivalent to printf format specifiers:
16536 FIELD_WIDTH PRECISION PRINTF
16537 ----------------------------------------
16543 MULTIBYTE zero means do not display multibyte chars, > 0 means do
16544 display them, and < 0 means obey the current buffer's value of
16545 enable_multibyte_characters.
16547 Value is the number of glyphs produced. */
16550 display_string (string
, lisp_string
, face_string
, face_string_pos
,
16551 start
, it
, field_width
, precision
, max_x
, multibyte
)
16552 unsigned char *string
;
16553 Lisp_Object lisp_string
;
16554 Lisp_Object face_string
;
16555 int face_string_pos
;
16558 int field_width
, precision
, max_x
;
16561 int hpos_at_start
= it
->hpos
;
16562 int saved_face_id
= it
->face_id
;
16563 struct glyph_row
*row
= it
->glyph_row
;
16565 /* Initialize the iterator IT for iteration over STRING beginning
16566 with index START. */
16567 reseat_to_string (it
, string
, lisp_string
, start
,
16568 precision
, field_width
, multibyte
);
16570 /* If displaying STRING, set up the face of the iterator
16571 from LISP_STRING, if that's given. */
16572 if (STRINGP (face_string
))
16578 = face_at_string_position (it
->w
, face_string
, face_string_pos
,
16579 0, it
->region_beg_charpos
,
16580 it
->region_end_charpos
,
16581 &endptr
, it
->base_face_id
, 0);
16582 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
16583 it
->face_box_p
= face
->box
!= FACE_NO_BOX
;
16586 /* Set max_x to the maximum allowed X position. Don't let it go
16587 beyond the right edge of the window. */
16589 max_x
= it
->last_visible_x
;
16591 max_x
= min (max_x
, it
->last_visible_x
);
16593 /* Skip over display elements that are not visible. because IT->w is
16595 if (it
->current_x
< it
->first_visible_x
)
16596 move_it_in_display_line_to (it
, 100000, it
->first_visible_x
,
16597 MOVE_TO_POS
| MOVE_TO_X
);
16599 row
->ascent
= it
->max_ascent
;
16600 row
->height
= it
->max_ascent
+ it
->max_descent
;
16601 row
->phys_ascent
= it
->max_phys_ascent
;
16602 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
16604 /* This condition is for the case that we are called with current_x
16605 past last_visible_x. */
16606 while (it
->current_x
< max_x
)
16608 int x_before
, x
, n_glyphs_before
, i
, nglyphs
;
16610 /* Get the next display element. */
16611 if (!get_next_display_element (it
))
16614 /* Produce glyphs. */
16615 x_before
= it
->current_x
;
16616 n_glyphs_before
= it
->glyph_row
->used
[TEXT_AREA
];
16617 PRODUCE_GLYPHS (it
);
16619 nglyphs
= it
->glyph_row
->used
[TEXT_AREA
] - n_glyphs_before
;
16622 while (i
< nglyphs
)
16624 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
16626 if (!it
->truncate_lines_p
16627 && x
+ glyph
->pixel_width
> max_x
)
16629 /* End of continued line or max_x reached. */
16630 if (CHAR_GLYPH_PADDING_P (*glyph
))
16632 /* A wide character is unbreakable. */
16633 it
->glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
;
16634 it
->current_x
= x_before
;
16638 it
->glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
+ i
;
16643 else if (x
+ glyph
->pixel_width
> it
->first_visible_x
)
16645 /* Glyph is at least partially visible. */
16647 if (x
< it
->first_visible_x
)
16648 it
->glyph_row
->x
= x
- it
->first_visible_x
;
16652 /* Glyph is off the left margin of the display area.
16653 Should not happen. */
16657 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
16658 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
16659 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
16660 row
->phys_height
= max (row
->phys_height
,
16661 it
->max_phys_ascent
+ it
->max_phys_descent
);
16662 x
+= glyph
->pixel_width
;
16666 /* Stop if max_x reached. */
16670 /* Stop at line ends. */
16671 if (ITERATOR_AT_END_OF_LINE_P (it
))
16673 it
->continuation_lines_width
= 0;
16677 set_iterator_to_next (it
, 1);
16679 /* Stop if truncating at the right edge. */
16680 if (it
->truncate_lines_p
16681 && it
->current_x
>= it
->last_visible_x
)
16683 /* Add truncation mark, but don't do it if the line is
16684 truncated at a padding space. */
16685 if (IT_CHARPOS (*it
) < it
->string_nchars
)
16687 if (!FRAME_WINDOW_P (it
->f
))
16691 if (it
->current_x
> it
->last_visible_x
)
16693 for (i
= row
->used
[TEXT_AREA
] - 1; i
> 0; --i
)
16694 if (!CHAR_GLYPH_PADDING_P (row
->glyphs
[TEXT_AREA
][i
]))
16696 for (n
= row
->used
[TEXT_AREA
]; i
< n
; ++i
)
16698 row
->used
[TEXT_AREA
] = i
;
16699 produce_special_glyphs (it
, IT_TRUNCATION
);
16702 produce_special_glyphs (it
, IT_TRUNCATION
);
16704 it
->glyph_row
->truncated_on_right_p
= 1;
16710 /* Maybe insert a truncation at the left. */
16711 if (it
->first_visible_x
16712 && IT_CHARPOS (*it
) > 0)
16714 if (!FRAME_WINDOW_P (it
->f
))
16715 insert_left_trunc_glyphs (it
);
16716 it
->glyph_row
->truncated_on_left_p
= 1;
16719 it
->face_id
= saved_face_id
;
16721 /* Value is number of columns displayed. */
16722 return it
->hpos
- hpos_at_start
;
16727 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
16728 appears as an element of LIST or as the car of an element of LIST.
16729 If PROPVAL is a list, compare each element against LIST in that
16730 way, and return 1/2 if any element of PROPVAL is found in LIST.
16731 Otherwise return 0. This function cannot quit.
16732 The return value is 2 if the text is invisible but with an ellipsis
16733 and 1 if it's invisible and without an ellipsis. */
16736 invisible_p (propval
, list
)
16737 register Lisp_Object propval
;
16740 register Lisp_Object tail
, proptail
;
16742 for (tail
= list
; CONSP (tail
); tail
= XCDR (tail
))
16744 register Lisp_Object tem
;
16746 if (EQ (propval
, tem
))
16748 if (CONSP (tem
) && EQ (propval
, XCAR (tem
)))
16749 return NILP (XCDR (tem
)) ? 1 : 2;
16752 if (CONSP (propval
))
16754 for (proptail
= propval
; CONSP (proptail
); proptail
= XCDR (proptail
))
16756 Lisp_Object propelt
;
16757 propelt
= XCAR (proptail
);
16758 for (tail
= list
; CONSP (tail
); tail
= XCDR (tail
))
16760 register Lisp_Object tem
;
16762 if (EQ (propelt
, tem
))
16764 if (CONSP (tem
) && EQ (propelt
, XCAR (tem
)))
16765 return NILP (XCDR (tem
)) ? 1 : 2;
16773 /* Calculate a width or height in pixels from a specification using
16774 the following elements:
16777 NUM - a (fractional) multiple of the default font width/height
16778 (NUM) - specifies exactly NUM pixels
16779 UNIT - a fixed number of pixels, see below.
16780 ELEMENT - size of a display element in pixels, see below.
16781 (NUM . SPEC) - equals NUM * SPEC
16782 (+ SPEC SPEC ...) - add pixel values
16783 (- SPEC SPEC ...) - subtract pixel values
16784 (- SPEC) - negate pixel value
16787 INT or FLOAT - a number constant
16788 SYMBOL - use symbol's (buffer local) variable binding.
16791 in - pixels per inch *)
16792 mm - pixels per 1/1000 meter *)
16793 cm - pixels per 1/100 meter *)
16794 width - width of current font in pixels.
16795 height - height of current font in pixels.
16797 *) using the ratio(s) defined in display-pixels-per-inch.
16801 left-fringe - left fringe width in pixels
16802 right-fringe - right fringe width in pixels
16804 left-margin - left margin width in pixels
16805 right-margin - right margin width in pixels
16807 scroll-bar - scroll-bar area width in pixels
16811 Pixels corresponding to 5 inches:
16814 Total width of non-text areas on left side of window (if scroll-bar is on left):
16815 '(space :width (+ left-fringe left-margin scroll-bar))
16817 Align to first text column (in header line):
16818 '(space :align-to 0)
16820 Align to middle of text area minus half the width of variable `my-image'
16821 containing a loaded image:
16822 '(space :align-to (0.5 . (- text my-image)))
16824 Width of left margin minus width of 1 character in the default font:
16825 '(space :width (- left-margin 1))
16827 Width of left margin minus width of 2 characters in the current font:
16828 '(space :width (- left-margin (2 . width)))
16830 Center 1 character over left-margin (in header line):
16831 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
16833 Different ways to express width of left fringe plus left margin minus one pixel:
16834 '(space :width (- (+ left-fringe left-margin) (1)))
16835 '(space :width (+ left-fringe left-margin (- (1))))
16836 '(space :width (+ left-fringe left-margin (-1)))
16840 #define NUMVAL(X) \
16841 ((INTEGERP (X) || FLOATP (X)) \
16846 calc_pixel_width_or_height (res
, it
, prop
, font
, width_p
, align_to
)
16851 int width_p
, *align_to
;
16855 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
16856 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
16859 return OK_PIXELS (0);
16861 if (SYMBOLP (prop
))
16863 if (SCHARS (SYMBOL_NAME (prop
)) == 2)
16865 char *unit
= SDATA (SYMBOL_NAME (prop
));
16867 if (unit
[0] == 'i' && unit
[1] == 'n')
16869 else if (unit
[0] == 'm' && unit
[1] == 'm')
16871 else if (unit
[0] == 'c' && unit
[1] == 'm')
16878 if ((ppi
= NUMVAL (Vdisplay_pixels_per_inch
), ppi
> 0)
16879 || (CONSP (Vdisplay_pixels_per_inch
)
16881 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch
))
16882 : NUMVAL (XCDR (Vdisplay_pixels_per_inch
))),
16884 return OK_PIXELS (ppi
/ pixels
);
16890 #ifdef HAVE_WINDOW_SYSTEM
16891 if (EQ (prop
, Qheight
))
16892 return OK_PIXELS (font
? FONT_HEIGHT ((XFontStruct
*)font
) : FRAME_LINE_HEIGHT (it
->f
));
16893 if (EQ (prop
, Qwidth
))
16894 return OK_PIXELS (font
? FONT_WIDTH ((XFontStruct
*)font
) : FRAME_COLUMN_WIDTH (it
->f
));
16896 if (EQ (prop
, Qheight
) || EQ (prop
, Qwidth
))
16897 return OK_PIXELS (1);
16900 if (EQ (prop
, Qtext
))
16901 return OK_PIXELS (width_p
16902 ? window_box_width (it
->w
, TEXT_AREA
)
16903 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it
->w
));
16905 if (align_to
&& *align_to
< 0)
16908 if (EQ (prop
, Qleft
))
16909 return OK_ALIGN_TO (window_box_left_offset (it
->w
, TEXT_AREA
));
16910 if (EQ (prop
, Qright
))
16911 return OK_ALIGN_TO (window_box_right_offset (it
->w
, TEXT_AREA
));
16912 if (EQ (prop
, Qcenter
))
16913 return OK_ALIGN_TO (window_box_left_offset (it
->w
, TEXT_AREA
)
16914 + window_box_width (it
->w
, TEXT_AREA
) / 2);
16915 if (EQ (prop
, Qleft_fringe
))
16916 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it
->w
)
16917 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it
->w
)
16918 : window_box_right_offset (it
->w
, LEFT_MARGIN_AREA
));
16919 if (EQ (prop
, Qright_fringe
))
16920 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it
->w
)
16921 ? window_box_right_offset (it
->w
, RIGHT_MARGIN_AREA
)
16922 : window_box_right_offset (it
->w
, TEXT_AREA
));
16923 if (EQ (prop
, Qleft_margin
))
16924 return OK_ALIGN_TO (window_box_left_offset (it
->w
, LEFT_MARGIN_AREA
));
16925 if (EQ (prop
, Qright_margin
))
16926 return OK_ALIGN_TO (window_box_left_offset (it
->w
, RIGHT_MARGIN_AREA
));
16927 if (EQ (prop
, Qscroll_bar
))
16928 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it
->w
)
16930 : (window_box_right_offset (it
->w
, RIGHT_MARGIN_AREA
)
16931 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it
->w
)
16932 ? WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)
16937 if (EQ (prop
, Qleft_fringe
))
16938 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it
->w
));
16939 if (EQ (prop
, Qright_fringe
))
16940 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it
->w
));
16941 if (EQ (prop
, Qleft_margin
))
16942 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it
->w
));
16943 if (EQ (prop
, Qright_margin
))
16944 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it
->w
));
16945 if (EQ (prop
, Qscroll_bar
))
16946 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it
->w
));
16949 prop
= Fbuffer_local_value (prop
, it
->w
->buffer
);
16952 if (INTEGERP (prop
) || FLOATP (prop
))
16954 int base_unit
= (width_p
16955 ? FRAME_COLUMN_WIDTH (it
->f
)
16956 : FRAME_LINE_HEIGHT (it
->f
));
16957 return OK_PIXELS (XFLOATINT (prop
) * base_unit
);
16962 Lisp_Object car
= XCAR (prop
);
16963 Lisp_Object cdr
= XCDR (prop
);
16967 #ifdef HAVE_WINDOW_SYSTEM
16968 if (valid_image_p (prop
))
16970 int id
= lookup_image (it
->f
, prop
);
16971 struct image
*img
= IMAGE_FROM_ID (it
->f
, id
);
16973 return OK_PIXELS (width_p
? img
->width
: img
->height
);
16976 if (EQ (car
, Qplus
) || EQ (car
, Qminus
))
16982 while (CONSP (cdr
))
16984 if (!calc_pixel_width_or_height (&px
, it
, XCAR (cdr
),
16985 font
, width_p
, align_to
))
16988 pixels
= (EQ (car
, Qplus
) ? px
: -px
), first
= 0;
16993 if (EQ (car
, Qminus
))
16995 return OK_PIXELS (pixels
);
16998 car
= Fbuffer_local_value (car
, it
->w
->buffer
);
17001 if (INTEGERP (car
) || FLOATP (car
))
17004 pixels
= XFLOATINT (car
);
17006 return OK_PIXELS (pixels
);
17007 if (calc_pixel_width_or_height (&fact
, it
, cdr
,
17008 font
, width_p
, align_to
))
17009 return OK_PIXELS (pixels
* fact
);
17020 /***********************************************************************
17022 ***********************************************************************/
17024 #ifdef HAVE_WINDOW_SYSTEM
17029 dump_glyph_string (s
)
17030 struct glyph_string
*s
;
17032 fprintf (stderr
, "glyph string\n");
17033 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
17034 s
->x
, s
->y
, s
->width
, s
->height
);
17035 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
17036 fprintf (stderr
, " hl = %d\n", s
->hl
);
17037 fprintf (stderr
, " left overhang = %d, right = %d\n",
17038 s
->left_overhang
, s
->right_overhang
);
17039 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
17040 fprintf (stderr
, " extends to end of line = %d\n",
17041 s
->extends_to_end_of_line_p
);
17042 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
17043 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
17046 #endif /* GLYPH_DEBUG */
17048 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
17049 of XChar2b structures for S; it can't be allocated in
17050 init_glyph_string because it must be allocated via `alloca'. W
17051 is the window on which S is drawn. ROW and AREA are the glyph row
17052 and area within the row from which S is constructed. START is the
17053 index of the first glyph structure covered by S. HL is a
17054 face-override for drawing S. */
17057 #define OPTIONAL_HDC(hdc) hdc,
17058 #define DECLARE_HDC(hdc) HDC hdc;
17059 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
17060 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
17063 #ifndef OPTIONAL_HDC
17064 #define OPTIONAL_HDC(hdc)
17065 #define DECLARE_HDC(hdc)
17066 #define ALLOCATE_HDC(hdc, f)
17067 #define RELEASE_HDC(hdc, f)
17071 init_glyph_string (s
, OPTIONAL_HDC (hdc
) char2b
, w
, row
, area
, start
, hl
)
17072 struct glyph_string
*s
;
17076 struct glyph_row
*row
;
17077 enum glyph_row_area area
;
17079 enum draw_glyphs_face hl
;
17081 bzero (s
, sizeof *s
);
17083 s
->f
= XFRAME (w
->frame
);
17087 s
->display
= FRAME_X_DISPLAY (s
->f
);
17088 s
->window
= FRAME_X_WINDOW (s
->f
);
17089 s
->char2b
= char2b
;
17093 s
->first_glyph
= row
->glyphs
[area
] + start
;
17094 s
->height
= row
->height
;
17095 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
17097 /* Display the internal border below the tool-bar window. */
17098 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
17099 s
->y
-= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
17101 s
->ybase
= s
->y
+ row
->ascent
;
17105 /* Append the list of glyph strings with head H and tail T to the list
17106 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
17109 append_glyph_string_lists (head
, tail
, h
, t
)
17110 struct glyph_string
**head
, **tail
;
17111 struct glyph_string
*h
, *t
;
17125 /* Prepend the list of glyph strings with head H and tail T to the
17126 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
17130 prepend_glyph_string_lists (head
, tail
, h
, t
)
17131 struct glyph_string
**head
, **tail
;
17132 struct glyph_string
*h
, *t
;
17146 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
17147 Set *HEAD and *TAIL to the resulting list. */
17150 append_glyph_string (head
, tail
, s
)
17151 struct glyph_string
**head
, **tail
;
17152 struct glyph_string
*s
;
17154 s
->next
= s
->prev
= NULL
;
17155 append_glyph_string_lists (head
, tail
, s
, s
);
17159 /* Get face and two-byte form of character glyph GLYPH on frame F.
17160 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
17161 a pointer to a realized face that is ready for display. */
17163 static INLINE
struct face
*
17164 get_glyph_face_and_encoding (f
, glyph
, char2b
, two_byte_p
)
17166 struct glyph
*glyph
;
17172 xassert (glyph
->type
== CHAR_GLYPH
);
17173 face
= FACE_FROM_ID (f
, glyph
->face_id
);
17178 if (!glyph
->multibyte_p
)
17180 /* Unibyte case. We don't have to encode, but we have to make
17181 sure to use a face suitable for unibyte. */
17182 STORE_XCHAR2B (char2b
, 0, glyph
->u
.ch
);
17184 else if (glyph
->u
.ch
< 128
17185 && glyph
->face_id
< BASIC_FACE_ID_SENTINEL
)
17187 /* Case of ASCII in a face known to fit ASCII. */
17188 STORE_XCHAR2B (char2b
, 0, glyph
->u
.ch
);
17192 int c1
, c2
, charset
;
17194 /* Split characters into bytes. If c2 is -1 afterwards, C is
17195 really a one-byte character so that byte1 is zero. */
17196 SPLIT_CHAR (glyph
->u
.ch
, charset
, c1
, c2
);
17198 STORE_XCHAR2B (char2b
, c1
, c2
);
17200 STORE_XCHAR2B (char2b
, 0, c1
);
17202 /* Maybe encode the character in *CHAR2B. */
17203 if (charset
!= CHARSET_ASCII
)
17205 struct font_info
*font_info
17206 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
17209 = rif
->encode_char (glyph
->u
.ch
, char2b
, font_info
, two_byte_p
);
17213 /* Make sure X resources of the face are allocated. */
17214 xassert (face
!= NULL
);
17215 PREPARE_FACE_FOR_DISPLAY (f
, face
);
17220 /* Fill glyph string S with composition components specified by S->cmp.
17222 FACES is an array of faces for all components of this composition.
17223 S->gidx is the index of the first component for S.
17224 OVERLAPS_P non-zero means S should draw the foreground only, and
17225 use its physical height for clipping.
17227 Value is the index of a component not in S. */
17230 fill_composite_glyph_string (s
, faces
, overlaps_p
)
17231 struct glyph_string
*s
;
17232 struct face
**faces
;
17239 s
->for_overlaps_p
= overlaps_p
;
17241 s
->face
= faces
[s
->gidx
];
17242 s
->font
= s
->face
->font
;
17243 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
17245 /* For all glyphs of this composition, starting at the offset
17246 S->gidx, until we reach the end of the definition or encounter a
17247 glyph that requires the different face, add it to S. */
17249 for (i
= s
->gidx
+ 1; i
< s
->cmp
->glyph_len
&& faces
[i
] == s
->face
; ++i
)
17252 /* All glyph strings for the same composition has the same width,
17253 i.e. the width set for the first component of the composition. */
17255 s
->width
= s
->first_glyph
->pixel_width
;
17257 /* If the specified font could not be loaded, use the frame's
17258 default font, but record the fact that we couldn't load it in
17259 the glyph string so that we can draw rectangles for the
17260 characters of the glyph string. */
17261 if (s
->font
== NULL
)
17263 s
->font_not_found_p
= 1;
17264 s
->font
= FRAME_FONT (s
->f
);
17267 /* Adjust base line for subscript/superscript text. */
17268 s
->ybase
+= s
->first_glyph
->voffset
;
17270 xassert (s
->face
&& s
->face
->gc
);
17272 /* This glyph string must always be drawn with 16-bit functions. */
17275 return s
->gidx
+ s
->nchars
;
17279 /* Fill glyph string S from a sequence of character glyphs.
17281 FACE_ID is the face id of the string. START is the index of the
17282 first glyph to consider, END is the index of the last + 1.
17283 OVERLAPS_P non-zero means S should draw the foreground only, and
17284 use its physical height for clipping.
17286 Value is the index of the first glyph not in S. */
17289 fill_glyph_string (s
, face_id
, start
, end
, overlaps_p
)
17290 struct glyph_string
*s
;
17292 int start
, end
, overlaps_p
;
17294 struct glyph
*glyph
, *last
;
17296 int glyph_not_available_p
;
17298 xassert (s
->f
== XFRAME (s
->w
->frame
));
17299 xassert (s
->nchars
== 0);
17300 xassert (start
>= 0 && end
> start
);
17302 s
->for_overlaps_p
= overlaps_p
,
17303 glyph
= s
->row
->glyphs
[s
->area
] + start
;
17304 last
= s
->row
->glyphs
[s
->area
] + end
;
17305 voffset
= glyph
->voffset
;
17307 glyph_not_available_p
= glyph
->glyph_not_available_p
;
17309 while (glyph
< last
17310 && glyph
->type
== CHAR_GLYPH
17311 && glyph
->voffset
== voffset
17312 /* Same face id implies same font, nowadays. */
17313 && glyph
->face_id
== face_id
17314 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
17318 s
->face
= get_glyph_face_and_encoding (s
->f
, glyph
,
17319 s
->char2b
+ s
->nchars
,
17321 s
->two_byte_p
= two_byte_p
;
17323 xassert (s
->nchars
<= end
- start
);
17324 s
->width
+= glyph
->pixel_width
;
17328 s
->font
= s
->face
->font
;
17329 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
17331 /* If the specified font could not be loaded, use the frame's font,
17332 but record the fact that we couldn't load it in
17333 S->font_not_found_p so that we can draw rectangles for the
17334 characters of the glyph string. */
17335 if (s
->font
== NULL
|| glyph_not_available_p
)
17337 s
->font_not_found_p
= 1;
17338 s
->font
= FRAME_FONT (s
->f
);
17341 /* Adjust base line for subscript/superscript text. */
17342 s
->ybase
+= voffset
;
17344 xassert (s
->face
&& s
->face
->gc
);
17345 return glyph
- s
->row
->glyphs
[s
->area
];
17349 /* Fill glyph string S from image glyph S->first_glyph. */
17352 fill_image_glyph_string (s
)
17353 struct glyph_string
*s
;
17355 xassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
17356 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
17358 s
->slice
= s
->first_glyph
->slice
;
17359 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
17360 s
->font
= s
->face
->font
;
17361 s
->width
= s
->first_glyph
->pixel_width
;
17363 /* Adjust base line for subscript/superscript text. */
17364 s
->ybase
+= s
->first_glyph
->voffset
;
17368 /* Fill glyph string S from a sequence of stretch glyphs.
17370 ROW is the glyph row in which the glyphs are found, AREA is the
17371 area within the row. START is the index of the first glyph to
17372 consider, END is the index of the last + 1.
17374 Value is the index of the first glyph not in S. */
17377 fill_stretch_glyph_string (s
, row
, area
, start
, end
)
17378 struct glyph_string
*s
;
17379 struct glyph_row
*row
;
17380 enum glyph_row_area area
;
17383 struct glyph
*glyph
, *last
;
17384 int voffset
, face_id
;
17386 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
17388 glyph
= s
->row
->glyphs
[s
->area
] + start
;
17389 last
= s
->row
->glyphs
[s
->area
] + end
;
17390 face_id
= glyph
->face_id
;
17391 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
17392 s
->font
= s
->face
->font
;
17393 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
17394 s
->width
= glyph
->pixel_width
;
17395 voffset
= glyph
->voffset
;
17399 && glyph
->type
== STRETCH_GLYPH
17400 && glyph
->voffset
== voffset
17401 && glyph
->face_id
== face_id
);
17403 s
->width
+= glyph
->pixel_width
;
17405 /* Adjust base line for subscript/superscript text. */
17406 s
->ybase
+= voffset
;
17408 /* The case that face->gc == 0 is handled when drawing the glyph
17409 string by calling PREPARE_FACE_FOR_DISPLAY. */
17411 return glyph
- s
->row
->glyphs
[s
->area
];
17416 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
17417 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
17418 assumed to be zero. */
17421 x_get_glyph_overhangs (glyph
, f
, left
, right
)
17422 struct glyph
*glyph
;
17426 *left
= *right
= 0;
17428 if (glyph
->type
== CHAR_GLYPH
)
17432 struct font_info
*font_info
;
17436 face
= get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
17438 font_info
= FONT_INFO_FROM_ID (f
, face
->font_info_id
);
17439 if (font
/* ++KFS: Should this be font_info ? */
17440 && (pcm
= rif
->per_char_metric (font
, &char2b
, glyph
->font_type
)))
17442 if (pcm
->rbearing
> pcm
->width
)
17443 *right
= pcm
->rbearing
- pcm
->width
;
17444 if (pcm
->lbearing
< 0)
17445 *left
= -pcm
->lbearing
;
17451 /* Return the index of the first glyph preceding glyph string S that
17452 is overwritten by S because of S's left overhang. Value is -1
17453 if no glyphs are overwritten. */
17456 left_overwritten (s
)
17457 struct glyph_string
*s
;
17461 if (s
->left_overhang
)
17464 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
17465 int first
= s
->first_glyph
- glyphs
;
17467 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
17468 x
-= glyphs
[i
].pixel_width
;
17479 /* Return the index of the first glyph preceding glyph string S that
17480 is overwriting S because of its right overhang. Value is -1 if no
17481 glyph in front of S overwrites S. */
17484 left_overwriting (s
)
17485 struct glyph_string
*s
;
17488 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
17489 int first
= s
->first_glyph
- glyphs
;
17493 for (i
= first
- 1; i
>= 0; --i
)
17496 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
17499 x
-= glyphs
[i
].pixel_width
;
17506 /* Return the index of the last glyph following glyph string S that is
17507 not overwritten by S because of S's right overhang. Value is -1 if
17508 no such glyph is found. */
17511 right_overwritten (s
)
17512 struct glyph_string
*s
;
17516 if (s
->right_overhang
)
17519 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
17520 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
17521 int end
= s
->row
->used
[s
->area
];
17523 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
17524 x
+= glyphs
[i
].pixel_width
;
17533 /* Return the index of the last glyph following glyph string S that
17534 overwrites S because of its left overhang. Value is negative
17535 if no such glyph is found. */
17538 right_overwriting (s
)
17539 struct glyph_string
*s
;
17542 int end
= s
->row
->used
[s
->area
];
17543 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
17544 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
17548 for (i
= first
; i
< end
; ++i
)
17551 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
17554 x
+= glyphs
[i
].pixel_width
;
17561 /* Get face and two-byte form of character C in face FACE_ID on frame
17562 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
17563 means we want to display multibyte text. DISPLAY_P non-zero means
17564 make sure that X resources for the face returned are allocated.
17565 Value is a pointer to a realized face that is ready for display if
17566 DISPLAY_P is non-zero. */
17568 static INLINE
struct face
*
17569 get_char_face_and_encoding (f
, c
, face_id
, char2b
, multibyte_p
, display_p
)
17573 int multibyte_p
, display_p
;
17575 struct face
*face
= FACE_FROM_ID (f
, face_id
);
17579 /* Unibyte case. We don't have to encode, but we have to make
17580 sure to use a face suitable for unibyte. */
17581 STORE_XCHAR2B (char2b
, 0, c
);
17582 face_id
= FACE_FOR_CHAR (f
, face
, c
);
17583 face
= FACE_FROM_ID (f
, face_id
);
17585 else if (c
< 128 && face_id
< BASIC_FACE_ID_SENTINEL
)
17587 /* Case of ASCII in a face known to fit ASCII. */
17588 STORE_XCHAR2B (char2b
, 0, c
);
17592 int c1
, c2
, charset
;
17594 /* Split characters into bytes. If c2 is -1 afterwards, C is
17595 really a one-byte character so that byte1 is zero. */
17596 SPLIT_CHAR (c
, charset
, c1
, c2
);
17598 STORE_XCHAR2B (char2b
, c1
, c2
);
17600 STORE_XCHAR2B (char2b
, 0, c1
);
17602 /* Maybe encode the character in *CHAR2B. */
17603 if (face
->font
!= NULL
)
17605 struct font_info
*font_info
17606 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
17608 rif
->encode_char (c
, char2b
, font_info
, 0);
17612 /* Make sure X resources of the face are allocated. */
17613 #ifdef HAVE_X_WINDOWS
17617 xassert (face
!= NULL
);
17618 PREPARE_FACE_FOR_DISPLAY (f
, face
);
17625 /* Set background width of glyph string S. START is the index of the
17626 first glyph following S. LAST_X is the right-most x-position + 1
17627 in the drawing area. */
17630 set_glyph_string_background_width (s
, start
, last_x
)
17631 struct glyph_string
*s
;
17635 /* If the face of this glyph string has to be drawn to the end of
17636 the drawing area, set S->extends_to_end_of_line_p. */
17637 struct face
*default_face
= FACE_FROM_ID (s
->f
, DEFAULT_FACE_ID
);
17639 if (start
== s
->row
->used
[s
->area
]
17640 && s
->area
== TEXT_AREA
17641 && ((s
->hl
== DRAW_NORMAL_TEXT
17642 && (s
->row
->fill_line_p
17643 || s
->face
->background
!= default_face
->background
17644 || s
->face
->stipple
!= default_face
->stipple
17645 || s
->row
->mouse_face_p
))
17646 || s
->hl
== DRAW_MOUSE_FACE
17647 || ((s
->hl
== DRAW_IMAGE_RAISED
|| s
->hl
== DRAW_IMAGE_SUNKEN
)
17648 && s
->row
->fill_line_p
)))
17649 s
->extends_to_end_of_line_p
= 1;
17651 /* If S extends its face to the end of the line, set its
17652 background_width to the distance to the right edge of the drawing
17654 if (s
->extends_to_end_of_line_p
)
17655 s
->background_width
= last_x
- s
->x
+ 1;
17657 s
->background_width
= s
->width
;
17661 /* Compute overhangs and x-positions for glyph string S and its
17662 predecessors, or successors. X is the starting x-position for S.
17663 BACKWARD_P non-zero means process predecessors. */
17666 compute_overhangs_and_x (s
, x
, backward_p
)
17667 struct glyph_string
*s
;
17675 if (rif
->compute_glyph_string_overhangs
)
17676 rif
->compute_glyph_string_overhangs (s
);
17686 if (rif
->compute_glyph_string_overhangs
)
17687 rif
->compute_glyph_string_overhangs (s
);
17697 /* The following macros are only called from draw_glyphs below.
17698 They reference the following parameters of that function directly:
17699 `w', `row', `area', and `overlap_p'
17700 as well as the following local variables:
17701 `s', `f', and `hdc' (in W32) */
17704 /* On W32, silently add local `hdc' variable to argument list of
17705 init_glyph_string. */
17706 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17707 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
17709 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17710 init_glyph_string (s, char2b, w, row, area, start, hl)
17713 /* Add a glyph string for a stretch glyph to the list of strings
17714 between HEAD and TAIL. START is the index of the stretch glyph in
17715 row area AREA of glyph row ROW. END is the index of the last glyph
17716 in that glyph row area. X is the current output position assigned
17717 to the new glyph string constructed. HL overrides that face of the
17718 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17719 is the right-most x-position of the drawing area. */
17721 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
17722 and below -- keep them on one line. */
17723 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17726 s = (struct glyph_string *) alloca (sizeof *s); \
17727 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17728 START = fill_stretch_glyph_string (s, row, area, START, END); \
17729 append_glyph_string (&HEAD, &TAIL, s); \
17735 /* Add a glyph string for an image glyph to the list of strings
17736 between HEAD and TAIL. START is the index of the image glyph in
17737 row area AREA of glyph row ROW. END is the index of the last glyph
17738 in that glyph row area. X is the current output position assigned
17739 to the new glyph string constructed. HL overrides that face of the
17740 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17741 is the right-most x-position of the drawing area. */
17743 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17746 s = (struct glyph_string *) alloca (sizeof *s); \
17747 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17748 fill_image_glyph_string (s); \
17749 append_glyph_string (&HEAD, &TAIL, s); \
17756 /* Add a glyph string for a sequence of character glyphs to the list
17757 of strings between HEAD and TAIL. START is the index of the first
17758 glyph in row area AREA of glyph row ROW that is part of the new
17759 glyph string. END is the index of the last glyph in that glyph row
17760 area. X is the current output position assigned to the new glyph
17761 string constructed. HL overrides that face of the glyph; e.g. it
17762 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
17763 right-most x-position of the drawing area. */
17765 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17771 c = (row)->glyphs[area][START].u.ch; \
17772 face_id = (row)->glyphs[area][START].face_id; \
17774 s = (struct glyph_string *) alloca (sizeof *s); \
17775 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
17776 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
17777 append_glyph_string (&HEAD, &TAIL, s); \
17779 START = fill_glyph_string (s, face_id, START, END, overlaps_p); \
17784 /* Add a glyph string for a composite sequence to the list of strings
17785 between HEAD and TAIL. START is the index of the first glyph in
17786 row area AREA of glyph row ROW that is part of the new glyph
17787 string. END is the index of the last glyph in that glyph row area.
17788 X is the current output position assigned to the new glyph string
17789 constructed. HL overrides that face of the glyph; e.g. it is
17790 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
17791 x-position of the drawing area. */
17793 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17795 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
17796 int face_id = (row)->glyphs[area][START].face_id; \
17797 struct face *base_face = FACE_FROM_ID (f, face_id); \
17798 struct composition *cmp = composition_table[cmp_id]; \
17799 int glyph_len = cmp->glyph_len; \
17801 struct face **faces; \
17802 struct glyph_string *first_s = NULL; \
17805 base_face = base_face->ascii_face; \
17806 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
17807 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
17808 /* At first, fill in `char2b' and `faces'. */ \
17809 for (n = 0; n < glyph_len; n++) \
17811 int c = COMPOSITION_GLYPH (cmp, n); \
17812 int this_face_id = FACE_FOR_CHAR (f, base_face, c); \
17813 faces[n] = FACE_FROM_ID (f, this_face_id); \
17814 get_char_face_and_encoding (f, c, this_face_id, \
17815 char2b + n, 1, 1); \
17818 /* Make glyph_strings for each glyph sequence that is drawable by \
17819 the same face, and append them to HEAD/TAIL. */ \
17820 for (n = 0; n < cmp->glyph_len;) \
17822 s = (struct glyph_string *) alloca (sizeof *s); \
17823 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \
17824 append_glyph_string (&(HEAD), &(TAIL), s); \
17832 n = fill_composite_glyph_string (s, faces, overlaps_p); \
17840 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
17841 of AREA of glyph row ROW on window W between indices START and END.
17842 HL overrides the face for drawing glyph strings, e.g. it is
17843 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
17844 x-positions of the drawing area.
17846 This is an ugly monster macro construct because we must use alloca
17847 to allocate glyph strings (because draw_glyphs can be called
17848 asynchronously). */
17850 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17853 HEAD = TAIL = NULL; \
17854 while (START < END) \
17856 struct glyph *first_glyph = (row)->glyphs[area] + START; \
17857 switch (first_glyph->type) \
17860 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
17864 case COMPOSITE_GLYPH: \
17865 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
17869 case STRETCH_GLYPH: \
17870 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
17874 case IMAGE_GLYPH: \
17875 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
17883 set_glyph_string_background_width (s, START, LAST_X); \
17890 /* Draw glyphs between START and END in AREA of ROW on window W,
17891 starting at x-position X. X is relative to AREA in W. HL is a
17892 face-override with the following meaning:
17894 DRAW_NORMAL_TEXT draw normally
17895 DRAW_CURSOR draw in cursor face
17896 DRAW_MOUSE_FACE draw in mouse face.
17897 DRAW_INVERSE_VIDEO draw in mode line face
17898 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
17899 DRAW_IMAGE_RAISED draw an image with a raised relief around it
17901 If OVERLAPS_P is non-zero, draw only the foreground of characters
17902 and clip to the physical height of ROW.
17904 Value is the x-position reached, relative to AREA of W. */
17907 draw_glyphs (w
, x
, row
, area
, start
, end
, hl
, overlaps_p
)
17910 struct glyph_row
*row
;
17911 enum glyph_row_area area
;
17913 enum draw_glyphs_face hl
;
17916 struct glyph_string
*head
, *tail
;
17917 struct glyph_string
*s
;
17918 int last_x
, area_width
;
17921 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
17924 ALLOCATE_HDC (hdc
, f
);
17926 /* Let's rather be paranoid than getting a SEGV. */
17927 end
= min (end
, row
->used
[area
]);
17928 start
= max (0, start
);
17929 start
= min (end
, start
);
17931 /* Translate X to frame coordinates. Set last_x to the right
17932 end of the drawing area. */
17933 if (row
->full_width_p
)
17935 /* X is relative to the left edge of W, without scroll bars
17937 x
+= WINDOW_LEFT_EDGE_X (w
);
17938 last_x
= WINDOW_LEFT_EDGE_X (w
) + WINDOW_TOTAL_WIDTH (w
);
17942 int area_left
= window_box_left (w
, area
);
17944 area_width
= window_box_width (w
, area
);
17945 last_x
= area_left
+ area_width
;
17948 /* Build a doubly-linked list of glyph_string structures between
17949 head and tail from what we have to draw. Note that the macro
17950 BUILD_GLYPH_STRINGS will modify its start parameter. That's
17951 the reason we use a separate variable `i'. */
17953 BUILD_GLYPH_STRINGS (i
, end
, head
, tail
, hl
, x
, last_x
);
17955 x_reached
= tail
->x
+ tail
->background_width
;
17959 /* If there are any glyphs with lbearing < 0 or rbearing > width in
17960 the row, redraw some glyphs in front or following the glyph
17961 strings built above. */
17962 if (head
&& !overlaps_p
&& row
->contains_overlapping_glyphs_p
)
17965 struct glyph_string
*h
, *t
;
17967 /* Compute overhangs for all glyph strings. */
17968 if (rif
->compute_glyph_string_overhangs
)
17969 for (s
= head
; s
; s
= s
->next
)
17970 rif
->compute_glyph_string_overhangs (s
);
17972 /* Prepend glyph strings for glyphs in front of the first glyph
17973 string that are overwritten because of the first glyph
17974 string's left overhang. The background of all strings
17975 prepended must be drawn because the first glyph string
17977 i
= left_overwritten (head
);
17981 BUILD_GLYPH_STRINGS (j
, start
, h
, t
,
17982 DRAW_NORMAL_TEXT
, dummy_x
, last_x
);
17984 compute_overhangs_and_x (t
, head
->x
, 1);
17985 prepend_glyph_string_lists (&head
, &tail
, h
, t
);
17988 /* Prepend glyph strings for glyphs in front of the first glyph
17989 string that overwrite that glyph string because of their
17990 right overhang. For these strings, only the foreground must
17991 be drawn, because it draws over the glyph string at `head'.
17992 The background must not be drawn because this would overwrite
17993 right overhangs of preceding glyphs for which no glyph
17995 i
= left_overwriting (head
);
17998 BUILD_GLYPH_STRINGS (i
, start
, h
, t
,
17999 DRAW_NORMAL_TEXT
, dummy_x
, last_x
);
18000 for (s
= h
; s
; s
= s
->next
)
18001 s
->background_filled_p
= 1;
18002 compute_overhangs_and_x (t
, head
->x
, 1);
18003 prepend_glyph_string_lists (&head
, &tail
, h
, t
);
18006 /* Append glyphs strings for glyphs following the last glyph
18007 string tail that are overwritten by tail. The background of
18008 these strings has to be drawn because tail's foreground draws
18010 i
= right_overwritten (tail
);
18013 BUILD_GLYPH_STRINGS (end
, i
, h
, t
,
18014 DRAW_NORMAL_TEXT
, x
, last_x
);
18015 compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
18016 append_glyph_string_lists (&head
, &tail
, h
, t
);
18019 /* Append glyph strings for glyphs following the last glyph
18020 string tail that overwrite tail. The foreground of such
18021 glyphs has to be drawn because it writes into the background
18022 of tail. The background must not be drawn because it could
18023 paint over the foreground of following glyphs. */
18024 i
= right_overwriting (tail
);
18027 BUILD_GLYPH_STRINGS (end
, i
, h
, t
,
18028 DRAW_NORMAL_TEXT
, x
, last_x
);
18029 for (s
= h
; s
; s
= s
->next
)
18030 s
->background_filled_p
= 1;
18031 compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
18032 append_glyph_string_lists (&head
, &tail
, h
, t
);
18036 /* Draw all strings. */
18037 for (s
= head
; s
; s
= s
->next
)
18038 rif
->draw_glyph_string (s
);
18040 if (area
== TEXT_AREA
18041 && !row
->full_width_p
18042 /* When drawing overlapping rows, only the glyph strings'
18043 foreground is drawn, which doesn't erase a cursor
18047 int x0
= head
? head
->x
: x
;
18048 int x1
= tail
? tail
->x
+ tail
->background_width
: x
;
18050 int text_left
= window_box_left (w
, TEXT_AREA
);
18054 notice_overwritten_cursor (w
, TEXT_AREA
, x0
, x1
,
18055 row
->y
, MATRIX_ROW_BOTTOM_Y (row
));
18058 /* Value is the x-position up to which drawn, relative to AREA of W.
18059 This doesn't include parts drawn because of overhangs. */
18060 if (row
->full_width_p
)
18061 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
18063 x_reached
-= window_box_left (w
, area
);
18065 RELEASE_HDC (hdc
, f
);
18071 /* Store one glyph for IT->char_to_display in IT->glyph_row.
18072 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18078 struct glyph
*glyph
;
18079 enum glyph_row_area area
= it
->area
;
18081 xassert (it
->glyph_row
);
18082 xassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
18084 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
18085 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
18087 glyph
->charpos
= CHARPOS (it
->position
);
18088 glyph
->object
= it
->object
;
18089 glyph
->pixel_width
= it
->pixel_width
;
18090 glyph
->ascent
= it
->ascent
;
18091 glyph
->descent
= it
->descent
;
18092 glyph
->voffset
= it
->voffset
;
18093 glyph
->type
= CHAR_GLYPH
;
18094 glyph
->multibyte_p
= it
->multibyte_p
;
18095 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
18096 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
18097 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
18098 || it
->phys_descent
> it
->descent
);
18099 glyph
->padding_p
= 0;
18100 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
18101 glyph
->face_id
= it
->face_id
;
18102 glyph
->u
.ch
= it
->char_to_display
;
18103 glyph
->slice
= null_glyph_slice
;
18104 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
18105 ++it
->glyph_row
->used
[area
];
18109 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
18110 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18113 append_composite_glyph (it
)
18116 struct glyph
*glyph
;
18117 enum glyph_row_area area
= it
->area
;
18119 xassert (it
->glyph_row
);
18121 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
18122 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
18124 glyph
->charpos
= CHARPOS (it
->position
);
18125 glyph
->object
= it
->object
;
18126 glyph
->pixel_width
= it
->pixel_width
;
18127 glyph
->ascent
= it
->ascent
;
18128 glyph
->descent
= it
->descent
;
18129 glyph
->voffset
= it
->voffset
;
18130 glyph
->type
= COMPOSITE_GLYPH
;
18131 glyph
->multibyte_p
= it
->multibyte_p
;
18132 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
18133 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
18134 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
18135 || it
->phys_descent
> it
->descent
);
18136 glyph
->padding_p
= 0;
18137 glyph
->glyph_not_available_p
= 0;
18138 glyph
->face_id
= it
->face_id
;
18139 glyph
->u
.cmp_id
= it
->cmp_id
;
18140 glyph
->slice
= null_glyph_slice
;
18141 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
18142 ++it
->glyph_row
->used
[area
];
18147 /* Change IT->ascent and IT->height according to the setting of
18151 take_vertical_position_into_account (it
)
18156 if (it
->voffset
< 0)
18157 /* Increase the ascent so that we can display the text higher
18159 it
->ascent
-= it
->voffset
;
18161 /* Increase the descent so that we can display the text lower
18163 it
->descent
+= it
->voffset
;
18168 /* Produce glyphs/get display metrics for the image IT is loaded with.
18169 See the description of struct display_iterator in dispextern.h for
18170 an overview of struct display_iterator. */
18173 produce_image_glyph (it
)
18178 int face_ascent
, glyph_ascent
;
18179 struct glyph_slice slice
;
18181 xassert (it
->what
== IT_IMAGE
);
18183 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
18185 /* Make sure X resources of the face is loaded. */
18186 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
18188 if (it
->image_id
< 0)
18190 /* Fringe bitmap. */
18191 it
->ascent
= it
->phys_ascent
= 0;
18192 it
->descent
= it
->phys_descent
= 0;
18193 it
->pixel_width
= 0;
18198 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
18200 /* Make sure X resources of the image is loaded. */
18201 prepare_image_for_display (it
->f
, img
);
18203 slice
.x
= slice
.y
= 0;
18204 slice
.width
= img
->width
;
18205 slice
.height
= img
->height
;
18207 if (INTEGERP (it
->slice
.x
))
18208 slice
.x
= XINT (it
->slice
.x
);
18209 else if (FLOATP (it
->slice
.x
))
18210 slice
.x
= XFLOAT_DATA (it
->slice
.x
) * img
->width
;
18212 if (INTEGERP (it
->slice
.y
))
18213 slice
.y
= XINT (it
->slice
.y
);
18214 else if (FLOATP (it
->slice
.y
))
18215 slice
.y
= XFLOAT_DATA (it
->slice
.y
) * img
->height
;
18217 if (INTEGERP (it
->slice
.width
))
18218 slice
.width
= XINT (it
->slice
.width
);
18219 else if (FLOATP (it
->slice
.width
))
18220 slice
.width
= XFLOAT_DATA (it
->slice
.width
) * img
->width
;
18222 if (INTEGERP (it
->slice
.height
))
18223 slice
.height
= XINT (it
->slice
.height
);
18224 else if (FLOATP (it
->slice
.height
))
18225 slice
.height
= XFLOAT_DATA (it
->slice
.height
) * img
->height
;
18227 if (slice
.x
>= img
->width
)
18228 slice
.x
= img
->width
;
18229 if (slice
.y
>= img
->height
)
18230 slice
.y
= img
->height
;
18231 if (slice
.x
+ slice
.width
>= img
->width
)
18232 slice
.width
= img
->width
- slice
.x
;
18233 if (slice
.y
+ slice
.height
> img
->height
)
18234 slice
.height
= img
->height
- slice
.y
;
18236 if (slice
.width
== 0 || slice
.height
== 0)
18239 it
->ascent
= it
->phys_ascent
= glyph_ascent
= image_ascent (img
, face
, &slice
);
18241 it
->descent
= slice
.height
- glyph_ascent
;
18243 it
->descent
+= img
->vmargin
;
18244 if (slice
.y
+ slice
.height
== img
->height
)
18245 it
->descent
+= img
->vmargin
;
18246 it
->phys_descent
= it
->descent
;
18248 it
->pixel_width
= slice
.width
;
18250 it
->pixel_width
+= img
->hmargin
;
18251 if (slice
.x
+ slice
.width
== img
->width
)
18252 it
->pixel_width
+= img
->hmargin
;
18254 /* It's quite possible for images to have an ascent greater than
18255 their height, so don't get confused in that case. */
18256 if (it
->descent
< 0)
18259 #if 0 /* this breaks image tiling */
18260 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
18261 face_ascent
= face
->font
? FONT_BASE (face
->font
) : FRAME_BASELINE_OFFSET (it
->f
);
18262 if (face_ascent
> it
->ascent
)
18263 it
->ascent
= it
->phys_ascent
= face_ascent
;
18268 if (face
->box
!= FACE_NO_BOX
)
18270 if (face
->box_line_width
> 0)
18273 it
->ascent
+= face
->box_line_width
;
18274 if (slice
.y
+ slice
.height
== img
->height
)
18275 it
->descent
+= face
->box_line_width
;
18278 if (it
->start_of_box_run_p
&& slice
.x
== 0)
18279 it
->pixel_width
+= abs (face
->box_line_width
);
18280 if (it
->end_of_box_run_p
&& slice
.x
+ slice
.width
== img
->width
)
18281 it
->pixel_width
+= abs (face
->box_line_width
);
18284 take_vertical_position_into_account (it
);
18288 struct glyph
*glyph
;
18289 enum glyph_row_area area
= it
->area
;
18291 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
18292 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
18294 glyph
->charpos
= CHARPOS (it
->position
);
18295 glyph
->object
= it
->object
;
18296 glyph
->pixel_width
= it
->pixel_width
;
18297 glyph
->ascent
= glyph_ascent
;
18298 glyph
->descent
= it
->descent
;
18299 glyph
->voffset
= it
->voffset
;
18300 glyph
->type
= IMAGE_GLYPH
;
18301 glyph
->multibyte_p
= it
->multibyte_p
;
18302 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
18303 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
18304 glyph
->overlaps_vertically_p
= 0;
18305 glyph
->padding_p
= 0;
18306 glyph
->glyph_not_available_p
= 0;
18307 glyph
->face_id
= it
->face_id
;
18308 glyph
->u
.img_id
= img
->id
;
18309 glyph
->slice
= slice
;
18310 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
18311 ++it
->glyph_row
->used
[area
];
18317 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
18318 of the glyph, WIDTH and HEIGHT are the width and height of the
18319 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
18322 append_stretch_glyph (it
, object
, width
, height
, ascent
)
18324 Lisp_Object object
;
18328 struct glyph
*glyph
;
18329 enum glyph_row_area area
= it
->area
;
18331 xassert (ascent
>= 0 && ascent
<= height
);
18333 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
18334 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
18336 glyph
->charpos
= CHARPOS (it
->position
);
18337 glyph
->object
= object
;
18338 glyph
->pixel_width
= width
;
18339 glyph
->ascent
= ascent
;
18340 glyph
->descent
= height
- ascent
;
18341 glyph
->voffset
= it
->voffset
;
18342 glyph
->type
= STRETCH_GLYPH
;
18343 glyph
->multibyte_p
= it
->multibyte_p
;
18344 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
18345 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
18346 glyph
->overlaps_vertically_p
= 0;
18347 glyph
->padding_p
= 0;
18348 glyph
->glyph_not_available_p
= 0;
18349 glyph
->face_id
= it
->face_id
;
18350 glyph
->u
.stretch
.ascent
= ascent
;
18351 glyph
->u
.stretch
.height
= height
;
18352 glyph
->slice
= null_glyph_slice
;
18353 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
18354 ++it
->glyph_row
->used
[area
];
18359 /* Produce a stretch glyph for iterator IT. IT->object is the value
18360 of the glyph property displayed. The value must be a list
18361 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
18364 1. `:width WIDTH' specifies that the space should be WIDTH *
18365 canonical char width wide. WIDTH may be an integer or floating
18368 2. `:relative-width FACTOR' specifies that the width of the stretch
18369 should be computed from the width of the first character having the
18370 `glyph' property, and should be FACTOR times that width.
18372 3. `:align-to HPOS' specifies that the space should be wide enough
18373 to reach HPOS, a value in canonical character units.
18375 Exactly one of the above pairs must be present.
18377 4. `:height HEIGHT' specifies that the height of the stretch produced
18378 should be HEIGHT, measured in canonical character units.
18380 5. `:relative-height FACTOR' specifies that the height of the
18381 stretch should be FACTOR times the height of the characters having
18382 the glyph property.
18384 Either none or exactly one of 4 or 5 must be present.
18386 6. `:ascent ASCENT' specifies that ASCENT percent of the height
18387 of the stretch should be used for the ascent of the stretch.
18388 ASCENT must be in the range 0 <= ASCENT <= 100. */
18391 produce_stretch_glyph (it
)
18394 /* (space :width WIDTH :height HEIGHT ...) */
18395 Lisp_Object prop
, plist
;
18396 int width
= 0, height
= 0, align_to
= -1;
18397 int zero_width_ok_p
= 0, zero_height_ok_p
= 0;
18400 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
18401 XFontStruct
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
18403 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
18405 /* List should start with `space'. */
18406 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
18407 plist
= XCDR (it
->object
);
18409 /* Compute the width of the stretch. */
18410 if ((prop
= Fplist_get (plist
, QCwidth
), !NILP (prop
))
18411 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 1, 0))
18413 /* Absolute width `:width WIDTH' specified and valid. */
18414 zero_width_ok_p
= 1;
18417 else if (prop
= Fplist_get (plist
, QCrelative_width
),
18420 /* Relative width `:relative-width FACTOR' specified and valid.
18421 Compute the width of the characters having the `glyph'
18424 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
18427 if (it
->multibyte_p
)
18429 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT
? ZV
: GPT
)
18430 - IT_BYTEPOS (*it
));
18431 it2
.c
= STRING_CHAR_AND_LENGTH (p
, maxlen
, it2
.len
);
18434 it2
.c
= *p
, it2
.len
= 1;
18436 it2
.glyph_row
= NULL
;
18437 it2
.what
= IT_CHARACTER
;
18438 x_produce_glyphs (&it2
);
18439 width
= NUMVAL (prop
) * it2
.pixel_width
;
18441 else if ((prop
= Fplist_get (plist
, QCalign_to
), !NILP (prop
))
18442 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 1, &align_to
))
18444 if (it
->glyph_row
== NULL
|| !it
->glyph_row
->mode_line_p
)
18445 align_to
= (align_to
< 0
18447 : align_to
- window_box_left_offset (it
->w
, TEXT_AREA
));
18448 else if (align_to
< 0)
18449 align_to
= window_box_left_offset (it
->w
, TEXT_AREA
);
18450 width
= max (0, (int)tem
+ align_to
- it
->current_x
);
18451 zero_width_ok_p
= 1;
18454 /* Nothing specified -> width defaults to canonical char width. */
18455 width
= FRAME_COLUMN_WIDTH (it
->f
);
18457 if (width
<= 0 && (width
< 0 || !zero_width_ok_p
))
18460 /* Compute height. */
18461 if ((prop
= Fplist_get (plist
, QCheight
), !NILP (prop
))
18462 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 0, 0))
18465 zero_height_ok_p
= 1;
18467 else if (prop
= Fplist_get (plist
, QCrelative_height
),
18469 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
18471 height
= FONT_HEIGHT (font
);
18473 if (height
<= 0 && (height
< 0 || !zero_height_ok_p
))
18476 /* Compute percentage of height used for ascent. If
18477 `:ascent ASCENT' is present and valid, use that. Otherwise,
18478 derive the ascent from the font in use. */
18479 if (prop
= Fplist_get (plist
, QCascent
),
18480 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
18481 ascent
= height
* NUMVAL (prop
) / 100.0;
18482 else if (!NILP (prop
)
18483 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 0, 0))
18484 ascent
= min (max (0, (int)tem
), height
);
18486 ascent
= (height
* FONT_BASE (font
)) / FONT_HEIGHT (font
);
18488 if (width
> 0 && height
> 0 && it
->glyph_row
)
18490 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
18491 if (!STRINGP (object
))
18492 object
= it
->w
->buffer
;
18493 append_stretch_glyph (it
, object
, width
, height
, ascent
);
18496 it
->pixel_width
= width
;
18497 it
->ascent
= it
->phys_ascent
= ascent
;
18498 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
18499 it
->nglyphs
= width
> 0 && height
> 0 ? 1 : 0;
18501 if (width
> 0 && height
> 0 && face
->box
!= FACE_NO_BOX
)
18503 if (face
->box_line_width
> 0)
18505 it
->ascent
+= face
->box_line_width
;
18506 it
->descent
+= face
->box_line_width
;
18509 if (it
->start_of_box_run_p
)
18510 it
->pixel_width
+= abs (face
->box_line_width
);
18511 if (it
->end_of_box_run_p
)
18512 it
->pixel_width
+= abs (face
->box_line_width
);
18515 take_vertical_position_into_account (it
);
18518 /* Calculate line-height and line-spacing properties.
18519 An integer value specifies explicit pixel value.
18520 A float value specifies relative value to current face height.
18521 A cons (float . face-name) specifies relative value to
18522 height of specified face font.
18524 Returns height in pixels, or nil. */
18527 calc_line_height_property (it
, prop
, font
, boff
, total
)
18533 Lisp_Object position
, val
;
18534 Lisp_Object face_name
= Qnil
;
18535 int ascent
, descent
, height
, override
;
18537 if (STRINGP (it
->object
))
18538 position
= make_number (IT_STRING_CHARPOS (*it
));
18540 position
= make_number (IT_CHARPOS (*it
));
18542 val
= Fget_char_property (position
, prop
, it
->object
);
18547 if (total
&& CONSP (val
) && EQ (XCAR (val
), Qtotal
))
18553 if (INTEGERP (val
))
18558 face_name
= XCDR (val
);
18561 else if (SYMBOLP (val
))
18567 override
= EQ (prop
, Qline_height
);
18569 if (NILP (face_name
))
18571 font
= FRAME_FONT (it
->f
);
18572 boff
= FRAME_BASELINE_OFFSET (it
->f
);
18574 else if (EQ (face_name
, Qt
))
18582 struct font_info
*font_info
;
18584 face_id
= lookup_named_face (it
->f
, face_name
, ' ');
18586 return make_number (-1);
18588 face
= FACE_FROM_ID (it
->f
, face_id
);
18591 return make_number (-1);
18593 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
18594 boff
= font_info
->baseline_offset
;
18595 if (font_info
->vertical_centering
)
18596 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
18599 ascent
= FONT_BASE (font
) + boff
;
18600 descent
= FONT_DESCENT (font
) - boff
;
18604 it
->override_ascent
= ascent
;
18605 it
->override_descent
= descent
;
18606 it
->override_boff
= boff
;
18609 height
= ascent
+ descent
;
18611 height
= (int)(XFLOAT_DATA (val
) * height
);
18612 else if (INTEGERP (val
))
18613 height
*= XINT (val
);
18615 return make_number (height
);
18620 Produce glyphs/get display metrics for the display element IT is
18621 loaded with. See the description of struct display_iterator in
18622 dispextern.h for an overview of struct display_iterator. */
18625 x_produce_glyphs (it
)
18628 int extra_line_spacing
= it
->extra_line_spacing
;
18630 it
->glyph_not_available_p
= 0;
18632 if (it
->what
== IT_CHARACTER
)
18636 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
18638 int font_not_found_p
;
18639 struct font_info
*font_info
;
18640 int boff
; /* baseline offset */
18641 /* We may change it->multibyte_p upon unibyte<->multibyte
18642 conversion. So, save the current value now and restore it
18645 Note: It seems that we don't have to record multibyte_p in
18646 struct glyph because the character code itself tells if or
18647 not the character is multibyte. Thus, in the future, we must
18648 consider eliminating the field `multibyte_p' in the struct
18650 int saved_multibyte_p
= it
->multibyte_p
;
18652 /* Maybe translate single-byte characters to multibyte, or the
18654 it
->char_to_display
= it
->c
;
18655 if (!ASCII_BYTE_P (it
->c
))
18657 if (unibyte_display_via_language_environment
18658 && SINGLE_BYTE_CHAR_P (it
->c
)
18660 || !NILP (Vnonascii_translation_table
)))
18662 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
18663 it
->multibyte_p
= 1;
18664 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
18665 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
18667 else if (!SINGLE_BYTE_CHAR_P (it
->c
)
18668 && !it
->multibyte_p
)
18670 it
->multibyte_p
= 1;
18671 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
18672 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
18676 /* Get font to use. Encode IT->char_to_display. */
18677 get_char_face_and_encoding (it
->f
, it
->char_to_display
, it
->face_id
,
18678 &char2b
, it
->multibyte_p
, 0);
18681 /* When no suitable font found, use the default font. */
18682 font_not_found_p
= font
== NULL
;
18683 if (font_not_found_p
)
18685 font
= FRAME_FONT (it
->f
);
18686 boff
= FRAME_BASELINE_OFFSET (it
->f
);
18691 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
18692 boff
= font_info
->baseline_offset
;
18693 if (font_info
->vertical_centering
)
18694 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
18697 if (it
->char_to_display
>= ' '
18698 && (!it
->multibyte_p
|| it
->char_to_display
< 128))
18700 /* Either unibyte or ASCII. */
18705 pcm
= rif
->per_char_metric (font
, &char2b
,
18706 FONT_TYPE_FOR_UNIBYTE (font
, it
->char_to_display
));
18708 if (it
->override_ascent
>= 0)
18710 it
->ascent
= it
->override_ascent
;
18711 it
->descent
= it
->override_descent
;
18712 boff
= it
->override_boff
;
18716 it
->ascent
= FONT_BASE (font
) + boff
;
18717 it
->descent
= FONT_DESCENT (font
) - boff
;
18722 it
->phys_ascent
= pcm
->ascent
+ boff
;
18723 it
->phys_descent
= pcm
->descent
- boff
;
18724 it
->pixel_width
= pcm
->width
;
18728 it
->glyph_not_available_p
= 1;
18729 it
->phys_ascent
= it
->ascent
;
18730 it
->phys_descent
= it
->descent
;
18731 it
->pixel_width
= FONT_WIDTH (font
);
18734 if (it
->constrain_row_ascent_descent_p
)
18736 if (it
->descent
> it
->max_descent
)
18738 it
->ascent
+= it
->descent
- it
->max_descent
;
18739 it
->descent
= it
->max_descent
;
18741 if (it
->ascent
> it
->max_ascent
)
18743 it
->descent
= min (it
->max_descent
, it
->descent
+ it
->ascent
- it
->max_ascent
);
18744 it
->ascent
= it
->max_ascent
;
18746 it
->phys_ascent
= min (it
->phys_ascent
, it
->ascent
);
18747 it
->phys_descent
= min (it
->phys_descent
, it
->descent
);
18748 extra_line_spacing
= 0;
18751 /* If this is a space inside a region of text with
18752 `space-width' property, change its width. */
18753 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
18755 it
->pixel_width
*= XFLOATINT (it
->space_width
);
18757 /* If face has a box, add the box thickness to the character
18758 height. If character has a box line to the left and/or
18759 right, add the box line width to the character's width. */
18760 if (face
->box
!= FACE_NO_BOX
)
18762 int thick
= face
->box_line_width
;
18766 it
->ascent
+= thick
;
18767 it
->descent
+= thick
;
18772 if (it
->start_of_box_run_p
)
18773 it
->pixel_width
+= thick
;
18774 if (it
->end_of_box_run_p
)
18775 it
->pixel_width
+= thick
;
18778 /* If face has an overline, add the height of the overline
18779 (1 pixel) and a 1 pixel margin to the character height. */
18780 if (face
->overline_p
)
18783 if (it
->constrain_row_ascent_descent_p
)
18785 if (it
->ascent
> it
->max_ascent
)
18786 it
->ascent
= it
->max_ascent
;
18787 if (it
->descent
> it
->max_descent
)
18788 it
->descent
= it
->max_descent
;
18791 take_vertical_position_into_account (it
);
18793 /* If we have to actually produce glyphs, do it. */
18798 /* Translate a space with a `space-width' property
18799 into a stretch glyph. */
18800 int ascent
= (((it
->ascent
+ it
->descent
) * FONT_BASE (font
))
18801 / FONT_HEIGHT (font
));
18802 append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
18803 it
->ascent
+ it
->descent
, ascent
);
18808 /* If characters with lbearing or rbearing are displayed
18809 in this line, record that fact in a flag of the
18810 glyph row. This is used to optimize X output code. */
18811 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
18812 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
18815 else if (it
->char_to_display
== '\n')
18817 /* A newline has no width but we need the height of the line.
18818 But if previous part of the line set a height, don't
18819 increase that height */
18821 Lisp_Object height
;
18823 it
->override_ascent
= -1;
18824 it
->pixel_width
= 0;
18827 height
= calc_line_height_property(it
, Qline_height
, font
, boff
, 0);
18829 if (it
->override_ascent
>= 0)
18831 it
->ascent
= it
->override_ascent
;
18832 it
->descent
= it
->override_descent
;
18833 boff
= it
->override_boff
;
18837 it
->ascent
= FONT_BASE (font
) + boff
;
18838 it
->descent
= FONT_DESCENT (font
) - boff
;
18841 if (EQ (height
, make_number(0)))
18843 if (it
->descent
> it
->max_descent
)
18845 it
->ascent
+= it
->descent
- it
->max_descent
;
18846 it
->descent
= it
->max_descent
;
18848 if (it
->ascent
> it
->max_ascent
)
18850 it
->descent
= min (it
->max_descent
, it
->descent
+ it
->ascent
- it
->max_ascent
);
18851 it
->ascent
= it
->max_ascent
;
18853 it
->phys_ascent
= min (it
->phys_ascent
, it
->ascent
);
18854 it
->phys_descent
= min (it
->phys_descent
, it
->descent
);
18855 it
->constrain_row_ascent_descent_p
= 1;
18856 extra_line_spacing
= 0;
18860 Lisp_Object spacing
;
18863 it
->phys_ascent
= it
->ascent
;
18864 it
->phys_descent
= it
->descent
;
18866 if ((it
->max_ascent
> 0 || it
->max_descent
> 0)
18867 && face
->box
!= FACE_NO_BOX
18868 && face
->box_line_width
> 0)
18870 it
->ascent
+= face
->box_line_width
;
18871 it
->descent
+= face
->box_line_width
;
18874 && XINT (height
) > it
->ascent
+ it
->descent
)
18875 it
->ascent
= XINT (height
) - it
->descent
;
18877 spacing
= calc_line_height_property(it
, Qline_spacing
, font
, boff
, &total
);
18878 if (INTEGERP (spacing
))
18880 extra_line_spacing
= XINT (spacing
);
18882 extra_line_spacing
-= (it
->phys_ascent
+ it
->phys_descent
);
18886 else if (it
->char_to_display
== '\t')
18888 int tab_width
= it
->tab_width
* FRAME_COLUMN_WIDTH (it
->f
);
18889 int x
= it
->current_x
+ it
->continuation_lines_width
;
18890 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
18892 /* If the distance from the current position to the next tab
18893 stop is less than a canonical character width, use the
18894 tab stop after that. */
18895 if (next_tab_x
- x
< FRAME_COLUMN_WIDTH (it
->f
))
18896 next_tab_x
+= tab_width
;
18898 it
->pixel_width
= next_tab_x
- x
;
18900 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
18901 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
18905 append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
18906 it
->ascent
+ it
->descent
, it
->ascent
);
18911 /* A multi-byte character. Assume that the display width of the
18912 character is the width of the character multiplied by the
18913 width of the font. */
18915 /* If we found a font, this font should give us the right
18916 metrics. If we didn't find a font, use the frame's
18917 default font and calculate the width of the character
18918 from the charset width; this is what old redisplay code
18921 pcm
= rif
->per_char_metric (font
, &char2b
,
18922 FONT_TYPE_FOR_MULTIBYTE (font
, it
->c
));
18924 if (font_not_found_p
|| !pcm
)
18926 int charset
= CHAR_CHARSET (it
->char_to_display
);
18928 it
->glyph_not_available_p
= 1;
18929 it
->pixel_width
= (FRAME_COLUMN_WIDTH (it
->f
)
18930 * CHARSET_WIDTH (charset
));
18931 it
->phys_ascent
= FONT_BASE (font
) + boff
;
18932 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
18936 it
->pixel_width
= pcm
->width
;
18937 it
->phys_ascent
= pcm
->ascent
+ boff
;
18938 it
->phys_descent
= pcm
->descent
- boff
;
18940 && (pcm
->lbearing
< 0
18941 || pcm
->rbearing
> pcm
->width
))
18942 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
18945 it
->ascent
= FONT_BASE (font
) + boff
;
18946 it
->descent
= FONT_DESCENT (font
) - boff
;
18947 if (face
->box
!= FACE_NO_BOX
)
18949 int thick
= face
->box_line_width
;
18953 it
->ascent
+= thick
;
18954 it
->descent
+= thick
;
18959 if (it
->start_of_box_run_p
)
18960 it
->pixel_width
+= thick
;
18961 if (it
->end_of_box_run_p
)
18962 it
->pixel_width
+= thick
;
18965 /* If face has an overline, add the height of the overline
18966 (1 pixel) and a 1 pixel margin to the character height. */
18967 if (face
->overline_p
)
18970 take_vertical_position_into_account (it
);
18975 it
->multibyte_p
= saved_multibyte_p
;
18977 else if (it
->what
== IT_COMPOSITION
)
18979 /* Note: A composition is represented as one glyph in the
18980 glyph matrix. There are no padding glyphs. */
18983 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
18985 int font_not_found_p
;
18986 struct font_info
*font_info
;
18987 int boff
; /* baseline offset */
18988 struct composition
*cmp
= composition_table
[it
->cmp_id
];
18990 /* Maybe translate single-byte characters to multibyte. */
18991 it
->char_to_display
= it
->c
;
18992 if (unibyte_display_via_language_environment
18993 && SINGLE_BYTE_CHAR_P (it
->c
)
18996 && !NILP (Vnonascii_translation_table
))))
18998 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
19001 /* Get face and font to use. Encode IT->char_to_display. */
19002 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
19003 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
19004 get_char_face_and_encoding (it
->f
, it
->char_to_display
, it
->face_id
,
19005 &char2b
, it
->multibyte_p
, 0);
19008 /* When no suitable font found, use the default font. */
19009 font_not_found_p
= font
== NULL
;
19010 if (font_not_found_p
)
19012 font
= FRAME_FONT (it
->f
);
19013 boff
= FRAME_BASELINE_OFFSET (it
->f
);
19018 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
19019 boff
= font_info
->baseline_offset
;
19020 if (font_info
->vertical_centering
)
19021 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
19024 /* There are no padding glyphs, so there is only one glyph to
19025 produce for the composition. Important is that pixel_width,
19026 ascent and descent are the values of what is drawn by
19027 draw_glyphs (i.e. the values of the overall glyphs composed). */
19030 /* If we have not yet calculated pixel size data of glyphs of
19031 the composition for the current face font, calculate them
19032 now. Theoretically, we have to check all fonts for the
19033 glyphs, but that requires much time and memory space. So,
19034 here we check only the font of the first glyph. This leads
19035 to incorrect display very rarely, and C-l (recenter) can
19036 correct the display anyway. */
19037 if (cmp
->font
!= (void *) font
)
19039 /* Ascent and descent of the font of the first character of
19040 this composition (adjusted by baseline offset). Ascent
19041 and descent of overall glyphs should not be less than
19042 them respectively. */
19043 int font_ascent
= FONT_BASE (font
) + boff
;
19044 int font_descent
= FONT_DESCENT (font
) - boff
;
19045 /* Bounding box of the overall glyphs. */
19046 int leftmost
, rightmost
, lowest
, highest
;
19047 int i
, width
, ascent
, descent
;
19049 cmp
->font
= (void *) font
;
19051 /* Initialize the bounding box. */
19053 && (pcm
= rif
->per_char_metric (font
, &char2b
,
19054 FONT_TYPE_FOR_MULTIBYTE (font
, it
->c
))))
19056 width
= pcm
->width
;
19057 ascent
= pcm
->ascent
;
19058 descent
= pcm
->descent
;
19062 width
= FONT_WIDTH (font
);
19063 ascent
= FONT_BASE (font
);
19064 descent
= FONT_DESCENT (font
);
19068 lowest
= - descent
+ boff
;
19069 highest
= ascent
+ boff
;
19073 && font_info
->default_ascent
19074 && CHAR_TABLE_P (Vuse_default_ascent
)
19075 && !NILP (Faref (Vuse_default_ascent
,
19076 make_number (it
->char_to_display
))))
19077 highest
= font_info
->default_ascent
+ boff
;
19079 /* Draw the first glyph at the normal position. It may be
19080 shifted to right later if some other glyphs are drawn at
19082 cmp
->offsets
[0] = 0;
19083 cmp
->offsets
[1] = boff
;
19085 /* Set cmp->offsets for the remaining glyphs. */
19086 for (i
= 1; i
< cmp
->glyph_len
; i
++)
19088 int left
, right
, btm
, top
;
19089 int ch
= COMPOSITION_GLYPH (cmp
, i
);
19090 int face_id
= FACE_FOR_CHAR (it
->f
, face
, ch
);
19092 face
= FACE_FROM_ID (it
->f
, face_id
);
19093 get_char_face_and_encoding (it
->f
, ch
, face
->id
,
19094 &char2b
, it
->multibyte_p
, 0);
19098 font
= FRAME_FONT (it
->f
);
19099 boff
= FRAME_BASELINE_OFFSET (it
->f
);
19105 = FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
19106 boff
= font_info
->baseline_offset
;
19107 if (font_info
->vertical_centering
)
19108 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
19112 && (pcm
= rif
->per_char_metric (font
, &char2b
,
19113 FONT_TYPE_FOR_MULTIBYTE (font
, ch
))))
19115 width
= pcm
->width
;
19116 ascent
= pcm
->ascent
;
19117 descent
= pcm
->descent
;
19121 width
= FONT_WIDTH (font
);
19126 if (cmp
->method
!= COMPOSITION_WITH_RULE_ALTCHARS
)
19128 /* Relative composition with or without
19129 alternate chars. */
19130 left
= (leftmost
+ rightmost
- width
) / 2;
19131 btm
= - descent
+ boff
;
19132 if (font_info
&& font_info
->relative_compose
19133 && (! CHAR_TABLE_P (Vignore_relative_composition
)
19134 || NILP (Faref (Vignore_relative_composition
,
19135 make_number (ch
)))))
19138 if (- descent
>= font_info
->relative_compose
)
19139 /* One extra pixel between two glyphs. */
19141 else if (ascent
<= 0)
19142 /* One extra pixel between two glyphs. */
19143 btm
= lowest
- 1 - ascent
- descent
;
19148 /* A composition rule is specified by an integer
19149 value that encodes global and new reference
19150 points (GREF and NREF). GREF and NREF are
19151 specified by numbers as below:
19153 0---1---2 -- ascent
19157 9--10--11 -- center
19159 ---3---4---5--- baseline
19161 6---7---8 -- descent
19163 int rule
= COMPOSITION_RULE (cmp
, i
);
19164 int gref
, nref
, grefx
, grefy
, nrefx
, nrefy
;
19166 COMPOSITION_DECODE_RULE (rule
, gref
, nref
);
19167 grefx
= gref
% 3, nrefx
= nref
% 3;
19168 grefy
= gref
/ 3, nrefy
= nref
/ 3;
19171 + grefx
* (rightmost
- leftmost
) / 2
19172 - nrefx
* width
/ 2);
19173 btm
= ((grefy
== 0 ? highest
19175 : grefy
== 2 ? lowest
19176 : (highest
+ lowest
) / 2)
19177 - (nrefy
== 0 ? ascent
+ descent
19178 : nrefy
== 1 ? descent
- boff
19180 : (ascent
+ descent
) / 2));
19183 cmp
->offsets
[i
* 2] = left
;
19184 cmp
->offsets
[i
* 2 + 1] = btm
+ descent
;
19186 /* Update the bounding box of the overall glyphs. */
19187 right
= left
+ width
;
19188 top
= btm
+ descent
+ ascent
;
19189 if (left
< leftmost
)
19191 if (right
> rightmost
)
19199 /* If there are glyphs whose x-offsets are negative,
19200 shift all glyphs to the right and make all x-offsets
19204 for (i
= 0; i
< cmp
->glyph_len
; i
++)
19205 cmp
->offsets
[i
* 2] -= leftmost
;
19206 rightmost
-= leftmost
;
19209 cmp
->pixel_width
= rightmost
;
19210 cmp
->ascent
= highest
;
19211 cmp
->descent
= - lowest
;
19212 if (cmp
->ascent
< font_ascent
)
19213 cmp
->ascent
= font_ascent
;
19214 if (cmp
->descent
< font_descent
)
19215 cmp
->descent
= font_descent
;
19218 it
->pixel_width
= cmp
->pixel_width
;
19219 it
->ascent
= it
->phys_ascent
= cmp
->ascent
;
19220 it
->descent
= it
->phys_descent
= cmp
->descent
;
19222 if (face
->box
!= FACE_NO_BOX
)
19224 int thick
= face
->box_line_width
;
19228 it
->ascent
+= thick
;
19229 it
->descent
+= thick
;
19234 if (it
->start_of_box_run_p
)
19235 it
->pixel_width
+= thick
;
19236 if (it
->end_of_box_run_p
)
19237 it
->pixel_width
+= thick
;
19240 /* If face has an overline, add the height of the overline
19241 (1 pixel) and a 1 pixel margin to the character height. */
19242 if (face
->overline_p
)
19245 take_vertical_position_into_account (it
);
19248 append_composite_glyph (it
);
19250 else if (it
->what
== IT_IMAGE
)
19251 produce_image_glyph (it
);
19252 else if (it
->what
== IT_STRETCH
)
19253 produce_stretch_glyph (it
);
19255 /* Accumulate dimensions. Note: can't assume that it->descent > 0
19256 because this isn't true for images with `:ascent 100'. */
19257 xassert (it
->ascent
>= 0 && it
->descent
>= 0);
19258 if (it
->area
== TEXT_AREA
)
19259 it
->current_x
+= it
->pixel_width
;
19261 if (extra_line_spacing
> 0)
19262 it
->descent
+= extra_line_spacing
;
19264 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
19265 it
->max_descent
= max (it
->max_descent
, it
->descent
);
19266 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
19267 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
19271 Output LEN glyphs starting at START at the nominal cursor position.
19272 Advance the nominal cursor over the text. The global variable
19273 updated_window contains the window being updated, updated_row is
19274 the glyph row being updated, and updated_area is the area of that
19275 row being updated. */
19278 x_write_glyphs (start
, len
)
19279 struct glyph
*start
;
19284 xassert (updated_window
&& updated_row
);
19287 /* Write glyphs. */
19289 hpos
= start
- updated_row
->glyphs
[updated_area
];
19290 x
= draw_glyphs (updated_window
, output_cursor
.x
,
19291 updated_row
, updated_area
,
19293 DRAW_NORMAL_TEXT
, 0);
19295 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
19296 if (updated_area
== TEXT_AREA
19297 && updated_window
->phys_cursor_on_p
19298 && updated_window
->phys_cursor
.vpos
== output_cursor
.vpos
19299 && updated_window
->phys_cursor
.hpos
>= hpos
19300 && updated_window
->phys_cursor
.hpos
< hpos
+ len
)
19301 updated_window
->phys_cursor_on_p
= 0;
19305 /* Advance the output cursor. */
19306 output_cursor
.hpos
+= len
;
19307 output_cursor
.x
= x
;
19312 Insert LEN glyphs from START at the nominal cursor position. */
19315 x_insert_glyphs (start
, len
)
19316 struct glyph
*start
;
19321 int line_height
, shift_by_width
, shifted_region_width
;
19322 struct glyph_row
*row
;
19323 struct glyph
*glyph
;
19324 int frame_x
, frame_y
, hpos
;
19326 xassert (updated_window
&& updated_row
);
19328 w
= updated_window
;
19329 f
= XFRAME (WINDOW_FRAME (w
));
19331 /* Get the height of the line we are in. */
19333 line_height
= row
->height
;
19335 /* Get the width of the glyphs to insert. */
19336 shift_by_width
= 0;
19337 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
19338 shift_by_width
+= glyph
->pixel_width
;
19340 /* Get the width of the region to shift right. */
19341 shifted_region_width
= (window_box_width (w
, updated_area
)
19346 frame_x
= window_box_left (w
, updated_area
) + output_cursor
.x
;
19347 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
19349 rif
->shift_glyphs_for_insert (f
, frame_x
, frame_y
, shifted_region_width
,
19350 line_height
, shift_by_width
);
19352 /* Write the glyphs. */
19353 hpos
= start
- row
->glyphs
[updated_area
];
19354 draw_glyphs (w
, output_cursor
.x
, row
, updated_area
,
19356 DRAW_NORMAL_TEXT
, 0);
19358 /* Advance the output cursor. */
19359 output_cursor
.hpos
+= len
;
19360 output_cursor
.x
+= shift_by_width
;
19366 Erase the current text line from the nominal cursor position
19367 (inclusive) to pixel column TO_X (exclusive). The idea is that
19368 everything from TO_X onward is already erased.
19370 TO_X is a pixel position relative to updated_area of
19371 updated_window. TO_X == -1 means clear to the end of this area. */
19374 x_clear_end_of_line (to_x
)
19378 struct window
*w
= updated_window
;
19379 int max_x
, min_y
, max_y
;
19380 int from_x
, from_y
, to_y
;
19382 xassert (updated_window
&& updated_row
);
19383 f
= XFRAME (w
->frame
);
19385 if (updated_row
->full_width_p
)
19386 max_x
= WINDOW_TOTAL_WIDTH (w
);
19388 max_x
= window_box_width (w
, updated_area
);
19389 max_y
= window_text_bottom_y (w
);
19391 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
19392 of window. For TO_X > 0, truncate to end of drawing area. */
19398 to_x
= min (to_x
, max_x
);
19400 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
19402 /* Notice if the cursor will be cleared by this operation. */
19403 if (!updated_row
->full_width_p
)
19404 notice_overwritten_cursor (w
, updated_area
,
19405 output_cursor
.x
, -1,
19407 MATRIX_ROW_BOTTOM_Y (updated_row
));
19409 from_x
= output_cursor
.x
;
19411 /* Translate to frame coordinates. */
19412 if (updated_row
->full_width_p
)
19414 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
19415 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
19419 int area_left
= window_box_left (w
, updated_area
);
19420 from_x
+= area_left
;
19424 min_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
19425 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
19426 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
19428 /* Prevent inadvertently clearing to end of the X window. */
19429 if (to_x
> from_x
&& to_y
> from_y
)
19432 rif
->clear_frame_area (f
, from_x
, from_y
,
19433 to_x
- from_x
, to_y
- from_y
);
19438 #endif /* HAVE_WINDOW_SYSTEM */
19442 /***********************************************************************
19444 ***********************************************************************/
19446 /* Value is the internal representation of the specified cursor type
19447 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
19448 of the bar cursor. */
19450 static enum text_cursor_kinds
19451 get_specified_cursor_type (arg
, width
)
19455 enum text_cursor_kinds type
;
19460 if (EQ (arg
, Qbox
))
19461 return FILLED_BOX_CURSOR
;
19463 if (EQ (arg
, Qhollow
))
19464 return HOLLOW_BOX_CURSOR
;
19466 if (EQ (arg
, Qbar
))
19473 && EQ (XCAR (arg
), Qbar
)
19474 && INTEGERP (XCDR (arg
))
19475 && XINT (XCDR (arg
)) >= 0)
19477 *width
= XINT (XCDR (arg
));
19481 if (EQ (arg
, Qhbar
))
19484 return HBAR_CURSOR
;
19488 && EQ (XCAR (arg
), Qhbar
)
19489 && INTEGERP (XCDR (arg
))
19490 && XINT (XCDR (arg
)) >= 0)
19492 *width
= XINT (XCDR (arg
));
19493 return HBAR_CURSOR
;
19496 /* Treat anything unknown as "hollow box cursor".
19497 It was bad to signal an error; people have trouble fixing
19498 .Xdefaults with Emacs, when it has something bad in it. */
19499 type
= HOLLOW_BOX_CURSOR
;
19504 /* Set the default cursor types for specified frame. */
19506 set_frame_cursor_types (f
, arg
)
19513 FRAME_DESIRED_CURSOR (f
) = get_specified_cursor_type (arg
, &width
);
19514 FRAME_CURSOR_WIDTH (f
) = width
;
19516 /* By default, set up the blink-off state depending on the on-state. */
19518 tem
= Fassoc (arg
, Vblink_cursor_alist
);
19521 FRAME_BLINK_OFF_CURSOR (f
)
19522 = get_specified_cursor_type (XCDR (tem
), &width
);
19523 FRAME_BLINK_OFF_CURSOR_WIDTH (f
) = width
;
19526 FRAME_BLINK_OFF_CURSOR (f
) = DEFAULT_CURSOR
;
19530 /* Return the cursor we want to be displayed in window W. Return
19531 width of bar/hbar cursor through WIDTH arg. Return with
19532 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
19533 (i.e. if the `system caret' should track this cursor).
19535 In a mini-buffer window, we want the cursor only to appear if we
19536 are reading input from this window. For the selected window, we
19537 want the cursor type given by the frame parameter or buffer local
19538 setting of cursor-type. If explicitly marked off, draw no cursor.
19539 In all other cases, we want a hollow box cursor. */
19541 static enum text_cursor_kinds
19542 get_window_cursor_type (w
, glyph
, width
, active_cursor
)
19544 struct glyph
*glyph
;
19546 int *active_cursor
;
19548 struct frame
*f
= XFRAME (w
->frame
);
19549 struct buffer
*b
= XBUFFER (w
->buffer
);
19550 int cursor_type
= DEFAULT_CURSOR
;
19551 Lisp_Object alt_cursor
;
19552 int non_selected
= 0;
19554 *active_cursor
= 1;
19557 if (cursor_in_echo_area
19558 && FRAME_HAS_MINIBUF_P (f
)
19559 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
19561 if (w
== XWINDOW (echo_area_window
))
19563 *width
= FRAME_CURSOR_WIDTH (f
);
19564 return FRAME_DESIRED_CURSOR (f
);
19567 *active_cursor
= 0;
19571 /* Nonselected window or nonselected frame. */
19572 else if (w
!= XWINDOW (f
->selected_window
)
19573 #ifdef HAVE_WINDOW_SYSTEM
19574 || f
!= FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
19578 *active_cursor
= 0;
19580 if (MINI_WINDOW_P (w
) && minibuf_level
== 0)
19586 /* Never display a cursor in a window in which cursor-type is nil. */
19587 if (NILP (b
->cursor_type
))
19590 /* Use cursor-in-non-selected-windows for non-selected window or frame. */
19593 alt_cursor
= Fbuffer_local_value (Qcursor_in_non_selected_windows
, w
->buffer
);
19594 return get_specified_cursor_type (alt_cursor
, width
);
19597 /* Get the normal cursor type for this window. */
19598 if (EQ (b
->cursor_type
, Qt
))
19600 cursor_type
= FRAME_DESIRED_CURSOR (f
);
19601 *width
= FRAME_CURSOR_WIDTH (f
);
19604 cursor_type
= get_specified_cursor_type (b
->cursor_type
, width
);
19606 /* Use normal cursor if not blinked off. */
19607 if (!w
->cursor_off_p
)
19609 if (glyph
!= NULL
&& glyph
->type
== IMAGE_GLYPH
) {
19610 if (cursor_type
== FILLED_BOX_CURSOR
)
19611 cursor_type
= HOLLOW_BOX_CURSOR
;
19613 return cursor_type
;
19616 /* Cursor is blinked off, so determine how to "toggle" it. */
19618 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
19619 if ((alt_cursor
= Fassoc (b
->cursor_type
, Vblink_cursor_alist
), !NILP (alt_cursor
)))
19620 return get_specified_cursor_type (XCDR (alt_cursor
), width
);
19622 /* Then see if frame has specified a specific blink off cursor type. */
19623 if (FRAME_BLINK_OFF_CURSOR (f
) != DEFAULT_CURSOR
)
19625 *width
= FRAME_BLINK_OFF_CURSOR_WIDTH (f
);
19626 return FRAME_BLINK_OFF_CURSOR (f
);
19630 /* Some people liked having a permanently visible blinking cursor,
19631 while others had very strong opinions against it. So it was
19632 decided to remove it. KFS 2003-09-03 */
19634 /* Finally perform built-in cursor blinking:
19635 filled box <-> hollow box
19636 wide [h]bar <-> narrow [h]bar
19637 narrow [h]bar <-> no cursor
19638 other type <-> no cursor */
19640 if (cursor_type
== FILLED_BOX_CURSOR
)
19641 return HOLLOW_BOX_CURSOR
;
19643 if ((cursor_type
== BAR_CURSOR
|| cursor_type
== HBAR_CURSOR
) && *width
> 1)
19646 return cursor_type
;
19654 #ifdef HAVE_WINDOW_SYSTEM
19656 /* Notice when the text cursor of window W has been completely
19657 overwritten by a drawing operation that outputs glyphs in AREA
19658 starting at X0 and ending at X1 in the line starting at Y0 and
19659 ending at Y1. X coordinates are area-relative. X1 < 0 means all
19660 the rest of the line after X0 has been written. Y coordinates
19661 are window-relative. */
19664 notice_overwritten_cursor (w
, area
, x0
, x1
, y0
, y1
)
19666 enum glyph_row_area area
;
19667 int x0
, y0
, x1
, y1
;
19669 int cx0
, cx1
, cy0
, cy1
;
19670 struct glyph_row
*row
;
19672 if (!w
->phys_cursor_on_p
)
19674 if (area
!= TEXT_AREA
)
19677 row
= w
->current_matrix
->rows
+ w
->phys_cursor
.vpos
;
19678 if (!row
->displays_text_p
)
19681 if (row
->cursor_in_fringe_p
)
19683 row
->cursor_in_fringe_p
= 0;
19684 draw_fringe_bitmap (w
, row
, 0);
19685 w
->phys_cursor_on_p
= 0;
19689 cx0
= w
->phys_cursor
.x
;
19690 cx1
= cx0
+ w
->phys_cursor_width
;
19691 if (x0
> cx0
|| (x1
>= 0 && x1
< cx1
))
19694 /* The cursor image will be completely removed from the
19695 screen if the output area intersects the cursor area in
19696 y-direction. When we draw in [y0 y1[, and some part of
19697 the cursor is at y < y0, that part must have been drawn
19698 before. When scrolling, the cursor is erased before
19699 actually scrolling, so we don't come here. When not
19700 scrolling, the rows above the old cursor row must have
19701 changed, and in this case these rows must have written
19702 over the cursor image.
19704 Likewise if part of the cursor is below y1, with the
19705 exception of the cursor being in the first blank row at
19706 the buffer and window end because update_text_area
19707 doesn't draw that row. (Except when it does, but
19708 that's handled in update_text_area.) */
19710 cy0
= w
->phys_cursor
.y
;
19711 cy1
= cy0
+ w
->phys_cursor_height
;
19712 if ((y0
< cy0
|| y0
>= cy1
) && (y1
<= cy0
|| y1
>= cy1
))
19715 w
->phys_cursor_on_p
= 0;
19718 #endif /* HAVE_WINDOW_SYSTEM */
19721 /************************************************************************
19723 ************************************************************************/
19725 #ifdef HAVE_WINDOW_SYSTEM
19728 Fix the display of area AREA of overlapping row ROW in window W. */
19731 x_fix_overlapping_area (w
, row
, area
)
19733 struct glyph_row
*row
;
19734 enum glyph_row_area area
;
19741 for (i
= 0; i
< row
->used
[area
];)
19743 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
19745 int start
= i
, start_x
= x
;
19749 x
+= row
->glyphs
[area
][i
].pixel_width
;
19752 while (i
< row
->used
[area
]
19753 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
19755 draw_glyphs (w
, start_x
, row
, area
,
19757 DRAW_NORMAL_TEXT
, 1);
19761 x
+= row
->glyphs
[area
][i
].pixel_width
;
19771 Draw the cursor glyph of window W in glyph row ROW. See the
19772 comment of draw_glyphs for the meaning of HL. */
19775 draw_phys_cursor_glyph (w
, row
, hl
)
19777 struct glyph_row
*row
;
19778 enum draw_glyphs_face hl
;
19780 /* If cursor hpos is out of bounds, don't draw garbage. This can
19781 happen in mini-buffer windows when switching between echo area
19782 glyphs and mini-buffer. */
19783 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
19785 int on_p
= w
->phys_cursor_on_p
;
19787 x1
= draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
19788 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
19790 w
->phys_cursor_on_p
= on_p
;
19792 if (hl
== DRAW_CURSOR
)
19793 w
->phys_cursor_width
= x1
- w
->phys_cursor
.x
;
19794 /* When we erase the cursor, and ROW is overlapped by other
19795 rows, make sure that these overlapping parts of other rows
19797 else if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
19799 if (row
> w
->current_matrix
->rows
19800 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
19801 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
);
19803 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
19804 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
19805 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
);
19812 Erase the image of a cursor of window W from the screen. */
19815 erase_phys_cursor (w
)
19818 struct frame
*f
= XFRAME (w
->frame
);
19819 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
19820 int hpos
= w
->phys_cursor
.hpos
;
19821 int vpos
= w
->phys_cursor
.vpos
;
19822 int mouse_face_here_p
= 0;
19823 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
19824 struct glyph_row
*cursor_row
;
19825 struct glyph
*cursor_glyph
;
19826 enum draw_glyphs_face hl
;
19828 /* No cursor displayed or row invalidated => nothing to do on the
19830 if (w
->phys_cursor_type
== NO_CURSOR
)
19831 goto mark_cursor_off
;
19833 /* VPOS >= active_glyphs->nrows means that window has been resized.
19834 Don't bother to erase the cursor. */
19835 if (vpos
>= active_glyphs
->nrows
)
19836 goto mark_cursor_off
;
19838 /* If row containing cursor is marked invalid, there is nothing we
19840 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
19841 if (!cursor_row
->enabled_p
)
19842 goto mark_cursor_off
;
19844 /* If row is completely invisible, don't attempt to delete a cursor which
19845 isn't there. This can happen if cursor is at top of a window, and
19846 we switch to a buffer with a header line in that window. */
19847 if (cursor_row
->visible_height
<= 0)
19848 goto mark_cursor_off
;
19850 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
19851 if (cursor_row
->cursor_in_fringe_p
)
19853 cursor_row
->cursor_in_fringe_p
= 0;
19854 draw_fringe_bitmap (w
, cursor_row
, 0);
19855 goto mark_cursor_off
;
19858 /* This can happen when the new row is shorter than the old one.
19859 In this case, either draw_glyphs or clear_end_of_line
19860 should have cleared the cursor. Note that we wouldn't be
19861 able to erase the cursor in this case because we don't have a
19862 cursor glyph at hand. */
19863 if (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])
19864 goto mark_cursor_off
;
19866 /* If the cursor is in the mouse face area, redisplay that when
19867 we clear the cursor. */
19868 if (! NILP (dpyinfo
->mouse_face_window
)
19869 && w
== XWINDOW (dpyinfo
->mouse_face_window
)
19870 && (vpos
> dpyinfo
->mouse_face_beg_row
19871 || (vpos
== dpyinfo
->mouse_face_beg_row
19872 && hpos
>= dpyinfo
->mouse_face_beg_col
))
19873 && (vpos
< dpyinfo
->mouse_face_end_row
19874 || (vpos
== dpyinfo
->mouse_face_end_row
19875 && hpos
< dpyinfo
->mouse_face_end_col
))
19876 /* Don't redraw the cursor's spot in mouse face if it is at the
19877 end of a line (on a newline). The cursor appears there, but
19878 mouse highlighting does not. */
19879 && cursor_row
->used
[TEXT_AREA
] > hpos
)
19880 mouse_face_here_p
= 1;
19882 /* Maybe clear the display under the cursor. */
19883 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
19886 int header_line_height
= WINDOW_HEADER_LINE_HEIGHT (w
);
19888 cursor_glyph
= get_phys_cursor_glyph (w
);
19889 if (cursor_glyph
== NULL
)
19890 goto mark_cursor_off
;
19892 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
19893 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
, cursor_row
->y
));
19895 rif
->clear_frame_area (f
, x
, y
,
19896 cursor_glyph
->pixel_width
, cursor_row
->visible_height
);
19899 /* Erase the cursor by redrawing the character underneath it. */
19900 if (mouse_face_here_p
)
19901 hl
= DRAW_MOUSE_FACE
;
19903 hl
= DRAW_NORMAL_TEXT
;
19904 draw_phys_cursor_glyph (w
, cursor_row
, hl
);
19907 w
->phys_cursor_on_p
= 0;
19908 w
->phys_cursor_type
= NO_CURSOR
;
19913 Display or clear cursor of window W. If ON is zero, clear the
19914 cursor. If it is non-zero, display the cursor. If ON is nonzero,
19915 where to put the cursor is specified by HPOS, VPOS, X and Y. */
19918 display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
)
19920 int on
, hpos
, vpos
, x
, y
;
19922 struct frame
*f
= XFRAME (w
->frame
);
19923 int new_cursor_type
;
19924 int new_cursor_width
;
19926 struct glyph_row
*glyph_row
;
19927 struct glyph
*glyph
;
19929 /* This is pointless on invisible frames, and dangerous on garbaged
19930 windows and frames; in the latter case, the frame or window may
19931 be in the midst of changing its size, and x and y may be off the
19933 if (! FRAME_VISIBLE_P (f
)
19934 || FRAME_GARBAGED_P (f
)
19935 || vpos
>= w
->current_matrix
->nrows
19936 || hpos
>= w
->current_matrix
->matrix_w
)
19939 /* If cursor is off and we want it off, return quickly. */
19940 if (!on
&& !w
->phys_cursor_on_p
)
19943 glyph_row
= MATRIX_ROW (w
->current_matrix
, vpos
);
19944 /* If cursor row is not enabled, we don't really know where to
19945 display the cursor. */
19946 if (!glyph_row
->enabled_p
)
19948 w
->phys_cursor_on_p
= 0;
19953 if (!glyph_row
->exact_window_width_line_p
19954 || hpos
< glyph_row
->used
[TEXT_AREA
])
19955 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
19957 xassert (interrupt_input_blocked
);
19959 /* Set new_cursor_type to the cursor we want to be displayed. */
19960 new_cursor_type
= get_window_cursor_type (w
, glyph
,
19961 &new_cursor_width
, &active_cursor
);
19963 /* If cursor is currently being shown and we don't want it to be or
19964 it is in the wrong place, or the cursor type is not what we want,
19966 if (w
->phys_cursor_on_p
19968 || w
->phys_cursor
.x
!= x
19969 || w
->phys_cursor
.y
!= y
19970 || new_cursor_type
!= w
->phys_cursor_type
19971 || ((new_cursor_type
== BAR_CURSOR
|| new_cursor_type
== HBAR_CURSOR
)
19972 && new_cursor_width
!= w
->phys_cursor_width
)))
19973 erase_phys_cursor (w
);
19975 /* Don't check phys_cursor_on_p here because that flag is only set
19976 to zero in some cases where we know that the cursor has been
19977 completely erased, to avoid the extra work of erasing the cursor
19978 twice. In other words, phys_cursor_on_p can be 1 and the cursor
19979 still not be visible, or it has only been partly erased. */
19982 w
->phys_cursor_ascent
= glyph_row
->ascent
;
19983 w
->phys_cursor_height
= glyph_row
->height
;
19985 /* Set phys_cursor_.* before x_draw_.* is called because some
19986 of them may need the information. */
19987 w
->phys_cursor
.x
= x
;
19988 w
->phys_cursor
.y
= glyph_row
->y
;
19989 w
->phys_cursor
.hpos
= hpos
;
19990 w
->phys_cursor
.vpos
= vpos
;
19993 rif
->draw_window_cursor (w
, glyph_row
, x
, y
,
19994 new_cursor_type
, new_cursor_width
,
19995 on
, active_cursor
);
19999 /* Switch the display of W's cursor on or off, according to the value
20003 update_window_cursor (w
, on
)
20007 /* Don't update cursor in windows whose frame is in the process
20008 of being deleted. */
20009 if (w
->current_matrix
)
20012 display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
20013 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
20019 /* Call update_window_cursor with parameter ON_P on all leaf windows
20020 in the window tree rooted at W. */
20023 update_cursor_in_window_tree (w
, on_p
)
20029 if (!NILP (w
->hchild
))
20030 update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
20031 else if (!NILP (w
->vchild
))
20032 update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
20034 update_window_cursor (w
, on_p
);
20036 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
20042 Display the cursor on window W, or clear it, according to ON_P.
20043 Don't change the cursor's position. */
20046 x_update_cursor (f
, on_p
)
20050 update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
20055 Clear the cursor of window W to background color, and mark the
20056 cursor as not shown. This is used when the text where the cursor
20057 is is about to be rewritten. */
20063 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
20064 update_window_cursor (w
, 0);
20069 Display the active region described by mouse_face_* according to DRAW. */
20072 show_mouse_face (dpyinfo
, draw
)
20073 Display_Info
*dpyinfo
;
20074 enum draw_glyphs_face draw
;
20076 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
20077 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
20079 if (/* If window is in the process of being destroyed, don't bother
20081 w
->current_matrix
!= NULL
20082 /* Don't update mouse highlight if hidden */
20083 && (draw
!= DRAW_MOUSE_FACE
|| !dpyinfo
->mouse_face_hidden
)
20084 /* Recognize when we are called to operate on rows that don't exist
20085 anymore. This can happen when a window is split. */
20086 && dpyinfo
->mouse_face_end_row
< w
->current_matrix
->nrows
)
20088 int phys_cursor_on_p
= w
->phys_cursor_on_p
;
20089 struct glyph_row
*row
, *first
, *last
;
20091 first
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_beg_row
);
20092 last
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_end_row
);
20094 for (row
= first
; row
<= last
&& row
->enabled_p
; ++row
)
20096 int start_hpos
, end_hpos
, start_x
;
20098 /* For all but the first row, the highlight starts at column 0. */
20101 start_hpos
= dpyinfo
->mouse_face_beg_col
;
20102 start_x
= dpyinfo
->mouse_face_beg_x
;
20111 end_hpos
= dpyinfo
->mouse_face_end_col
;
20113 end_hpos
= row
->used
[TEXT_AREA
];
20115 if (end_hpos
> start_hpos
)
20117 draw_glyphs (w
, start_x
, row
, TEXT_AREA
,
20118 start_hpos
, end_hpos
,
20122 = draw
== DRAW_MOUSE_FACE
|| draw
== DRAW_IMAGE_RAISED
;
20126 /* When we've written over the cursor, arrange for it to
20127 be displayed again. */
20128 if (phys_cursor_on_p
&& !w
->phys_cursor_on_p
)
20131 display_and_set_cursor (w
, 1,
20132 w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
20133 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
20138 /* Change the mouse cursor. */
20139 if (draw
== DRAW_NORMAL_TEXT
)
20140 rif
->define_frame_cursor (f
, FRAME_X_OUTPUT (f
)->text_cursor
);
20141 else if (draw
== DRAW_MOUSE_FACE
)
20142 rif
->define_frame_cursor (f
, FRAME_X_OUTPUT (f
)->hand_cursor
);
20144 rif
->define_frame_cursor (f
, FRAME_X_OUTPUT (f
)->nontext_cursor
);
20148 Clear out the mouse-highlighted active region.
20149 Redraw it un-highlighted first. Value is non-zero if mouse
20150 face was actually drawn unhighlighted. */
20153 clear_mouse_face (dpyinfo
)
20154 Display_Info
*dpyinfo
;
20158 if (!dpyinfo
->mouse_face_hidden
&& !NILP (dpyinfo
->mouse_face_window
))
20160 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
20164 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
20165 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
20166 dpyinfo
->mouse_face_window
= Qnil
;
20167 dpyinfo
->mouse_face_overlay
= Qnil
;
20173 Non-zero if physical cursor of window W is within mouse face. */
20176 cursor_in_mouse_face_p (w
)
20179 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (XFRAME (w
->frame
));
20180 int in_mouse_face
= 0;
20182 if (WINDOWP (dpyinfo
->mouse_face_window
)
20183 && XWINDOW (dpyinfo
->mouse_face_window
) == w
)
20185 int hpos
= w
->phys_cursor
.hpos
;
20186 int vpos
= w
->phys_cursor
.vpos
;
20188 if (vpos
>= dpyinfo
->mouse_face_beg_row
20189 && vpos
<= dpyinfo
->mouse_face_end_row
20190 && (vpos
> dpyinfo
->mouse_face_beg_row
20191 || hpos
>= dpyinfo
->mouse_face_beg_col
)
20192 && (vpos
< dpyinfo
->mouse_face_end_row
20193 || hpos
< dpyinfo
->mouse_face_end_col
20194 || dpyinfo
->mouse_face_past_end
))
20198 return in_mouse_face
;
20204 /* Find the glyph matrix position of buffer position CHARPOS in window
20205 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
20206 current glyphs must be up to date. If CHARPOS is above window
20207 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
20208 of last line in W. In the row containing CHARPOS, stop before glyphs
20209 having STOP as object. */
20211 #if 1 /* This is a version of fast_find_position that's more correct
20212 in the presence of hscrolling, for example. I didn't install
20213 it right away because the problem fixed is minor, it failed
20214 in 20.x as well, and I think it's too risky to install
20215 so near the release of 21.1. 2001-09-25 gerd. */
20218 fast_find_position (w
, charpos
, hpos
, vpos
, x
, y
, stop
)
20221 int *hpos
, *vpos
, *x
, *y
;
20224 struct glyph_row
*row
, *first
;
20225 struct glyph
*glyph
, *end
;
20228 first
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
20229 row
= row_containing_pos (w
, charpos
, first
, NULL
, 0);
20232 if (charpos
< MATRIX_ROW_START_CHARPOS (first
))
20234 *x
= *y
= *hpos
= *vpos
= 0;
20239 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
20246 *vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
20248 glyph
= row
->glyphs
[TEXT_AREA
];
20249 end
= glyph
+ row
->used
[TEXT_AREA
];
20251 /* Skip over glyphs not having an object at the start of the row.
20252 These are special glyphs like truncation marks on terminal
20254 if (row
->displays_text_p
)
20256 && INTEGERP (glyph
->object
)
20257 && !EQ (stop
, glyph
->object
)
20258 && glyph
->charpos
< 0)
20260 *x
+= glyph
->pixel_width
;
20265 && !INTEGERP (glyph
->object
)
20266 && !EQ (stop
, glyph
->object
)
20267 && (!BUFFERP (glyph
->object
)
20268 || glyph
->charpos
< charpos
))
20270 *x
+= glyph
->pixel_width
;
20274 *hpos
= glyph
- row
->glyphs
[TEXT_AREA
];
20281 fast_find_position (w
, pos
, hpos
, vpos
, x
, y
, stop
)
20284 int *hpos
, *vpos
, *x
, *y
;
20289 int maybe_next_line_p
= 0;
20290 int line_start_position
;
20291 int yb
= window_text_bottom_y (w
);
20292 struct glyph_row
*row
, *best_row
;
20293 int row_vpos
, best_row_vpos
;
20296 row
= best_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
20297 row_vpos
= best_row_vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
20299 while (row
->y
< yb
)
20301 if (row
->used
[TEXT_AREA
])
20302 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
20304 line_start_position
= 0;
20306 if (line_start_position
> pos
)
20308 /* If the position sought is the end of the buffer,
20309 don't include the blank lines at the bottom of the window. */
20310 else if (line_start_position
== pos
20311 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
20313 maybe_next_line_p
= 1;
20316 else if (line_start_position
> 0)
20319 best_row_vpos
= row_vpos
;
20322 if (row
->y
+ row
->height
>= yb
)
20329 /* Find the right column within BEST_ROW. */
20331 current_x
= best_row
->x
;
20332 for (i
= 0; i
< best_row
->used
[TEXT_AREA
]; i
++)
20334 struct glyph
*glyph
= best_row
->glyphs
[TEXT_AREA
] + i
;
20335 int charpos
= glyph
->charpos
;
20337 if (BUFFERP (glyph
->object
))
20339 if (charpos
== pos
)
20342 *vpos
= best_row_vpos
;
20347 else if (charpos
> pos
)
20350 else if (EQ (glyph
->object
, stop
))
20355 current_x
+= glyph
->pixel_width
;
20358 /* If we're looking for the end of the buffer,
20359 and we didn't find it in the line we scanned,
20360 use the start of the following line. */
20361 if (maybe_next_line_p
)
20366 current_x
= best_row
->x
;
20369 *vpos
= best_row_vpos
;
20370 *hpos
= lastcol
+ 1;
20379 /* Find the position of the glyph for position POS in OBJECT in
20380 window W's current matrix, and return in *X, *Y the pixel
20381 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
20383 RIGHT_P non-zero means return the position of the right edge of the
20384 glyph, RIGHT_P zero means return the left edge position.
20386 If no glyph for POS exists in the matrix, return the position of
20387 the glyph with the next smaller position that is in the matrix, if
20388 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
20389 exists in the matrix, return the position of the glyph with the
20390 next larger position in OBJECT.
20392 Value is non-zero if a glyph was found. */
20395 fast_find_string_pos (w
, pos
, object
, hpos
, vpos
, x
, y
, right_p
)
20398 Lisp_Object object
;
20399 int *hpos
, *vpos
, *x
, *y
;
20402 int yb
= window_text_bottom_y (w
);
20403 struct glyph_row
*r
;
20404 struct glyph
*best_glyph
= NULL
;
20405 struct glyph_row
*best_row
= NULL
;
20408 for (r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
20409 r
->enabled_p
&& r
->y
< yb
;
20412 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
20413 struct glyph
*e
= g
+ r
->used
[TEXT_AREA
];
20416 for (gx
= r
->x
; g
< e
; gx
+= g
->pixel_width
, ++g
)
20417 if (EQ (g
->object
, object
))
20419 if (g
->charpos
== pos
)
20426 else if (best_glyph
== NULL
20427 || ((abs (g
->charpos
- pos
)
20428 < abs (best_glyph
->charpos
- pos
))
20431 : g
->charpos
> pos
)))
20445 *hpos
= best_glyph
- best_row
->glyphs
[TEXT_AREA
];
20449 *x
+= best_glyph
->pixel_width
;
20454 *vpos
= best_row
- w
->current_matrix
->rows
;
20457 return best_glyph
!= NULL
;
20461 /* See if position X, Y is within a hot-spot of an image. */
20464 on_hot_spot_p (hot_spot
, x
, y
)
20465 Lisp_Object hot_spot
;
20468 if (!CONSP (hot_spot
))
20471 if (EQ (XCAR (hot_spot
), Qrect
))
20473 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
20474 Lisp_Object rect
= XCDR (hot_spot
);
20478 if (!CONSP (XCAR (rect
)))
20480 if (!CONSP (XCDR (rect
)))
20482 if (!(tem
= XCAR (XCAR (rect
)), INTEGERP (tem
) && x
>= XINT (tem
)))
20484 if (!(tem
= XCDR (XCAR (rect
)), INTEGERP (tem
) && y
>= XINT (tem
)))
20486 if (!(tem
= XCAR (XCDR (rect
)), INTEGERP (tem
) && x
<= XINT (tem
)))
20488 if (!(tem
= XCDR (XCDR (rect
)), INTEGERP (tem
) && y
<= XINT (tem
)))
20492 else if (EQ (XCAR (hot_spot
), Qcircle
))
20494 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
20495 Lisp_Object circ
= XCDR (hot_spot
);
20496 Lisp_Object lr
, lx0
, ly0
;
20498 && CONSP (XCAR (circ
))
20499 && (lr
= XCDR (circ
), INTEGERP (lr
) || FLOATP (lr
))
20500 && (lx0
= XCAR (XCAR (circ
)), INTEGERP (lx0
))
20501 && (ly0
= XCDR (XCAR (circ
)), INTEGERP (ly0
)))
20503 double r
= XFLOATINT (lr
);
20504 double dx
= XINT (lx0
) - x
;
20505 double dy
= XINT (ly0
) - y
;
20506 return (dx
* dx
+ dy
* dy
<= r
* r
);
20509 else if (EQ (XCAR (hot_spot
), Qpoly
))
20511 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
20512 if (VECTORP (XCDR (hot_spot
)))
20514 struct Lisp_Vector
*v
= XVECTOR (XCDR (hot_spot
));
20515 Lisp_Object
*poly
= v
->contents
;
20519 Lisp_Object lx
, ly
;
20522 /* Need an even number of coordinates, and at least 3 edges. */
20523 if (n
< 6 || n
& 1)
20526 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
20527 If count is odd, we are inside polygon. Pixels on edges
20528 may or may not be included depending on actual geometry of the
20530 if ((lx
= poly
[n
-2], !INTEGERP (lx
))
20531 || (ly
= poly
[n
-1], !INTEGERP (lx
)))
20533 x0
= XINT (lx
), y0
= XINT (ly
);
20534 for (i
= 0; i
< n
; i
+= 2)
20536 int x1
= x0
, y1
= y0
;
20537 if ((lx
= poly
[i
], !INTEGERP (lx
))
20538 || (ly
= poly
[i
+1], !INTEGERP (ly
)))
20540 x0
= XINT (lx
), y0
= XINT (ly
);
20542 /* Does this segment cross the X line? */
20550 if (y
> y0
&& y
> y1
)
20552 if (y
< y0
+ ((y1
- y0
) * (x
- x0
)) / (x1
- x0
))
20558 /* If we don't understand the format, pretend we're not in the hot-spot. */
20563 find_hot_spot (map
, x
, y
)
20567 while (CONSP (map
))
20569 if (CONSP (XCAR (map
))
20570 && on_hot_spot_p (XCAR (XCAR (map
)), x
, y
))
20578 DEFUN ("lookup-image-map", Flookup_image_map
, Slookup_image_map
,
20580 doc
: /* Lookup in image map MAP coordinates X and Y.
20581 An image map is an alist where each element has the format (AREA ID PLIST).
20582 An AREA is specified as either a rectangle, a circle, or a polygon:
20583 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
20584 pixel coordinates of the upper left and bottom right corners.
20585 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
20586 and the radius of the circle; r may be a float or integer.
20587 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
20588 vector describes one corner in the polygon.
20589 Returns the alist element for the first matching AREA in MAP. */)
20600 return find_hot_spot (map
, XINT (x
), XINT (y
));
20604 /* Display frame CURSOR, optionally using shape defined by POINTER. */
20606 define_frame_cursor1 (f
, cursor
, pointer
)
20609 Lisp_Object pointer
;
20611 if (!NILP (pointer
))
20613 if (EQ (pointer
, Qarrow
))
20614 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
20615 else if (EQ (pointer
, Qhand
))
20616 cursor
= FRAME_X_OUTPUT (f
)->hand_cursor
;
20617 else if (EQ (pointer
, Qtext
))
20618 cursor
= FRAME_X_OUTPUT (f
)->text_cursor
;
20619 else if (EQ (pointer
, intern ("hdrag")))
20620 cursor
= FRAME_X_OUTPUT (f
)->horizontal_drag_cursor
;
20621 #ifdef HAVE_X_WINDOWS
20622 else if (EQ (pointer
, intern ("vdrag")))
20623 cursor
= FRAME_X_DISPLAY_INFO (f
)->vertical_scroll_bar_cursor
;
20625 else if (EQ (pointer
, intern ("hourglass")))
20626 cursor
= FRAME_X_OUTPUT (f
)->hourglass_cursor
;
20627 else if (EQ (pointer
, Qmodeline
))
20628 cursor
= FRAME_X_OUTPUT (f
)->modeline_cursor
;
20630 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
20633 #ifndef HAVE_CARBON
20634 if (cursor
!= No_Cursor
)
20636 if (bcmp (&cursor
, &No_Cursor
, sizeof (Cursor
)))
20638 rif
->define_frame_cursor (f
, cursor
);
20641 /* Take proper action when mouse has moved to the mode or header line
20642 or marginal area AREA of window W, x-position X and y-position Y.
20643 X is relative to the start of the text display area of W, so the
20644 width of bitmap areas and scroll bars must be subtracted to get a
20645 position relative to the start of the mode line. */
20648 note_mode_line_or_margin_highlight (w
, x
, y
, area
)
20651 enum window_part area
;
20653 struct frame
*f
= XFRAME (w
->frame
);
20654 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
20655 Cursor cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
20656 Lisp_Object pointer
= Qnil
;
20657 int charpos
, dx
, dy
, width
, height
;
20658 Lisp_Object string
, object
= Qnil
;
20659 Lisp_Object pos
, help
;
20661 if (area
== ON_MODE_LINE
|| area
== ON_HEADER_LINE
)
20662 string
= mode_line_string (w
, area
, &x
, &y
, &charpos
,
20663 &object
, &dx
, &dy
, &width
, &height
);
20666 x
-= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w
);
20667 string
= marginal_area_string (w
, area
, &x
, &y
, &charpos
,
20668 &object
, &dx
, &dy
, &width
, &height
);
20673 if (IMAGEP (object
))
20675 Lisp_Object image_map
, hotspot
;
20676 if ((image_map
= Fplist_get (XCDR (object
), QCmap
),
20678 && (hotspot
= find_hot_spot (image_map
, dx
, dy
),
20680 && (hotspot
= XCDR (hotspot
), CONSP (hotspot
)))
20682 Lisp_Object area_id
, plist
;
20684 area_id
= XCAR (hotspot
);
20685 /* Could check AREA_ID to see if we enter/leave this hot-spot.
20686 If so, we could look for mouse-enter, mouse-leave
20687 properties in PLIST (and do something...). */
20688 if ((plist
= XCDR (hotspot
), CONSP (plist
)))
20690 pointer
= Fplist_get (plist
, Qpointer
);
20691 if (NILP (pointer
))
20693 help
= Fplist_get (plist
, Qhelp_echo
);
20696 help_echo_string
= help
;
20697 /* Is this correct? ++kfs */
20698 XSETWINDOW (help_echo_window
, w
);
20699 help_echo_object
= w
->buffer
;
20700 help_echo_pos
= charpos
;
20703 if (NILP (pointer
))
20704 pointer
= Fplist_get (XCDR (object
), QCpointer
);
20708 if (STRINGP (string
))
20710 pos
= make_number (charpos
);
20711 /* If we're on a string with `help-echo' text property, arrange
20712 for the help to be displayed. This is done by setting the
20713 global variable help_echo_string to the help string. */
20714 help
= Fget_text_property (pos
, Qhelp_echo
, string
);
20717 help_echo_string
= help
;
20718 XSETWINDOW (help_echo_window
, w
);
20719 help_echo_object
= string
;
20720 help_echo_pos
= charpos
;
20723 if (NILP (pointer
))
20724 pointer
= Fget_text_property (pos
, Qpointer
, string
);
20726 /* Change the mouse pointer according to what is under X/Y. */
20727 if (NILP (pointer
) && ((area
== ON_MODE_LINE
) || (area
== ON_HEADER_LINE
)))
20730 map
= Fget_text_property (pos
, Qlocal_map
, string
);
20731 if (!KEYMAPP (map
))
20732 map
= Fget_text_property (pos
, Qkeymap
, string
);
20733 if (!KEYMAPP (map
))
20734 cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
20738 define_frame_cursor1 (f
, cursor
, pointer
);
20743 Take proper action when the mouse has moved to position X, Y on
20744 frame F as regards highlighting characters that have mouse-face
20745 properties. Also de-highlighting chars where the mouse was before.
20746 X and Y can be negative or out of range. */
20749 note_mouse_highlight (f
, x
, y
)
20753 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
20754 enum window_part part
;
20755 Lisp_Object window
;
20757 Cursor cursor
= No_Cursor
;
20758 Lisp_Object pointer
= Qnil
; /* Takes precedence over cursor! */
20761 /* When a menu is active, don't highlight because this looks odd. */
20762 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
20763 if (popup_activated ())
20767 if (NILP (Vmouse_highlight
)
20768 || !f
->glyphs_initialized_p
)
20771 dpyinfo
->mouse_face_mouse_x
= x
;
20772 dpyinfo
->mouse_face_mouse_y
= y
;
20773 dpyinfo
->mouse_face_mouse_frame
= f
;
20775 if (dpyinfo
->mouse_face_defer
)
20778 if (gc_in_progress
)
20780 dpyinfo
->mouse_face_deferred_gc
= 1;
20784 /* Which window is that in? */
20785 window
= window_from_coordinates (f
, x
, y
, &part
, 0, 0, 1);
20787 /* If we were displaying active text in another window, clear that. */
20788 if (! EQ (window
, dpyinfo
->mouse_face_window
))
20789 clear_mouse_face (dpyinfo
);
20791 /* Not on a window -> return. */
20792 if (!WINDOWP (window
))
20795 /* Reset help_echo_string. It will get recomputed below. */
20796 help_echo_string
= Qnil
;
20798 /* Convert to window-relative pixel coordinates. */
20799 w
= XWINDOW (window
);
20800 frame_to_window_pixel_xy (w
, &x
, &y
);
20802 /* Handle tool-bar window differently since it doesn't display a
20804 if (EQ (window
, f
->tool_bar_window
))
20806 note_tool_bar_highlight (f
, x
, y
);
20810 /* Mouse is on the mode, header line or margin? */
20811 if (part
== ON_MODE_LINE
|| part
== ON_HEADER_LINE
20812 || part
== ON_LEFT_MARGIN
|| part
== ON_RIGHT_MARGIN
)
20814 note_mode_line_or_margin_highlight (w
, x
, y
, part
);
20818 if (part
== ON_VERTICAL_BORDER
)
20819 cursor
= FRAME_X_OUTPUT (f
)->horizontal_drag_cursor
;
20820 else if (part
== ON_LEFT_FRINGE
|| part
== ON_RIGHT_FRINGE
)
20821 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
20823 cursor
= FRAME_X_OUTPUT (f
)->text_cursor
;
20825 /* Are we in a window whose display is up to date?
20826 And verify the buffer's text has not changed. */
20827 b
= XBUFFER (w
->buffer
);
20828 if (part
== ON_TEXT
20829 && EQ (w
->window_end_valid
, w
->buffer
)
20830 && XFASTINT (w
->last_modified
) == BUF_MODIFF (b
)
20831 && XFASTINT (w
->last_overlay_modified
) == BUF_OVERLAY_MODIFF (b
))
20833 int hpos
, vpos
, pos
, i
, dx
, dy
, area
;
20834 struct glyph
*glyph
;
20835 Lisp_Object object
;
20836 Lisp_Object mouse_face
= Qnil
, overlay
= Qnil
, position
;
20837 Lisp_Object
*overlay_vec
= NULL
;
20839 struct buffer
*obuf
;
20840 int obegv
, ozv
, same_region
;
20842 /* Find the glyph under X/Y. */
20843 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &dx
, &dy
, &area
);
20845 /* Look for :pointer property on image. */
20846 if (glyph
!= NULL
&& glyph
->type
== IMAGE_GLYPH
)
20848 struct image
*img
= IMAGE_FROM_ID (f
, glyph
->u
.img_id
);
20849 if (img
!= NULL
&& IMAGEP (img
->spec
))
20851 Lisp_Object image_map
, hotspot
;
20852 if ((image_map
= Fplist_get (XCDR (img
->spec
), QCmap
),
20854 && (hotspot
= find_hot_spot (image_map
,
20855 glyph
->slice
.x
+ dx
,
20856 glyph
->slice
.y
+ dy
),
20858 && (hotspot
= XCDR (hotspot
), CONSP (hotspot
)))
20860 Lisp_Object area_id
, plist
;
20862 area_id
= XCAR (hotspot
);
20863 /* Could check AREA_ID to see if we enter/leave this hot-spot.
20864 If so, we could look for mouse-enter, mouse-leave
20865 properties in PLIST (and do something...). */
20866 if ((plist
= XCDR (hotspot
), CONSP (plist
)))
20868 pointer
= Fplist_get (plist
, Qpointer
);
20869 if (NILP (pointer
))
20871 help_echo_string
= Fplist_get (plist
, Qhelp_echo
);
20872 if (!NILP (help_echo_string
))
20874 help_echo_window
= window
;
20875 help_echo_object
= glyph
->object
;
20876 help_echo_pos
= glyph
->charpos
;
20880 if (NILP (pointer
))
20881 pointer
= Fplist_get (XCDR (img
->spec
), QCpointer
);
20885 /* Clear mouse face if X/Y not over text. */
20887 || area
!= TEXT_AREA
20888 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
)
20890 if (clear_mouse_face (dpyinfo
))
20891 cursor
= No_Cursor
;
20892 if (NILP (pointer
))
20894 if (area
!= TEXT_AREA
)
20895 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
20897 pointer
= Vvoid_text_area_pointer
;
20902 pos
= glyph
->charpos
;
20903 object
= glyph
->object
;
20904 if (!STRINGP (object
) && !BUFFERP (object
))
20907 /* If we get an out-of-range value, return now; avoid an error. */
20908 if (BUFFERP (object
) && pos
> BUF_Z (b
))
20911 /* Make the window's buffer temporarily current for
20912 overlays_at and compute_char_face. */
20913 obuf
= current_buffer
;
20914 current_buffer
= b
;
20920 /* Is this char mouse-active or does it have help-echo? */
20921 position
= make_number (pos
);
20923 if (BUFFERP (object
))
20925 /* Put all the overlays we want in a vector in overlay_vec. */
20926 GET_OVERLAYS_AT (pos
, overlay_vec
, noverlays
, NULL
, 0);
20927 /* Sort overlays into increasing priority order. */
20928 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
20933 same_region
= (EQ (window
, dpyinfo
->mouse_face_window
)
20934 && vpos
>= dpyinfo
->mouse_face_beg_row
20935 && vpos
<= dpyinfo
->mouse_face_end_row
20936 && (vpos
> dpyinfo
->mouse_face_beg_row
20937 || hpos
>= dpyinfo
->mouse_face_beg_col
)
20938 && (vpos
< dpyinfo
->mouse_face_end_row
20939 || hpos
< dpyinfo
->mouse_face_end_col
20940 || dpyinfo
->mouse_face_past_end
));
20943 cursor
= No_Cursor
;
20945 /* Check mouse-face highlighting. */
20947 /* If there exists an overlay with mouse-face overlapping
20948 the one we are currently highlighting, we have to
20949 check if we enter the overlapping overlay, and then
20950 highlight only that. */
20951 || (OVERLAYP (dpyinfo
->mouse_face_overlay
)
20952 && mouse_face_overlay_overlaps (dpyinfo
->mouse_face_overlay
)))
20954 /* Find the highest priority overlay that has a mouse-face
20957 for (i
= noverlays
- 1; i
>= 0 && NILP (overlay
); --i
)
20959 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
20960 if (!NILP (mouse_face
))
20961 overlay
= overlay_vec
[i
];
20964 /* If we're actually highlighting the same overlay as
20965 before, there's no need to do that again. */
20966 if (!NILP (overlay
)
20967 && EQ (overlay
, dpyinfo
->mouse_face_overlay
))
20968 goto check_help_echo
;
20970 dpyinfo
->mouse_face_overlay
= overlay
;
20972 /* Clear the display of the old active region, if any. */
20973 if (clear_mouse_face (dpyinfo
))
20974 cursor
= No_Cursor
;
20976 /* If no overlay applies, get a text property. */
20977 if (NILP (overlay
))
20978 mouse_face
= Fget_text_property (position
, Qmouse_face
, object
);
20980 /* Handle the overlay case. */
20981 if (!NILP (overlay
))
20983 /* Find the range of text around this char that
20984 should be active. */
20985 Lisp_Object before
, after
;
20988 before
= Foverlay_start (overlay
);
20989 after
= Foverlay_end (overlay
);
20990 /* Record this as the current active region. */
20991 fast_find_position (w
, XFASTINT (before
),
20992 &dpyinfo
->mouse_face_beg_col
,
20993 &dpyinfo
->mouse_face_beg_row
,
20994 &dpyinfo
->mouse_face_beg_x
,
20995 &dpyinfo
->mouse_face_beg_y
, Qnil
);
20997 dpyinfo
->mouse_face_past_end
20998 = !fast_find_position (w
, XFASTINT (after
),
20999 &dpyinfo
->mouse_face_end_col
,
21000 &dpyinfo
->mouse_face_end_row
,
21001 &dpyinfo
->mouse_face_end_x
,
21002 &dpyinfo
->mouse_face_end_y
, Qnil
);
21003 dpyinfo
->mouse_face_window
= window
;
21005 dpyinfo
->mouse_face_face_id
21006 = face_at_buffer_position (w
, pos
, 0, 0,
21008 !dpyinfo
->mouse_face_hidden
);
21010 /* Display it as active. */
21011 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
21012 cursor
= No_Cursor
;
21014 /* Handle the text property case. */
21015 else if (!NILP (mouse_face
) && BUFFERP (object
))
21017 /* Find the range of text around this char that
21018 should be active. */
21019 Lisp_Object before
, after
, beginning
, end
;
21022 beginning
= Fmarker_position (w
->start
);
21023 end
= make_number (BUF_Z (XBUFFER (object
))
21024 - XFASTINT (w
->window_end_pos
));
21026 = Fprevious_single_property_change (make_number (pos
+ 1),
21028 object
, beginning
);
21030 = Fnext_single_property_change (position
, Qmouse_face
,
21033 /* Record this as the current active region. */
21034 fast_find_position (w
, XFASTINT (before
),
21035 &dpyinfo
->mouse_face_beg_col
,
21036 &dpyinfo
->mouse_face_beg_row
,
21037 &dpyinfo
->mouse_face_beg_x
,
21038 &dpyinfo
->mouse_face_beg_y
, Qnil
);
21039 dpyinfo
->mouse_face_past_end
21040 = !fast_find_position (w
, XFASTINT (after
),
21041 &dpyinfo
->mouse_face_end_col
,
21042 &dpyinfo
->mouse_face_end_row
,
21043 &dpyinfo
->mouse_face_end_x
,
21044 &dpyinfo
->mouse_face_end_y
, Qnil
);
21045 dpyinfo
->mouse_face_window
= window
;
21047 if (BUFFERP (object
))
21048 dpyinfo
->mouse_face_face_id
21049 = face_at_buffer_position (w
, pos
, 0, 0,
21051 !dpyinfo
->mouse_face_hidden
);
21053 /* Display it as active. */
21054 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
21055 cursor
= No_Cursor
;
21057 else if (!NILP (mouse_face
) && STRINGP (object
))
21062 b
= Fprevious_single_property_change (make_number (pos
+ 1),
21065 e
= Fnext_single_property_change (position
, Qmouse_face
,
21068 b
= make_number (0);
21070 e
= make_number (SCHARS (object
) - 1);
21071 fast_find_string_pos (w
, XINT (b
), object
,
21072 &dpyinfo
->mouse_face_beg_col
,
21073 &dpyinfo
->mouse_face_beg_row
,
21074 &dpyinfo
->mouse_face_beg_x
,
21075 &dpyinfo
->mouse_face_beg_y
, 0);
21076 fast_find_string_pos (w
, XINT (e
), object
,
21077 &dpyinfo
->mouse_face_end_col
,
21078 &dpyinfo
->mouse_face_end_row
,
21079 &dpyinfo
->mouse_face_end_x
,
21080 &dpyinfo
->mouse_face_end_y
, 1);
21081 dpyinfo
->mouse_face_past_end
= 0;
21082 dpyinfo
->mouse_face_window
= window
;
21083 dpyinfo
->mouse_face_face_id
21084 = face_at_string_position (w
, object
, pos
, 0, 0, 0, &ignore
,
21085 glyph
->face_id
, 1);
21086 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
21087 cursor
= No_Cursor
;
21089 else if (STRINGP (object
) && NILP (mouse_face
))
21091 /* A string which doesn't have mouse-face, but
21092 the text ``under'' it might have. */
21093 struct glyph_row
*r
= MATRIX_ROW (w
->current_matrix
, vpos
);
21094 int start
= MATRIX_ROW_START_CHARPOS (r
);
21096 pos
= string_buffer_position (w
, object
, start
);
21098 mouse_face
= get_char_property_and_overlay (make_number (pos
),
21102 if (!NILP (mouse_face
) && !NILP (overlay
))
21104 Lisp_Object before
= Foverlay_start (overlay
);
21105 Lisp_Object after
= Foverlay_end (overlay
);
21108 /* Note that we might not be able to find position
21109 BEFORE in the glyph matrix if the overlay is
21110 entirely covered by a `display' property. In
21111 this case, we overshoot. So let's stop in
21112 the glyph matrix before glyphs for OBJECT. */
21113 fast_find_position (w
, XFASTINT (before
),
21114 &dpyinfo
->mouse_face_beg_col
,
21115 &dpyinfo
->mouse_face_beg_row
,
21116 &dpyinfo
->mouse_face_beg_x
,
21117 &dpyinfo
->mouse_face_beg_y
,
21120 dpyinfo
->mouse_face_past_end
21121 = !fast_find_position (w
, XFASTINT (after
),
21122 &dpyinfo
->mouse_face_end_col
,
21123 &dpyinfo
->mouse_face_end_row
,
21124 &dpyinfo
->mouse_face_end_x
,
21125 &dpyinfo
->mouse_face_end_y
,
21127 dpyinfo
->mouse_face_window
= window
;
21128 dpyinfo
->mouse_face_face_id
21129 = face_at_buffer_position (w
, pos
, 0, 0,
21131 !dpyinfo
->mouse_face_hidden
);
21133 /* Display it as active. */
21134 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
21135 cursor
= No_Cursor
;
21142 /* Look for a `help-echo' property. */
21143 if (NILP (help_echo_string
)) {
21144 Lisp_Object help
, overlay
;
21146 /* Check overlays first. */
21147 help
= overlay
= Qnil
;
21148 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
21150 overlay
= overlay_vec
[i
];
21151 help
= Foverlay_get (overlay
, Qhelp_echo
);
21156 help_echo_string
= help
;
21157 help_echo_window
= window
;
21158 help_echo_object
= overlay
;
21159 help_echo_pos
= pos
;
21163 Lisp_Object object
= glyph
->object
;
21164 int charpos
= glyph
->charpos
;
21166 /* Try text properties. */
21167 if (STRINGP (object
)
21169 && charpos
< SCHARS (object
))
21171 help
= Fget_text_property (make_number (charpos
),
21172 Qhelp_echo
, object
);
21175 /* If the string itself doesn't specify a help-echo,
21176 see if the buffer text ``under'' it does. */
21177 struct glyph_row
*r
21178 = MATRIX_ROW (w
->current_matrix
, vpos
);
21179 int start
= MATRIX_ROW_START_CHARPOS (r
);
21180 int pos
= string_buffer_position (w
, object
, start
);
21183 help
= Fget_char_property (make_number (pos
),
21184 Qhelp_echo
, w
->buffer
);
21188 object
= w
->buffer
;
21193 else if (BUFFERP (object
)
21196 help
= Fget_text_property (make_number (charpos
), Qhelp_echo
,
21201 help_echo_string
= help
;
21202 help_echo_window
= window
;
21203 help_echo_object
= object
;
21204 help_echo_pos
= charpos
;
21209 /* Look for a `pointer' property. */
21210 if (NILP (pointer
))
21212 /* Check overlays first. */
21213 for (i
= noverlays
- 1; i
>= 0 && NILP (pointer
); --i
)
21214 pointer
= Foverlay_get (overlay_vec
[i
], Qpointer
);
21216 if (NILP (pointer
))
21218 Lisp_Object object
= glyph
->object
;
21219 int charpos
= glyph
->charpos
;
21221 /* Try text properties. */
21222 if (STRINGP (object
)
21224 && charpos
< SCHARS (object
))
21226 pointer
= Fget_text_property (make_number (charpos
),
21228 if (NILP (pointer
))
21230 /* If the string itself doesn't specify a pointer,
21231 see if the buffer text ``under'' it does. */
21232 struct glyph_row
*r
21233 = MATRIX_ROW (w
->current_matrix
, vpos
);
21234 int start
= MATRIX_ROW_START_CHARPOS (r
);
21235 int pos
= string_buffer_position (w
, object
, start
);
21237 pointer
= Fget_char_property (make_number (pos
),
21238 Qpointer
, w
->buffer
);
21241 else if (BUFFERP (object
)
21244 pointer
= Fget_text_property (make_number (charpos
),
21251 current_buffer
= obuf
;
21256 define_frame_cursor1 (f
, cursor
, pointer
);
21261 Clear any mouse-face on window W. This function is part of the
21262 redisplay interface, and is called from try_window_id and similar
21263 functions to ensure the mouse-highlight is off. */
21266 x_clear_window_mouse_face (w
)
21269 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (XFRAME (w
->frame
));
21270 Lisp_Object window
;
21273 XSETWINDOW (window
, w
);
21274 if (EQ (window
, dpyinfo
->mouse_face_window
))
21275 clear_mouse_face (dpyinfo
);
21281 Just discard the mouse face information for frame F, if any.
21282 This is used when the size of F is changed. */
21285 cancel_mouse_face (f
)
21288 Lisp_Object window
;
21289 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
21291 window
= dpyinfo
->mouse_face_window
;
21292 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
21294 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
21295 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
21296 dpyinfo
->mouse_face_window
= Qnil
;
21301 #endif /* HAVE_WINDOW_SYSTEM */
21304 /***********************************************************************
21306 ***********************************************************************/
21308 #ifdef HAVE_WINDOW_SYSTEM
21310 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
21311 which intersects rectangle R. R is in window-relative coordinates. */
21314 expose_area (w
, row
, r
, area
)
21316 struct glyph_row
*row
;
21318 enum glyph_row_area area
;
21320 struct glyph
*first
= row
->glyphs
[area
];
21321 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
21322 struct glyph
*last
;
21323 int first_x
, start_x
, x
;
21325 if (area
== TEXT_AREA
&& row
->fill_line_p
)
21326 /* If row extends face to end of line write the whole line. */
21327 draw_glyphs (w
, 0, row
, area
,
21328 0, row
->used
[area
],
21329 DRAW_NORMAL_TEXT
, 0);
21332 /* Set START_X to the window-relative start position for drawing glyphs of
21333 AREA. The first glyph of the text area can be partially visible.
21334 The first glyphs of other areas cannot. */
21335 start_x
= window_box_left_offset (w
, area
);
21337 if (area
== TEXT_AREA
)
21340 /* Find the first glyph that must be redrawn. */
21342 && x
+ first
->pixel_width
< r
->x
)
21344 x
+= first
->pixel_width
;
21348 /* Find the last one. */
21352 && x
< r
->x
+ r
->width
)
21354 x
+= last
->pixel_width
;
21360 draw_glyphs (w
, first_x
- start_x
, row
, area
,
21361 first
- row
->glyphs
[area
], last
- row
->glyphs
[area
],
21362 DRAW_NORMAL_TEXT
, 0);
21367 /* Redraw the parts of the glyph row ROW on window W intersecting
21368 rectangle R. R is in window-relative coordinates. Value is
21369 non-zero if mouse-face was overwritten. */
21372 expose_line (w
, row
, r
)
21374 struct glyph_row
*row
;
21377 xassert (row
->enabled_p
);
21379 if (row
->mode_line_p
|| w
->pseudo_window_p
)
21380 draw_glyphs (w
, 0, row
, TEXT_AREA
,
21381 0, row
->used
[TEXT_AREA
],
21382 DRAW_NORMAL_TEXT
, 0);
21385 if (row
->used
[LEFT_MARGIN_AREA
])
21386 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
21387 if (row
->used
[TEXT_AREA
])
21388 expose_area (w
, row
, r
, TEXT_AREA
);
21389 if (row
->used
[RIGHT_MARGIN_AREA
])
21390 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
21391 draw_row_fringe_bitmaps (w
, row
);
21394 return row
->mouse_face_p
;
21398 /* Redraw those parts of glyphs rows during expose event handling that
21399 overlap other rows. Redrawing of an exposed line writes over parts
21400 of lines overlapping that exposed line; this function fixes that.
21402 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
21403 row in W's current matrix that is exposed and overlaps other rows.
21404 LAST_OVERLAPPING_ROW is the last such row. */
21407 expose_overlaps (w
, first_overlapping_row
, last_overlapping_row
)
21409 struct glyph_row
*first_overlapping_row
;
21410 struct glyph_row
*last_overlapping_row
;
21412 struct glyph_row
*row
;
21414 for (row
= first_overlapping_row
; row
<= last_overlapping_row
; ++row
)
21415 if (row
->overlapping_p
)
21417 xassert (row
->enabled_p
&& !row
->mode_line_p
);
21419 if (row
->used
[LEFT_MARGIN_AREA
])
21420 x_fix_overlapping_area (w
, row
, LEFT_MARGIN_AREA
);
21422 if (row
->used
[TEXT_AREA
])
21423 x_fix_overlapping_area (w
, row
, TEXT_AREA
);
21425 if (row
->used
[RIGHT_MARGIN_AREA
])
21426 x_fix_overlapping_area (w
, row
, RIGHT_MARGIN_AREA
);
21431 /* Return non-zero if W's cursor intersects rectangle R. */
21434 phys_cursor_in_rect_p (w
, r
)
21438 XRectangle cr
, result
;
21439 struct glyph
*cursor_glyph
;
21441 cursor_glyph
= get_phys_cursor_glyph (w
);
21444 /* r is relative to W's box, but w->phys_cursor.x is relative
21445 to left edge of W's TEXT area. Adjust it. */
21446 cr
.x
= window_box_left_offset (w
, TEXT_AREA
) + w
->phys_cursor
.x
;
21447 cr
.y
= w
->phys_cursor
.y
;
21448 cr
.width
= cursor_glyph
->pixel_width
;
21449 cr
.height
= w
->phys_cursor_height
;
21450 /* ++KFS: W32 version used W32-specific IntersectRect here, but
21451 I assume the effect is the same -- and this is portable. */
21452 return x_intersect_rectangles (&cr
, r
, &result
);
21460 Draw a vertical window border to the right of window W if W doesn't
21461 have vertical scroll bars. */
21464 x_draw_vertical_border (w
)
21467 /* We could do better, if we knew what type of scroll-bar the adjacent
21468 windows (on either side) have... But we don't :-(
21469 However, I think this works ok. ++KFS 2003-04-25 */
21471 /* Redraw borders between horizontally adjacent windows. Don't
21472 do it for frames with vertical scroll bars because either the
21473 right scroll bar of a window, or the left scroll bar of its
21474 neighbor will suffice as a border. */
21475 if (!WINDOW_RIGHTMOST_P (w
)
21476 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w
))
21478 int x0
, x1
, y0
, y1
;
21480 window_box_edges (w
, -1, &x0
, &y0
, &x1
, &y1
);
21483 rif
->draw_vertical_window_border (w
, x1
, y0
, y1
);
21485 else if (!WINDOW_LEFTMOST_P (w
)
21486 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w
))
21488 int x0
, x1
, y0
, y1
;
21490 window_box_edges (w
, -1, &x0
, &y0
, &x1
, &y1
);
21493 rif
->draw_vertical_window_border (w
, x0
, y0
, y1
);
21498 /* Redraw the part of window W intersection rectangle FR. Pixel
21499 coordinates in FR are frame-relative. Call this function with
21500 input blocked. Value is non-zero if the exposure overwrites
21504 expose_window (w
, fr
)
21508 struct frame
*f
= XFRAME (w
->frame
);
21510 int mouse_face_overwritten_p
= 0;
21512 /* If window is not yet fully initialized, do nothing. This can
21513 happen when toolkit scroll bars are used and a window is split.
21514 Reconfiguring the scroll bar will generate an expose for a newly
21516 if (w
->current_matrix
== NULL
)
21519 /* When we're currently updating the window, display and current
21520 matrix usually don't agree. Arrange for a thorough display
21522 if (w
== updated_window
)
21524 SET_FRAME_GARBAGED (f
);
21528 /* Frame-relative pixel rectangle of W. */
21529 wr
.x
= WINDOW_LEFT_EDGE_X (w
);
21530 wr
.y
= WINDOW_TOP_EDGE_Y (w
);
21531 wr
.width
= WINDOW_TOTAL_WIDTH (w
);
21532 wr
.height
= WINDOW_TOTAL_HEIGHT (w
);
21534 if (x_intersect_rectangles (fr
, &wr
, &r
))
21536 int yb
= window_text_bottom_y (w
);
21537 struct glyph_row
*row
;
21538 int cursor_cleared_p
;
21539 struct glyph_row
*first_overlapping_row
, *last_overlapping_row
;
21541 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
21542 r
.x
, r
.y
, r
.width
, r
.height
));
21544 /* Convert to window coordinates. */
21545 r
.x
-= WINDOW_LEFT_EDGE_X (w
);
21546 r
.y
-= WINDOW_TOP_EDGE_Y (w
);
21548 /* Turn off the cursor. */
21549 if (!w
->pseudo_window_p
21550 && phys_cursor_in_rect_p (w
, &r
))
21552 x_clear_cursor (w
);
21553 cursor_cleared_p
= 1;
21556 cursor_cleared_p
= 0;
21558 /* Update lines intersecting rectangle R. */
21559 first_overlapping_row
= last_overlapping_row
= NULL
;
21560 for (row
= w
->current_matrix
->rows
;
21565 int y1
= MATRIX_ROW_BOTTOM_Y (row
);
21567 if ((y0
>= r
.y
&& y0
< r
.y
+ r
.height
)
21568 || (y1
> r
.y
&& y1
< r
.y
+ r
.height
)
21569 || (r
.y
>= y0
&& r
.y
< y1
)
21570 || (r
.y
+ r
.height
> y0
&& r
.y
+ r
.height
< y1
))
21572 if (row
->overlapping_p
)
21574 if (first_overlapping_row
== NULL
)
21575 first_overlapping_row
= row
;
21576 last_overlapping_row
= row
;
21579 if (expose_line (w
, row
, &r
))
21580 mouse_face_overwritten_p
= 1;
21587 /* Display the mode line if there is one. */
21588 if (WINDOW_WANTS_MODELINE_P (w
)
21589 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
21591 && row
->y
< r
.y
+ r
.height
)
21593 if (expose_line (w
, row
, &r
))
21594 mouse_face_overwritten_p
= 1;
21597 if (!w
->pseudo_window_p
)
21599 /* Fix the display of overlapping rows. */
21600 if (first_overlapping_row
)
21601 expose_overlaps (w
, first_overlapping_row
, last_overlapping_row
);
21603 /* Draw border between windows. */
21604 x_draw_vertical_border (w
);
21606 /* Turn the cursor on again. */
21607 if (cursor_cleared_p
)
21608 update_window_cursor (w
, 1);
21613 /* Display scroll bar for this window. */
21614 if (!NILP (w
->vertical_scroll_bar
))
21617 If this doesn't work here (maybe some header files are missing),
21618 make a function in macterm.c and call it to do the job! */
21620 = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (w
->vertical_scroll_bar
));
21626 return mouse_face_overwritten_p
;
21631 /* Redraw (parts) of all windows in the window tree rooted at W that
21632 intersect R. R contains frame pixel coordinates. Value is
21633 non-zero if the exposure overwrites mouse-face. */
21636 expose_window_tree (w
, r
)
21640 struct frame
*f
= XFRAME (w
->frame
);
21641 int mouse_face_overwritten_p
= 0;
21643 while (w
&& !FRAME_GARBAGED_P (f
))
21645 if (!NILP (w
->hchild
))
21646 mouse_face_overwritten_p
21647 |= expose_window_tree (XWINDOW (w
->hchild
), r
);
21648 else if (!NILP (w
->vchild
))
21649 mouse_face_overwritten_p
21650 |= expose_window_tree (XWINDOW (w
->vchild
), r
);
21652 mouse_face_overwritten_p
|= expose_window (w
, r
);
21654 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
21657 return mouse_face_overwritten_p
;
21662 Redisplay an exposed area of frame F. X and Y are the upper-left
21663 corner of the exposed rectangle. W and H are width and height of
21664 the exposed area. All are pixel values. W or H zero means redraw
21665 the entire frame. */
21668 expose_frame (f
, x
, y
, w
, h
)
21673 int mouse_face_overwritten_p
= 0;
21675 TRACE ((stderr
, "expose_frame "));
21677 /* No need to redraw if frame will be redrawn soon. */
21678 if (FRAME_GARBAGED_P (f
))
21680 TRACE ((stderr
, " garbaged\n"));
21685 /* MAC_TODO: this is a kludge, but if scroll bars are not activated
21686 or deactivated here, for unknown reasons, activated scroll bars
21687 are shown in deactivated frames in some instances. */
21688 if (f
== FRAME_MAC_DISPLAY_INFO (f
)->x_focus_frame
)
21689 activate_scroll_bars (f
);
21691 deactivate_scroll_bars (f
);
21694 /* If basic faces haven't been realized yet, there is no point in
21695 trying to redraw anything. This can happen when we get an expose
21696 event while Emacs is starting, e.g. by moving another window. */
21697 if (FRAME_FACE_CACHE (f
) == NULL
21698 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
21700 TRACE ((stderr
, " no faces\n"));
21704 if (w
== 0 || h
== 0)
21707 r
.width
= FRAME_COLUMN_WIDTH (f
) * FRAME_COLS (f
);
21708 r
.height
= FRAME_LINE_HEIGHT (f
) * FRAME_LINES (f
);
21718 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.x
, r
.y
, r
.width
, r
.height
));
21719 mouse_face_overwritten_p
= expose_window_tree (XWINDOW (f
->root_window
), &r
);
21721 if (WINDOWP (f
->tool_bar_window
))
21722 mouse_face_overwritten_p
21723 |= expose_window (XWINDOW (f
->tool_bar_window
), &r
);
21725 #ifdef HAVE_X_WINDOWS
21727 #ifndef USE_X_TOOLKIT
21728 if (WINDOWP (f
->menu_bar_window
))
21729 mouse_face_overwritten_p
21730 |= expose_window (XWINDOW (f
->menu_bar_window
), &r
);
21731 #endif /* not USE_X_TOOLKIT */
21735 /* Some window managers support a focus-follows-mouse style with
21736 delayed raising of frames. Imagine a partially obscured frame,
21737 and moving the mouse into partially obscured mouse-face on that
21738 frame. The visible part of the mouse-face will be highlighted,
21739 then the WM raises the obscured frame. With at least one WM, KDE
21740 2.1, Emacs is not getting any event for the raising of the frame
21741 (even tried with SubstructureRedirectMask), only Expose events.
21742 These expose events will draw text normally, i.e. not
21743 highlighted. Which means we must redo the highlight here.
21744 Subsume it under ``we love X''. --gerd 2001-08-15 */
21745 /* Included in Windows version because Windows most likely does not
21746 do the right thing if any third party tool offers
21747 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
21748 if (mouse_face_overwritten_p
&& !FRAME_GARBAGED_P (f
))
21750 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
21751 if (f
== dpyinfo
->mouse_face_mouse_frame
)
21753 int x
= dpyinfo
->mouse_face_mouse_x
;
21754 int y
= dpyinfo
->mouse_face_mouse_y
;
21755 clear_mouse_face (dpyinfo
);
21756 note_mouse_highlight (f
, x
, y
);
21763 Determine the intersection of two rectangles R1 and R2. Return
21764 the intersection in *RESULT. Value is non-zero if RESULT is not
21768 x_intersect_rectangles (r1
, r2
, result
)
21769 XRectangle
*r1
, *r2
, *result
;
21771 XRectangle
*left
, *right
;
21772 XRectangle
*upper
, *lower
;
21773 int intersection_p
= 0;
21775 /* Rearrange so that R1 is the left-most rectangle. */
21777 left
= r1
, right
= r2
;
21779 left
= r2
, right
= r1
;
21781 /* X0 of the intersection is right.x0, if this is inside R1,
21782 otherwise there is no intersection. */
21783 if (right
->x
<= left
->x
+ left
->width
)
21785 result
->x
= right
->x
;
21787 /* The right end of the intersection is the minimum of the
21788 the right ends of left and right. */
21789 result
->width
= (min (left
->x
+ left
->width
, right
->x
+ right
->width
)
21792 /* Same game for Y. */
21794 upper
= r1
, lower
= r2
;
21796 upper
= r2
, lower
= r1
;
21798 /* The upper end of the intersection is lower.y0, if this is inside
21799 of upper. Otherwise, there is no intersection. */
21800 if (lower
->y
<= upper
->y
+ upper
->height
)
21802 result
->y
= lower
->y
;
21804 /* The lower end of the intersection is the minimum of the lower
21805 ends of upper and lower. */
21806 result
->height
= (min (lower
->y
+ lower
->height
,
21807 upper
->y
+ upper
->height
)
21809 intersection_p
= 1;
21813 return intersection_p
;
21816 #endif /* HAVE_WINDOW_SYSTEM */
21819 /***********************************************************************
21821 ***********************************************************************/
21826 Vwith_echo_area_save_vector
= Qnil
;
21827 staticpro (&Vwith_echo_area_save_vector
);
21829 Vmessage_stack
= Qnil
;
21830 staticpro (&Vmessage_stack
);
21832 Qinhibit_redisplay
= intern ("inhibit-redisplay");
21833 staticpro (&Qinhibit_redisplay
);
21835 message_dolog_marker1
= Fmake_marker ();
21836 staticpro (&message_dolog_marker1
);
21837 message_dolog_marker2
= Fmake_marker ();
21838 staticpro (&message_dolog_marker2
);
21839 message_dolog_marker3
= Fmake_marker ();
21840 staticpro (&message_dolog_marker3
);
21843 defsubr (&Sdump_frame_glyph_matrix
);
21844 defsubr (&Sdump_glyph_matrix
);
21845 defsubr (&Sdump_glyph_row
);
21846 defsubr (&Sdump_tool_bar_row
);
21847 defsubr (&Strace_redisplay
);
21848 defsubr (&Strace_to_stderr
);
21850 #ifdef HAVE_WINDOW_SYSTEM
21851 defsubr (&Stool_bar_lines_needed
);
21852 defsubr (&Slookup_image_map
);
21854 defsubr (&Sformat_mode_line
);
21856 staticpro (&Qmenu_bar_update_hook
);
21857 Qmenu_bar_update_hook
= intern ("menu-bar-update-hook");
21859 staticpro (&Qoverriding_terminal_local_map
);
21860 Qoverriding_terminal_local_map
= intern ("overriding-terminal-local-map");
21862 staticpro (&Qoverriding_local_map
);
21863 Qoverriding_local_map
= intern ("overriding-local-map");
21865 staticpro (&Qwindow_scroll_functions
);
21866 Qwindow_scroll_functions
= intern ("window-scroll-functions");
21868 staticpro (&Qredisplay_end_trigger_functions
);
21869 Qredisplay_end_trigger_functions
= intern ("redisplay-end-trigger-functions");
21871 staticpro (&Qinhibit_point_motion_hooks
);
21872 Qinhibit_point_motion_hooks
= intern ("inhibit-point-motion-hooks");
21874 QCdata
= intern (":data");
21875 staticpro (&QCdata
);
21876 Qdisplay
= intern ("display");
21877 staticpro (&Qdisplay
);
21878 Qspace_width
= intern ("space-width");
21879 staticpro (&Qspace_width
);
21880 Qraise
= intern ("raise");
21881 staticpro (&Qraise
);
21882 Qslice
= intern ("slice");
21883 staticpro (&Qslice
);
21884 Qspace
= intern ("space");
21885 staticpro (&Qspace
);
21886 Qmargin
= intern ("margin");
21887 staticpro (&Qmargin
);
21888 Qpointer
= intern ("pointer");
21889 staticpro (&Qpointer
);
21890 Qleft_margin
= intern ("left-margin");
21891 staticpro (&Qleft_margin
);
21892 Qright_margin
= intern ("right-margin");
21893 staticpro (&Qright_margin
);
21894 Qcenter
= intern ("center");
21895 staticpro (&Qcenter
);
21896 Qline_height
= intern ("line-height");
21897 staticpro (&Qline_height
);
21898 Qtotal
= intern ("total");
21899 staticpro (&Qtotal
);
21900 QCalign_to
= intern (":align-to");
21901 staticpro (&QCalign_to
);
21902 QCrelative_width
= intern (":relative-width");
21903 staticpro (&QCrelative_width
);
21904 QCrelative_height
= intern (":relative-height");
21905 staticpro (&QCrelative_height
);
21906 QCeval
= intern (":eval");
21907 staticpro (&QCeval
);
21908 QCpropertize
= intern (":propertize");
21909 staticpro (&QCpropertize
);
21910 QCfile
= intern (":file");
21911 staticpro (&QCfile
);
21912 Qfontified
= intern ("fontified");
21913 staticpro (&Qfontified
);
21914 Qfontification_functions
= intern ("fontification-functions");
21915 staticpro (&Qfontification_functions
);
21916 Qtrailing_whitespace
= intern ("trailing-whitespace");
21917 staticpro (&Qtrailing_whitespace
);
21918 Qimage
= intern ("image");
21919 staticpro (&Qimage
);
21920 QCmap
= intern (":map");
21921 staticpro (&QCmap
);
21922 QCpointer
= intern (":pointer");
21923 staticpro (&QCpointer
);
21924 Qrect
= intern ("rect");
21925 staticpro (&Qrect
);
21926 Qcircle
= intern ("circle");
21927 staticpro (&Qcircle
);
21928 Qpoly
= intern ("poly");
21929 staticpro (&Qpoly
);
21930 Qmessage_truncate_lines
= intern ("message-truncate-lines");
21931 staticpro (&Qmessage_truncate_lines
);
21932 Qcursor_in_non_selected_windows
= intern ("cursor-in-non-selected-windows");
21933 staticpro (&Qcursor_in_non_selected_windows
);
21934 Qgrow_only
= intern ("grow-only");
21935 staticpro (&Qgrow_only
);
21936 Qinhibit_menubar_update
= intern ("inhibit-menubar-update");
21937 staticpro (&Qinhibit_menubar_update
);
21938 Qinhibit_eval_during_redisplay
= intern ("inhibit-eval-during-redisplay");
21939 staticpro (&Qinhibit_eval_during_redisplay
);
21940 Qposition
= intern ("position");
21941 staticpro (&Qposition
);
21942 Qbuffer_position
= intern ("buffer-position");
21943 staticpro (&Qbuffer_position
);
21944 Qobject
= intern ("object");
21945 staticpro (&Qobject
);
21946 Qbar
= intern ("bar");
21948 Qhbar
= intern ("hbar");
21949 staticpro (&Qhbar
);
21950 Qbox
= intern ("box");
21952 Qhollow
= intern ("hollow");
21953 staticpro (&Qhollow
);
21954 Qhand
= intern ("hand");
21955 staticpro (&Qhand
);
21956 Qarrow
= intern ("arrow");
21957 staticpro (&Qarrow
);
21958 Qtext
= intern ("text");
21959 staticpro (&Qtext
);
21960 Qrisky_local_variable
= intern ("risky-local-variable");
21961 staticpro (&Qrisky_local_variable
);
21962 Qinhibit_free_realized_faces
= intern ("inhibit-free-realized-faces");
21963 staticpro (&Qinhibit_free_realized_faces
);
21965 list_of_error
= Fcons (Fcons (intern ("error"),
21966 Fcons (intern ("void-variable"), Qnil
)),
21968 staticpro (&list_of_error
);
21970 Qlast_arrow_position
= intern ("last-arrow-position");
21971 staticpro (&Qlast_arrow_position
);
21972 Qlast_arrow_string
= intern ("last-arrow-string");
21973 staticpro (&Qlast_arrow_string
);
21975 Qoverlay_arrow_string
= intern ("overlay-arrow-string");
21976 staticpro (&Qoverlay_arrow_string
);
21977 Qoverlay_arrow_bitmap
= intern ("overlay-arrow-bitmap");
21978 staticpro (&Qoverlay_arrow_bitmap
);
21980 echo_buffer
[0] = echo_buffer
[1] = Qnil
;
21981 staticpro (&echo_buffer
[0]);
21982 staticpro (&echo_buffer
[1]);
21984 echo_area_buffer
[0] = echo_area_buffer
[1] = Qnil
;
21985 staticpro (&echo_area_buffer
[0]);
21986 staticpro (&echo_area_buffer
[1]);
21988 Vmessages_buffer_name
= build_string ("*Messages*");
21989 staticpro (&Vmessages_buffer_name
);
21991 mode_line_proptrans_alist
= Qnil
;
21992 staticpro (&mode_line_proptrans_alist
);
21994 mode_line_string_list
= Qnil
;
21995 staticpro (&mode_line_string_list
);
21997 help_echo_string
= Qnil
;
21998 staticpro (&help_echo_string
);
21999 help_echo_object
= Qnil
;
22000 staticpro (&help_echo_object
);
22001 help_echo_window
= Qnil
;
22002 staticpro (&help_echo_window
);
22003 previous_help_echo_string
= Qnil
;
22004 staticpro (&previous_help_echo_string
);
22005 help_echo_pos
= -1;
22007 #ifdef HAVE_WINDOW_SYSTEM
22008 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
22009 doc
: /* *Non-nil means draw block cursor as wide as the glyph under it.
22010 For example, if a block cursor is over a tab, it will be drawn as
22011 wide as that tab on the display. */);
22012 x_stretch_cursor_p
= 0;
22015 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace
,
22016 doc
: /* *Non-nil means highlight trailing whitespace.
22017 The face used for trailing whitespace is `trailing-whitespace'. */);
22018 Vshow_trailing_whitespace
= Qnil
;
22020 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer
,
22021 doc
: /* *The pointer shape to show in void text areas.
22022 Nil means to show the text pointer. Other options are `arrow', `text',
22023 `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
22024 Vvoid_text_area_pointer
= Qarrow
;
22026 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay
,
22027 doc
: /* Non-nil means don't actually do any redisplay.
22028 This is used for internal purposes. */);
22029 Vinhibit_redisplay
= Qnil
;
22031 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string
,
22032 doc
: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
22033 Vglobal_mode_string
= Qnil
;
22035 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position
,
22036 doc
: /* Marker for where to display an arrow on top of the buffer text.
22037 This must be the beginning of a line in order to work.
22038 See also `overlay-arrow-string'. */);
22039 Voverlay_arrow_position
= Qnil
;
22041 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string
,
22042 doc
: /* String to display as an arrow in non-window frames.
22043 See also `overlay-arrow-position'. */);
22044 Voverlay_arrow_string
= Qnil
;
22046 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list
,
22047 doc
: /* List of variables (symbols) which hold markers for overlay arrows.
22048 The symbols on this list are examined during redisplay to determine
22049 where to display overlay arrows. */);
22050 Voverlay_arrow_variable_list
22051 = Fcons (intern ("overlay-arrow-position"), Qnil
);
22053 DEFVAR_INT ("scroll-step", &scroll_step
,
22054 doc
: /* *The number of lines to try scrolling a window by when point moves out.
22055 If that fails to bring point back on frame, point is centered instead.
22056 If this is zero, point is always centered after it moves off frame.
22057 If you want scrolling to always be a line at a time, you should set
22058 `scroll-conservatively' to a large value rather than set this to 1. */);
22060 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively
,
22061 doc
: /* *Scroll up to this many lines, to bring point back on screen.
22062 A value of zero means to scroll the text to center point vertically
22063 in the window. */);
22064 scroll_conservatively
= 0;
22066 DEFVAR_INT ("scroll-margin", &scroll_margin
,
22067 doc
: /* *Number of lines of margin at the top and bottom of a window.
22068 Recenter the window whenever point gets within this many lines
22069 of the top or bottom of the window. */);
22072 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch
,
22073 doc
: /* Pixels per inch on current display.
22074 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
22075 Vdisplay_pixels_per_inch
= make_float (72.0);
22078 DEFVAR_INT ("debug-end-pos", &debug_end_pos
, doc
: /* Don't ask. */);
22081 DEFVAR_BOOL ("truncate-partial-width-windows",
22082 &truncate_partial_width_windows
,
22083 doc
: /* *Non-nil means truncate lines in all windows less than full frame wide. */);
22084 truncate_partial_width_windows
= 1;
22086 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video
,
22087 doc
: /* nil means display the mode-line/header-line/menu-bar in the default face.
22088 Any other value means to use the appropriate face, `mode-line',
22089 `header-line', or `menu' respectively. */);
22090 mode_line_inverse_video
= 1;
22092 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit
,
22093 doc
: /* *Maximum buffer size for which line number should be displayed.
22094 If the buffer is bigger than this, the line number does not appear
22095 in the mode line. A value of nil means no limit. */);
22096 Vline_number_display_limit
= Qnil
;
22098 DEFVAR_INT ("line-number-display-limit-width",
22099 &line_number_display_limit_width
,
22100 doc
: /* *Maximum line width (in characters) for line number display.
22101 If the average length of the lines near point is bigger than this, then the
22102 line number may be omitted from the mode line. */);
22103 line_number_display_limit_width
= 200;
22105 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows
,
22106 doc
: /* *Non-nil means highlight region even in nonselected windows. */);
22107 highlight_nonselected_windows
= 0;
22109 DEFVAR_BOOL ("multiple-frames", &multiple_frames
,
22110 doc
: /* Non-nil if more than one frame is visible on this display.
22111 Minibuffer-only frames don't count, but iconified frames do.
22112 This variable is not guaranteed to be accurate except while processing
22113 `frame-title-format' and `icon-title-format'. */);
22115 DEFVAR_LISP ("frame-title-format", &Vframe_title_format
,
22116 doc
: /* Template for displaying the title bar of visible frames.
22117 \(Assuming the window manager supports this feature.)
22118 This variable has the same structure as `mode-line-format' (which see),
22119 and is used only on frames for which no explicit name has been set
22120 \(see `modify-frame-parameters'). */);
22122 DEFVAR_LISP ("icon-title-format", &Vicon_title_format
,
22123 doc
: /* Template for displaying the title bar of an iconified frame.
22124 \(Assuming the window manager supports this feature.)
22125 This variable has the same structure as `mode-line-format' (which see),
22126 and is used only on frames for which no explicit name has been set
22127 \(see `modify-frame-parameters'). */);
22129 = Vframe_title_format
22130 = Fcons (intern ("multiple-frames"),
22131 Fcons (build_string ("%b"),
22132 Fcons (Fcons (empty_string
,
22133 Fcons (intern ("invocation-name"),
22134 Fcons (build_string ("@"),
22135 Fcons (intern ("system-name"),
22139 DEFVAR_LISP ("message-log-max", &Vmessage_log_max
,
22140 doc
: /* Maximum number of lines to keep in the message log buffer.
22141 If nil, disable message logging. If t, log messages but don't truncate
22142 the buffer when it becomes large. */);
22143 Vmessage_log_max
= make_number (50);
22145 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions
,
22146 doc
: /* Functions called before redisplay, if window sizes have changed.
22147 The value should be a list of functions that take one argument.
22148 Just before redisplay, for each frame, if any of its windows have changed
22149 size since the last redisplay, or have been split or deleted,
22150 all the functions in the list are called, with the frame as argument. */);
22151 Vwindow_size_change_functions
= Qnil
;
22153 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions
,
22154 doc
: /* List of Functions to call before redisplaying a window with scrolling.
22155 Each function is called with two arguments, the window
22156 and its new display-start position. Note that the value of `window-end'
22157 is not valid when these functions are called. */);
22158 Vwindow_scroll_functions
= Qnil
;
22160 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window
,
22161 doc
: /* *Non-nil means autoselect window with mouse pointer. */);
22162 mouse_autoselect_window
= 0;
22164 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p
,
22165 doc
: /* *Non-nil means automatically resize tool-bars.
22166 This increases a tool-bar's height if not all tool-bar items are visible.
22167 It decreases a tool-bar's height when it would display blank lines
22169 auto_resize_tool_bars_p
= 1;
22171 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p
,
22172 doc
: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
22173 auto_raise_tool_bar_buttons_p
= 1;
22175 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin
,
22176 doc
: /* *Margin around tool-bar buttons in pixels.
22177 If an integer, use that for both horizontal and vertical margins.
22178 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
22179 HORZ specifying the horizontal margin, and VERT specifying the
22180 vertical margin. */);
22181 Vtool_bar_button_margin
= make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN
);
22183 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief
,
22184 doc
: /* *Relief thickness of tool-bar buttons. */);
22185 tool_bar_button_relief
= DEFAULT_TOOL_BAR_BUTTON_RELIEF
;
22187 DEFVAR_LISP ("fontification-functions", &Vfontification_functions
,
22188 doc
: /* List of functions to call to fontify regions of text.
22189 Each function is called with one argument POS. Functions must
22190 fontify a region starting at POS in the current buffer, and give
22191 fontified regions the property `fontified'. */);
22192 Vfontification_functions
= Qnil
;
22193 Fmake_variable_buffer_local (Qfontification_functions
);
22195 DEFVAR_BOOL ("unibyte-display-via-language-environment",
22196 &unibyte_display_via_language_environment
,
22197 doc
: /* *Non-nil means display unibyte text according to language environment.
22198 Specifically this means that unibyte non-ASCII characters
22199 are displayed by converting them to the equivalent multibyte characters
22200 according to the current language environment. As a result, they are
22201 displayed according to the current fontset. */);
22202 unibyte_display_via_language_environment
= 0;
22204 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height
,
22205 doc
: /* *Maximum height for resizing mini-windows.
22206 If a float, it specifies a fraction of the mini-window frame's height.
22207 If an integer, it specifies a number of lines. */);
22208 Vmax_mini_window_height
= make_float (0.25);
22210 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows
,
22211 doc
: /* *How to resize mini-windows.
22212 A value of nil means don't automatically resize mini-windows.
22213 A value of t means resize them to fit the text displayed in them.
22214 A value of `grow-only', the default, means let mini-windows grow
22215 only, until their display becomes empty, at which point the windows
22216 go back to their normal size. */);
22217 Vresize_mini_windows
= Qgrow_only
;
22219 DEFVAR_LISP ("cursor-in-non-selected-windows",
22220 &Vcursor_in_non_selected_windows
,
22221 doc
: /* *Cursor type to display in non-selected windows.
22222 t means to use hollow box cursor. See `cursor-type' for other values. */);
22223 Vcursor_in_non_selected_windows
= Qt
;
22225 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist
,
22226 doc
: /* Alist specifying how to blink the cursor off.
22227 Each element has the form (ON-STATE . OFF-STATE). Whenever the
22228 `cursor-type' frame-parameter or variable equals ON-STATE,
22229 comparing using `equal', Emacs uses OFF-STATE to specify
22230 how to blink it off. */);
22231 Vblink_cursor_alist
= Qnil
;
22233 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p
,
22234 doc
: /* *Non-nil means scroll the display automatically to make point visible. */);
22235 automatic_hscrolling_p
= 1;
22237 DEFVAR_INT ("hscroll-margin", &hscroll_margin
,
22238 doc
: /* *How many columns away from the window edge point is allowed to get
22239 before automatic hscrolling will horizontally scroll the window. */);
22240 hscroll_margin
= 5;
22242 DEFVAR_LISP ("hscroll-step", &Vhscroll_step
,
22243 doc
: /* *How many columns to scroll the window when point gets too close to the edge.
22244 When point is less than `automatic-hscroll-margin' columns from the window
22245 edge, automatic hscrolling will scroll the window by the amount of columns
22246 determined by this variable. If its value is a positive integer, scroll that
22247 many columns. If it's a positive floating-point number, it specifies the
22248 fraction of the window's width to scroll. If it's nil or zero, point will be
22249 centered horizontally after the scroll. Any other value, including negative
22250 numbers, are treated as if the value were zero.
22252 Automatic hscrolling always moves point outside the scroll margin, so if
22253 point was more than scroll step columns inside the margin, the window will
22254 scroll more than the value given by the scroll step.
22256 Note that the lower bound for automatic hscrolling specified by `scroll-left'
22257 and `scroll-right' overrides this variable's effect. */);
22258 Vhscroll_step
= make_number (0);
22260 DEFVAR_LISP ("image-types", &Vimage_types
,
22261 doc
: /* List of supported image types.
22262 Each element of the list is a symbol for a supported image type. */);
22263 Vimage_types
= Qnil
;
22265 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines
,
22266 doc
: /* If non-nil, messages are truncated instead of resizing the echo area.
22267 Bind this around calls to `message' to let it take effect. */);
22268 message_truncate_lines
= 0;
22270 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook
,
22271 doc
: /* Normal hook run for clicks on menu bar, before displaying a submenu.
22272 Can be used to update submenus whose contents should vary. */);
22273 Vmenu_bar_update_hook
= Qnil
;
22275 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update
,
22276 doc
: /* Non-nil means don't update menu bars. Internal use only. */);
22277 inhibit_menubar_update
= 0;
22279 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay
,
22280 doc
: /* Non-nil means don't eval Lisp during redisplay. */);
22281 inhibit_eval_during_redisplay
= 0;
22283 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces
,
22284 doc
: /* Non-nil means don't free realized faces. Internal use only. */);
22285 inhibit_free_realized_faces
= 0;
22288 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id
,
22289 doc
: /* Inhibit try_window_id display optimization. */);
22290 inhibit_try_window_id
= 0;
22292 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing
,
22293 doc
: /* Inhibit try_window_reusing display optimization. */);
22294 inhibit_try_window_reusing
= 0;
22296 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement
,
22297 doc
: /* Inhibit try_cursor_movement display optimization. */);
22298 inhibit_try_cursor_movement
= 0;
22299 #endif /* GLYPH_DEBUG */
22303 /* Initialize this module when Emacs starts. */
22308 Lisp_Object root_window
;
22309 struct window
*mini_w
;
22311 current_header_line_height
= current_mode_line_height
= -1;
22313 CHARPOS (this_line_start_pos
) = 0;
22315 mini_w
= XWINDOW (minibuf_window
);
22316 root_window
= FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w
)));
22318 if (!noninteractive
)
22320 struct frame
*f
= XFRAME (WINDOW_FRAME (XWINDOW (root_window
)));
22323 XWINDOW (root_window
)->top_line
= make_number (FRAME_TOP_MARGIN (f
));
22324 set_window_height (root_window
,
22325 FRAME_LINES (f
) - 1 - FRAME_TOP_MARGIN (f
),
22327 mini_w
->top_line
= make_number (FRAME_LINES (f
) - 1);
22328 set_window_height (minibuf_window
, 1, 0);
22330 XWINDOW (root_window
)->total_cols
= make_number (FRAME_COLS (f
));
22331 mini_w
->total_cols
= make_number (FRAME_COLS (f
));
22333 scratch_glyph_row
.glyphs
[TEXT_AREA
] = scratch_glyphs
;
22334 scratch_glyph_row
.glyphs
[TEXT_AREA
+ 1]
22335 = scratch_glyphs
+ MAX_SCRATCH_GLYPHS
;
22337 /* The default ellipsis glyphs `...'. */
22338 for (i
= 0; i
< 3; ++i
)
22339 default_invis_vector
[i
] = make_number ('.');
22343 /* Allocate the buffer for frame titles.
22344 Also used for `format-mode-line'. */
22346 frame_title_buf
= (char *) xmalloc (size
);
22347 frame_title_buf_end
= frame_title_buf
+ size
;
22348 frame_title_ptr
= NULL
;
22351 help_echo_showing_p
= 0;
22355 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
22356 (do not change this comment) */