1 /* Display generation from window structure and buffer text.
2 Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* New redisplay written by Gerd Moellmann <gerd@gnu.org>.
26 Emacs separates the task of updating the display from code
27 modifying global state, e.g. buffer text. This way functions
28 operating on buffers don't also have to be concerned with updating
31 Updating the display is triggered by the Lisp interpreter when it
32 decides it's time to do it. This is done either automatically for
33 you as part of the interpreter's command loop or as the result of
34 calling Lisp functions like `sit-for'. The C function `redisplay'
35 in xdisp.c is the only entry into the inner redisplay code. (Or,
36 let's say almost---see the description of direct update
39 The following diagram shows how redisplay code is invoked. As you
40 can see, Lisp calls redisplay and vice versa. Under window systems
41 like X, some portions of the redisplay code are also called
42 asynchronously during mouse movement or expose events. It is very
43 important that these code parts do NOT use the C library (malloc,
44 free) because many C libraries under Unix are not reentrant. They
45 may also NOT call functions of the Lisp interpreter which could
46 change the interpreter's state. If you don't follow these rules,
47 you will encounter bugs which are very hard to explain.
49 (Direct functions, see below)
50 direct_output_for_insert,
51 direct_forward_char (dispnew.c)
52 +---------------------------------+
55 +--------------+ redisplay +----------------+
56 | Lisp machine |---------------->| Redisplay code |<--+
57 +--------------+ (xdisp.c) +----------------+ |
59 +----------------------------------+ |
60 Don't use this path when called |
63 expose_window (asynchronous) |
65 X expose events -----+
67 What does redisplay do? Obviously, it has to figure out somehow what
68 has been changed since the last time the display has been updated,
69 and to make these changes visible. Preferably it would do that in
70 a moderately intelligent way, i.e. fast.
72 Changes in buffer text can be deduced from window and buffer
73 structures, and from some global variables like `beg_unchanged' and
74 `end_unchanged'. The contents of the display are additionally
75 recorded in a `glyph matrix', a two-dimensional matrix of glyph
76 structures. Each row in such a matrix corresponds to a line on the
77 display, and each glyph in a row corresponds to a column displaying
78 a character, an image, or what else. This matrix is called the
79 `current glyph matrix' or `current matrix' in redisplay
82 For buffer parts that have been changed since the last update, a
83 second glyph matrix is constructed, the so called `desired glyph
84 matrix' or short `desired matrix'. Current and desired matrix are
85 then compared to find a cheap way to update the display, e.g. by
86 reusing part of the display by scrolling lines.
91 You will find a lot of redisplay optimizations when you start
92 looking at the innards of redisplay. The overall goal of all these
93 optimizations is to make redisplay fast because it is done
96 Two optimizations are not found in xdisp.c. These are the direct
97 operations mentioned above. As the name suggests they follow a
98 different principle than the rest of redisplay. Instead of
99 building a desired matrix and then comparing it with the current
100 display, they perform their actions directly on the display and on
103 One direct operation updates the display after one character has
104 been entered. The other one moves the cursor by one position
105 forward or backward. You find these functions under the names
106 `direct_output_for_insert' and `direct_output_forward_char' in
112 Desired matrices are always built per Emacs window. The function
113 `display_line' is the central function to look at if you are
114 interested. It constructs one row in a desired matrix given an
115 iterator structure containing both a buffer position and a
116 description of the environment in which the text is to be
117 displayed. But this is too early, read on.
119 Characters and pixmaps displayed for a range of buffer text depend
120 on various settings of buffers and windows, on overlays and text
121 properties, on display tables, on selective display. The good news
122 is that all this hairy stuff is hidden behind a small set of
123 interface functions taking an iterator structure (struct it)
126 Iteration over things to be displayed is then simple. It is
127 started by initializing an iterator with a call to init_iterator.
128 Calls to get_next_display_element fill the iterator structure with
129 relevant information about the next thing to display. Calls to
130 set_iterator_to_next move the iterator to the next thing.
132 Besides this, an iterator also contains information about the
133 display environment in which glyphs for display elements are to be
134 produced. It has fields for the width and height of the display,
135 the information whether long lines are truncated or continued, a
136 current X and Y position, and lots of other stuff you can better
139 Glyphs in a desired matrix are normally constructed in a loop
140 calling get_next_display_element and then produce_glyphs. The call
141 to produce_glyphs will fill the iterator structure with pixel
142 information about the element being displayed and at the same time
143 produce glyphs for it. If the display element fits on the line
144 being displayed, set_iterator_to_next is called next, otherwise the
145 glyphs produced are discarded.
150 That just couldn't be all, could it? What about terminal types not
151 supporting operations on sub-windows of the screen? To update the
152 display on such a terminal, window-based glyph matrices are not
153 well suited. To be able to reuse part of the display (scrolling
154 lines up and down), we must instead have a view of the whole
155 screen. This is what `frame matrices' are for. They are a trick.
157 Frames on terminals like above have a glyph pool. Windows on such
158 a frame sub-allocate their glyph memory from their frame's glyph
159 pool. The frame itself is given its own glyph matrices. By
160 coincidence---or maybe something else---rows in window glyph
161 matrices are slices of corresponding rows in frame matrices. Thus
162 writing to window matrices implicitly updates a frame matrix which
163 provides us with the view of the whole screen that we originally
164 wanted to have without having to move many bytes around. To be
165 honest, there is a little bit more done, but not much more. If you
166 plan to extend that code, take a look at dispnew.c. The function
167 build_frame_matrix is a good starting point. */
173 #include "keyboard.h"
176 #include "termchar.h"
177 #include "dispextern.h"
181 #include "commands.h"
185 #include "termhooks.h"
186 #include "intervals.h"
189 #include "region-cache.h"
191 #include "blockinput.h"
193 #ifdef HAVE_X_WINDOWS
203 #ifndef FRAME_X_OUTPUT
204 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
207 #define INFINITY 10000000
209 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
211 extern void set_frame_menubar
P_ ((struct frame
*f
, int, int));
212 extern int pending_menu_activation
;
215 extern int interrupt_input
;
216 extern int command_loop_level
;
218 extern Lisp_Object do_mouse_tracking
;
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 /* Non-zero means to reposition window if cursor line is only partially visible. */
269 int make_cursor_line_fully_visible_p
;
271 /* Margin around tool bar buttons in pixels. */
273 Lisp_Object Vtool_bar_button_margin
;
275 /* Thickness of shadow to draw around tool bar buttons. */
277 EMACS_INT tool_bar_button_relief
;
279 /* Non-zero means automatically resize tool-bars so that all tool-bar
280 items are visible, and no blank lines remain. */
282 int auto_resize_tool_bars_p
;
284 /* Non-zero means draw block and hollow cursor as wide as the glyph
285 under it. For example, if a block cursor is over a tab, it will be
286 drawn as wide as that tab on the display. */
288 int x_stretch_cursor_p
;
290 /* Non-nil means don't actually do any redisplay. */
292 Lisp_Object Vinhibit_redisplay
, Qinhibit_redisplay
;
294 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
296 int inhibit_eval_during_redisplay
;
298 /* Names of text properties relevant for redisplay. */
300 Lisp_Object Qdisplay
;
301 extern Lisp_Object Qface
, Qinvisible
, Qwidth
;
303 /* Symbols used in text property values. */
305 Lisp_Object Vdisplay_pixels_per_inch
;
306 Lisp_Object Qspace
, QCalign_to
, QCrelative_width
, QCrelative_height
;
307 Lisp_Object Qleft_margin
, Qright_margin
, Qspace_width
, Qraise
;
310 Lisp_Object Qmargin
, Qpointer
;
311 Lisp_Object Qline_height
;
312 extern Lisp_Object Qheight
;
313 extern Lisp_Object QCwidth
, QCheight
, QCascent
;
314 extern Lisp_Object Qscroll_bar
;
315 extern Lisp_Object Qcursor
;
317 /* Non-nil means highlight trailing whitespace. */
319 Lisp_Object Vshow_trailing_whitespace
;
321 /* Non-nil means escape non-break space and hyphens. */
323 Lisp_Object Vshow_nonbreak_escape
;
325 #ifdef HAVE_WINDOW_SYSTEM
326 extern Lisp_Object Voverflow_newline_into_fringe
;
328 /* Test if overflow newline into fringe. Called with iterator IT
329 at or past right window margin, and with IT->current_x set. */
331 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) \
332 (!NILP (Voverflow_newline_into_fringe) \
333 && FRAME_WINDOW_P (it->f) \
334 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
335 && it->current_x == it->last_visible_x)
337 #endif /* HAVE_WINDOW_SYSTEM */
339 /* Non-nil means show the text cursor in void text areas
340 i.e. in blank areas after eol and eob. This used to be
341 the default in 21.3. */
343 Lisp_Object Vvoid_text_area_pointer
;
345 /* Name of the face used to highlight trailing whitespace. */
347 Lisp_Object Qtrailing_whitespace
;
349 /* Name and number of the face used to highlight escape glyphs. */
351 Lisp_Object Qescape_glyph
;
353 /* The symbol `image' which is the car of the lists used to represent
358 /* The image map types. */
359 Lisp_Object QCmap
, QCpointer
;
360 Lisp_Object Qrect
, Qcircle
, Qpoly
;
362 /* Non-zero means print newline to stdout before next mini-buffer
365 int noninteractive_need_newline
;
367 /* Non-zero means print newline to message log before next message. */
369 static int message_log_need_newline
;
371 /* Three markers that message_dolog uses.
372 It could allocate them itself, but that causes trouble
373 in handling memory-full errors. */
374 static Lisp_Object message_dolog_marker1
;
375 static Lisp_Object message_dolog_marker2
;
376 static Lisp_Object message_dolog_marker3
;
378 /* The buffer position of the first character appearing entirely or
379 partially on the line of the selected window which contains the
380 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
381 redisplay optimization in redisplay_internal. */
383 static struct text_pos this_line_start_pos
;
385 /* Number of characters past the end of the line above, including the
386 terminating newline. */
388 static struct text_pos this_line_end_pos
;
390 /* The vertical positions and the height of this line. */
392 static int this_line_vpos
;
393 static int this_line_y
;
394 static int this_line_pixel_height
;
396 /* X position at which this display line starts. Usually zero;
397 negative if first character is partially visible. */
399 static int this_line_start_x
;
401 /* Buffer that this_line_.* variables are referring to. */
403 static struct buffer
*this_line_buffer
;
405 /* Nonzero means truncate lines in all windows less wide than the
408 int truncate_partial_width_windows
;
410 /* A flag to control how to display unibyte 8-bit character. */
412 int unibyte_display_via_language_environment
;
414 /* Nonzero means we have more than one non-mini-buffer-only frame.
415 Not guaranteed to be accurate except while parsing
416 frame-title-format. */
420 Lisp_Object Vglobal_mode_string
;
423 /* List of variables (symbols) which hold markers for overlay arrows.
424 The symbols on this list are examined during redisplay to determine
425 where to display overlay arrows. */
427 Lisp_Object Voverlay_arrow_variable_list
;
429 /* Marker for where to display an arrow on top of the buffer text. */
431 Lisp_Object Voverlay_arrow_position
;
433 /* String to display for the arrow. Only used on terminal frames. */
435 Lisp_Object Voverlay_arrow_string
;
437 /* Values of those variables at last redisplay are stored as
438 properties on `overlay-arrow-position' symbol. However, if
439 Voverlay_arrow_position is a marker, last-arrow-position is its
440 numerical position. */
442 Lisp_Object Qlast_arrow_position
, Qlast_arrow_string
;
444 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
445 properties on a symbol in overlay-arrow-variable-list. */
447 Lisp_Object Qoverlay_arrow_string
, Qoverlay_arrow_bitmap
;
449 /* Like mode-line-format, but for the title bar on a visible frame. */
451 Lisp_Object Vframe_title_format
;
453 /* Like mode-line-format, but for the title bar on an iconified frame. */
455 Lisp_Object Vicon_title_format
;
457 /* List of functions to call when a window's size changes. These
458 functions get one arg, a frame on which one or more windows' sizes
461 static Lisp_Object Vwindow_size_change_functions
;
463 Lisp_Object Qmenu_bar_update_hook
, Vmenu_bar_update_hook
;
465 /* Nonzero if overlay arrow has been displayed once in this window. */
467 static int overlay_arrow_seen
;
469 /* Nonzero means highlight the region even in nonselected windows. */
471 int highlight_nonselected_windows
;
473 /* If cursor motion alone moves point off frame, try scrolling this
474 many lines up or down if that will bring it back. */
476 static EMACS_INT scroll_step
;
478 /* Nonzero means scroll just far enough to bring point back on the
479 screen, when appropriate. */
481 static EMACS_INT scroll_conservatively
;
483 /* Recenter the window whenever point gets within this many lines of
484 the top or bottom of the window. This value is translated into a
485 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
486 that there is really a fixed pixel height scroll margin. */
488 EMACS_INT scroll_margin
;
490 /* Number of windows showing the buffer of the selected window (or
491 another buffer with the same base buffer). keyboard.c refers to
496 /* Vector containing glyphs for an ellipsis `...'. */
498 static Lisp_Object default_invis_vector
[3];
500 /* Zero means display the mode-line/header-line/menu-bar in the default face
501 (this slightly odd definition is for compatibility with previous versions
502 of emacs), non-zero means display them using their respective faces.
504 This variable is deprecated. */
506 int mode_line_inverse_video
;
508 /* Prompt to display in front of the mini-buffer contents. */
510 Lisp_Object minibuf_prompt
;
512 /* Width of current mini-buffer prompt. Only set after display_line
513 of the line that contains the prompt. */
515 int minibuf_prompt_width
;
517 /* This is the window where the echo area message was displayed. It
518 is always a mini-buffer window, but it may not be the same window
519 currently active as a mini-buffer. */
521 Lisp_Object echo_area_window
;
523 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
524 pushes the current message and the value of
525 message_enable_multibyte on the stack, the function restore_message
526 pops the stack and displays MESSAGE again. */
528 Lisp_Object Vmessage_stack
;
530 /* Nonzero means multibyte characters were enabled when the echo area
531 message was specified. */
533 int message_enable_multibyte
;
535 /* Nonzero if we should redraw the mode lines on the next redisplay. */
537 int update_mode_lines
;
539 /* Nonzero if window sizes or contents have changed since last
540 redisplay that finished. */
542 int windows_or_buffers_changed
;
544 /* Nonzero means a frame's cursor type has been changed. */
546 int cursor_type_changed
;
548 /* Nonzero after display_mode_line if %l was used and it displayed a
551 int line_number_displayed
;
553 /* Maximum buffer size for which to display line numbers. */
555 Lisp_Object Vline_number_display_limit
;
557 /* Line width to consider when repositioning for line number display. */
559 static EMACS_INT line_number_display_limit_width
;
561 /* Number of lines to keep in the message log buffer. t means
562 infinite. nil means don't log at all. */
564 Lisp_Object Vmessage_log_max
;
566 /* The name of the *Messages* buffer, a string. */
568 static Lisp_Object Vmessages_buffer_name
;
570 /* Current, index 0, and last displayed echo area message. Either
571 buffers from echo_buffers, or nil to indicate no message. */
573 Lisp_Object echo_area_buffer
[2];
575 /* The buffers referenced from echo_area_buffer. */
577 static Lisp_Object echo_buffer
[2];
579 /* A vector saved used in with_area_buffer to reduce consing. */
581 static Lisp_Object Vwith_echo_area_save_vector
;
583 /* Non-zero means display_echo_area should display the last echo area
584 message again. Set by redisplay_preserve_echo_area. */
586 static int display_last_displayed_message_p
;
588 /* Nonzero if echo area is being used by print; zero if being used by
591 int message_buf_print
;
593 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
595 Lisp_Object Qinhibit_menubar_update
;
596 int inhibit_menubar_update
;
598 /* Maximum height for resizing mini-windows. Either a float
599 specifying a fraction of the available height, or an integer
600 specifying a number of lines. */
602 Lisp_Object Vmax_mini_window_height
;
604 /* Non-zero means messages should be displayed with truncated
605 lines instead of being continued. */
607 int message_truncate_lines
;
608 Lisp_Object Qmessage_truncate_lines
;
610 /* Set to 1 in clear_message to make redisplay_internal aware
611 of an emptied echo area. */
613 static int message_cleared_p
;
615 /* Non-zero means we want a hollow cursor in windows that are not
616 selected. Zero means there's no cursor in such windows. */
618 Lisp_Object Vcursor_in_non_selected_windows
;
619 Lisp_Object Qcursor_in_non_selected_windows
;
621 /* How to blink the default frame cursor off. */
622 Lisp_Object Vblink_cursor_alist
;
624 /* A scratch glyph row with contents used for generating truncation
625 glyphs. Also used in direct_output_for_insert. */
627 #define MAX_SCRATCH_GLYPHS 100
628 struct glyph_row scratch_glyph_row
;
629 static struct glyph scratch_glyphs
[MAX_SCRATCH_GLYPHS
];
631 /* Ascent and height of the last line processed by move_it_to. */
633 static int last_max_ascent
, last_height
;
635 /* Non-zero if there's a help-echo in the echo area. */
637 int help_echo_showing_p
;
639 /* If >= 0, computed, exact values of mode-line and header-line height
640 to use in the macros CURRENT_MODE_LINE_HEIGHT and
641 CURRENT_HEADER_LINE_HEIGHT. */
643 int current_mode_line_height
, current_header_line_height
;
645 /* The maximum distance to look ahead for text properties. Values
646 that are too small let us call compute_char_face and similar
647 functions too often which is expensive. Values that are too large
648 let us call compute_char_face and alike too often because we
649 might not be interested in text properties that far away. */
651 #define TEXT_PROP_DISTANCE_LIMIT 100
655 /* Variables to turn off display optimizations from Lisp. */
657 int inhibit_try_window_id
, inhibit_try_window_reusing
;
658 int inhibit_try_cursor_movement
;
660 /* Non-zero means print traces of redisplay if compiled with
663 int trace_redisplay_p
;
665 #endif /* GLYPH_DEBUG */
667 #ifdef DEBUG_TRACE_MOVE
668 /* Non-zero means trace with TRACE_MOVE to stderr. */
671 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
673 #define TRACE_MOVE(x) (void) 0
676 /* Non-zero means automatically scroll windows horizontally to make
679 int automatic_hscrolling_p
;
681 /* How close to the margin can point get before the window is scrolled
683 EMACS_INT hscroll_margin
;
685 /* How much to scroll horizontally when point is inside the above margin. */
686 Lisp_Object Vhscroll_step
;
688 /* The variable `resize-mini-windows'. If nil, don't resize
689 mini-windows. If t, always resize them to fit the text they
690 display. If `grow-only', let mini-windows grow only until they
693 Lisp_Object Vresize_mini_windows
;
695 /* Buffer being redisplayed -- for redisplay_window_error. */
697 struct buffer
*displayed_buffer
;
699 /* Value returned from text property handlers (see below). */
704 HANDLED_RECOMPUTE_PROPS
,
705 HANDLED_OVERLAY_STRING_CONSUMED
,
709 /* A description of text properties that redisplay is interested
714 /* The name of the property. */
717 /* A unique index for the property. */
720 /* A handler function called to set up iterator IT from the property
721 at IT's current position. Value is used to steer handle_stop. */
722 enum prop_handled (*handler
) P_ ((struct it
*it
));
725 static enum prop_handled handle_face_prop
P_ ((struct it
*));
726 static enum prop_handled handle_invisible_prop
P_ ((struct it
*));
727 static enum prop_handled handle_display_prop
P_ ((struct it
*));
728 static enum prop_handled handle_composition_prop
P_ ((struct it
*));
729 static enum prop_handled handle_overlay_change
P_ ((struct it
*));
730 static enum prop_handled handle_fontified_prop
P_ ((struct it
*));
732 /* Properties handled by iterators. */
734 static struct props it_props
[] =
736 {&Qfontified
, FONTIFIED_PROP_IDX
, handle_fontified_prop
},
737 /* Handle `face' before `display' because some sub-properties of
738 `display' need to know the face. */
739 {&Qface
, FACE_PROP_IDX
, handle_face_prop
},
740 {&Qdisplay
, DISPLAY_PROP_IDX
, handle_display_prop
},
741 {&Qinvisible
, INVISIBLE_PROP_IDX
, handle_invisible_prop
},
742 {&Qcomposition
, COMPOSITION_PROP_IDX
, handle_composition_prop
},
746 /* Value is the position described by X. If X is a marker, value is
747 the marker_position of X. Otherwise, value is X. */
749 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
751 /* Enumeration returned by some move_it_.* functions internally. */
755 /* Not used. Undefined value. */
758 /* Move ended at the requested buffer position or ZV. */
759 MOVE_POS_MATCH_OR_ZV
,
761 /* Move ended at the requested X pixel position. */
764 /* Move within a line ended at the end of a line that must be
768 /* Move within a line ended at the end of a line that would
769 be displayed truncated. */
772 /* Move within a line ended at a line end. */
776 /* This counter is used to clear the face cache every once in a while
777 in redisplay_internal. It is incremented for each redisplay.
778 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
781 #define CLEAR_FACE_CACHE_COUNT 500
782 static int clear_face_cache_count
;
784 /* Similarly for the image cache. */
786 #ifdef HAVE_WINDOW_SYSTEM
787 #define CLEAR_IMAGE_CACHE_COUNT 101
788 static int clear_image_cache_count
;
791 /* Record the previous terminal frame we displayed. */
793 static struct frame
*previous_terminal_frame
;
795 /* Non-zero while redisplay_internal is in progress. */
799 /* Non-zero means don't free realized faces. Bound while freeing
800 realized faces is dangerous because glyph matrices might still
803 int inhibit_free_realized_faces
;
804 Lisp_Object Qinhibit_free_realized_faces
;
806 /* If a string, XTread_socket generates an event to display that string.
807 (The display is done in read_char.) */
809 Lisp_Object help_echo_string
;
810 Lisp_Object help_echo_window
;
811 Lisp_Object help_echo_object
;
814 /* Temporary variable for XTread_socket. */
816 Lisp_Object previous_help_echo_string
;
818 /* Null glyph slice */
820 static struct glyph_slice null_glyph_slice
= { 0, 0, 0, 0 };
823 /* Function prototypes. */
825 static void setup_for_ellipsis
P_ ((struct it
*, int));
826 static void mark_window_display_accurate_1
P_ ((struct window
*, int));
827 static int single_display_spec_string_p
P_ ((Lisp_Object
, Lisp_Object
));
828 static int display_prop_string_p
P_ ((Lisp_Object
, Lisp_Object
));
829 static int cursor_row_p
P_ ((struct window
*, struct glyph_row
*));
830 static int redisplay_mode_lines
P_ ((Lisp_Object
, int));
831 static char *decode_mode_spec_coding
P_ ((Lisp_Object
, char *, int));
834 static int invisible_text_between_p
P_ ((struct it
*, int, int));
837 static void pint2str
P_ ((char *, int, int));
838 static void pint2hrstr
P_ ((char *, int, int));
839 static struct text_pos run_window_scroll_functions
P_ ((Lisp_Object
,
841 static void reconsider_clip_changes
P_ ((struct window
*, struct buffer
*));
842 static int text_outside_line_unchanged_p
P_ ((struct window
*, int, int));
843 static void store_frame_title_char
P_ ((char));
844 static int store_frame_title
P_ ((const unsigned char *, int, int));
845 static void x_consider_frame_title
P_ ((Lisp_Object
));
846 static void handle_stop
P_ ((struct it
*));
847 static int tool_bar_lines_needed
P_ ((struct frame
*));
848 static int single_display_spec_intangible_p
P_ ((Lisp_Object
));
849 static void ensure_echo_area_buffers
P_ ((void));
850 static Lisp_Object unwind_with_echo_area_buffer
P_ ((Lisp_Object
));
851 static Lisp_Object with_echo_area_buffer_unwind_data
P_ ((struct window
*));
852 static int with_echo_area_buffer
P_ ((struct window
*, int,
853 int (*) (EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
),
854 EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
855 static void clear_garbaged_frames
P_ ((void));
856 static int current_message_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
857 static int truncate_message_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
858 static int set_message_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
859 static int display_echo_area
P_ ((struct window
*));
860 static int display_echo_area_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
861 static int resize_mini_window_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
862 static Lisp_Object unwind_redisplay
P_ ((Lisp_Object
));
863 static int string_char_and_length
P_ ((const unsigned char *, int, int *));
864 static struct text_pos display_prop_end
P_ ((struct it
*, Lisp_Object
,
866 static int compute_window_start_on_continuation_line
P_ ((struct window
*));
867 static Lisp_Object safe_eval_handler
P_ ((Lisp_Object
));
868 static void insert_left_trunc_glyphs
P_ ((struct it
*));
869 static struct glyph_row
*get_overlay_arrow_glyph_row
P_ ((struct window
*,
871 static void extend_face_to_end_of_line
P_ ((struct it
*));
872 static int append_space_for_newline
P_ ((struct it
*, int));
873 static int cursor_row_fully_visible_p
P_ ((struct window
*, int, int));
874 static int try_scrolling
P_ ((Lisp_Object
, int, EMACS_INT
, EMACS_INT
, int, int));
875 static int try_cursor_movement
P_ ((Lisp_Object
, struct text_pos
, int *));
876 static int trailing_whitespace_p
P_ ((int));
877 static int message_log_check_duplicate
P_ ((int, int, int, int));
878 static void push_it
P_ ((struct it
*));
879 static void pop_it
P_ ((struct it
*));
880 static void sync_frame_with_window_matrix_rows
P_ ((struct window
*));
881 static void select_frame_for_redisplay
P_ ((Lisp_Object
));
882 static void redisplay_internal
P_ ((int));
883 static int echo_area_display
P_ ((int));
884 static void redisplay_windows
P_ ((Lisp_Object
));
885 static void redisplay_window
P_ ((Lisp_Object
, int));
886 static Lisp_Object
redisplay_window_error ();
887 static Lisp_Object redisplay_window_0
P_ ((Lisp_Object
));
888 static Lisp_Object redisplay_window_1
P_ ((Lisp_Object
));
889 static void update_menu_bar
P_ ((struct frame
*, int));
890 static int try_window_reusing_current_matrix
P_ ((struct window
*));
891 static int try_window_id
P_ ((struct window
*));
892 static int display_line
P_ ((struct it
*));
893 static int display_mode_lines
P_ ((struct window
*));
894 static int display_mode_line
P_ ((struct window
*, enum face_id
, Lisp_Object
));
895 static int display_mode_element
P_ ((struct it
*, int, int, int, Lisp_Object
, Lisp_Object
, int));
896 static int store_mode_line_string
P_ ((char *, Lisp_Object
, int, int, int, Lisp_Object
));
897 static char *decode_mode_spec
P_ ((struct window
*, int, int, int, int *));
898 static void display_menu_bar
P_ ((struct window
*));
899 static int display_count_lines
P_ ((int, int, int, int, int *));
900 static int display_string
P_ ((unsigned char *, Lisp_Object
, Lisp_Object
,
901 int, int, struct it
*, int, int, int, int));
902 static void compute_line_metrics
P_ ((struct it
*));
903 static void run_redisplay_end_trigger_hook
P_ ((struct it
*));
904 static int get_overlay_strings
P_ ((struct it
*, int));
905 static void next_overlay_string
P_ ((struct it
*));
906 static void reseat
P_ ((struct it
*, struct text_pos
, int));
907 static void reseat_1
P_ ((struct it
*, struct text_pos
, int));
908 static void back_to_previous_visible_line_start
P_ ((struct it
*));
909 void reseat_at_previous_visible_line_start
P_ ((struct it
*));
910 static void reseat_at_next_visible_line_start
P_ ((struct it
*, int));
911 static int next_element_from_ellipsis
P_ ((struct it
*));
912 static int next_element_from_display_vector
P_ ((struct it
*));
913 static int next_element_from_string
P_ ((struct it
*));
914 static int next_element_from_c_string
P_ ((struct it
*));
915 static int next_element_from_buffer
P_ ((struct it
*));
916 static int next_element_from_composition
P_ ((struct it
*));
917 static int next_element_from_image
P_ ((struct it
*));
918 static int next_element_from_stretch
P_ ((struct it
*));
919 static void load_overlay_strings
P_ ((struct it
*, int));
920 static int init_from_display_pos
P_ ((struct it
*, struct window
*,
921 struct display_pos
*));
922 static void reseat_to_string
P_ ((struct it
*, unsigned char *,
923 Lisp_Object
, int, int, int, int));
924 static enum move_it_result move_it_in_display_line_to
P_ ((struct it
*,
926 void move_it_vertically_backward
P_ ((struct it
*, int));
927 static void init_to_row_start
P_ ((struct it
*, struct window
*,
928 struct glyph_row
*));
929 static int init_to_row_end
P_ ((struct it
*, struct window
*,
930 struct glyph_row
*));
931 static void back_to_previous_line_start
P_ ((struct it
*));
932 static int forward_to_next_line_start
P_ ((struct it
*, int *));
933 static struct text_pos string_pos_nchars_ahead
P_ ((struct text_pos
,
935 static struct text_pos string_pos
P_ ((int, Lisp_Object
));
936 static struct text_pos c_string_pos
P_ ((int, unsigned char *, int));
937 static int number_of_chars
P_ ((unsigned char *, int));
938 static void compute_stop_pos
P_ ((struct it
*));
939 static void compute_string_pos
P_ ((struct text_pos
*, struct text_pos
,
941 static int face_before_or_after_it_pos
P_ ((struct it
*, int));
942 static int next_overlay_change
P_ ((int));
943 static int handle_single_display_spec
P_ ((struct it
*, Lisp_Object
,
944 Lisp_Object
, struct text_pos
*,
946 static int underlying_face_id
P_ ((struct it
*));
947 static int in_ellipses_for_invisible_text_p
P_ ((struct display_pos
*,
950 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
951 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
953 #ifdef HAVE_WINDOW_SYSTEM
955 static void update_tool_bar
P_ ((struct frame
*, int));
956 static void build_desired_tool_bar_string
P_ ((struct frame
*f
));
957 static int redisplay_tool_bar
P_ ((struct frame
*));
958 static void display_tool_bar_line
P_ ((struct it
*));
959 static void notice_overwritten_cursor
P_ ((struct window
*,
961 int, int, int, int));
965 #endif /* HAVE_WINDOW_SYSTEM */
968 /***********************************************************************
969 Window display dimensions
970 ***********************************************************************/
972 /* Return the bottom boundary y-position for text lines in window W.
973 This is the first y position at which a line cannot start.
974 It is relative to the top of the window.
976 This is the height of W minus the height of a mode line, if any. */
979 window_text_bottom_y (w
)
982 int height
= WINDOW_TOTAL_HEIGHT (w
);
984 if (WINDOW_WANTS_MODELINE_P (w
))
985 height
-= CURRENT_MODE_LINE_HEIGHT (w
);
989 /* Return the pixel width of display area AREA of window W. AREA < 0
990 means return the total width of W, not including fringes to
991 the left and right of the window. */
994 window_box_width (w
, area
)
998 int cols
= XFASTINT (w
->total_cols
);
1001 if (!w
->pseudo_window_p
)
1003 cols
-= WINDOW_SCROLL_BAR_COLS (w
);
1005 if (area
== TEXT_AREA
)
1007 if (INTEGERP (w
->left_margin_cols
))
1008 cols
-= XFASTINT (w
->left_margin_cols
);
1009 if (INTEGERP (w
->right_margin_cols
))
1010 cols
-= XFASTINT (w
->right_margin_cols
);
1011 pixels
= -WINDOW_TOTAL_FRINGE_WIDTH (w
);
1013 else if (area
== LEFT_MARGIN_AREA
)
1015 cols
= (INTEGERP (w
->left_margin_cols
)
1016 ? XFASTINT (w
->left_margin_cols
) : 0);
1019 else if (area
== RIGHT_MARGIN_AREA
)
1021 cols
= (INTEGERP (w
->right_margin_cols
)
1022 ? XFASTINT (w
->right_margin_cols
) : 0);
1027 return cols
* WINDOW_FRAME_COLUMN_WIDTH (w
) + pixels
;
1031 /* Return the pixel height of the display area of window W, not
1032 including mode lines of W, if any. */
1035 window_box_height (w
)
1038 struct frame
*f
= XFRAME (w
->frame
);
1039 int height
= WINDOW_TOTAL_HEIGHT (w
);
1041 xassert (height
>= 0);
1043 /* Note: the code below that determines the mode-line/header-line
1044 height is essentially the same as that contained in the macro
1045 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1046 the appropriate glyph row has its `mode_line_p' flag set,
1047 and if it doesn't, uses estimate_mode_line_height instead. */
1049 if (WINDOW_WANTS_MODELINE_P (w
))
1051 struct glyph_row
*ml_row
1052 = (w
->current_matrix
&& w
->current_matrix
->rows
1053 ? MATRIX_MODE_LINE_ROW (w
->current_matrix
)
1055 if (ml_row
&& ml_row
->mode_line_p
)
1056 height
-= ml_row
->height
;
1058 height
-= estimate_mode_line_height (f
, CURRENT_MODE_LINE_FACE_ID (w
));
1061 if (WINDOW_WANTS_HEADER_LINE_P (w
))
1063 struct glyph_row
*hl_row
1064 = (w
->current_matrix
&& w
->current_matrix
->rows
1065 ? MATRIX_HEADER_LINE_ROW (w
->current_matrix
)
1067 if (hl_row
&& hl_row
->mode_line_p
)
1068 height
-= hl_row
->height
;
1070 height
-= estimate_mode_line_height (f
, HEADER_LINE_FACE_ID
);
1073 /* With a very small font and a mode-line that's taller than
1074 default, we might end up with a negative height. */
1075 return max (0, height
);
1078 /* Return the window-relative coordinate of the left edge of display
1079 area AREA of window W. AREA < 0 means return the left edge of the
1080 whole window, to the right of the left fringe of W. */
1083 window_box_left_offset (w
, area
)
1089 if (w
->pseudo_window_p
)
1092 x
= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w
);
1094 if (area
== TEXT_AREA
)
1095 x
+= (WINDOW_LEFT_FRINGE_WIDTH (w
)
1096 + window_box_width (w
, LEFT_MARGIN_AREA
));
1097 else if (area
== RIGHT_MARGIN_AREA
)
1098 x
+= (WINDOW_LEFT_FRINGE_WIDTH (w
)
1099 + window_box_width (w
, LEFT_MARGIN_AREA
)
1100 + window_box_width (w
, TEXT_AREA
)
1101 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
1103 : WINDOW_RIGHT_FRINGE_WIDTH (w
)));
1104 else if (area
== LEFT_MARGIN_AREA
1105 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
))
1106 x
+= WINDOW_LEFT_FRINGE_WIDTH (w
);
1112 /* Return the window-relative coordinate of the right edge of display
1113 area AREA of window W. AREA < 0 means return the left edge of the
1114 whole window, to the left of the right fringe of W. */
1117 window_box_right_offset (w
, area
)
1121 return window_box_left_offset (w
, area
) + window_box_width (w
, area
);
1124 /* Return the frame-relative coordinate of the left edge of display
1125 area AREA of window W. AREA < 0 means return the left edge of the
1126 whole window, to the right of the left fringe of W. */
1129 window_box_left (w
, area
)
1133 struct frame
*f
= XFRAME (w
->frame
);
1136 if (w
->pseudo_window_p
)
1137 return FRAME_INTERNAL_BORDER_WIDTH (f
);
1139 x
= (WINDOW_LEFT_EDGE_X (w
)
1140 + window_box_left_offset (w
, area
));
1146 /* Return the frame-relative coordinate of the right edge of display
1147 area AREA of window W. AREA < 0 means return the left edge of the
1148 whole window, to the left of the right fringe of W. */
1151 window_box_right (w
, area
)
1155 return window_box_left (w
, area
) + window_box_width (w
, area
);
1158 /* Get the bounding box of the display area AREA of window W, without
1159 mode lines, in frame-relative coordinates. AREA < 0 means the
1160 whole window, not including the left and right fringes of
1161 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1162 coordinates of the upper-left corner of the box. Return in
1163 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1166 window_box (w
, area
, box_x
, box_y
, box_width
, box_height
)
1169 int *box_x
, *box_y
, *box_width
, *box_height
;
1172 *box_width
= window_box_width (w
, area
);
1174 *box_height
= window_box_height (w
);
1176 *box_x
= window_box_left (w
, area
);
1179 *box_y
= WINDOW_TOP_EDGE_Y (w
);
1180 if (WINDOW_WANTS_HEADER_LINE_P (w
))
1181 *box_y
+= CURRENT_HEADER_LINE_HEIGHT (w
);
1186 /* Get the bounding box of the display area AREA of window W, without
1187 mode lines. AREA < 0 means the whole window, not including the
1188 left and right fringe of the window. Return in *TOP_LEFT_X
1189 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1190 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1191 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1195 window_box_edges (w
, area
, top_left_x
, top_left_y
,
1196 bottom_right_x
, bottom_right_y
)
1199 int *top_left_x
, *top_left_y
, *bottom_right_x
, *bottom_right_y
;
1201 window_box (w
, area
, top_left_x
, top_left_y
, bottom_right_x
,
1203 *bottom_right_x
+= *top_left_x
;
1204 *bottom_right_y
+= *top_left_y
;
1209 /***********************************************************************
1211 ***********************************************************************/
1213 /* Return the bottom y-position of the line the iterator IT is in.
1214 This can modify IT's settings. */
1220 int line_height
= it
->max_ascent
+ it
->max_descent
;
1221 int line_top_y
= it
->current_y
;
1223 if (line_height
== 0)
1226 line_height
= last_height
;
1227 else if (IT_CHARPOS (*it
) < ZV
)
1229 move_it_by_lines (it
, 1, 1);
1230 line_height
= (it
->max_ascent
|| it
->max_descent
1231 ? it
->max_ascent
+ it
->max_descent
1236 struct glyph_row
*row
= it
->glyph_row
;
1238 /* Use the default character height. */
1239 it
->glyph_row
= NULL
;
1240 it
->what
= IT_CHARACTER
;
1243 PRODUCE_GLYPHS (it
);
1244 line_height
= it
->ascent
+ it
->descent
;
1245 it
->glyph_row
= row
;
1249 return line_top_y
+ line_height
;
1253 /* Return 1 if position CHARPOS is visible in window W.
1254 If visible, set *X and *Y to pixel coordinates of top left corner.
1255 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1256 EXACT_MODE_LINE_HEIGHTS_P non-zero means compute exact mode-line
1257 and header-lines heights. */
1260 pos_visible_p (w
, charpos
, x
, y
, rtop
, rbot
, exact_mode_line_heights_p
)
1262 int charpos
, *x
, *y
, *rtop
, *rbot
, exact_mode_line_heights_p
;
1265 struct text_pos top
;
1267 struct buffer
*old_buffer
= NULL
;
1272 if (XBUFFER (w
->buffer
) != current_buffer
)
1274 old_buffer
= current_buffer
;
1275 set_buffer_internal_1 (XBUFFER (w
->buffer
));
1278 SET_TEXT_POS_FROM_MARKER (top
, w
->start
);
1280 /* Compute exact mode line heights, if requested. */
1281 if (exact_mode_line_heights_p
)
1283 if (WINDOW_WANTS_MODELINE_P (w
))
1284 current_mode_line_height
1285 = display_mode_line (w
, CURRENT_MODE_LINE_FACE_ID (w
),
1286 current_buffer
->mode_line_format
);
1288 if (WINDOW_WANTS_HEADER_LINE_P (w
))
1289 current_header_line_height
1290 = display_mode_line (w
, HEADER_LINE_FACE_ID
,
1291 current_buffer
->header_line_format
);
1294 start_display (&it
, w
, top
);
1295 move_it_to (&it
, charpos
, -1, it
.last_visible_y
, -1,
1296 MOVE_TO_POS
| MOVE_TO_Y
);
1298 /* Note that we may overshoot because of invisible text. */
1299 if (IT_CHARPOS (it
) >= charpos
)
1301 int top_x
= it
.current_x
;
1302 int top_y
= it
.current_y
;
1303 int bottom_y
= (last_height
= 0, line_bottom_y (&it
));
1304 int window_top_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
1306 if (top_y
< window_top_y
)
1307 visible_p
= bottom_y
> window_top_y
;
1308 else if (top_y
< it
.last_visible_y
)
1313 *y
= max (top_y
+ max (0, it
.max_ascent
- it
.ascent
), window_top_y
);
1314 *rtop
= max (0, window_top_y
- top_y
);
1315 *rbot
= max (0, bottom_y
- it
.last_visible_y
);
1323 if (IT_CHARPOS (it
) < ZV
&& FETCH_BYTE (IT_BYTEPOS (it
)) != '\n')
1324 move_it_by_lines (&it
, 1, 0);
1325 if (charpos
< IT_CHARPOS (it
))
1328 move_it_to (&it2
, charpos
, -1, -1, -1, MOVE_TO_POS
);
1330 *y
= it2
.current_y
+ it2
.max_ascent
- it2
.ascent
;
1331 *rtop
= max (0, -it2
.current_y
);
1332 *rbot
= max (0, ((it2
.current_y
+ it2
.max_ascent
+ it2
.max_descent
)
1333 - it
.last_visible_y
));
1338 set_buffer_internal_1 (old_buffer
);
1340 current_header_line_height
= current_mode_line_height
= -1;
1346 /* Return the next character from STR which is MAXLEN bytes long.
1347 Return in *LEN the length of the character. This is like
1348 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1349 we find one, we return a `?', but with the length of the invalid
1353 string_char_and_length (str
, maxlen
, len
)
1354 const unsigned char *str
;
1359 c
= STRING_CHAR_AND_LENGTH (str
, maxlen
, *len
);
1360 if (!CHAR_VALID_P (c
, 1))
1361 /* We may not change the length here because other places in Emacs
1362 don't use this function, i.e. they silently accept invalid
1371 /* Given a position POS containing a valid character and byte position
1372 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1374 static struct text_pos
1375 string_pos_nchars_ahead (pos
, string
, nchars
)
1376 struct text_pos pos
;
1380 xassert (STRINGP (string
) && nchars
>= 0);
1382 if (STRING_MULTIBYTE (string
))
1384 int rest
= SBYTES (string
) - BYTEPOS (pos
);
1385 const unsigned char *p
= SDATA (string
) + BYTEPOS (pos
);
1390 string_char_and_length (p
, rest
, &len
);
1391 p
+= len
, rest
-= len
;
1392 xassert (rest
>= 0);
1394 BYTEPOS (pos
) += len
;
1398 SET_TEXT_POS (pos
, CHARPOS (pos
) + nchars
, BYTEPOS (pos
) + nchars
);
1404 /* Value is the text position, i.e. character and byte position,
1405 for character position CHARPOS in STRING. */
1407 static INLINE
struct text_pos
1408 string_pos (charpos
, string
)
1412 struct text_pos pos
;
1413 xassert (STRINGP (string
));
1414 xassert (charpos
>= 0);
1415 SET_TEXT_POS (pos
, charpos
, string_char_to_byte (string
, charpos
));
1420 /* Value is a text position, i.e. character and byte position, for
1421 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1422 means recognize multibyte characters. */
1424 static struct text_pos
1425 c_string_pos (charpos
, s
, multibyte_p
)
1430 struct text_pos pos
;
1432 xassert (s
!= NULL
);
1433 xassert (charpos
>= 0);
1437 int rest
= strlen (s
), len
;
1439 SET_TEXT_POS (pos
, 0, 0);
1442 string_char_and_length (s
, rest
, &len
);
1443 s
+= len
, rest
-= len
;
1444 xassert (rest
>= 0);
1446 BYTEPOS (pos
) += len
;
1450 SET_TEXT_POS (pos
, charpos
, charpos
);
1456 /* Value is the number of characters in C string S. MULTIBYTE_P
1457 non-zero means recognize multibyte characters. */
1460 number_of_chars (s
, multibyte_p
)
1468 int rest
= strlen (s
), len
;
1469 unsigned char *p
= (unsigned char *) s
;
1471 for (nchars
= 0; rest
> 0; ++nchars
)
1473 string_char_and_length (p
, rest
, &len
);
1474 rest
-= len
, p
+= len
;
1478 nchars
= strlen (s
);
1484 /* Compute byte position NEWPOS->bytepos corresponding to
1485 NEWPOS->charpos. POS is a known position in string STRING.
1486 NEWPOS->charpos must be >= POS.charpos. */
1489 compute_string_pos (newpos
, pos
, string
)
1490 struct text_pos
*newpos
, pos
;
1493 xassert (STRINGP (string
));
1494 xassert (CHARPOS (*newpos
) >= CHARPOS (pos
));
1496 if (STRING_MULTIBYTE (string
))
1497 *newpos
= string_pos_nchars_ahead (pos
, string
,
1498 CHARPOS (*newpos
) - CHARPOS (pos
));
1500 BYTEPOS (*newpos
) = CHARPOS (*newpos
);
1504 Return an estimation of the pixel height of mode or top lines on
1505 frame F. FACE_ID specifies what line's height to estimate. */
1508 estimate_mode_line_height (f
, face_id
)
1510 enum face_id face_id
;
1512 #ifdef HAVE_WINDOW_SYSTEM
1513 if (FRAME_WINDOW_P (f
))
1515 int height
= FONT_HEIGHT (FRAME_FONT (f
));
1517 /* This function is called so early when Emacs starts that the face
1518 cache and mode line face are not yet initialized. */
1519 if (FRAME_FACE_CACHE (f
))
1521 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1525 height
= FONT_HEIGHT (face
->font
);
1526 if (face
->box_line_width
> 0)
1527 height
+= 2 * face
->box_line_width
;
1538 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1539 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1540 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1541 not force the value into range. */
1544 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
, noclip
)
1546 register int pix_x
, pix_y
;
1548 NativeRectangle
*bounds
;
1552 #ifdef HAVE_WINDOW_SYSTEM
1553 if (FRAME_WINDOW_P (f
))
1555 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1556 even for negative values. */
1558 pix_x
-= FRAME_COLUMN_WIDTH (f
) - 1;
1560 pix_y
-= FRAME_LINE_HEIGHT (f
) - 1;
1562 pix_x
= FRAME_PIXEL_X_TO_COL (f
, pix_x
);
1563 pix_y
= FRAME_PIXEL_Y_TO_LINE (f
, pix_y
);
1566 STORE_NATIVE_RECT (*bounds
,
1567 FRAME_COL_TO_PIXEL_X (f
, pix_x
),
1568 FRAME_LINE_TO_PIXEL_Y (f
, pix_y
),
1569 FRAME_COLUMN_WIDTH (f
) - 1,
1570 FRAME_LINE_HEIGHT (f
) - 1);
1576 else if (pix_x
> FRAME_TOTAL_COLS (f
))
1577 pix_x
= FRAME_TOTAL_COLS (f
);
1581 else if (pix_y
> FRAME_LINES (f
))
1582 pix_y
= FRAME_LINES (f
);
1592 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1593 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1594 can't tell the positions because W's display is not up to date,
1598 glyph_to_pixel_coords (w
, hpos
, vpos
, frame_x
, frame_y
)
1601 int *frame_x
, *frame_y
;
1603 #ifdef HAVE_WINDOW_SYSTEM
1604 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w
))))
1608 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
1609 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
1611 if (display_completed
)
1613 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
1614 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
1615 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
1621 hpos
+= glyph
->pixel_width
;
1625 /* If first glyph is partially visible, its first visible position is still 0. */
1637 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, hpos
);
1638 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, vpos
);
1649 #ifdef HAVE_WINDOW_SYSTEM
1651 /* Find the glyph under window-relative coordinates X/Y in window W.
1652 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1653 strings. Return in *HPOS and *VPOS the row and column number of
1654 the glyph found. Return in *AREA the glyph area containing X.
1655 Value is a pointer to the glyph found or null if X/Y is not on
1656 text, or we can't tell because W's current matrix is not up to
1659 static struct glyph
*
1660 x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, dx
, dy
, area
)
1663 int *hpos
, *vpos
, *dx
, *dy
, *area
;
1665 struct glyph
*glyph
, *end
;
1666 struct glyph_row
*row
= NULL
;
1669 /* Find row containing Y. Give up if some row is not enabled. */
1670 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
1672 row
= MATRIX_ROW (w
->current_matrix
, i
);
1673 if (!row
->enabled_p
)
1675 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
1682 /* Give up if Y is not in the window. */
1683 if (i
== w
->current_matrix
->nrows
)
1686 /* Get the glyph area containing X. */
1687 if (w
->pseudo_window_p
)
1694 if (x
< window_box_left_offset (w
, TEXT_AREA
))
1696 *area
= LEFT_MARGIN_AREA
;
1697 x0
= window_box_left_offset (w
, LEFT_MARGIN_AREA
);
1699 else if (x
< window_box_right_offset (w
, TEXT_AREA
))
1702 x0
= window_box_left_offset (w
, TEXT_AREA
) + min (row
->x
, 0);
1706 *area
= RIGHT_MARGIN_AREA
;
1707 x0
= window_box_left_offset (w
, RIGHT_MARGIN_AREA
);
1711 /* Find glyph containing X. */
1712 glyph
= row
->glyphs
[*area
];
1713 end
= glyph
+ row
->used
[*area
];
1715 while (glyph
< end
&& x
>= glyph
->pixel_width
)
1717 x
-= glyph
->pixel_width
;
1727 *dy
= y
- (row
->y
+ row
->ascent
- glyph
->ascent
);
1730 *hpos
= glyph
- row
->glyphs
[*area
];
1736 Convert frame-relative x/y to coordinates relative to window W.
1737 Takes pseudo-windows into account. */
1740 frame_to_window_pixel_xy (w
, x
, y
)
1744 if (w
->pseudo_window_p
)
1746 /* A pseudo-window is always full-width, and starts at the
1747 left edge of the frame, plus a frame border. */
1748 struct frame
*f
= XFRAME (w
->frame
);
1749 *x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
1750 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
1754 *x
-= WINDOW_LEFT_EDGE_X (w
);
1755 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
1760 Return in *R the clipping rectangle for glyph string S. */
1763 get_glyph_string_clip_rect (s
, nr
)
1764 struct glyph_string
*s
;
1765 NativeRectangle
*nr
;
1769 if (s
->row
->full_width_p
)
1771 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1772 r
.x
= WINDOW_LEFT_EDGE_X (s
->w
);
1773 r
.width
= WINDOW_TOTAL_WIDTH (s
->w
);
1775 /* Unless displaying a mode or menu bar line, which are always
1776 fully visible, clip to the visible part of the row. */
1777 if (s
->w
->pseudo_window_p
)
1778 r
.height
= s
->row
->visible_height
;
1780 r
.height
= s
->height
;
1784 /* This is a text line that may be partially visible. */
1785 r
.x
= window_box_left (s
->w
, s
->area
);
1786 r
.width
= window_box_width (s
->w
, s
->area
);
1787 r
.height
= s
->row
->visible_height
;
1791 if (r
.x
< s
->clip_head
->x
)
1793 if (r
.width
>= s
->clip_head
->x
- r
.x
)
1794 r
.width
-= s
->clip_head
->x
- r
.x
;
1797 r
.x
= s
->clip_head
->x
;
1800 if (r
.x
+ r
.width
> s
->clip_tail
->x
+ s
->clip_tail
->background_width
)
1802 if (s
->clip_tail
->x
+ s
->clip_tail
->background_width
>= r
.x
)
1803 r
.width
= s
->clip_tail
->x
+ s
->clip_tail
->background_width
- r
.x
;
1808 /* If S draws overlapping rows, it's sufficient to use the top and
1809 bottom of the window for clipping because this glyph string
1810 intentionally draws over other lines. */
1811 if (s
->for_overlaps_p
)
1813 r
.y
= WINDOW_HEADER_LINE_HEIGHT (s
->w
);
1814 r
.height
= window_text_bottom_y (s
->w
) - r
.y
;
1818 /* Don't use S->y for clipping because it doesn't take partially
1819 visible lines into account. For example, it can be negative for
1820 partially visible lines at the top of a window. */
1821 if (!s
->row
->full_width_p
1822 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
1823 r
.y
= WINDOW_HEADER_LINE_HEIGHT (s
->w
);
1825 r
.y
= max (0, s
->row
->y
);
1827 /* If drawing a tool-bar window, draw it over the internal border
1828 at the top of the window. */
1829 if (WINDOWP (s
->f
->tool_bar_window
)
1830 && s
->w
== XWINDOW (s
->f
->tool_bar_window
))
1831 r
.y
-= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
1834 r
.y
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
.y
);
1836 /* If drawing the cursor, don't let glyph draw outside its
1837 advertised boundaries. Cleartype does this under some circumstances. */
1838 if (s
->hl
== DRAW_CURSOR
)
1840 struct glyph
*glyph
= s
->first_glyph
;
1845 r
.width
-= s
->x
- r
.x
;
1848 r
.width
= min (r
.width
, glyph
->pixel_width
);
1850 /* If r.y is below window bottom, ensure that we still see a cursor. */
1851 height
= min (glyph
->ascent
+ glyph
->descent
,
1852 min (FRAME_LINE_HEIGHT (s
->f
), s
->row
->visible_height
));
1853 max_y
= window_text_bottom_y (s
->w
) - height
;
1854 max_y
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, max_y
);
1855 if (s
->ybase
- glyph
->ascent
> max_y
)
1862 /* Don't draw cursor glyph taller than our actual glyph. */
1863 height
= max (FRAME_LINE_HEIGHT (s
->f
), glyph
->ascent
+ glyph
->descent
);
1864 if (height
< r
.height
)
1866 max_y
= r
.y
+ r
.height
;
1867 r
.y
= min (max_y
, max (r
.y
, s
->ybase
+ glyph
->descent
- height
));
1868 r
.height
= min (max_y
- r
.y
, height
);
1873 #ifdef CONVERT_FROM_XRECT
1874 CONVERT_FROM_XRECT (r
, *nr
);
1882 Return the position and height of the phys cursor in window W.
1883 Set w->phys_cursor_width to width of phys cursor.
1887 get_phys_cursor_geometry (w
, row
, glyph
, heightp
)
1889 struct glyph_row
*row
;
1890 struct glyph
*glyph
;
1893 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1894 int x
, y
, wd
, h
, h0
, y0
;
1896 /* Compute the width of the rectangle to draw. If on a stretch
1897 glyph, and `x-stretch-block-cursor' is nil, don't draw a
1898 rectangle as wide as the glyph, but use a canonical character
1900 wd
= glyph
->pixel_width
- 1;
1904 if (glyph
->type
== STRETCH_GLYPH
1905 && !x_stretch_cursor_p
)
1906 wd
= min (FRAME_COLUMN_WIDTH (f
), wd
);
1907 w
->phys_cursor_width
= wd
;
1909 y
= w
->phys_cursor
.y
+ row
->ascent
- glyph
->ascent
;
1911 /* If y is below window bottom, ensure that we still see a cursor. */
1912 h0
= min (FRAME_LINE_HEIGHT (f
), row
->visible_height
);
1914 h
= max (h0
, glyph
->ascent
+ glyph
->descent
);
1915 h0
= min (h0
, glyph
->ascent
+ glyph
->descent
);
1917 y0
= WINDOW_HEADER_LINE_HEIGHT (w
);
1920 h
= max (h
- (y0
- y
) + 1, h0
);
1925 y0
= window_text_bottom_y (w
) - h0
;
1934 return WINDOW_TO_FRAME_PIXEL_Y (w
, y
);
1938 #endif /* HAVE_WINDOW_SYSTEM */
1941 /***********************************************************************
1942 Lisp form evaluation
1943 ***********************************************************************/
1945 /* Error handler for safe_eval and safe_call. */
1948 safe_eval_handler (arg
)
1951 add_to_log ("Error during redisplay: %s", arg
, Qnil
);
1956 /* Evaluate SEXPR and return the result, or nil if something went
1957 wrong. Prevent redisplay during the evaluation. */
1965 if (inhibit_eval_during_redisplay
)
1969 int count
= SPECPDL_INDEX ();
1970 struct gcpro gcpro1
;
1973 specbind (Qinhibit_redisplay
, Qt
);
1974 /* Use Qt to ensure debugger does not run,
1975 so there is no possibility of wanting to redisplay. */
1976 val
= internal_condition_case_1 (Feval
, sexpr
, Qt
,
1979 val
= unbind_to (count
, val
);
1986 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
1987 Return the result, or nil if something went wrong. Prevent
1988 redisplay during the evaluation. */
1991 safe_call (nargs
, args
)
1997 if (inhibit_eval_during_redisplay
)
2001 int count
= SPECPDL_INDEX ();
2002 struct gcpro gcpro1
;
2005 gcpro1
.nvars
= nargs
;
2006 specbind (Qinhibit_redisplay
, Qt
);
2007 /* Use Qt to ensure debugger does not run,
2008 so there is no possibility of wanting to redisplay. */
2009 val
= internal_condition_case_2 (Ffuncall
, nargs
, args
, Qt
,
2012 val
= unbind_to (count
, val
);
2019 /* Call function FN with one argument ARG.
2020 Return the result, or nil if something went wrong. */
2023 safe_call1 (fn
, arg
)
2024 Lisp_Object fn
, arg
;
2026 Lisp_Object args
[2];
2029 return safe_call (2, args
);
2034 /***********************************************************************
2036 ***********************************************************************/
2040 /* Define CHECK_IT to perform sanity checks on iterators.
2041 This is for debugging. It is too slow to do unconditionally. */
2047 if (it
->method
== GET_FROM_STRING
)
2049 xassert (STRINGP (it
->string
));
2050 xassert (IT_STRING_CHARPOS (*it
) >= 0);
2054 xassert (IT_STRING_CHARPOS (*it
) < 0);
2055 if (it
->method
== GET_FROM_BUFFER
)
2057 /* Check that character and byte positions agree. */
2058 xassert (IT_CHARPOS (*it
) == BYTE_TO_CHAR (IT_BYTEPOS (*it
)));
2063 xassert (it
->current
.dpvec_index
>= 0);
2065 xassert (it
->current
.dpvec_index
< 0);
2068 #define CHECK_IT(IT) check_it ((IT))
2072 #define CHECK_IT(IT) (void) 0
2079 /* Check that the window end of window W is what we expect it
2080 to be---the last row in the current matrix displaying text. */
2083 check_window_end (w
)
2086 if (!MINI_WINDOW_P (w
)
2087 && !NILP (w
->window_end_valid
))
2089 struct glyph_row
*row
;
2090 xassert ((row
= MATRIX_ROW (w
->current_matrix
,
2091 XFASTINT (w
->window_end_vpos
)),
2093 || MATRIX_ROW_DISPLAYS_TEXT_P (row
)
2094 || MATRIX_ROW_VPOS (row
, w
->current_matrix
) == 0));
2098 #define CHECK_WINDOW_END(W) check_window_end ((W))
2100 #else /* not GLYPH_DEBUG */
2102 #define CHECK_WINDOW_END(W) (void) 0
2104 #endif /* not GLYPH_DEBUG */
2108 /***********************************************************************
2109 Iterator initialization
2110 ***********************************************************************/
2112 /* Initialize IT for displaying current_buffer in window W, starting
2113 at character position CHARPOS. CHARPOS < 0 means that no buffer
2114 position is specified which is useful when the iterator is assigned
2115 a position later. BYTEPOS is the byte position corresponding to
2116 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2118 If ROW is not null, calls to produce_glyphs with IT as parameter
2119 will produce glyphs in that row.
2121 BASE_FACE_ID is the id of a base face to use. It must be one of
2122 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2123 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2124 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2126 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2127 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2128 will be initialized to use the corresponding mode line glyph row of
2129 the desired matrix of W. */
2132 init_iterator (it
, w
, charpos
, bytepos
, row
, base_face_id
)
2135 int charpos
, bytepos
;
2136 struct glyph_row
*row
;
2137 enum face_id base_face_id
;
2139 int highlight_region_p
;
2141 /* Some precondition checks. */
2142 xassert (w
!= NULL
&& it
!= NULL
);
2143 xassert (charpos
< 0 || (charpos
>= BUF_BEG (current_buffer
)
2146 /* If face attributes have been changed since the last redisplay,
2147 free realized faces now because they depend on face definitions
2148 that might have changed. Don't free faces while there might be
2149 desired matrices pending which reference these faces. */
2150 if (face_change_count
&& !inhibit_free_realized_faces
)
2152 face_change_count
= 0;
2153 free_all_realized_faces (Qnil
);
2156 /* Use one of the mode line rows of W's desired matrix if
2160 if (base_face_id
== MODE_LINE_FACE_ID
2161 || base_face_id
== MODE_LINE_INACTIVE_FACE_ID
)
2162 row
= MATRIX_MODE_LINE_ROW (w
->desired_matrix
);
2163 else if (base_face_id
== HEADER_LINE_FACE_ID
)
2164 row
= MATRIX_HEADER_LINE_ROW (w
->desired_matrix
);
2168 bzero (it
, sizeof *it
);
2169 it
->current
.overlay_string_index
= -1;
2170 it
->current
.dpvec_index
= -1;
2171 it
->base_face_id
= base_face_id
;
2173 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = -1;
2175 /* The window in which we iterate over current_buffer: */
2176 XSETWINDOW (it
->window
, w
);
2178 it
->f
= XFRAME (w
->frame
);
2180 /* Extra space between lines (on window systems only). */
2181 if (base_face_id
== DEFAULT_FACE_ID
2182 && FRAME_WINDOW_P (it
->f
))
2184 if (NATNUMP (current_buffer
->extra_line_spacing
))
2185 it
->extra_line_spacing
= XFASTINT (current_buffer
->extra_line_spacing
);
2186 else if (FLOATP (current_buffer
->extra_line_spacing
))
2187 it
->extra_line_spacing
= (XFLOAT_DATA (current_buffer
->extra_line_spacing
)
2188 * FRAME_LINE_HEIGHT (it
->f
));
2189 else if (it
->f
->extra_line_spacing
> 0)
2190 it
->extra_line_spacing
= it
->f
->extra_line_spacing
;
2191 it
->max_extra_line_spacing
= 0;
2194 /* If realized faces have been removed, e.g. because of face
2195 attribute changes of named faces, recompute them. When running
2196 in batch mode, the face cache of Vterminal_frame is null. If
2197 we happen to get called, make a dummy face cache. */
2198 if (noninteractive
&& FRAME_FACE_CACHE (it
->f
) == NULL
)
2199 init_frame_faces (it
->f
);
2200 if (FRAME_FACE_CACHE (it
->f
)->used
== 0)
2201 recompute_basic_faces (it
->f
);
2203 /* Current value of the `slice', `space-width', and 'height' properties. */
2204 it
->slice
.x
= it
->slice
.y
= it
->slice
.width
= it
->slice
.height
= Qnil
;
2205 it
->space_width
= Qnil
;
2206 it
->font_height
= Qnil
;
2207 it
->override_ascent
= -1;
2209 /* Are control characters displayed as `^C'? */
2210 it
->ctl_arrow_p
= !NILP (current_buffer
->ctl_arrow
);
2212 /* -1 means everything between a CR and the following line end
2213 is invisible. >0 means lines indented more than this value are
2215 it
->selective
= (INTEGERP (current_buffer
->selective_display
)
2216 ? XFASTINT (current_buffer
->selective_display
)
2217 : (!NILP (current_buffer
->selective_display
)
2219 it
->selective_display_ellipsis_p
2220 = !NILP (current_buffer
->selective_display_ellipses
);
2222 /* Display table to use. */
2223 it
->dp
= window_display_table (w
);
2225 /* Are multibyte characters enabled in current_buffer? */
2226 it
->multibyte_p
= !NILP (current_buffer
->enable_multibyte_characters
);
2228 /* Non-zero if we should highlight the region. */
2230 = (!NILP (Vtransient_mark_mode
)
2231 && !NILP (current_buffer
->mark_active
)
2232 && XMARKER (current_buffer
->mark
)->buffer
!= 0);
2234 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2235 start and end of a visible region in window IT->w. Set both to
2236 -1 to indicate no region. */
2237 if (highlight_region_p
2238 /* Maybe highlight only in selected window. */
2239 && (/* Either show region everywhere. */
2240 highlight_nonselected_windows
2241 /* Or show region in the selected window. */
2242 || w
== XWINDOW (selected_window
)
2243 /* Or show the region if we are in the mini-buffer and W is
2244 the window the mini-buffer refers to. */
2245 || (MINI_WINDOW_P (XWINDOW (selected_window
))
2246 && WINDOWP (minibuf_selected_window
)
2247 && w
== XWINDOW (minibuf_selected_window
))))
2249 int charpos
= marker_position (current_buffer
->mark
);
2250 it
->region_beg_charpos
= min (PT
, charpos
);
2251 it
->region_end_charpos
= max (PT
, charpos
);
2254 it
->region_beg_charpos
= it
->region_end_charpos
= -1;
2256 /* Get the position at which the redisplay_end_trigger hook should
2257 be run, if it is to be run at all. */
2258 if (MARKERP (w
->redisplay_end_trigger
)
2259 && XMARKER (w
->redisplay_end_trigger
)->buffer
!= 0)
2260 it
->redisplay_end_trigger_charpos
2261 = marker_position (w
->redisplay_end_trigger
);
2262 else if (INTEGERP (w
->redisplay_end_trigger
))
2263 it
->redisplay_end_trigger_charpos
= XINT (w
->redisplay_end_trigger
);
2265 /* Correct bogus values of tab_width. */
2266 it
->tab_width
= XINT (current_buffer
->tab_width
);
2267 if (it
->tab_width
<= 0 || it
->tab_width
> 1000)
2270 /* Are lines in the display truncated? */
2271 it
->truncate_lines_p
2272 = (base_face_id
!= DEFAULT_FACE_ID
2273 || XINT (it
->w
->hscroll
)
2274 || (truncate_partial_width_windows
2275 && !WINDOW_FULL_WIDTH_P (it
->w
))
2276 || !NILP (current_buffer
->truncate_lines
));
2278 /* Get dimensions of truncation and continuation glyphs. These are
2279 displayed as fringe bitmaps under X, so we don't need them for such
2281 if (!FRAME_WINDOW_P (it
->f
))
2283 if (it
->truncate_lines_p
)
2285 /* We will need the truncation glyph. */
2286 xassert (it
->glyph_row
== NULL
);
2287 produce_special_glyphs (it
, IT_TRUNCATION
);
2288 it
->truncation_pixel_width
= it
->pixel_width
;
2292 /* We will need the continuation glyph. */
2293 xassert (it
->glyph_row
== NULL
);
2294 produce_special_glyphs (it
, IT_CONTINUATION
);
2295 it
->continuation_pixel_width
= it
->pixel_width
;
2298 /* Reset these values to zero because the produce_special_glyphs
2299 above has changed them. */
2300 it
->pixel_width
= it
->ascent
= it
->descent
= 0;
2301 it
->phys_ascent
= it
->phys_descent
= 0;
2304 /* Set this after getting the dimensions of truncation and
2305 continuation glyphs, so that we don't produce glyphs when calling
2306 produce_special_glyphs, above. */
2307 it
->glyph_row
= row
;
2308 it
->area
= TEXT_AREA
;
2310 /* Get the dimensions of the display area. The display area
2311 consists of the visible window area plus a horizontally scrolled
2312 part to the left of the window. All x-values are relative to the
2313 start of this total display area. */
2314 if (base_face_id
!= DEFAULT_FACE_ID
)
2316 /* Mode lines, menu bar in terminal frames. */
2317 it
->first_visible_x
= 0;
2318 it
->last_visible_x
= WINDOW_TOTAL_WIDTH (w
);
2323 = XFASTINT (it
->w
->hscroll
) * FRAME_COLUMN_WIDTH (it
->f
);
2324 it
->last_visible_x
= (it
->first_visible_x
2325 + window_box_width (w
, TEXT_AREA
));
2327 /* If we truncate lines, leave room for the truncator glyph(s) at
2328 the right margin. Otherwise, leave room for the continuation
2329 glyph(s). Truncation and continuation glyphs are not inserted
2330 for window-based redisplay. */
2331 if (!FRAME_WINDOW_P (it
->f
))
2333 if (it
->truncate_lines_p
)
2334 it
->last_visible_x
-= it
->truncation_pixel_width
;
2336 it
->last_visible_x
-= it
->continuation_pixel_width
;
2339 it
->header_line_p
= WINDOW_WANTS_HEADER_LINE_P (w
);
2340 it
->current_y
= WINDOW_HEADER_LINE_HEIGHT (w
) + w
->vscroll
;
2343 /* Leave room for a border glyph. */
2344 if (!FRAME_WINDOW_P (it
->f
)
2345 && !WINDOW_RIGHTMOST_P (it
->w
))
2346 it
->last_visible_x
-= 1;
2348 it
->last_visible_y
= window_text_bottom_y (w
);
2350 /* For mode lines and alike, arrange for the first glyph having a
2351 left box line if the face specifies a box. */
2352 if (base_face_id
!= DEFAULT_FACE_ID
)
2356 it
->face_id
= base_face_id
;
2358 /* If we have a boxed mode line, make the first character appear
2359 with a left box line. */
2360 face
= FACE_FROM_ID (it
->f
, base_face_id
);
2361 if (face
->box
!= FACE_NO_BOX
)
2362 it
->start_of_box_run_p
= 1;
2365 /* If a buffer position was specified, set the iterator there,
2366 getting overlays and face properties from that position. */
2367 if (charpos
>= BUF_BEG (current_buffer
))
2369 it
->end_charpos
= ZV
;
2371 IT_CHARPOS (*it
) = charpos
;
2373 /* Compute byte position if not specified. */
2374 if (bytepos
< charpos
)
2375 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (charpos
);
2377 IT_BYTEPOS (*it
) = bytepos
;
2379 it
->start
= it
->current
;
2381 /* Compute faces etc. */
2382 reseat (it
, it
->current
.pos
, 1);
2389 /* Initialize IT for the display of window W with window start POS. */
2392 start_display (it
, w
, pos
)
2395 struct text_pos pos
;
2397 struct glyph_row
*row
;
2398 int first_vpos
= WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0;
2400 row
= w
->desired_matrix
->rows
+ first_vpos
;
2401 init_iterator (it
, w
, CHARPOS (pos
), BYTEPOS (pos
), row
, DEFAULT_FACE_ID
);
2402 it
->first_vpos
= first_vpos
;
2404 if (!it
->truncate_lines_p
)
2406 int start_at_line_beg_p
;
2407 int first_y
= it
->current_y
;
2409 /* If window start is not at a line start, skip forward to POS to
2410 get the correct continuation lines width. */
2411 start_at_line_beg_p
= (CHARPOS (pos
) == BEGV
2412 || FETCH_BYTE (BYTEPOS (pos
) - 1) == '\n');
2413 if (!start_at_line_beg_p
)
2417 reseat_at_previous_visible_line_start (it
);
2418 move_it_to (it
, CHARPOS (pos
), -1, -1, -1, MOVE_TO_POS
);
2420 new_x
= it
->current_x
+ it
->pixel_width
;
2422 /* If lines are continued, this line may end in the middle
2423 of a multi-glyph character (e.g. a control character
2424 displayed as \003, or in the middle of an overlay
2425 string). In this case move_it_to above will not have
2426 taken us to the start of the continuation line but to the
2427 end of the continued line. */
2428 if (it
->current_x
> 0
2429 && !it
->truncate_lines_p
/* Lines are continued. */
2430 && (/* And glyph doesn't fit on the line. */
2431 new_x
> it
->last_visible_x
2432 /* Or it fits exactly and we're on a window
2434 || (new_x
== it
->last_visible_x
2435 && FRAME_WINDOW_P (it
->f
))))
2437 if (it
->current
.dpvec_index
>= 0
2438 || it
->current
.overlay_string_index
>= 0)
2440 set_iterator_to_next (it
, 1);
2441 move_it_in_display_line_to (it
, -1, -1, 0);
2444 it
->continuation_lines_width
+= it
->current_x
;
2447 /* We're starting a new display line, not affected by the
2448 height of the continued line, so clear the appropriate
2449 fields in the iterator structure. */
2450 it
->max_ascent
= it
->max_descent
= 0;
2451 it
->max_phys_ascent
= it
->max_phys_descent
= 0;
2453 it
->current_y
= first_y
;
2455 it
->current_x
= it
->hpos
= 0;
2459 #if 0 /* Don't assert the following because start_display is sometimes
2460 called intentionally with a window start that is not at a
2461 line start. Please leave this code in as a comment. */
2463 /* Window start should be on a line start, now. */
2464 xassert (it
->continuation_lines_width
2465 || IT_CHARPOS (it
) == BEGV
2466 || FETCH_BYTE (IT_BYTEPOS (it
) - 1) == '\n');
2471 /* Return 1 if POS is a position in ellipses displayed for invisible
2472 text. W is the window we display, for text property lookup. */
2475 in_ellipses_for_invisible_text_p (pos
, w
)
2476 struct display_pos
*pos
;
2479 Lisp_Object prop
, window
;
2481 int charpos
= CHARPOS (pos
->pos
);
2483 /* If POS specifies a position in a display vector, this might
2484 be for an ellipsis displayed for invisible text. We won't
2485 get the iterator set up for delivering that ellipsis unless
2486 we make sure that it gets aware of the invisible text. */
2487 if (pos
->dpvec_index
>= 0
2488 && pos
->overlay_string_index
< 0
2489 && CHARPOS (pos
->string_pos
) < 0
2491 && (XSETWINDOW (window
, w
),
2492 prop
= Fget_char_property (make_number (charpos
),
2493 Qinvisible
, window
),
2494 !TEXT_PROP_MEANS_INVISIBLE (prop
)))
2496 prop
= Fget_char_property (make_number (charpos
- 1), Qinvisible
,
2498 ellipses_p
= 2 == TEXT_PROP_MEANS_INVISIBLE (prop
);
2505 /* Initialize IT for stepping through current_buffer in window W,
2506 starting at position POS that includes overlay string and display
2507 vector/ control character translation position information. Value
2508 is zero if there are overlay strings with newlines at POS. */
2511 init_from_display_pos (it
, w
, pos
)
2514 struct display_pos
*pos
;
2516 int charpos
= CHARPOS (pos
->pos
), bytepos
= BYTEPOS (pos
->pos
);
2517 int i
, overlay_strings_with_newlines
= 0;
2519 /* If POS specifies a position in a display vector, this might
2520 be for an ellipsis displayed for invisible text. We won't
2521 get the iterator set up for delivering that ellipsis unless
2522 we make sure that it gets aware of the invisible text. */
2523 if (in_ellipses_for_invisible_text_p (pos
, w
))
2529 /* Keep in mind: the call to reseat in init_iterator skips invisible
2530 text, so we might end up at a position different from POS. This
2531 is only a problem when POS is a row start after a newline and an
2532 overlay starts there with an after-string, and the overlay has an
2533 invisible property. Since we don't skip invisible text in
2534 display_line and elsewhere immediately after consuming the
2535 newline before the row start, such a POS will not be in a string,
2536 but the call to init_iterator below will move us to the
2538 init_iterator (it
, w
, charpos
, bytepos
, NULL
, DEFAULT_FACE_ID
);
2540 /* This only scans the current chunk -- it should scan all chunks.
2541 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
2542 to 16 in 22.1 to make this a lesser problem. */
2543 for (i
= 0; i
< it
->n_overlay_strings
&& i
< OVERLAY_STRING_CHUNK_SIZE
; ++i
)
2545 const char *s
= SDATA (it
->overlay_strings
[i
]);
2546 const char *e
= s
+ SBYTES (it
->overlay_strings
[i
]);
2548 while (s
< e
&& *s
!= '\n')
2553 overlay_strings_with_newlines
= 1;
2558 /* If position is within an overlay string, set up IT to the right
2560 if (pos
->overlay_string_index
>= 0)
2564 /* If the first overlay string happens to have a `display'
2565 property for an image, the iterator will be set up for that
2566 image, and we have to undo that setup first before we can
2567 correct the overlay string index. */
2568 if (it
->method
== GET_FROM_IMAGE
)
2571 /* We already have the first chunk of overlay strings in
2572 IT->overlay_strings. Load more until the one for
2573 pos->overlay_string_index is in IT->overlay_strings. */
2574 if (pos
->overlay_string_index
>= OVERLAY_STRING_CHUNK_SIZE
)
2576 int n
= pos
->overlay_string_index
/ OVERLAY_STRING_CHUNK_SIZE
;
2577 it
->current
.overlay_string_index
= 0;
2580 load_overlay_strings (it
, 0);
2581 it
->current
.overlay_string_index
+= OVERLAY_STRING_CHUNK_SIZE
;
2585 it
->current
.overlay_string_index
= pos
->overlay_string_index
;
2586 relative_index
= (it
->current
.overlay_string_index
2587 % OVERLAY_STRING_CHUNK_SIZE
);
2588 it
->string
= it
->overlay_strings
[relative_index
];
2589 xassert (STRINGP (it
->string
));
2590 it
->current
.string_pos
= pos
->string_pos
;
2591 it
->method
= GET_FROM_STRING
;
2594 #if 0 /* This is bogus because POS not having an overlay string
2595 position does not mean it's after the string. Example: A
2596 line starting with a before-string and initialization of IT
2597 to the previous row's end position. */
2598 else if (it
->current
.overlay_string_index
>= 0)
2600 /* If POS says we're already after an overlay string ending at
2601 POS, make sure to pop the iterator because it will be in
2602 front of that overlay string. When POS is ZV, we've thereby
2603 also ``processed'' overlay strings at ZV. */
2606 it
->current
.overlay_string_index
= -1;
2607 it
->method
= GET_FROM_BUFFER
;
2608 if (CHARPOS (pos
->pos
) == ZV
)
2609 it
->overlay_strings_at_end_processed_p
= 1;
2613 if (CHARPOS (pos
->string_pos
) >= 0)
2615 /* Recorded position is not in an overlay string, but in another
2616 string. This can only be a string from a `display' property.
2617 IT should already be filled with that string. */
2618 it
->current
.string_pos
= pos
->string_pos
;
2619 xassert (STRINGP (it
->string
));
2622 /* Restore position in display vector translations, control
2623 character translations or ellipses. */
2624 if (pos
->dpvec_index
>= 0)
2626 if (it
->dpvec
== NULL
)
2627 get_next_display_element (it
);
2628 xassert (it
->dpvec
&& it
->current
.dpvec_index
== 0);
2629 it
->current
.dpvec_index
= pos
->dpvec_index
;
2633 return !overlay_strings_with_newlines
;
2637 /* Initialize IT for stepping through current_buffer in window W
2638 starting at ROW->start. */
2641 init_to_row_start (it
, w
, row
)
2644 struct glyph_row
*row
;
2646 init_from_display_pos (it
, w
, &row
->start
);
2647 it
->start
= row
->start
;
2648 it
->continuation_lines_width
= row
->continuation_lines_width
;
2653 /* Initialize IT for stepping through current_buffer in window W
2654 starting in the line following ROW, i.e. starting at ROW->end.
2655 Value is zero if there are overlay strings with newlines at ROW's
2659 init_to_row_end (it
, w
, row
)
2662 struct glyph_row
*row
;
2666 if (init_from_display_pos (it
, w
, &row
->end
))
2668 if (row
->continued_p
)
2669 it
->continuation_lines_width
2670 = row
->continuation_lines_width
+ row
->pixel_width
;
2681 /***********************************************************************
2683 ***********************************************************************/
2685 /* Called when IT reaches IT->stop_charpos. Handle text property and
2686 overlay changes. Set IT->stop_charpos to the next position where
2693 enum prop_handled handled
;
2694 int handle_overlay_change_p
= 1;
2698 it
->current
.dpvec_index
= -1;
2702 handled
= HANDLED_NORMALLY
;
2704 /* Call text property handlers. */
2705 for (p
= it_props
; p
->handler
; ++p
)
2707 handled
= p
->handler (it
);
2709 if (handled
== HANDLED_RECOMPUTE_PROPS
)
2711 else if (handled
== HANDLED_RETURN
)
2713 else if (handled
== HANDLED_OVERLAY_STRING_CONSUMED
)
2714 handle_overlay_change_p
= 0;
2717 if (handled
!= HANDLED_RECOMPUTE_PROPS
)
2719 /* Don't check for overlay strings below when set to deliver
2720 characters from a display vector. */
2721 if (it
->method
== GET_FROM_DISPLAY_VECTOR
)
2722 handle_overlay_change_p
= 0;
2724 /* Handle overlay changes. */
2725 if (handle_overlay_change_p
)
2726 handled
= handle_overlay_change (it
);
2728 /* Determine where to stop next. */
2729 if (handled
== HANDLED_NORMALLY
)
2730 compute_stop_pos (it
);
2733 while (handled
== HANDLED_RECOMPUTE_PROPS
);
2737 /* Compute IT->stop_charpos from text property and overlay change
2738 information for IT's current position. */
2741 compute_stop_pos (it
)
2744 register INTERVAL iv
, next_iv
;
2745 Lisp_Object object
, limit
, position
;
2747 /* If nowhere else, stop at the end. */
2748 it
->stop_charpos
= it
->end_charpos
;
2750 if (STRINGP (it
->string
))
2752 /* Strings are usually short, so don't limit the search for
2754 object
= it
->string
;
2756 position
= make_number (IT_STRING_CHARPOS (*it
));
2762 /* If next overlay change is in front of the current stop pos
2763 (which is IT->end_charpos), stop there. Note: value of
2764 next_overlay_change is point-max if no overlay change
2766 charpos
= next_overlay_change (IT_CHARPOS (*it
));
2767 if (charpos
< it
->stop_charpos
)
2768 it
->stop_charpos
= charpos
;
2770 /* If showing the region, we have to stop at the region
2771 start or end because the face might change there. */
2772 if (it
->region_beg_charpos
> 0)
2774 if (IT_CHARPOS (*it
) < it
->region_beg_charpos
)
2775 it
->stop_charpos
= min (it
->stop_charpos
, it
->region_beg_charpos
);
2776 else if (IT_CHARPOS (*it
) < it
->region_end_charpos
)
2777 it
->stop_charpos
= min (it
->stop_charpos
, it
->region_end_charpos
);
2780 /* Set up variables for computing the stop position from text
2781 property changes. */
2782 XSETBUFFER (object
, current_buffer
);
2783 limit
= make_number (IT_CHARPOS (*it
) + TEXT_PROP_DISTANCE_LIMIT
);
2784 position
= make_number (IT_CHARPOS (*it
));
2788 /* Get the interval containing IT's position. Value is a null
2789 interval if there isn't such an interval. */
2790 iv
= validate_interval_range (object
, &position
, &position
, 0);
2791 if (!NULL_INTERVAL_P (iv
))
2793 Lisp_Object values_here
[LAST_PROP_IDX
];
2796 /* Get properties here. */
2797 for (p
= it_props
; p
->handler
; ++p
)
2798 values_here
[p
->idx
] = textget (iv
->plist
, *p
->name
);
2800 /* Look for an interval following iv that has different
2802 for (next_iv
= next_interval (iv
);
2803 (!NULL_INTERVAL_P (next_iv
)
2805 || XFASTINT (limit
) > next_iv
->position
));
2806 next_iv
= next_interval (next_iv
))
2808 for (p
= it_props
; p
->handler
; ++p
)
2810 Lisp_Object new_value
;
2812 new_value
= textget (next_iv
->plist
, *p
->name
);
2813 if (!EQ (values_here
[p
->idx
], new_value
))
2821 if (!NULL_INTERVAL_P (next_iv
))
2823 if (INTEGERP (limit
)
2824 && next_iv
->position
>= XFASTINT (limit
))
2825 /* No text property change up to limit. */
2826 it
->stop_charpos
= min (XFASTINT (limit
), it
->stop_charpos
);
2828 /* Text properties change in next_iv. */
2829 it
->stop_charpos
= min (it
->stop_charpos
, next_iv
->position
);
2833 xassert (STRINGP (it
->string
)
2834 || (it
->stop_charpos
>= BEGV
2835 && it
->stop_charpos
>= IT_CHARPOS (*it
)));
2839 /* Return the position of the next overlay change after POS in
2840 current_buffer. Value is point-max if no overlay change
2841 follows. This is like `next-overlay-change' but doesn't use
2845 next_overlay_change (pos
)
2850 Lisp_Object
*overlays
;
2853 /* Get all overlays at the given position. */
2854 GET_OVERLAYS_AT (pos
, overlays
, noverlays
, &endpos
, 1);
2856 /* If any of these overlays ends before endpos,
2857 use its ending point instead. */
2858 for (i
= 0; i
< noverlays
; ++i
)
2863 oend
= OVERLAY_END (overlays
[i
]);
2864 oendpos
= OVERLAY_POSITION (oend
);
2865 endpos
= min (endpos
, oendpos
);
2873 /***********************************************************************
2875 ***********************************************************************/
2877 /* Handle changes in the `fontified' property of the current buffer by
2878 calling hook functions from Qfontification_functions to fontify
2881 static enum prop_handled
2882 handle_fontified_prop (it
)
2885 Lisp_Object prop
, pos
;
2886 enum prop_handled handled
= HANDLED_NORMALLY
;
2888 /* Get the value of the `fontified' property at IT's current buffer
2889 position. (The `fontified' property doesn't have a special
2890 meaning in strings.) If the value is nil, call functions from
2891 Qfontification_functions. */
2892 if (!STRINGP (it
->string
)
2894 && !NILP (Vfontification_functions
)
2895 && !NILP (Vrun_hooks
)
2896 && (pos
= make_number (IT_CHARPOS (*it
)),
2897 prop
= Fget_char_property (pos
, Qfontified
, Qnil
),
2900 int count
= SPECPDL_INDEX ();
2903 val
= Vfontification_functions
;
2904 specbind (Qfontification_functions
, Qnil
);
2906 if (!CONSP (val
) || EQ (XCAR (val
), Qlambda
))
2907 safe_call1 (val
, pos
);
2910 Lisp_Object globals
, fn
;
2911 struct gcpro gcpro1
, gcpro2
;
2914 GCPRO2 (val
, globals
);
2916 for (; CONSP (val
); val
= XCDR (val
))
2922 /* A value of t indicates this hook has a local
2923 binding; it means to run the global binding too.
2924 In a global value, t should not occur. If it
2925 does, we must ignore it to avoid an endless
2927 for (globals
= Fdefault_value (Qfontification_functions
);
2929 globals
= XCDR (globals
))
2931 fn
= XCAR (globals
);
2933 safe_call1 (fn
, pos
);
2937 safe_call1 (fn
, pos
);
2943 unbind_to (count
, Qnil
);
2945 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
2946 something. This avoids an endless loop if they failed to
2947 fontify the text for which reason ever. */
2948 if (!NILP (Fget_char_property (pos
, Qfontified
, Qnil
)))
2949 handled
= HANDLED_RECOMPUTE_PROPS
;
2957 /***********************************************************************
2959 ***********************************************************************/
2961 /* Set up iterator IT from face properties at its current position.
2962 Called from handle_stop. */
2964 static enum prop_handled
2965 handle_face_prop (it
)
2968 int new_face_id
, next_stop
;
2970 if (!STRINGP (it
->string
))
2973 = face_at_buffer_position (it
->w
,
2975 it
->region_beg_charpos
,
2976 it
->region_end_charpos
,
2979 + TEXT_PROP_DISTANCE_LIMIT
),
2982 /* Is this a start of a run of characters with box face?
2983 Caveat: this can be called for a freshly initialized
2984 iterator; face_id is -1 in this case. We know that the new
2985 face will not change until limit, i.e. if the new face has a
2986 box, all characters up to limit will have one. But, as
2987 usual, we don't know whether limit is really the end. */
2988 if (new_face_id
!= it
->face_id
)
2990 struct face
*new_face
= FACE_FROM_ID (it
->f
, new_face_id
);
2992 /* If new face has a box but old face has not, this is
2993 the start of a run of characters with box, i.e. it has
2994 a shadow on the left side. The value of face_id of the
2995 iterator will be -1 if this is the initial call that gets
2996 the face. In this case, we have to look in front of IT's
2997 position and see whether there is a face != new_face_id. */
2998 it
->start_of_box_run_p
2999 = (new_face
->box
!= FACE_NO_BOX
3000 && (it
->face_id
>= 0
3001 || IT_CHARPOS (*it
) == BEG
3002 || new_face_id
!= face_before_it_pos (it
)));
3003 it
->face_box_p
= new_face
->box
!= FACE_NO_BOX
;
3008 int base_face_id
, bufpos
;
3010 if (it
->current
.overlay_string_index
>= 0)
3011 bufpos
= IT_CHARPOS (*it
);
3015 /* For strings from a buffer, i.e. overlay strings or strings
3016 from a `display' property, use the face at IT's current
3017 buffer position as the base face to merge with, so that
3018 overlay strings appear in the same face as surrounding
3019 text, unless they specify their own faces. */
3020 base_face_id
= underlying_face_id (it
);
3022 new_face_id
= face_at_string_position (it
->w
,
3024 IT_STRING_CHARPOS (*it
),
3026 it
->region_beg_charpos
,
3027 it
->region_end_charpos
,
3031 #if 0 /* This shouldn't be neccessary. Let's check it. */
3032 /* If IT is used to display a mode line we would really like to
3033 use the mode line face instead of the frame's default face. */
3034 if (it
->glyph_row
== MATRIX_MODE_LINE_ROW (it
->w
->desired_matrix
)
3035 && new_face_id
== DEFAULT_FACE_ID
)
3036 new_face_id
= CURRENT_MODE_LINE_FACE_ID (it
->w
);
3039 /* Is this a start of a run of characters with box? Caveat:
3040 this can be called for a freshly allocated iterator; face_id
3041 is -1 is this case. We know that the new face will not
3042 change until the next check pos, i.e. if the new face has a
3043 box, all characters up to that position will have a
3044 box. But, as usual, we don't know whether that position
3045 is really the end. */
3046 if (new_face_id
!= it
->face_id
)
3048 struct face
*new_face
= FACE_FROM_ID (it
->f
, new_face_id
);
3049 struct face
*old_face
= FACE_FROM_ID (it
->f
, it
->face_id
);
3051 /* If new face has a box but old face hasn't, this is the
3052 start of a run of characters with box, i.e. it has a
3053 shadow on the left side. */
3054 it
->start_of_box_run_p
3055 = new_face
->box
&& (old_face
== NULL
|| !old_face
->box
);
3056 it
->face_box_p
= new_face
->box
!= FACE_NO_BOX
;
3060 it
->face_id
= new_face_id
;
3061 return HANDLED_NORMALLY
;
3065 /* Return the ID of the face ``underlying'' IT's current position,
3066 which is in a string. If the iterator is associated with a
3067 buffer, return the face at IT's current buffer position.
3068 Otherwise, use the iterator's base_face_id. */
3071 underlying_face_id (it
)
3074 int face_id
= it
->base_face_id
, i
;
3076 xassert (STRINGP (it
->string
));
3078 for (i
= it
->sp
- 1; i
>= 0; --i
)
3079 if (NILP (it
->stack
[i
].string
))
3080 face_id
= it
->stack
[i
].face_id
;
3086 /* Compute the face one character before or after the current position
3087 of IT. BEFORE_P non-zero means get the face in front of IT's
3088 position. Value is the id of the face. */
3091 face_before_or_after_it_pos (it
, before_p
)
3096 int next_check_charpos
;
3097 struct text_pos pos
;
3099 xassert (it
->s
== NULL
);
3101 if (STRINGP (it
->string
))
3103 int bufpos
, base_face_id
;
3105 /* No face change past the end of the string (for the case
3106 we are padding with spaces). No face change before the
3108 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
)
3109 || (IT_STRING_CHARPOS (*it
) == 0 && before_p
))
3112 /* Set pos to the position before or after IT's current position. */
3114 pos
= string_pos (IT_STRING_CHARPOS (*it
) - 1, it
->string
);
3116 /* For composition, we must check the character after the
3118 pos
= (it
->what
== IT_COMPOSITION
3119 ? string_pos (IT_STRING_CHARPOS (*it
) + it
->cmp_len
, it
->string
)
3120 : string_pos (IT_STRING_CHARPOS (*it
) + 1, it
->string
));
3122 if (it
->current
.overlay_string_index
>= 0)
3123 bufpos
= IT_CHARPOS (*it
);
3127 base_face_id
= underlying_face_id (it
);
3129 /* Get the face for ASCII, or unibyte. */
3130 face_id
= face_at_string_position (it
->w
,
3134 it
->region_beg_charpos
,
3135 it
->region_end_charpos
,
3136 &next_check_charpos
,
3139 /* Correct the face for charsets different from ASCII. Do it
3140 for the multibyte case only. The face returned above is
3141 suitable for unibyte text if IT->string is unibyte. */
3142 if (STRING_MULTIBYTE (it
->string
))
3144 const unsigned char *p
= SDATA (it
->string
) + BYTEPOS (pos
);
3145 int rest
= SBYTES (it
->string
) - BYTEPOS (pos
);
3147 struct face
*face
= FACE_FROM_ID (it
->f
, face_id
);
3149 c
= string_char_and_length (p
, rest
, &len
);
3150 face_id
= FACE_FOR_CHAR (it
->f
, face
, c
);
3155 if ((IT_CHARPOS (*it
) >= ZV
&& !before_p
)
3156 || (IT_CHARPOS (*it
) <= BEGV
&& before_p
))
3159 limit
= IT_CHARPOS (*it
) + TEXT_PROP_DISTANCE_LIMIT
;
3160 pos
= it
->current
.pos
;
3163 DEC_TEXT_POS (pos
, it
->multibyte_p
);
3166 if (it
->what
== IT_COMPOSITION
)
3167 /* For composition, we must check the position after the
3169 pos
.charpos
+= it
->cmp_len
, pos
.bytepos
+= it
->len
;
3171 INC_TEXT_POS (pos
, it
->multibyte_p
);
3174 /* Determine face for CHARSET_ASCII, or unibyte. */
3175 face_id
= face_at_buffer_position (it
->w
,
3177 it
->region_beg_charpos
,
3178 it
->region_end_charpos
,
3179 &next_check_charpos
,
3182 /* Correct the face for charsets different from ASCII. Do it
3183 for the multibyte case only. The face returned above is
3184 suitable for unibyte text if current_buffer is unibyte. */
3185 if (it
->multibyte_p
)
3187 int c
= FETCH_MULTIBYTE_CHAR (BYTEPOS (pos
));
3188 struct face
*face
= FACE_FROM_ID (it
->f
, face_id
);
3189 face_id
= FACE_FOR_CHAR (it
->f
, face
, c
);
3198 /***********************************************************************
3200 ***********************************************************************/
3202 /* Set up iterator IT from invisible properties at its current
3203 position. Called from handle_stop. */
3205 static enum prop_handled
3206 handle_invisible_prop (it
)
3209 enum prop_handled handled
= HANDLED_NORMALLY
;
3211 if (STRINGP (it
->string
))
3213 extern Lisp_Object Qinvisible
;
3214 Lisp_Object prop
, end_charpos
, limit
, charpos
;
3216 /* Get the value of the invisible text property at the
3217 current position. Value will be nil if there is no such
3219 charpos
= make_number (IT_STRING_CHARPOS (*it
));
3220 prop
= Fget_text_property (charpos
, Qinvisible
, it
->string
);
3223 && IT_STRING_CHARPOS (*it
) < it
->end_charpos
)
3225 handled
= HANDLED_RECOMPUTE_PROPS
;
3227 /* Get the position at which the next change of the
3228 invisible text property can be found in IT->string.
3229 Value will be nil if the property value is the same for
3230 all the rest of IT->string. */
3231 XSETINT (limit
, SCHARS (it
->string
));
3232 end_charpos
= Fnext_single_property_change (charpos
, Qinvisible
,
3235 /* Text at current position is invisible. The next
3236 change in the property is at position end_charpos.
3237 Move IT's current position to that position. */
3238 if (INTEGERP (end_charpos
)
3239 && XFASTINT (end_charpos
) < XFASTINT (limit
))
3241 struct text_pos old
;
3242 old
= it
->current
.string_pos
;
3243 IT_STRING_CHARPOS (*it
) = XFASTINT (end_charpos
);
3244 compute_string_pos (&it
->current
.string_pos
, old
, it
->string
);
3248 /* The rest of the string is invisible. If this is an
3249 overlay string, proceed with the next overlay string
3250 or whatever comes and return a character from there. */
3251 if (it
->current
.overlay_string_index
>= 0)
3253 next_overlay_string (it
);
3254 /* Don't check for overlay strings when we just
3255 finished processing them. */
3256 handled
= HANDLED_OVERLAY_STRING_CONSUMED
;
3260 IT_STRING_CHARPOS (*it
) = SCHARS (it
->string
);
3261 IT_STRING_BYTEPOS (*it
) = SBYTES (it
->string
);
3268 int invis_p
, newpos
, next_stop
, start_charpos
;
3269 Lisp_Object pos
, prop
, overlay
;
3271 /* First of all, is there invisible text at this position? */
3272 start_charpos
= IT_CHARPOS (*it
);
3273 pos
= make_number (IT_CHARPOS (*it
));
3274 prop
= get_char_property_and_overlay (pos
, Qinvisible
, it
->window
,
3276 invis_p
= TEXT_PROP_MEANS_INVISIBLE (prop
);
3278 /* If we are on invisible text, skip over it. */
3279 if (invis_p
&& IT_CHARPOS (*it
) < it
->end_charpos
)
3281 /* Record whether we have to display an ellipsis for the
3283 int display_ellipsis_p
= invis_p
== 2;
3285 handled
= HANDLED_RECOMPUTE_PROPS
;
3287 /* Loop skipping over invisible text. The loop is left at
3288 ZV or with IT on the first char being visible again. */
3291 /* Try to skip some invisible text. Return value is the
3292 position reached which can be equal to IT's position
3293 if there is nothing invisible here. This skips both
3294 over invisible text properties and overlays with
3295 invisible property. */
3296 newpos
= skip_invisible (IT_CHARPOS (*it
),
3297 &next_stop
, ZV
, it
->window
);
3299 /* If we skipped nothing at all we weren't at invisible
3300 text in the first place. If everything to the end of
3301 the buffer was skipped, end the loop. */
3302 if (newpos
== IT_CHARPOS (*it
) || newpos
>= ZV
)
3306 /* We skipped some characters but not necessarily
3307 all there are. Check if we ended up on visible
3308 text. Fget_char_property returns the property of
3309 the char before the given position, i.e. if we
3310 get invis_p = 0, this means that the char at
3311 newpos is visible. */
3312 pos
= make_number (newpos
);
3313 prop
= Fget_char_property (pos
, Qinvisible
, it
->window
);
3314 invis_p
= TEXT_PROP_MEANS_INVISIBLE (prop
);
3317 /* If we ended up on invisible text, proceed to
3318 skip starting with next_stop. */
3320 IT_CHARPOS (*it
) = next_stop
;
3324 /* The position newpos is now either ZV or on visible text. */
3325 IT_CHARPOS (*it
) = newpos
;
3326 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (newpos
);
3328 /* If there are before-strings at the start of invisible
3329 text, and the text is invisible because of a text
3330 property, arrange to show before-strings because 20.x did
3331 it that way. (If the text is invisible because of an
3332 overlay property instead of a text property, this is
3333 already handled in the overlay code.) */
3335 && get_overlay_strings (it
, start_charpos
))
3337 handled
= HANDLED_RECOMPUTE_PROPS
;
3338 it
->stack
[it
->sp
- 1].display_ellipsis_p
= display_ellipsis_p
;
3340 else if (display_ellipsis_p
)
3341 setup_for_ellipsis (it
, 0);
3349 /* Make iterator IT return `...' next.
3350 Replaces LEN characters from buffer. */
3353 setup_for_ellipsis (it
, len
)
3357 /* Use the display table definition for `...'. Invalid glyphs
3358 will be handled by the method returning elements from dpvec. */
3359 if (it
->dp
&& VECTORP (DISP_INVIS_VECTOR (it
->dp
)))
3361 struct Lisp_Vector
*v
= XVECTOR (DISP_INVIS_VECTOR (it
->dp
));
3362 it
->dpvec
= v
->contents
;
3363 it
->dpend
= v
->contents
+ v
->size
;
3367 /* Default `...'. */
3368 it
->dpvec
= default_invis_vector
;
3369 it
->dpend
= default_invis_vector
+ 3;
3372 it
->dpvec_char_len
= len
;
3373 it
->current
.dpvec_index
= 0;
3374 it
->dpvec_face_id
= -1;
3376 /* Remember the current face id in case glyphs specify faces.
3377 IT's face is restored in set_iterator_to_next. */
3378 it
->saved_face_id
= it
->face_id
;
3379 it
->method
= GET_FROM_DISPLAY_VECTOR
;
3385 /***********************************************************************
3387 ***********************************************************************/
3389 /* Set up iterator IT from `display' property at its current position.
3390 Called from handle_stop.
3391 We return HANDLED_RETURN if some part of the display property
3392 overrides the display of the buffer text itself.
3393 Otherwise we return HANDLED_NORMALLY. */
3395 static enum prop_handled
3396 handle_display_prop (it
)
3399 Lisp_Object prop
, object
;
3400 struct text_pos
*position
;
3401 /* Nonzero if some property replaces the display of the text itself. */
3402 int display_replaced_p
= 0;
3404 if (STRINGP (it
->string
))
3406 object
= it
->string
;
3407 position
= &it
->current
.string_pos
;
3411 object
= it
->w
->buffer
;
3412 position
= &it
->current
.pos
;
3415 /* Reset those iterator values set from display property values. */
3416 it
->slice
.x
= it
->slice
.y
= it
->slice
.width
= it
->slice
.height
= Qnil
;
3417 it
->space_width
= Qnil
;
3418 it
->font_height
= Qnil
;
3421 /* We don't support recursive `display' properties, i.e. string
3422 values that have a string `display' property, that have a string
3423 `display' property etc. */
3424 if (!it
->string_from_display_prop_p
)
3425 it
->area
= TEXT_AREA
;
3427 prop
= Fget_char_property (make_number (position
->charpos
),
3430 return HANDLED_NORMALLY
;
3433 /* Simple properties. */
3434 && !EQ (XCAR (prop
), Qimage
)
3435 && !EQ (XCAR (prop
), Qspace
)
3436 && !EQ (XCAR (prop
), Qwhen
)
3437 && !EQ (XCAR (prop
), Qslice
)
3438 && !EQ (XCAR (prop
), Qspace_width
)
3439 && !EQ (XCAR (prop
), Qheight
)
3440 && !EQ (XCAR (prop
), Qraise
)
3441 /* Marginal area specifications. */
3442 && !(CONSP (XCAR (prop
)) && EQ (XCAR (XCAR (prop
)), Qmargin
))
3443 && !EQ (XCAR (prop
), Qleft_fringe
)
3444 && !EQ (XCAR (prop
), Qright_fringe
)
3445 && !NILP (XCAR (prop
)))
3447 for (; CONSP (prop
); prop
= XCDR (prop
))
3449 if (handle_single_display_spec (it
, XCAR (prop
), object
,
3450 position
, display_replaced_p
))
3451 display_replaced_p
= 1;
3454 else if (VECTORP (prop
))
3457 for (i
= 0; i
< ASIZE (prop
); ++i
)
3458 if (handle_single_display_spec (it
, AREF (prop
, i
), object
,
3459 position
, display_replaced_p
))
3460 display_replaced_p
= 1;
3464 if (handle_single_display_spec (it
, prop
, object
, position
, 0))
3465 display_replaced_p
= 1;
3468 return display_replaced_p
? HANDLED_RETURN
: HANDLED_NORMALLY
;
3472 /* Value is the position of the end of the `display' property starting
3473 at START_POS in OBJECT. */
3475 static struct text_pos
3476 display_prop_end (it
, object
, start_pos
)
3479 struct text_pos start_pos
;
3482 struct text_pos end_pos
;
3484 end
= Fnext_single_char_property_change (make_number (CHARPOS (start_pos
)),
3485 Qdisplay
, object
, Qnil
);
3486 CHARPOS (end_pos
) = XFASTINT (end
);
3487 if (STRINGP (object
))
3488 compute_string_pos (&end_pos
, start_pos
, it
->string
);
3490 BYTEPOS (end_pos
) = CHAR_TO_BYTE (XFASTINT (end
));
3496 /* Set up IT from a single `display' specification PROP. OBJECT
3497 is the object in which the `display' property was found. *POSITION
3498 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3499 means that we previously saw a display specification which already
3500 replaced text display with something else, for example an image;
3501 we ignore such properties after the first one has been processed.
3503 If PROP is a `space' or `image' specification, and in some other
3504 cases too, set *POSITION to the position where the `display'
3507 Value is non-zero if something was found which replaces the display
3508 of buffer or string text. */
3511 handle_single_display_spec (it
, spec
, object
, position
,
3512 display_replaced_before_p
)
3516 struct text_pos
*position
;
3517 int display_replaced_before_p
;
3520 Lisp_Object location
, value
;
3521 struct text_pos start_pos
;
3524 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
3525 If the result is non-nil, use VALUE instead of SPEC. */
3527 if (CONSP (spec
) && EQ (XCAR (spec
), Qwhen
))
3536 if (!NILP (form
) && !EQ (form
, Qt
))
3538 int count
= SPECPDL_INDEX ();
3539 struct gcpro gcpro1
;
3541 /* Bind `object' to the object having the `display' property, a
3542 buffer or string. Bind `position' to the position in the
3543 object where the property was found, and `buffer-position'
3544 to the current position in the buffer. */
3545 specbind (Qobject
, object
);
3546 specbind (Qposition
, make_number (CHARPOS (*position
)));
3547 specbind (Qbuffer_position
,
3548 make_number (STRINGP (object
)
3549 ? IT_CHARPOS (*it
) : CHARPOS (*position
)));
3551 form
= safe_eval (form
);
3553 unbind_to (count
, Qnil
);
3559 /* Handle `(height HEIGHT)' specifications. */
3561 && EQ (XCAR (spec
), Qheight
)
3562 && CONSP (XCDR (spec
)))
3564 if (FRAME_TERMCAP_P (it
->f
) || FRAME_MSDOS_P (it
->f
))
3567 it
->font_height
= XCAR (XCDR (spec
));
3568 if (!NILP (it
->font_height
))
3570 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
3571 int new_height
= -1;
3573 if (CONSP (it
->font_height
)
3574 && (EQ (XCAR (it
->font_height
), Qplus
)
3575 || EQ (XCAR (it
->font_height
), Qminus
))
3576 && CONSP (XCDR (it
->font_height
))
3577 && INTEGERP (XCAR (XCDR (it
->font_height
))))
3579 /* `(+ N)' or `(- N)' where N is an integer. */
3580 int steps
= XINT (XCAR (XCDR (it
->font_height
)));
3581 if (EQ (XCAR (it
->font_height
), Qplus
))
3583 it
->face_id
= smaller_face (it
->f
, it
->face_id
, steps
);
3585 else if (FUNCTIONP (it
->font_height
))
3587 /* Call function with current height as argument.
3588 Value is the new height. */
3590 height
= safe_call1 (it
->font_height
,
3591 face
->lface
[LFACE_HEIGHT_INDEX
]);
3592 if (NUMBERP (height
))
3593 new_height
= XFLOATINT (height
);
3595 else if (NUMBERP (it
->font_height
))
3597 /* Value is a multiple of the canonical char height. */
3600 face
= FACE_FROM_ID (it
->f
, DEFAULT_FACE_ID
);
3601 new_height
= (XFLOATINT (it
->font_height
)
3602 * XINT (face
->lface
[LFACE_HEIGHT_INDEX
]));
3606 /* Evaluate IT->font_height with `height' bound to the
3607 current specified height to get the new height. */
3608 int count
= SPECPDL_INDEX ();
3610 specbind (Qheight
, face
->lface
[LFACE_HEIGHT_INDEX
]);
3611 value
= safe_eval (it
->font_height
);
3612 unbind_to (count
, Qnil
);
3614 if (NUMBERP (value
))
3615 new_height
= XFLOATINT (value
);
3619 it
->face_id
= face_with_height (it
->f
, it
->face_id
, new_height
);
3625 /* Handle `(space_width WIDTH)'. */
3627 && EQ (XCAR (spec
), Qspace_width
)
3628 && CONSP (XCDR (spec
)))
3630 if (FRAME_TERMCAP_P (it
->f
) || FRAME_MSDOS_P (it
->f
))
3633 value
= XCAR (XCDR (spec
));
3634 if (NUMBERP (value
) && XFLOATINT (value
) > 0)
3635 it
->space_width
= value
;
3640 /* Handle `(slice X Y WIDTH HEIGHT)'. */
3642 && EQ (XCAR (spec
), Qslice
))
3646 if (FRAME_TERMCAP_P (it
->f
) || FRAME_MSDOS_P (it
->f
))
3649 if (tem
= XCDR (spec
), CONSP (tem
))
3651 it
->slice
.x
= XCAR (tem
);
3652 if (tem
= XCDR (tem
), CONSP (tem
))
3654 it
->slice
.y
= XCAR (tem
);
3655 if (tem
= XCDR (tem
), CONSP (tem
))
3657 it
->slice
.width
= XCAR (tem
);
3658 if (tem
= XCDR (tem
), CONSP (tem
))
3659 it
->slice
.height
= XCAR (tem
);
3667 /* Handle `(raise FACTOR)'. */
3669 && EQ (XCAR (spec
), Qraise
)
3670 && CONSP (XCDR (spec
)))
3672 if (FRAME_TERMCAP_P (it
->f
) || FRAME_MSDOS_P (it
->f
))
3675 #ifdef HAVE_WINDOW_SYSTEM
3676 value
= XCAR (XCDR (spec
));
3677 if (NUMBERP (value
))
3679 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
3680 it
->voffset
= - (XFLOATINT (value
)
3681 * (FONT_HEIGHT (face
->font
)));
3683 #endif /* HAVE_WINDOW_SYSTEM */
3688 /* Don't handle the other kinds of display specifications
3689 inside a string that we got from a `display' property. */
3690 if (it
->string_from_display_prop_p
)
3693 /* Characters having this form of property are not displayed, so
3694 we have to find the end of the property. */
3695 start_pos
= *position
;
3696 *position
= display_prop_end (it
, object
, start_pos
);
3699 /* Stop the scan at that end position--we assume that all
3700 text properties change there. */
3701 it
->stop_charpos
= position
->charpos
;
3703 /* Handle `(left-fringe BITMAP [FACE])'
3704 and `(right-fringe BITMAP [FACE])'. */
3706 && (EQ (XCAR (spec
), Qleft_fringe
)
3707 || EQ (XCAR (spec
), Qright_fringe
))
3708 && CONSP (XCDR (spec
)))
3710 int face_id
= DEFAULT_FACE_ID
;
3713 if (FRAME_TERMCAP_P (it
->f
) || FRAME_MSDOS_P (it
->f
))
3714 /* If we return here, POSITION has been advanced
3715 across the text with this property. */
3718 #ifdef HAVE_WINDOW_SYSTEM
3719 value
= XCAR (XCDR (spec
));
3720 if (!SYMBOLP (value
)
3721 || !(fringe_bitmap
= lookup_fringe_bitmap (value
)))
3722 /* If we return here, POSITION has been advanced
3723 across the text with this property. */
3726 if (CONSP (XCDR (XCDR (spec
))))
3728 Lisp_Object face_name
= XCAR (XCDR (XCDR (spec
)));
3729 int face_id2
= lookup_named_face (it
->f
, face_name
, 'A', 0);
3734 /* Save current settings of IT so that we can restore them
3735 when we are finished with the glyph property value. */
3739 it
->area
= TEXT_AREA
;
3740 it
->what
= IT_IMAGE
;
3741 it
->image_id
= -1; /* no image */
3742 it
->position
= start_pos
;
3743 it
->object
= NILP (object
) ? it
->w
->buffer
: object
;
3744 it
->method
= GET_FROM_IMAGE
;
3745 it
->face_id
= face_id
;
3747 /* Say that we haven't consumed the characters with
3748 `display' property yet. The call to pop_it in
3749 set_iterator_to_next will clean this up. */
3750 *position
= start_pos
;
3752 if (EQ (XCAR (spec
), Qleft_fringe
))
3754 it
->left_user_fringe_bitmap
= fringe_bitmap
;
3755 it
->left_user_fringe_face_id
= face_id
;
3759 it
->right_user_fringe_bitmap
= fringe_bitmap
;
3760 it
->right_user_fringe_face_id
= face_id
;
3762 #endif /* HAVE_WINDOW_SYSTEM */
3766 /* Prepare to handle `((margin left-margin) ...)',
3767 `((margin right-margin) ...)' and `((margin nil) ...)'
3768 prefixes for display specifications. */
3769 location
= Qunbound
;
3770 if (CONSP (spec
) && CONSP (XCAR (spec
)))
3774 value
= XCDR (spec
);
3776 value
= XCAR (value
);
3779 if (EQ (XCAR (tem
), Qmargin
)
3780 && (tem
= XCDR (tem
),
3781 tem
= CONSP (tem
) ? XCAR (tem
) : Qnil
,
3783 || EQ (tem
, Qleft_margin
)
3784 || EQ (tem
, Qright_margin
))))
3788 if (EQ (location
, Qunbound
))
3794 /* After this point, VALUE is the property after any
3795 margin prefix has been stripped. It must be a string,
3796 an image specification, or `(space ...)'.
3798 LOCATION specifies where to display: `left-margin',
3799 `right-margin' or nil. */
3801 valid_p
= (STRINGP (value
)
3802 #ifdef HAVE_WINDOW_SYSTEM
3803 || (!FRAME_TERMCAP_P (it
->f
) && valid_image_p (value
))
3804 #endif /* not HAVE_WINDOW_SYSTEM */
3805 || (CONSP (value
) && EQ (XCAR (value
), Qspace
)));
3807 if (valid_p
&& !display_replaced_before_p
)
3809 /* Save current settings of IT so that we can restore them
3810 when we are finished with the glyph property value. */
3813 if (NILP (location
))
3814 it
->area
= TEXT_AREA
;
3815 else if (EQ (location
, Qleft_margin
))
3816 it
->area
= LEFT_MARGIN_AREA
;
3818 it
->area
= RIGHT_MARGIN_AREA
;
3820 if (STRINGP (value
))
3823 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
3824 it
->current
.overlay_string_index
= -1;
3825 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = 0;
3826 it
->end_charpos
= it
->string_nchars
= SCHARS (it
->string
);
3827 it
->method
= GET_FROM_STRING
;
3828 it
->stop_charpos
= 0;
3829 it
->string_from_display_prop_p
= 1;
3830 /* Say that we haven't consumed the characters with
3831 `display' property yet. The call to pop_it in
3832 set_iterator_to_next will clean this up. */
3833 *position
= start_pos
;
3835 else if (CONSP (value
) && EQ (XCAR (value
), Qspace
))
3837 it
->method
= GET_FROM_STRETCH
;
3839 it
->current
.pos
= it
->position
= start_pos
;
3841 #ifdef HAVE_WINDOW_SYSTEM
3844 it
->what
= IT_IMAGE
;
3845 it
->image_id
= lookup_image (it
->f
, value
);
3846 it
->position
= start_pos
;
3847 it
->object
= NILP (object
) ? it
->w
->buffer
: object
;
3848 it
->method
= GET_FROM_IMAGE
;
3850 /* Say that we haven't consumed the characters with
3851 `display' property yet. The call to pop_it in
3852 set_iterator_to_next will clean this up. */
3853 *position
= start_pos
;
3855 #endif /* HAVE_WINDOW_SYSTEM */
3860 /* Invalid property or property not supported. Restore
3861 POSITION to what it was before. */
3862 *position
= start_pos
;
3867 /* Check if SPEC is a display specification value whose text should be
3868 treated as intangible. */
3871 single_display_spec_intangible_p (prop
)
3874 /* Skip over `when FORM'. */
3875 if (CONSP (prop
) && EQ (XCAR (prop
), Qwhen
))
3889 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
3890 we don't need to treat text as intangible. */
3891 if (EQ (XCAR (prop
), Qmargin
))
3899 || EQ (XCAR (prop
), Qleft_margin
)
3900 || EQ (XCAR (prop
), Qright_margin
))
3904 return (CONSP (prop
)
3905 && (EQ (XCAR (prop
), Qimage
)
3906 || EQ (XCAR (prop
), Qspace
)));
3910 /* Check if PROP is a display property value whose text should be
3911 treated as intangible. */
3914 display_prop_intangible_p (prop
)
3918 && CONSP (XCAR (prop
))
3919 && !EQ (Qmargin
, XCAR (XCAR (prop
))))
3921 /* A list of sub-properties. */
3922 while (CONSP (prop
))
3924 if (single_display_spec_intangible_p (XCAR (prop
)))
3929 else if (VECTORP (prop
))
3931 /* A vector of sub-properties. */
3933 for (i
= 0; i
< ASIZE (prop
); ++i
)
3934 if (single_display_spec_intangible_p (AREF (prop
, i
)))
3938 return single_display_spec_intangible_p (prop
);
3944 /* Return 1 if PROP is a display sub-property value containing STRING. */
3947 single_display_spec_string_p (prop
, string
)
3948 Lisp_Object prop
, string
;
3950 if (EQ (string
, prop
))
3953 /* Skip over `when FORM'. */
3954 if (CONSP (prop
) && EQ (XCAR (prop
), Qwhen
))
3963 /* Skip over `margin LOCATION'. */
3964 if (EQ (XCAR (prop
), Qmargin
))
3975 return CONSP (prop
) && EQ (XCAR (prop
), string
);
3979 /* Return 1 if STRING appears in the `display' property PROP. */
3982 display_prop_string_p (prop
, string
)
3983 Lisp_Object prop
, string
;
3986 && CONSP (XCAR (prop
))
3987 && !EQ (Qmargin
, XCAR (XCAR (prop
))))
3989 /* A list of sub-properties. */
3990 while (CONSP (prop
))
3992 if (single_display_spec_string_p (XCAR (prop
), string
))
3997 else if (VECTORP (prop
))
3999 /* A vector of sub-properties. */
4001 for (i
= 0; i
< ASIZE (prop
); ++i
)
4002 if (single_display_spec_string_p (AREF (prop
, i
), string
))
4006 return single_display_spec_string_p (prop
, string
);
4012 /* Determine from which buffer position in W's buffer STRING comes
4013 from. AROUND_CHARPOS is an approximate position where it could
4014 be from. Value is the buffer position or 0 if it couldn't be
4017 W's buffer must be current.
4019 This function is necessary because we don't record buffer positions
4020 in glyphs generated from strings (to keep struct glyph small).
4021 This function may only use code that doesn't eval because it is
4022 called asynchronously from note_mouse_highlight. */
4025 string_buffer_position (w
, string
, around_charpos
)
4030 Lisp_Object limit
, prop
, pos
;
4031 const int MAX_DISTANCE
= 1000;
4034 pos
= make_number (around_charpos
);
4035 limit
= make_number (min (XINT (pos
) + MAX_DISTANCE
, ZV
));
4036 while (!found
&& !EQ (pos
, limit
))
4038 prop
= Fget_char_property (pos
, Qdisplay
, Qnil
);
4039 if (!NILP (prop
) && display_prop_string_p (prop
, string
))
4042 pos
= Fnext_single_char_property_change (pos
, Qdisplay
, Qnil
, limit
);
4047 pos
= make_number (around_charpos
);
4048 limit
= make_number (max (XINT (pos
) - MAX_DISTANCE
, BEGV
));
4049 while (!found
&& !EQ (pos
, limit
))
4051 prop
= Fget_char_property (pos
, Qdisplay
, Qnil
);
4052 if (!NILP (prop
) && display_prop_string_p (prop
, string
))
4055 pos
= Fprevious_single_char_property_change (pos
, Qdisplay
, Qnil
,
4060 return found
? XINT (pos
) : 0;
4065 /***********************************************************************
4066 `composition' property
4067 ***********************************************************************/
4069 /* Set up iterator IT from `composition' property at its current
4070 position. Called from handle_stop. */
4072 static enum prop_handled
4073 handle_composition_prop (it
)
4076 Lisp_Object prop
, string
;
4077 int pos
, pos_byte
, end
;
4078 enum prop_handled handled
= HANDLED_NORMALLY
;
4080 if (STRINGP (it
->string
))
4082 pos
= IT_STRING_CHARPOS (*it
);
4083 pos_byte
= IT_STRING_BYTEPOS (*it
);
4084 string
= it
->string
;
4088 pos
= IT_CHARPOS (*it
);
4089 pos_byte
= IT_BYTEPOS (*it
);
4093 /* If there's a valid composition and point is not inside of the
4094 composition (in the case that the composition is from the current
4095 buffer), draw a glyph composed from the composition components. */
4096 if (find_composition (pos
, -1, &pos
, &end
, &prop
, string
)
4097 && COMPOSITION_VALID_P (pos
, end
, prop
)
4098 && (STRINGP (it
->string
) || (PT
<= pos
|| PT
>= end
)))
4100 int id
= get_composition_id (pos
, pos_byte
, end
- pos
, prop
, string
);
4104 it
->method
= GET_FROM_COMPOSITION
;
4106 it
->cmp_len
= COMPOSITION_LENGTH (prop
);
4107 /* For a terminal, draw only the first character of the
4109 it
->c
= COMPOSITION_GLYPH (composition_table
[id
], 0);
4110 it
->len
= (STRINGP (it
->string
)
4111 ? string_char_to_byte (it
->string
, end
)
4112 : CHAR_TO_BYTE (end
)) - pos_byte
;
4113 it
->stop_charpos
= end
;
4114 handled
= HANDLED_RETURN
;
4123 /***********************************************************************
4125 ***********************************************************************/
4127 /* The following structure is used to record overlay strings for
4128 later sorting in load_overlay_strings. */
4130 struct overlay_entry
4132 Lisp_Object overlay
;
4139 /* Set up iterator IT from overlay strings at its current position.
4140 Called from handle_stop. */
4142 static enum prop_handled
4143 handle_overlay_change (it
)
4146 if (!STRINGP (it
->string
) && get_overlay_strings (it
, 0))
4147 return HANDLED_RECOMPUTE_PROPS
;
4149 return HANDLED_NORMALLY
;
4153 /* Set up the next overlay string for delivery by IT, if there is an
4154 overlay string to deliver. Called by set_iterator_to_next when the
4155 end of the current overlay string is reached. If there are more
4156 overlay strings to display, IT->string and
4157 IT->current.overlay_string_index are set appropriately here.
4158 Otherwise IT->string is set to nil. */
4161 next_overlay_string (it
)
4164 ++it
->current
.overlay_string_index
;
4165 if (it
->current
.overlay_string_index
== it
->n_overlay_strings
)
4167 /* No more overlay strings. Restore IT's settings to what
4168 they were before overlay strings were processed, and
4169 continue to deliver from current_buffer. */
4170 int display_ellipsis_p
= it
->stack
[it
->sp
- 1].display_ellipsis_p
;
4173 xassert (it
->stop_charpos
>= BEGV
4174 && it
->stop_charpos
<= it
->end_charpos
);
4176 it
->current
.overlay_string_index
= -1;
4177 SET_TEXT_POS (it
->current
.string_pos
, -1, -1);
4178 it
->n_overlay_strings
= 0;
4179 it
->method
= GET_FROM_BUFFER
;
4181 /* If we're at the end of the buffer, record that we have
4182 processed the overlay strings there already, so that
4183 next_element_from_buffer doesn't try it again. */
4184 if (IT_CHARPOS (*it
) >= it
->end_charpos
)
4185 it
->overlay_strings_at_end_processed_p
= 1;
4187 /* If we have to display `...' for invisible text, set
4188 the iterator up for that. */
4189 if (display_ellipsis_p
)
4190 setup_for_ellipsis (it
, 0);
4194 /* There are more overlay strings to process. If
4195 IT->current.overlay_string_index has advanced to a position
4196 where we must load IT->overlay_strings with more strings, do
4198 int i
= it
->current
.overlay_string_index
% OVERLAY_STRING_CHUNK_SIZE
;
4200 if (it
->current
.overlay_string_index
&& i
== 0)
4201 load_overlay_strings (it
, 0);
4203 /* Initialize IT to deliver display elements from the overlay
4205 it
->string
= it
->overlay_strings
[i
];
4206 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
4207 SET_TEXT_POS (it
->current
.string_pos
, 0, 0);
4208 it
->method
= GET_FROM_STRING
;
4209 it
->stop_charpos
= 0;
4216 /* Compare two overlay_entry structures E1 and E2. Used as a
4217 comparison function for qsort in load_overlay_strings. Overlay
4218 strings for the same position are sorted so that
4220 1. All after-strings come in front of before-strings, except
4221 when they come from the same overlay.
4223 2. Within after-strings, strings are sorted so that overlay strings
4224 from overlays with higher priorities come first.
4226 2. Within before-strings, strings are sorted so that overlay
4227 strings from overlays with higher priorities come last.
4229 Value is analogous to strcmp. */
4233 compare_overlay_entries (e1
, e2
)
4236 struct overlay_entry
*entry1
= (struct overlay_entry
*) e1
;
4237 struct overlay_entry
*entry2
= (struct overlay_entry
*) e2
;
4240 if (entry1
->after_string_p
!= entry2
->after_string_p
)
4242 /* Let after-strings appear in front of before-strings if
4243 they come from different overlays. */
4244 if (EQ (entry1
->overlay
, entry2
->overlay
))
4245 result
= entry1
->after_string_p
? 1 : -1;
4247 result
= entry1
->after_string_p
? -1 : 1;
4249 else if (entry1
->after_string_p
)
4250 /* After-strings sorted in order of decreasing priority. */
4251 result
= entry2
->priority
- entry1
->priority
;
4253 /* Before-strings sorted in order of increasing priority. */
4254 result
= entry1
->priority
- entry2
->priority
;
4260 /* Load the vector IT->overlay_strings with overlay strings from IT's
4261 current buffer position, or from CHARPOS if that is > 0. Set
4262 IT->n_overlays to the total number of overlay strings found.
4264 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4265 a time. On entry into load_overlay_strings,
4266 IT->current.overlay_string_index gives the number of overlay
4267 strings that have already been loaded by previous calls to this
4270 IT->add_overlay_start contains an additional overlay start
4271 position to consider for taking overlay strings from, if non-zero.
4272 This position comes into play when the overlay has an `invisible'
4273 property, and both before and after-strings. When we've skipped to
4274 the end of the overlay, because of its `invisible' property, we
4275 nevertheless want its before-string to appear.
4276 IT->add_overlay_start will contain the overlay start position
4279 Overlay strings are sorted so that after-string strings come in
4280 front of before-string strings. Within before and after-strings,
4281 strings are sorted by overlay priority. See also function
4282 compare_overlay_entries. */
4285 load_overlay_strings (it
, charpos
)
4289 extern Lisp_Object Qafter_string
, Qbefore_string
, Qwindow
, Qpriority
;
4290 Lisp_Object overlay
, window
, str
, invisible
;
4291 struct Lisp_Overlay
*ov
;
4294 int n
= 0, i
, j
, invis_p
;
4295 struct overlay_entry
*entries
4296 = (struct overlay_entry
*) alloca (size
* sizeof *entries
);
4299 charpos
= IT_CHARPOS (*it
);
4301 /* Append the overlay string STRING of overlay OVERLAY to vector
4302 `entries' which has size `size' and currently contains `n'
4303 elements. AFTER_P non-zero means STRING is an after-string of
4305 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4308 Lisp_Object priority; \
4312 int new_size = 2 * size; \
4313 struct overlay_entry *old = entries; \
4315 (struct overlay_entry *) alloca (new_size \
4316 * sizeof *entries); \
4317 bcopy (old, entries, size * sizeof *entries); \
4321 entries[n].string = (STRING); \
4322 entries[n].overlay = (OVERLAY); \
4323 priority = Foverlay_get ((OVERLAY), Qpriority); \
4324 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4325 entries[n].after_string_p = (AFTER_P); \
4330 /* Process overlay before the overlay center. */
4331 for (ov
= current_buffer
->overlays_before
; ov
; ov
= ov
->next
)
4333 XSETMISC (overlay
, ov
);
4334 xassert (OVERLAYP (overlay
));
4335 start
= OVERLAY_POSITION (OVERLAY_START (overlay
));
4336 end
= OVERLAY_POSITION (OVERLAY_END (overlay
));
4341 /* Skip this overlay if it doesn't start or end at IT's current
4343 if (end
!= charpos
&& start
!= charpos
)
4346 /* Skip this overlay if it doesn't apply to IT->w. */
4347 window
= Foverlay_get (overlay
, Qwindow
);
4348 if (WINDOWP (window
) && XWINDOW (window
) != it
->w
)
4351 /* If the text ``under'' the overlay is invisible, both before-
4352 and after-strings from this overlay are visible; start and
4353 end position are indistinguishable. */
4354 invisible
= Foverlay_get (overlay
, Qinvisible
);
4355 invis_p
= TEXT_PROP_MEANS_INVISIBLE (invisible
);
4357 /* If overlay has a non-empty before-string, record it. */
4358 if ((start
== charpos
|| (end
== charpos
&& invis_p
))
4359 && (str
= Foverlay_get (overlay
, Qbefore_string
), STRINGP (str
))
4361 RECORD_OVERLAY_STRING (overlay
, str
, 0);
4363 /* If overlay has a non-empty after-string, record it. */
4364 if ((end
== charpos
|| (start
== charpos
&& invis_p
))
4365 && (str
= Foverlay_get (overlay
, Qafter_string
), STRINGP (str
))
4367 RECORD_OVERLAY_STRING (overlay
, str
, 1);
4370 /* Process overlays after the overlay center. */
4371 for (ov
= current_buffer
->overlays_after
; ov
; ov
= ov
->next
)
4373 XSETMISC (overlay
, ov
);
4374 xassert (OVERLAYP (overlay
));
4375 start
= OVERLAY_POSITION (OVERLAY_START (overlay
));
4376 end
= OVERLAY_POSITION (OVERLAY_END (overlay
));
4378 if (start
> charpos
)
4381 /* Skip this overlay if it doesn't start or end at IT's current
4383 if (end
!= charpos
&& start
!= charpos
)
4386 /* Skip this overlay if it doesn't apply to IT->w. */
4387 window
= Foverlay_get (overlay
, Qwindow
);
4388 if (WINDOWP (window
) && XWINDOW (window
) != it
->w
)
4391 /* If the text ``under'' the overlay is invisible, it has a zero
4392 dimension, and both before- and after-strings apply. */
4393 invisible
= Foverlay_get (overlay
, Qinvisible
);
4394 invis_p
= TEXT_PROP_MEANS_INVISIBLE (invisible
);
4396 /* If overlay has a non-empty before-string, record it. */
4397 if ((start
== charpos
|| (end
== charpos
&& invis_p
))
4398 && (str
= Foverlay_get (overlay
, Qbefore_string
), STRINGP (str
))
4400 RECORD_OVERLAY_STRING (overlay
, str
, 0);
4402 /* If overlay has a non-empty after-string, record it. */
4403 if ((end
== charpos
|| (start
== charpos
&& invis_p
))
4404 && (str
= Foverlay_get (overlay
, Qafter_string
), STRINGP (str
))
4406 RECORD_OVERLAY_STRING (overlay
, str
, 1);
4409 #undef RECORD_OVERLAY_STRING
4413 qsort (entries
, n
, sizeof *entries
, compare_overlay_entries
);
4415 /* Record the total number of strings to process. */
4416 it
->n_overlay_strings
= n
;
4418 /* IT->current.overlay_string_index is the number of overlay strings
4419 that have already been consumed by IT. Copy some of the
4420 remaining overlay strings to IT->overlay_strings. */
4422 j
= it
->current
.overlay_string_index
;
4423 while (i
< OVERLAY_STRING_CHUNK_SIZE
&& j
< n
)
4424 it
->overlay_strings
[i
++] = entries
[j
++].string
;
4430 /* Get the first chunk of overlay strings at IT's current buffer
4431 position, or at CHARPOS if that is > 0. Value is non-zero if at
4432 least one overlay string was found. */
4435 get_overlay_strings (it
, charpos
)
4439 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4440 process. This fills IT->overlay_strings with strings, and sets
4441 IT->n_overlay_strings to the total number of strings to process.
4442 IT->pos.overlay_string_index has to be set temporarily to zero
4443 because load_overlay_strings needs this; it must be set to -1
4444 when no overlay strings are found because a zero value would
4445 indicate a position in the first overlay string. */
4446 it
->current
.overlay_string_index
= 0;
4447 load_overlay_strings (it
, charpos
);
4449 /* If we found overlay strings, set up IT to deliver display
4450 elements from the first one. Otherwise set up IT to deliver
4451 from current_buffer. */
4452 if (it
->n_overlay_strings
)
4454 /* Make sure we know settings in current_buffer, so that we can
4455 restore meaningful values when we're done with the overlay
4457 compute_stop_pos (it
);
4458 xassert (it
->face_id
>= 0);
4460 /* Save IT's settings. They are restored after all overlay
4461 strings have been processed. */
4462 xassert (it
->sp
== 0);
4465 /* Set up IT to deliver display elements from the first overlay
4467 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = 0;
4468 it
->string
= it
->overlay_strings
[0];
4469 it
->stop_charpos
= 0;
4470 xassert (STRINGP (it
->string
));
4471 it
->end_charpos
= SCHARS (it
->string
);
4472 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
4473 it
->method
= GET_FROM_STRING
;
4478 it
->current
.overlay_string_index
= -1;
4479 it
->method
= GET_FROM_BUFFER
;
4484 /* Value is non-zero if we found at least one overlay string. */
4485 return STRINGP (it
->string
);
4490 /***********************************************************************
4491 Saving and restoring state
4492 ***********************************************************************/
4494 /* Save current settings of IT on IT->stack. Called, for example,
4495 before setting up IT for an overlay string, to be able to restore
4496 IT's settings to what they were after the overlay string has been
4503 struct iterator_stack_entry
*p
;
4505 xassert (it
->sp
< 2);
4506 p
= it
->stack
+ it
->sp
;
4508 p
->stop_charpos
= it
->stop_charpos
;
4509 xassert (it
->face_id
>= 0);
4510 p
->face_id
= it
->face_id
;
4511 p
->string
= it
->string
;
4512 p
->pos
= it
->current
;
4513 p
->end_charpos
= it
->end_charpos
;
4514 p
->string_nchars
= it
->string_nchars
;
4516 p
->multibyte_p
= it
->multibyte_p
;
4517 p
->slice
= it
->slice
;
4518 p
->space_width
= it
->space_width
;
4519 p
->font_height
= it
->font_height
;
4520 p
->voffset
= it
->voffset
;
4521 p
->string_from_display_prop_p
= it
->string_from_display_prop_p
;
4522 p
->display_ellipsis_p
= 0;
4527 /* Restore IT's settings from IT->stack. Called, for example, when no
4528 more overlay strings must be processed, and we return to delivering
4529 display elements from a buffer, or when the end of a string from a
4530 `display' property is reached and we return to delivering display
4531 elements from an overlay string, or from a buffer. */
4537 struct iterator_stack_entry
*p
;
4539 xassert (it
->sp
> 0);
4541 p
= it
->stack
+ it
->sp
;
4542 it
->stop_charpos
= p
->stop_charpos
;
4543 it
->face_id
= p
->face_id
;
4544 it
->string
= p
->string
;
4545 it
->current
= p
->pos
;
4546 it
->end_charpos
= p
->end_charpos
;
4547 it
->string_nchars
= p
->string_nchars
;
4549 it
->multibyte_p
= p
->multibyte_p
;
4550 it
->slice
= p
->slice
;
4551 it
->space_width
= p
->space_width
;
4552 it
->font_height
= p
->font_height
;
4553 it
->voffset
= p
->voffset
;
4554 it
->string_from_display_prop_p
= p
->string_from_display_prop_p
;
4559 /***********************************************************************
4561 ***********************************************************************/
4563 /* Set IT's current position to the previous line start. */
4566 back_to_previous_line_start (it
)
4569 IT_CHARPOS (*it
) = find_next_newline_no_quit (IT_CHARPOS (*it
) - 1, -1);
4570 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (IT_CHARPOS (*it
));
4574 /* Move IT to the next line start.
4576 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
4577 we skipped over part of the text (as opposed to moving the iterator
4578 continuously over the text). Otherwise, don't change the value
4581 Newlines may come from buffer text, overlay strings, or strings
4582 displayed via the `display' property. That's the reason we can't
4583 simply use find_next_newline_no_quit.
4585 Note that this function may not skip over invisible text that is so
4586 because of text properties and immediately follows a newline. If
4587 it would, function reseat_at_next_visible_line_start, when called
4588 from set_iterator_to_next, would effectively make invisible
4589 characters following a newline part of the wrong glyph row, which
4590 leads to wrong cursor motion. */
4593 forward_to_next_line_start (it
, skipped_p
)
4597 int old_selective
, newline_found_p
, n
;
4598 const int MAX_NEWLINE_DISTANCE
= 500;
4600 /* If already on a newline, just consume it to avoid unintended
4601 skipping over invisible text below. */
4602 if (it
->what
== IT_CHARACTER
4604 && CHARPOS (it
->position
) == IT_CHARPOS (*it
))
4606 set_iterator_to_next (it
, 0);
4611 /* Don't handle selective display in the following. It's (a)
4612 unnecessary because it's done by the caller, and (b) leads to an
4613 infinite recursion because next_element_from_ellipsis indirectly
4614 calls this function. */
4615 old_selective
= it
->selective
;
4618 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
4619 from buffer text. */
4620 for (n
= newline_found_p
= 0;
4621 !newline_found_p
&& n
< MAX_NEWLINE_DISTANCE
;
4622 n
+= STRINGP (it
->string
) ? 0 : 1)
4624 if (!get_next_display_element (it
))
4626 newline_found_p
= it
->what
== IT_CHARACTER
&& it
->c
== '\n';
4627 set_iterator_to_next (it
, 0);
4630 /* If we didn't find a newline near enough, see if we can use a
4632 if (!newline_found_p
)
4634 int start
= IT_CHARPOS (*it
);
4635 int limit
= find_next_newline_no_quit (start
, 1);
4638 xassert (!STRINGP (it
->string
));
4640 /* If there isn't any `display' property in sight, and no
4641 overlays, we can just use the position of the newline in
4643 if (it
->stop_charpos
>= limit
4644 || ((pos
= Fnext_single_property_change (make_number (start
),
4646 Qnil
, make_number (limit
)),
4648 && next_overlay_change (start
) == ZV
))
4650 IT_CHARPOS (*it
) = limit
;
4651 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (limit
);
4652 *skipped_p
= newline_found_p
= 1;
4656 while (get_next_display_element (it
)
4657 && !newline_found_p
)
4659 newline_found_p
= ITERATOR_AT_END_OF_LINE_P (it
);
4660 set_iterator_to_next (it
, 0);
4665 it
->selective
= old_selective
;
4666 return newline_found_p
;
4670 /* Set IT's current position to the previous visible line start. Skip
4671 invisible text that is so either due to text properties or due to
4672 selective display. Caution: this does not change IT->current_x and
4676 back_to_previous_visible_line_start (it
)
4679 while (IT_CHARPOS (*it
) > BEGV
)
4681 back_to_previous_line_start (it
);
4682 if (IT_CHARPOS (*it
) <= BEGV
)
4685 /* If selective > 0, then lines indented more than that values
4687 if (it
->selective
> 0
4688 && indented_beyond_p (IT_CHARPOS (*it
), IT_BYTEPOS (*it
),
4689 (double) it
->selective
)) /* iftc */
4692 /* Check the newline before point for invisibility. */
4695 prop
= Fget_char_property (make_number (IT_CHARPOS (*it
) - 1),
4696 Qinvisible
, it
->window
);
4697 if (TEXT_PROP_MEANS_INVISIBLE (prop
))
4701 /* If newline has a display property that replaces the newline with something
4702 else (image or text), find start of overlay or interval and continue search
4704 if (IT_CHARPOS (*it
) > BEGV
)
4706 struct it it2
= *it
;
4709 Lisp_Object val
, overlay
;
4711 pos
= --IT_CHARPOS (it2
);
4714 if (handle_display_prop (&it2
) == HANDLED_RETURN
4715 && !NILP (val
= get_char_property_and_overlay
4716 (make_number (pos
), Qdisplay
, Qnil
, &overlay
))
4717 && (OVERLAYP (overlay
)
4718 ? (beg
= OVERLAY_POSITION (OVERLAY_START (overlay
)))
4719 : get_property_and_range (pos
, Qdisplay
, &val
, &beg
, &end
, Qnil
)))
4723 IT_CHARPOS (*it
) = beg
;
4724 IT_BYTEPOS (*it
) = buf_charpos_to_bytepos (current_buffer
, beg
);
4732 xassert (IT_CHARPOS (*it
) >= BEGV
);
4733 xassert (IT_CHARPOS (*it
) == BEGV
4734 || FETCH_BYTE (IT_BYTEPOS (*it
) - 1) == '\n');
4739 /* Reseat iterator IT at the previous visible line start. Skip
4740 invisible text that is so either due to text properties or due to
4741 selective display. At the end, update IT's overlay information,
4742 face information etc. */
4745 reseat_at_previous_visible_line_start (it
)
4748 back_to_previous_visible_line_start (it
);
4749 reseat (it
, it
->current
.pos
, 1);
4754 /* Reseat iterator IT on the next visible line start in the current
4755 buffer. ON_NEWLINE_P non-zero means position IT on the newline
4756 preceding the line start. Skip over invisible text that is so
4757 because of selective display. Compute faces, overlays etc at the
4758 new position. Note that this function does not skip over text that
4759 is invisible because of text properties. */
4762 reseat_at_next_visible_line_start (it
, on_newline_p
)
4766 int newline_found_p
, skipped_p
= 0;
4768 newline_found_p
= forward_to_next_line_start (it
, &skipped_p
);
4770 /* Skip over lines that are invisible because they are indented
4771 more than the value of IT->selective. */
4772 if (it
->selective
> 0)
4773 while (IT_CHARPOS (*it
) < ZV
4774 && indented_beyond_p (IT_CHARPOS (*it
), IT_BYTEPOS (*it
),
4775 (double) it
->selective
)) /* iftc */
4777 xassert (FETCH_BYTE (IT_BYTEPOS (*it
) - 1) == '\n');
4778 newline_found_p
= forward_to_next_line_start (it
, &skipped_p
);
4781 /* Position on the newline if that's what's requested. */
4782 if (on_newline_p
&& newline_found_p
)
4784 if (STRINGP (it
->string
))
4786 if (IT_STRING_CHARPOS (*it
) > 0)
4788 --IT_STRING_CHARPOS (*it
);
4789 --IT_STRING_BYTEPOS (*it
);
4792 else if (IT_CHARPOS (*it
) > BEGV
)
4796 reseat (it
, it
->current
.pos
, 0);
4800 reseat (it
, it
->current
.pos
, 0);
4807 /***********************************************************************
4808 Changing an iterator's position
4809 ***********************************************************************/
4811 /* Change IT's current position to POS in current_buffer. If FORCE_P
4812 is non-zero, always check for text properties at the new position.
4813 Otherwise, text properties are only looked up if POS >=
4814 IT->check_charpos of a property. */
4817 reseat (it
, pos
, force_p
)
4819 struct text_pos pos
;
4822 int original_pos
= IT_CHARPOS (*it
);
4824 reseat_1 (it
, pos
, 0);
4826 /* Determine where to check text properties. Avoid doing it
4827 where possible because text property lookup is very expensive. */
4829 || CHARPOS (pos
) > it
->stop_charpos
4830 || CHARPOS (pos
) < original_pos
)
4837 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
4838 IT->stop_pos to POS, also. */
4841 reseat_1 (it
, pos
, set_stop_p
)
4843 struct text_pos pos
;
4846 /* Don't call this function when scanning a C string. */
4847 xassert (it
->s
== NULL
);
4849 /* POS must be a reasonable value. */
4850 xassert (CHARPOS (pos
) >= BEGV
&& CHARPOS (pos
) <= ZV
);
4852 it
->current
.pos
= it
->position
= pos
;
4853 XSETBUFFER (it
->object
, current_buffer
);
4854 it
->end_charpos
= ZV
;
4856 it
->current
.dpvec_index
= -1;
4857 it
->current
.overlay_string_index
= -1;
4858 IT_STRING_CHARPOS (*it
) = -1;
4859 IT_STRING_BYTEPOS (*it
) = -1;
4861 it
->method
= GET_FROM_BUFFER
;
4862 /* RMS: I added this to fix a bug in move_it_vertically_backward
4863 where it->area continued to relate to the starting point
4864 for the backward motion. Bug report from
4865 Nick Roberts <nick@nick.uklinux.net> on 19 May 2003.
4866 However, I am not sure whether reseat still does the right thing
4867 in general after this change. */
4868 it
->area
= TEXT_AREA
;
4869 it
->multibyte_p
= !NILP (current_buffer
->enable_multibyte_characters
);
4871 it
->face_before_selective_p
= 0;
4874 it
->stop_charpos
= CHARPOS (pos
);
4878 /* Set up IT for displaying a string, starting at CHARPOS in window W.
4879 If S is non-null, it is a C string to iterate over. Otherwise,
4880 STRING gives a Lisp string to iterate over.
4882 If PRECISION > 0, don't return more then PRECISION number of
4883 characters from the string.
4885 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
4886 characters have been returned. FIELD_WIDTH < 0 means an infinite
4889 MULTIBYTE = 0 means disable processing of multibyte characters,
4890 MULTIBYTE > 0 means enable it,
4891 MULTIBYTE < 0 means use IT->multibyte_p.
4893 IT must be initialized via a prior call to init_iterator before
4894 calling this function. */
4897 reseat_to_string (it
, s
, string
, charpos
, precision
, field_width
, multibyte
)
4902 int precision
, field_width
, multibyte
;
4904 /* No region in strings. */
4905 it
->region_beg_charpos
= it
->region_end_charpos
= -1;
4907 /* No text property checks performed by default, but see below. */
4908 it
->stop_charpos
= -1;
4910 /* Set iterator position and end position. */
4911 bzero (&it
->current
, sizeof it
->current
);
4912 it
->current
.overlay_string_index
= -1;
4913 it
->current
.dpvec_index
= -1;
4914 xassert (charpos
>= 0);
4916 /* If STRING is specified, use its multibyteness, otherwise use the
4917 setting of MULTIBYTE, if specified. */
4919 it
->multibyte_p
= multibyte
> 0;
4923 xassert (STRINGP (string
));
4924 it
->string
= string
;
4926 it
->end_charpos
= it
->string_nchars
= SCHARS (string
);
4927 it
->method
= GET_FROM_STRING
;
4928 it
->current
.string_pos
= string_pos (charpos
, string
);
4935 /* Note that we use IT->current.pos, not it->current.string_pos,
4936 for displaying C strings. */
4937 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = -1;
4938 if (it
->multibyte_p
)
4940 it
->current
.pos
= c_string_pos (charpos
, s
, 1);
4941 it
->end_charpos
= it
->string_nchars
= number_of_chars (s
, 1);
4945 IT_CHARPOS (*it
) = IT_BYTEPOS (*it
) = charpos
;
4946 it
->end_charpos
= it
->string_nchars
= strlen (s
);
4949 it
->method
= GET_FROM_C_STRING
;
4952 /* PRECISION > 0 means don't return more than PRECISION characters
4954 if (precision
> 0 && it
->end_charpos
- charpos
> precision
)
4955 it
->end_charpos
= it
->string_nchars
= charpos
+ precision
;
4957 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
4958 characters have been returned. FIELD_WIDTH == 0 means don't pad,
4959 FIELD_WIDTH < 0 means infinite field width. This is useful for
4960 padding with `-' at the end of a mode line. */
4961 if (field_width
< 0)
4962 field_width
= INFINITY
;
4963 if (field_width
> it
->end_charpos
- charpos
)
4964 it
->end_charpos
= charpos
+ field_width
;
4966 /* Use the standard display table for displaying strings. */
4967 if (DISP_TABLE_P (Vstandard_display_table
))
4968 it
->dp
= XCHAR_TABLE (Vstandard_display_table
);
4970 it
->stop_charpos
= charpos
;
4976 /***********************************************************************
4978 ***********************************************************************/
4980 /* Map enum it_method value to corresponding next_element_from_* function. */
4982 static int (* get_next_element
[NUM_IT_METHODS
]) P_ ((struct it
*it
)) =
4984 next_element_from_buffer
,
4985 next_element_from_display_vector
,
4986 next_element_from_composition
,
4987 next_element_from_string
,
4988 next_element_from_c_string
,
4989 next_element_from_image
,
4990 next_element_from_stretch
4994 /* Load IT's display element fields with information about the next
4995 display element from the current position of IT. Value is zero if
4996 end of buffer (or C string) is reached. */
4999 get_next_display_element (it
)
5002 /* Non-zero means that we found a display element. Zero means that
5003 we hit the end of what we iterate over. Performance note: the
5004 function pointer `method' used here turns out to be faster than
5005 using a sequence of if-statements. */
5009 success_p
= (*get_next_element
[it
->method
]) (it
);
5011 if (it
->what
== IT_CHARACTER
)
5013 /* Map via display table or translate control characters.
5014 IT->c, IT->len etc. have been set to the next character by
5015 the function call above. If we have a display table, and it
5016 contains an entry for IT->c, translate it. Don't do this if
5017 IT->c itself comes from a display table, otherwise we could
5018 end up in an infinite recursion. (An alternative could be to
5019 count the recursion depth of this function and signal an
5020 error when a certain maximum depth is reached.) Is it worth
5022 if (success_p
&& it
->dpvec
== NULL
)
5027 && (dv
= DISP_CHAR_VECTOR (it
->dp
, it
->c
),
5030 struct Lisp_Vector
*v
= XVECTOR (dv
);
5032 /* Return the first character from the display table
5033 entry, if not empty. If empty, don't display the
5034 current character. */
5037 it
->dpvec_char_len
= it
->len
;
5038 it
->dpvec
= v
->contents
;
5039 it
->dpend
= v
->contents
+ v
->size
;
5040 it
->current
.dpvec_index
= 0;
5041 it
->dpvec_face_id
= -1;
5042 it
->saved_face_id
= it
->face_id
;
5043 it
->method
= GET_FROM_DISPLAY_VECTOR
;
5048 set_iterator_to_next (it
, 0);
5053 /* Translate control characters into `\003' or `^C' form.
5054 Control characters coming from a display table entry are
5055 currently not translated because we use IT->dpvec to hold
5056 the translation. This could easily be changed but I
5057 don't believe that it is worth doing.
5059 If it->multibyte_p is nonzero, eight-bit characters and
5060 non-printable multibyte characters are also translated to
5063 If it->multibyte_p is zero, eight-bit characters that
5064 don't have corresponding multibyte char code are also
5065 translated to octal form. */
5066 else if ((it
->c
< ' '
5067 && (it
->area
!= TEXT_AREA
5068 /* In mode line, treat \n like other crl chars. */
5070 && it
->glyph_row
&& it
->glyph_row
->mode_line_p
)
5071 || (it
->c
!= '\n' && it
->c
!= '\t')))
5075 || !CHAR_PRINTABLE_P (it
->c
)
5076 || (!NILP (Vshow_nonbreak_escape
)
5077 && (it
->c
== 0x8ad || it
->c
== 0x8a0)))
5079 && (!unibyte_display_via_language_environment
5080 || it
->c
== unibyte_char_to_multibyte (it
->c
)))))
5082 /* IT->c is a control character which must be displayed
5083 either as '\003' or as `^C' where the '\\' and '^'
5084 can be defined in the display table. Fill
5085 IT->ctl_chars with glyphs for what we have to
5086 display. Then, set IT->dpvec to these glyphs. */
5089 int face_id
, lface_id
= 0 ;
5092 if (it
->c
< 128 && it
->ctl_arrow_p
)
5094 g
= '^'; /* default glyph for Control */
5095 /* Set IT->ctl_chars[0] to the glyph for `^'. */
5097 && INTEGERP (DISP_CTRL_GLYPH (it
->dp
))
5098 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it
->dp
))))
5100 g
= XINT (DISP_CTRL_GLYPH (it
->dp
));
5101 lface_id
= FAST_GLYPH_FACE (g
);
5105 g
= FAST_GLYPH_CHAR (g
);
5106 face_id
= merge_faces (it
->f
, Qt
, lface_id
,
5111 /* Merge the escape-glyph face into the current face. */
5112 face_id
= merge_faces (it
->f
, Qescape_glyph
, 0,
5116 XSETINT (it
->ctl_chars
[0], g
);
5118 XSETINT (it
->ctl_chars
[1], g
);
5120 goto display_control
;
5123 escape_glyph
= '\\'; /* default for Octal display */
5125 && INTEGERP (DISP_ESCAPE_GLYPH (it
->dp
))
5126 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it
->dp
))))
5128 escape_glyph
= XFASTINT (DISP_ESCAPE_GLYPH (it
->dp
));
5129 lface_id
= FAST_GLYPH_FACE (escape_glyph
);
5133 escape_glyph
= FAST_GLYPH_CHAR (escape_glyph
);
5134 face_id
= merge_faces (it
->f
, Qt
, lface_id
,
5139 /* Merge the escape-glyph face into the current face. */
5140 face_id
= merge_faces (it
->f
, Qescape_glyph
, 0,
5144 if (it
->c
== 0x8a0 || it
->c
== 0x8ad)
5146 XSETINT (it
->ctl_chars
[0], escape_glyph
);
5147 g
= it
->c
== 0x8ad ? '-' : ' ';
5148 XSETINT (it
->ctl_chars
[1], g
);
5150 goto display_control
;
5154 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
5158 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
5159 if (SINGLE_BYTE_CHAR_P (it
->c
))
5160 str
[0] = it
->c
, len
= 1;
5163 len
= CHAR_STRING_NO_SIGNAL (it
->c
, str
);
5166 /* It's an invalid character, which shouldn't
5167 happen actually, but due to bugs it may
5168 happen. Let's print the char as is, there's
5169 not much meaningful we can do with it. */
5171 str
[1] = it
->c
>> 8;
5172 str
[2] = it
->c
>> 16;
5173 str
[3] = it
->c
>> 24;
5178 for (i
= 0; i
< len
; i
++)
5180 XSETINT (it
->ctl_chars
[i
* 4], escape_glyph
);
5181 /* Insert three more glyphs into IT->ctl_chars for
5182 the octal display of the character. */
5183 g
= ((str
[i
] >> 6) & 7) + '0';
5184 XSETINT (it
->ctl_chars
[i
* 4 + 1], g
);
5185 g
= ((str
[i
] >> 3) & 7) + '0';
5186 XSETINT (it
->ctl_chars
[i
* 4 + 2], g
);
5187 g
= (str
[i
] & 7) + '0';
5188 XSETINT (it
->ctl_chars
[i
* 4 + 3], g
);
5194 /* Set up IT->dpvec and return first character from it. */
5195 it
->dpvec_char_len
= it
->len
;
5196 it
->dpvec
= it
->ctl_chars
;
5197 it
->dpend
= it
->dpvec
+ ctl_len
;
5198 it
->current
.dpvec_index
= 0;
5199 it
->dpvec_face_id
= face_id
;
5200 it
->saved_face_id
= it
->face_id
;
5201 it
->method
= GET_FROM_DISPLAY_VECTOR
;
5207 /* Adjust face id for a multibyte character. There are no
5208 multibyte character in unibyte text. */
5211 && FRAME_WINDOW_P (it
->f
))
5213 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
5214 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->c
);
5218 /* Is this character the last one of a run of characters with
5219 box? If yes, set IT->end_of_box_run_p to 1. */
5226 it
->end_of_box_run_p
5227 = ((face_id
= face_after_it_pos (it
),
5228 face_id
!= it
->face_id
)
5229 && (face
= FACE_FROM_ID (it
->f
, face_id
),
5230 face
->box
== FACE_NO_BOX
));
5233 /* Value is 0 if end of buffer or string reached. */
5238 /* Move IT to the next display element.
5240 RESEAT_P non-zero means if called on a newline in buffer text,
5241 skip to the next visible line start.
5243 Functions get_next_display_element and set_iterator_to_next are
5244 separate because I find this arrangement easier to handle than a
5245 get_next_display_element function that also increments IT's
5246 position. The way it is we can first look at an iterator's current
5247 display element, decide whether it fits on a line, and if it does,
5248 increment the iterator position. The other way around we probably
5249 would either need a flag indicating whether the iterator has to be
5250 incremented the next time, or we would have to implement a
5251 decrement position function which would not be easy to write. */
5254 set_iterator_to_next (it
, reseat_p
)
5258 /* Reset flags indicating start and end of a sequence of characters
5259 with box. Reset them at the start of this function because
5260 moving the iterator to a new position might set them. */
5261 it
->start_of_box_run_p
= it
->end_of_box_run_p
= 0;
5265 case GET_FROM_BUFFER
:
5266 /* The current display element of IT is a character from
5267 current_buffer. Advance in the buffer, and maybe skip over
5268 invisible lines that are so because of selective display. */
5269 if (ITERATOR_AT_END_OF_LINE_P (it
) && reseat_p
)
5270 reseat_at_next_visible_line_start (it
, 0);
5273 xassert (it
->len
!= 0);
5274 IT_BYTEPOS (*it
) += it
->len
;
5275 IT_CHARPOS (*it
) += 1;
5276 xassert (IT_BYTEPOS (*it
) == CHAR_TO_BYTE (IT_CHARPOS (*it
)));
5280 case GET_FROM_COMPOSITION
:
5281 xassert (it
->cmp_id
>= 0 && it
->cmp_id
< n_compositions
);
5282 if (STRINGP (it
->string
))
5284 IT_STRING_BYTEPOS (*it
) += it
->len
;
5285 IT_STRING_CHARPOS (*it
) += it
->cmp_len
;
5286 it
->method
= GET_FROM_STRING
;
5287 goto consider_string_end
;
5291 IT_BYTEPOS (*it
) += it
->len
;
5292 IT_CHARPOS (*it
) += it
->cmp_len
;
5293 it
->method
= GET_FROM_BUFFER
;
5297 case GET_FROM_C_STRING
:
5298 /* Current display element of IT is from a C string. */
5299 IT_BYTEPOS (*it
) += it
->len
;
5300 IT_CHARPOS (*it
) += 1;
5303 case GET_FROM_DISPLAY_VECTOR
:
5304 /* Current display element of IT is from a display table entry.
5305 Advance in the display table definition. Reset it to null if
5306 end reached, and continue with characters from buffers/
5308 ++it
->current
.dpvec_index
;
5310 /* Restore face of the iterator to what they were before the
5311 display vector entry (these entries may contain faces). */
5312 it
->face_id
= it
->saved_face_id
;
5314 if (it
->dpvec
+ it
->current
.dpvec_index
== it
->dpend
)
5317 it
->method
= GET_FROM_C_STRING
;
5318 else if (STRINGP (it
->string
))
5319 it
->method
= GET_FROM_STRING
;
5321 it
->method
= GET_FROM_BUFFER
;
5324 it
->current
.dpvec_index
= -1;
5326 /* Skip over characters which were displayed via IT->dpvec. */
5327 if (it
->dpvec_char_len
< 0)
5328 reseat_at_next_visible_line_start (it
, 1);
5329 else if (it
->dpvec_char_len
> 0)
5331 it
->len
= it
->dpvec_char_len
;
5332 set_iterator_to_next (it
, reseat_p
);
5335 /* Recheck faces after display vector */
5336 it
->stop_charpos
= IT_CHARPOS (*it
);
5340 case GET_FROM_STRING
:
5341 /* Current display element is a character from a Lisp string. */
5342 xassert (it
->s
== NULL
&& STRINGP (it
->string
));
5343 IT_STRING_BYTEPOS (*it
) += it
->len
;
5344 IT_STRING_CHARPOS (*it
) += 1;
5346 consider_string_end
:
5348 if (it
->current
.overlay_string_index
>= 0)
5350 /* IT->string is an overlay string. Advance to the
5351 next, if there is one. */
5352 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
))
5353 next_overlay_string (it
);
5357 /* IT->string is not an overlay string. If we reached
5358 its end, and there is something on IT->stack, proceed
5359 with what is on the stack. This can be either another
5360 string, this time an overlay string, or a buffer. */
5361 if (IT_STRING_CHARPOS (*it
) == SCHARS (it
->string
)
5365 if (STRINGP (it
->string
))
5366 goto consider_string_end
;
5367 it
->method
= GET_FROM_BUFFER
;
5372 case GET_FROM_IMAGE
:
5373 case GET_FROM_STRETCH
:
5374 /* The position etc with which we have to proceed are on
5375 the stack. The position may be at the end of a string,
5376 if the `display' property takes up the whole string. */
5377 xassert (it
->sp
> 0);
5380 if (STRINGP (it
->string
))
5382 it
->method
= GET_FROM_STRING
;
5383 goto consider_string_end
;
5385 it
->method
= GET_FROM_BUFFER
;
5389 /* There are no other methods defined, so this should be a bug. */
5393 xassert (it
->method
!= GET_FROM_STRING
5394 || (STRINGP (it
->string
)
5395 && IT_STRING_CHARPOS (*it
) >= 0));
5398 /* Load IT's display element fields with information about the next
5399 display element which comes from a display table entry or from the
5400 result of translating a control character to one of the forms `^C'
5403 IT->dpvec holds the glyphs to return as characters.
5404 IT->saved_face_id holds the face id before the display vector--
5405 it is restored into IT->face_idin set_iterator_to_next. */
5408 next_element_from_display_vector (it
)
5412 xassert (it
->dpvec
&& it
->current
.dpvec_index
>= 0);
5414 if (INTEGERP (*it
->dpvec
)
5415 && GLYPH_CHAR_VALID_P (XFASTINT (*it
->dpvec
)))
5419 g
= XFASTINT (it
->dpvec
[it
->current
.dpvec_index
]);
5420 it
->c
= FAST_GLYPH_CHAR (g
);
5421 it
->len
= CHAR_BYTES (it
->c
);
5423 /* The entry may contain a face id to use. Such a face id is
5424 the id of a Lisp face, not a realized face. A face id of
5425 zero means no face is specified. */
5426 if (it
->dpvec_face_id
>= 0)
5427 it
->face_id
= it
->dpvec_face_id
;
5430 int lface_id
= FAST_GLYPH_FACE (g
);
5432 it
->face_id
= merge_faces (it
->f
, Qt
, lface_id
,
5437 /* Display table entry is invalid. Return a space. */
5438 it
->c
= ' ', it
->len
= 1;
5440 /* Don't change position and object of the iterator here. They are
5441 still the values of the character that had this display table
5442 entry or was translated, and that's what we want. */
5443 it
->what
= IT_CHARACTER
;
5448 /* Load IT with the next display element from Lisp string IT->string.
5449 IT->current.string_pos is the current position within the string.
5450 If IT->current.overlay_string_index >= 0, the Lisp string is an
5454 next_element_from_string (it
)
5457 struct text_pos position
;
5459 xassert (STRINGP (it
->string
));
5460 xassert (IT_STRING_CHARPOS (*it
) >= 0);
5461 position
= it
->current
.string_pos
;
5463 /* Time to check for invisible text? */
5464 if (IT_STRING_CHARPOS (*it
) < it
->end_charpos
5465 && IT_STRING_CHARPOS (*it
) == it
->stop_charpos
)
5469 /* Since a handler may have changed IT->method, we must
5471 return get_next_display_element (it
);
5474 if (it
->current
.overlay_string_index
>= 0)
5476 /* Get the next character from an overlay string. In overlay
5477 strings, There is no field width or padding with spaces to
5479 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
))
5484 else if (STRING_MULTIBYTE (it
->string
))
5486 int remaining
= SBYTES (it
->string
) - IT_STRING_BYTEPOS (*it
);
5487 const unsigned char *s
= (SDATA (it
->string
)
5488 + IT_STRING_BYTEPOS (*it
));
5489 it
->c
= string_char_and_length (s
, remaining
, &it
->len
);
5493 it
->c
= SREF (it
->string
, IT_STRING_BYTEPOS (*it
));
5499 /* Get the next character from a Lisp string that is not an
5500 overlay string. Such strings come from the mode line, for
5501 example. We may have to pad with spaces, or truncate the
5502 string. See also next_element_from_c_string. */
5503 if (IT_STRING_CHARPOS (*it
) >= it
->end_charpos
)
5508 else if (IT_STRING_CHARPOS (*it
) >= it
->string_nchars
)
5510 /* Pad with spaces. */
5511 it
->c
= ' ', it
->len
= 1;
5512 CHARPOS (position
) = BYTEPOS (position
) = -1;
5514 else if (STRING_MULTIBYTE (it
->string
))
5516 int maxlen
= SBYTES (it
->string
) - IT_STRING_BYTEPOS (*it
);
5517 const unsigned char *s
= (SDATA (it
->string
)
5518 + IT_STRING_BYTEPOS (*it
));
5519 it
->c
= string_char_and_length (s
, maxlen
, &it
->len
);
5523 it
->c
= SREF (it
->string
, IT_STRING_BYTEPOS (*it
));
5528 /* Record what we have and where it came from. Note that we store a
5529 buffer position in IT->position although it could arguably be a
5531 it
->what
= IT_CHARACTER
;
5532 it
->object
= it
->string
;
5533 it
->position
= position
;
5538 /* Load IT with next display element from C string IT->s.
5539 IT->string_nchars is the maximum number of characters to return
5540 from the string. IT->end_charpos may be greater than
5541 IT->string_nchars when this function is called, in which case we
5542 may have to return padding spaces. Value is zero if end of string
5543 reached, including padding spaces. */
5546 next_element_from_c_string (it
)
5552 it
->what
= IT_CHARACTER
;
5553 BYTEPOS (it
->position
) = CHARPOS (it
->position
) = 0;
5556 /* IT's position can be greater IT->string_nchars in case a field
5557 width or precision has been specified when the iterator was
5559 if (IT_CHARPOS (*it
) >= it
->end_charpos
)
5561 /* End of the game. */
5565 else if (IT_CHARPOS (*it
) >= it
->string_nchars
)
5567 /* Pad with spaces. */
5568 it
->c
= ' ', it
->len
= 1;
5569 BYTEPOS (it
->position
) = CHARPOS (it
->position
) = -1;
5571 else if (it
->multibyte_p
)
5573 /* Implementation note: The calls to strlen apparently aren't a
5574 performance problem because there is no noticeable performance
5575 difference between Emacs running in unibyte or multibyte mode. */
5576 int maxlen
= strlen (it
->s
) - IT_BYTEPOS (*it
);
5577 it
->c
= string_char_and_length (it
->s
+ IT_BYTEPOS (*it
),
5581 it
->c
= it
->s
[IT_BYTEPOS (*it
)], it
->len
= 1;
5587 /* Set up IT to return characters from an ellipsis, if appropriate.
5588 The definition of the ellipsis glyphs may come from a display table
5589 entry. This function Fills IT with the first glyph from the
5590 ellipsis if an ellipsis is to be displayed. */
5593 next_element_from_ellipsis (it
)
5596 if (it
->selective_display_ellipsis_p
)
5597 setup_for_ellipsis (it
, it
->len
);
5600 /* The face at the current position may be different from the
5601 face we find after the invisible text. Remember what it
5602 was in IT->saved_face_id, and signal that it's there by
5603 setting face_before_selective_p. */
5604 it
->saved_face_id
= it
->face_id
;
5605 it
->method
= GET_FROM_BUFFER
;
5606 reseat_at_next_visible_line_start (it
, 1);
5607 it
->face_before_selective_p
= 1;
5610 return get_next_display_element (it
);
5614 /* Deliver an image display element. The iterator IT is already
5615 filled with image information (done in handle_display_prop). Value
5620 next_element_from_image (it
)
5623 it
->what
= IT_IMAGE
;
5628 /* Fill iterator IT with next display element from a stretch glyph
5629 property. IT->object is the value of the text property. Value is
5633 next_element_from_stretch (it
)
5636 it
->what
= IT_STRETCH
;
5641 /* Load IT with the next display element from current_buffer. Value
5642 is zero if end of buffer reached. IT->stop_charpos is the next
5643 position at which to stop and check for text properties or buffer
5647 next_element_from_buffer (it
)
5652 /* Check this assumption, otherwise, we would never enter the
5653 if-statement, below. */
5654 xassert (IT_CHARPOS (*it
) >= BEGV
5655 && IT_CHARPOS (*it
) <= it
->stop_charpos
);
5657 if (IT_CHARPOS (*it
) >= it
->stop_charpos
)
5659 if (IT_CHARPOS (*it
) >= it
->end_charpos
)
5661 int overlay_strings_follow_p
;
5663 /* End of the game, except when overlay strings follow that
5664 haven't been returned yet. */
5665 if (it
->overlay_strings_at_end_processed_p
)
5666 overlay_strings_follow_p
= 0;
5669 it
->overlay_strings_at_end_processed_p
= 1;
5670 overlay_strings_follow_p
= get_overlay_strings (it
, 0);
5673 if (overlay_strings_follow_p
)
5674 success_p
= get_next_display_element (it
);
5678 it
->position
= it
->current
.pos
;
5685 return get_next_display_element (it
);
5690 /* No face changes, overlays etc. in sight, so just return a
5691 character from current_buffer. */
5694 /* Maybe run the redisplay end trigger hook. Performance note:
5695 This doesn't seem to cost measurable time. */
5696 if (it
->redisplay_end_trigger_charpos
5698 && IT_CHARPOS (*it
) >= it
->redisplay_end_trigger_charpos
)
5699 run_redisplay_end_trigger_hook (it
);
5701 /* Get the next character, maybe multibyte. */
5702 p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
5703 if (it
->multibyte_p
&& !ASCII_BYTE_P (*p
))
5705 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT_BYTE
? ZV_BYTE
: GPT_BYTE
)
5706 - IT_BYTEPOS (*it
));
5707 it
->c
= string_char_and_length (p
, maxlen
, &it
->len
);
5710 it
->c
= *p
, it
->len
= 1;
5712 /* Record what we have and where it came from. */
5713 it
->what
= IT_CHARACTER
;;
5714 it
->object
= it
->w
->buffer
;
5715 it
->position
= it
->current
.pos
;
5717 /* Normally we return the character found above, except when we
5718 really want to return an ellipsis for selective display. */
5723 /* A value of selective > 0 means hide lines indented more
5724 than that number of columns. */
5725 if (it
->selective
> 0
5726 && IT_CHARPOS (*it
) + 1 < ZV
5727 && indented_beyond_p (IT_CHARPOS (*it
) + 1,
5728 IT_BYTEPOS (*it
) + 1,
5729 (double) it
->selective
)) /* iftc */
5731 success_p
= next_element_from_ellipsis (it
);
5732 it
->dpvec_char_len
= -1;
5735 else if (it
->c
== '\r' && it
->selective
== -1)
5737 /* A value of selective == -1 means that everything from the
5738 CR to the end of the line is invisible, with maybe an
5739 ellipsis displayed for it. */
5740 success_p
= next_element_from_ellipsis (it
);
5741 it
->dpvec_char_len
= -1;
5746 /* Value is zero if end of buffer reached. */
5747 xassert (!success_p
|| it
->what
!= IT_CHARACTER
|| it
->len
> 0);
5752 /* Run the redisplay end trigger hook for IT. */
5755 run_redisplay_end_trigger_hook (it
)
5758 Lisp_Object args
[3];
5760 /* IT->glyph_row should be non-null, i.e. we should be actually
5761 displaying something, or otherwise we should not run the hook. */
5762 xassert (it
->glyph_row
);
5764 /* Set up hook arguments. */
5765 args
[0] = Qredisplay_end_trigger_functions
;
5766 args
[1] = it
->window
;
5767 XSETINT (args
[2], it
->redisplay_end_trigger_charpos
);
5768 it
->redisplay_end_trigger_charpos
= 0;
5770 /* Since we are *trying* to run these functions, don't try to run
5771 them again, even if they get an error. */
5772 it
->w
->redisplay_end_trigger
= Qnil
;
5773 Frun_hook_with_args (3, args
);
5775 /* Notice if it changed the face of the character we are on. */
5776 handle_face_prop (it
);
5780 /* Deliver a composition display element. The iterator IT is already
5781 filled with composition information (done in
5782 handle_composition_prop). Value is always 1. */
5785 next_element_from_composition (it
)
5788 it
->what
= IT_COMPOSITION
;
5789 it
->position
= (STRINGP (it
->string
)
5790 ? it
->current
.string_pos
5797 /***********************************************************************
5798 Moving an iterator without producing glyphs
5799 ***********************************************************************/
5801 /* Move iterator IT to a specified buffer or X position within one
5802 line on the display without producing glyphs.
5804 OP should be a bit mask including some or all of these bits:
5805 MOVE_TO_X: Stop on reaching x-position TO_X.
5806 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
5807 Regardless of OP's value, stop in reaching the end of the display line.
5809 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
5810 This means, in particular, that TO_X includes window's horizontal
5813 The return value has several possible values that
5814 say what condition caused the scan to stop:
5816 MOVE_POS_MATCH_OR_ZV
5817 - when TO_POS or ZV was reached.
5820 -when TO_X was reached before TO_POS or ZV were reached.
5823 - when we reached the end of the display area and the line must
5827 - when we reached the end of the display area and the line is
5831 - when we stopped at a line end, i.e. a newline or a CR and selective
5834 static enum move_it_result
5835 move_it_in_display_line_to (it
, to_charpos
, to_x
, op
)
5837 int to_charpos
, to_x
, op
;
5839 enum move_it_result result
= MOVE_UNDEFINED
;
5840 struct glyph_row
*saved_glyph_row
;
5842 /* Don't produce glyphs in produce_glyphs. */
5843 saved_glyph_row
= it
->glyph_row
;
5844 it
->glyph_row
= NULL
;
5846 #define BUFFER_POS_REACHED_P() \
5847 ((op & MOVE_TO_POS) != 0 \
5848 && BUFFERP (it->object) \
5849 && IT_CHARPOS (*it) >= to_charpos \
5850 && (it->method == GET_FROM_BUFFER \
5851 || (it->method == GET_FROM_DISPLAY_VECTOR \
5852 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
5857 int x
, i
, ascent
= 0, descent
= 0;
5859 /* Stop when ZV reached.
5860 We used to stop here when TO_CHARPOS reached as well, but that is
5861 too soon if this glyph does not fit on this line. So we handle it
5862 explicitly below. */
5863 if (!get_next_display_element (it
)
5864 || (it
->truncate_lines_p
5865 && BUFFER_POS_REACHED_P ()))
5867 result
= MOVE_POS_MATCH_OR_ZV
;
5871 /* The call to produce_glyphs will get the metrics of the
5872 display element IT is loaded with. We record in x the
5873 x-position before this display element in case it does not
5877 /* Remember the line height so far in case the next element doesn't
5879 if (!it
->truncate_lines_p
)
5881 ascent
= it
->max_ascent
;
5882 descent
= it
->max_descent
;
5885 PRODUCE_GLYPHS (it
);
5887 if (it
->area
!= TEXT_AREA
)
5889 set_iterator_to_next (it
, 1);
5893 /* The number of glyphs we get back in IT->nglyphs will normally
5894 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
5895 character on a terminal frame, or (iii) a line end. For the
5896 second case, IT->nglyphs - 1 padding glyphs will be present
5897 (on X frames, there is only one glyph produced for a
5898 composite character.
5900 The behavior implemented below means, for continuation lines,
5901 that as many spaces of a TAB as fit on the current line are
5902 displayed there. For terminal frames, as many glyphs of a
5903 multi-glyph character are displayed in the current line, too.
5904 This is what the old redisplay code did, and we keep it that
5905 way. Under X, the whole shape of a complex character must
5906 fit on the line or it will be completely displayed in the
5909 Note that both for tabs and padding glyphs, all glyphs have
5913 /* More than one glyph or glyph doesn't fit on line. All
5914 glyphs have the same width. */
5915 int single_glyph_width
= it
->pixel_width
/ it
->nglyphs
;
5918 for (i
= 0; i
< it
->nglyphs
; ++i
, x
= new_x
)
5920 new_x
= x
+ single_glyph_width
;
5922 /* We want to leave anything reaching TO_X to the caller. */
5923 if ((op
& MOVE_TO_X
) && new_x
> to_x
)
5925 if (BUFFER_POS_REACHED_P ())
5926 goto buffer_pos_reached
;
5928 result
= MOVE_X_REACHED
;
5931 else if (/* Lines are continued. */
5932 !it
->truncate_lines_p
5933 && (/* And glyph doesn't fit on the line. */
5934 new_x
> it
->last_visible_x
5935 /* Or it fits exactly and we're on a window
5937 || (new_x
== it
->last_visible_x
5938 && FRAME_WINDOW_P (it
->f
))))
5940 if (/* IT->hpos == 0 means the very first glyph
5941 doesn't fit on the line, e.g. a wide image. */
5943 || (new_x
== it
->last_visible_x
5944 && FRAME_WINDOW_P (it
->f
)))
5947 it
->current_x
= new_x
;
5948 if (i
== it
->nglyphs
- 1)
5950 set_iterator_to_next (it
, 1);
5951 #ifdef HAVE_WINDOW_SYSTEM
5952 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
5954 if (!get_next_display_element (it
))
5956 result
= MOVE_POS_MATCH_OR_ZV
;
5959 if (BUFFER_POS_REACHED_P ())
5961 if (ITERATOR_AT_END_OF_LINE_P (it
))
5962 result
= MOVE_POS_MATCH_OR_ZV
;
5964 result
= MOVE_LINE_CONTINUED
;
5967 if (ITERATOR_AT_END_OF_LINE_P (it
))
5969 result
= MOVE_NEWLINE_OR_CR
;
5973 #endif /* HAVE_WINDOW_SYSTEM */
5979 it
->max_ascent
= ascent
;
5980 it
->max_descent
= descent
;
5983 TRACE_MOVE ((stderr
, "move_it_in: continued at %d\n",
5985 result
= MOVE_LINE_CONTINUED
;
5988 else if (BUFFER_POS_REACHED_P ())
5989 goto buffer_pos_reached
;
5990 else if (new_x
> it
->first_visible_x
)
5992 /* Glyph is visible. Increment number of glyphs that
5993 would be displayed. */
5998 /* Glyph is completely off the left margin of the display
5999 area. Nothing to do. */
6003 if (result
!= MOVE_UNDEFINED
)
6006 else if (BUFFER_POS_REACHED_P ())
6010 it
->max_ascent
= ascent
;
6011 it
->max_descent
= descent
;
6012 result
= MOVE_POS_MATCH_OR_ZV
;
6015 else if ((op
& MOVE_TO_X
) && it
->current_x
>= to_x
)
6017 /* Stop when TO_X specified and reached. This check is
6018 necessary here because of lines consisting of a line end,
6019 only. The line end will not produce any glyphs and we
6020 would never get MOVE_X_REACHED. */
6021 xassert (it
->nglyphs
== 0);
6022 result
= MOVE_X_REACHED
;
6026 /* Is this a line end? If yes, we're done. */
6027 if (ITERATOR_AT_END_OF_LINE_P (it
))
6029 result
= MOVE_NEWLINE_OR_CR
;
6033 /* The current display element has been consumed. Advance
6035 set_iterator_to_next (it
, 1);
6037 /* Stop if lines are truncated and IT's current x-position is
6038 past the right edge of the window now. */
6039 if (it
->truncate_lines_p
6040 && it
->current_x
>= it
->last_visible_x
)
6042 #ifdef HAVE_WINDOW_SYSTEM
6043 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
6045 if (!get_next_display_element (it
)
6046 || BUFFER_POS_REACHED_P ())
6048 result
= MOVE_POS_MATCH_OR_ZV
;
6051 if (ITERATOR_AT_END_OF_LINE_P (it
))
6053 result
= MOVE_NEWLINE_OR_CR
;
6057 #endif /* HAVE_WINDOW_SYSTEM */
6058 result
= MOVE_LINE_TRUNCATED
;
6063 #undef BUFFER_POS_REACHED_P
6065 /* Restore the iterator settings altered at the beginning of this
6067 it
->glyph_row
= saved_glyph_row
;
6072 /* Move IT forward until it satisfies one or more of the criteria in
6073 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
6075 OP is a bit-mask that specifies where to stop, and in particular,
6076 which of those four position arguments makes a difference. See the
6077 description of enum move_operation_enum.
6079 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
6080 screen line, this function will set IT to the next position >
6084 move_it_to (it
, to_charpos
, to_x
, to_y
, to_vpos
, op
)
6086 int to_charpos
, to_x
, to_y
, to_vpos
;
6089 enum move_it_result skip
, skip2
= MOVE_X_REACHED
;
6095 if (op
& MOVE_TO_VPOS
)
6097 /* If no TO_CHARPOS and no TO_X specified, stop at the
6098 start of the line TO_VPOS. */
6099 if ((op
& (MOVE_TO_X
| MOVE_TO_POS
)) == 0)
6101 if (it
->vpos
== to_vpos
)
6107 skip
= move_it_in_display_line_to (it
, -1, -1, 0);
6111 /* TO_VPOS >= 0 means stop at TO_X in the line at
6112 TO_VPOS, or at TO_POS, whichever comes first. */
6113 if (it
->vpos
== to_vpos
)
6119 skip
= move_it_in_display_line_to (it
, to_charpos
, to_x
, op
);
6121 if (skip
== MOVE_POS_MATCH_OR_ZV
|| it
->vpos
== to_vpos
)
6126 else if (skip
== MOVE_X_REACHED
&& it
->vpos
!= to_vpos
)
6128 /* We have reached TO_X but not in the line we want. */
6129 skip
= move_it_in_display_line_to (it
, to_charpos
,
6131 if (skip
== MOVE_POS_MATCH_OR_ZV
)
6139 else if (op
& MOVE_TO_Y
)
6141 struct it it_backup
;
6143 /* TO_Y specified means stop at TO_X in the line containing
6144 TO_Y---or at TO_CHARPOS if this is reached first. The
6145 problem is that we can't really tell whether the line
6146 contains TO_Y before we have completely scanned it, and
6147 this may skip past TO_X. What we do is to first scan to
6150 If TO_X is not specified, use a TO_X of zero. The reason
6151 is to make the outcome of this function more predictable.
6152 If we didn't use TO_X == 0, we would stop at the end of
6153 the line which is probably not what a caller would expect
6155 skip
= move_it_in_display_line_to (it
, to_charpos
,
6159 | (op
& MOVE_TO_POS
)));
6161 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
6162 if (skip
== MOVE_POS_MATCH_OR_ZV
)
6168 /* If TO_X was reached, we would like to know whether TO_Y
6169 is in the line. This can only be said if we know the
6170 total line height which requires us to scan the rest of
6172 if (skip
== MOVE_X_REACHED
)
6175 TRACE_MOVE ((stderr
, "move_it: from %d\n", IT_CHARPOS (*it
)));
6176 skip2
= move_it_in_display_line_to (it
, to_charpos
, -1,
6178 TRACE_MOVE ((stderr
, "move_it: to %d\n", IT_CHARPOS (*it
)));
6181 /* Now, decide whether TO_Y is in this line. */
6182 line_height
= it
->max_ascent
+ it
->max_descent
;
6183 TRACE_MOVE ((stderr
, "move_it: line_height = %d\n", line_height
));
6185 if (to_y
>= it
->current_y
6186 && to_y
< it
->current_y
+ line_height
)
6188 if (skip
== MOVE_X_REACHED
)
6189 /* If TO_Y is in this line and TO_X was reached above,
6190 we scanned too far. We have to restore IT's settings
6191 to the ones before skipping. */
6195 else if (skip
== MOVE_X_REACHED
)
6198 if (skip
== MOVE_POS_MATCH_OR_ZV
)
6206 skip
= move_it_in_display_line_to (it
, to_charpos
, -1, MOVE_TO_POS
);
6210 case MOVE_POS_MATCH_OR_ZV
:
6214 case MOVE_NEWLINE_OR_CR
:
6215 set_iterator_to_next (it
, 1);
6216 it
->continuation_lines_width
= 0;
6219 case MOVE_LINE_TRUNCATED
:
6220 it
->continuation_lines_width
= 0;
6221 reseat_at_next_visible_line_start (it
, 0);
6222 if ((op
& MOVE_TO_POS
) != 0
6223 && IT_CHARPOS (*it
) > to_charpos
)
6230 case MOVE_LINE_CONTINUED
:
6231 it
->continuation_lines_width
+= it
->current_x
;
6238 /* Reset/increment for the next run. */
6239 recenter_overlay_lists (current_buffer
, IT_CHARPOS (*it
));
6240 it
->current_x
= it
->hpos
= 0;
6241 it
->current_y
+= it
->max_ascent
+ it
->max_descent
;
6243 last_height
= it
->max_ascent
+ it
->max_descent
;
6244 last_max_ascent
= it
->max_ascent
;
6245 it
->max_ascent
= it
->max_descent
= 0;
6250 TRACE_MOVE ((stderr
, "move_it_to: reached %d\n", reached
));
6254 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
6256 If DY > 0, move IT backward at least that many pixels. DY = 0
6257 means move IT backward to the preceding line start or BEGV. This
6258 function may move over more than DY pixels if IT->current_y - DY
6259 ends up in the middle of a line; in this case IT->current_y will be
6260 set to the top of the line moved to. */
6263 move_it_vertically_backward (it
, dy
)
6274 start_pos
= IT_CHARPOS (*it
);
6276 /* Estimate how many newlines we must move back. */
6277 nlines
= max (1, dy
/ FRAME_LINE_HEIGHT (it
->f
));
6279 /* Set the iterator's position that many lines back. */
6280 while (nlines
-- && IT_CHARPOS (*it
) > BEGV
)
6281 back_to_previous_visible_line_start (it
);
6283 /* Reseat the iterator here. When moving backward, we don't want
6284 reseat to skip forward over invisible text, set up the iterator
6285 to deliver from overlay strings at the new position etc. So,
6286 use reseat_1 here. */
6287 reseat_1 (it
, it
->current
.pos
, 1);
6289 /* We are now surely at a line start. */
6290 it
->current_x
= it
->hpos
= 0;
6291 it
->continuation_lines_width
= 0;
6293 /* Move forward and see what y-distance we moved. First move to the
6294 start of the next line so that we get its height. We need this
6295 height to be able to tell whether we reached the specified
6298 it2
.max_ascent
= it2
.max_descent
= 0;
6299 move_it_to (&it2
, start_pos
, -1, -1, it2
.vpos
+ 1,
6300 MOVE_TO_POS
| MOVE_TO_VPOS
);
6301 xassert (IT_CHARPOS (*it
) >= BEGV
);
6304 move_it_to (&it2
, start_pos
, -1, -1, -1, MOVE_TO_POS
);
6305 xassert (IT_CHARPOS (*it
) >= BEGV
);
6306 /* H is the actual vertical distance from the position in *IT
6307 and the starting position. */
6308 h
= it2
.current_y
- it
->current_y
;
6309 /* NLINES is the distance in number of lines. */
6310 nlines
= it2
.vpos
- it
->vpos
;
6312 /* Correct IT's y and vpos position
6313 so that they are relative to the starting point. */
6319 /* DY == 0 means move to the start of the screen line. The
6320 value of nlines is > 0 if continuation lines were involved. */
6322 move_it_by_lines (it
, nlines
, 1);
6324 /* I think this assert is bogus if buffer contains
6325 invisible text or images. KFS. */
6326 xassert (IT_CHARPOS (*it
) <= start_pos
);
6331 /* The y-position we try to reach, relative to *IT.
6332 Note that H has been subtracted in front of the if-statement. */
6333 int target_y
= it
->current_y
+ h
- dy
;
6334 int y0
= it3
.current_y
;
6335 int y1
= line_bottom_y (&it3
);
6336 int line_height
= y1
- y0
;
6338 /* If we did not reach target_y, try to move further backward if
6339 we can. If we moved too far backward, try to move forward. */
6340 if (target_y
< it
->current_y
6341 /* This is heuristic. In a window that's 3 lines high, with
6342 a line height of 13 pixels each, recentering with point
6343 on the bottom line will try to move -39/2 = 19 pixels
6344 backward. Try to avoid moving into the first line. */
6345 && (it
->current_y
- target_y
6346 > min (window_box_height (it
->w
), line_height
* 2 / 3))
6347 && IT_CHARPOS (*it
) > BEGV
)
6349 TRACE_MOVE ((stderr
, " not far enough -> move_vert %d\n",
6350 target_y
- it
->current_y
));
6351 dy
= it
->current_y
- target_y
;
6352 goto move_further_back
;
6354 else if (target_y
>= it
->current_y
+ line_height
6355 && IT_CHARPOS (*it
) < ZV
)
6357 /* Should move forward by at least one line, maybe more.
6359 Note: Calling move_it_by_lines can be expensive on
6360 terminal frames, where compute_motion is used (via
6361 vmotion) to do the job, when there are very long lines
6362 and truncate-lines is nil. That's the reason for
6363 treating terminal frames specially here. */
6365 if (!FRAME_WINDOW_P (it
->f
))
6366 move_it_vertically (it
, target_y
- (it
->current_y
+ line_height
));
6371 move_it_by_lines (it
, 1, 1);
6373 while (target_y
>= line_bottom_y (it
) && IT_CHARPOS (*it
) < ZV
);
6377 /* I think this assert is bogus if buffer contains
6378 invisible text or images. KFS. */
6379 xassert (IT_CHARPOS (*it
) >= BEGV
);
6386 /* Move IT by a specified amount of pixel lines DY. DY negative means
6387 move backwards. DY = 0 means move to start of screen line. At the
6388 end, IT will be on the start of a screen line. */
6391 move_it_vertically (it
, dy
)
6396 move_it_vertically_backward (it
, -dy
);
6399 TRACE_MOVE ((stderr
, "move_it_v: from %d, %d\n", IT_CHARPOS (*it
), dy
));
6400 move_it_to (it
, ZV
, -1, it
->current_y
+ dy
, -1,
6401 MOVE_TO_POS
| MOVE_TO_Y
);
6402 TRACE_MOVE ((stderr
, "move_it_v: to %d\n", IT_CHARPOS (*it
)));
6404 /* If buffer ends in ZV without a newline, move to the start of
6405 the line to satisfy the post-condition. */
6406 if (IT_CHARPOS (*it
) == ZV
6407 && FETCH_BYTE (IT_BYTEPOS (*it
) - 1) != '\n')
6408 move_it_by_lines (it
, 0, 0);
6413 /* Move iterator IT past the end of the text line it is in. */
6416 move_it_past_eol (it
)
6419 enum move_it_result rc
;
6421 rc
= move_it_in_display_line_to (it
, Z
, 0, MOVE_TO_POS
);
6422 if (rc
== MOVE_NEWLINE_OR_CR
)
6423 set_iterator_to_next (it
, 0);
6427 #if 0 /* Currently not used. */
6429 /* Return non-zero if some text between buffer positions START_CHARPOS
6430 and END_CHARPOS is invisible. IT->window is the window for text
6434 invisible_text_between_p (it
, start_charpos
, end_charpos
)
6436 int start_charpos
, end_charpos
;
6438 Lisp_Object prop
, limit
;
6439 int invisible_found_p
;
6441 xassert (it
!= NULL
&& start_charpos
<= end_charpos
);
6443 /* Is text at START invisible? */
6444 prop
= Fget_char_property (make_number (start_charpos
), Qinvisible
,
6446 if (TEXT_PROP_MEANS_INVISIBLE (prop
))
6447 invisible_found_p
= 1;
6450 limit
= Fnext_single_char_property_change (make_number (start_charpos
),
6452 make_number (end_charpos
));
6453 invisible_found_p
= XFASTINT (limit
) < end_charpos
;
6456 return invisible_found_p
;
6462 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
6463 negative means move up. DVPOS == 0 means move to the start of the
6464 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
6465 NEED_Y_P is zero, IT->current_y will be left unchanged.
6467 Further optimization ideas: If we would know that IT->f doesn't use
6468 a face with proportional font, we could be faster for
6469 truncate-lines nil. */
6472 move_it_by_lines (it
, dvpos
, need_y_p
)
6474 int dvpos
, need_y_p
;
6476 struct position pos
;
6478 if (!FRAME_WINDOW_P (it
->f
))
6480 struct text_pos textpos
;
6482 /* We can use vmotion on frames without proportional fonts. */
6483 pos
= *vmotion (IT_CHARPOS (*it
), dvpos
, it
->w
);
6484 SET_TEXT_POS (textpos
, pos
.bufpos
, pos
.bytepos
);
6485 reseat (it
, textpos
, 1);
6486 it
->vpos
+= pos
.vpos
;
6487 it
->current_y
+= pos
.vpos
;
6489 else if (dvpos
== 0)
6491 /* DVPOS == 0 means move to the start of the screen line. */
6492 move_it_vertically_backward (it
, 0);
6493 xassert (it
->current_x
== 0 && it
->hpos
== 0);
6494 /* Let next call to line_bottom_y calculate real line height */
6498 move_it_to (it
, -1, -1, -1, it
->vpos
+ dvpos
, MOVE_TO_VPOS
);
6502 int start_charpos
, i
;
6504 /* Start at the beginning of the screen line containing IT's
6506 move_it_vertically_backward (it
, 0);
6508 /* Go back -DVPOS visible lines and reseat the iterator there. */
6509 start_charpos
= IT_CHARPOS (*it
);
6510 for (i
= -dvpos
; i
&& IT_CHARPOS (*it
) > BEGV
; --i
)
6511 back_to_previous_visible_line_start (it
);
6512 reseat (it
, it
->current
.pos
, 1);
6513 it
->current_x
= it
->hpos
= 0;
6515 /* Above call may have moved too far if continuation lines
6516 are involved. Scan forward and see if it did. */
6518 it2
.vpos
= it2
.current_y
= 0;
6519 move_it_to (&it2
, start_charpos
, -1, -1, -1, MOVE_TO_POS
);
6520 it
->vpos
-= it2
.vpos
;
6521 it
->current_y
-= it2
.current_y
;
6522 it
->current_x
= it
->hpos
= 0;
6524 /* If we moved too far back, move IT some lines forward. */
6525 if (it2
.vpos
> -dvpos
)
6527 int delta
= it2
.vpos
+ dvpos
;
6529 move_it_to (it
, -1, -1, -1, it
->vpos
+ delta
, MOVE_TO_VPOS
);
6530 /* Move back again if we got too far ahead. */
6531 if (IT_CHARPOS (*it
) >= start_charpos
)
6537 /* Return 1 if IT points into the middle of a display vector. */
6540 in_display_vector_p (it
)
6543 return (it
->method
== GET_FROM_DISPLAY_VECTOR
6544 && it
->current
.dpvec_index
> 0
6545 && it
->dpvec
+ it
->current
.dpvec_index
!= it
->dpend
);
6549 /***********************************************************************
6551 ***********************************************************************/
6554 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
6558 add_to_log (format
, arg1
, arg2
)
6560 Lisp_Object arg1
, arg2
;
6562 Lisp_Object args
[3];
6563 Lisp_Object msg
, fmt
;
6566 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
6569 /* Do nothing if called asynchronously. Inserting text into
6570 a buffer may call after-change-functions and alike and
6571 that would means running Lisp asynchronously. */
6572 if (handling_signal
)
6576 GCPRO4 (fmt
, msg
, arg1
, arg2
);
6578 args
[0] = fmt
= build_string (format
);
6581 msg
= Fformat (3, args
);
6583 len
= SBYTES (msg
) + 1;
6584 SAFE_ALLOCA (buffer
, char *, len
);
6585 bcopy (SDATA (msg
), buffer
, len
);
6587 message_dolog (buffer
, len
- 1, 1, 0);
6594 /* Output a newline in the *Messages* buffer if "needs" one. */
6597 message_log_maybe_newline ()
6599 if (message_log_need_newline
)
6600 message_dolog ("", 0, 1, 0);
6604 /* Add a string M of length NBYTES to the message log, optionally
6605 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
6606 nonzero, means interpret the contents of M as multibyte. This
6607 function calls low-level routines in order to bypass text property
6608 hooks, etc. which might not be safe to run. */
6611 message_dolog (m
, nbytes
, nlflag
, multibyte
)
6613 int nbytes
, nlflag
, multibyte
;
6615 if (!NILP (Vmemory_full
))
6618 if (!NILP (Vmessage_log_max
))
6620 struct buffer
*oldbuf
;
6621 Lisp_Object oldpoint
, oldbegv
, oldzv
;
6622 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
6623 int point_at_end
= 0;
6625 Lisp_Object old_deactivate_mark
, tem
;
6626 struct gcpro gcpro1
;
6628 old_deactivate_mark
= Vdeactivate_mark
;
6629 oldbuf
= current_buffer
;
6630 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name
));
6631 current_buffer
->undo_list
= Qt
;
6633 oldpoint
= message_dolog_marker1
;
6634 set_marker_restricted (oldpoint
, make_number (PT
), Qnil
);
6635 oldbegv
= message_dolog_marker2
;
6636 set_marker_restricted (oldbegv
, make_number (BEGV
), Qnil
);
6637 oldzv
= message_dolog_marker3
;
6638 set_marker_restricted (oldzv
, make_number (ZV
), Qnil
);
6639 GCPRO1 (old_deactivate_mark
);
6647 BEGV_BYTE
= BEG_BYTE
;
6650 TEMP_SET_PT_BOTH (Z
, Z_BYTE
);
6652 /* Insert the string--maybe converting multibyte to single byte
6653 or vice versa, so that all the text fits the buffer. */
6655 && NILP (current_buffer
->enable_multibyte_characters
))
6657 int i
, c
, char_bytes
;
6658 unsigned char work
[1];
6660 /* Convert a multibyte string to single-byte
6661 for the *Message* buffer. */
6662 for (i
= 0; i
< nbytes
; i
+= char_bytes
)
6664 c
= string_char_and_length (m
+ i
, nbytes
- i
, &char_bytes
);
6665 work
[0] = (SINGLE_BYTE_CHAR_P (c
)
6667 : multibyte_char_to_unibyte (c
, Qnil
));
6668 insert_1_both (work
, 1, 1, 1, 0, 0);
6671 else if (! multibyte
6672 && ! NILP (current_buffer
->enable_multibyte_characters
))
6674 int i
, c
, char_bytes
;
6675 unsigned char *msg
= (unsigned char *) m
;
6676 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
6677 /* Convert a single-byte string to multibyte
6678 for the *Message* buffer. */
6679 for (i
= 0; i
< nbytes
; i
++)
6681 c
= unibyte_char_to_multibyte (msg
[i
]);
6682 char_bytes
= CHAR_STRING (c
, str
);
6683 insert_1_both (str
, 1, char_bytes
, 1, 0, 0);
6687 insert_1 (m
, nbytes
, 1, 0, 0);
6691 int this_bol
, this_bol_byte
, prev_bol
, prev_bol_byte
, dup
;
6692 insert_1 ("\n", 1, 1, 0, 0);
6694 scan_newline (Z
, Z_BYTE
, BEG
, BEG_BYTE
, -2, 0);
6696 this_bol_byte
= PT_BYTE
;
6698 /* See if this line duplicates the previous one.
6699 If so, combine duplicates. */
6702 scan_newline (PT
, PT_BYTE
, BEG
, BEG_BYTE
, -2, 0);
6704 prev_bol_byte
= PT_BYTE
;
6706 dup
= message_log_check_duplicate (prev_bol
, prev_bol_byte
,
6707 this_bol
, this_bol_byte
);
6710 del_range_both (prev_bol
, prev_bol_byte
,
6711 this_bol
, this_bol_byte
, 0);
6717 /* If you change this format, don't forget to also
6718 change message_log_check_duplicate. */
6719 sprintf (dupstr
, " [%d times]", dup
);
6720 duplen
= strlen (dupstr
);
6721 TEMP_SET_PT_BOTH (Z
- 1, Z_BYTE
- 1);
6722 insert_1 (dupstr
, duplen
, 1, 0, 1);
6727 /* If we have more than the desired maximum number of lines
6728 in the *Messages* buffer now, delete the oldest ones.
6729 This is safe because we don't have undo in this buffer. */
6731 if (NATNUMP (Vmessage_log_max
))
6733 scan_newline (Z
, Z_BYTE
, BEG
, BEG_BYTE
,
6734 -XFASTINT (Vmessage_log_max
) - 1, 0);
6735 del_range_both (BEG
, BEG_BYTE
, PT
, PT_BYTE
, 0);
6738 BEGV
= XMARKER (oldbegv
)->charpos
;
6739 BEGV_BYTE
= marker_byte_position (oldbegv
);
6748 ZV
= XMARKER (oldzv
)->charpos
;
6749 ZV_BYTE
= marker_byte_position (oldzv
);
6753 TEMP_SET_PT_BOTH (Z
, Z_BYTE
);
6755 /* We can't do Fgoto_char (oldpoint) because it will run some
6757 TEMP_SET_PT_BOTH (XMARKER (oldpoint
)->charpos
,
6758 XMARKER (oldpoint
)->bytepos
);
6761 unchain_marker (XMARKER (oldpoint
));
6762 unchain_marker (XMARKER (oldbegv
));
6763 unchain_marker (XMARKER (oldzv
));
6765 tem
= Fget_buffer_window (Fcurrent_buffer (), Qt
);
6766 set_buffer_internal (oldbuf
);
6768 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
6769 message_log_need_newline
= !nlflag
;
6770 Vdeactivate_mark
= old_deactivate_mark
;
6775 /* We are at the end of the buffer after just having inserted a newline.
6776 (Note: We depend on the fact we won't be crossing the gap.)
6777 Check to see if the most recent message looks a lot like the previous one.
6778 Return 0 if different, 1 if the new one should just replace it, or a
6779 value N > 1 if we should also append " [N times]". */
6782 message_log_check_duplicate (prev_bol
, prev_bol_byte
, this_bol
, this_bol_byte
)
6783 int prev_bol
, this_bol
;
6784 int prev_bol_byte
, this_bol_byte
;
6787 int len
= Z_BYTE
- 1 - this_bol_byte
;
6789 unsigned char *p1
= BUF_BYTE_ADDRESS (current_buffer
, prev_bol_byte
);
6790 unsigned char *p2
= BUF_BYTE_ADDRESS (current_buffer
, this_bol_byte
);
6792 for (i
= 0; i
< len
; i
++)
6794 if (i
>= 3 && p1
[i
-3] == '.' && p1
[i
-2] == '.' && p1
[i
-1] == '.')
6802 if (*p1
++ == ' ' && *p1
++ == '[')
6805 while (*p1
>= '0' && *p1
<= '9')
6806 n
= n
* 10 + *p1
++ - '0';
6807 if (strncmp (p1
, " times]\n", 8) == 0)
6814 /* Display an echo area message M with a specified length of NBYTES
6815 bytes. The string may include null characters. If M is 0, clear
6816 out any existing message, and let the mini-buffer text show
6819 The buffer M must continue to exist until after the echo area gets
6820 cleared or some other message gets displayed there. This means do
6821 not pass text that is stored in a Lisp string; do not pass text in
6822 a buffer that was alloca'd. */
6825 message2 (m
, nbytes
, multibyte
)
6830 /* First flush out any partial line written with print. */
6831 message_log_maybe_newline ();
6833 message_dolog (m
, nbytes
, 1, multibyte
);
6834 message2_nolog (m
, nbytes
, multibyte
);
6838 /* The non-logging counterpart of message2. */
6841 message2_nolog (m
, nbytes
, multibyte
)
6843 int nbytes
, multibyte
;
6845 struct frame
*sf
= SELECTED_FRAME ();
6846 message_enable_multibyte
= multibyte
;
6850 if (noninteractive_need_newline
)
6851 putc ('\n', stderr
);
6852 noninteractive_need_newline
= 0;
6854 fwrite (m
, nbytes
, 1, stderr
);
6855 if (cursor_in_echo_area
== 0)
6856 fprintf (stderr
, "\n");
6859 /* A null message buffer means that the frame hasn't really been
6860 initialized yet. Error messages get reported properly by
6861 cmd_error, so this must be just an informative message; toss it. */
6862 else if (INTERACTIVE
6863 && sf
->glyphs_initialized_p
6864 && FRAME_MESSAGE_BUF (sf
))
6866 Lisp_Object mini_window
;
6869 /* Get the frame containing the mini-buffer
6870 that the selected frame is using. */
6871 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
6872 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
6874 FRAME_SAMPLE_VISIBILITY (f
);
6875 if (FRAME_VISIBLE_P (sf
)
6876 && ! FRAME_VISIBLE_P (f
))
6877 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window
)));
6881 set_message (m
, Qnil
, nbytes
, multibyte
);
6882 if (minibuffer_auto_raise
)
6883 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window
)));
6886 clear_message (1, 1);
6888 do_pending_window_change (0);
6889 echo_area_display (1);
6890 do_pending_window_change (0);
6891 if (frame_up_to_date_hook
!= 0 && ! gc_in_progress
)
6892 (*frame_up_to_date_hook
) (f
);
6897 /* Display an echo area message M with a specified length of NBYTES
6898 bytes. The string may include null characters. If M is not a
6899 string, clear out any existing message, and let the mini-buffer
6900 text show through. */
6903 message3 (m
, nbytes
, multibyte
)
6908 struct gcpro gcpro1
;
6911 clear_message (1,1);
6913 /* First flush out any partial line written with print. */
6914 message_log_maybe_newline ();
6916 message_dolog (SDATA (m
), nbytes
, 1, multibyte
);
6917 message3_nolog (m
, nbytes
, multibyte
);
6923 /* The non-logging version of message3. */
6926 message3_nolog (m
, nbytes
, multibyte
)
6928 int nbytes
, multibyte
;
6930 struct frame
*sf
= SELECTED_FRAME ();
6931 message_enable_multibyte
= multibyte
;
6935 if (noninteractive_need_newline
)
6936 putc ('\n', stderr
);
6937 noninteractive_need_newline
= 0;
6939 fwrite (SDATA (m
), nbytes
, 1, stderr
);
6940 if (cursor_in_echo_area
== 0)
6941 fprintf (stderr
, "\n");
6944 /* A null message buffer means that the frame hasn't really been
6945 initialized yet. Error messages get reported properly by
6946 cmd_error, so this must be just an informative message; toss it. */
6947 else if (INTERACTIVE
6948 && sf
->glyphs_initialized_p
6949 && FRAME_MESSAGE_BUF (sf
))
6951 Lisp_Object mini_window
;
6955 /* Get the frame containing the mini-buffer
6956 that the selected frame is using. */
6957 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
6958 frame
= XWINDOW (mini_window
)->frame
;
6961 FRAME_SAMPLE_VISIBILITY (f
);
6962 if (FRAME_VISIBLE_P (sf
)
6963 && !FRAME_VISIBLE_P (f
))
6964 Fmake_frame_visible (frame
);
6966 if (STRINGP (m
) && SCHARS (m
) > 0)
6968 set_message (NULL
, m
, nbytes
, multibyte
);
6969 if (minibuffer_auto_raise
)
6970 Fraise_frame (frame
);
6973 clear_message (1, 1);
6975 do_pending_window_change (0);
6976 echo_area_display (1);
6977 do_pending_window_change (0);
6978 if (frame_up_to_date_hook
!= 0 && ! gc_in_progress
)
6979 (*frame_up_to_date_hook
) (f
);
6984 /* Display a null-terminated echo area message M. If M is 0, clear
6985 out any existing message, and let the mini-buffer text show through.
6987 The buffer M must continue to exist until after the echo area gets
6988 cleared or some other message gets displayed there. Do not pass
6989 text that is stored in a Lisp string. Do not pass text in a buffer
6990 that was alloca'd. */
6996 message2 (m
, (m
? strlen (m
) : 0), 0);
7000 /* The non-logging counterpart of message1. */
7006 message2_nolog (m
, (m
? strlen (m
) : 0), 0);
7009 /* Display a message M which contains a single %s
7010 which gets replaced with STRING. */
7013 message_with_string (m
, string
, log
)
7018 CHECK_STRING (string
);
7024 if (noninteractive_need_newline
)
7025 putc ('\n', stderr
);
7026 noninteractive_need_newline
= 0;
7027 fprintf (stderr
, m
, SDATA (string
));
7028 if (cursor_in_echo_area
== 0)
7029 fprintf (stderr
, "\n");
7033 else if (INTERACTIVE
)
7035 /* The frame whose minibuffer we're going to display the message on.
7036 It may be larger than the selected frame, so we need
7037 to use its buffer, not the selected frame's buffer. */
7038 Lisp_Object mini_window
;
7039 struct frame
*f
, *sf
= SELECTED_FRAME ();
7041 /* Get the frame containing the minibuffer
7042 that the selected frame is using. */
7043 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
7044 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
7046 /* A null message buffer means that the frame hasn't really been
7047 initialized yet. Error messages get reported properly by
7048 cmd_error, so this must be just an informative message; toss it. */
7049 if (FRAME_MESSAGE_BUF (f
))
7051 Lisp_Object args
[2], message
;
7052 struct gcpro gcpro1
, gcpro2
;
7054 args
[0] = build_string (m
);
7055 args
[1] = message
= string
;
7056 GCPRO2 (args
[0], message
);
7059 message
= Fformat (2, args
);
7062 message3 (message
, SBYTES (message
), STRING_MULTIBYTE (message
));
7064 message3_nolog (message
, SBYTES (message
), STRING_MULTIBYTE (message
));
7068 /* Print should start at the beginning of the message
7069 buffer next time. */
7070 message_buf_print
= 0;
7076 /* Dump an informative message to the minibuf. If M is 0, clear out
7077 any existing message, and let the mini-buffer text show through. */
7081 message (m
, a1
, a2
, a3
)
7083 EMACS_INT a1
, a2
, a3
;
7089 if (noninteractive_need_newline
)
7090 putc ('\n', stderr
);
7091 noninteractive_need_newline
= 0;
7092 fprintf (stderr
, m
, a1
, a2
, a3
);
7093 if (cursor_in_echo_area
== 0)
7094 fprintf (stderr
, "\n");
7098 else if (INTERACTIVE
)
7100 /* The frame whose mini-buffer we're going to display the message
7101 on. It may be larger than the selected frame, so we need to
7102 use its buffer, not the selected frame's buffer. */
7103 Lisp_Object mini_window
;
7104 struct frame
*f
, *sf
= SELECTED_FRAME ();
7106 /* Get the frame containing the mini-buffer
7107 that the selected frame is using. */
7108 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
7109 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
7111 /* A null message buffer means that the frame hasn't really been
7112 initialized yet. Error messages get reported properly by
7113 cmd_error, so this must be just an informative message; toss
7115 if (FRAME_MESSAGE_BUF (f
))
7126 len
= doprnt (FRAME_MESSAGE_BUF (f
),
7127 FRAME_MESSAGE_BUF_SIZE (f
), m
, (char *)0, 3, a
);
7129 len
= doprnt (FRAME_MESSAGE_BUF (f
),
7130 FRAME_MESSAGE_BUF_SIZE (f
), m
, (char *)0, 3,
7132 #endif /* NO_ARG_ARRAY */
7134 message2 (FRAME_MESSAGE_BUF (f
), len
, 0);
7139 /* Print should start at the beginning of the message
7140 buffer next time. */
7141 message_buf_print
= 0;
7147 /* The non-logging version of message. */
7150 message_nolog (m
, a1
, a2
, a3
)
7152 EMACS_INT a1
, a2
, a3
;
7154 Lisp_Object old_log_max
;
7155 old_log_max
= Vmessage_log_max
;
7156 Vmessage_log_max
= Qnil
;
7157 message (m
, a1
, a2
, a3
);
7158 Vmessage_log_max
= old_log_max
;
7162 /* Display the current message in the current mini-buffer. This is
7163 only called from error handlers in process.c, and is not time
7169 if (!NILP (echo_area_buffer
[0]))
7172 string
= Fcurrent_message ();
7173 message3 (string
, SBYTES (string
),
7174 !NILP (current_buffer
->enable_multibyte_characters
));
7179 /* Make sure echo area buffers in `echo_buffers' are live.
7180 If they aren't, make new ones. */
7183 ensure_echo_area_buffers ()
7187 for (i
= 0; i
< 2; ++i
)
7188 if (!BUFFERP (echo_buffer
[i
])
7189 || NILP (XBUFFER (echo_buffer
[i
])->name
))
7192 Lisp_Object old_buffer
;
7195 old_buffer
= echo_buffer
[i
];
7196 sprintf (name
, " *Echo Area %d*", i
);
7197 echo_buffer
[i
] = Fget_buffer_create (build_string (name
));
7198 XBUFFER (echo_buffer
[i
])->truncate_lines
= Qnil
;
7200 for (j
= 0; j
< 2; ++j
)
7201 if (EQ (old_buffer
, echo_area_buffer
[j
]))
7202 echo_area_buffer
[j
] = echo_buffer
[i
];
7207 /* Call FN with args A1..A4 with either the current or last displayed
7208 echo_area_buffer as current buffer.
7210 WHICH zero means use the current message buffer
7211 echo_area_buffer[0]. If that is nil, choose a suitable buffer
7212 from echo_buffer[] and clear it.
7214 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
7215 suitable buffer from echo_buffer[] and clear it.
7217 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
7218 that the current message becomes the last displayed one, make
7219 choose a suitable buffer for echo_area_buffer[0], and clear it.
7221 Value is what FN returns. */
7224 with_echo_area_buffer (w
, which
, fn
, a1
, a2
, a3
, a4
)
7227 int (*fn
) P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
7233 int this_one
, the_other
, clear_buffer_p
, rc
;
7234 int count
= SPECPDL_INDEX ();
7236 /* If buffers aren't live, make new ones. */
7237 ensure_echo_area_buffers ();
7242 this_one
= 0, the_other
= 1;
7244 this_one
= 1, the_other
= 0;
7247 this_one
= 0, the_other
= 1;
7250 /* We need a fresh one in case the current echo buffer equals
7251 the one containing the last displayed echo area message. */
7252 if (!NILP (echo_area_buffer
[this_one
])
7253 && EQ (echo_area_buffer
[this_one
], echo_area_buffer
[the_other
]))
7254 echo_area_buffer
[this_one
] = Qnil
;
7257 /* Choose a suitable buffer from echo_buffer[] is we don't
7259 if (NILP (echo_area_buffer
[this_one
]))
7261 echo_area_buffer
[this_one
]
7262 = (EQ (echo_area_buffer
[the_other
], echo_buffer
[this_one
])
7263 ? echo_buffer
[the_other
]
7264 : echo_buffer
[this_one
]);
7268 buffer
= echo_area_buffer
[this_one
];
7270 /* Don't get confused by reusing the buffer used for echoing
7271 for a different purpose. */
7272 if (echo_kboard
== NULL
&& EQ (buffer
, echo_message_buffer
))
7275 record_unwind_protect (unwind_with_echo_area_buffer
,
7276 with_echo_area_buffer_unwind_data (w
));
7278 /* Make the echo area buffer current. Note that for display
7279 purposes, it is not necessary that the displayed window's buffer
7280 == current_buffer, except for text property lookup. So, let's
7281 only set that buffer temporarily here without doing a full
7282 Fset_window_buffer. We must also change w->pointm, though,
7283 because otherwise an assertions in unshow_buffer fails, and Emacs
7285 set_buffer_internal_1 (XBUFFER (buffer
));
7289 set_marker_both (w
->pointm
, buffer
, BEG
, BEG_BYTE
);
7292 current_buffer
->undo_list
= Qt
;
7293 current_buffer
->read_only
= Qnil
;
7294 specbind (Qinhibit_read_only
, Qt
);
7295 specbind (Qinhibit_modification_hooks
, Qt
);
7297 if (clear_buffer_p
&& Z
> BEG
)
7300 xassert (BEGV
>= BEG
);
7301 xassert (ZV
<= Z
&& ZV
>= BEGV
);
7303 rc
= fn (a1
, a2
, a3
, a4
);
7305 xassert (BEGV
>= BEG
);
7306 xassert (ZV
<= Z
&& ZV
>= BEGV
);
7308 unbind_to (count
, Qnil
);
7313 /* Save state that should be preserved around the call to the function
7314 FN called in with_echo_area_buffer. */
7317 with_echo_area_buffer_unwind_data (w
)
7323 /* Reduce consing by keeping one vector in
7324 Vwith_echo_area_save_vector. */
7325 vector
= Vwith_echo_area_save_vector
;
7326 Vwith_echo_area_save_vector
= Qnil
;
7329 vector
= Fmake_vector (make_number (7), Qnil
);
7331 XSETBUFFER (AREF (vector
, i
), current_buffer
); ++i
;
7332 AREF (vector
, i
) = Vdeactivate_mark
, ++i
;
7333 AREF (vector
, i
) = make_number (windows_or_buffers_changed
), ++i
;
7337 XSETWINDOW (AREF (vector
, i
), w
); ++i
;
7338 AREF (vector
, i
) = w
->buffer
; ++i
;
7339 AREF (vector
, i
) = make_number (XMARKER (w
->pointm
)->charpos
); ++i
;
7340 AREF (vector
, i
) = make_number (XMARKER (w
->pointm
)->bytepos
); ++i
;
7345 for (; i
< end
; ++i
)
7346 AREF (vector
, i
) = Qnil
;
7349 xassert (i
== ASIZE (vector
));
7354 /* Restore global state from VECTOR which was created by
7355 with_echo_area_buffer_unwind_data. */
7358 unwind_with_echo_area_buffer (vector
)
7361 set_buffer_internal_1 (XBUFFER (AREF (vector
, 0)));
7362 Vdeactivate_mark
= AREF (vector
, 1);
7363 windows_or_buffers_changed
= XFASTINT (AREF (vector
, 2));
7365 if (WINDOWP (AREF (vector
, 3)))
7368 Lisp_Object buffer
, charpos
, bytepos
;
7370 w
= XWINDOW (AREF (vector
, 3));
7371 buffer
= AREF (vector
, 4);
7372 charpos
= AREF (vector
, 5);
7373 bytepos
= AREF (vector
, 6);
7376 set_marker_both (w
->pointm
, buffer
,
7377 XFASTINT (charpos
), XFASTINT (bytepos
));
7380 Vwith_echo_area_save_vector
= vector
;
7385 /* Set up the echo area for use by print functions. MULTIBYTE_P
7386 non-zero means we will print multibyte. */
7389 setup_echo_area_for_printing (multibyte_p
)
7392 /* If we can't find an echo area any more, exit. */
7393 if (! FRAME_LIVE_P (XFRAME (selected_frame
)))
7396 ensure_echo_area_buffers ();
7398 if (!message_buf_print
)
7400 /* A message has been output since the last time we printed.
7401 Choose a fresh echo area buffer. */
7402 if (EQ (echo_area_buffer
[1], echo_buffer
[0]))
7403 echo_area_buffer
[0] = echo_buffer
[1];
7405 echo_area_buffer
[0] = echo_buffer
[0];
7407 /* Switch to that buffer and clear it. */
7408 set_buffer_internal (XBUFFER (echo_area_buffer
[0]));
7409 current_buffer
->truncate_lines
= Qnil
;
7413 int count
= SPECPDL_INDEX ();
7414 specbind (Qinhibit_read_only
, Qt
);
7415 /* Note that undo recording is always disabled. */
7417 unbind_to (count
, Qnil
);
7419 TEMP_SET_PT_BOTH (BEG
, BEG_BYTE
);
7421 /* Set up the buffer for the multibyteness we need. */
7423 != !NILP (current_buffer
->enable_multibyte_characters
))
7424 Fset_buffer_multibyte (multibyte_p
? Qt
: Qnil
);
7426 /* Raise the frame containing the echo area. */
7427 if (minibuffer_auto_raise
)
7429 struct frame
*sf
= SELECTED_FRAME ();
7430 Lisp_Object mini_window
;
7431 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
7432 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window
)));
7435 message_log_maybe_newline ();
7436 message_buf_print
= 1;
7440 if (NILP (echo_area_buffer
[0]))
7442 if (EQ (echo_area_buffer
[1], echo_buffer
[0]))
7443 echo_area_buffer
[0] = echo_buffer
[1];
7445 echo_area_buffer
[0] = echo_buffer
[0];
7448 if (current_buffer
!= XBUFFER (echo_area_buffer
[0]))
7450 /* Someone switched buffers between print requests. */
7451 set_buffer_internal (XBUFFER (echo_area_buffer
[0]));
7452 current_buffer
->truncate_lines
= Qnil
;
7458 /* Display an echo area message in window W. Value is non-zero if W's
7459 height is changed. If display_last_displayed_message_p is
7460 non-zero, display the message that was last displayed, otherwise
7461 display the current message. */
7464 display_echo_area (w
)
7467 int i
, no_message_p
, window_height_changed_p
, count
;
7469 /* Temporarily disable garbage collections while displaying the echo
7470 area. This is done because a GC can print a message itself.
7471 That message would modify the echo area buffer's contents while a
7472 redisplay of the buffer is going on, and seriously confuse
7474 count
= inhibit_garbage_collection ();
7476 /* If there is no message, we must call display_echo_area_1
7477 nevertheless because it resizes the window. But we will have to
7478 reset the echo_area_buffer in question to nil at the end because
7479 with_echo_area_buffer will sets it to an empty buffer. */
7480 i
= display_last_displayed_message_p
? 1 : 0;
7481 no_message_p
= NILP (echo_area_buffer
[i
]);
7483 window_height_changed_p
7484 = with_echo_area_buffer (w
, display_last_displayed_message_p
,
7485 display_echo_area_1
,
7486 (EMACS_INT
) w
, Qnil
, 0, 0);
7489 echo_area_buffer
[i
] = Qnil
;
7491 unbind_to (count
, Qnil
);
7492 return window_height_changed_p
;
7496 /* Helper for display_echo_area. Display the current buffer which
7497 contains the current echo area message in window W, a mini-window,
7498 a pointer to which is passed in A1. A2..A4 are currently not used.
7499 Change the height of W so that all of the message is displayed.
7500 Value is non-zero if height of W was changed. */
7503 display_echo_area_1 (a1
, a2
, a3
, a4
)
7508 struct window
*w
= (struct window
*) a1
;
7510 struct text_pos start
;
7511 int window_height_changed_p
= 0;
7513 /* Do this before displaying, so that we have a large enough glyph
7514 matrix for the display. */
7515 window_height_changed_p
= resize_mini_window (w
, 0);
7518 clear_glyph_matrix (w
->desired_matrix
);
7519 XSETWINDOW (window
, w
);
7520 SET_TEXT_POS (start
, BEG
, BEG_BYTE
);
7521 try_window (window
, start
);
7523 return window_height_changed_p
;
7527 /* Resize the echo area window to exactly the size needed for the
7528 currently displayed message, if there is one. If a mini-buffer
7529 is active, don't shrink it. */
7532 resize_echo_area_exactly ()
7534 if (BUFFERP (echo_area_buffer
[0])
7535 && WINDOWP (echo_area_window
))
7537 struct window
*w
= XWINDOW (echo_area_window
);
7539 Lisp_Object resize_exactly
;
7541 if (minibuf_level
== 0)
7542 resize_exactly
= Qt
;
7544 resize_exactly
= Qnil
;
7546 resized_p
= with_echo_area_buffer (w
, 0, resize_mini_window_1
,
7547 (EMACS_INT
) w
, resize_exactly
, 0, 0);
7550 ++windows_or_buffers_changed
;
7551 ++update_mode_lines
;
7552 redisplay_internal (0);
7558 /* Callback function for with_echo_area_buffer, when used from
7559 resize_echo_area_exactly. A1 contains a pointer to the window to
7560 resize, EXACTLY non-nil means resize the mini-window exactly to the
7561 size of the text displayed. A3 and A4 are not used. Value is what
7562 resize_mini_window returns. */
7565 resize_mini_window_1 (a1
, exactly
, a3
, a4
)
7567 Lisp_Object exactly
;
7570 return resize_mini_window ((struct window
*) a1
, !NILP (exactly
));
7574 /* Resize mini-window W to fit the size of its contents. EXACT:P
7575 means size the window exactly to the size needed. Otherwise, it's
7576 only enlarged until W's buffer is empty. Value is non-zero if
7577 the window height has been changed. */
7580 resize_mini_window (w
, exact_p
)
7584 struct frame
*f
= XFRAME (w
->frame
);
7585 int window_height_changed_p
= 0;
7587 xassert (MINI_WINDOW_P (w
));
7589 /* Don't resize windows while redisplaying a window; it would
7590 confuse redisplay functions when the size of the window they are
7591 displaying changes from under them. Such a resizing can happen,
7592 for instance, when which-func prints a long message while
7593 we are running fontification-functions. We're running these
7594 functions with safe_call which binds inhibit-redisplay to t. */
7595 if (!NILP (Vinhibit_redisplay
))
7598 /* Nil means don't try to resize. */
7599 if (NILP (Vresize_mini_windows
)
7600 || (FRAME_X_P (f
) && FRAME_X_OUTPUT (f
) == NULL
))
7603 if (!FRAME_MINIBUF_ONLY_P (f
))
7606 struct window
*root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
7607 int total_height
= WINDOW_TOTAL_LINES (root
) + WINDOW_TOTAL_LINES (w
);
7608 int height
, max_height
;
7609 int unit
= FRAME_LINE_HEIGHT (f
);
7610 struct text_pos start
;
7611 struct buffer
*old_current_buffer
= NULL
;
7613 if (current_buffer
!= XBUFFER (w
->buffer
))
7615 old_current_buffer
= current_buffer
;
7616 set_buffer_internal (XBUFFER (w
->buffer
));
7619 init_iterator (&it
, w
, BEGV
, BEGV_BYTE
, NULL
, DEFAULT_FACE_ID
);
7621 /* Compute the max. number of lines specified by the user. */
7622 if (FLOATP (Vmax_mini_window_height
))
7623 max_height
= XFLOATINT (Vmax_mini_window_height
) * FRAME_LINES (f
);
7624 else if (INTEGERP (Vmax_mini_window_height
))
7625 max_height
= XINT (Vmax_mini_window_height
);
7627 max_height
= total_height
/ 4;
7629 /* Correct that max. height if it's bogus. */
7630 max_height
= max (1, max_height
);
7631 max_height
= min (total_height
, max_height
);
7633 /* Find out the height of the text in the window. */
7634 if (it
.truncate_lines_p
)
7639 move_it_to (&it
, ZV
, -1, -1, -1, MOVE_TO_POS
);
7640 if (it
.max_ascent
== 0 && it
.max_descent
== 0)
7641 height
= it
.current_y
+ last_height
;
7643 height
= it
.current_y
+ it
.max_ascent
+ it
.max_descent
;
7644 height
-= min (it
.extra_line_spacing
, it
.max_extra_line_spacing
);
7645 height
= (height
+ unit
- 1) / unit
;
7648 /* Compute a suitable window start. */
7649 if (height
> max_height
)
7651 height
= max_height
;
7652 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
7653 move_it_vertically_backward (&it
, (height
- 1) * unit
);
7654 start
= it
.current
.pos
;
7657 SET_TEXT_POS (start
, BEGV
, BEGV_BYTE
);
7658 SET_MARKER_FROM_TEXT_POS (w
->start
, start
);
7660 if (EQ (Vresize_mini_windows
, Qgrow_only
))
7662 /* Let it grow only, until we display an empty message, in which
7663 case the window shrinks again. */
7664 if (height
> WINDOW_TOTAL_LINES (w
))
7666 int old_height
= WINDOW_TOTAL_LINES (w
);
7667 freeze_window_starts (f
, 1);
7668 grow_mini_window (w
, height
- WINDOW_TOTAL_LINES (w
));
7669 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
7671 else if (height
< WINDOW_TOTAL_LINES (w
)
7672 && (exact_p
|| BEGV
== ZV
))
7674 int old_height
= WINDOW_TOTAL_LINES (w
);
7675 freeze_window_starts (f
, 0);
7676 shrink_mini_window (w
);
7677 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
7682 /* Always resize to exact size needed. */
7683 if (height
> WINDOW_TOTAL_LINES (w
))
7685 int old_height
= WINDOW_TOTAL_LINES (w
);
7686 freeze_window_starts (f
, 1);
7687 grow_mini_window (w
, height
- WINDOW_TOTAL_LINES (w
));
7688 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
7690 else if (height
< WINDOW_TOTAL_LINES (w
))
7692 int old_height
= WINDOW_TOTAL_LINES (w
);
7693 freeze_window_starts (f
, 0);
7694 shrink_mini_window (w
);
7698 freeze_window_starts (f
, 1);
7699 grow_mini_window (w
, height
- WINDOW_TOTAL_LINES (w
));
7702 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
7706 if (old_current_buffer
)
7707 set_buffer_internal (old_current_buffer
);
7710 return window_height_changed_p
;
7714 /* Value is the current message, a string, or nil if there is no
7722 if (NILP (echo_area_buffer
[0]))
7726 with_echo_area_buffer (0, 0, current_message_1
,
7727 (EMACS_INT
) &msg
, Qnil
, 0, 0);
7729 echo_area_buffer
[0] = Qnil
;
7737 current_message_1 (a1
, a2
, a3
, a4
)
7742 Lisp_Object
*msg
= (Lisp_Object
*) a1
;
7745 *msg
= make_buffer_string (BEG
, Z
, 1);
7752 /* Push the current message on Vmessage_stack for later restauration
7753 by restore_message. Value is non-zero if the current message isn't
7754 empty. This is a relatively infrequent operation, so it's not
7755 worth optimizing. */
7761 msg
= current_message ();
7762 Vmessage_stack
= Fcons (msg
, Vmessage_stack
);
7763 return STRINGP (msg
);
7767 /* Restore message display from the top of Vmessage_stack. */
7774 xassert (CONSP (Vmessage_stack
));
7775 msg
= XCAR (Vmessage_stack
);
7777 message3_nolog (msg
, SBYTES (msg
), STRING_MULTIBYTE (msg
));
7779 message3_nolog (msg
, 0, 0);
7783 /* Handler for record_unwind_protect calling pop_message. */
7786 pop_message_unwind (dummy
)
7793 /* Pop the top-most entry off Vmessage_stack. */
7798 xassert (CONSP (Vmessage_stack
));
7799 Vmessage_stack
= XCDR (Vmessage_stack
);
7803 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
7804 exits. If the stack is not empty, we have a missing pop_message
7808 check_message_stack ()
7810 if (!NILP (Vmessage_stack
))
7815 /* Truncate to NCHARS what will be displayed in the echo area the next
7816 time we display it---but don't redisplay it now. */
7819 truncate_echo_area (nchars
)
7823 echo_area_buffer
[0] = Qnil
;
7824 /* A null message buffer means that the frame hasn't really been
7825 initialized yet. Error messages get reported properly by
7826 cmd_error, so this must be just an informative message; toss it. */
7827 else if (!noninteractive
7829 && !NILP (echo_area_buffer
[0]))
7831 struct frame
*sf
= SELECTED_FRAME ();
7832 if (FRAME_MESSAGE_BUF (sf
))
7833 with_echo_area_buffer (0, 0, truncate_message_1
, nchars
, Qnil
, 0, 0);
7838 /* Helper function for truncate_echo_area. Truncate the current
7839 message to at most NCHARS characters. */
7842 truncate_message_1 (nchars
, a2
, a3
, a4
)
7847 if (BEG
+ nchars
< Z
)
7848 del_range (BEG
+ nchars
, Z
);
7850 echo_area_buffer
[0] = Qnil
;
7855 /* Set the current message to a substring of S or STRING.
7857 If STRING is a Lisp string, set the message to the first NBYTES
7858 bytes from STRING. NBYTES zero means use the whole string. If
7859 STRING is multibyte, the message will be displayed multibyte.
7861 If S is not null, set the message to the first LEN bytes of S. LEN
7862 zero means use the whole string. MULTIBYTE_P non-zero means S is
7863 multibyte. Display the message multibyte in that case. */
7866 set_message (s
, string
, nbytes
, multibyte_p
)
7869 int nbytes
, multibyte_p
;
7871 message_enable_multibyte
7872 = ((s
&& multibyte_p
)
7873 || (STRINGP (string
) && STRING_MULTIBYTE (string
)));
7875 with_echo_area_buffer (0, -1, set_message_1
,
7876 (EMACS_INT
) s
, string
, nbytes
, multibyte_p
);
7877 message_buf_print
= 0;
7878 help_echo_showing_p
= 0;
7882 /* Helper function for set_message. Arguments have the same meaning
7883 as there, with A1 corresponding to S and A2 corresponding to STRING
7884 This function is called with the echo area buffer being
7888 set_message_1 (a1
, a2
, nbytes
, multibyte_p
)
7891 EMACS_INT nbytes
, multibyte_p
;
7893 const char *s
= (const char *) a1
;
7894 Lisp_Object string
= a2
;
7898 /* Change multibyteness of the echo buffer appropriately. */
7899 if (message_enable_multibyte
7900 != !NILP (current_buffer
->enable_multibyte_characters
))
7901 Fset_buffer_multibyte (message_enable_multibyte
? Qt
: Qnil
);
7903 current_buffer
->truncate_lines
= message_truncate_lines
? Qt
: Qnil
;
7905 /* Insert new message at BEG. */
7906 TEMP_SET_PT_BOTH (BEG
, BEG_BYTE
);
7908 if (STRINGP (string
))
7913 nbytes
= SBYTES (string
);
7914 nchars
= string_byte_to_char (string
, nbytes
);
7916 /* This function takes care of single/multibyte conversion. We
7917 just have to ensure that the echo area buffer has the right
7918 setting of enable_multibyte_characters. */
7919 insert_from_string (string
, 0, 0, nchars
, nbytes
, 1);
7924 nbytes
= strlen (s
);
7926 if (multibyte_p
&& NILP (current_buffer
->enable_multibyte_characters
))
7928 /* Convert from multi-byte to single-byte. */
7930 unsigned char work
[1];
7932 /* Convert a multibyte string to single-byte. */
7933 for (i
= 0; i
< nbytes
; i
+= n
)
7935 c
= string_char_and_length (s
+ i
, nbytes
- i
, &n
);
7936 work
[0] = (SINGLE_BYTE_CHAR_P (c
)
7938 : multibyte_char_to_unibyte (c
, Qnil
));
7939 insert_1_both (work
, 1, 1, 1, 0, 0);
7942 else if (!multibyte_p
7943 && !NILP (current_buffer
->enable_multibyte_characters
))
7945 /* Convert from single-byte to multi-byte. */
7947 const unsigned char *msg
= (const unsigned char *) s
;
7948 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
7950 /* Convert a single-byte string to multibyte. */
7951 for (i
= 0; i
< nbytes
; i
++)
7953 c
= unibyte_char_to_multibyte (msg
[i
]);
7954 n
= CHAR_STRING (c
, str
);
7955 insert_1_both (str
, 1, n
, 1, 0, 0);
7959 insert_1 (s
, nbytes
, 1, 0, 0);
7966 /* Clear messages. CURRENT_P non-zero means clear the current
7967 message. LAST_DISPLAYED_P non-zero means clear the message
7971 clear_message (current_p
, last_displayed_p
)
7972 int current_p
, last_displayed_p
;
7976 echo_area_buffer
[0] = Qnil
;
7977 message_cleared_p
= 1;
7980 if (last_displayed_p
)
7981 echo_area_buffer
[1] = Qnil
;
7983 message_buf_print
= 0;
7986 /* Clear garbaged frames.
7988 This function is used where the old redisplay called
7989 redraw_garbaged_frames which in turn called redraw_frame which in
7990 turn called clear_frame. The call to clear_frame was a source of
7991 flickering. I believe a clear_frame is not necessary. It should
7992 suffice in the new redisplay to invalidate all current matrices,
7993 and ensure a complete redisplay of all windows. */
7996 clear_garbaged_frames ()
8000 Lisp_Object tail
, frame
;
8001 int changed_count
= 0;
8003 FOR_EACH_FRAME (tail
, frame
)
8005 struct frame
*f
= XFRAME (frame
);
8007 if (FRAME_VISIBLE_P (f
) && FRAME_GARBAGED_P (f
))
8011 Fredraw_frame (frame
);
8012 f
->force_flush_display_p
= 1;
8014 clear_current_matrices (f
);
8023 ++windows_or_buffers_changed
;
8028 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
8029 is non-zero update selected_frame. Value is non-zero if the
8030 mini-windows height has been changed. */
8033 echo_area_display (update_frame_p
)
8036 Lisp_Object mini_window
;
8039 int window_height_changed_p
= 0;
8040 struct frame
*sf
= SELECTED_FRAME ();
8042 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
8043 w
= XWINDOW (mini_window
);
8044 f
= XFRAME (WINDOW_FRAME (w
));
8046 /* Don't display if frame is invisible or not yet initialized. */
8047 if (!FRAME_VISIBLE_P (f
) || !f
->glyphs_initialized_p
)
8050 /* The terminal frame is used as the first Emacs frame on the Mac OS. */
8052 #ifdef HAVE_WINDOW_SYSTEM
8053 /* When Emacs starts, selected_frame may be a visible terminal
8054 frame, even if we run under a window system. If we let this
8055 through, a message would be displayed on the terminal. */
8056 if (EQ (selected_frame
, Vterminal_frame
)
8057 && !NILP (Vwindow_system
))
8059 #endif /* HAVE_WINDOW_SYSTEM */
8062 /* Redraw garbaged frames. */
8064 clear_garbaged_frames ();
8066 if (!NILP (echo_area_buffer
[0]) || minibuf_level
== 0)
8068 echo_area_window
= mini_window
;
8069 window_height_changed_p
= display_echo_area (w
);
8070 w
->must_be_updated_p
= 1;
8072 /* Update the display, unless called from redisplay_internal.
8073 Also don't update the screen during redisplay itself. The
8074 update will happen at the end of redisplay, and an update
8075 here could cause confusion. */
8076 if (update_frame_p
&& !redisplaying_p
)
8080 /* If the display update has been interrupted by pending
8081 input, update mode lines in the frame. Due to the
8082 pending input, it might have been that redisplay hasn't
8083 been called, so that mode lines above the echo area are
8084 garbaged. This looks odd, so we prevent it here. */
8085 if (!display_completed
)
8086 n
= redisplay_mode_lines (FRAME_ROOT_WINDOW (f
), 0);
8088 if (window_height_changed_p
8089 /* Don't do this if Emacs is shutting down. Redisplay
8090 needs to run hooks. */
8091 && !NILP (Vrun_hooks
))
8093 /* Must update other windows. Likewise as in other
8094 cases, don't let this update be interrupted by
8096 int count
= SPECPDL_INDEX ();
8097 specbind (Qredisplay_dont_pause
, Qt
);
8098 windows_or_buffers_changed
= 1;
8099 redisplay_internal (0);
8100 unbind_to (count
, Qnil
);
8102 else if (FRAME_WINDOW_P (f
) && n
== 0)
8104 /* Window configuration is the same as before.
8105 Can do with a display update of the echo area,
8106 unless we displayed some mode lines. */
8107 update_single_window (w
, 1);
8108 rif
->flush_display (f
);
8111 update_frame (f
, 1, 1);
8113 /* If cursor is in the echo area, make sure that the next
8114 redisplay displays the minibuffer, so that the cursor will
8115 be replaced with what the minibuffer wants. */
8116 if (cursor_in_echo_area
)
8117 ++windows_or_buffers_changed
;
8120 else if (!EQ (mini_window
, selected_window
))
8121 windows_or_buffers_changed
++;
8123 /* Last displayed message is now the current message. */
8124 echo_area_buffer
[1] = echo_area_buffer
[0];
8125 /* Inform read_char that we're not echoing. */
8126 echo_message_buffer
= Qnil
;
8128 /* Prevent redisplay optimization in redisplay_internal by resetting
8129 this_line_start_pos. This is done because the mini-buffer now
8130 displays the message instead of its buffer text. */
8131 if (EQ (mini_window
, selected_window
))
8132 CHARPOS (this_line_start_pos
) = 0;
8134 return window_height_changed_p
;
8139 /***********************************************************************
8141 ***********************************************************************/
8144 /* The frame title buffering code is also used by Fformat_mode_line.
8145 So it is not conditioned by HAVE_WINDOW_SYSTEM. */
8147 /* A buffer for constructing frame titles in it; allocated from the
8148 heap in init_xdisp and resized as needed in store_frame_title_char. */
8150 static char *frame_title_buf
;
8152 /* The buffer's end, and a current output position in it. */
8154 static char *frame_title_buf_end
;
8155 static char *frame_title_ptr
;
8158 /* Store a single character C for the frame title in frame_title_buf.
8159 Re-allocate frame_title_buf if necessary. */
8163 store_frame_title_char (char c
)
8165 store_frame_title_char (c
)
8169 /* If output position has reached the end of the allocated buffer,
8170 double the buffer's size. */
8171 if (frame_title_ptr
== frame_title_buf_end
)
8173 int len
= frame_title_ptr
- frame_title_buf
;
8174 int new_size
= 2 * len
* sizeof *frame_title_buf
;
8175 frame_title_buf
= (char *) xrealloc (frame_title_buf
, new_size
);
8176 frame_title_buf_end
= frame_title_buf
+ new_size
;
8177 frame_title_ptr
= frame_title_buf
+ len
;
8180 *frame_title_ptr
++ = c
;
8184 /* Store part of a frame title in frame_title_buf, beginning at
8185 frame_title_ptr. STR is the string to store. Do not copy
8186 characters that yield more columns than PRECISION; PRECISION <= 0
8187 means copy the whole string. Pad with spaces until FIELD_WIDTH
8188 number of characters have been copied; FIELD_WIDTH <= 0 means don't
8189 pad. Called from display_mode_element when it is used to build a
8193 store_frame_title (str
, field_width
, precision
)
8194 const unsigned char *str
;
8195 int field_width
, precision
;
8200 /* Copy at most PRECISION chars from STR. */
8201 nbytes
= strlen (str
);
8202 n
+= c_string_width (str
, nbytes
, precision
, &dummy
, &nbytes
);
8204 store_frame_title_char (*str
++);
8206 /* Fill up with spaces until FIELD_WIDTH reached. */
8207 while (field_width
> 0
8210 store_frame_title_char (' ');
8217 #ifdef HAVE_WINDOW_SYSTEM
8219 /* Set the title of FRAME, if it has changed. The title format is
8220 Vicon_title_format if FRAME is iconified, otherwise it is
8221 frame_title_format. */
8224 x_consider_frame_title (frame
)
8227 struct frame
*f
= XFRAME (frame
);
8229 if (FRAME_WINDOW_P (f
)
8230 || FRAME_MINIBUF_ONLY_P (f
)
8231 || f
->explicit_name
)
8233 /* Do we have more than one visible frame on this X display? */
8236 struct buffer
*obuf
;
8240 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCDR (tail
))
8242 Lisp_Object other_frame
= XCAR (tail
);
8243 struct frame
*tf
= XFRAME (other_frame
);
8246 && FRAME_KBOARD (tf
) == FRAME_KBOARD (f
)
8247 && !FRAME_MINIBUF_ONLY_P (tf
)
8248 && !EQ (other_frame
, tip_frame
)
8249 && (FRAME_VISIBLE_P (tf
) || FRAME_ICONIFIED_P (tf
)))
8253 /* Set global variable indicating that multiple frames exist. */
8254 multiple_frames
= CONSP (tail
);
8256 /* Switch to the buffer of selected window of the frame. Set up
8257 frame_title_ptr so that display_mode_element will output into it;
8258 then display the title. */
8259 obuf
= current_buffer
;
8260 set_buffer_internal_1 (XBUFFER (XWINDOW (f
->selected_window
)->buffer
));
8261 fmt
= FRAME_ICONIFIED_P (f
) ? Vicon_title_format
: Vframe_title_format
;
8262 frame_title_ptr
= frame_title_buf
;
8263 init_iterator (&it
, XWINDOW (f
->selected_window
), -1, -1,
8264 NULL
, DEFAULT_FACE_ID
);
8265 display_mode_element (&it
, 0, -1, -1, fmt
, Qnil
, 0);
8266 len
= frame_title_ptr
- frame_title_buf
;
8267 frame_title_ptr
= NULL
;
8268 set_buffer_internal_1 (obuf
);
8270 /* Set the title only if it's changed. This avoids consing in
8271 the common case where it hasn't. (If it turns out that we've
8272 already wasted too much time by walking through the list with
8273 display_mode_element, then we might need to optimize at a
8274 higher level than this.) */
8275 if (! STRINGP (f
->name
)
8276 || SBYTES (f
->name
) != len
8277 || bcmp (frame_title_buf
, SDATA (f
->name
), len
) != 0)
8278 x_implicitly_set_name (f
, make_string (frame_title_buf
, len
), Qnil
);
8282 #endif /* not HAVE_WINDOW_SYSTEM */
8287 /***********************************************************************
8289 ***********************************************************************/
8292 /* Prepare for redisplay by updating menu-bar item lists when
8293 appropriate. This can call eval. */
8296 prepare_menu_bars ()
8299 struct gcpro gcpro1
, gcpro2
;
8301 Lisp_Object tooltip_frame
;
8303 #ifdef HAVE_WINDOW_SYSTEM
8304 tooltip_frame
= tip_frame
;
8306 tooltip_frame
= Qnil
;
8309 /* Update all frame titles based on their buffer names, etc. We do
8310 this before the menu bars so that the buffer-menu will show the
8311 up-to-date frame titles. */
8312 #ifdef HAVE_WINDOW_SYSTEM
8313 if (windows_or_buffers_changed
|| update_mode_lines
)
8315 Lisp_Object tail
, frame
;
8317 FOR_EACH_FRAME (tail
, frame
)
8320 if (!EQ (frame
, tooltip_frame
)
8321 && (FRAME_VISIBLE_P (f
) || FRAME_ICONIFIED_P (f
)))
8322 x_consider_frame_title (frame
);
8325 #endif /* HAVE_WINDOW_SYSTEM */
8327 /* Update the menu bar item lists, if appropriate. This has to be
8328 done before any actual redisplay or generation of display lines. */
8329 all_windows
= (update_mode_lines
8330 || buffer_shared
> 1
8331 || windows_or_buffers_changed
);
8334 Lisp_Object tail
, frame
;
8335 int count
= SPECPDL_INDEX ();
8337 record_unwind_protect (Fset_match_data
, Fmatch_data (Qnil
, Qnil
));
8339 FOR_EACH_FRAME (tail
, frame
)
8343 /* Ignore tooltip frame. */
8344 if (EQ (frame
, tooltip_frame
))
8347 /* If a window on this frame changed size, report that to
8348 the user and clear the size-change flag. */
8349 if (FRAME_WINDOW_SIZES_CHANGED (f
))
8351 Lisp_Object functions
;
8353 /* Clear flag first in case we get an error below. */
8354 FRAME_WINDOW_SIZES_CHANGED (f
) = 0;
8355 functions
= Vwindow_size_change_functions
;
8356 GCPRO2 (tail
, functions
);
8358 while (CONSP (functions
))
8360 call1 (XCAR (functions
), frame
);
8361 functions
= XCDR (functions
);
8367 update_menu_bar (f
, 0);
8368 #ifdef HAVE_WINDOW_SYSTEM
8369 update_tool_bar (f
, 0);
8374 unbind_to (count
, Qnil
);
8378 struct frame
*sf
= SELECTED_FRAME ();
8379 update_menu_bar (sf
, 1);
8380 #ifdef HAVE_WINDOW_SYSTEM
8381 update_tool_bar (sf
, 1);
8385 /* Motif needs this. See comment in xmenu.c. Turn it off when
8386 pending_menu_activation is not defined. */
8387 #ifdef USE_X_TOOLKIT
8388 pending_menu_activation
= 0;
8393 /* Update the menu bar item list for frame F. This has to be done
8394 before we start to fill in any display lines, because it can call
8397 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
8400 update_menu_bar (f
, save_match_data
)
8402 int save_match_data
;
8405 register struct window
*w
;
8407 /* If called recursively during a menu update, do nothing. This can
8408 happen when, for instance, an activate-menubar-hook causes a
8410 if (inhibit_menubar_update
)
8413 window
= FRAME_SELECTED_WINDOW (f
);
8414 w
= XWINDOW (window
);
8416 #if 0 /* The if statement below this if statement used to include the
8417 condition !NILP (w->update_mode_line), rather than using
8418 update_mode_lines directly, and this if statement may have
8419 been added to make that condition work. Now the if
8420 statement below matches its comment, this isn't needed. */
8421 if (update_mode_lines
)
8422 w
->update_mode_line
= Qt
;
8425 if (FRAME_WINDOW_P (f
)
8427 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8428 || defined (USE_GTK)
8429 FRAME_EXTERNAL_MENU_BAR (f
)
8431 FRAME_MENU_BAR_LINES (f
) > 0
8433 : FRAME_MENU_BAR_LINES (f
) > 0)
8435 /* If the user has switched buffers or windows, we need to
8436 recompute to reflect the new bindings. But we'll
8437 recompute when update_mode_lines is set too; that means
8438 that people can use force-mode-line-update to request
8439 that the menu bar be recomputed. The adverse effect on
8440 the rest of the redisplay algorithm is about the same as
8441 windows_or_buffers_changed anyway. */
8442 if (windows_or_buffers_changed
8443 /* This used to test w->update_mode_line, but we believe
8444 there is no need to recompute the menu in that case. */
8445 || update_mode_lines
8446 || ((BUF_SAVE_MODIFF (XBUFFER (w
->buffer
))
8447 < BUF_MODIFF (XBUFFER (w
->buffer
)))
8448 != !NILP (w
->last_had_star
))
8449 || ((!NILP (Vtransient_mark_mode
)
8450 && !NILP (XBUFFER (w
->buffer
)->mark_active
))
8451 != !NILP (w
->region_showing
)))
8453 struct buffer
*prev
= current_buffer
;
8454 int count
= SPECPDL_INDEX ();
8456 specbind (Qinhibit_menubar_update
, Qt
);
8458 set_buffer_internal_1 (XBUFFER (w
->buffer
));
8459 if (save_match_data
)
8460 record_unwind_protect (Fset_match_data
, Fmatch_data (Qnil
, Qnil
));
8461 if (NILP (Voverriding_local_map_menu_flag
))
8463 specbind (Qoverriding_terminal_local_map
, Qnil
);
8464 specbind (Qoverriding_local_map
, Qnil
);
8467 /* Run the Lucid hook. */
8468 safe_run_hooks (Qactivate_menubar_hook
);
8470 /* If it has changed current-menubar from previous value,
8471 really recompute the menu-bar from the value. */
8472 if (! NILP (Vlucid_menu_bar_dirty_flag
))
8473 call0 (Qrecompute_lucid_menubar
);
8475 safe_run_hooks (Qmenu_bar_update_hook
);
8476 FRAME_MENU_BAR_ITEMS (f
) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f
));
8478 /* Redisplay the menu bar in case we changed it. */
8479 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8480 || defined (USE_GTK)
8481 if (FRAME_WINDOW_P (f
)
8482 #if defined (MAC_OS)
8483 /* All frames on Mac OS share the same menubar. So only the
8484 selected frame should be allowed to set it. */
8485 && f
== SELECTED_FRAME ()
8488 set_frame_menubar (f
, 0, 0);
8490 /* On a terminal screen, the menu bar is an ordinary screen
8491 line, and this makes it get updated. */
8492 w
->update_mode_line
= Qt
;
8493 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8494 /* In the non-toolkit version, the menu bar is an ordinary screen
8495 line, and this makes it get updated. */
8496 w
->update_mode_line
= Qt
;
8497 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8499 unbind_to (count
, Qnil
);
8500 set_buffer_internal_1 (prev
);
8507 /***********************************************************************
8509 ***********************************************************************/
8511 #ifdef HAVE_WINDOW_SYSTEM
8514 Nominal cursor position -- where to draw output.
8515 HPOS and VPOS are window relative glyph matrix coordinates.
8516 X and Y are window relative pixel coordinates. */
8518 struct cursor_pos output_cursor
;
8522 Set the global variable output_cursor to CURSOR. All cursor
8523 positions are relative to updated_window. */
8526 set_output_cursor (cursor
)
8527 struct cursor_pos
*cursor
;
8529 output_cursor
.hpos
= cursor
->hpos
;
8530 output_cursor
.vpos
= cursor
->vpos
;
8531 output_cursor
.x
= cursor
->x
;
8532 output_cursor
.y
= cursor
->y
;
8537 Set a nominal cursor position.
8539 HPOS and VPOS are column/row positions in a window glyph matrix. X
8540 and Y are window text area relative pixel positions.
8542 If this is done during an update, updated_window will contain the
8543 window that is being updated and the position is the future output
8544 cursor position for that window. If updated_window is null, use
8545 selected_window and display the cursor at the given position. */
8548 x_cursor_to (vpos
, hpos
, y
, x
)
8549 int vpos
, hpos
, y
, x
;
8553 /* If updated_window is not set, work on selected_window. */
8557 w
= XWINDOW (selected_window
);
8559 /* Set the output cursor. */
8560 output_cursor
.hpos
= hpos
;
8561 output_cursor
.vpos
= vpos
;
8562 output_cursor
.x
= x
;
8563 output_cursor
.y
= y
;
8565 /* If not called as part of an update, really display the cursor.
8566 This will also set the cursor position of W. */
8567 if (updated_window
== NULL
)
8570 display_and_set_cursor (w
, 1, hpos
, vpos
, x
, y
);
8571 if (rif
->flush_display_optional
)
8572 rif
->flush_display_optional (SELECTED_FRAME ());
8577 #endif /* HAVE_WINDOW_SYSTEM */
8580 /***********************************************************************
8582 ***********************************************************************/
8584 #ifdef HAVE_WINDOW_SYSTEM
8586 /* Where the mouse was last time we reported a mouse event. */
8588 FRAME_PTR last_mouse_frame
;
8590 /* Tool-bar item index of the item on which a mouse button was pressed
8593 int last_tool_bar_item
;
8596 /* Update the tool-bar item list for frame F. This has to be done
8597 before we start to fill in any display lines. Called from
8598 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
8599 and restore it here. */
8602 update_tool_bar (f
, save_match_data
)
8604 int save_match_data
;
8607 int do_update
= FRAME_EXTERNAL_TOOL_BAR (f
);
8609 int do_update
= WINDOWP (f
->tool_bar_window
)
8610 && WINDOW_TOTAL_LINES (XWINDOW (f
->tool_bar_window
)) > 0;
8618 window
= FRAME_SELECTED_WINDOW (f
);
8619 w
= XWINDOW (window
);
8621 /* If the user has switched buffers or windows, we need to
8622 recompute to reflect the new bindings. But we'll
8623 recompute when update_mode_lines is set too; that means
8624 that people can use force-mode-line-update to request
8625 that the menu bar be recomputed. The adverse effect on
8626 the rest of the redisplay algorithm is about the same as
8627 windows_or_buffers_changed anyway. */
8628 if (windows_or_buffers_changed
8629 || !NILP (w
->update_mode_line
)
8630 || update_mode_lines
8631 || ((BUF_SAVE_MODIFF (XBUFFER (w
->buffer
))
8632 < BUF_MODIFF (XBUFFER (w
->buffer
)))
8633 != !NILP (w
->last_had_star
))
8634 || ((!NILP (Vtransient_mark_mode
)
8635 && !NILP (XBUFFER (w
->buffer
)->mark_active
))
8636 != !NILP (w
->region_showing
)))
8638 struct buffer
*prev
= current_buffer
;
8639 int count
= SPECPDL_INDEX ();
8640 Lisp_Object new_tool_bar
;
8642 struct gcpro gcpro1
;
8644 /* Set current_buffer to the buffer of the selected
8645 window of the frame, so that we get the right local
8647 set_buffer_internal_1 (XBUFFER (w
->buffer
));
8649 /* Save match data, if we must. */
8650 if (save_match_data
)
8651 record_unwind_protect (Fset_match_data
, Fmatch_data (Qnil
, Qnil
));
8653 /* Make sure that we don't accidentally use bogus keymaps. */
8654 if (NILP (Voverriding_local_map_menu_flag
))
8656 specbind (Qoverriding_terminal_local_map
, Qnil
);
8657 specbind (Qoverriding_local_map
, Qnil
);
8660 GCPRO1 (new_tool_bar
);
8662 /* Build desired tool-bar items from keymaps. */
8663 new_tool_bar
= tool_bar_items (Fcopy_sequence (f
->tool_bar_items
),
8666 /* Redisplay the tool-bar if we changed it. */
8667 if (NILP (Fequal (new_tool_bar
, f
->tool_bar_items
)))
8669 /* Redisplay that happens asynchronously due to an expose event
8670 may access f->tool_bar_items. Make sure we update both
8671 variables within BLOCK_INPUT so no such event interrupts. */
8673 f
->tool_bar_items
= new_tool_bar
;
8674 f
->n_tool_bar_items
= new_n_tool_bar
;
8675 w
->update_mode_line
= Qt
;
8681 unbind_to (count
, Qnil
);
8682 set_buffer_internal_1 (prev
);
8688 /* Set F->desired_tool_bar_string to a Lisp string representing frame
8689 F's desired tool-bar contents. F->tool_bar_items must have
8690 been set up previously by calling prepare_menu_bars. */
8693 build_desired_tool_bar_string (f
)
8696 int i
, size
, size_needed
;
8697 struct gcpro gcpro1
, gcpro2
, gcpro3
;
8698 Lisp_Object image
, plist
, props
;
8700 image
= plist
= props
= Qnil
;
8701 GCPRO3 (image
, plist
, props
);
8703 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
8704 Otherwise, make a new string. */
8706 /* The size of the string we might be able to reuse. */
8707 size
= (STRINGP (f
->desired_tool_bar_string
)
8708 ? SCHARS (f
->desired_tool_bar_string
)
8711 /* We need one space in the string for each image. */
8712 size_needed
= f
->n_tool_bar_items
;
8714 /* Reuse f->desired_tool_bar_string, if possible. */
8715 if (size
< size_needed
|| NILP (f
->desired_tool_bar_string
))
8716 f
->desired_tool_bar_string
= Fmake_string (make_number (size_needed
),
8720 props
= list4 (Qdisplay
, Qnil
, Qmenu_item
, Qnil
);
8721 Fremove_text_properties (make_number (0), make_number (size
),
8722 props
, f
->desired_tool_bar_string
);
8725 /* Put a `display' property on the string for the images to display,
8726 put a `menu_item' property on tool-bar items with a value that
8727 is the index of the item in F's tool-bar item vector. */
8728 for (i
= 0; i
< f
->n_tool_bar_items
; ++i
)
8730 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
8732 int enabled_p
= !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P
));
8733 int selected_p
= !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P
));
8734 int hmargin
, vmargin
, relief
, idx
, end
;
8735 extern Lisp_Object QCrelief
, QCmargin
, QCconversion
;
8737 /* If image is a vector, choose the image according to the
8739 image
= PROP (TOOL_BAR_ITEM_IMAGES
);
8740 if (VECTORP (image
))
8744 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
8745 : TOOL_BAR_IMAGE_ENABLED_DESELECTED
);
8748 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
8749 : TOOL_BAR_IMAGE_DISABLED_DESELECTED
);
8751 xassert (ASIZE (image
) >= idx
);
8752 image
= AREF (image
, idx
);
8757 /* Ignore invalid image specifications. */
8758 if (!valid_image_p (image
))
8761 /* Display the tool-bar button pressed, or depressed. */
8762 plist
= Fcopy_sequence (XCDR (image
));
8764 /* Compute margin and relief to draw. */
8765 relief
= (tool_bar_button_relief
>= 0
8766 ? tool_bar_button_relief
8767 : DEFAULT_TOOL_BAR_BUTTON_RELIEF
);
8768 hmargin
= vmargin
= relief
;
8770 if (INTEGERP (Vtool_bar_button_margin
)
8771 && XINT (Vtool_bar_button_margin
) > 0)
8773 hmargin
+= XFASTINT (Vtool_bar_button_margin
);
8774 vmargin
+= XFASTINT (Vtool_bar_button_margin
);
8776 else if (CONSP (Vtool_bar_button_margin
))
8778 if (INTEGERP (XCAR (Vtool_bar_button_margin
))
8779 && XINT (XCAR (Vtool_bar_button_margin
)) > 0)
8780 hmargin
+= XFASTINT (XCAR (Vtool_bar_button_margin
));
8782 if (INTEGERP (XCDR (Vtool_bar_button_margin
))
8783 && XINT (XCDR (Vtool_bar_button_margin
)) > 0)
8784 vmargin
+= XFASTINT (XCDR (Vtool_bar_button_margin
));
8787 if (auto_raise_tool_bar_buttons_p
)
8789 /* Add a `:relief' property to the image spec if the item is
8793 plist
= Fplist_put (plist
, QCrelief
, make_number (-relief
));
8800 /* If image is selected, display it pressed, i.e. with a
8801 negative relief. If it's not selected, display it with a
8803 plist
= Fplist_put (plist
, QCrelief
,
8805 ? make_number (-relief
)
8806 : make_number (relief
)));
8811 /* Put a margin around the image. */
8812 if (hmargin
|| vmargin
)
8814 if (hmargin
== vmargin
)
8815 plist
= Fplist_put (plist
, QCmargin
, make_number (hmargin
));
8817 plist
= Fplist_put (plist
, QCmargin
,
8818 Fcons (make_number (hmargin
),
8819 make_number (vmargin
)));
8822 /* If button is not enabled, and we don't have special images
8823 for the disabled state, make the image appear disabled by
8824 applying an appropriate algorithm to it. */
8825 if (!enabled_p
&& idx
< 0)
8826 plist
= Fplist_put (plist
, QCconversion
, Qdisabled
);
8828 /* Put a `display' text property on the string for the image to
8829 display. Put a `menu-item' property on the string that gives
8830 the start of this item's properties in the tool-bar items
8832 image
= Fcons (Qimage
, plist
);
8833 props
= list4 (Qdisplay
, image
,
8834 Qmenu_item
, make_number (i
* TOOL_BAR_ITEM_NSLOTS
));
8836 /* Let the last image hide all remaining spaces in the tool bar
8837 string. The string can be longer than needed when we reuse a
8839 if (i
+ 1 == f
->n_tool_bar_items
)
8840 end
= SCHARS (f
->desired_tool_bar_string
);
8843 Fadd_text_properties (make_number (i
), make_number (end
),
8844 props
, f
->desired_tool_bar_string
);
8852 /* Display one line of the tool-bar of frame IT->f. */
8855 display_tool_bar_line (it
)
8858 struct glyph_row
*row
= it
->glyph_row
;
8859 int max_x
= it
->last_visible_x
;
8862 prepare_desired_row (row
);
8863 row
->y
= it
->current_y
;
8865 /* Note that this isn't made use of if the face hasn't a box,
8866 so there's no need to check the face here. */
8867 it
->start_of_box_run_p
= 1;
8869 while (it
->current_x
< max_x
)
8871 int x_before
, x
, n_glyphs_before
, i
, nglyphs
;
8873 /* Get the next display element. */
8874 if (!get_next_display_element (it
))
8877 /* Produce glyphs. */
8878 x_before
= it
->current_x
;
8879 n_glyphs_before
= it
->glyph_row
->used
[TEXT_AREA
];
8880 PRODUCE_GLYPHS (it
);
8882 nglyphs
= it
->glyph_row
->used
[TEXT_AREA
] - n_glyphs_before
;
8887 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
8889 if (x
+ glyph
->pixel_width
> max_x
)
8891 /* Glyph doesn't fit on line. */
8892 it
->glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
+ i
;
8898 x
+= glyph
->pixel_width
;
8902 /* Stop at line ends. */
8903 if (ITERATOR_AT_END_OF_LINE_P (it
))
8906 set_iterator_to_next (it
, 1);
8911 row
->displays_text_p
= row
->used
[TEXT_AREA
] != 0;
8912 extend_face_to_end_of_line (it
);
8913 last
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
] - 1;
8914 last
->right_box_line_p
= 1;
8915 if (last
== row
->glyphs
[TEXT_AREA
])
8916 last
->left_box_line_p
= 1;
8917 compute_line_metrics (it
);
8919 /* If line is empty, make it occupy the rest of the tool-bar. */
8920 if (!row
->displays_text_p
)
8922 row
->height
= row
->phys_height
= it
->last_visible_y
- row
->y
;
8923 row
->ascent
= row
->phys_ascent
= 0;
8924 row
->extra_line_spacing
= 0;
8927 row
->full_width_p
= 1;
8928 row
->continued_p
= 0;
8929 row
->truncated_on_left_p
= 0;
8930 row
->truncated_on_right_p
= 0;
8932 it
->current_x
= it
->hpos
= 0;
8933 it
->current_y
+= row
->height
;
8939 /* Value is the number of screen lines needed to make all tool-bar
8940 items of frame F visible. */
8943 tool_bar_lines_needed (f
)
8946 struct window
*w
= XWINDOW (f
->tool_bar_window
);
8949 /* Initialize an iterator for iteration over
8950 F->desired_tool_bar_string in the tool-bar window of frame F. */
8951 init_iterator (&it
, w
, -1, -1, w
->desired_matrix
->rows
, TOOL_BAR_FACE_ID
);
8952 it
.first_visible_x
= 0;
8953 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
8954 reseat_to_string (&it
, NULL
, f
->desired_tool_bar_string
, 0, 0, 0, -1);
8956 while (!ITERATOR_AT_END_P (&it
))
8958 it
.glyph_row
= w
->desired_matrix
->rows
;
8959 clear_glyph_row (it
.glyph_row
);
8960 display_tool_bar_line (&it
);
8963 return (it
.current_y
+ FRAME_LINE_HEIGHT (f
) - 1) / FRAME_LINE_HEIGHT (f
);
8967 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed
, Stool_bar_lines_needed
,
8969 doc
: /* Return the number of lines occupied by the tool bar of FRAME. */)
8978 frame
= selected_frame
;
8980 CHECK_FRAME (frame
);
8983 if (WINDOWP (f
->tool_bar_window
)
8984 || (w
= XWINDOW (f
->tool_bar_window
),
8985 WINDOW_TOTAL_LINES (w
) > 0))
8987 update_tool_bar (f
, 1);
8988 if (f
->n_tool_bar_items
)
8990 build_desired_tool_bar_string (f
);
8991 nlines
= tool_bar_lines_needed (f
);
8995 return make_number (nlines
);
8999 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
9000 height should be changed. */
9003 redisplay_tool_bar (f
)
9008 struct glyph_row
*row
;
9009 int change_height_p
= 0;
9012 if (FRAME_EXTERNAL_TOOL_BAR (f
))
9013 update_frame_tool_bar (f
);
9017 /* If frame hasn't a tool-bar window or if it is zero-height, don't
9018 do anything. This means you must start with tool-bar-lines
9019 non-zero to get the auto-sizing effect. Or in other words, you
9020 can turn off tool-bars by specifying tool-bar-lines zero. */
9021 if (!WINDOWP (f
->tool_bar_window
)
9022 || (w
= XWINDOW (f
->tool_bar_window
),
9023 WINDOW_TOTAL_LINES (w
) == 0))
9026 /* Set up an iterator for the tool-bar window. */
9027 init_iterator (&it
, w
, -1, -1, w
->desired_matrix
->rows
, TOOL_BAR_FACE_ID
);
9028 it
.first_visible_x
= 0;
9029 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
9032 /* Build a string that represents the contents of the tool-bar. */
9033 build_desired_tool_bar_string (f
);
9034 reseat_to_string (&it
, NULL
, f
->desired_tool_bar_string
, 0, 0, 0, -1);
9036 /* Display as many lines as needed to display all tool-bar items. */
9037 while (it
.current_y
< it
.last_visible_y
)
9038 display_tool_bar_line (&it
);
9040 /* It doesn't make much sense to try scrolling in the tool-bar
9041 window, so don't do it. */
9042 w
->desired_matrix
->no_scrolling_p
= 1;
9043 w
->must_be_updated_p
= 1;
9045 if (auto_resize_tool_bars_p
)
9049 /* If we couldn't display everything, change the tool-bar's
9051 if (IT_STRING_CHARPOS (it
) < it
.end_charpos
)
9052 change_height_p
= 1;
9054 /* If there are blank lines at the end, except for a partially
9055 visible blank line at the end that is smaller than
9056 FRAME_LINE_HEIGHT, change the tool-bar's height. */
9057 row
= it
.glyph_row
- 1;
9058 if (!row
->displays_text_p
9059 && row
->height
>= FRAME_LINE_HEIGHT (f
))
9060 change_height_p
= 1;
9062 /* If row displays tool-bar items, but is partially visible,
9063 change the tool-bar's height. */
9064 if (row
->displays_text_p
9065 && MATRIX_ROW_BOTTOM_Y (row
) > it
.last_visible_y
)
9066 change_height_p
= 1;
9068 /* Resize windows as needed by changing the `tool-bar-lines'
9071 && (nlines
= tool_bar_lines_needed (f
),
9072 nlines
!= WINDOW_TOTAL_LINES (w
)))
9074 extern Lisp_Object Qtool_bar_lines
;
9076 int old_height
= WINDOW_TOTAL_LINES (w
);
9078 XSETFRAME (frame
, f
);
9079 clear_glyph_matrix (w
->desired_matrix
);
9080 Fmodify_frame_parameters (frame
,
9081 Fcons (Fcons (Qtool_bar_lines
,
9082 make_number (nlines
)),
9084 if (WINDOW_TOTAL_LINES (w
) != old_height
)
9085 fonts_changed_p
= 1;
9089 return change_height_p
;
9093 /* Get information about the tool-bar item which is displayed in GLYPH
9094 on frame F. Return in *PROP_IDX the index where tool-bar item
9095 properties start in F->tool_bar_items. Value is zero if
9096 GLYPH doesn't display a tool-bar item. */
9099 tool_bar_item_info (f
, glyph
, prop_idx
)
9101 struct glyph
*glyph
;
9108 /* This function can be called asynchronously, which means we must
9109 exclude any possibility that Fget_text_property signals an
9111 charpos
= min (SCHARS (f
->current_tool_bar_string
), glyph
->charpos
);
9112 charpos
= max (0, charpos
);
9114 /* Get the text property `menu-item' at pos. The value of that
9115 property is the start index of this item's properties in
9116 F->tool_bar_items. */
9117 prop
= Fget_text_property (make_number (charpos
),
9118 Qmenu_item
, f
->current_tool_bar_string
);
9119 if (INTEGERP (prop
))
9121 *prop_idx
= XINT (prop
);
9131 /* Get information about the tool-bar item at position X/Y on frame F.
9132 Return in *GLYPH a pointer to the glyph of the tool-bar item in
9133 the current matrix of the tool-bar window of F, or NULL if not
9134 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
9135 item in F->tool_bar_items. Value is
9137 -1 if X/Y is not on a tool-bar item
9138 0 if X/Y is on the same item that was highlighted before.
9142 get_tool_bar_item (f
, x
, y
, glyph
, hpos
, vpos
, prop_idx
)
9145 struct glyph
**glyph
;
9146 int *hpos
, *vpos
, *prop_idx
;
9148 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
9149 struct window
*w
= XWINDOW (f
->tool_bar_window
);
9152 /* Find the glyph under X/Y. */
9153 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, 0, 0, &area
);
9157 /* Get the start of this tool-bar item's properties in
9158 f->tool_bar_items. */
9159 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
9162 /* Is mouse on the highlighted item? */
9163 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
9164 && *vpos
>= dpyinfo
->mouse_face_beg_row
9165 && *vpos
<= dpyinfo
->mouse_face_end_row
9166 && (*vpos
> dpyinfo
->mouse_face_beg_row
9167 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
9168 && (*vpos
< dpyinfo
->mouse_face_end_row
9169 || *hpos
< dpyinfo
->mouse_face_end_col
9170 || dpyinfo
->mouse_face_past_end
))
9178 Handle mouse button event on the tool-bar of frame F, at
9179 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
9180 0 for button release. MODIFIERS is event modifiers for button
9184 handle_tool_bar_click (f
, x
, y
, down_p
, modifiers
)
9187 unsigned int modifiers
;
9189 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
9190 struct window
*w
= XWINDOW (f
->tool_bar_window
);
9191 int hpos
, vpos
, prop_idx
;
9192 struct glyph
*glyph
;
9193 Lisp_Object enabled_p
;
9195 /* If not on the highlighted tool-bar item, return. */
9196 frame_to_window_pixel_xy (w
, &x
, &y
);
9197 if (get_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
9200 /* If item is disabled, do nothing. */
9201 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
9202 if (NILP (enabled_p
))
9207 /* Show item in pressed state. */
9208 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
9209 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
9210 last_tool_bar_item
= prop_idx
;
9214 Lisp_Object key
, frame
;
9215 struct input_event event
;
9218 /* Show item in released state. */
9219 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
9220 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
9222 key
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_KEY
);
9224 XSETFRAME (frame
, f
);
9225 event
.kind
= TOOL_BAR_EVENT
;
9226 event
.frame_or_window
= frame
;
9228 kbd_buffer_store_event (&event
);
9230 event
.kind
= TOOL_BAR_EVENT
;
9231 event
.frame_or_window
= frame
;
9233 event
.modifiers
= modifiers
;
9234 kbd_buffer_store_event (&event
);
9235 last_tool_bar_item
= -1;
9240 /* Possibly highlight a tool-bar item on frame F when mouse moves to
9241 tool-bar window-relative coordinates X/Y. Called from
9242 note_mouse_highlight. */
9245 note_tool_bar_highlight (f
, x
, y
)
9249 Lisp_Object window
= f
->tool_bar_window
;
9250 struct window
*w
= XWINDOW (window
);
9251 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
9253 struct glyph
*glyph
;
9254 struct glyph_row
*row
;
9256 Lisp_Object enabled_p
;
9258 enum draw_glyphs_face draw
= DRAW_IMAGE_RAISED
;
9259 int mouse_down_p
, rc
;
9261 /* Function note_mouse_highlight is called with negative x(y
9262 values when mouse moves outside of the frame. */
9263 if (x
<= 0 || y
<= 0)
9265 clear_mouse_face (dpyinfo
);
9269 rc
= get_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
9272 /* Not on tool-bar item. */
9273 clear_mouse_face (dpyinfo
);
9277 /* On same tool-bar item as before. */
9280 clear_mouse_face (dpyinfo
);
9282 /* Mouse is down, but on different tool-bar item? */
9283 mouse_down_p
= (dpyinfo
->grabbed
9284 && f
== last_mouse_frame
9285 && FRAME_LIVE_P (f
));
9287 && last_tool_bar_item
!= prop_idx
)
9290 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
9291 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
9293 /* If tool-bar item is not enabled, don't highlight it. */
9294 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
9295 if (!NILP (enabled_p
))
9297 /* Compute the x-position of the glyph. In front and past the
9298 image is a space. We include this in the highlighted area. */
9299 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
9300 for (i
= x
= 0; i
< hpos
; ++i
)
9301 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
9303 /* Record this as the current active region. */
9304 dpyinfo
->mouse_face_beg_col
= hpos
;
9305 dpyinfo
->mouse_face_beg_row
= vpos
;
9306 dpyinfo
->mouse_face_beg_x
= x
;
9307 dpyinfo
->mouse_face_beg_y
= row
->y
;
9308 dpyinfo
->mouse_face_past_end
= 0;
9310 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
9311 dpyinfo
->mouse_face_end_row
= vpos
;
9312 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
9313 dpyinfo
->mouse_face_end_y
= row
->y
;
9314 dpyinfo
->mouse_face_window
= window
;
9315 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
9317 /* Display it as active. */
9318 show_mouse_face (dpyinfo
, draw
);
9319 dpyinfo
->mouse_face_image_state
= draw
;
9324 /* Set help_echo_string to a help string to display for this tool-bar item.
9325 XTread_socket does the rest. */
9326 help_echo_object
= help_echo_window
= Qnil
;
9328 help_echo_string
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_HELP
);
9329 if (NILP (help_echo_string
))
9330 help_echo_string
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_CAPTION
);
9333 #endif /* HAVE_WINDOW_SYSTEM */
9337 /************************************************************************
9338 Horizontal scrolling
9339 ************************************************************************/
9341 static int hscroll_window_tree
P_ ((Lisp_Object
));
9342 static int hscroll_windows
P_ ((Lisp_Object
));
9344 /* For all leaf windows in the window tree rooted at WINDOW, set their
9345 hscroll value so that PT is (i) visible in the window, and (ii) so
9346 that it is not within a certain margin at the window's left and
9347 right border. Value is non-zero if any window's hscroll has been
9351 hscroll_window_tree (window
)
9354 int hscrolled_p
= 0;
9355 int hscroll_relative_p
= FLOATP (Vhscroll_step
);
9356 int hscroll_step_abs
= 0;
9357 double hscroll_step_rel
= 0;
9359 if (hscroll_relative_p
)
9361 hscroll_step_rel
= XFLOAT_DATA (Vhscroll_step
);
9362 if (hscroll_step_rel
< 0)
9364 hscroll_relative_p
= 0;
9365 hscroll_step_abs
= 0;
9368 else if (INTEGERP (Vhscroll_step
))
9370 hscroll_step_abs
= XINT (Vhscroll_step
);
9371 if (hscroll_step_abs
< 0)
9372 hscroll_step_abs
= 0;
9375 hscroll_step_abs
= 0;
9377 while (WINDOWP (window
))
9379 struct window
*w
= XWINDOW (window
);
9381 if (WINDOWP (w
->hchild
))
9382 hscrolled_p
|= hscroll_window_tree (w
->hchild
);
9383 else if (WINDOWP (w
->vchild
))
9384 hscrolled_p
|= hscroll_window_tree (w
->vchild
);
9385 else if (w
->cursor
.vpos
>= 0)
9388 int text_area_width
;
9389 struct glyph_row
*current_cursor_row
9390 = MATRIX_ROW (w
->current_matrix
, w
->cursor
.vpos
);
9391 struct glyph_row
*desired_cursor_row
9392 = MATRIX_ROW (w
->desired_matrix
, w
->cursor
.vpos
);
9393 struct glyph_row
*cursor_row
9394 = (desired_cursor_row
->enabled_p
9395 ? desired_cursor_row
9396 : current_cursor_row
);
9398 text_area_width
= window_box_width (w
, TEXT_AREA
);
9400 /* Scroll when cursor is inside this scroll margin. */
9401 h_margin
= hscroll_margin
* WINDOW_FRAME_COLUMN_WIDTH (w
);
9403 if ((XFASTINT (w
->hscroll
)
9404 && w
->cursor
.x
<= h_margin
)
9405 || (cursor_row
->enabled_p
9406 && cursor_row
->truncated_on_right_p
9407 && (w
->cursor
.x
>= text_area_width
- h_margin
)))
9411 struct buffer
*saved_current_buffer
;
9415 /* Find point in a display of infinite width. */
9416 saved_current_buffer
= current_buffer
;
9417 current_buffer
= XBUFFER (w
->buffer
);
9419 if (w
== XWINDOW (selected_window
))
9420 pt
= BUF_PT (current_buffer
);
9423 pt
= marker_position (w
->pointm
);
9424 pt
= max (BEGV
, pt
);
9428 /* Move iterator to pt starting at cursor_row->start in
9429 a line with infinite width. */
9430 init_to_row_start (&it
, w
, cursor_row
);
9431 it
.last_visible_x
= INFINITY
;
9432 move_it_in_display_line_to (&it
, pt
, -1, MOVE_TO_POS
);
9433 current_buffer
= saved_current_buffer
;
9435 /* Position cursor in window. */
9436 if (!hscroll_relative_p
&& hscroll_step_abs
== 0)
9437 hscroll
= max (0, (it
.current_x
9438 - (ITERATOR_AT_END_OF_LINE_P (&it
)
9439 ? (text_area_width
- 4 * FRAME_COLUMN_WIDTH (it
.f
))
9440 : (text_area_width
/ 2))))
9441 / FRAME_COLUMN_WIDTH (it
.f
);
9442 else if (w
->cursor
.x
>= text_area_width
- h_margin
)
9444 if (hscroll_relative_p
)
9445 wanted_x
= text_area_width
* (1 - hscroll_step_rel
)
9448 wanted_x
= text_area_width
9449 - hscroll_step_abs
* FRAME_COLUMN_WIDTH (it
.f
)
9452 = max (0, it
.current_x
- wanted_x
) / FRAME_COLUMN_WIDTH (it
.f
);
9456 if (hscroll_relative_p
)
9457 wanted_x
= text_area_width
* hscroll_step_rel
9460 wanted_x
= hscroll_step_abs
* FRAME_COLUMN_WIDTH (it
.f
)
9463 = max (0, it
.current_x
- wanted_x
) / FRAME_COLUMN_WIDTH (it
.f
);
9465 hscroll
= max (hscroll
, XFASTINT (w
->min_hscroll
));
9467 /* Don't call Fset_window_hscroll if value hasn't
9468 changed because it will prevent redisplay
9470 if (XFASTINT (w
->hscroll
) != hscroll
)
9472 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
9473 w
->hscroll
= make_number (hscroll
);
9482 /* Value is non-zero if hscroll of any leaf window has been changed. */
9487 /* Set hscroll so that cursor is visible and not inside horizontal
9488 scroll margins for all windows in the tree rooted at WINDOW. See
9489 also hscroll_window_tree above. Value is non-zero if any window's
9490 hscroll has been changed. If it has, desired matrices on the frame
9491 of WINDOW are cleared. */
9494 hscroll_windows (window
)
9499 if (automatic_hscrolling_p
)
9501 hscrolled_p
= hscroll_window_tree (window
);
9503 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window
))));
9512 /************************************************************************
9514 ************************************************************************/
9516 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
9517 to a non-zero value. This is sometimes handy to have in a debugger
9522 /* First and last unchanged row for try_window_id. */
9524 int debug_first_unchanged_at_end_vpos
;
9525 int debug_last_unchanged_at_beg_vpos
;
9527 /* Delta vpos and y. */
9529 int debug_dvpos
, debug_dy
;
9531 /* Delta in characters and bytes for try_window_id. */
9533 int debug_delta
, debug_delta_bytes
;
9535 /* Values of window_end_pos and window_end_vpos at the end of
9538 EMACS_INT debug_end_pos
, debug_end_vpos
;
9540 /* Append a string to W->desired_matrix->method. FMT is a printf
9541 format string. A1...A9 are a supplement for a variable-length
9542 argument list. If trace_redisplay_p is non-zero also printf the
9543 resulting string to stderr. */
9546 debug_method_add (w
, fmt
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
)
9549 int a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
;
9552 char *method
= w
->desired_matrix
->method
;
9553 int len
= strlen (method
);
9554 int size
= sizeof w
->desired_matrix
->method
;
9555 int remaining
= size
- len
- 1;
9557 sprintf (buffer
, fmt
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
);
9558 if (len
&& remaining
)
9564 strncpy (method
+ len
, buffer
, remaining
);
9566 if (trace_redisplay_p
)
9567 fprintf (stderr
, "%p (%s): %s\n",
9569 ((BUFFERP (w
->buffer
)
9570 && STRINGP (XBUFFER (w
->buffer
)->name
))
9571 ? (char *) SDATA (XBUFFER (w
->buffer
)->name
)
9576 #endif /* GLYPH_DEBUG */
9579 /* Value is non-zero if all changes in window W, which displays
9580 current_buffer, are in the text between START and END. START is a
9581 buffer position, END is given as a distance from Z. Used in
9582 redisplay_internal for display optimization. */
9585 text_outside_line_unchanged_p (w
, start
, end
)
9589 int unchanged_p
= 1;
9591 /* If text or overlays have changed, see where. */
9592 if (XFASTINT (w
->last_modified
) < MODIFF
9593 || XFASTINT (w
->last_overlay_modified
) < OVERLAY_MODIFF
)
9595 /* Gap in the line? */
9596 if (GPT
< start
|| Z
- GPT
< end
)
9599 /* Changes start in front of the line, or end after it? */
9601 && (BEG_UNCHANGED
< start
- 1
9602 || END_UNCHANGED
< end
))
9605 /* If selective display, can't optimize if changes start at the
9606 beginning of the line. */
9608 && INTEGERP (current_buffer
->selective_display
)
9609 && XINT (current_buffer
->selective_display
) > 0
9610 && (BEG_UNCHANGED
< start
|| GPT
<= start
))
9613 /* If there are overlays at the start or end of the line, these
9614 may have overlay strings with newlines in them. A change at
9615 START, for instance, may actually concern the display of such
9616 overlay strings as well, and they are displayed on different
9617 lines. So, quickly rule out this case. (For the future, it
9618 might be desirable to implement something more telling than
9619 just BEG/END_UNCHANGED.) */
9622 if (BEG
+ BEG_UNCHANGED
== start
9623 && overlay_touches_p (start
))
9625 if (END_UNCHANGED
== end
9626 && overlay_touches_p (Z
- end
))
9635 /* Do a frame update, taking possible shortcuts into account. This is
9636 the main external entry point for redisplay.
9638 If the last redisplay displayed an echo area message and that message
9639 is no longer requested, we clear the echo area or bring back the
9640 mini-buffer if that is in use. */
9645 redisplay_internal (0);
9650 overlay_arrow_string_or_property (var
, pbitmap
)
9654 Lisp_Object pstr
= Fget (var
, Qoverlay_arrow_string
);
9660 if (bitmap
= Fget (var
, Qoverlay_arrow_bitmap
), INTEGERP (bitmap
))
9661 *pbitmap
= XINT (bitmap
);
9666 return Voverlay_arrow_string
;
9669 /* Return 1 if there are any overlay-arrows in current_buffer. */
9671 overlay_arrow_in_current_buffer_p ()
9675 for (vlist
= Voverlay_arrow_variable_list
;
9677 vlist
= XCDR (vlist
))
9679 Lisp_Object var
= XCAR (vlist
);
9684 val
= find_symbol_value (var
);
9686 && current_buffer
== XMARKER (val
)->buffer
)
9693 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
9697 overlay_arrows_changed_p ()
9701 for (vlist
= Voverlay_arrow_variable_list
;
9703 vlist
= XCDR (vlist
))
9705 Lisp_Object var
= XCAR (vlist
);
9706 Lisp_Object val
, pstr
;
9710 val
= find_symbol_value (var
);
9713 if (! EQ (COERCE_MARKER (val
),
9714 Fget (var
, Qlast_arrow_position
))
9715 || ! (pstr
= overlay_arrow_string_or_property (var
, 0),
9716 EQ (pstr
, Fget (var
, Qlast_arrow_string
))))
9722 /* Mark overlay arrows to be updated on next redisplay. */
9725 update_overlay_arrows (up_to_date
)
9730 for (vlist
= Voverlay_arrow_variable_list
;
9732 vlist
= XCDR (vlist
))
9734 Lisp_Object var
= XCAR (vlist
);
9741 Lisp_Object val
= find_symbol_value (var
);
9742 Fput (var
, Qlast_arrow_position
,
9743 COERCE_MARKER (val
));
9744 Fput (var
, Qlast_arrow_string
,
9745 overlay_arrow_string_or_property (var
, 0));
9747 else if (up_to_date
< 0
9748 || !NILP (Fget (var
, Qlast_arrow_position
)))
9750 Fput (var
, Qlast_arrow_position
, Qt
);
9751 Fput (var
, Qlast_arrow_string
, Qt
);
9757 /* Return overlay arrow string to display at row.
9758 Return t if display as bitmap in left fringe.
9759 Return nil if no overlay arrow. */
9762 overlay_arrow_at_row (it
, row
, pbitmap
)
9764 struct glyph_row
*row
;
9769 for (vlist
= Voverlay_arrow_variable_list
;
9771 vlist
= XCDR (vlist
))
9773 Lisp_Object var
= XCAR (vlist
);
9779 val
= find_symbol_value (var
);
9782 && current_buffer
== XMARKER (val
)->buffer
9783 && (MATRIX_ROW_START_CHARPOS (row
) == marker_position (val
)))
9785 val
= overlay_arrow_string_or_property (var
, pbitmap
);
9786 if (FRAME_WINDOW_P (it
->f
)
9787 && WINDOW_LEFT_FRINGE_WIDTH (it
->w
) > 0)
9799 /* Return 1 if point moved out of or into a composition. Otherwise
9800 return 0. PREV_BUF and PREV_PT are the last point buffer and
9801 position. BUF and PT are the current point buffer and position. */
9804 check_point_in_composition (prev_buf
, prev_pt
, buf
, pt
)
9805 struct buffer
*prev_buf
, *buf
;
9812 XSETBUFFER (buffer
, buf
);
9813 /* Check a composition at the last point if point moved within the
9815 if (prev_buf
== buf
)
9818 /* Point didn't move. */
9821 if (prev_pt
> BUF_BEGV (buf
) && prev_pt
< BUF_ZV (buf
)
9822 && find_composition (prev_pt
, -1, &start
, &end
, &prop
, buffer
)
9823 && COMPOSITION_VALID_P (start
, end
, prop
)
9824 && start
< prev_pt
&& end
> prev_pt
)
9825 /* The last point was within the composition. Return 1 iff
9826 point moved out of the composition. */
9827 return (pt
<= start
|| pt
>= end
);
9830 /* Check a composition at the current point. */
9831 return (pt
> BUF_BEGV (buf
) && pt
< BUF_ZV (buf
)
9832 && find_composition (pt
, -1, &start
, &end
, &prop
, buffer
)
9833 && COMPOSITION_VALID_P (start
, end
, prop
)
9834 && start
< pt
&& end
> pt
);
9838 /* Reconsider the setting of B->clip_changed which is displayed
9842 reconsider_clip_changes (w
, b
)
9847 && !NILP (w
->window_end_valid
)
9848 && w
->current_matrix
->buffer
== b
9849 && w
->current_matrix
->zv
== BUF_ZV (b
)
9850 && w
->current_matrix
->begv
== BUF_BEGV (b
))
9851 b
->clip_changed
= 0;
9853 /* If display wasn't paused, and W is not a tool bar window, see if
9854 point has been moved into or out of a composition. In that case,
9855 we set b->clip_changed to 1 to force updating the screen. If
9856 b->clip_changed has already been set to 1, we can skip this
9858 if (!b
->clip_changed
9859 && BUFFERP (w
->buffer
) && !NILP (w
->window_end_valid
))
9863 if (w
== XWINDOW (selected_window
))
9864 pt
= BUF_PT (current_buffer
);
9866 pt
= marker_position (w
->pointm
);
9868 if ((w
->current_matrix
->buffer
!= XBUFFER (w
->buffer
)
9869 || pt
!= XINT (w
->last_point
))
9870 && check_point_in_composition (w
->current_matrix
->buffer
,
9871 XINT (w
->last_point
),
9872 XBUFFER (w
->buffer
), pt
))
9873 b
->clip_changed
= 1;
9878 /* Select FRAME to forward the values of frame-local variables into C
9879 variables so that the redisplay routines can access those values
9883 select_frame_for_redisplay (frame
)
9886 Lisp_Object tail
, sym
, val
;
9887 Lisp_Object old
= selected_frame
;
9889 selected_frame
= frame
;
9891 for (tail
= XFRAME (frame
)->param_alist
; CONSP (tail
); tail
= XCDR (tail
))
9892 if (CONSP (XCAR (tail
))
9893 && (sym
= XCAR (XCAR (tail
)),
9895 && (sym
= indirect_variable (sym
),
9896 val
= SYMBOL_VALUE (sym
),
9897 (BUFFER_LOCAL_VALUEP (val
)
9898 || SOME_BUFFER_LOCAL_VALUEP (val
)))
9899 && XBUFFER_LOCAL_VALUE (val
)->check_frame
)
9900 Fsymbol_value (sym
);
9902 for (tail
= XFRAME (old
)->param_alist
; CONSP (tail
); tail
= XCDR (tail
))
9903 if (CONSP (XCAR (tail
))
9904 && (sym
= XCAR (XCAR (tail
)),
9906 && (sym
= indirect_variable (sym
),
9907 val
= SYMBOL_VALUE (sym
),
9908 (BUFFER_LOCAL_VALUEP (val
)
9909 || SOME_BUFFER_LOCAL_VALUEP (val
)))
9910 && XBUFFER_LOCAL_VALUE (val
)->check_frame
)
9911 Fsymbol_value (sym
);
9915 #define STOP_POLLING \
9916 do { if (! polling_stopped_here) stop_polling (); \
9917 polling_stopped_here = 1; } while (0)
9919 #define RESUME_POLLING \
9920 do { if (polling_stopped_here) start_polling (); \
9921 polling_stopped_here = 0; } while (0)
9924 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
9925 response to any user action; therefore, we should preserve the echo
9926 area. (Actually, our caller does that job.) Perhaps in the future
9927 avoid recentering windows if it is not necessary; currently that
9928 causes some problems. */
9931 redisplay_internal (preserve_echo_area
)
9932 int preserve_echo_area
;
9934 struct window
*w
= XWINDOW (selected_window
);
9935 struct frame
*f
= XFRAME (w
->frame
);
9937 int must_finish
= 0;
9938 struct text_pos tlbufpos
, tlendpos
;
9939 int number_of_visible_frames
;
9941 struct frame
*sf
= SELECTED_FRAME ();
9942 int polling_stopped_here
= 0;
9944 /* Non-zero means redisplay has to consider all windows on all
9945 frames. Zero means, only selected_window is considered. */
9946 int consider_all_windows_p
;
9948 TRACE ((stderr
, "redisplay_internal %d\n", redisplaying_p
));
9950 /* No redisplay if running in batch mode or frame is not yet fully
9951 initialized, or redisplay is explicitly turned off by setting
9952 Vinhibit_redisplay. */
9954 || !NILP (Vinhibit_redisplay
)
9955 || !f
->glyphs_initialized_p
)
9958 /* The flag redisplay_performed_directly_p is set by
9959 direct_output_for_insert when it already did the whole screen
9960 update necessary. */
9961 if (redisplay_performed_directly_p
)
9963 redisplay_performed_directly_p
= 0;
9964 if (!hscroll_windows (selected_window
))
9968 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
9969 if (popup_activated ())
9973 /* I don't think this happens but let's be paranoid. */
9977 /* Record a function that resets redisplaying_p to its old value
9978 when we leave this function. */
9979 count
= SPECPDL_INDEX ();
9980 record_unwind_protect (unwind_redisplay
,
9981 Fcons (make_number (redisplaying_p
), selected_frame
));
9983 specbind (Qinhibit_free_realized_faces
, Qnil
);
9987 reconsider_clip_changes (w
, current_buffer
);
9989 /* If new fonts have been loaded that make a glyph matrix adjustment
9990 necessary, do it. */
9991 if (fonts_changed_p
)
9993 adjust_glyphs (NULL
);
9994 ++windows_or_buffers_changed
;
9995 fonts_changed_p
= 0;
9998 /* If face_change_count is non-zero, init_iterator will free all
9999 realized faces, which includes the faces referenced from current
10000 matrices. So, we can't reuse current matrices in this case. */
10001 if (face_change_count
)
10002 ++windows_or_buffers_changed
;
10004 if (! FRAME_WINDOW_P (sf
)
10005 && previous_terminal_frame
!= sf
)
10007 /* Since frames on an ASCII terminal share the same display
10008 area, displaying a different frame means redisplay the whole
10010 windows_or_buffers_changed
++;
10011 SET_FRAME_GARBAGED (sf
);
10012 XSETFRAME (Vterminal_frame
, sf
);
10014 previous_terminal_frame
= sf
;
10016 /* Set the visible flags for all frames. Do this before checking
10017 for resized or garbaged frames; they want to know if their frames
10018 are visible. See the comment in frame.h for
10019 FRAME_SAMPLE_VISIBILITY. */
10021 Lisp_Object tail
, frame
;
10023 number_of_visible_frames
= 0;
10025 FOR_EACH_FRAME (tail
, frame
)
10027 struct frame
*f
= XFRAME (frame
);
10029 FRAME_SAMPLE_VISIBILITY (f
);
10030 if (FRAME_VISIBLE_P (f
))
10031 ++number_of_visible_frames
;
10032 clear_desired_matrices (f
);
10036 /* Notice any pending interrupt request to change frame size. */
10037 do_pending_window_change (1);
10039 /* Clear frames marked as garbaged. */
10040 if (frame_garbaged
)
10041 clear_garbaged_frames ();
10043 /* Build menubar and tool-bar items. */
10044 prepare_menu_bars ();
10046 if (windows_or_buffers_changed
)
10047 update_mode_lines
++;
10049 /* Detect case that we need to write or remove a star in the mode line. */
10050 if ((SAVE_MODIFF
< MODIFF
) != !NILP (w
->last_had_star
))
10052 w
->update_mode_line
= Qt
;
10053 if (buffer_shared
> 1)
10054 update_mode_lines
++;
10057 /* If %c is in the mode line, update it if needed. */
10058 if (!NILP (w
->column_number_displayed
)
10059 /* This alternative quickly identifies a common case
10060 where no change is needed. */
10061 && !(PT
== XFASTINT (w
->last_point
)
10062 && XFASTINT (w
->last_modified
) >= MODIFF
10063 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
)
10064 && (XFASTINT (w
->column_number_displayed
)
10065 != (int) current_column ())) /* iftc */
10066 w
->update_mode_line
= Qt
;
10068 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w
->frame
)) = -1;
10070 /* The variable buffer_shared is set in redisplay_window and
10071 indicates that we redisplay a buffer in different windows. See
10073 consider_all_windows_p
= (update_mode_lines
|| buffer_shared
> 1
10074 || cursor_type_changed
);
10076 /* If specs for an arrow have changed, do thorough redisplay
10077 to ensure we remove any arrow that should no longer exist. */
10078 if (overlay_arrows_changed_p ())
10079 consider_all_windows_p
= windows_or_buffers_changed
= 1;
10081 /* Normally the message* functions will have already displayed and
10082 updated the echo area, but the frame may have been trashed, or
10083 the update may have been preempted, so display the echo area
10084 again here. Checking message_cleared_p captures the case that
10085 the echo area should be cleared. */
10086 if ((!NILP (echo_area_buffer
[0]) && !display_last_displayed_message_p
)
10087 || (!NILP (echo_area_buffer
[1]) && display_last_displayed_message_p
)
10088 || (message_cleared_p
10089 && minibuf_level
== 0
10090 /* If the mini-window is currently selected, this means the
10091 echo-area doesn't show through. */
10092 && !MINI_WINDOW_P (XWINDOW (selected_window
))))
10094 int window_height_changed_p
= echo_area_display (0);
10097 /* If we don't display the current message, don't clear the
10098 message_cleared_p flag, because, if we did, we wouldn't clear
10099 the echo area in the next redisplay which doesn't preserve
10101 if (!display_last_displayed_message_p
)
10102 message_cleared_p
= 0;
10104 if (fonts_changed_p
)
10106 else if (window_height_changed_p
)
10108 consider_all_windows_p
= 1;
10109 ++update_mode_lines
;
10110 ++windows_or_buffers_changed
;
10112 /* If window configuration was changed, frames may have been
10113 marked garbaged. Clear them or we will experience
10114 surprises wrt scrolling. */
10115 if (frame_garbaged
)
10116 clear_garbaged_frames ();
10119 else if (EQ (selected_window
, minibuf_window
)
10120 && (current_buffer
->clip_changed
10121 || XFASTINT (w
->last_modified
) < MODIFF
10122 || XFASTINT (w
->last_overlay_modified
) < OVERLAY_MODIFF
)
10123 && resize_mini_window (w
, 0))
10125 /* Resized active mini-window to fit the size of what it is
10126 showing if its contents might have changed. */
10128 consider_all_windows_p
= 1;
10129 ++windows_or_buffers_changed
;
10130 ++update_mode_lines
;
10132 /* If window configuration was changed, frames may have been
10133 marked garbaged. Clear them or we will experience
10134 surprises wrt scrolling. */
10135 if (frame_garbaged
)
10136 clear_garbaged_frames ();
10140 /* If showing the region, and mark has changed, we must redisplay
10141 the whole window. The assignment to this_line_start_pos prevents
10142 the optimization directly below this if-statement. */
10143 if (((!NILP (Vtransient_mark_mode
)
10144 && !NILP (XBUFFER (w
->buffer
)->mark_active
))
10145 != !NILP (w
->region_showing
))
10146 || (!NILP (w
->region_showing
)
10147 && !EQ (w
->region_showing
,
10148 Fmarker_position (XBUFFER (w
->buffer
)->mark
))))
10149 CHARPOS (this_line_start_pos
) = 0;
10151 /* Optimize the case that only the line containing the cursor in the
10152 selected window has changed. Variables starting with this_ are
10153 set in display_line and record information about the line
10154 containing the cursor. */
10155 tlbufpos
= this_line_start_pos
;
10156 tlendpos
= this_line_end_pos
;
10157 if (!consider_all_windows_p
10158 && CHARPOS (tlbufpos
) > 0
10159 && NILP (w
->update_mode_line
)
10160 && !current_buffer
->clip_changed
10161 && !current_buffer
->prevent_redisplay_optimizations_p
10162 && FRAME_VISIBLE_P (XFRAME (w
->frame
))
10163 && !FRAME_OBSCURED_P (XFRAME (w
->frame
))
10164 /* Make sure recorded data applies to current buffer, etc. */
10165 && this_line_buffer
== current_buffer
10166 && current_buffer
== XBUFFER (w
->buffer
)
10167 && NILP (w
->force_start
)
10168 && NILP (w
->optional_new_start
)
10169 /* Point must be on the line that we have info recorded about. */
10170 && PT
>= CHARPOS (tlbufpos
)
10171 && PT
<= Z
- CHARPOS (tlendpos
)
10172 /* All text outside that line, including its final newline,
10173 must be unchanged */
10174 && text_outside_line_unchanged_p (w
, CHARPOS (tlbufpos
),
10175 CHARPOS (tlendpos
)))
10177 if (CHARPOS (tlbufpos
) > BEGV
10178 && FETCH_BYTE (BYTEPOS (tlbufpos
) - 1) != '\n'
10179 && (CHARPOS (tlbufpos
) == ZV
10180 || FETCH_BYTE (BYTEPOS (tlbufpos
)) == '\n'))
10181 /* Former continuation line has disappeared by becoming empty */
10183 else if (XFASTINT (w
->last_modified
) < MODIFF
10184 || XFASTINT (w
->last_overlay_modified
) < OVERLAY_MODIFF
10185 || MINI_WINDOW_P (w
))
10187 /* We have to handle the case of continuation around a
10188 wide-column character (See the comment in indent.c around
10191 For instance, in the following case:
10193 -------- Insert --------
10194 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
10195 J_I_ ==> J_I_ `^^' are cursors.
10199 As we have to redraw the line above, we should goto cancel. */
10202 int line_height_before
= this_line_pixel_height
;
10204 /* Note that start_display will handle the case that the
10205 line starting at tlbufpos is a continuation lines. */
10206 start_display (&it
, w
, tlbufpos
);
10208 /* Implementation note: It this still necessary? */
10209 if (it
.current_x
!= this_line_start_x
)
10212 TRACE ((stderr
, "trying display optimization 1\n"));
10213 w
->cursor
.vpos
= -1;
10214 overlay_arrow_seen
= 0;
10215 it
.vpos
= this_line_vpos
;
10216 it
.current_y
= this_line_y
;
10217 it
.glyph_row
= MATRIX_ROW (w
->desired_matrix
, this_line_vpos
);
10218 display_line (&it
);
10220 /* If line contains point, is not continued,
10221 and ends at same distance from eob as before, we win */
10222 if (w
->cursor
.vpos
>= 0
10223 /* Line is not continued, otherwise this_line_start_pos
10224 would have been set to 0 in display_line. */
10225 && CHARPOS (this_line_start_pos
)
10226 /* Line ends as before. */
10227 && CHARPOS (this_line_end_pos
) == CHARPOS (tlendpos
)
10228 /* Line has same height as before. Otherwise other lines
10229 would have to be shifted up or down. */
10230 && this_line_pixel_height
== line_height_before
)
10232 /* If this is not the window's last line, we must adjust
10233 the charstarts of the lines below. */
10234 if (it
.current_y
< it
.last_visible_y
)
10236 struct glyph_row
*row
10237 = MATRIX_ROW (w
->current_matrix
, this_line_vpos
+ 1);
10238 int delta
, delta_bytes
;
10240 if (Z
- CHARPOS (tlendpos
) == ZV
)
10242 /* This line ends at end of (accessible part of)
10243 buffer. There is no newline to count. */
10245 - CHARPOS (tlendpos
)
10246 - MATRIX_ROW_START_CHARPOS (row
));
10247 delta_bytes
= (Z_BYTE
10248 - BYTEPOS (tlendpos
)
10249 - MATRIX_ROW_START_BYTEPOS (row
));
10253 /* This line ends in a newline. Must take
10254 account of the newline and the rest of the
10255 text that follows. */
10257 - CHARPOS (tlendpos
)
10258 - MATRIX_ROW_START_CHARPOS (row
));
10259 delta_bytes
= (Z_BYTE
10260 - BYTEPOS (tlendpos
)
10261 - MATRIX_ROW_START_BYTEPOS (row
));
10264 increment_matrix_positions (w
->current_matrix
,
10265 this_line_vpos
+ 1,
10266 w
->current_matrix
->nrows
,
10267 delta
, delta_bytes
);
10270 /* If this row displays text now but previously didn't,
10271 or vice versa, w->window_end_vpos may have to be
10273 if ((it
.glyph_row
- 1)->displays_text_p
)
10275 if (XFASTINT (w
->window_end_vpos
) < this_line_vpos
)
10276 XSETINT (w
->window_end_vpos
, this_line_vpos
);
10278 else if (XFASTINT (w
->window_end_vpos
) == this_line_vpos
10279 && this_line_vpos
> 0)
10280 XSETINT (w
->window_end_vpos
, this_line_vpos
- 1);
10281 w
->window_end_valid
= Qnil
;
10283 /* Update hint: No need to try to scroll in update_window. */
10284 w
->desired_matrix
->no_scrolling_p
= 1;
10287 *w
->desired_matrix
->method
= 0;
10288 debug_method_add (w
, "optimization 1");
10290 #ifdef HAVE_WINDOW_SYSTEM
10291 update_window_fringes (w
, 0);
10298 else if (/* Cursor position hasn't changed. */
10299 PT
== XFASTINT (w
->last_point
)
10300 /* Make sure the cursor was last displayed
10301 in this window. Otherwise we have to reposition it. */
10302 && 0 <= w
->cursor
.vpos
10303 && WINDOW_TOTAL_LINES (w
) > w
->cursor
.vpos
)
10307 do_pending_window_change (1);
10309 /* We used to always goto end_of_redisplay here, but this
10310 isn't enough if we have a blinking cursor. */
10311 if (w
->cursor_off_p
== w
->last_cursor_off_p
)
10312 goto end_of_redisplay
;
10316 /* If highlighting the region, or if the cursor is in the echo area,
10317 then we can't just move the cursor. */
10318 else if (! (!NILP (Vtransient_mark_mode
)
10319 && !NILP (current_buffer
->mark_active
))
10320 && (EQ (selected_window
, current_buffer
->last_selected_window
)
10321 || highlight_nonselected_windows
)
10322 && NILP (w
->region_showing
)
10323 && NILP (Vshow_trailing_whitespace
)
10324 && !cursor_in_echo_area
)
10327 struct glyph_row
*row
;
10329 /* Skip from tlbufpos to PT and see where it is. Note that
10330 PT may be in invisible text. If so, we will end at the
10331 next visible position. */
10332 init_iterator (&it
, w
, CHARPOS (tlbufpos
), BYTEPOS (tlbufpos
),
10333 NULL
, DEFAULT_FACE_ID
);
10334 it
.current_x
= this_line_start_x
;
10335 it
.current_y
= this_line_y
;
10336 it
.vpos
= this_line_vpos
;
10338 /* The call to move_it_to stops in front of PT, but
10339 moves over before-strings. */
10340 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
10342 if (it
.vpos
== this_line_vpos
10343 && (row
= MATRIX_ROW (w
->current_matrix
, this_line_vpos
),
10346 xassert (this_line_vpos
== it
.vpos
);
10347 xassert (this_line_y
== it
.current_y
);
10348 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
10350 *w
->desired_matrix
->method
= 0;
10351 debug_method_add (w
, "optimization 3");
10360 /* Text changed drastically or point moved off of line. */
10361 SET_MATRIX_ROW_ENABLED_P (w
->desired_matrix
, this_line_vpos
, 0);
10364 CHARPOS (this_line_start_pos
) = 0;
10365 consider_all_windows_p
|= buffer_shared
> 1;
10366 ++clear_face_cache_count
;
10367 #ifdef HAVE_WINDOW_SYSTEM
10368 ++clear_image_cache_count
;
10371 /* Build desired matrices, and update the display. If
10372 consider_all_windows_p is non-zero, do it for all windows on all
10373 frames. Otherwise do it for selected_window, only. */
10375 if (consider_all_windows_p
)
10377 Lisp_Object tail
, frame
;
10378 int i
, n
= 0, size
= 50;
10379 struct frame
**updated
10380 = (struct frame
**) alloca (size
* sizeof *updated
);
10382 /* Recompute # windows showing selected buffer. This will be
10383 incremented each time such a window is displayed. */
10386 FOR_EACH_FRAME (tail
, frame
)
10388 struct frame
*f
= XFRAME (frame
);
10390 if (FRAME_WINDOW_P (f
) || f
== sf
)
10392 if (! EQ (frame
, selected_frame
))
10393 /* Select the frame, for the sake of frame-local
10395 select_frame_for_redisplay (frame
);
10397 /* Mark all the scroll bars to be removed; we'll redeem
10398 the ones we want when we redisplay their windows. */
10399 if (condemn_scroll_bars_hook
)
10400 condemn_scroll_bars_hook (f
);
10402 if (FRAME_VISIBLE_P (f
) && !FRAME_OBSCURED_P (f
))
10403 redisplay_windows (FRAME_ROOT_WINDOW (f
));
10405 /* Any scroll bars which redisplay_windows should have
10406 nuked should now go away. */
10407 if (judge_scroll_bars_hook
)
10408 judge_scroll_bars_hook (f
);
10410 /* If fonts changed, display again. */
10411 /* ??? rms: I suspect it is a mistake to jump all the way
10412 back to retry here. It should just retry this frame. */
10413 if (fonts_changed_p
)
10416 if (FRAME_VISIBLE_P (f
) && !FRAME_OBSCURED_P (f
))
10418 /* See if we have to hscroll. */
10419 if (hscroll_windows (f
->root_window
))
10422 /* Prevent various kinds of signals during display
10423 update. stdio is not robust about handling
10424 signals, which can cause an apparent I/O
10426 if (interrupt_input
)
10427 unrequest_sigio ();
10430 /* Update the display. */
10431 set_window_update_flags (XWINDOW (f
->root_window
), 1);
10432 pause
|= update_frame (f
, 0, 0);
10433 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
10440 int nbytes
= size
* sizeof *updated
;
10441 struct frame
**p
= (struct frame
**) alloca (2 * nbytes
);
10442 bcopy (updated
, p
, nbytes
);
10453 /* Do the mark_window_display_accurate after all windows have
10454 been redisplayed because this call resets flags in buffers
10455 which are needed for proper redisplay. */
10456 for (i
= 0; i
< n
; ++i
)
10458 struct frame
*f
= updated
[i
];
10459 mark_window_display_accurate (f
->root_window
, 1);
10460 if (frame_up_to_date_hook
)
10461 frame_up_to_date_hook (f
);
10465 else if (FRAME_VISIBLE_P (sf
) && !FRAME_OBSCURED_P (sf
))
10467 Lisp_Object mini_window
;
10468 struct frame
*mini_frame
;
10470 displayed_buffer
= XBUFFER (XWINDOW (selected_window
)->buffer
);
10471 /* Use list_of_error, not Qerror, so that
10472 we catch only errors and don't run the debugger. */
10473 internal_condition_case_1 (redisplay_window_1
, selected_window
,
10475 redisplay_window_error
);
10477 /* Compare desired and current matrices, perform output. */
10480 /* If fonts changed, display again. */
10481 if (fonts_changed_p
)
10484 /* Prevent various kinds of signals during display update.
10485 stdio is not robust about handling signals,
10486 which can cause an apparent I/O error. */
10487 if (interrupt_input
)
10488 unrequest_sigio ();
10491 if (FRAME_VISIBLE_P (sf
) && !FRAME_OBSCURED_P (sf
))
10493 if (hscroll_windows (selected_window
))
10496 XWINDOW (selected_window
)->must_be_updated_p
= 1;
10497 pause
= update_frame (sf
, 0, 0);
10500 /* We may have called echo_area_display at the top of this
10501 function. If the echo area is on another frame, that may
10502 have put text on a frame other than the selected one, so the
10503 above call to update_frame would not have caught it. Catch
10505 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
10506 mini_frame
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
10508 if (mini_frame
!= sf
&& FRAME_WINDOW_P (mini_frame
))
10510 XWINDOW (mini_window
)->must_be_updated_p
= 1;
10511 pause
|= update_frame (mini_frame
, 0, 0);
10512 if (!pause
&& hscroll_windows (mini_window
))
10517 /* If display was paused because of pending input, make sure we do a
10518 thorough update the next time. */
10521 /* Prevent the optimization at the beginning of
10522 redisplay_internal that tries a single-line update of the
10523 line containing the cursor in the selected window. */
10524 CHARPOS (this_line_start_pos
) = 0;
10526 /* Let the overlay arrow be updated the next time. */
10527 update_overlay_arrows (0);
10529 /* If we pause after scrolling, some rows in the current
10530 matrices of some windows are not valid. */
10531 if (!WINDOW_FULL_WIDTH_P (w
)
10532 && !FRAME_WINDOW_P (XFRAME (w
->frame
)))
10533 update_mode_lines
= 1;
10537 if (!consider_all_windows_p
)
10539 /* This has already been done above if
10540 consider_all_windows_p is set. */
10541 mark_window_display_accurate_1 (w
, 1);
10543 /* Say overlay arrows are up to date. */
10544 update_overlay_arrows (1);
10546 if (frame_up_to_date_hook
!= 0)
10547 frame_up_to_date_hook (sf
);
10550 update_mode_lines
= 0;
10551 windows_or_buffers_changed
= 0;
10552 cursor_type_changed
= 0;
10555 /* Start SIGIO interrupts coming again. Having them off during the
10556 code above makes it less likely one will discard output, but not
10557 impossible, since there might be stuff in the system buffer here.
10558 But it is much hairier to try to do anything about that. */
10559 if (interrupt_input
)
10563 /* If a frame has become visible which was not before, redisplay
10564 again, so that we display it. Expose events for such a frame
10565 (which it gets when becoming visible) don't call the parts of
10566 redisplay constructing glyphs, so simply exposing a frame won't
10567 display anything in this case. So, we have to display these
10568 frames here explicitly. */
10571 Lisp_Object tail
, frame
;
10574 FOR_EACH_FRAME (tail
, frame
)
10576 int this_is_visible
= 0;
10578 if (XFRAME (frame
)->visible
)
10579 this_is_visible
= 1;
10580 FRAME_SAMPLE_VISIBILITY (XFRAME (frame
));
10581 if (XFRAME (frame
)->visible
)
10582 this_is_visible
= 1;
10584 if (this_is_visible
)
10588 if (new_count
!= number_of_visible_frames
)
10589 windows_or_buffers_changed
++;
10592 /* Change frame size now if a change is pending. */
10593 do_pending_window_change (1);
10595 /* If we just did a pending size change, or have additional
10596 visible frames, redisplay again. */
10597 if (windows_or_buffers_changed
&& !pause
)
10600 /* Clear the face cache eventually. */
10601 if (consider_all_windows_p
)
10603 if (clear_face_cache_count
> CLEAR_FACE_CACHE_COUNT
)
10605 clear_face_cache (0);
10606 clear_face_cache_count
= 0;
10608 #ifdef HAVE_WINDOW_SYSTEM
10609 if (clear_image_cache_count
> CLEAR_IMAGE_CACHE_COUNT
)
10611 Lisp_Object tail
, frame
;
10612 FOR_EACH_FRAME (tail
, frame
)
10614 struct frame
*f
= XFRAME (frame
);
10615 if (FRAME_WINDOW_P (f
))
10616 clear_image_cache (f
, 0);
10618 clear_image_cache_count
= 0;
10620 #endif /* HAVE_WINDOW_SYSTEM */
10624 unbind_to (count
, Qnil
);
10629 /* Redisplay, but leave alone any recent echo area message unless
10630 another message has been requested in its place.
10632 This is useful in situations where you need to redisplay but no
10633 user action has occurred, making it inappropriate for the message
10634 area to be cleared. See tracking_off and
10635 wait_reading_process_output for examples of these situations.
10637 FROM_WHERE is an integer saying from where this function was
10638 called. This is useful for debugging. */
10641 redisplay_preserve_echo_area (from_where
)
10644 TRACE ((stderr
, "redisplay_preserve_echo_area (%d)\n", from_where
));
10646 if (!NILP (echo_area_buffer
[1]))
10648 /* We have a previously displayed message, but no current
10649 message. Redisplay the previous message. */
10650 display_last_displayed_message_p
= 1;
10651 redisplay_internal (1);
10652 display_last_displayed_message_p
= 0;
10655 redisplay_internal (1);
10657 if (rif
!= NULL
&& rif
->flush_display_optional
)
10658 rif
->flush_display_optional (NULL
);
10662 /* Function registered with record_unwind_protect in
10663 redisplay_internal. Reset redisplaying_p to the value it had
10664 before redisplay_internal was called, and clear
10665 prevent_freeing_realized_faces_p. It also selects the previously
10669 unwind_redisplay (val
)
10672 Lisp_Object old_redisplaying_p
, old_frame
;
10674 old_redisplaying_p
= XCAR (val
);
10675 redisplaying_p
= XFASTINT (old_redisplaying_p
);
10676 old_frame
= XCDR (val
);
10677 if (! EQ (old_frame
, selected_frame
))
10678 select_frame_for_redisplay (old_frame
);
10683 /* Mark the display of window W as accurate or inaccurate. If
10684 ACCURATE_P is non-zero mark display of W as accurate. If
10685 ACCURATE_P is zero, arrange for W to be redisplayed the next time
10686 redisplay_internal is called. */
10689 mark_window_display_accurate_1 (w
, accurate_p
)
10693 if (BUFFERP (w
->buffer
))
10695 struct buffer
*b
= XBUFFER (w
->buffer
);
10698 = make_number (accurate_p
? BUF_MODIFF (b
) : 0);
10699 w
->last_overlay_modified
10700 = make_number (accurate_p
? BUF_OVERLAY_MODIFF (b
) : 0);
10702 = BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
) ? Qt
: Qnil
;
10706 b
->clip_changed
= 0;
10707 b
->prevent_redisplay_optimizations_p
= 0;
10709 BUF_UNCHANGED_MODIFIED (b
) = BUF_MODIFF (b
);
10710 BUF_OVERLAY_UNCHANGED_MODIFIED (b
) = BUF_OVERLAY_MODIFF (b
);
10711 BUF_BEG_UNCHANGED (b
) = BUF_GPT (b
) - BUF_BEG (b
);
10712 BUF_END_UNCHANGED (b
) = BUF_Z (b
) - BUF_GPT (b
);
10714 w
->current_matrix
->buffer
= b
;
10715 w
->current_matrix
->begv
= BUF_BEGV (b
);
10716 w
->current_matrix
->zv
= BUF_ZV (b
);
10718 w
->last_cursor
= w
->cursor
;
10719 w
->last_cursor_off_p
= w
->cursor_off_p
;
10721 if (w
== XWINDOW (selected_window
))
10722 w
->last_point
= make_number (BUF_PT (b
));
10724 w
->last_point
= make_number (XMARKER (w
->pointm
)->charpos
);
10730 w
->window_end_valid
= w
->buffer
;
10731 #if 0 /* This is incorrect with variable-height lines. */
10732 xassert (XINT (w
->window_end_vpos
)
10733 < (WINDOW_TOTAL_LINES (w
)
10734 - (WINDOW_WANTS_MODELINE_P (w
) ? 1 : 0)));
10736 w
->update_mode_line
= Qnil
;
10741 /* Mark the display of windows in the window tree rooted at WINDOW as
10742 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
10743 windows as accurate. If ACCURATE_P is zero, arrange for windows to
10744 be redisplayed the next time redisplay_internal is called. */
10747 mark_window_display_accurate (window
, accurate_p
)
10748 Lisp_Object window
;
10753 for (; !NILP (window
); window
= w
->next
)
10755 w
= XWINDOW (window
);
10756 mark_window_display_accurate_1 (w
, accurate_p
);
10758 if (!NILP (w
->vchild
))
10759 mark_window_display_accurate (w
->vchild
, accurate_p
);
10760 if (!NILP (w
->hchild
))
10761 mark_window_display_accurate (w
->hchild
, accurate_p
);
10766 update_overlay_arrows (1);
10770 /* Force a thorough redisplay the next time by setting
10771 last_arrow_position and last_arrow_string to t, which is
10772 unequal to any useful value of Voverlay_arrow_... */
10773 update_overlay_arrows (-1);
10778 /* Return value in display table DP (Lisp_Char_Table *) for character
10779 C. Since a display table doesn't have any parent, we don't have to
10780 follow parent. Do not call this function directly but use the
10781 macro DISP_CHAR_VECTOR. */
10784 disp_char_vector (dp
, c
)
10785 struct Lisp_Char_Table
*dp
;
10791 if (SINGLE_BYTE_CHAR_P (c
))
10792 return (dp
->contents
[c
]);
10794 SPLIT_CHAR (c
, code
[0], code
[1], code
[2]);
10797 else if (code
[2] < 32)
10800 /* Here, the possible range of code[0] (== charset ID) is
10801 128..max_charset. Since the top level char table contains data
10802 for multibyte characters after 256th element, we must increment
10803 code[0] by 128 to get a correct index. */
10805 code
[3] = -1; /* anchor */
10807 for (i
= 0; code
[i
] >= 0; i
++, dp
= XCHAR_TABLE (val
))
10809 val
= dp
->contents
[code
[i
]];
10810 if (!SUB_CHAR_TABLE_P (val
))
10811 return (NILP (val
) ? dp
->defalt
: val
);
10814 /* Here, val is a sub char table. We return the default value of
10816 return (dp
->defalt
);
10821 /***********************************************************************
10823 ***********************************************************************/
10825 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
10828 redisplay_windows (window
)
10829 Lisp_Object window
;
10831 while (!NILP (window
))
10833 struct window
*w
= XWINDOW (window
);
10835 if (!NILP (w
->hchild
))
10836 redisplay_windows (w
->hchild
);
10837 else if (!NILP (w
->vchild
))
10838 redisplay_windows (w
->vchild
);
10841 displayed_buffer
= XBUFFER (w
->buffer
);
10842 /* Use list_of_error, not Qerror, so that
10843 we catch only errors and don't run the debugger. */
10844 internal_condition_case_1 (redisplay_window_0
, window
,
10846 redisplay_window_error
);
10854 redisplay_window_error ()
10856 displayed_buffer
->display_error_modiff
= BUF_MODIFF (displayed_buffer
);
10861 redisplay_window_0 (window
)
10862 Lisp_Object window
;
10864 if (displayed_buffer
->display_error_modiff
< BUF_MODIFF (displayed_buffer
))
10865 redisplay_window (window
, 0);
10870 redisplay_window_1 (window
)
10871 Lisp_Object window
;
10873 if (displayed_buffer
->display_error_modiff
< BUF_MODIFF (displayed_buffer
))
10874 redisplay_window (window
, 1);
10879 /* Increment GLYPH until it reaches END or CONDITION fails while
10880 adding (GLYPH)->pixel_width to X. */
10882 #define SKIP_GLYPHS(glyph, end, x, condition) \
10885 (x) += (glyph)->pixel_width; \
10888 while ((glyph) < (end) && (condition))
10891 /* Set cursor position of W. PT is assumed to be displayed in ROW.
10892 DELTA is the number of bytes by which positions recorded in ROW
10893 differ from current buffer positions. */
10896 set_cursor_from_row (w
, row
, matrix
, delta
, delta_bytes
, dy
, dvpos
)
10898 struct glyph_row
*row
;
10899 struct glyph_matrix
*matrix
;
10900 int delta
, delta_bytes
, dy
, dvpos
;
10902 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
10903 struct glyph
*end
= glyph
+ row
->used
[TEXT_AREA
];
10904 struct glyph
*cursor
= NULL
;
10905 /* The first glyph that starts a sequence of glyphs from string. */
10906 struct glyph
*string_start
;
10907 /* The X coordinate of string_start. */
10908 int string_start_x
;
10909 /* The last known character position. */
10910 int last_pos
= MATRIX_ROW_START_CHARPOS (row
) + delta
;
10911 /* The last known character position before string_start. */
10912 int string_before_pos
;
10915 int cursor_from_overlay_pos
= 0;
10916 int pt_old
= PT
- delta
;
10918 /* Skip over glyphs not having an object at the start of the row.
10919 These are special glyphs like truncation marks on terminal
10921 if (row
->displays_text_p
)
10923 && INTEGERP (glyph
->object
)
10924 && glyph
->charpos
< 0)
10926 x
+= glyph
->pixel_width
;
10930 string_start
= NULL
;
10932 && !INTEGERP (glyph
->object
)
10933 && (!BUFFERP (glyph
->object
)
10934 || (last_pos
= glyph
->charpos
) < pt_old
))
10936 if (! STRINGP (glyph
->object
))
10938 string_start
= NULL
;
10939 x
+= glyph
->pixel_width
;
10941 if (cursor_from_overlay_pos
10942 && last_pos
> cursor_from_overlay_pos
)
10944 cursor_from_overlay_pos
= 0;
10950 string_before_pos
= last_pos
;
10951 string_start
= glyph
;
10952 string_start_x
= x
;
10953 /* Skip all glyphs from string. */
10957 if ((cursor
== NULL
|| glyph
> cursor
)
10958 && !NILP (Fget_char_property (make_number ((glyph
)->charpos
),
10959 Qcursor
, (glyph
)->object
))
10960 && (pos
= string_buffer_position (w
, glyph
->object
,
10961 string_before_pos
),
10962 (pos
== 0 /* From overlay */
10963 || pos
== pt_old
)))
10965 /* Estimate overlay buffer position from the buffer
10966 positions of the glyphs before and after the overlay.
10967 Add 1 to last_pos so that if point corresponds to the
10968 glyph right after the overlay, we still use a 'cursor'
10969 property found in that overlay. */
10970 cursor_from_overlay_pos
= pos
== 0 ? last_pos
+1 : 0;
10974 x
+= glyph
->pixel_width
;
10977 while (glyph
< end
&& STRINGP (glyph
->object
));
10981 if (cursor
!= NULL
)
10986 else if (row
->ends_in_ellipsis_p
&& glyph
== end
)
10988 /* Scan back over the ellipsis glyphs, decrementing positions. */
10989 while (glyph
> row
->glyphs
[TEXT_AREA
]
10990 && (glyph
- 1)->charpos
== last_pos
)
10991 glyph
--, x
-= glyph
->pixel_width
;
10992 /* That loop always goes one position too far,
10993 including the glyph before the ellipsis.
10994 So scan forward over that one. */
10995 x
+= glyph
->pixel_width
;
10998 else if (string_start
10999 && (glyph
== end
|| !BUFFERP (glyph
->object
) || last_pos
> pt_old
))
11001 /* We may have skipped over point because the previous glyphs
11002 are from string. As there's no easy way to know the
11003 character position of the current glyph, find the correct
11004 glyph on point by scanning from string_start again. */
11006 Lisp_Object string
;
11009 limit
= make_number (pt_old
+ 1);
11011 glyph
= string_start
;
11012 x
= string_start_x
;
11013 string
= glyph
->object
;
11014 pos
= string_buffer_position (w
, string
, string_before_pos
);
11015 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
11016 because we always put cursor after overlay strings. */
11017 while (pos
== 0 && glyph
< end
)
11019 string
= glyph
->object
;
11020 SKIP_GLYPHS (glyph
, end
, x
, EQ (glyph
->object
, string
));
11022 pos
= string_buffer_position (w
, glyph
->object
, string_before_pos
);
11025 while (glyph
< end
)
11027 pos
= XINT (Fnext_single_char_property_change
11028 (make_number (pos
), Qdisplay
, Qnil
, limit
));
11031 /* Skip glyphs from the same string. */
11032 string
= glyph
->object
;
11033 SKIP_GLYPHS (glyph
, end
, x
, EQ (glyph
->object
, string
));
11034 /* Skip glyphs from an overlay. */
11036 && ! string_buffer_position (w
, glyph
->object
, pos
))
11038 string
= glyph
->object
;
11039 SKIP_GLYPHS (glyph
, end
, x
, EQ (glyph
->object
, string
));
11044 w
->cursor
.hpos
= glyph
- row
->glyphs
[TEXT_AREA
];
11046 w
->cursor
.vpos
= MATRIX_ROW_VPOS (row
, matrix
) + dvpos
;
11047 w
->cursor
.y
= row
->y
+ dy
;
11049 if (w
== XWINDOW (selected_window
))
11051 if (!row
->continued_p
11052 && !MATRIX_ROW_CONTINUATION_LINE_P (row
)
11055 this_line_buffer
= XBUFFER (w
->buffer
);
11057 CHARPOS (this_line_start_pos
)
11058 = MATRIX_ROW_START_CHARPOS (row
) + delta
;
11059 BYTEPOS (this_line_start_pos
)
11060 = MATRIX_ROW_START_BYTEPOS (row
) + delta_bytes
;
11062 CHARPOS (this_line_end_pos
)
11063 = Z
- (MATRIX_ROW_END_CHARPOS (row
) + delta
);
11064 BYTEPOS (this_line_end_pos
)
11065 = Z_BYTE
- (MATRIX_ROW_END_BYTEPOS (row
) + delta_bytes
);
11067 this_line_y
= w
->cursor
.y
;
11068 this_line_pixel_height
= row
->height
;
11069 this_line_vpos
= w
->cursor
.vpos
;
11070 this_line_start_x
= row
->x
;
11073 CHARPOS (this_line_start_pos
) = 0;
11078 /* Run window scroll functions, if any, for WINDOW with new window
11079 start STARTP. Sets the window start of WINDOW to that position.
11081 We assume that the window's buffer is really current. */
11083 static INLINE
struct text_pos
11084 run_window_scroll_functions (window
, startp
)
11085 Lisp_Object window
;
11086 struct text_pos startp
;
11088 struct window
*w
= XWINDOW (window
);
11089 SET_MARKER_FROM_TEXT_POS (w
->start
, startp
);
11091 if (current_buffer
!= XBUFFER (w
->buffer
))
11094 if (!NILP (Vwindow_scroll_functions
))
11096 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
11097 make_number (CHARPOS (startp
)));
11098 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
11099 /* In case the hook functions switch buffers. */
11100 if (current_buffer
!= XBUFFER (w
->buffer
))
11101 set_buffer_internal_1 (XBUFFER (w
->buffer
));
11108 /* Make sure the line containing the cursor is fully visible.
11109 A value of 1 means there is nothing to be done.
11110 (Either the line is fully visible, or it cannot be made so,
11111 or we cannot tell.)
11113 If FORCE_P is non-zero, return 0 even if partial visible cursor row
11114 is higher than window.
11116 A value of 0 means the caller should do scrolling
11117 as if point had gone off the screen. */
11120 cursor_row_fully_visible_p (w
, force_p
, current_matrix_p
)
11124 struct glyph_matrix
*matrix
;
11125 struct glyph_row
*row
;
11128 if (!make_cursor_line_fully_visible_p
)
11131 /* It's not always possible to find the cursor, e.g, when a window
11132 is full of overlay strings. Don't do anything in that case. */
11133 if (w
->cursor
.vpos
< 0)
11136 matrix
= current_matrix_p
? w
->current_matrix
: w
->desired_matrix
;
11137 row
= MATRIX_ROW (matrix
, w
->cursor
.vpos
);
11139 /* If the cursor row is not partially visible, there's nothing to do. */
11140 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w
, row
))
11143 /* If the row the cursor is in is taller than the window's height,
11144 it's not clear what to do, so do nothing. */
11145 window_height
= window_box_height (w
);
11146 if (row
->height
>= window_height
)
11148 if (!force_p
|| w
->vscroll
)
11154 /* This code used to try to scroll the window just enough to make
11155 the line visible. It returned 0 to say that the caller should
11156 allocate larger glyph matrices. */
11158 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w
, row
))
11160 int dy
= row
->height
- row
->visible_height
;
11163 shift_glyph_matrix (w
, matrix
, 0, matrix
->nrows
, dy
);
11165 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
11167 int dy
= - (row
->height
- row
->visible_height
);
11170 shift_glyph_matrix (w
, matrix
, 0, matrix
->nrows
, dy
);
11173 /* When we change the cursor y-position of the selected window,
11174 change this_line_y as well so that the display optimization for
11175 the cursor line of the selected window in redisplay_internal uses
11176 the correct y-position. */
11177 if (w
== XWINDOW (selected_window
))
11178 this_line_y
= w
->cursor
.y
;
11180 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
11181 redisplay with larger matrices. */
11182 if (matrix
->nrows
< required_matrix_height (w
))
11184 fonts_changed_p
= 1;
11193 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
11194 non-zero means only WINDOW is redisplayed in redisplay_internal.
11195 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
11196 in redisplay_window to bring a partially visible line into view in
11197 the case that only the cursor has moved.
11199 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
11200 last screen line's vertical height extends past the end of the screen.
11204 1 if scrolling succeeded
11206 0 if scrolling didn't find point.
11208 -1 if new fonts have been loaded so that we must interrupt
11209 redisplay, adjust glyph matrices, and try again. */
11215 SCROLLING_NEED_LARGER_MATRICES
11219 try_scrolling (window
, just_this_one_p
, scroll_conservatively
,
11220 scroll_step
, temp_scroll_step
, last_line_misfit
)
11221 Lisp_Object window
;
11222 int just_this_one_p
;
11223 EMACS_INT scroll_conservatively
, scroll_step
;
11224 int temp_scroll_step
;
11225 int last_line_misfit
;
11227 struct window
*w
= XWINDOW (window
);
11228 struct frame
*f
= XFRAME (w
->frame
);
11229 struct text_pos scroll_margin_pos
;
11230 struct text_pos pos
;
11231 struct text_pos startp
;
11233 Lisp_Object window_end
;
11234 int this_scroll_margin
;
11238 int amount_to_scroll
= 0;
11239 Lisp_Object aggressive
;
11241 int extra_scroll_margin_lines
= last_line_misfit
? 1 : 0;
11244 debug_method_add (w
, "try_scrolling");
11247 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
11249 /* Compute scroll margin height in pixels. We scroll when point is
11250 within this distance from the top or bottom of the window. */
11251 if (scroll_margin
> 0)
11253 this_scroll_margin
= min (scroll_margin
, WINDOW_TOTAL_LINES (w
) / 4);
11254 this_scroll_margin
*= FRAME_LINE_HEIGHT (f
);
11257 this_scroll_margin
= 0;
11259 /* Force scroll_conservatively to have a reasonable value so it doesn't
11260 cause an overflow while computing how much to scroll. */
11261 if (scroll_conservatively
)
11262 scroll_conservatively
= min (scroll_conservatively
,
11263 MOST_POSITIVE_FIXNUM
/ FRAME_LINE_HEIGHT (f
));
11265 /* Compute how much we should try to scroll maximally to bring point
11267 if (scroll_step
|| scroll_conservatively
|| temp_scroll_step
)
11268 scroll_max
= max (scroll_step
,
11269 max (scroll_conservatively
, temp_scroll_step
));
11270 else if (NUMBERP (current_buffer
->scroll_down_aggressively
)
11271 || NUMBERP (current_buffer
->scroll_up_aggressively
))
11272 /* We're trying to scroll because of aggressive scrolling
11273 but no scroll_step is set. Choose an arbitrary one. Maybe
11274 there should be a variable for this. */
11278 scroll_max
*= FRAME_LINE_HEIGHT (f
);
11280 /* Decide whether we have to scroll down. Start at the window end
11281 and move this_scroll_margin up to find the position of the scroll
11283 window_end
= Fwindow_end (window
, Qt
);
11287 CHARPOS (scroll_margin_pos
) = XINT (window_end
);
11288 BYTEPOS (scroll_margin_pos
) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos
));
11290 if (this_scroll_margin
|| extra_scroll_margin_lines
)
11292 start_display (&it
, w
, scroll_margin_pos
);
11293 if (this_scroll_margin
)
11294 move_it_vertically_backward (&it
, this_scroll_margin
);
11295 if (extra_scroll_margin_lines
)
11296 move_it_by_lines (&it
, - extra_scroll_margin_lines
, 0);
11297 scroll_margin_pos
= it
.current
.pos
;
11300 if (PT
>= CHARPOS (scroll_margin_pos
))
11304 /* Point is in the scroll margin at the bottom of the window, or
11305 below. Compute a new window start that makes point visible. */
11307 /* Compute the distance from the scroll margin to PT.
11308 Give up if the distance is greater than scroll_max. */
11309 start_display (&it
, w
, scroll_margin_pos
);
11311 move_it_to (&it
, PT
, 0, it
.last_visible_y
, -1,
11312 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
11314 /* To make point visible, we have to move the window start
11315 down so that the line the cursor is in is visible, which
11316 means we have to add in the height of the cursor line. */
11317 dy
= line_bottom_y (&it
) - y0
;
11319 if (dy
> scroll_max
)
11320 return SCROLLING_FAILED
;
11322 /* Move the window start down. If scrolling conservatively,
11323 move it just enough down to make point visible. If
11324 scroll_step is set, move it down by scroll_step. */
11325 start_display (&it
, w
, startp
);
11327 if (scroll_conservatively
)
11328 /* Set AMOUNT_TO_SCROLL to at least one line,
11329 and at most scroll_conservatively lines. */
11331 = min (max (dy
, FRAME_LINE_HEIGHT (f
)),
11332 FRAME_LINE_HEIGHT (f
) * scroll_conservatively
);
11333 else if (scroll_step
|| temp_scroll_step
)
11334 amount_to_scroll
= scroll_max
;
11337 aggressive
= current_buffer
->scroll_up_aggressively
;
11338 height
= WINDOW_BOX_TEXT_HEIGHT (w
);
11339 if (NUMBERP (aggressive
))
11341 double float_amount
= XFLOATINT (aggressive
) * height
;
11342 amount_to_scroll
= float_amount
;
11343 if (amount_to_scroll
== 0 && float_amount
> 0)
11344 amount_to_scroll
= 1;
11348 if (amount_to_scroll
<= 0)
11349 return SCROLLING_FAILED
;
11351 /* If moving by amount_to_scroll leaves STARTP unchanged,
11352 move it down one screen line. */
11354 move_it_vertically (&it
, amount_to_scroll
);
11355 if (CHARPOS (it
.current
.pos
) == CHARPOS (startp
))
11356 move_it_by_lines (&it
, 1, 1);
11357 startp
= it
.current
.pos
;
11361 /* See if point is inside the scroll margin at the top of the
11363 scroll_margin_pos
= startp
;
11364 if (this_scroll_margin
)
11366 start_display (&it
, w
, startp
);
11367 move_it_vertically (&it
, this_scroll_margin
);
11368 scroll_margin_pos
= it
.current
.pos
;
11371 if (PT
< CHARPOS (scroll_margin_pos
))
11373 /* Point is in the scroll margin at the top of the window or
11374 above what is displayed in the window. */
11377 /* Compute the vertical distance from PT to the scroll
11378 margin position. Give up if distance is greater than
11380 SET_TEXT_POS (pos
, PT
, PT_BYTE
);
11381 start_display (&it
, w
, pos
);
11383 move_it_to (&it
, CHARPOS (scroll_margin_pos
), 0,
11384 it
.last_visible_y
, -1,
11385 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
11386 dy
= it
.current_y
- y0
;
11387 if (dy
> scroll_max
)
11388 return SCROLLING_FAILED
;
11390 /* Compute new window start. */
11391 start_display (&it
, w
, startp
);
11393 if (scroll_conservatively
)
11395 = max (dy
, FRAME_LINE_HEIGHT (f
) * max (scroll_step
, temp_scroll_step
));
11396 else if (scroll_step
|| temp_scroll_step
)
11397 amount_to_scroll
= scroll_max
;
11400 aggressive
= current_buffer
->scroll_down_aggressively
;
11401 height
= WINDOW_BOX_TEXT_HEIGHT (w
);
11402 if (NUMBERP (aggressive
))
11404 double float_amount
= XFLOATINT (aggressive
) * height
;
11405 amount_to_scroll
= float_amount
;
11406 if (amount_to_scroll
== 0 && float_amount
> 0)
11407 amount_to_scroll
= 1;
11411 if (amount_to_scroll
<= 0)
11412 return SCROLLING_FAILED
;
11414 move_it_vertically_backward (&it
, amount_to_scroll
);
11415 startp
= it
.current
.pos
;
11419 /* Run window scroll functions. */
11420 startp
= run_window_scroll_functions (window
, startp
);
11422 /* Display the window. Give up if new fonts are loaded, or if point
11424 if (!try_window (window
, startp
))
11425 rc
= SCROLLING_NEED_LARGER_MATRICES
;
11426 else if (w
->cursor
.vpos
< 0)
11428 clear_glyph_matrix (w
->desired_matrix
);
11429 rc
= SCROLLING_FAILED
;
11433 /* Maybe forget recorded base line for line number display. */
11434 if (!just_this_one_p
11435 || current_buffer
->clip_changed
11436 || BEG_UNCHANGED
< CHARPOS (startp
))
11437 w
->base_line_number
= Qnil
;
11439 /* If cursor ends up on a partially visible line,
11440 treat that as being off the bottom of the screen. */
11441 if (! cursor_row_fully_visible_p (w
, extra_scroll_margin_lines
<= 1, 0))
11443 clear_glyph_matrix (w
->desired_matrix
);
11444 ++extra_scroll_margin_lines
;
11447 rc
= SCROLLING_SUCCESS
;
11454 /* Compute a suitable window start for window W if display of W starts
11455 on a continuation line. Value is non-zero if a new window start
11458 The new window start will be computed, based on W's width, starting
11459 from the start of the continued line. It is the start of the
11460 screen line with the minimum distance from the old start W->start. */
11463 compute_window_start_on_continuation_line (w
)
11466 struct text_pos pos
, start_pos
;
11467 int window_start_changed_p
= 0;
11469 SET_TEXT_POS_FROM_MARKER (start_pos
, w
->start
);
11471 /* If window start is on a continuation line... Window start may be
11472 < BEGV in case there's invisible text at the start of the
11473 buffer (M-x rmail, for example). */
11474 if (CHARPOS (start_pos
) > BEGV
11475 && FETCH_BYTE (BYTEPOS (start_pos
) - 1) != '\n')
11478 struct glyph_row
*row
;
11480 /* Handle the case that the window start is out of range. */
11481 if (CHARPOS (start_pos
) < BEGV
)
11482 SET_TEXT_POS (start_pos
, BEGV
, BEGV_BYTE
);
11483 else if (CHARPOS (start_pos
) > ZV
)
11484 SET_TEXT_POS (start_pos
, ZV
, ZV_BYTE
);
11486 /* Find the start of the continued line. This should be fast
11487 because scan_buffer is fast (newline cache). */
11488 row
= w
->desired_matrix
->rows
+ (WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0);
11489 init_iterator (&it
, w
, CHARPOS (start_pos
), BYTEPOS (start_pos
),
11490 row
, DEFAULT_FACE_ID
);
11491 reseat_at_previous_visible_line_start (&it
);
11493 /* If the line start is "too far" away from the window start,
11494 say it takes too much time to compute a new window start. */
11495 if (CHARPOS (start_pos
) - IT_CHARPOS (it
)
11496 < WINDOW_TOTAL_LINES (w
) * WINDOW_TOTAL_COLS (w
))
11498 int min_distance
, distance
;
11500 /* Move forward by display lines to find the new window
11501 start. If window width was enlarged, the new start can
11502 be expected to be > the old start. If window width was
11503 decreased, the new window start will be < the old start.
11504 So, we're looking for the display line start with the
11505 minimum distance from the old window start. */
11506 pos
= it
.current
.pos
;
11507 min_distance
= INFINITY
;
11508 while ((distance
= abs (CHARPOS (start_pos
) - IT_CHARPOS (it
))),
11509 distance
< min_distance
)
11511 min_distance
= distance
;
11512 pos
= it
.current
.pos
;
11513 move_it_by_lines (&it
, 1, 0);
11516 /* Set the window start there. */
11517 SET_MARKER_FROM_TEXT_POS (w
->start
, pos
);
11518 window_start_changed_p
= 1;
11522 return window_start_changed_p
;
11526 /* Try cursor movement in case text has not changed in window WINDOW,
11527 with window start STARTP. Value is
11529 CURSOR_MOVEMENT_SUCCESS if successful
11531 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
11533 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
11534 display. *SCROLL_STEP is set to 1, under certain circumstances, if
11535 we want to scroll as if scroll-step were set to 1. See the code.
11537 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
11538 which case we have to abort this redisplay, and adjust matrices
11543 CURSOR_MOVEMENT_SUCCESS
,
11544 CURSOR_MOVEMENT_CANNOT_BE_USED
,
11545 CURSOR_MOVEMENT_MUST_SCROLL
,
11546 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
11550 try_cursor_movement (window
, startp
, scroll_step
)
11551 Lisp_Object window
;
11552 struct text_pos startp
;
11555 struct window
*w
= XWINDOW (window
);
11556 struct frame
*f
= XFRAME (w
->frame
);
11557 int rc
= CURSOR_MOVEMENT_CANNOT_BE_USED
;
11560 if (inhibit_try_cursor_movement
)
11564 /* Handle case where text has not changed, only point, and it has
11565 not moved off the frame. */
11566 if (/* Point may be in this window. */
11567 PT
>= CHARPOS (startp
)
11568 /* Selective display hasn't changed. */
11569 && !current_buffer
->clip_changed
11570 /* Function force-mode-line-update is used to force a thorough
11571 redisplay. It sets either windows_or_buffers_changed or
11572 update_mode_lines. So don't take a shortcut here for these
11574 && !update_mode_lines
11575 && !windows_or_buffers_changed
11576 && !cursor_type_changed
11577 /* Can't use this case if highlighting a region. When a
11578 region exists, cursor movement has to do more than just
11580 && !(!NILP (Vtransient_mark_mode
)
11581 && !NILP (current_buffer
->mark_active
))
11582 && NILP (w
->region_showing
)
11583 && NILP (Vshow_trailing_whitespace
)
11584 /* Right after splitting windows, last_point may be nil. */
11585 && INTEGERP (w
->last_point
)
11586 /* This code is not used for mini-buffer for the sake of the case
11587 of redisplaying to replace an echo area message; since in
11588 that case the mini-buffer contents per se are usually
11589 unchanged. This code is of no real use in the mini-buffer
11590 since the handling of this_line_start_pos, etc., in redisplay
11591 handles the same cases. */
11592 && !EQ (window
, minibuf_window
)
11593 /* When splitting windows or for new windows, it happens that
11594 redisplay is called with a nil window_end_vpos or one being
11595 larger than the window. This should really be fixed in
11596 window.c. I don't have this on my list, now, so we do
11597 approximately the same as the old redisplay code. --gerd. */
11598 && INTEGERP (w
->window_end_vpos
)
11599 && XFASTINT (w
->window_end_vpos
) < w
->current_matrix
->nrows
11600 && (FRAME_WINDOW_P (f
)
11601 || !overlay_arrow_in_current_buffer_p ()))
11603 int this_scroll_margin
, top_scroll_margin
;
11604 struct glyph_row
*row
= NULL
;
11607 debug_method_add (w
, "cursor movement");
11610 /* Scroll if point within this distance from the top or bottom
11611 of the window. This is a pixel value. */
11612 this_scroll_margin
= max (0, scroll_margin
);
11613 this_scroll_margin
= min (this_scroll_margin
, WINDOW_TOTAL_LINES (w
) / 4);
11614 this_scroll_margin
*= FRAME_LINE_HEIGHT (f
);
11616 top_scroll_margin
= this_scroll_margin
;
11617 if (WINDOW_WANTS_HEADER_LINE_P (w
))
11618 top_scroll_margin
+= CURRENT_HEADER_LINE_HEIGHT (w
);
11620 /* Start with the row the cursor was displayed during the last
11621 not paused redisplay. Give up if that row is not valid. */
11622 if (w
->last_cursor
.vpos
< 0
11623 || w
->last_cursor
.vpos
>= w
->current_matrix
->nrows
)
11624 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11627 row
= MATRIX_ROW (w
->current_matrix
, w
->last_cursor
.vpos
);
11628 if (row
->mode_line_p
)
11630 if (!row
->enabled_p
)
11631 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11634 if (rc
== CURSOR_MOVEMENT_CANNOT_BE_USED
)
11637 int last_y
= window_text_bottom_y (w
) - this_scroll_margin
;
11639 if (PT
> XFASTINT (w
->last_point
))
11641 /* Point has moved forward. */
11642 while (MATRIX_ROW_END_CHARPOS (row
) < PT
11643 && MATRIX_ROW_BOTTOM_Y (row
) < last_y
)
11645 xassert (row
->enabled_p
);
11649 /* The end position of a row equals the start position
11650 of the next row. If PT is there, we would rather
11651 display it in the next line. */
11652 while (MATRIX_ROW_BOTTOM_Y (row
) < last_y
11653 && MATRIX_ROW_END_CHARPOS (row
) == PT
11654 && !cursor_row_p (w
, row
))
11657 /* If within the scroll margin, scroll. Note that
11658 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
11659 the next line would be drawn, and that
11660 this_scroll_margin can be zero. */
11661 if (MATRIX_ROW_BOTTOM_Y (row
) > last_y
11662 || PT
> MATRIX_ROW_END_CHARPOS (row
)
11663 /* Line is completely visible last line in window
11664 and PT is to be set in the next line. */
11665 || (MATRIX_ROW_BOTTOM_Y (row
) == last_y
11666 && PT
== MATRIX_ROW_END_CHARPOS (row
)
11667 && !row
->ends_at_zv_p
11668 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
)))
11671 else if (PT
< XFASTINT (w
->last_point
))
11673 /* Cursor has to be moved backward. Note that PT >=
11674 CHARPOS (startp) because of the outer if-statement. */
11675 while (!row
->mode_line_p
11676 && (MATRIX_ROW_START_CHARPOS (row
) > PT
11677 || (MATRIX_ROW_START_CHARPOS (row
) == PT
11678 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row
)))
11679 && (row
->y
> top_scroll_margin
11680 || CHARPOS (startp
) == BEGV
))
11682 xassert (row
->enabled_p
);
11686 /* Consider the following case: Window starts at BEGV,
11687 there is invisible, intangible text at BEGV, so that
11688 display starts at some point START > BEGV. It can
11689 happen that we are called with PT somewhere between
11690 BEGV and START. Try to handle that case. */
11691 if (row
< w
->current_matrix
->rows
11692 || row
->mode_line_p
)
11694 row
= w
->current_matrix
->rows
;
11695 if (row
->mode_line_p
)
11699 /* Due to newlines in overlay strings, we may have to
11700 skip forward over overlay strings. */
11701 while (MATRIX_ROW_BOTTOM_Y (row
) < last_y
11702 && MATRIX_ROW_END_CHARPOS (row
) == PT
11703 && !cursor_row_p (w
, row
))
11706 /* If within the scroll margin, scroll. */
11707 if (row
->y
< top_scroll_margin
11708 && CHARPOS (startp
) != BEGV
)
11713 /* Cursor did not move. So don't scroll even if cursor line
11714 is partially visible, as it was so before. */
11715 rc
= CURSOR_MOVEMENT_SUCCESS
;
11718 if (PT
< MATRIX_ROW_START_CHARPOS (row
)
11719 || PT
> MATRIX_ROW_END_CHARPOS (row
))
11721 /* if PT is not in the glyph row, give up. */
11722 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11724 else if (rc
!= CURSOR_MOVEMENT_SUCCESS
11725 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w
, row
)
11726 && make_cursor_line_fully_visible_p
)
11728 if (PT
== MATRIX_ROW_END_CHARPOS (row
)
11729 && !row
->ends_at_zv_p
11730 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
))
11731 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11732 else if (row
->height
> window_box_height (w
))
11734 /* If we end up in a partially visible line, let's
11735 make it fully visible, except when it's taller
11736 than the window, in which case we can't do much
11739 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11743 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
11744 if (!cursor_row_fully_visible_p (w
, 0, 1))
11745 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11747 rc
= CURSOR_MOVEMENT_SUCCESS
;
11751 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11754 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
11755 rc
= CURSOR_MOVEMENT_SUCCESS
;
11764 set_vertical_scroll_bar (w
)
11767 int start
, end
, whole
;
11769 /* Calculate the start and end positions for the current window.
11770 At some point, it would be nice to choose between scrollbars
11771 which reflect the whole buffer size, with special markers
11772 indicating narrowing, and scrollbars which reflect only the
11775 Note that mini-buffers sometimes aren't displaying any text. */
11776 if (!MINI_WINDOW_P (w
)
11777 || (w
== XWINDOW (minibuf_window
)
11778 && NILP (echo_area_buffer
[0])))
11780 struct buffer
*buf
= XBUFFER (w
->buffer
);
11781 whole
= BUF_ZV (buf
) - BUF_BEGV (buf
);
11782 start
= marker_position (w
->start
) - BUF_BEGV (buf
);
11783 /* I don't think this is guaranteed to be right. For the
11784 moment, we'll pretend it is. */
11785 end
= BUF_Z (buf
) - XFASTINT (w
->window_end_pos
) - BUF_BEGV (buf
);
11789 if (whole
< (end
- start
))
11790 whole
= end
- start
;
11793 start
= end
= whole
= 0;
11795 /* Indicate what this scroll bar ought to be displaying now. */
11796 set_vertical_scroll_bar_hook (w
, end
- start
, whole
, start
);
11800 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
11801 selected_window is redisplayed.
11803 We can return without actually redisplaying the window if
11804 fonts_changed_p is nonzero. In that case, redisplay_internal will
11808 redisplay_window (window
, just_this_one_p
)
11809 Lisp_Object window
;
11810 int just_this_one_p
;
11812 struct window
*w
= XWINDOW (window
);
11813 struct frame
*f
= XFRAME (w
->frame
);
11814 struct buffer
*buffer
= XBUFFER (w
->buffer
);
11815 struct buffer
*old
= current_buffer
;
11816 struct text_pos lpoint
, opoint
, startp
;
11817 int update_mode_line
;
11820 /* Record it now because it's overwritten. */
11821 int current_matrix_up_to_date_p
= 0;
11822 int used_current_matrix_p
= 0;
11823 /* This is less strict than current_matrix_up_to_date_p.
11824 It indictes that the buffer contents and narrowing are unchanged. */
11825 int buffer_unchanged_p
= 0;
11826 int temp_scroll_step
= 0;
11827 int count
= SPECPDL_INDEX ();
11829 int centering_position
= -1;
11830 int last_line_misfit
= 0;
11832 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
11835 /* W must be a leaf window here. */
11836 xassert (!NILP (w
->buffer
));
11838 *w
->desired_matrix
->method
= 0;
11841 specbind (Qinhibit_point_motion_hooks
, Qt
);
11843 reconsider_clip_changes (w
, buffer
);
11845 /* Has the mode line to be updated? */
11846 update_mode_line
= (!NILP (w
->update_mode_line
)
11847 || update_mode_lines
11848 || buffer
->clip_changed
11849 || buffer
->prevent_redisplay_optimizations_p
);
11851 if (MINI_WINDOW_P (w
))
11853 if (w
== XWINDOW (echo_area_window
)
11854 && !NILP (echo_area_buffer
[0]))
11856 if (update_mode_line
)
11857 /* We may have to update a tty frame's menu bar or a
11858 tool-bar. Example `M-x C-h C-h C-g'. */
11859 goto finish_menu_bars
;
11861 /* We've already displayed the echo area glyphs in this window. */
11862 goto finish_scroll_bars
;
11864 else if ((w
!= XWINDOW (minibuf_window
)
11865 || minibuf_level
== 0)
11866 /* When buffer is nonempty, redisplay window normally. */
11867 && BUF_Z (XBUFFER (w
->buffer
)) == BUF_BEG (XBUFFER (w
->buffer
))
11868 /* Quail displays non-mini buffers in minibuffer window.
11869 In that case, redisplay the window normally. */
11870 && !NILP (Fmemq (w
->buffer
, Vminibuffer_list
)))
11872 /* W is a mini-buffer window, but it's not active, so clear
11874 int yb
= window_text_bottom_y (w
);
11875 struct glyph_row
*row
;
11878 for (y
= 0, row
= w
->desired_matrix
->rows
;
11880 y
+= row
->height
, ++row
)
11881 blank_row (w
, row
, y
);
11882 goto finish_scroll_bars
;
11885 clear_glyph_matrix (w
->desired_matrix
);
11888 /* Otherwise set up data on this window; select its buffer and point
11890 /* Really select the buffer, for the sake of buffer-local
11892 set_buffer_internal_1 (XBUFFER (w
->buffer
));
11893 SET_TEXT_POS (opoint
, PT
, PT_BYTE
);
11895 current_matrix_up_to_date_p
11896 = (!NILP (w
->window_end_valid
)
11897 && !current_buffer
->clip_changed
11898 && !current_buffer
->prevent_redisplay_optimizations_p
11899 && XFASTINT (w
->last_modified
) >= MODIFF
11900 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
);
11903 = (!NILP (w
->window_end_valid
)
11904 && !current_buffer
->clip_changed
11905 && XFASTINT (w
->last_modified
) >= MODIFF
11906 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
);
11908 /* When windows_or_buffers_changed is non-zero, we can't rely on
11909 the window end being valid, so set it to nil there. */
11910 if (windows_or_buffers_changed
)
11912 /* If window starts on a continuation line, maybe adjust the
11913 window start in case the window's width changed. */
11914 if (XMARKER (w
->start
)->buffer
== current_buffer
)
11915 compute_window_start_on_continuation_line (w
);
11917 w
->window_end_valid
= Qnil
;
11920 /* Some sanity checks. */
11921 CHECK_WINDOW_END (w
);
11922 if (Z
== Z_BYTE
&& CHARPOS (opoint
) != BYTEPOS (opoint
))
11924 if (BYTEPOS (opoint
) < CHARPOS (opoint
))
11927 /* If %c is in mode line, update it if needed. */
11928 if (!NILP (w
->column_number_displayed
)
11929 /* This alternative quickly identifies a common case
11930 where no change is needed. */
11931 && !(PT
== XFASTINT (w
->last_point
)
11932 && XFASTINT (w
->last_modified
) >= MODIFF
11933 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
)
11934 && (XFASTINT (w
->column_number_displayed
)
11935 != (int) current_column ())) /* iftc */
11936 update_mode_line
= 1;
11938 /* Count number of windows showing the selected buffer. An indirect
11939 buffer counts as its base buffer. */
11940 if (!just_this_one_p
)
11942 struct buffer
*current_base
, *window_base
;
11943 current_base
= current_buffer
;
11944 window_base
= XBUFFER (XWINDOW (selected_window
)->buffer
);
11945 if (current_base
->base_buffer
)
11946 current_base
= current_base
->base_buffer
;
11947 if (window_base
->base_buffer
)
11948 window_base
= window_base
->base_buffer
;
11949 if (current_base
== window_base
)
11953 /* Point refers normally to the selected window. For any other
11954 window, set up appropriate value. */
11955 if (!EQ (window
, selected_window
))
11957 int new_pt
= XMARKER (w
->pointm
)->charpos
;
11958 int new_pt_byte
= marker_byte_position (w
->pointm
);
11962 new_pt_byte
= BEGV_BYTE
;
11963 set_marker_both (w
->pointm
, Qnil
, BEGV
, BEGV_BYTE
);
11965 else if (new_pt
> (ZV
- 1))
11968 new_pt_byte
= ZV_BYTE
;
11969 set_marker_both (w
->pointm
, Qnil
, ZV
, ZV_BYTE
);
11972 /* We don't use SET_PT so that the point-motion hooks don't run. */
11973 TEMP_SET_PT_BOTH (new_pt
, new_pt_byte
);
11976 /* If any of the character widths specified in the display table
11977 have changed, invalidate the width run cache. It's true that
11978 this may be a bit late to catch such changes, but the rest of
11979 redisplay goes (non-fatally) haywire when the display table is
11980 changed, so why should we worry about doing any better? */
11981 if (current_buffer
->width_run_cache
)
11983 struct Lisp_Char_Table
*disptab
= buffer_display_table ();
11985 if (! disptab_matches_widthtab (disptab
,
11986 XVECTOR (current_buffer
->width_table
)))
11988 invalidate_region_cache (current_buffer
,
11989 current_buffer
->width_run_cache
,
11991 recompute_width_table (current_buffer
, disptab
);
11995 /* If window-start is screwed up, choose a new one. */
11996 if (XMARKER (w
->start
)->buffer
!= current_buffer
)
11999 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
12001 /* If someone specified a new starting point but did not insist,
12002 check whether it can be used. */
12003 if (!NILP (w
->optional_new_start
)
12004 && CHARPOS (startp
) >= BEGV
12005 && CHARPOS (startp
) <= ZV
)
12007 w
->optional_new_start
= Qnil
;
12008 start_display (&it
, w
, startp
);
12009 move_it_to (&it
, PT
, 0, it
.last_visible_y
, -1,
12010 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
12011 if (IT_CHARPOS (it
) == PT
)
12012 w
->force_start
= Qt
;
12013 /* IT may overshoot PT if text at PT is invisible. */
12014 else if (IT_CHARPOS (it
) > PT
&& CHARPOS (startp
) <= PT
)
12015 w
->force_start
= Qt
;
12020 /* Handle case where place to start displaying has been specified,
12021 unless the specified location is outside the accessible range. */
12022 if (!NILP (w
->force_start
)
12023 || w
->frozen_window_start_p
)
12025 /* We set this later on if we have to adjust point. */
12028 w
->force_start
= Qnil
;
12030 w
->window_end_valid
= Qnil
;
12032 /* Forget any recorded base line for line number display. */
12033 if (!buffer_unchanged_p
)
12034 w
->base_line_number
= Qnil
;
12036 /* Redisplay the mode line. Select the buffer properly for that.
12037 Also, run the hook window-scroll-functions
12038 because we have scrolled. */
12039 /* Note, we do this after clearing force_start because
12040 if there's an error, it is better to forget about force_start
12041 than to get into an infinite loop calling the hook functions
12042 and having them get more errors. */
12043 if (!update_mode_line
12044 || ! NILP (Vwindow_scroll_functions
))
12046 update_mode_line
= 1;
12047 w
->update_mode_line
= Qt
;
12048 startp
= run_window_scroll_functions (window
, startp
);
12051 w
->last_modified
= make_number (0);
12052 w
->last_overlay_modified
= make_number (0);
12053 if (CHARPOS (startp
) < BEGV
)
12054 SET_TEXT_POS (startp
, BEGV
, BEGV_BYTE
);
12055 else if (CHARPOS (startp
) > ZV
)
12056 SET_TEXT_POS (startp
, ZV
, ZV_BYTE
);
12058 /* Redisplay, then check if cursor has been set during the
12059 redisplay. Give up if new fonts were loaded. */
12060 if (!try_window (window
, startp
))
12062 w
->force_start
= Qt
;
12063 clear_glyph_matrix (w
->desired_matrix
);
12064 goto need_larger_matrices
;
12067 if (w
->cursor
.vpos
< 0 && !w
->frozen_window_start_p
)
12069 /* If point does not appear, try to move point so it does
12070 appear. The desired matrix has been built above, so we
12071 can use it here. */
12072 new_vpos
= window_box_height (w
) / 2;
12075 if (!cursor_row_fully_visible_p (w
, 0, 0))
12077 /* Point does appear, but on a line partly visible at end of window.
12078 Move it back to a fully-visible line. */
12079 new_vpos
= window_box_height (w
);
12082 /* If we need to move point for either of the above reasons,
12083 now actually do it. */
12086 struct glyph_row
*row
;
12088 row
= MATRIX_FIRST_TEXT_ROW (w
->desired_matrix
);
12089 while (MATRIX_ROW_BOTTOM_Y (row
) < new_vpos
)
12092 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row
),
12093 MATRIX_ROW_START_BYTEPOS (row
));
12095 if (w
!= XWINDOW (selected_window
))
12096 set_marker_both (w
->pointm
, Qnil
, PT
, PT_BYTE
);
12097 else if (current_buffer
== old
)
12098 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
12100 set_cursor_from_row (w
, row
, w
->desired_matrix
, 0, 0, 0, 0);
12102 /* If we are highlighting the region, then we just changed
12103 the region, so redisplay to show it. */
12104 if (!NILP (Vtransient_mark_mode
)
12105 && !NILP (current_buffer
->mark_active
))
12107 clear_glyph_matrix (w
->desired_matrix
);
12108 if (!try_window (window
, startp
))
12109 goto need_larger_matrices
;
12114 debug_method_add (w
, "forced window start");
12119 /* Handle case where text has not changed, only point, and it has
12120 not moved off the frame, and we are not retrying after hscroll.
12121 (current_matrix_up_to_date_p is nonzero when retrying.) */
12122 if (current_matrix_up_to_date_p
12123 && (rc
= try_cursor_movement (window
, startp
, &temp_scroll_step
),
12124 rc
!= CURSOR_MOVEMENT_CANNOT_BE_USED
))
12128 case CURSOR_MOVEMENT_SUCCESS
:
12129 used_current_matrix_p
= 1;
12132 #if 0 /* try_cursor_movement never returns this value. */
12133 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES
:
12134 goto need_larger_matrices
;
12137 case CURSOR_MOVEMENT_MUST_SCROLL
:
12138 goto try_to_scroll
;
12144 /* If current starting point was originally the beginning of a line
12145 but no longer is, find a new starting point. */
12146 else if (!NILP (w
->start_at_line_beg
)
12147 && !(CHARPOS (startp
) <= BEGV
12148 || FETCH_BYTE (BYTEPOS (startp
) - 1) == '\n'))
12151 debug_method_add (w
, "recenter 1");
12156 /* Try scrolling with try_window_id. Value is > 0 if update has
12157 been done, it is -1 if we know that the same window start will
12158 not work. It is 0 if unsuccessful for some other reason. */
12159 else if ((tem
= try_window_id (w
)) != 0)
12162 debug_method_add (w
, "try_window_id %d", tem
);
12165 if (fonts_changed_p
)
12166 goto need_larger_matrices
;
12170 /* Otherwise try_window_id has returned -1 which means that we
12171 don't want the alternative below this comment to execute. */
12173 else if (CHARPOS (startp
) >= BEGV
12174 && CHARPOS (startp
) <= ZV
12175 && PT
>= CHARPOS (startp
)
12176 && (CHARPOS (startp
) < ZV
12177 /* Avoid starting at end of buffer. */
12178 || CHARPOS (startp
) == BEGV
12179 || (XFASTINT (w
->last_modified
) >= MODIFF
12180 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
)))
12183 debug_method_add (w
, "same window start");
12186 /* Try to redisplay starting at same place as before.
12187 If point has not moved off frame, accept the results. */
12188 if (!current_matrix_up_to_date_p
12189 /* Don't use try_window_reusing_current_matrix in this case
12190 because a window scroll function can have changed the
12192 || !NILP (Vwindow_scroll_functions
)
12193 || MINI_WINDOW_P (w
)
12194 || !(used_current_matrix_p
12195 = try_window_reusing_current_matrix (w
)))
12197 IF_DEBUG (debug_method_add (w
, "1"));
12198 try_window (window
, startp
);
12201 if (fonts_changed_p
)
12202 goto need_larger_matrices
;
12204 if (w
->cursor
.vpos
>= 0)
12206 if (!just_this_one_p
12207 || current_buffer
->clip_changed
12208 || BEG_UNCHANGED
< CHARPOS (startp
))
12209 /* Forget any recorded base line for line number display. */
12210 w
->base_line_number
= Qnil
;
12212 if (!cursor_row_fully_visible_p (w
, 1, 0))
12214 clear_glyph_matrix (w
->desired_matrix
);
12215 last_line_misfit
= 1;
12217 /* Drop through and scroll. */
12222 clear_glyph_matrix (w
->desired_matrix
);
12227 w
->last_modified
= make_number (0);
12228 w
->last_overlay_modified
= make_number (0);
12230 /* Redisplay the mode line. Select the buffer properly for that. */
12231 if (!update_mode_line
)
12233 update_mode_line
= 1;
12234 w
->update_mode_line
= Qt
;
12237 /* Try to scroll by specified few lines. */
12238 if ((scroll_conservatively
12240 || temp_scroll_step
12241 || NUMBERP (current_buffer
->scroll_up_aggressively
)
12242 || NUMBERP (current_buffer
->scroll_down_aggressively
))
12243 && !current_buffer
->clip_changed
12244 && CHARPOS (startp
) >= BEGV
12245 && CHARPOS (startp
) <= ZV
)
12247 /* The function returns -1 if new fonts were loaded, 1 if
12248 successful, 0 if not successful. */
12249 int rc
= try_scrolling (window
, just_this_one_p
,
12250 scroll_conservatively
,
12252 temp_scroll_step
, last_line_misfit
);
12255 case SCROLLING_SUCCESS
:
12258 case SCROLLING_NEED_LARGER_MATRICES
:
12259 goto need_larger_matrices
;
12261 case SCROLLING_FAILED
:
12269 /* Finally, just choose place to start which centers point */
12272 if (centering_position
< 0)
12273 centering_position
= window_box_height (w
) / 2;
12276 debug_method_add (w
, "recenter");
12279 /* w->vscroll = 0; */
12281 /* Forget any previously recorded base line for line number display. */
12282 if (!buffer_unchanged_p
)
12283 w
->base_line_number
= Qnil
;
12285 /* Move backward half the height of the window. */
12286 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
12287 it
.current_y
= it
.last_visible_y
;
12288 move_it_vertically_backward (&it
, centering_position
);
12289 xassert (IT_CHARPOS (it
) >= BEGV
);
12291 /* The function move_it_vertically_backward may move over more
12292 than the specified y-distance. If it->w is small, e.g. a
12293 mini-buffer window, we may end up in front of the window's
12294 display area. Start displaying at the start of the line
12295 containing PT in this case. */
12296 if (it
.current_y
<= 0)
12298 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
12299 move_it_vertically_backward (&it
, 0);
12301 /* I think this assert is bogus if buffer contains
12302 invisible text or images. KFS. */
12303 xassert (IT_CHARPOS (it
) <= PT
);
12308 it
.current_x
= it
.hpos
= 0;
12310 /* Set startp here explicitly in case that helps avoid an infinite loop
12311 in case the window-scroll-functions functions get errors. */
12312 set_marker_both (w
->start
, Qnil
, IT_CHARPOS (it
), IT_BYTEPOS (it
));
12314 /* Run scroll hooks. */
12315 startp
= run_window_scroll_functions (window
, it
.current
.pos
);
12317 /* Redisplay the window. */
12318 if (!current_matrix_up_to_date_p
12319 || windows_or_buffers_changed
12320 || cursor_type_changed
12321 /* Don't use try_window_reusing_current_matrix in this case
12322 because it can have changed the buffer. */
12323 || !NILP (Vwindow_scroll_functions
)
12324 || !just_this_one_p
12325 || MINI_WINDOW_P (w
)
12326 || !(used_current_matrix_p
12327 = try_window_reusing_current_matrix (w
)))
12328 try_window (window
, startp
);
12330 /* If new fonts have been loaded (due to fontsets), give up. We
12331 have to start a new redisplay since we need to re-adjust glyph
12333 if (fonts_changed_p
)
12334 goto need_larger_matrices
;
12336 /* If cursor did not appear assume that the middle of the window is
12337 in the first line of the window. Do it again with the next line.
12338 (Imagine a window of height 100, displaying two lines of height
12339 60. Moving back 50 from it->last_visible_y will end in the first
12341 if (w
->cursor
.vpos
< 0)
12343 if (!NILP (w
->window_end_valid
)
12344 && PT
>= Z
- XFASTINT (w
->window_end_pos
))
12346 clear_glyph_matrix (w
->desired_matrix
);
12347 move_it_by_lines (&it
, 1, 0);
12348 try_window (window
, it
.current
.pos
);
12350 else if (PT
< IT_CHARPOS (it
))
12352 clear_glyph_matrix (w
->desired_matrix
);
12353 move_it_by_lines (&it
, -1, 0);
12354 try_window (window
, it
.current
.pos
);
12358 /* Not much we can do about it. */
12362 /* Consider the following case: Window starts at BEGV, there is
12363 invisible, intangible text at BEGV, so that display starts at
12364 some point START > BEGV. It can happen that we are called with
12365 PT somewhere between BEGV and START. Try to handle that case. */
12366 if (w
->cursor
.vpos
< 0)
12368 struct glyph_row
*row
= w
->current_matrix
->rows
;
12369 if (row
->mode_line_p
)
12371 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
12374 if (!cursor_row_fully_visible_p (w
, 0, 0))
12376 /* If vscroll is enabled, disable it and try again. */
12380 clear_glyph_matrix (w
->desired_matrix
);
12384 /* If centering point failed to make the whole line visible,
12385 put point at the top instead. That has to make the whole line
12386 visible, if it can be done. */
12387 if (centering_position
== 0)
12390 clear_glyph_matrix (w
->desired_matrix
);
12391 centering_position
= 0;
12397 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
12398 w
->start_at_line_beg
= ((CHARPOS (startp
) == BEGV
12399 || FETCH_BYTE (BYTEPOS (startp
) - 1) == '\n')
12402 /* Display the mode line, if we must. */
12403 if ((update_mode_line
12404 /* If window not full width, must redo its mode line
12405 if (a) the window to its side is being redone and
12406 (b) we do a frame-based redisplay. This is a consequence
12407 of how inverted lines are drawn in frame-based redisplay. */
12408 || (!just_this_one_p
12409 && !FRAME_WINDOW_P (f
)
12410 && !WINDOW_FULL_WIDTH_P (w
))
12411 /* Line number to display. */
12412 || INTEGERP (w
->base_line_pos
)
12413 /* Column number is displayed and different from the one displayed. */
12414 || (!NILP (w
->column_number_displayed
)
12415 && (XFASTINT (w
->column_number_displayed
)
12416 != (int) current_column ()))) /* iftc */
12417 /* This means that the window has a mode line. */
12418 && (WINDOW_WANTS_MODELINE_P (w
)
12419 || WINDOW_WANTS_HEADER_LINE_P (w
)))
12421 display_mode_lines (w
);
12423 /* If mode line height has changed, arrange for a thorough
12424 immediate redisplay using the correct mode line height. */
12425 if (WINDOW_WANTS_MODELINE_P (w
)
12426 && CURRENT_MODE_LINE_HEIGHT (w
) != DESIRED_MODE_LINE_HEIGHT (w
))
12428 fonts_changed_p
= 1;
12429 MATRIX_MODE_LINE_ROW (w
->current_matrix
)->height
12430 = DESIRED_MODE_LINE_HEIGHT (w
);
12433 /* If top line height has changed, arrange for a thorough
12434 immediate redisplay using the correct mode line height. */
12435 if (WINDOW_WANTS_HEADER_LINE_P (w
)
12436 && CURRENT_HEADER_LINE_HEIGHT (w
) != DESIRED_HEADER_LINE_HEIGHT (w
))
12438 fonts_changed_p
= 1;
12439 MATRIX_HEADER_LINE_ROW (w
->current_matrix
)->height
12440 = DESIRED_HEADER_LINE_HEIGHT (w
);
12443 if (fonts_changed_p
)
12444 goto need_larger_matrices
;
12447 if (!line_number_displayed
12448 && !BUFFERP (w
->base_line_pos
))
12450 w
->base_line_pos
= Qnil
;
12451 w
->base_line_number
= Qnil
;
12456 /* When we reach a frame's selected window, redo the frame's menu bar. */
12457 if (update_mode_line
12458 && EQ (FRAME_SELECTED_WINDOW (f
), window
))
12460 int redisplay_menu_p
= 0;
12461 int redisplay_tool_bar_p
= 0;
12463 if (FRAME_WINDOW_P (f
))
12465 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
12466 || defined (USE_GTK)
12467 redisplay_menu_p
= FRAME_EXTERNAL_MENU_BAR (f
);
12469 redisplay_menu_p
= FRAME_MENU_BAR_LINES (f
) > 0;
12473 redisplay_menu_p
= FRAME_MENU_BAR_LINES (f
) > 0;
12475 if (redisplay_menu_p
)
12476 display_menu_bar (w
);
12478 #ifdef HAVE_WINDOW_SYSTEM
12480 redisplay_tool_bar_p
= FRAME_EXTERNAL_TOOL_BAR (f
);
12482 redisplay_tool_bar_p
= WINDOWP (f
->tool_bar_window
)
12483 && (FRAME_TOOL_BAR_LINES (f
) > 0
12484 || auto_resize_tool_bars_p
);
12488 if (redisplay_tool_bar_p
)
12489 redisplay_tool_bar (f
);
12493 #ifdef HAVE_WINDOW_SYSTEM
12494 if (FRAME_WINDOW_P (f
)
12495 && update_window_fringes (w
, 0)
12496 && !just_this_one_p
12497 && (used_current_matrix_p
|| overlay_arrow_seen
)
12498 && !w
->pseudo_window_p
)
12502 if (draw_window_fringes (w
, 1))
12503 x_draw_vertical_border (w
);
12507 #endif /* HAVE_WINDOW_SYSTEM */
12509 /* We go to this label, with fonts_changed_p nonzero,
12510 if it is necessary to try again using larger glyph matrices.
12511 We have to redeem the scroll bar even in this case,
12512 because the loop in redisplay_internal expects that. */
12513 need_larger_matrices
:
12515 finish_scroll_bars
:
12517 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w
))
12519 /* Set the thumb's position and size. */
12520 set_vertical_scroll_bar (w
);
12522 /* Note that we actually used the scroll bar attached to this
12523 window, so it shouldn't be deleted at the end of redisplay. */
12524 redeem_scroll_bar_hook (w
);
12527 /* Restore current_buffer and value of point in it. */
12528 TEMP_SET_PT_BOTH (CHARPOS (opoint
), BYTEPOS (opoint
));
12529 set_buffer_internal_1 (old
);
12530 TEMP_SET_PT_BOTH (CHARPOS (lpoint
), BYTEPOS (lpoint
));
12532 unbind_to (count
, Qnil
);
12536 /* Build the complete desired matrix of WINDOW with a window start
12537 buffer position POS. Value is non-zero if successful. It is zero
12538 if fonts were loaded during redisplay which makes re-adjusting
12539 glyph matrices necessary. */
12542 try_window (window
, pos
)
12543 Lisp_Object window
;
12544 struct text_pos pos
;
12546 struct window
*w
= XWINDOW (window
);
12548 struct glyph_row
*last_text_row
= NULL
;
12550 /* Make POS the new window start. */
12551 set_marker_both (w
->start
, Qnil
, CHARPOS (pos
), BYTEPOS (pos
));
12553 /* Mark cursor position as unknown. No overlay arrow seen. */
12554 w
->cursor
.vpos
= -1;
12555 overlay_arrow_seen
= 0;
12557 /* Initialize iterator and info to start at POS. */
12558 start_display (&it
, w
, pos
);
12560 /* Display all lines of W. */
12561 while (it
.current_y
< it
.last_visible_y
)
12563 if (display_line (&it
))
12564 last_text_row
= it
.glyph_row
- 1;
12565 if (fonts_changed_p
)
12569 /* If bottom moved off end of frame, change mode line percentage. */
12570 if (XFASTINT (w
->window_end_pos
) <= 0
12571 && Z
!= IT_CHARPOS (it
))
12572 w
->update_mode_line
= Qt
;
12574 /* Set window_end_pos to the offset of the last character displayed
12575 on the window from the end of current_buffer. Set
12576 window_end_vpos to its row number. */
12579 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row
));
12580 w
->window_end_bytepos
12581 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
12583 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
12585 = make_number (MATRIX_ROW_VPOS (last_text_row
, w
->desired_matrix
));
12586 xassert (MATRIX_ROW (w
->desired_matrix
, XFASTINT (w
->window_end_vpos
))
12587 ->displays_text_p
);
12591 w
->window_end_bytepos
= Z_BYTE
- ZV_BYTE
;
12592 w
->window_end_pos
= make_number (Z
- ZV
);
12593 w
->window_end_vpos
= make_number (0);
12596 /* But that is not valid info until redisplay finishes. */
12597 w
->window_end_valid
= Qnil
;
12603 /************************************************************************
12604 Window redisplay reusing current matrix when buffer has not changed
12605 ************************************************************************/
12607 /* Try redisplay of window W showing an unchanged buffer with a
12608 different window start than the last time it was displayed by
12609 reusing its current matrix. Value is non-zero if successful.
12610 W->start is the new window start. */
12613 try_window_reusing_current_matrix (w
)
12616 struct frame
*f
= XFRAME (w
->frame
);
12617 struct glyph_row
*row
, *bottom_row
;
12620 struct text_pos start
, new_start
;
12621 int nrows_scrolled
, i
;
12622 struct glyph_row
*last_text_row
;
12623 struct glyph_row
*last_reused_text_row
;
12624 struct glyph_row
*start_row
;
12625 int start_vpos
, min_y
, max_y
;
12628 if (inhibit_try_window_reusing
)
12632 if (/* This function doesn't handle terminal frames. */
12633 !FRAME_WINDOW_P (f
)
12634 /* Don't try to reuse the display if windows have been split
12636 || windows_or_buffers_changed
12637 || cursor_type_changed
)
12640 /* Can't do this if region may have changed. */
12641 if ((!NILP (Vtransient_mark_mode
)
12642 && !NILP (current_buffer
->mark_active
))
12643 || !NILP (w
->region_showing
)
12644 || !NILP (Vshow_trailing_whitespace
))
12647 /* If top-line visibility has changed, give up. */
12648 if (WINDOW_WANTS_HEADER_LINE_P (w
)
12649 != MATRIX_HEADER_LINE_ROW (w
->current_matrix
)->mode_line_p
)
12652 /* Give up if old or new display is scrolled vertically. We could
12653 make this function handle this, but right now it doesn't. */
12654 start_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
12655 if (w
->vscroll
|| MATRIX_ROW_PARTIALLY_VISIBLE_P (w
, start_row
))
12658 /* The variable new_start now holds the new window start. The old
12659 start `start' can be determined from the current matrix. */
12660 SET_TEXT_POS_FROM_MARKER (new_start
, w
->start
);
12661 start
= start_row
->start
.pos
;
12662 start_vpos
= MATRIX_ROW_VPOS (start_row
, w
->current_matrix
);
12664 /* Clear the desired matrix for the display below. */
12665 clear_glyph_matrix (w
->desired_matrix
);
12667 if (CHARPOS (new_start
) <= CHARPOS (start
))
12671 /* Don't use this method if the display starts with an ellipsis
12672 displayed for invisible text. It's not easy to handle that case
12673 below, and it's certainly not worth the effort since this is
12674 not a frequent case. */
12675 if (in_ellipses_for_invisible_text_p (&start_row
->start
, w
))
12678 IF_DEBUG (debug_method_add (w
, "twu1"));
12680 /* Display up to a row that can be reused. The variable
12681 last_text_row is set to the last row displayed that displays
12682 text. Note that it.vpos == 0 if or if not there is a
12683 header-line; it's not the same as the MATRIX_ROW_VPOS! */
12684 start_display (&it
, w
, new_start
);
12685 first_row_y
= it
.current_y
;
12686 w
->cursor
.vpos
= -1;
12687 last_text_row
= last_reused_text_row
= NULL
;
12689 while (it
.current_y
< it
.last_visible_y
12690 && !fonts_changed_p
)
12692 /* If we have reached into the characters in the START row,
12693 that means the line boundaries have changed. So we
12694 can't start copying with the row START. Maybe it will
12695 work to start copying with the following row. */
12696 while (IT_CHARPOS (it
) > CHARPOS (start
))
12698 /* Advance to the next row as the "start". */
12700 start
= start_row
->start
.pos
;
12701 /* If there are no more rows to try, or just one, give up. */
12702 if (start_row
== MATRIX_MODE_LINE_ROW (w
->current_matrix
) - 1
12703 || w
->vscroll
|| MATRIX_ROW_PARTIALLY_VISIBLE_P (w
, start_row
)
12704 || CHARPOS (start
) == ZV
)
12706 clear_glyph_matrix (w
->desired_matrix
);
12710 start_vpos
= MATRIX_ROW_VPOS (start_row
, w
->current_matrix
);
12712 /* If we have reached alignment,
12713 we can copy the rest of the rows. */
12714 if (IT_CHARPOS (it
) == CHARPOS (start
))
12717 if (display_line (&it
))
12718 last_text_row
= it
.glyph_row
- 1;
12721 /* A value of current_y < last_visible_y means that we stopped
12722 at the previous window start, which in turn means that we
12723 have at least one reusable row. */
12724 if (it
.current_y
< it
.last_visible_y
)
12726 /* IT.vpos always starts from 0; it counts text lines. */
12727 nrows_scrolled
= it
.vpos
- (start_row
- MATRIX_FIRST_TEXT_ROW (w
->current_matrix
));
12729 /* Find PT if not already found in the lines displayed. */
12730 if (w
->cursor
.vpos
< 0)
12732 int dy
= it
.current_y
- start_row
->y
;
12734 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
12735 row
= row_containing_pos (w
, PT
, row
, NULL
, dy
);
12737 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0,
12738 dy
, nrows_scrolled
);
12741 clear_glyph_matrix (w
->desired_matrix
);
12746 /* Scroll the display. Do it before the current matrix is
12747 changed. The problem here is that update has not yet
12748 run, i.e. part of the current matrix is not up to date.
12749 scroll_run_hook will clear the cursor, and use the
12750 current matrix to get the height of the row the cursor is
12752 run
.current_y
= start_row
->y
;
12753 run
.desired_y
= it
.current_y
;
12754 run
.height
= it
.last_visible_y
- it
.current_y
;
12756 if (run
.height
> 0 && run
.current_y
!= run
.desired_y
)
12759 rif
->update_window_begin_hook (w
);
12760 rif
->clear_window_mouse_face (w
);
12761 rif
->scroll_run_hook (w
, &run
);
12762 rif
->update_window_end_hook (w
, 0, 0);
12766 /* Shift current matrix down by nrows_scrolled lines. */
12767 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
12768 rotate_matrix (w
->current_matrix
,
12770 MATRIX_ROW_VPOS (bottom_row
, w
->current_matrix
),
12773 /* Disable lines that must be updated. */
12774 for (i
= 0; i
< it
.vpos
; ++i
)
12775 (start_row
+ i
)->enabled_p
= 0;
12777 /* Re-compute Y positions. */
12778 min_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
12779 max_y
= it
.last_visible_y
;
12780 for (row
= start_row
+ nrows_scrolled
;
12784 row
->y
= it
.current_y
;
12785 row
->visible_height
= row
->height
;
12787 if (row
->y
< min_y
)
12788 row
->visible_height
-= min_y
- row
->y
;
12789 if (row
->y
+ row
->height
> max_y
)
12790 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
12791 row
->redraw_fringe_bitmaps_p
= 1;
12793 it
.current_y
+= row
->height
;
12795 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
12796 last_reused_text_row
= row
;
12797 if (MATRIX_ROW_BOTTOM_Y (row
) >= it
.last_visible_y
)
12801 /* Disable lines in the current matrix which are now
12802 below the window. */
12803 for (++row
; row
< bottom_row
; ++row
)
12804 row
->enabled_p
= 0;
12807 /* Update window_end_pos etc.; last_reused_text_row is the last
12808 reused row from the current matrix containing text, if any.
12809 The value of last_text_row is the last displayed line
12810 containing text. */
12811 if (last_reused_text_row
)
12813 w
->window_end_bytepos
12814 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_reused_text_row
);
12816 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_reused_text_row
));
12818 = make_number (MATRIX_ROW_VPOS (last_reused_text_row
,
12819 w
->current_matrix
));
12821 else if (last_text_row
)
12823 w
->window_end_bytepos
12824 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
12826 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
12828 = make_number (MATRIX_ROW_VPOS (last_text_row
, w
->desired_matrix
));
12832 /* This window must be completely empty. */
12833 w
->window_end_bytepos
= Z_BYTE
- ZV_BYTE
;
12834 w
->window_end_pos
= make_number (Z
- ZV
);
12835 w
->window_end_vpos
= make_number (0);
12837 w
->window_end_valid
= Qnil
;
12839 /* Update hint: don't try scrolling again in update_window. */
12840 w
->desired_matrix
->no_scrolling_p
= 1;
12843 debug_method_add (w
, "try_window_reusing_current_matrix 1");
12847 else if (CHARPOS (new_start
) > CHARPOS (start
))
12849 struct glyph_row
*pt_row
, *row
;
12850 struct glyph_row
*first_reusable_row
;
12851 struct glyph_row
*first_row_to_display
;
12853 int yb
= window_text_bottom_y (w
);
12855 /* Find the row starting at new_start, if there is one. Don't
12856 reuse a partially visible line at the end. */
12857 first_reusable_row
= start_row
;
12858 while (first_reusable_row
->enabled_p
12859 && MATRIX_ROW_BOTTOM_Y (first_reusable_row
) < yb
12860 && (MATRIX_ROW_START_CHARPOS (first_reusable_row
)
12861 < CHARPOS (new_start
)))
12862 ++first_reusable_row
;
12864 /* Give up if there is no row to reuse. */
12865 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row
) >= yb
12866 || !first_reusable_row
->enabled_p
12867 || (MATRIX_ROW_START_CHARPOS (first_reusable_row
)
12868 != CHARPOS (new_start
)))
12871 /* We can reuse fully visible rows beginning with
12872 first_reusable_row to the end of the window. Set
12873 first_row_to_display to the first row that cannot be reused.
12874 Set pt_row to the row containing point, if there is any. */
12876 for (first_row_to_display
= first_reusable_row
;
12877 MATRIX_ROW_BOTTOM_Y (first_row_to_display
) < yb
;
12878 ++first_row_to_display
)
12880 if (PT
>= MATRIX_ROW_START_CHARPOS (first_row_to_display
)
12881 && PT
< MATRIX_ROW_END_CHARPOS (first_row_to_display
))
12882 pt_row
= first_row_to_display
;
12885 /* Start displaying at the start of first_row_to_display. */
12886 xassert (first_row_to_display
->y
< yb
);
12887 init_to_row_start (&it
, w
, first_row_to_display
);
12889 nrows_scrolled
= (MATRIX_ROW_VPOS (first_reusable_row
, w
->current_matrix
)
12891 it
.vpos
= (MATRIX_ROW_VPOS (first_row_to_display
, w
->current_matrix
)
12893 it
.current_y
= (first_row_to_display
->y
- first_reusable_row
->y
12894 + WINDOW_HEADER_LINE_HEIGHT (w
));
12896 /* Display lines beginning with first_row_to_display in the
12897 desired matrix. Set last_text_row to the last row displayed
12898 that displays text. */
12899 it
.glyph_row
= MATRIX_ROW (w
->desired_matrix
, it
.vpos
);
12900 if (pt_row
== NULL
)
12901 w
->cursor
.vpos
= -1;
12902 last_text_row
= NULL
;
12903 while (it
.current_y
< it
.last_visible_y
&& !fonts_changed_p
)
12904 if (display_line (&it
))
12905 last_text_row
= it
.glyph_row
- 1;
12907 /* Give up If point isn't in a row displayed or reused. */
12908 if (w
->cursor
.vpos
< 0)
12910 clear_glyph_matrix (w
->desired_matrix
);
12914 /* If point is in a reused row, adjust y and vpos of the cursor
12918 w
->cursor
.vpos
-= nrows_scrolled
;
12919 w
->cursor
.y
-= first_reusable_row
->y
- start_row
->y
;
12922 /* Scroll the display. */
12923 run
.current_y
= first_reusable_row
->y
;
12924 run
.desired_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
12925 run
.height
= it
.last_visible_y
- run
.current_y
;
12926 dy
= run
.current_y
- run
.desired_y
;
12931 rif
->update_window_begin_hook (w
);
12932 rif
->clear_window_mouse_face (w
);
12933 rif
->scroll_run_hook (w
, &run
);
12934 rif
->update_window_end_hook (w
, 0, 0);
12938 /* Adjust Y positions of reused rows. */
12939 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
12940 min_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
12941 max_y
= it
.last_visible_y
;
12942 for (row
= first_reusable_row
; row
< first_row_to_display
; ++row
)
12945 row
->visible_height
= row
->height
;
12946 if (row
->y
< min_y
)
12947 row
->visible_height
-= min_y
- row
->y
;
12948 if (row
->y
+ row
->height
> max_y
)
12949 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
12950 row
->redraw_fringe_bitmaps_p
= 1;
12953 /* Scroll the current matrix. */
12954 xassert (nrows_scrolled
> 0);
12955 rotate_matrix (w
->current_matrix
,
12957 MATRIX_ROW_VPOS (bottom_row
, w
->current_matrix
),
12960 /* Disable rows not reused. */
12961 for (row
-= nrows_scrolled
; row
< bottom_row
; ++row
)
12962 row
->enabled_p
= 0;
12964 /* Point may have moved to a different line, so we cannot assume that
12965 the previous cursor position is valid; locate the correct row. */
12968 for (row
= MATRIX_ROW (w
->current_matrix
, w
->cursor
.vpos
);
12969 row
< bottom_row
&& PT
>= MATRIX_ROW_END_CHARPOS (row
);
12973 w
->cursor
.y
= row
->y
;
12975 if (row
< bottom_row
)
12977 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + w
->cursor
.hpos
;
12978 while (glyph
->charpos
< PT
)
12981 w
->cursor
.x
+= glyph
->pixel_width
;
12987 /* Adjust window end. A null value of last_text_row means that
12988 the window end is in reused rows which in turn means that
12989 only its vpos can have changed. */
12992 w
->window_end_bytepos
12993 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
12995 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
12997 = make_number (MATRIX_ROW_VPOS (last_text_row
, w
->desired_matrix
));
13002 = make_number (XFASTINT (w
->window_end_vpos
) - nrows_scrolled
);
13005 w
->window_end_valid
= Qnil
;
13006 w
->desired_matrix
->no_scrolling_p
= 1;
13009 debug_method_add (w
, "try_window_reusing_current_matrix 2");
13019 /************************************************************************
13020 Window redisplay reusing current matrix when buffer has changed
13021 ************************************************************************/
13023 static struct glyph_row
*find_last_unchanged_at_beg_row
P_ ((struct window
*));
13024 static struct glyph_row
*find_first_unchanged_at_end_row
P_ ((struct window
*,
13026 static struct glyph_row
*
13027 find_last_row_displaying_text
P_ ((struct glyph_matrix
*, struct it
*,
13028 struct glyph_row
*));
13031 /* Return the last row in MATRIX displaying text. If row START is
13032 non-null, start searching with that row. IT gives the dimensions
13033 of the display. Value is null if matrix is empty; otherwise it is
13034 a pointer to the row found. */
13036 static struct glyph_row
*
13037 find_last_row_displaying_text (matrix
, it
, start
)
13038 struct glyph_matrix
*matrix
;
13040 struct glyph_row
*start
;
13042 struct glyph_row
*row
, *row_found
;
13044 /* Set row_found to the last row in IT->w's current matrix
13045 displaying text. The loop looks funny but think of partially
13048 row
= start
? start
: MATRIX_FIRST_TEXT_ROW (matrix
);
13049 while (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
13051 xassert (row
->enabled_p
);
13053 if (MATRIX_ROW_BOTTOM_Y (row
) >= it
->last_visible_y
)
13062 /* Return the last row in the current matrix of W that is not affected
13063 by changes at the start of current_buffer that occurred since W's
13064 current matrix was built. Value is null if no such row exists.
13066 BEG_UNCHANGED us the number of characters unchanged at the start of
13067 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
13068 first changed character in current_buffer. Characters at positions <
13069 BEG + BEG_UNCHANGED are at the same buffer positions as they were
13070 when the current matrix was built. */
13072 static struct glyph_row
*
13073 find_last_unchanged_at_beg_row (w
)
13076 int first_changed_pos
= BEG
+ BEG_UNCHANGED
;
13077 struct glyph_row
*row
;
13078 struct glyph_row
*row_found
= NULL
;
13079 int yb
= window_text_bottom_y (w
);
13081 /* Find the last row displaying unchanged text. */
13082 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
13083 while (MATRIX_ROW_DISPLAYS_TEXT_P (row
)
13084 && MATRIX_ROW_START_CHARPOS (row
) < first_changed_pos
)
13086 if (/* If row ends before first_changed_pos, it is unchanged,
13087 except in some case. */
13088 MATRIX_ROW_END_CHARPOS (row
) <= first_changed_pos
13089 /* When row ends in ZV and we write at ZV it is not
13091 && !row
->ends_at_zv_p
13092 /* When first_changed_pos is the end of a continued line,
13093 row is not unchanged because it may be no longer
13095 && !(MATRIX_ROW_END_CHARPOS (row
) == first_changed_pos
13096 && (row
->continued_p
13097 || row
->exact_window_width_line_p
)))
13100 /* Stop if last visible row. */
13101 if (MATRIX_ROW_BOTTOM_Y (row
) >= yb
)
13111 /* Find the first glyph row in the current matrix of W that is not
13112 affected by changes at the end of current_buffer since the
13113 time W's current matrix was built.
13115 Return in *DELTA the number of chars by which buffer positions in
13116 unchanged text at the end of current_buffer must be adjusted.
13118 Return in *DELTA_BYTES the corresponding number of bytes.
13120 Value is null if no such row exists, i.e. all rows are affected by
13123 static struct glyph_row
*
13124 find_first_unchanged_at_end_row (w
, delta
, delta_bytes
)
13126 int *delta
, *delta_bytes
;
13128 struct glyph_row
*row
;
13129 struct glyph_row
*row_found
= NULL
;
13131 *delta
= *delta_bytes
= 0;
13133 /* Display must not have been paused, otherwise the current matrix
13134 is not up to date. */
13135 if (NILP (w
->window_end_valid
))
13138 /* A value of window_end_pos >= END_UNCHANGED means that the window
13139 end is in the range of changed text. If so, there is no
13140 unchanged row at the end of W's current matrix. */
13141 if (XFASTINT (w
->window_end_pos
) >= END_UNCHANGED
)
13144 /* Set row to the last row in W's current matrix displaying text. */
13145 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
13147 /* If matrix is entirely empty, no unchanged row exists. */
13148 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
13150 /* The value of row is the last glyph row in the matrix having a
13151 meaningful buffer position in it. The end position of row
13152 corresponds to window_end_pos. This allows us to translate
13153 buffer positions in the current matrix to current buffer
13154 positions for characters not in changed text. */
13155 int Z_old
= MATRIX_ROW_END_CHARPOS (row
) + XFASTINT (w
->window_end_pos
);
13156 int Z_BYTE_old
= MATRIX_ROW_END_BYTEPOS (row
) + w
->window_end_bytepos
;
13157 int last_unchanged_pos
, last_unchanged_pos_old
;
13158 struct glyph_row
*first_text_row
13159 = MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
13161 *delta
= Z
- Z_old
;
13162 *delta_bytes
= Z_BYTE
- Z_BYTE_old
;
13164 /* Set last_unchanged_pos to the buffer position of the last
13165 character in the buffer that has not been changed. Z is the
13166 index + 1 of the last character in current_buffer, i.e. by
13167 subtracting END_UNCHANGED we get the index of the last
13168 unchanged character, and we have to add BEG to get its buffer
13170 last_unchanged_pos
= Z
- END_UNCHANGED
+ BEG
;
13171 last_unchanged_pos_old
= last_unchanged_pos
- *delta
;
13173 /* Search backward from ROW for a row displaying a line that
13174 starts at a minimum position >= last_unchanged_pos_old. */
13175 for (; row
> first_text_row
; --row
)
13177 /* This used to abort, but it can happen.
13178 It is ok to just stop the search instead here. KFS. */
13179 if (!row
->enabled_p
|| !MATRIX_ROW_DISPLAYS_TEXT_P (row
))
13182 if (MATRIX_ROW_START_CHARPOS (row
) >= last_unchanged_pos_old
)
13187 if (row_found
&& !MATRIX_ROW_DISPLAYS_TEXT_P (row_found
))
13194 /* Make sure that glyph rows in the current matrix of window W
13195 reference the same glyph memory as corresponding rows in the
13196 frame's frame matrix. This function is called after scrolling W's
13197 current matrix on a terminal frame in try_window_id and
13198 try_window_reusing_current_matrix. */
13201 sync_frame_with_window_matrix_rows (w
)
13204 struct frame
*f
= XFRAME (w
->frame
);
13205 struct glyph_row
*window_row
, *window_row_end
, *frame_row
;
13207 /* Preconditions: W must be a leaf window and full-width. Its frame
13208 must have a frame matrix. */
13209 xassert (NILP (w
->hchild
) && NILP (w
->vchild
));
13210 xassert (WINDOW_FULL_WIDTH_P (w
));
13211 xassert (!FRAME_WINDOW_P (f
));
13213 /* If W is a full-width window, glyph pointers in W's current matrix
13214 have, by definition, to be the same as glyph pointers in the
13215 corresponding frame matrix. Note that frame matrices have no
13216 marginal areas (see build_frame_matrix). */
13217 window_row
= w
->current_matrix
->rows
;
13218 window_row_end
= window_row
+ w
->current_matrix
->nrows
;
13219 frame_row
= f
->current_matrix
->rows
+ WINDOW_TOP_EDGE_LINE (w
);
13220 while (window_row
< window_row_end
)
13222 struct glyph
*start
= window_row
->glyphs
[LEFT_MARGIN_AREA
];
13223 struct glyph
*end
= window_row
->glyphs
[LAST_AREA
];
13225 frame_row
->glyphs
[LEFT_MARGIN_AREA
] = start
;
13226 frame_row
->glyphs
[TEXT_AREA
] = start
;
13227 frame_row
->glyphs
[RIGHT_MARGIN_AREA
] = end
;
13228 frame_row
->glyphs
[LAST_AREA
] = end
;
13230 /* Disable frame rows whose corresponding window rows have
13231 been disabled in try_window_id. */
13232 if (!window_row
->enabled_p
)
13233 frame_row
->enabled_p
= 0;
13235 ++window_row
, ++frame_row
;
13240 /* Find the glyph row in window W containing CHARPOS. Consider all
13241 rows between START and END (not inclusive). END null means search
13242 all rows to the end of the display area of W. Value is the row
13243 containing CHARPOS or null. */
13246 row_containing_pos (w
, charpos
, start
, end
, dy
)
13249 struct glyph_row
*start
, *end
;
13252 struct glyph_row
*row
= start
;
13255 /* If we happen to start on a header-line, skip that. */
13256 if (row
->mode_line_p
)
13259 if ((end
&& row
>= end
) || !row
->enabled_p
)
13262 last_y
= window_text_bottom_y (w
) - dy
;
13266 /* Give up if we have gone too far. */
13267 if (end
&& row
>= end
)
13269 /* This formerly returned if they were equal.
13270 I think that both quantities are of a "last plus one" type;
13271 if so, when they are equal, the row is within the screen. -- rms. */
13272 if (MATRIX_ROW_BOTTOM_Y (row
) > last_y
)
13275 /* If it is in this row, return this row. */
13276 if (! (MATRIX_ROW_END_CHARPOS (row
) < charpos
13277 || (MATRIX_ROW_END_CHARPOS (row
) == charpos
13278 /* The end position of a row equals the start
13279 position of the next row. If CHARPOS is there, we
13280 would rather display it in the next line, except
13281 when this line ends in ZV. */
13282 && !row
->ends_at_zv_p
13283 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
)))
13284 && charpos
>= MATRIX_ROW_START_CHARPOS (row
))
13291 /* Try to redisplay window W by reusing its existing display. W's
13292 current matrix must be up to date when this function is called,
13293 i.e. window_end_valid must not be nil.
13297 1 if display has been updated
13298 0 if otherwise unsuccessful
13299 -1 if redisplay with same window start is known not to succeed
13301 The following steps are performed:
13303 1. Find the last row in the current matrix of W that is not
13304 affected by changes at the start of current_buffer. If no such row
13307 2. Find the first row in W's current matrix that is not affected by
13308 changes at the end of current_buffer. Maybe there is no such row.
13310 3. Display lines beginning with the row + 1 found in step 1 to the
13311 row found in step 2 or, if step 2 didn't find a row, to the end of
13314 4. If cursor is not known to appear on the window, give up.
13316 5. If display stopped at the row found in step 2, scroll the
13317 display and current matrix as needed.
13319 6. Maybe display some lines at the end of W, if we must. This can
13320 happen under various circumstances, like a partially visible line
13321 becoming fully visible, or because newly displayed lines are displayed
13322 in smaller font sizes.
13324 7. Update W's window end information. */
13330 struct frame
*f
= XFRAME (w
->frame
);
13331 struct glyph_matrix
*current_matrix
= w
->current_matrix
;
13332 struct glyph_matrix
*desired_matrix
= w
->desired_matrix
;
13333 struct glyph_row
*last_unchanged_at_beg_row
;
13334 struct glyph_row
*first_unchanged_at_end_row
;
13335 struct glyph_row
*row
;
13336 struct glyph_row
*bottom_row
;
13339 int delta
= 0, delta_bytes
= 0, stop_pos
, dvpos
, dy
;
13340 struct text_pos start_pos
;
13342 int first_unchanged_at_end_vpos
= 0;
13343 struct glyph_row
*last_text_row
, *last_text_row_at_end
;
13344 struct text_pos start
;
13345 int first_changed_charpos
, last_changed_charpos
;
13348 if (inhibit_try_window_id
)
13352 /* This is handy for debugging. */
13354 #define GIVE_UP(X) \
13356 fprintf (stderr, "try_window_id give up %d\n", (X)); \
13360 #define GIVE_UP(X) return 0
13363 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
13365 /* Don't use this for mini-windows because these can show
13366 messages and mini-buffers, and we don't handle that here. */
13367 if (MINI_WINDOW_P (w
))
13370 /* This flag is used to prevent redisplay optimizations. */
13371 if (windows_or_buffers_changed
|| cursor_type_changed
)
13374 /* Verify that narrowing has not changed.
13375 Also verify that we were not told to prevent redisplay optimizations.
13376 It would be nice to further
13377 reduce the number of cases where this prevents try_window_id. */
13378 if (current_buffer
->clip_changed
13379 || current_buffer
->prevent_redisplay_optimizations_p
)
13382 /* Window must either use window-based redisplay or be full width. */
13383 if (!FRAME_WINDOW_P (f
)
13384 && (!line_ins_del_ok
13385 || !WINDOW_FULL_WIDTH_P (w
)))
13388 /* Give up if point is not known NOT to appear in W. */
13389 if (PT
< CHARPOS (start
))
13392 /* Another way to prevent redisplay optimizations. */
13393 if (XFASTINT (w
->last_modified
) == 0)
13396 /* Verify that window is not hscrolled. */
13397 if (XFASTINT (w
->hscroll
) != 0)
13400 /* Verify that display wasn't paused. */
13401 if (NILP (w
->window_end_valid
))
13404 /* Can't use this if highlighting a region because a cursor movement
13405 will do more than just set the cursor. */
13406 if (!NILP (Vtransient_mark_mode
)
13407 && !NILP (current_buffer
->mark_active
))
13410 /* Likewise if highlighting trailing whitespace. */
13411 if (!NILP (Vshow_trailing_whitespace
))
13414 /* Likewise if showing a region. */
13415 if (!NILP (w
->region_showing
))
13418 /* Can use this if overlay arrow position and or string have changed. */
13419 if (overlay_arrows_changed_p ())
13423 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
13424 only if buffer has really changed. The reason is that the gap is
13425 initially at Z for freshly visited files. The code below would
13426 set end_unchanged to 0 in that case. */
13427 if (MODIFF
> SAVE_MODIFF
13428 /* This seems to happen sometimes after saving a buffer. */
13429 || BEG_UNCHANGED
+ END_UNCHANGED
> Z_BYTE
)
13431 if (GPT
- BEG
< BEG_UNCHANGED
)
13432 BEG_UNCHANGED
= GPT
- BEG
;
13433 if (Z
- GPT
< END_UNCHANGED
)
13434 END_UNCHANGED
= Z
- GPT
;
13437 /* The position of the first and last character that has been changed. */
13438 first_changed_charpos
= BEG
+ BEG_UNCHANGED
;
13439 last_changed_charpos
= Z
- END_UNCHANGED
;
13441 /* If window starts after a line end, and the last change is in
13442 front of that newline, then changes don't affect the display.
13443 This case happens with stealth-fontification. Note that although
13444 the display is unchanged, glyph positions in the matrix have to
13445 be adjusted, of course. */
13446 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
13447 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
)
13448 && ((last_changed_charpos
< CHARPOS (start
)
13449 && CHARPOS (start
) == BEGV
)
13450 || (last_changed_charpos
< CHARPOS (start
) - 1
13451 && FETCH_BYTE (BYTEPOS (start
) - 1) == '\n')))
13453 int Z_old
, delta
, Z_BYTE_old
, delta_bytes
;
13454 struct glyph_row
*r0
;
13456 /* Compute how many chars/bytes have been added to or removed
13457 from the buffer. */
13458 Z_old
= MATRIX_ROW_END_CHARPOS (row
) + XFASTINT (w
->window_end_pos
);
13459 Z_BYTE_old
= MATRIX_ROW_END_BYTEPOS (row
) + w
->window_end_bytepos
;
13461 delta_bytes
= Z_BYTE
- Z_BYTE_old
;
13463 /* Give up if PT is not in the window. Note that it already has
13464 been checked at the start of try_window_id that PT is not in
13465 front of the window start. */
13466 if (PT
>= MATRIX_ROW_END_CHARPOS (row
) + delta
)
13469 /* If window start is unchanged, we can reuse the whole matrix
13470 as is, after adjusting glyph positions. No need to compute
13471 the window end again, since its offset from Z hasn't changed. */
13472 r0
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
13473 if (CHARPOS (start
) == MATRIX_ROW_START_CHARPOS (r0
) + delta
13474 && BYTEPOS (start
) == MATRIX_ROW_START_BYTEPOS (r0
) + delta_bytes
13475 /* PT must not be in a partially visible line. */
13476 && !(PT
>= MATRIX_ROW_START_CHARPOS (row
) + delta
13477 && MATRIX_ROW_BOTTOM_Y (row
) > window_text_bottom_y (w
)))
13479 /* Adjust positions in the glyph matrix. */
13480 if (delta
|| delta_bytes
)
13482 struct glyph_row
*r1
13483 = MATRIX_BOTTOM_TEXT_ROW (current_matrix
, w
);
13484 increment_matrix_positions (w
->current_matrix
,
13485 MATRIX_ROW_VPOS (r0
, current_matrix
),
13486 MATRIX_ROW_VPOS (r1
, current_matrix
),
13487 delta
, delta_bytes
);
13490 /* Set the cursor. */
13491 row
= row_containing_pos (w
, PT
, r0
, NULL
, 0);
13493 set_cursor_from_row (w
, row
, current_matrix
, 0, 0, 0, 0);
13500 /* Handle the case that changes are all below what is displayed in
13501 the window, and that PT is in the window. This shortcut cannot
13502 be taken if ZV is visible in the window, and text has been added
13503 there that is visible in the window. */
13504 if (first_changed_charpos
>= MATRIX_ROW_END_CHARPOS (row
)
13505 /* ZV is not visible in the window, or there are no
13506 changes at ZV, actually. */
13507 && (current_matrix
->zv
> MATRIX_ROW_END_CHARPOS (row
)
13508 || first_changed_charpos
== last_changed_charpos
))
13510 struct glyph_row
*r0
;
13512 /* Give up if PT is not in the window. Note that it already has
13513 been checked at the start of try_window_id that PT is not in
13514 front of the window start. */
13515 if (PT
>= MATRIX_ROW_END_CHARPOS (row
))
13518 /* If window start is unchanged, we can reuse the whole matrix
13519 as is, without changing glyph positions since no text has
13520 been added/removed in front of the window end. */
13521 r0
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
13522 if (TEXT_POS_EQUAL_P (start
, r0
->start
.pos
)
13523 /* PT must not be in a partially visible line. */
13524 && !(PT
>= MATRIX_ROW_START_CHARPOS (row
)
13525 && MATRIX_ROW_BOTTOM_Y (row
) > window_text_bottom_y (w
)))
13527 /* We have to compute the window end anew since text
13528 can have been added/removed after it. */
13530 = make_number (Z
- MATRIX_ROW_END_CHARPOS (row
));
13531 w
->window_end_bytepos
13532 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
13534 /* Set the cursor. */
13535 row
= row_containing_pos (w
, PT
, r0
, NULL
, 0);
13537 set_cursor_from_row (w
, row
, current_matrix
, 0, 0, 0, 0);
13544 /* Give up if window start is in the changed area.
13546 The condition used to read
13548 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
13550 but why that was tested escapes me at the moment. */
13551 if (CHARPOS (start
) >= first_changed_charpos
13552 && CHARPOS (start
) <= last_changed_charpos
)
13555 /* Check that window start agrees with the start of the first glyph
13556 row in its current matrix. Check this after we know the window
13557 start is not in changed text, otherwise positions would not be
13559 row
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
13560 if (!TEXT_POS_EQUAL_P (start
, row
->start
.pos
))
13563 /* Give up if the window ends in strings. Overlay strings
13564 at the end are difficult to handle, so don't try. */
13565 row
= MATRIX_ROW (current_matrix
, XFASTINT (w
->window_end_vpos
));
13566 if (MATRIX_ROW_START_CHARPOS (row
) == MATRIX_ROW_END_CHARPOS (row
))
13569 /* Compute the position at which we have to start displaying new
13570 lines. Some of the lines at the top of the window might be
13571 reusable because they are not displaying changed text. Find the
13572 last row in W's current matrix not affected by changes at the
13573 start of current_buffer. Value is null if changes start in the
13574 first line of window. */
13575 last_unchanged_at_beg_row
= find_last_unchanged_at_beg_row (w
);
13576 if (last_unchanged_at_beg_row
)
13578 /* Avoid starting to display in the moddle of a character, a TAB
13579 for instance. This is easier than to set up the iterator
13580 exactly, and it's not a frequent case, so the additional
13581 effort wouldn't really pay off. */
13582 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row
)
13583 || last_unchanged_at_beg_row
->ends_in_newline_from_string_p
)
13584 && last_unchanged_at_beg_row
> w
->current_matrix
->rows
)
13585 --last_unchanged_at_beg_row
;
13587 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row
))
13590 if (init_to_row_end (&it
, w
, last_unchanged_at_beg_row
) == 0)
13592 start_pos
= it
.current
.pos
;
13594 /* Start displaying new lines in the desired matrix at the same
13595 vpos we would use in the current matrix, i.e. below
13596 last_unchanged_at_beg_row. */
13597 it
.vpos
= 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row
,
13599 it
.glyph_row
= MATRIX_ROW (desired_matrix
, it
.vpos
);
13600 it
.current_y
= MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row
);
13602 xassert (it
.hpos
== 0 && it
.current_x
== 0);
13606 /* There are no reusable lines at the start of the window.
13607 Start displaying in the first text line. */
13608 start_display (&it
, w
, start
);
13609 it
.vpos
= it
.first_vpos
;
13610 start_pos
= it
.current
.pos
;
13613 /* Find the first row that is not affected by changes at the end of
13614 the buffer. Value will be null if there is no unchanged row, in
13615 which case we must redisplay to the end of the window. delta
13616 will be set to the value by which buffer positions beginning with
13617 first_unchanged_at_end_row have to be adjusted due to text
13619 first_unchanged_at_end_row
13620 = find_first_unchanged_at_end_row (w
, &delta
, &delta_bytes
);
13621 IF_DEBUG (debug_delta
= delta
);
13622 IF_DEBUG (debug_delta_bytes
= delta_bytes
);
13624 /* Set stop_pos to the buffer position up to which we will have to
13625 display new lines. If first_unchanged_at_end_row != NULL, this
13626 is the buffer position of the start of the line displayed in that
13627 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
13628 that we don't stop at a buffer position. */
13630 if (first_unchanged_at_end_row
)
13632 xassert (last_unchanged_at_beg_row
== NULL
13633 || first_unchanged_at_end_row
>= last_unchanged_at_beg_row
);
13635 /* If this is a continuation line, move forward to the next one
13636 that isn't. Changes in lines above affect this line.
13637 Caution: this may move first_unchanged_at_end_row to a row
13638 not displaying text. */
13639 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row
)
13640 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
)
13641 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row
)
13642 < it
.last_visible_y
))
13643 ++first_unchanged_at_end_row
;
13645 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
)
13646 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row
)
13647 >= it
.last_visible_y
))
13648 first_unchanged_at_end_row
= NULL
;
13651 stop_pos
= (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row
)
13653 first_unchanged_at_end_vpos
13654 = MATRIX_ROW_VPOS (first_unchanged_at_end_row
, current_matrix
);
13655 xassert (stop_pos
>= Z
- END_UNCHANGED
);
13658 else if (last_unchanged_at_beg_row
== NULL
)
13664 /* Either there is no unchanged row at the end, or the one we have
13665 now displays text. This is a necessary condition for the window
13666 end pos calculation at the end of this function. */
13667 xassert (first_unchanged_at_end_row
== NULL
13668 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
));
13670 debug_last_unchanged_at_beg_vpos
13671 = (last_unchanged_at_beg_row
13672 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row
, current_matrix
)
13674 debug_first_unchanged_at_end_vpos
= first_unchanged_at_end_vpos
;
13676 #endif /* GLYPH_DEBUG != 0 */
13679 /* Display new lines. Set last_text_row to the last new line
13680 displayed which has text on it, i.e. might end up as being the
13681 line where the window_end_vpos is. */
13682 w
->cursor
.vpos
= -1;
13683 last_text_row
= NULL
;
13684 overlay_arrow_seen
= 0;
13685 while (it
.current_y
< it
.last_visible_y
13686 && !fonts_changed_p
13687 && (first_unchanged_at_end_row
== NULL
13688 || IT_CHARPOS (it
) < stop_pos
))
13690 if (display_line (&it
))
13691 last_text_row
= it
.glyph_row
- 1;
13694 if (fonts_changed_p
)
13698 /* Compute differences in buffer positions, y-positions etc. for
13699 lines reused at the bottom of the window. Compute what we can
13701 if (first_unchanged_at_end_row
13702 /* No lines reused because we displayed everything up to the
13703 bottom of the window. */
13704 && it
.current_y
< it
.last_visible_y
)
13707 - MATRIX_ROW_VPOS (first_unchanged_at_end_row
,
13709 dy
= it
.current_y
- first_unchanged_at_end_row
->y
;
13710 run
.current_y
= first_unchanged_at_end_row
->y
;
13711 run
.desired_y
= run
.current_y
+ dy
;
13712 run
.height
= it
.last_visible_y
- max (run
.current_y
, run
.desired_y
);
13716 delta
= dvpos
= dy
= run
.current_y
= run
.desired_y
= run
.height
= 0;
13717 first_unchanged_at_end_row
= NULL
;
13719 IF_DEBUG (debug_dvpos
= dvpos
; debug_dy
= dy
);
13722 /* Find the cursor if not already found. We have to decide whether
13723 PT will appear on this window (it sometimes doesn't, but this is
13724 not a very frequent case.) This decision has to be made before
13725 the current matrix is altered. A value of cursor.vpos < 0 means
13726 that PT is either in one of the lines beginning at
13727 first_unchanged_at_end_row or below the window. Don't care for
13728 lines that might be displayed later at the window end; as
13729 mentioned, this is not a frequent case. */
13730 if (w
->cursor
.vpos
< 0)
13732 /* Cursor in unchanged rows at the top? */
13733 if (PT
< CHARPOS (start_pos
)
13734 && last_unchanged_at_beg_row
)
13736 row
= row_containing_pos (w
, PT
,
13737 MATRIX_FIRST_TEXT_ROW (w
->current_matrix
),
13738 last_unchanged_at_beg_row
+ 1, 0);
13740 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
13743 /* Start from first_unchanged_at_end_row looking for PT. */
13744 else if (first_unchanged_at_end_row
)
13746 row
= row_containing_pos (w
, PT
- delta
,
13747 first_unchanged_at_end_row
, NULL
, 0);
13749 set_cursor_from_row (w
, row
, w
->current_matrix
, delta
,
13750 delta_bytes
, dy
, dvpos
);
13753 /* Give up if cursor was not found. */
13754 if (w
->cursor
.vpos
< 0)
13756 clear_glyph_matrix (w
->desired_matrix
);
13761 /* Don't let the cursor end in the scroll margins. */
13763 int this_scroll_margin
, cursor_height
;
13765 this_scroll_margin
= max (0, scroll_margin
);
13766 this_scroll_margin
= min (this_scroll_margin
, WINDOW_TOTAL_LINES (w
) / 4);
13767 this_scroll_margin
*= FRAME_LINE_HEIGHT (it
.f
);
13768 cursor_height
= MATRIX_ROW (w
->desired_matrix
, w
->cursor
.vpos
)->height
;
13770 if ((w
->cursor
.y
< this_scroll_margin
13771 && CHARPOS (start
) > BEGV
)
13772 /* Old redisplay didn't take scroll margin into account at the bottom,
13773 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
13774 || (w
->cursor
.y
+ (make_cursor_line_fully_visible_p
13775 ? cursor_height
+ this_scroll_margin
13776 : 1)) > it
.last_visible_y
)
13778 w
->cursor
.vpos
= -1;
13779 clear_glyph_matrix (w
->desired_matrix
);
13784 /* Scroll the display. Do it before changing the current matrix so
13785 that xterm.c doesn't get confused about where the cursor glyph is
13787 if (dy
&& run
.height
)
13791 if (FRAME_WINDOW_P (f
))
13793 rif
->update_window_begin_hook (w
);
13794 rif
->clear_window_mouse_face (w
);
13795 rif
->scroll_run_hook (w
, &run
);
13796 rif
->update_window_end_hook (w
, 0, 0);
13800 /* Terminal frame. In this case, dvpos gives the number of
13801 lines to scroll by; dvpos < 0 means scroll up. */
13802 int first_unchanged_at_end_vpos
13803 = MATRIX_ROW_VPOS (first_unchanged_at_end_row
, w
->current_matrix
);
13804 int from
= WINDOW_TOP_EDGE_LINE (w
) + first_unchanged_at_end_vpos
;
13805 int end
= (WINDOW_TOP_EDGE_LINE (w
)
13806 + (WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0)
13807 + window_internal_height (w
));
13809 /* Perform the operation on the screen. */
13812 /* Scroll last_unchanged_at_beg_row to the end of the
13813 window down dvpos lines. */
13814 set_terminal_window (end
);
13816 /* On dumb terminals delete dvpos lines at the end
13817 before inserting dvpos empty lines. */
13818 if (!scroll_region_ok
)
13819 ins_del_lines (end
- dvpos
, -dvpos
);
13821 /* Insert dvpos empty lines in front of
13822 last_unchanged_at_beg_row. */
13823 ins_del_lines (from
, dvpos
);
13825 else if (dvpos
< 0)
13827 /* Scroll up last_unchanged_at_beg_vpos to the end of
13828 the window to last_unchanged_at_beg_vpos - |dvpos|. */
13829 set_terminal_window (end
);
13831 /* Delete dvpos lines in front of
13832 last_unchanged_at_beg_vpos. ins_del_lines will set
13833 the cursor to the given vpos and emit |dvpos| delete
13835 ins_del_lines (from
+ dvpos
, dvpos
);
13837 /* On a dumb terminal insert dvpos empty lines at the
13839 if (!scroll_region_ok
)
13840 ins_del_lines (end
+ dvpos
, -dvpos
);
13843 set_terminal_window (0);
13849 /* Shift reused rows of the current matrix to the right position.
13850 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
13852 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (current_matrix
, w
);
13853 bottom_vpos
= MATRIX_ROW_VPOS (bottom_row
, current_matrix
);
13856 rotate_matrix (current_matrix
, first_unchanged_at_end_vpos
+ dvpos
,
13857 bottom_vpos
, dvpos
);
13858 enable_glyph_matrix_rows (current_matrix
, bottom_vpos
+ dvpos
,
13861 else if (dvpos
> 0)
13863 rotate_matrix (current_matrix
, first_unchanged_at_end_vpos
,
13864 bottom_vpos
, dvpos
);
13865 enable_glyph_matrix_rows (current_matrix
, first_unchanged_at_end_vpos
,
13866 first_unchanged_at_end_vpos
+ dvpos
, 0);
13869 /* For frame-based redisplay, make sure that current frame and window
13870 matrix are in sync with respect to glyph memory. */
13871 if (!FRAME_WINDOW_P (f
))
13872 sync_frame_with_window_matrix_rows (w
);
13874 /* Adjust buffer positions in reused rows. */
13876 increment_matrix_positions (current_matrix
,
13877 first_unchanged_at_end_vpos
+ dvpos
,
13878 bottom_vpos
, delta
, delta_bytes
);
13880 /* Adjust Y positions. */
13882 shift_glyph_matrix (w
, current_matrix
,
13883 first_unchanged_at_end_vpos
+ dvpos
,
13886 if (first_unchanged_at_end_row
)
13888 first_unchanged_at_end_row
+= dvpos
;
13889 if (first_unchanged_at_end_row
->y
>= it
.last_visible_y
13890 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
))
13891 first_unchanged_at_end_row
= NULL
;
13894 /* If scrolling up, there may be some lines to display at the end of
13896 last_text_row_at_end
= NULL
;
13899 /* Scrolling up can leave for example a partially visible line
13900 at the end of the window to be redisplayed. */
13901 /* Set last_row to the glyph row in the current matrix where the
13902 window end line is found. It has been moved up or down in
13903 the matrix by dvpos. */
13904 int last_vpos
= XFASTINT (w
->window_end_vpos
) + dvpos
;
13905 struct glyph_row
*last_row
= MATRIX_ROW (current_matrix
, last_vpos
);
13907 /* If last_row is the window end line, it should display text. */
13908 xassert (last_row
->displays_text_p
);
13910 /* If window end line was partially visible before, begin
13911 displaying at that line. Otherwise begin displaying with the
13912 line following it. */
13913 if (MATRIX_ROW_BOTTOM_Y (last_row
) - dy
>= it
.last_visible_y
)
13915 init_to_row_start (&it
, w
, last_row
);
13916 it
.vpos
= last_vpos
;
13917 it
.current_y
= last_row
->y
;
13921 init_to_row_end (&it
, w
, last_row
);
13922 it
.vpos
= 1 + last_vpos
;
13923 it
.current_y
= MATRIX_ROW_BOTTOM_Y (last_row
);
13927 /* We may start in a continuation line. If so, we have to
13928 get the right continuation_lines_width and current_x. */
13929 it
.continuation_lines_width
= last_row
->continuation_lines_width
;
13930 it
.hpos
= it
.current_x
= 0;
13932 /* Display the rest of the lines at the window end. */
13933 it
.glyph_row
= MATRIX_ROW (desired_matrix
, it
.vpos
);
13934 while (it
.current_y
< it
.last_visible_y
13935 && !fonts_changed_p
)
13937 /* Is it always sure that the display agrees with lines in
13938 the current matrix? I don't think so, so we mark rows
13939 displayed invalid in the current matrix by setting their
13940 enabled_p flag to zero. */
13941 MATRIX_ROW (w
->current_matrix
, it
.vpos
)->enabled_p
= 0;
13942 if (display_line (&it
))
13943 last_text_row_at_end
= it
.glyph_row
- 1;
13947 /* Update window_end_pos and window_end_vpos. */
13948 if (first_unchanged_at_end_row
13949 && !last_text_row_at_end
)
13951 /* Window end line if one of the preserved rows from the current
13952 matrix. Set row to the last row displaying text in current
13953 matrix starting at first_unchanged_at_end_row, after
13955 xassert (first_unchanged_at_end_row
->displays_text_p
);
13956 row
= find_last_row_displaying_text (w
->current_matrix
, &it
,
13957 first_unchanged_at_end_row
);
13958 xassert (row
&& MATRIX_ROW_DISPLAYS_TEXT_P (row
));
13960 w
->window_end_pos
= make_number (Z
- MATRIX_ROW_END_CHARPOS (row
));
13961 w
->window_end_bytepos
= Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
13963 = make_number (MATRIX_ROW_VPOS (row
, w
->current_matrix
));
13964 xassert (w
->window_end_bytepos
>= 0);
13965 IF_DEBUG (debug_method_add (w
, "A"));
13967 else if (last_text_row_at_end
)
13970 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row_at_end
));
13971 w
->window_end_bytepos
13972 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row_at_end
);
13974 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end
, desired_matrix
));
13975 xassert (w
->window_end_bytepos
>= 0);
13976 IF_DEBUG (debug_method_add (w
, "B"));
13978 else if (last_text_row
)
13980 /* We have displayed either to the end of the window or at the
13981 end of the window, i.e. the last row with text is to be found
13982 in the desired matrix. */
13984 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
13985 w
->window_end_bytepos
13986 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
13988 = make_number (MATRIX_ROW_VPOS (last_text_row
, desired_matrix
));
13989 xassert (w
->window_end_bytepos
>= 0);
13991 else if (first_unchanged_at_end_row
== NULL
13992 && last_text_row
== NULL
13993 && last_text_row_at_end
== NULL
)
13995 /* Displayed to end of window, but no line containing text was
13996 displayed. Lines were deleted at the end of the window. */
13997 int first_vpos
= WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0;
13998 int vpos
= XFASTINT (w
->window_end_vpos
);
13999 struct glyph_row
*current_row
= current_matrix
->rows
+ vpos
;
14000 struct glyph_row
*desired_row
= desired_matrix
->rows
+ vpos
;
14003 row
== NULL
&& vpos
>= first_vpos
;
14004 --vpos
, --current_row
, --desired_row
)
14006 if (desired_row
->enabled_p
)
14008 if (desired_row
->displays_text_p
)
14011 else if (current_row
->displays_text_p
)
14015 xassert (row
!= NULL
);
14016 w
->window_end_vpos
= make_number (vpos
+ 1);
14017 w
->window_end_pos
= make_number (Z
- MATRIX_ROW_END_CHARPOS (row
));
14018 w
->window_end_bytepos
= Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
14019 xassert (w
->window_end_bytepos
>= 0);
14020 IF_DEBUG (debug_method_add (w
, "C"));
14025 #if 0 /* This leads to problems, for instance when the cursor is
14026 at ZV, and the cursor line displays no text. */
14027 /* Disable rows below what's displayed in the window. This makes
14028 debugging easier. */
14029 enable_glyph_matrix_rows (current_matrix
,
14030 XFASTINT (w
->window_end_vpos
) + 1,
14034 IF_DEBUG (debug_end_pos
= XFASTINT (w
->window_end_pos
);
14035 debug_end_vpos
= XFASTINT (w
->window_end_vpos
));
14037 /* Record that display has not been completed. */
14038 w
->window_end_valid
= Qnil
;
14039 w
->desired_matrix
->no_scrolling_p
= 1;
14047 /***********************************************************************
14048 More debugging support
14049 ***********************************************************************/
14053 void dump_glyph_row
P_ ((struct glyph_row
*, int, int));
14054 void dump_glyph_matrix
P_ ((struct glyph_matrix
*, int));
14055 void dump_glyph
P_ ((struct glyph_row
*, struct glyph
*, int));
14058 /* Dump the contents of glyph matrix MATRIX on stderr.
14060 GLYPHS 0 means don't show glyph contents.
14061 GLYPHS 1 means show glyphs in short form
14062 GLYPHS > 1 means show glyphs in long form. */
14065 dump_glyph_matrix (matrix
, glyphs
)
14066 struct glyph_matrix
*matrix
;
14070 for (i
= 0; i
< matrix
->nrows
; ++i
)
14071 dump_glyph_row (MATRIX_ROW (matrix
, i
), i
, glyphs
);
14075 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
14076 the glyph row and area where the glyph comes from. */
14079 dump_glyph (row
, glyph
, area
)
14080 struct glyph_row
*row
;
14081 struct glyph
*glyph
;
14084 if (glyph
->type
== CHAR_GLYPH
)
14087 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
14088 glyph
- row
->glyphs
[TEXT_AREA
],
14091 (BUFFERP (glyph
->object
)
14093 : (STRINGP (glyph
->object
)
14096 glyph
->pixel_width
,
14098 (glyph
->u
.ch
< 0x80 && glyph
->u
.ch
>= ' '
14102 glyph
->left_box_line_p
,
14103 glyph
->right_box_line_p
);
14105 else if (glyph
->type
== STRETCH_GLYPH
)
14108 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
14109 glyph
- row
->glyphs
[TEXT_AREA
],
14112 (BUFFERP (glyph
->object
)
14114 : (STRINGP (glyph
->object
)
14117 glyph
->pixel_width
,
14121 glyph
->left_box_line_p
,
14122 glyph
->right_box_line_p
);
14124 else if (glyph
->type
== IMAGE_GLYPH
)
14127 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
14128 glyph
- row
->glyphs
[TEXT_AREA
],
14131 (BUFFERP (glyph
->object
)
14133 : (STRINGP (glyph
->object
)
14136 glyph
->pixel_width
,
14140 glyph
->left_box_line_p
,
14141 glyph
->right_box_line_p
);
14146 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
14147 GLYPHS 0 means don't show glyph contents.
14148 GLYPHS 1 means show glyphs in short form
14149 GLYPHS > 1 means show glyphs in long form. */
14152 dump_glyph_row (row
, vpos
, glyphs
)
14153 struct glyph_row
*row
;
14158 fprintf (stderr
, "Row Start End Used oEI><O\\CTZFesm X Y W H V A P\n");
14159 fprintf (stderr
, "=======================================================================\n");
14161 fprintf (stderr
, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d%1.1d\
14162 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
14164 MATRIX_ROW_START_CHARPOS (row
),
14165 MATRIX_ROW_END_CHARPOS (row
),
14166 row
->used
[TEXT_AREA
],
14167 row
->contains_overlapping_glyphs_p
,
14169 row
->truncated_on_left_p
,
14170 row
->truncated_on_right_p
,
14171 row
->overlay_arrow_p
,
14173 MATRIX_ROW_CONTINUATION_LINE_P (row
),
14174 row
->displays_text_p
,
14177 row
->ends_in_middle_of_char_p
,
14178 row
->starts_in_middle_of_char_p
,
14184 row
->visible_height
,
14187 fprintf (stderr
, "%9d %5d\t%5d\n", row
->start
.overlay_string_index
,
14188 row
->end
.overlay_string_index
,
14189 row
->continuation_lines_width
);
14190 fprintf (stderr
, "%9d %5d\n",
14191 CHARPOS (row
->start
.string_pos
),
14192 CHARPOS (row
->end
.string_pos
));
14193 fprintf (stderr
, "%9d %5d\n", row
->start
.dpvec_index
,
14194 row
->end
.dpvec_index
);
14201 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
14203 struct glyph
*glyph
= row
->glyphs
[area
];
14204 struct glyph
*glyph_end
= glyph
+ row
->used
[area
];
14206 /* Glyph for a line end in text. */
14207 if (area
== TEXT_AREA
&& glyph
== glyph_end
&& glyph
->charpos
> 0)
14210 if (glyph
< glyph_end
)
14211 fprintf (stderr
, " Glyph Type Pos O W Code C Face LR\n");
14213 for (; glyph
< glyph_end
; ++glyph
)
14214 dump_glyph (row
, glyph
, area
);
14217 else if (glyphs
== 1)
14221 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
14223 char *s
= (char *) alloca (row
->used
[area
] + 1);
14226 for (i
= 0; i
< row
->used
[area
]; ++i
)
14228 struct glyph
*glyph
= row
->glyphs
[area
] + i
;
14229 if (glyph
->type
== CHAR_GLYPH
14230 && glyph
->u
.ch
< 0x80
14231 && glyph
->u
.ch
>= ' ')
14232 s
[i
] = glyph
->u
.ch
;
14238 fprintf (stderr
, "%3d: (%d) '%s'\n", vpos
, row
->enabled_p
, s
);
14244 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix
,
14245 Sdump_glyph_matrix
, 0, 1, "p",
14246 doc
: /* Dump the current matrix of the selected window to stderr.
14247 Shows contents of glyph row structures. With non-nil
14248 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
14249 glyphs in short form, otherwise show glyphs in long form. */)
14251 Lisp_Object glyphs
;
14253 struct window
*w
= XWINDOW (selected_window
);
14254 struct buffer
*buffer
= XBUFFER (w
->buffer
);
14256 fprintf (stderr
, "PT = %d, BEGV = %d. ZV = %d\n",
14257 BUF_PT (buffer
), BUF_BEGV (buffer
), BUF_ZV (buffer
));
14258 fprintf (stderr
, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
14259 w
->cursor
.x
, w
->cursor
.y
, w
->cursor
.hpos
, w
->cursor
.vpos
);
14260 fprintf (stderr
, "=============================================\n");
14261 dump_glyph_matrix (w
->current_matrix
,
14262 NILP (glyphs
) ? 0 : XINT (glyphs
));
14267 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix
,
14268 Sdump_frame_glyph_matrix
, 0, 0, "", doc
: /* */)
14271 struct frame
*f
= XFRAME (selected_frame
);
14272 dump_glyph_matrix (f
->current_matrix
, 1);
14277 DEFUN ("dump-glyph-row", Fdump_glyph_row
, Sdump_glyph_row
, 1, 2, "",
14278 doc
: /* Dump glyph row ROW to stderr.
14279 GLYPH 0 means don't dump glyphs.
14280 GLYPH 1 means dump glyphs in short form.
14281 GLYPH > 1 or omitted means dump glyphs in long form. */)
14283 Lisp_Object row
, glyphs
;
14285 struct glyph_matrix
*matrix
;
14288 CHECK_NUMBER (row
);
14289 matrix
= XWINDOW (selected_window
)->current_matrix
;
14291 if (vpos
>= 0 && vpos
< matrix
->nrows
)
14292 dump_glyph_row (MATRIX_ROW (matrix
, vpos
),
14294 INTEGERP (glyphs
) ? XINT (glyphs
) : 2);
14299 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row
, Sdump_tool_bar_row
, 1, 2, "",
14300 doc
: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
14301 GLYPH 0 means don't dump glyphs.
14302 GLYPH 1 means dump glyphs in short form.
14303 GLYPH > 1 or omitted means dump glyphs in long form. */)
14305 Lisp_Object row
, glyphs
;
14307 struct frame
*sf
= SELECTED_FRAME ();
14308 struct glyph_matrix
*m
= XWINDOW (sf
->tool_bar_window
)->current_matrix
;
14311 CHECK_NUMBER (row
);
14313 if (vpos
>= 0 && vpos
< m
->nrows
)
14314 dump_glyph_row (MATRIX_ROW (m
, vpos
), vpos
,
14315 INTEGERP (glyphs
) ? XINT (glyphs
) : 2);
14320 DEFUN ("trace-redisplay", Ftrace_redisplay
, Strace_redisplay
, 0, 1, "P",
14321 doc
: /* Toggle tracing of redisplay.
14322 With ARG, turn tracing on if and only if ARG is positive. */)
14327 trace_redisplay_p
= !trace_redisplay_p
;
14330 arg
= Fprefix_numeric_value (arg
);
14331 trace_redisplay_p
= XINT (arg
) > 0;
14338 DEFUN ("trace-to-stderr", Ftrace_to_stderr
, Strace_to_stderr
, 1, MANY
, "",
14339 doc
: /* Like `format', but print result to stderr.
14340 usage: (trace-to-stderr STRING &rest OBJECTS) */)
14345 Lisp_Object s
= Fformat (nargs
, args
);
14346 fprintf (stderr
, "%s", SDATA (s
));
14350 #endif /* GLYPH_DEBUG */
14354 /***********************************************************************
14355 Building Desired Matrix Rows
14356 ***********************************************************************/
14358 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
14359 Used for non-window-redisplay windows, and for windows w/o left fringe. */
14361 static struct glyph_row
*
14362 get_overlay_arrow_glyph_row (w
, overlay_arrow_string
)
14364 Lisp_Object overlay_arrow_string
;
14366 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
14367 struct buffer
*buffer
= XBUFFER (w
->buffer
);
14368 struct buffer
*old
= current_buffer
;
14369 const unsigned char *arrow_string
= SDATA (overlay_arrow_string
);
14370 int arrow_len
= SCHARS (overlay_arrow_string
);
14371 const unsigned char *arrow_end
= arrow_string
+ arrow_len
;
14372 const unsigned char *p
;
14375 int n_glyphs_before
;
14377 set_buffer_temp (buffer
);
14378 init_iterator (&it
, w
, -1, -1, &scratch_glyph_row
, DEFAULT_FACE_ID
);
14379 it
.glyph_row
->used
[TEXT_AREA
] = 0;
14380 SET_TEXT_POS (it
.position
, 0, 0);
14382 multibyte_p
= !NILP (buffer
->enable_multibyte_characters
);
14384 while (p
< arrow_end
)
14386 Lisp_Object face
, ilisp
;
14388 /* Get the next character. */
14390 it
.c
= string_char_and_length (p
, arrow_len
, &it
.len
);
14392 it
.c
= *p
, it
.len
= 1;
14395 /* Get its face. */
14396 ilisp
= make_number (p
- arrow_string
);
14397 face
= Fget_text_property (ilisp
, Qface
, overlay_arrow_string
);
14398 it
.face_id
= compute_char_face (f
, it
.c
, face
);
14400 /* Compute its width, get its glyphs. */
14401 n_glyphs_before
= it
.glyph_row
->used
[TEXT_AREA
];
14402 SET_TEXT_POS (it
.position
, -1, -1);
14403 PRODUCE_GLYPHS (&it
);
14405 /* If this character doesn't fit any more in the line, we have
14406 to remove some glyphs. */
14407 if (it
.current_x
> it
.last_visible_x
)
14409 it
.glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
;
14414 set_buffer_temp (old
);
14415 return it
.glyph_row
;
14419 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
14420 glyphs are only inserted for terminal frames since we can't really
14421 win with truncation glyphs when partially visible glyphs are
14422 involved. Which glyphs to insert is determined by
14423 produce_special_glyphs. */
14426 insert_left_trunc_glyphs (it
)
14429 struct it truncate_it
;
14430 struct glyph
*from
, *end
, *to
, *toend
;
14432 xassert (!FRAME_WINDOW_P (it
->f
));
14434 /* Get the truncation glyphs. */
14436 truncate_it
.current_x
= 0;
14437 truncate_it
.face_id
= DEFAULT_FACE_ID
;
14438 truncate_it
.glyph_row
= &scratch_glyph_row
;
14439 truncate_it
.glyph_row
->used
[TEXT_AREA
] = 0;
14440 CHARPOS (truncate_it
.position
) = BYTEPOS (truncate_it
.position
) = -1;
14441 truncate_it
.object
= make_number (0);
14442 produce_special_glyphs (&truncate_it
, IT_TRUNCATION
);
14444 /* Overwrite glyphs from IT with truncation glyphs. */
14445 from
= truncate_it
.glyph_row
->glyphs
[TEXT_AREA
];
14446 end
= from
+ truncate_it
.glyph_row
->used
[TEXT_AREA
];
14447 to
= it
->glyph_row
->glyphs
[TEXT_AREA
];
14448 toend
= to
+ it
->glyph_row
->used
[TEXT_AREA
];
14453 /* There may be padding glyphs left over. Overwrite them too. */
14454 while (to
< toend
&& CHAR_GLYPH_PADDING_P (*to
))
14456 from
= truncate_it
.glyph_row
->glyphs
[TEXT_AREA
];
14462 it
->glyph_row
->used
[TEXT_AREA
] = to
- it
->glyph_row
->glyphs
[TEXT_AREA
];
14466 /* Compute the pixel height and width of IT->glyph_row.
14468 Most of the time, ascent and height of a display line will be equal
14469 to the max_ascent and max_height values of the display iterator
14470 structure. This is not the case if
14472 1. We hit ZV without displaying anything. In this case, max_ascent
14473 and max_height will be zero.
14475 2. We have some glyphs that don't contribute to the line height.
14476 (The glyph row flag contributes_to_line_height_p is for future
14477 pixmap extensions).
14479 The first case is easily covered by using default values because in
14480 these cases, the line height does not really matter, except that it
14481 must not be zero. */
14484 compute_line_metrics (it
)
14487 struct glyph_row
*row
= it
->glyph_row
;
14490 if (FRAME_WINDOW_P (it
->f
))
14492 int i
, min_y
, max_y
;
14494 /* The line may consist of one space only, that was added to
14495 place the cursor on it. If so, the row's height hasn't been
14497 if (row
->height
== 0)
14499 if (it
->max_ascent
+ it
->max_descent
== 0)
14500 it
->max_descent
= it
->max_phys_descent
= FRAME_LINE_HEIGHT (it
->f
);
14501 row
->ascent
= it
->max_ascent
;
14502 row
->height
= it
->max_ascent
+ it
->max_descent
;
14503 row
->phys_ascent
= it
->max_phys_ascent
;
14504 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
14505 row
->extra_line_spacing
= it
->max_extra_line_spacing
;
14508 /* Compute the width of this line. */
14509 row
->pixel_width
= row
->x
;
14510 for (i
= 0; i
< row
->used
[TEXT_AREA
]; ++i
)
14511 row
->pixel_width
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
14513 xassert (row
->pixel_width
>= 0);
14514 xassert (row
->ascent
>= 0 && row
->height
> 0);
14516 row
->overlapping_p
= (MATRIX_ROW_OVERLAPS_SUCC_P (row
)
14517 || MATRIX_ROW_OVERLAPS_PRED_P (row
));
14519 /* If first line's physical ascent is larger than its logical
14520 ascent, use the physical ascent, and make the row taller.
14521 This makes accented characters fully visible. */
14522 if (row
== MATRIX_FIRST_TEXT_ROW (it
->w
->desired_matrix
)
14523 && row
->phys_ascent
> row
->ascent
)
14525 row
->height
+= row
->phys_ascent
- row
->ascent
;
14526 row
->ascent
= row
->phys_ascent
;
14529 /* Compute how much of the line is visible. */
14530 row
->visible_height
= row
->height
;
14532 min_y
= WINDOW_HEADER_LINE_HEIGHT (it
->w
);
14533 max_y
= WINDOW_BOX_HEIGHT_NO_MODE_LINE (it
->w
);
14535 if (row
->y
< min_y
)
14536 row
->visible_height
-= min_y
- row
->y
;
14537 if (row
->y
+ row
->height
> max_y
)
14538 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
14542 row
->pixel_width
= row
->used
[TEXT_AREA
];
14543 if (row
->continued_p
)
14544 row
->pixel_width
-= it
->continuation_pixel_width
;
14545 else if (row
->truncated_on_right_p
)
14546 row
->pixel_width
-= it
->truncation_pixel_width
;
14547 row
->ascent
= row
->phys_ascent
= 0;
14548 row
->height
= row
->phys_height
= row
->visible_height
= 1;
14549 row
->extra_line_spacing
= 0;
14552 /* Compute a hash code for this row. */
14554 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
14555 for (i
= 0; i
< row
->used
[area
]; ++i
)
14556 row
->hash
= ((((row
->hash
<< 4) + (row
->hash
>> 24)) & 0x0fffffff)
14557 + row
->glyphs
[area
][i
].u
.val
14558 + row
->glyphs
[area
][i
].face_id
14559 + row
->glyphs
[area
][i
].padding_p
14560 + (row
->glyphs
[area
][i
].type
<< 2));
14562 it
->max_ascent
= it
->max_descent
= 0;
14563 it
->max_phys_ascent
= it
->max_phys_descent
= 0;
14567 /* Append one space to the glyph row of iterator IT if doing a
14568 window-based redisplay. The space has the same face as
14569 IT->face_id. Value is non-zero if a space was added.
14571 This function is called to make sure that there is always one glyph
14572 at the end of a glyph row that the cursor can be set on under
14573 window-systems. (If there weren't such a glyph we would not know
14574 how wide and tall a box cursor should be displayed).
14576 At the same time this space let's a nicely handle clearing to the
14577 end of the line if the row ends in italic text. */
14580 append_space_for_newline (it
, default_face_p
)
14582 int default_face_p
;
14584 if (FRAME_WINDOW_P (it
->f
))
14586 int n
= it
->glyph_row
->used
[TEXT_AREA
];
14588 if (it
->glyph_row
->glyphs
[TEXT_AREA
] + n
14589 < it
->glyph_row
->glyphs
[1 + TEXT_AREA
])
14591 /* Save some values that must not be changed.
14592 Must save IT->c and IT->len because otherwise
14593 ITERATOR_AT_END_P wouldn't work anymore after
14594 append_space_for_newline has been called. */
14595 enum display_element_type saved_what
= it
->what
;
14596 int saved_c
= it
->c
, saved_len
= it
->len
;
14597 int saved_x
= it
->current_x
;
14598 int saved_face_id
= it
->face_id
;
14599 struct text_pos saved_pos
;
14600 Lisp_Object saved_object
;
14603 saved_object
= it
->object
;
14604 saved_pos
= it
->position
;
14606 it
->what
= IT_CHARACTER
;
14607 bzero (&it
->position
, sizeof it
->position
);
14608 it
->object
= make_number (0);
14612 if (default_face_p
)
14613 it
->face_id
= DEFAULT_FACE_ID
;
14614 else if (it
->face_before_selective_p
)
14615 it
->face_id
= it
->saved_face_id
;
14616 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
14617 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, 0);
14619 PRODUCE_GLYPHS (it
);
14621 it
->override_ascent
= -1;
14622 it
->constrain_row_ascent_descent_p
= 0;
14623 it
->current_x
= saved_x
;
14624 it
->object
= saved_object
;
14625 it
->position
= saved_pos
;
14626 it
->what
= saved_what
;
14627 it
->face_id
= saved_face_id
;
14628 it
->len
= saved_len
;
14638 /* Extend the face of the last glyph in the text area of IT->glyph_row
14639 to the end of the display line. Called from display_line.
14640 If the glyph row is empty, add a space glyph to it so that we
14641 know the face to draw. Set the glyph row flag fill_line_p. */
14644 extend_face_to_end_of_line (it
)
14648 struct frame
*f
= it
->f
;
14650 /* If line is already filled, do nothing. */
14651 if (it
->current_x
>= it
->last_visible_x
)
14654 /* Face extension extends the background and box of IT->face_id
14655 to the end of the line. If the background equals the background
14656 of the frame, we don't have to do anything. */
14657 if (it
->face_before_selective_p
)
14658 face
= FACE_FROM_ID (it
->f
, it
->saved_face_id
);
14660 face
= FACE_FROM_ID (f
, it
->face_id
);
14662 if (FRAME_WINDOW_P (f
)
14663 && face
->box
== FACE_NO_BOX
14664 && face
->background
== FRAME_BACKGROUND_PIXEL (f
)
14668 /* Set the glyph row flag indicating that the face of the last glyph
14669 in the text area has to be drawn to the end of the text area. */
14670 it
->glyph_row
->fill_line_p
= 1;
14672 /* If current character of IT is not ASCII, make sure we have the
14673 ASCII face. This will be automatically undone the next time
14674 get_next_display_element returns a multibyte character. Note
14675 that the character will always be single byte in unibyte text. */
14676 if (!SINGLE_BYTE_CHAR_P (it
->c
))
14678 it
->face_id
= FACE_FOR_CHAR (f
, face
, 0);
14681 if (FRAME_WINDOW_P (f
))
14683 /* If the row is empty, add a space with the current face of IT,
14684 so that we know which face to draw. */
14685 if (it
->glyph_row
->used
[TEXT_AREA
] == 0)
14687 it
->glyph_row
->glyphs
[TEXT_AREA
][0] = space_glyph
;
14688 it
->glyph_row
->glyphs
[TEXT_AREA
][0].face_id
= it
->face_id
;
14689 it
->glyph_row
->used
[TEXT_AREA
] = 1;
14694 /* Save some values that must not be changed. */
14695 int saved_x
= it
->current_x
;
14696 struct text_pos saved_pos
;
14697 Lisp_Object saved_object
;
14698 enum display_element_type saved_what
= it
->what
;
14699 int saved_face_id
= it
->face_id
;
14701 saved_object
= it
->object
;
14702 saved_pos
= it
->position
;
14704 it
->what
= IT_CHARACTER
;
14705 bzero (&it
->position
, sizeof it
->position
);
14706 it
->object
= make_number (0);
14709 it
->face_id
= face
->id
;
14711 PRODUCE_GLYPHS (it
);
14713 while (it
->current_x
<= it
->last_visible_x
)
14714 PRODUCE_GLYPHS (it
);
14716 /* Don't count these blanks really. It would let us insert a left
14717 truncation glyph below and make us set the cursor on them, maybe. */
14718 it
->current_x
= saved_x
;
14719 it
->object
= saved_object
;
14720 it
->position
= saved_pos
;
14721 it
->what
= saved_what
;
14722 it
->face_id
= saved_face_id
;
14727 /* Value is non-zero if text starting at CHARPOS in current_buffer is
14728 trailing whitespace. */
14731 trailing_whitespace_p (charpos
)
14734 int bytepos
= CHAR_TO_BYTE (charpos
);
14737 while (bytepos
< ZV_BYTE
14738 && (c
= FETCH_CHAR (bytepos
),
14739 c
== ' ' || c
== '\t'))
14742 if (bytepos
>= ZV_BYTE
|| c
== '\n' || c
== '\r')
14744 if (bytepos
!= PT_BYTE
)
14751 /* Highlight trailing whitespace, if any, in ROW. */
14754 highlight_trailing_whitespace (f
, row
)
14756 struct glyph_row
*row
;
14758 int used
= row
->used
[TEXT_AREA
];
14762 struct glyph
*start
= row
->glyphs
[TEXT_AREA
];
14763 struct glyph
*glyph
= start
+ used
- 1;
14765 /* Skip over glyphs inserted to display the cursor at the
14766 end of a line, for extending the face of the last glyph
14767 to the end of the line on terminals, and for truncation
14768 and continuation glyphs. */
14769 while (glyph
>= start
14770 && glyph
->type
== CHAR_GLYPH
14771 && INTEGERP (glyph
->object
))
14774 /* If last glyph is a space or stretch, and it's trailing
14775 whitespace, set the face of all trailing whitespace glyphs in
14776 IT->glyph_row to `trailing-whitespace'. */
14778 && BUFFERP (glyph
->object
)
14779 && (glyph
->type
== STRETCH_GLYPH
14780 || (glyph
->type
== CHAR_GLYPH
14781 && glyph
->u
.ch
== ' '))
14782 && trailing_whitespace_p (glyph
->charpos
))
14784 int face_id
= lookup_named_face (f
, Qtrailing_whitespace
, 0, 0);
14788 while (glyph
>= start
14789 && BUFFERP (glyph
->object
)
14790 && (glyph
->type
== STRETCH_GLYPH
14791 || (glyph
->type
== CHAR_GLYPH
14792 && glyph
->u
.ch
== ' ')))
14793 (glyph
--)->face_id
= face_id
;
14799 /* Value is non-zero if glyph row ROW in window W should be
14800 used to hold the cursor. */
14803 cursor_row_p (w
, row
)
14805 struct glyph_row
*row
;
14807 int cursor_row_p
= 1;
14809 if (PT
== MATRIX_ROW_END_CHARPOS (row
))
14811 /* If the row ends with a newline from a string, we don't want
14812 the cursor there (if the row is continued it doesn't end in a
14814 if (CHARPOS (row
->end
.string_pos
) >= 0)
14815 cursor_row_p
= row
->continued_p
;
14816 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
))
14818 /* If the row ends in middle of a real character,
14819 and the line is continued, we want the cursor here.
14820 That's because MATRIX_ROW_END_CHARPOS would equal
14821 PT if PT is before the character. */
14822 if (!row
->ends_in_ellipsis_p
)
14823 cursor_row_p
= row
->continued_p
;
14825 /* If the row ends in an ellipsis, then
14826 MATRIX_ROW_END_CHARPOS will equal point after the invisible text.
14827 We want that position to be displayed after the ellipsis. */
14830 /* If the row ends at ZV, display the cursor at the end of that
14831 row instead of at the start of the row below. */
14832 else if (row
->ends_at_zv_p
)
14838 return cursor_row_p
;
14842 /* Construct the glyph row IT->glyph_row in the desired matrix of
14843 IT->w from text at the current position of IT. See dispextern.h
14844 for an overview of struct it. Value is non-zero if
14845 IT->glyph_row displays text, as opposed to a line displaying ZV
14852 struct glyph_row
*row
= it
->glyph_row
;
14853 int overlay_arrow_bitmap
;
14854 Lisp_Object overlay_arrow_string
;
14856 /* We always start displaying at hpos zero even if hscrolled. */
14857 xassert (it
->hpos
== 0 && it
->current_x
== 0);
14859 if (MATRIX_ROW_VPOS (row
, it
->w
->desired_matrix
)
14860 >= it
->w
->desired_matrix
->nrows
)
14862 it
->w
->nrows_scale_factor
++;
14863 fonts_changed_p
= 1;
14867 /* Is IT->w showing the region? */
14868 it
->w
->region_showing
= it
->region_beg_charpos
> 0 ? Qt
: Qnil
;
14870 /* Clear the result glyph row and enable it. */
14871 prepare_desired_row (row
);
14873 row
->y
= it
->current_y
;
14874 row
->start
= it
->start
;
14875 row
->continuation_lines_width
= it
->continuation_lines_width
;
14876 row
->displays_text_p
= 1;
14877 row
->starts_in_middle_of_char_p
= it
->starts_in_middle_of_char_p
;
14878 it
->starts_in_middle_of_char_p
= 0;
14880 /* Arrange the overlays nicely for our purposes. Usually, we call
14881 display_line on only one line at a time, in which case this
14882 can't really hurt too much, or we call it on lines which appear
14883 one after another in the buffer, in which case all calls to
14884 recenter_overlay_lists but the first will be pretty cheap. */
14885 recenter_overlay_lists (current_buffer
, IT_CHARPOS (*it
));
14887 /* Move over display elements that are not visible because we are
14888 hscrolled. This may stop at an x-position < IT->first_visible_x
14889 if the first glyph is partially visible or if we hit a line end. */
14890 if (it
->current_x
< it
->first_visible_x
)
14892 move_it_in_display_line_to (it
, ZV
, it
->first_visible_x
,
14893 MOVE_TO_POS
| MOVE_TO_X
);
14896 /* Get the initial row height. This is either the height of the
14897 text hscrolled, if there is any, or zero. */
14898 row
->ascent
= it
->max_ascent
;
14899 row
->height
= it
->max_ascent
+ it
->max_descent
;
14900 row
->phys_ascent
= it
->max_phys_ascent
;
14901 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
14902 row
->extra_line_spacing
= it
->max_extra_line_spacing
;
14904 /* Loop generating characters. The loop is left with IT on the next
14905 character to display. */
14908 int n_glyphs_before
, hpos_before
, x_before
;
14910 int ascent
= 0, descent
= 0, phys_ascent
= 0, phys_descent
= 0;
14912 /* Retrieve the next thing to display. Value is zero if end of
14914 if (!get_next_display_element (it
))
14916 /* Maybe add a space at the end of this line that is used to
14917 display the cursor there under X. Set the charpos of the
14918 first glyph of blank lines not corresponding to any text
14920 #ifdef HAVE_WINDOW_SYSTEM
14921 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
14922 row
->exact_window_width_line_p
= 1;
14924 #endif /* HAVE_WINDOW_SYSTEM */
14925 if ((append_space_for_newline (it
, 1) && row
->used
[TEXT_AREA
] == 1)
14926 || row
->used
[TEXT_AREA
] == 0)
14928 row
->glyphs
[TEXT_AREA
]->charpos
= -1;
14929 row
->displays_text_p
= 0;
14931 if (!NILP (XBUFFER (it
->w
->buffer
)->indicate_empty_lines
)
14932 && (!MINI_WINDOW_P (it
->w
)
14933 || (minibuf_level
&& EQ (it
->window
, minibuf_window
))))
14934 row
->indicate_empty_line_p
= 1;
14937 it
->continuation_lines_width
= 0;
14938 row
->ends_at_zv_p
= 1;
14942 /* Now, get the metrics of what we want to display. This also
14943 generates glyphs in `row' (which is IT->glyph_row). */
14944 n_glyphs_before
= row
->used
[TEXT_AREA
];
14947 /* Remember the line height so far in case the next element doesn't
14948 fit on the line. */
14949 if (!it
->truncate_lines_p
)
14951 ascent
= it
->max_ascent
;
14952 descent
= it
->max_descent
;
14953 phys_ascent
= it
->max_phys_ascent
;
14954 phys_descent
= it
->max_phys_descent
;
14957 PRODUCE_GLYPHS (it
);
14959 /* If this display element was in marginal areas, continue with
14961 if (it
->area
!= TEXT_AREA
)
14963 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
14964 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
14965 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
14966 row
->phys_height
= max (row
->phys_height
,
14967 it
->max_phys_ascent
+ it
->max_phys_descent
);
14968 row
->extra_line_spacing
= max (row
->extra_line_spacing
,
14969 it
->max_extra_line_spacing
);
14970 set_iterator_to_next (it
, 1);
14974 /* Does the display element fit on the line? If we truncate
14975 lines, we should draw past the right edge of the window. If
14976 we don't truncate, we want to stop so that we can display the
14977 continuation glyph before the right margin. If lines are
14978 continued, there are two possible strategies for characters
14979 resulting in more than 1 glyph (e.g. tabs): Display as many
14980 glyphs as possible in this line and leave the rest for the
14981 continuation line, or display the whole element in the next
14982 line. Original redisplay did the former, so we do it also. */
14983 nglyphs
= row
->used
[TEXT_AREA
] - n_glyphs_before
;
14984 hpos_before
= it
->hpos
;
14987 if (/* Not a newline. */
14989 /* Glyphs produced fit entirely in the line. */
14990 && it
->current_x
< it
->last_visible_x
)
14992 it
->hpos
+= nglyphs
;
14993 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
14994 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
14995 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
14996 row
->phys_height
= max (row
->phys_height
,
14997 it
->max_phys_ascent
+ it
->max_phys_descent
);
14998 row
->extra_line_spacing
= max (row
->extra_line_spacing
,
14999 it
->max_extra_line_spacing
);
15000 if (it
->current_x
- it
->pixel_width
< it
->first_visible_x
)
15001 row
->x
= x
- it
->first_visible_x
;
15006 struct glyph
*glyph
;
15008 for (i
= 0; i
< nglyphs
; ++i
, x
= new_x
)
15010 glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
15011 new_x
= x
+ glyph
->pixel_width
;
15013 if (/* Lines are continued. */
15014 !it
->truncate_lines_p
15015 && (/* Glyph doesn't fit on the line. */
15016 new_x
> it
->last_visible_x
15017 /* Or it fits exactly on a window system frame. */
15018 || (new_x
== it
->last_visible_x
15019 && FRAME_WINDOW_P (it
->f
))))
15021 /* End of a continued line. */
15024 || (new_x
== it
->last_visible_x
15025 && FRAME_WINDOW_P (it
->f
)))
15027 /* Current glyph is the only one on the line or
15028 fits exactly on the line. We must continue
15029 the line because we can't draw the cursor
15030 after the glyph. */
15031 row
->continued_p
= 1;
15032 it
->current_x
= new_x
;
15033 it
->continuation_lines_width
+= new_x
;
15035 if (i
== nglyphs
- 1)
15037 set_iterator_to_next (it
, 1);
15038 #ifdef HAVE_WINDOW_SYSTEM
15039 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
15041 if (!get_next_display_element (it
))
15043 row
->exact_window_width_line_p
= 1;
15044 it
->continuation_lines_width
= 0;
15045 row
->continued_p
= 0;
15046 row
->ends_at_zv_p
= 1;
15048 else if (ITERATOR_AT_END_OF_LINE_P (it
))
15050 row
->continued_p
= 0;
15051 row
->exact_window_width_line_p
= 1;
15054 #endif /* HAVE_WINDOW_SYSTEM */
15057 else if (CHAR_GLYPH_PADDING_P (*glyph
)
15058 && !FRAME_WINDOW_P (it
->f
))
15060 /* A padding glyph that doesn't fit on this line.
15061 This means the whole character doesn't fit
15063 row
->used
[TEXT_AREA
] = n_glyphs_before
;
15065 /* Fill the rest of the row with continuation
15066 glyphs like in 20.x. */
15067 while (row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
]
15068 < row
->glyphs
[1 + TEXT_AREA
])
15069 produce_special_glyphs (it
, IT_CONTINUATION
);
15071 row
->continued_p
= 1;
15072 it
->current_x
= x_before
;
15073 it
->continuation_lines_width
+= x_before
;
15075 /* Restore the height to what it was before the
15076 element not fitting on the line. */
15077 it
->max_ascent
= ascent
;
15078 it
->max_descent
= descent
;
15079 it
->max_phys_ascent
= phys_ascent
;
15080 it
->max_phys_descent
= phys_descent
;
15082 else if (it
->c
== '\t' && FRAME_WINDOW_P (it
->f
))
15084 /* A TAB that extends past the right edge of the
15085 window. This produces a single glyph on
15086 window system frames. We leave the glyph in
15087 this row and let it fill the row, but don't
15088 consume the TAB. */
15089 it
->continuation_lines_width
+= it
->last_visible_x
;
15090 row
->ends_in_middle_of_char_p
= 1;
15091 row
->continued_p
= 1;
15092 glyph
->pixel_width
= it
->last_visible_x
- x
;
15093 it
->starts_in_middle_of_char_p
= 1;
15097 /* Something other than a TAB that draws past
15098 the right edge of the window. Restore
15099 positions to values before the element. */
15100 row
->used
[TEXT_AREA
] = n_glyphs_before
+ i
;
15102 /* Display continuation glyphs. */
15103 if (!FRAME_WINDOW_P (it
->f
))
15104 produce_special_glyphs (it
, IT_CONTINUATION
);
15105 row
->continued_p
= 1;
15107 it
->continuation_lines_width
+= x
;
15109 if (nglyphs
> 1 && i
> 0)
15111 row
->ends_in_middle_of_char_p
= 1;
15112 it
->starts_in_middle_of_char_p
= 1;
15115 /* Restore the height to what it was before the
15116 element not fitting on the line. */
15117 it
->max_ascent
= ascent
;
15118 it
->max_descent
= descent
;
15119 it
->max_phys_ascent
= phys_ascent
;
15120 it
->max_phys_descent
= phys_descent
;
15125 else if (new_x
> it
->first_visible_x
)
15127 /* Increment number of glyphs actually displayed. */
15130 if (x
< it
->first_visible_x
)
15131 /* Glyph is partially visible, i.e. row starts at
15132 negative X position. */
15133 row
->x
= x
- it
->first_visible_x
;
15137 /* Glyph is completely off the left margin of the
15138 window. This should not happen because of the
15139 move_it_in_display_line at the start of this
15140 function, unless the text display area of the
15141 window is empty. */
15142 xassert (it
->first_visible_x
<= it
->last_visible_x
);
15146 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
15147 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
15148 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
15149 row
->phys_height
= max (row
->phys_height
,
15150 it
->max_phys_ascent
+ it
->max_phys_descent
);
15151 row
->extra_line_spacing
= max (row
->extra_line_spacing
,
15152 it
->max_extra_line_spacing
);
15154 /* End of this display line if row is continued. */
15155 if (row
->continued_p
|| row
->ends_at_zv_p
)
15160 /* Is this a line end? If yes, we're also done, after making
15161 sure that a non-default face is extended up to the right
15162 margin of the window. */
15163 if (ITERATOR_AT_END_OF_LINE_P (it
))
15165 int used_before
= row
->used
[TEXT_AREA
];
15167 row
->ends_in_newline_from_string_p
= STRINGP (it
->object
);
15169 #ifdef HAVE_WINDOW_SYSTEM
15170 /* Add a space at the end of the line that is used to
15171 display the cursor there. */
15172 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
15173 append_space_for_newline (it
, 0);
15174 #endif /* HAVE_WINDOW_SYSTEM */
15176 /* Extend the face to the end of the line. */
15177 extend_face_to_end_of_line (it
);
15179 /* Make sure we have the position. */
15180 if (used_before
== 0)
15181 row
->glyphs
[TEXT_AREA
]->charpos
= CHARPOS (it
->position
);
15183 /* Consume the line end. This skips over invisible lines. */
15184 set_iterator_to_next (it
, 1);
15185 it
->continuation_lines_width
= 0;
15189 /* Proceed with next display element. Note that this skips
15190 over lines invisible because of selective display. */
15191 set_iterator_to_next (it
, 1);
15193 /* If we truncate lines, we are done when the last displayed
15194 glyphs reach past the right margin of the window. */
15195 if (it
->truncate_lines_p
15196 && (FRAME_WINDOW_P (it
->f
)
15197 ? (it
->current_x
>= it
->last_visible_x
)
15198 : (it
->current_x
> it
->last_visible_x
)))
15200 /* Maybe add truncation glyphs. */
15201 if (!FRAME_WINDOW_P (it
->f
))
15205 for (i
= row
->used
[TEXT_AREA
] - 1; i
> 0; --i
)
15206 if (!CHAR_GLYPH_PADDING_P (row
->glyphs
[TEXT_AREA
][i
]))
15209 for (n
= row
->used
[TEXT_AREA
]; i
< n
; ++i
)
15211 row
->used
[TEXT_AREA
] = i
;
15212 produce_special_glyphs (it
, IT_TRUNCATION
);
15215 #ifdef HAVE_WINDOW_SYSTEM
15218 /* Don't truncate if we can overflow newline into fringe. */
15219 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
15221 if (!get_next_display_element (it
))
15223 it
->continuation_lines_width
= 0;
15224 row
->ends_at_zv_p
= 1;
15225 row
->exact_window_width_line_p
= 1;
15228 if (ITERATOR_AT_END_OF_LINE_P (it
))
15230 row
->exact_window_width_line_p
= 1;
15231 goto at_end_of_line
;
15235 #endif /* HAVE_WINDOW_SYSTEM */
15237 row
->truncated_on_right_p
= 1;
15238 it
->continuation_lines_width
= 0;
15239 reseat_at_next_visible_line_start (it
, 0);
15240 row
->ends_at_zv_p
= FETCH_BYTE (IT_BYTEPOS (*it
) - 1) != '\n';
15241 it
->hpos
= hpos_before
;
15242 it
->current_x
= x_before
;
15247 /* If line is not empty and hscrolled, maybe insert truncation glyphs
15248 at the left window margin. */
15249 if (it
->first_visible_x
15250 && IT_CHARPOS (*it
) != MATRIX_ROW_START_CHARPOS (row
))
15252 if (!FRAME_WINDOW_P (it
->f
))
15253 insert_left_trunc_glyphs (it
);
15254 row
->truncated_on_left_p
= 1;
15257 /* If the start of this line is the overlay arrow-position, then
15258 mark this glyph row as the one containing the overlay arrow.
15259 This is clearly a mess with variable size fonts. It would be
15260 better to let it be displayed like cursors under X. */
15261 if (! overlay_arrow_seen
15262 && (overlay_arrow_string
15263 = overlay_arrow_at_row (it
, row
, &overlay_arrow_bitmap
),
15264 !NILP (overlay_arrow_string
)))
15266 /* Overlay arrow in window redisplay is a fringe bitmap. */
15267 if (STRINGP (overlay_arrow_string
))
15269 struct glyph_row
*arrow_row
15270 = get_overlay_arrow_glyph_row (it
->w
, overlay_arrow_string
);
15271 struct glyph
*glyph
= arrow_row
->glyphs
[TEXT_AREA
];
15272 struct glyph
*arrow_end
= glyph
+ arrow_row
->used
[TEXT_AREA
];
15273 struct glyph
*p
= row
->glyphs
[TEXT_AREA
];
15274 struct glyph
*p2
, *end
;
15276 /* Copy the arrow glyphs. */
15277 while (glyph
< arrow_end
)
15280 /* Throw away padding glyphs. */
15282 end
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
];
15283 while (p2
< end
&& CHAR_GLYPH_PADDING_P (*p2
))
15289 row
->used
[TEXT_AREA
] = p2
- row
->glyphs
[TEXT_AREA
];
15294 it
->w
->overlay_arrow_bitmap
= overlay_arrow_bitmap
;
15295 row
->overlay_arrow_p
= 1;
15297 overlay_arrow_seen
= 1;
15300 /* Compute pixel dimensions of this line. */
15301 compute_line_metrics (it
);
15303 /* Remember the position at which this line ends. */
15304 row
->end
= it
->current
;
15306 /* Record whether this row ends inside an ellipsis. */
15307 row
->ends_in_ellipsis_p
15308 = (it
->method
== GET_FROM_DISPLAY_VECTOR
15309 && it
->ellipsis_p
);
15311 /* Save fringe bitmaps in this row. */
15312 row
->left_user_fringe_bitmap
= it
->left_user_fringe_bitmap
;
15313 row
->left_user_fringe_face_id
= it
->left_user_fringe_face_id
;
15314 row
->right_user_fringe_bitmap
= it
->right_user_fringe_bitmap
;
15315 row
->right_user_fringe_face_id
= it
->right_user_fringe_face_id
;
15317 it
->left_user_fringe_bitmap
= 0;
15318 it
->left_user_fringe_face_id
= 0;
15319 it
->right_user_fringe_bitmap
= 0;
15320 it
->right_user_fringe_face_id
= 0;
15322 /* Maybe set the cursor. */
15323 if (it
->w
->cursor
.vpos
< 0
15324 && PT
>= MATRIX_ROW_START_CHARPOS (row
)
15325 && PT
<= MATRIX_ROW_END_CHARPOS (row
)
15326 && cursor_row_p (it
->w
, row
))
15327 set_cursor_from_row (it
->w
, row
, it
->w
->desired_matrix
, 0, 0, 0, 0);
15329 /* Highlight trailing whitespace. */
15330 if (!NILP (Vshow_trailing_whitespace
))
15331 highlight_trailing_whitespace (it
->f
, it
->glyph_row
);
15333 /* Prepare for the next line. This line starts horizontally at (X
15334 HPOS) = (0 0). Vertical positions are incremented. As a
15335 convenience for the caller, IT->glyph_row is set to the next
15337 it
->current_x
= it
->hpos
= 0;
15338 it
->current_y
+= row
->height
;
15341 it
->start
= it
->current
;
15342 return row
->displays_text_p
;
15347 /***********************************************************************
15349 ***********************************************************************/
15351 /* Redisplay the menu bar in the frame for window W.
15353 The menu bar of X frames that don't have X toolkit support is
15354 displayed in a special window W->frame->menu_bar_window.
15356 The menu bar of terminal frames is treated specially as far as
15357 glyph matrices are concerned. Menu bar lines are not part of
15358 windows, so the update is done directly on the frame matrix rows
15359 for the menu bar. */
15362 display_menu_bar (w
)
15365 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
15370 /* Don't do all this for graphical frames. */
15372 if (!NILP (Vwindow_system
))
15375 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
15380 if (FRAME_MAC_P (f
))
15384 #ifdef USE_X_TOOLKIT
15385 xassert (!FRAME_WINDOW_P (f
));
15386 init_iterator (&it
, w
, -1, -1, f
->desired_matrix
->rows
, MENU_FACE_ID
);
15387 it
.first_visible_x
= 0;
15388 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
15389 #else /* not USE_X_TOOLKIT */
15390 if (FRAME_WINDOW_P (f
))
15392 /* Menu bar lines are displayed in the desired matrix of the
15393 dummy window menu_bar_window. */
15394 struct window
*menu_w
;
15395 xassert (WINDOWP (f
->menu_bar_window
));
15396 menu_w
= XWINDOW (f
->menu_bar_window
);
15397 init_iterator (&it
, menu_w
, -1, -1, menu_w
->desired_matrix
->rows
,
15399 it
.first_visible_x
= 0;
15400 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
15404 /* This is a TTY frame, i.e. character hpos/vpos are used as
15406 init_iterator (&it
, w
, -1, -1, f
->desired_matrix
->rows
,
15408 it
.first_visible_x
= 0;
15409 it
.last_visible_x
= FRAME_COLS (f
);
15411 #endif /* not USE_X_TOOLKIT */
15413 if (! mode_line_inverse_video
)
15414 /* Force the menu-bar to be displayed in the default face. */
15415 it
.base_face_id
= it
.face_id
= DEFAULT_FACE_ID
;
15417 /* Clear all rows of the menu bar. */
15418 for (i
= 0; i
< FRAME_MENU_BAR_LINES (f
); ++i
)
15420 struct glyph_row
*row
= it
.glyph_row
+ i
;
15421 clear_glyph_row (row
);
15422 row
->enabled_p
= 1;
15423 row
->full_width_p
= 1;
15426 /* Display all items of the menu bar. */
15427 items
= FRAME_MENU_BAR_ITEMS (it
.f
);
15428 for (i
= 0; i
< XVECTOR (items
)->size
; i
+= 4)
15430 Lisp_Object string
;
15432 /* Stop at nil string. */
15433 string
= AREF (items
, i
+ 1);
15437 /* Remember where item was displayed. */
15438 AREF (items
, i
+ 3) = make_number (it
.hpos
);
15440 /* Display the item, pad with one space. */
15441 if (it
.current_x
< it
.last_visible_x
)
15442 display_string (NULL
, string
, Qnil
, 0, 0, &it
,
15443 SCHARS (string
) + 1, 0, 0, -1);
15446 /* Fill out the line with spaces. */
15447 if (it
.current_x
< it
.last_visible_x
)
15448 display_string ("", Qnil
, Qnil
, 0, 0, &it
, -1, 0, 0, -1);
15450 /* Compute the total height of the lines. */
15451 compute_line_metrics (&it
);
15456 /***********************************************************************
15458 ***********************************************************************/
15460 /* Redisplay mode lines in the window tree whose root is WINDOW. If
15461 FORCE is non-zero, redisplay mode lines unconditionally.
15462 Otherwise, redisplay only mode lines that are garbaged. Value is
15463 the number of windows whose mode lines were redisplayed. */
15466 redisplay_mode_lines (window
, force
)
15467 Lisp_Object window
;
15472 while (!NILP (window
))
15474 struct window
*w
= XWINDOW (window
);
15476 if (WINDOWP (w
->hchild
))
15477 nwindows
+= redisplay_mode_lines (w
->hchild
, force
);
15478 else if (WINDOWP (w
->vchild
))
15479 nwindows
+= redisplay_mode_lines (w
->vchild
, force
);
15481 || FRAME_GARBAGED_P (XFRAME (w
->frame
))
15482 || !MATRIX_MODE_LINE_ROW (w
->current_matrix
)->enabled_p
)
15484 struct text_pos lpoint
;
15485 struct buffer
*old
= current_buffer
;
15487 /* Set the window's buffer for the mode line display. */
15488 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
15489 set_buffer_internal_1 (XBUFFER (w
->buffer
));
15491 /* Point refers normally to the selected window. For any
15492 other window, set up appropriate value. */
15493 if (!EQ (window
, selected_window
))
15495 struct text_pos pt
;
15497 SET_TEXT_POS_FROM_MARKER (pt
, w
->pointm
);
15498 if (CHARPOS (pt
) < BEGV
)
15499 TEMP_SET_PT_BOTH (BEGV
, BEGV_BYTE
);
15500 else if (CHARPOS (pt
) > (ZV
- 1))
15501 TEMP_SET_PT_BOTH (ZV
, ZV_BYTE
);
15503 TEMP_SET_PT_BOTH (CHARPOS (pt
), BYTEPOS (pt
));
15506 /* Display mode lines. */
15507 clear_glyph_matrix (w
->desired_matrix
);
15508 if (display_mode_lines (w
))
15511 w
->must_be_updated_p
= 1;
15514 /* Restore old settings. */
15515 set_buffer_internal_1 (old
);
15516 TEMP_SET_PT_BOTH (CHARPOS (lpoint
), BYTEPOS (lpoint
));
15526 /* Display the mode and/or top line of window W. Value is the number
15527 of mode lines displayed. */
15530 display_mode_lines (w
)
15533 Lisp_Object old_selected_window
, old_selected_frame
;
15536 old_selected_frame
= selected_frame
;
15537 selected_frame
= w
->frame
;
15538 old_selected_window
= selected_window
;
15539 XSETWINDOW (selected_window
, w
);
15541 /* These will be set while the mode line specs are processed. */
15542 line_number_displayed
= 0;
15543 w
->column_number_displayed
= Qnil
;
15545 if (WINDOW_WANTS_MODELINE_P (w
))
15547 struct window
*sel_w
= XWINDOW (old_selected_window
);
15549 /* Select mode line face based on the real selected window. */
15550 display_mode_line (w
, CURRENT_MODE_LINE_FACE_ID_3 (sel_w
, sel_w
, w
),
15551 current_buffer
->mode_line_format
);
15555 if (WINDOW_WANTS_HEADER_LINE_P (w
))
15557 display_mode_line (w
, HEADER_LINE_FACE_ID
,
15558 current_buffer
->header_line_format
);
15562 selected_frame
= old_selected_frame
;
15563 selected_window
= old_selected_window
;
15568 /* Display mode or top line of window W. FACE_ID specifies which line
15569 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
15570 FORMAT is the mode line format to display. Value is the pixel
15571 height of the mode line displayed. */
15574 display_mode_line (w
, face_id
, format
)
15576 enum face_id face_id
;
15577 Lisp_Object format
;
15582 init_iterator (&it
, w
, -1, -1, NULL
, face_id
);
15583 prepare_desired_row (it
.glyph_row
);
15585 it
.glyph_row
->mode_line_p
= 1;
15587 if (! mode_line_inverse_video
)
15588 /* Force the mode-line to be displayed in the default face. */
15589 it
.base_face_id
= it
.face_id
= DEFAULT_FACE_ID
;
15591 /* Temporarily make frame's keyboard the current kboard so that
15592 kboard-local variables in the mode_line_format will get the right
15594 push_frame_kboard (it
.f
);
15595 display_mode_element (&it
, 0, 0, 0, format
, Qnil
, 0);
15596 pop_frame_kboard ();
15598 /* Fill up with spaces. */
15599 display_string (" ", Qnil
, Qnil
, 0, 0, &it
, 10000, -1, -1, 0);
15601 compute_line_metrics (&it
);
15602 it
.glyph_row
->full_width_p
= 1;
15603 it
.glyph_row
->continued_p
= 0;
15604 it
.glyph_row
->truncated_on_left_p
= 0;
15605 it
.glyph_row
->truncated_on_right_p
= 0;
15607 /* Make a 3D mode-line have a shadow at its right end. */
15608 face
= FACE_FROM_ID (it
.f
, face_id
);
15609 extend_face_to_end_of_line (&it
);
15610 if (face
->box
!= FACE_NO_BOX
)
15612 struct glyph
*last
= (it
.glyph_row
->glyphs
[TEXT_AREA
]
15613 + it
.glyph_row
->used
[TEXT_AREA
] - 1);
15614 last
->right_box_line_p
= 1;
15617 return it
.glyph_row
->height
;
15620 /* Alist that caches the results of :propertize.
15621 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
15622 Lisp_Object mode_line_proptrans_alist
;
15624 /* List of strings making up the mode-line. */
15625 Lisp_Object mode_line_string_list
;
15627 /* Base face property when building propertized mode line string. */
15628 static Lisp_Object mode_line_string_face
;
15629 static Lisp_Object mode_line_string_face_prop
;
15632 /* Contribute ELT to the mode line for window IT->w. How it
15633 translates into text depends on its data type.
15635 IT describes the display environment in which we display, as usual.
15637 DEPTH is the depth in recursion. It is used to prevent
15638 infinite recursion here.
15640 FIELD_WIDTH is the number of characters the display of ELT should
15641 occupy in the mode line, and PRECISION is the maximum number of
15642 characters to display from ELT's representation. See
15643 display_string for details.
15645 Returns the hpos of the end of the text generated by ELT.
15647 PROPS is a property list to add to any string we encounter.
15649 If RISKY is nonzero, remove (disregard) any properties in any string
15650 we encounter, and ignore :eval and :propertize.
15652 If the global variable `frame_title_ptr' is non-NULL, then the output
15653 is passed to `store_frame_title' instead of `display_string'. */
15656 display_mode_element (it
, depth
, field_width
, precision
, elt
, props
, risky
)
15659 int field_width
, precision
;
15660 Lisp_Object elt
, props
;
15663 int n
= 0, field
, prec
;
15668 elt
= build_string ("*too-deep*");
15672 switch (SWITCH_ENUM_CAST (XTYPE (elt
)))
15676 /* A string: output it and check for %-constructs within it. */
15678 const unsigned char *this, *lisp_string
;
15680 if (!NILP (props
) || risky
)
15682 Lisp_Object oprops
, aelt
;
15683 oprops
= Ftext_properties_at (make_number (0), elt
);
15685 /* If the starting string's properties are not what
15686 we want, translate the string. Also, if the string
15687 is risky, do that anyway. */
15689 if (NILP (Fequal (props
, oprops
)) || risky
)
15691 /* If the starting string has properties,
15692 merge the specified ones onto the existing ones. */
15693 if (! NILP (oprops
) && !risky
)
15697 oprops
= Fcopy_sequence (oprops
);
15699 while (CONSP (tem
))
15701 oprops
= Fplist_put (oprops
, XCAR (tem
),
15702 XCAR (XCDR (tem
)));
15703 tem
= XCDR (XCDR (tem
));
15708 aelt
= Fassoc (elt
, mode_line_proptrans_alist
);
15709 if (! NILP (aelt
) && !NILP (Fequal (props
, XCDR (aelt
))))
15711 mode_line_proptrans_alist
15712 = Fcons (aelt
, Fdelq (aelt
, mode_line_proptrans_alist
));
15719 elt
= Fcopy_sequence (elt
);
15720 Fset_text_properties (make_number (0), Flength (elt
),
15722 /* Add this item to mode_line_proptrans_alist. */
15723 mode_line_proptrans_alist
15724 = Fcons (Fcons (elt
, props
),
15725 mode_line_proptrans_alist
);
15726 /* Truncate mode_line_proptrans_alist
15727 to at most 50 elements. */
15728 tem
= Fnthcdr (make_number (50),
15729 mode_line_proptrans_alist
);
15731 XSETCDR (tem
, Qnil
);
15736 this = SDATA (elt
);
15737 lisp_string
= this;
15741 prec
= precision
- n
;
15742 if (frame_title_ptr
)
15743 n
+= store_frame_title (SDATA (elt
), -1, prec
);
15744 else if (!NILP (mode_line_string_list
))
15745 n
+= store_mode_line_string (NULL
, elt
, 1, 0, prec
, Qnil
);
15747 n
+= display_string (NULL
, elt
, Qnil
, 0, 0, it
,
15748 0, prec
, 0, STRING_MULTIBYTE (elt
));
15753 while ((precision
<= 0 || n
< precision
)
15755 && (frame_title_ptr
15756 || !NILP (mode_line_string_list
)
15757 || it
->current_x
< it
->last_visible_x
))
15759 const unsigned char *last
= this;
15761 /* Advance to end of string or next format specifier. */
15762 while ((c
= *this++) != '\0' && c
!= '%')
15765 if (this - 1 != last
)
15767 int nchars
, nbytes
;
15769 /* Output to end of string or up to '%'. Field width
15770 is length of string. Don't output more than
15771 PRECISION allows us. */
15774 prec
= c_string_width (last
, this - last
, precision
- n
,
15777 if (frame_title_ptr
)
15778 n
+= store_frame_title (last
, 0, prec
);
15779 else if (!NILP (mode_line_string_list
))
15781 int bytepos
= last
- lisp_string
;
15782 int charpos
= string_byte_to_char (elt
, bytepos
);
15783 int endpos
= (precision
<= 0
15784 ? string_byte_to_char (elt
,
15785 this - lisp_string
)
15786 : charpos
+ nchars
);
15788 n
+= store_mode_line_string (NULL
,
15789 Fsubstring (elt
, make_number (charpos
),
15790 make_number (endpos
)),
15795 int bytepos
= last
- lisp_string
;
15796 int charpos
= string_byte_to_char (elt
, bytepos
);
15797 n
+= display_string (NULL
, elt
, Qnil
, 0, charpos
,
15799 STRING_MULTIBYTE (elt
));
15802 else /* c == '%' */
15804 const unsigned char *percent_position
= this;
15806 /* Get the specified minimum width. Zero means
15809 while ((c
= *this++) >= '0' && c
<= '9')
15810 field
= field
* 10 + c
- '0';
15812 /* Don't pad beyond the total padding allowed. */
15813 if (field_width
- n
> 0 && field
> field_width
- n
)
15814 field
= field_width
- n
;
15816 /* Note that either PRECISION <= 0 or N < PRECISION. */
15817 prec
= precision
- n
;
15820 n
+= display_mode_element (it
, depth
, field
, prec
,
15821 Vglobal_mode_string
, props
,
15826 int bytepos
, charpos
;
15827 unsigned char *spec
;
15829 bytepos
= percent_position
- lisp_string
;
15830 charpos
= (STRING_MULTIBYTE (elt
)
15831 ? string_byte_to_char (elt
, bytepos
)
15835 = decode_mode_spec (it
->w
, c
, field
, prec
, &multibyte
);
15837 if (frame_title_ptr
)
15838 n
+= store_frame_title (spec
, field
, prec
);
15839 else if (!NILP (mode_line_string_list
))
15841 int len
= strlen (spec
);
15842 Lisp_Object tem
= make_string (spec
, len
);
15843 props
= Ftext_properties_at (make_number (charpos
), elt
);
15844 /* Should only keep face property in props */
15845 n
+= store_mode_line_string (NULL
, tem
, 0, field
, prec
, props
);
15849 int nglyphs_before
, nwritten
;
15851 nglyphs_before
= it
->glyph_row
->used
[TEXT_AREA
];
15852 nwritten
= display_string (spec
, Qnil
, elt
,
15857 /* Assign to the glyphs written above the
15858 string where the `%x' came from, position
15862 struct glyph
*glyph
15863 = (it
->glyph_row
->glyphs
[TEXT_AREA
]
15867 for (i
= 0; i
< nwritten
; ++i
)
15869 glyph
[i
].object
= elt
;
15870 glyph
[i
].charpos
= charpos
;
15885 /* A symbol: process the value of the symbol recursively
15886 as if it appeared here directly. Avoid error if symbol void.
15887 Special case: if value of symbol is a string, output the string
15890 register Lisp_Object tem
;
15892 /* If the variable is not marked as risky to set
15893 then its contents are risky to use. */
15894 if (NILP (Fget (elt
, Qrisky_local_variable
)))
15897 tem
= Fboundp (elt
);
15900 tem
= Fsymbol_value (elt
);
15901 /* If value is a string, output that string literally:
15902 don't check for % within it. */
15906 if (!EQ (tem
, elt
))
15908 /* Give up right away for nil or t. */
15918 register Lisp_Object car
, tem
;
15920 /* A cons cell: five distinct cases.
15921 If first element is :eval or :propertize, do something special.
15922 If first element is a string or a cons, process all the elements
15923 and effectively concatenate them.
15924 If first element is a negative number, truncate displaying cdr to
15925 at most that many characters. If positive, pad (with spaces)
15926 to at least that many characters.
15927 If first element is a symbol, process the cadr or caddr recursively
15928 according to whether the symbol's value is non-nil or nil. */
15930 if (EQ (car
, QCeval
))
15932 /* An element of the form (:eval FORM) means evaluate FORM
15933 and use the result as mode line elements. */
15938 if (CONSP (XCDR (elt
)))
15941 spec
= safe_eval (XCAR (XCDR (elt
)));
15942 n
+= display_mode_element (it
, depth
, field_width
- n
,
15943 precision
- n
, spec
, props
,
15947 else if (EQ (car
, QCpropertize
))
15949 /* An element of the form (:propertize ELT PROPS...)
15950 means display ELT but applying properties PROPS. */
15955 if (CONSP (XCDR (elt
)))
15956 n
+= display_mode_element (it
, depth
, field_width
- n
,
15957 precision
- n
, XCAR (XCDR (elt
)),
15958 XCDR (XCDR (elt
)), risky
);
15960 else if (SYMBOLP (car
))
15962 tem
= Fboundp (car
);
15966 /* elt is now the cdr, and we know it is a cons cell.
15967 Use its car if CAR has a non-nil value. */
15970 tem
= Fsymbol_value (car
);
15977 /* Symbol's value is nil (or symbol is unbound)
15978 Get the cddr of the original list
15979 and if possible find the caddr and use that. */
15983 else if (!CONSP (elt
))
15988 else if (INTEGERP (car
))
15990 register int lim
= XINT (car
);
15994 /* Negative int means reduce maximum width. */
15995 if (precision
<= 0)
15998 precision
= min (precision
, -lim
);
16002 /* Padding specified. Don't let it be more than
16003 current maximum. */
16005 lim
= min (precision
, lim
);
16007 /* If that's more padding than already wanted, queue it.
16008 But don't reduce padding already specified even if
16009 that is beyond the current truncation point. */
16010 field_width
= max (lim
, field_width
);
16014 else if (STRINGP (car
) || CONSP (car
))
16016 register int limit
= 50;
16017 /* Limit is to protect against circular lists. */
16020 && (precision
<= 0 || n
< precision
))
16022 n
+= display_mode_element (it
, depth
, field_width
- n
,
16023 precision
- n
, XCAR (elt
),
16033 elt
= build_string ("*invalid*");
16037 /* Pad to FIELD_WIDTH. */
16038 if (field_width
> 0 && n
< field_width
)
16040 if (frame_title_ptr
)
16041 n
+= store_frame_title ("", field_width
- n
, 0);
16042 else if (!NILP (mode_line_string_list
))
16043 n
+= store_mode_line_string ("", Qnil
, 0, field_width
- n
, 0, Qnil
);
16045 n
+= display_string ("", Qnil
, Qnil
, 0, 0, it
, field_width
- n
,
16052 /* Store a mode-line string element in mode_line_string_list.
16054 If STRING is non-null, display that C string. Otherwise, the Lisp
16055 string LISP_STRING is displayed.
16057 FIELD_WIDTH is the minimum number of output glyphs to produce.
16058 If STRING has fewer characters than FIELD_WIDTH, pad to the right
16059 with spaces. FIELD_WIDTH <= 0 means don't pad.
16061 PRECISION is the maximum number of characters to output from
16062 STRING. PRECISION <= 0 means don't truncate the string.
16064 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
16065 properties to the string.
16067 PROPS are the properties to add to the string.
16068 The mode_line_string_face face property is always added to the string.
16072 store_mode_line_string (string
, lisp_string
, copy_string
, field_width
, precision
, props
)
16074 Lisp_Object lisp_string
;
16083 if (string
!= NULL
)
16085 len
= strlen (string
);
16086 if (precision
> 0 && len
> precision
)
16088 lisp_string
= make_string (string
, len
);
16090 props
= mode_line_string_face_prop
;
16091 else if (!NILP (mode_line_string_face
))
16093 Lisp_Object face
= Fsafe_plist_get (props
, Qface
);
16094 props
= Fcopy_sequence (props
);
16096 face
= mode_line_string_face
;
16098 face
= Fcons (face
, Fcons (mode_line_string_face
, Qnil
));
16099 props
= Fplist_put (props
, Qface
, face
);
16101 Fadd_text_properties (make_number (0), make_number (len
),
16102 props
, lisp_string
);
16106 len
= XFASTINT (Flength (lisp_string
));
16107 if (precision
> 0 && len
> precision
)
16110 lisp_string
= Fsubstring (lisp_string
, make_number (0), make_number (len
));
16113 if (!NILP (mode_line_string_face
))
16117 props
= Ftext_properties_at (make_number (0), lisp_string
);
16118 face
= Fsafe_plist_get (props
, Qface
);
16120 face
= mode_line_string_face
;
16122 face
= Fcons (face
, Fcons (mode_line_string_face
, Qnil
));
16123 props
= Fcons (Qface
, Fcons (face
, Qnil
));
16125 lisp_string
= Fcopy_sequence (lisp_string
);
16128 Fadd_text_properties (make_number (0), make_number (len
),
16129 props
, lisp_string
);
16134 mode_line_string_list
= Fcons (lisp_string
, mode_line_string_list
);
16138 if (field_width
> len
)
16140 field_width
-= len
;
16141 lisp_string
= Fmake_string (make_number (field_width
), make_number (' '));
16143 Fadd_text_properties (make_number (0), make_number (field_width
),
16144 props
, lisp_string
);
16145 mode_line_string_list
= Fcons (lisp_string
, mode_line_string_list
);
16153 DEFUN ("format-mode-line", Fformat_mode_line
, Sformat_mode_line
,
16155 doc
: /* Format a string out of a mode line format specification.
16156 First arg FORMAT specifies the mode line format (see `mode-line-format'
16157 for details) to use.
16159 Optional second arg FACE specifies the face property to put
16160 on all characters for which no face is specified.
16161 t means whatever face the window's mode line currently uses
16162 \(either `mode-line' or `mode-line-inactive', depending).
16163 nil means the default is no face property.
16164 If FACE is an integer, the value string has no text properties.
16166 Optional third and fourth args WINDOW and BUFFER specify the window
16167 and buffer to use as the context for the formatting (defaults
16168 are the selected window and the window's buffer). */)
16169 (format
, face
, window
, buffer
)
16170 Lisp_Object format
, face
, window
, buffer
;
16175 struct buffer
*old_buffer
= NULL
;
16177 int no_props
= INTEGERP (face
);
16180 window
= selected_window
;
16181 CHECK_WINDOW (window
);
16182 w
= XWINDOW (window
);
16185 buffer
= w
->buffer
;
16186 CHECK_BUFFER (buffer
);
16189 return build_string ("");
16197 face
= (EQ (window
, selected_window
) ? Qmode_line
: Qmode_line_inactive
);
16198 face_id
= lookup_named_face (XFRAME (WINDOW_FRAME (w
)), face
, 0, 0);
16202 face_id
= DEFAULT_FACE_ID
;
16204 if (XBUFFER (buffer
) != current_buffer
)
16206 old_buffer
= current_buffer
;
16207 set_buffer_internal_1 (XBUFFER (buffer
));
16210 init_iterator (&it
, w
, -1, -1, NULL
, face_id
);
16214 mode_line_string_face
= face
;
16215 mode_line_string_face_prop
16216 = (NILP (face
) ? Qnil
: Fcons (Qface
, Fcons (face
, Qnil
)));
16218 /* We need a dummy last element in mode_line_string_list to
16219 indicate we are building the propertized mode-line string.
16220 Using mode_line_string_face_prop here GC protects it. */
16221 mode_line_string_list
16222 = Fcons (mode_line_string_face_prop
, Qnil
);
16223 frame_title_ptr
= NULL
;
16227 mode_line_string_face_prop
= Qnil
;
16228 mode_line_string_list
= Qnil
;
16229 frame_title_ptr
= frame_title_buf
;
16232 push_frame_kboard (it
.f
);
16233 display_mode_element (&it
, 0, 0, 0, format
, Qnil
, 0);
16234 pop_frame_kboard ();
16237 set_buffer_internal_1 (old_buffer
);
16242 mode_line_string_list
= Fnreverse (mode_line_string_list
);
16243 str
= Fmapconcat (intern ("identity"), XCDR (mode_line_string_list
),
16244 make_string ("", 0));
16245 mode_line_string_face_prop
= Qnil
;
16246 mode_line_string_list
= Qnil
;
16250 len
= frame_title_ptr
- frame_title_buf
;
16251 if (len
> 0 && frame_title_ptr
[-1] == '-')
16253 /* Mode lines typically ends with numerous dashes; reduce to two dashes. */
16254 while (frame_title_ptr
> frame_title_buf
&& *--frame_title_ptr
== '-')
16256 frame_title_ptr
+= 3; /* restore last non-dash + two dashes */
16257 if (len
> frame_title_ptr
- frame_title_buf
)
16258 len
= frame_title_ptr
- frame_title_buf
;
16261 frame_title_ptr
= NULL
;
16262 return make_string (frame_title_buf
, len
);
16265 /* Write a null-terminated, right justified decimal representation of
16266 the positive integer D to BUF using a minimal field width WIDTH. */
16269 pint2str (buf
, width
, d
)
16270 register char *buf
;
16271 register int width
;
16274 register char *p
= buf
;
16282 *p
++ = d
% 10 + '0';
16287 for (width
-= (int) (p
- buf
); width
> 0; --width
)
16298 /* Write a null-terminated, right justified decimal and "human
16299 readable" representation of the nonnegative integer D to BUF using
16300 a minimal field width WIDTH. D should be smaller than 999.5e24. */
16302 static const char power_letter
[] =
16316 pint2hrstr (buf
, width
, d
)
16321 /* We aim to represent the nonnegative integer D as
16322 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
16325 /* -1 means: do not use TENTHS. */
16329 /* Length of QUOTIENT.TENTHS as a string. */
16335 if (1000 <= quotient
)
16337 /* Scale to the appropriate EXPONENT. */
16340 remainder
= quotient
% 1000;
16344 while (1000 <= quotient
);
16346 /* Round to nearest and decide whether to use TENTHS or not. */
16349 tenths
= remainder
/ 100;
16350 if (50 <= remainder
% 100)
16357 if (quotient
== 10)
16365 if (500 <= remainder
)
16367 if (quotient
< 999)
16378 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
16379 if (tenths
== -1 && quotient
<= 99)
16386 p
= psuffix
= buf
+ max (width
, length
);
16388 /* Print EXPONENT. */
16390 *psuffix
++ = power_letter
[exponent
];
16393 /* Print TENTHS. */
16396 *--p
= '0' + tenths
;
16400 /* Print QUOTIENT. */
16403 int digit
= quotient
% 10;
16404 *--p
= '0' + digit
;
16406 while ((quotient
/= 10) != 0);
16408 /* Print leading spaces. */
16413 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
16414 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
16415 type of CODING_SYSTEM. Return updated pointer into BUF. */
16417 static unsigned char invalid_eol_type
[] = "(*invalid*)";
16420 decode_mode_spec_coding (coding_system
, buf
, eol_flag
)
16421 Lisp_Object coding_system
;
16422 register char *buf
;
16426 int multibyte
= !NILP (current_buffer
->enable_multibyte_characters
);
16427 const unsigned char *eol_str
;
16429 /* The EOL conversion we are using. */
16430 Lisp_Object eoltype
;
16432 val
= Fget (coding_system
, Qcoding_system
);
16435 if (!VECTORP (val
)) /* Not yet decided. */
16440 eoltype
= eol_mnemonic_undecided
;
16441 /* Don't mention EOL conversion if it isn't decided. */
16445 Lisp_Object eolvalue
;
16447 eolvalue
= Fget (coding_system
, Qeol_type
);
16450 *buf
++ = XFASTINT (AREF (val
, 1));
16454 /* The EOL conversion that is normal on this system. */
16456 if (NILP (eolvalue
)) /* Not yet decided. */
16457 eoltype
= eol_mnemonic_undecided
;
16458 else if (VECTORP (eolvalue
)) /* Not yet decided. */
16459 eoltype
= eol_mnemonic_undecided
;
16460 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
16461 eoltype
= (XFASTINT (eolvalue
) == 0
16462 ? eol_mnemonic_unix
16463 : (XFASTINT (eolvalue
) == 1
16464 ? eol_mnemonic_dos
: eol_mnemonic_mac
));
16470 /* Mention the EOL conversion if it is not the usual one. */
16471 if (STRINGP (eoltype
))
16473 eol_str
= SDATA (eoltype
);
16474 eol_str_len
= SBYTES (eoltype
);
16476 else if (INTEGERP (eoltype
)
16477 && CHAR_VALID_P (XINT (eoltype
), 0))
16479 unsigned char *tmp
= (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH
);
16480 eol_str_len
= CHAR_STRING (XINT (eoltype
), tmp
);
16485 eol_str
= invalid_eol_type
;
16486 eol_str_len
= sizeof (invalid_eol_type
) - 1;
16488 bcopy (eol_str
, buf
, eol_str_len
);
16489 buf
+= eol_str_len
;
16495 /* Return a string for the output of a mode line %-spec for window W,
16496 generated by character C. PRECISION >= 0 means don't return a
16497 string longer than that value. FIELD_WIDTH > 0 means pad the
16498 string returned with spaces to that value. Return 1 in *MULTIBYTE
16499 if the result is multibyte text.
16501 Note we operate on the current buffer for most purposes,
16502 the exception being w->base_line_pos. */
16504 static char lots_of_dashes
[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
16507 decode_mode_spec (w
, c
, field_width
, precision
, multibyte
)
16510 int field_width
, precision
;
16514 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
16515 char *decode_mode_spec_buf
= f
->decode_mode_spec_buffer
;
16516 struct buffer
*b
= current_buffer
;
16524 if (!NILP (b
->read_only
))
16526 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
16531 /* This differs from %* only for a modified read-only buffer. */
16532 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
16534 if (!NILP (b
->read_only
))
16539 /* This differs from %* in ignoring read-only-ness. */
16540 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
16552 if (command_loop_level
> 5)
16554 p
= decode_mode_spec_buf
;
16555 for (i
= 0; i
< command_loop_level
; i
++)
16558 return decode_mode_spec_buf
;
16566 if (command_loop_level
> 5)
16568 p
= decode_mode_spec_buf
;
16569 for (i
= 0; i
< command_loop_level
; i
++)
16572 return decode_mode_spec_buf
;
16579 /* Let lots_of_dashes be a string of infinite length. */
16580 if (!NILP (mode_line_string_list
))
16582 if (field_width
<= 0
16583 || field_width
> sizeof (lots_of_dashes
))
16585 for (i
= 0; i
< FRAME_MESSAGE_BUF_SIZE (f
) - 1; ++i
)
16586 decode_mode_spec_buf
[i
] = '-';
16587 decode_mode_spec_buf
[i
] = '\0';
16588 return decode_mode_spec_buf
;
16591 return lots_of_dashes
;
16600 int col
= (int) current_column (); /* iftc */
16601 w
->column_number_displayed
= make_number (col
);
16602 pint2str (decode_mode_spec_buf
, field_width
, col
);
16603 return decode_mode_spec_buf
;
16607 /* %F displays the frame name. */
16608 if (!NILP (f
->title
))
16609 return (char *) SDATA (f
->title
);
16610 if (f
->explicit_name
|| ! FRAME_WINDOW_P (f
))
16611 return (char *) SDATA (f
->name
);
16620 int size
= ZV
- BEGV
;
16621 pint2str (decode_mode_spec_buf
, field_width
, size
);
16622 return decode_mode_spec_buf
;
16627 int size
= ZV
- BEGV
;
16628 pint2hrstr (decode_mode_spec_buf
, field_width
, size
);
16629 return decode_mode_spec_buf
;
16634 int startpos
= XMARKER (w
->start
)->charpos
;
16635 int startpos_byte
= marker_byte_position (w
->start
);
16636 int line
, linepos
, linepos_byte
, topline
;
16638 int height
= WINDOW_TOTAL_LINES (w
);
16640 /* If we decided that this buffer isn't suitable for line numbers,
16641 don't forget that too fast. */
16642 if (EQ (w
->base_line_pos
, w
->buffer
))
16644 /* But do forget it, if the window shows a different buffer now. */
16645 else if (BUFFERP (w
->base_line_pos
))
16646 w
->base_line_pos
= Qnil
;
16648 /* If the buffer is very big, don't waste time. */
16649 if (INTEGERP (Vline_number_display_limit
)
16650 && BUF_ZV (b
) - BUF_BEGV (b
) > XINT (Vline_number_display_limit
))
16652 w
->base_line_pos
= Qnil
;
16653 w
->base_line_number
= Qnil
;
16657 if (!NILP (w
->base_line_number
)
16658 && !NILP (w
->base_line_pos
)
16659 && XFASTINT (w
->base_line_pos
) <= startpos
)
16661 line
= XFASTINT (w
->base_line_number
);
16662 linepos
= XFASTINT (w
->base_line_pos
);
16663 linepos_byte
= buf_charpos_to_bytepos (b
, linepos
);
16668 linepos
= BUF_BEGV (b
);
16669 linepos_byte
= BUF_BEGV_BYTE (b
);
16672 /* Count lines from base line to window start position. */
16673 nlines
= display_count_lines (linepos
, linepos_byte
,
16677 topline
= nlines
+ line
;
16679 /* Determine a new base line, if the old one is too close
16680 or too far away, or if we did not have one.
16681 "Too close" means it's plausible a scroll-down would
16682 go back past it. */
16683 if (startpos
== BUF_BEGV (b
))
16685 w
->base_line_number
= make_number (topline
);
16686 w
->base_line_pos
= make_number (BUF_BEGV (b
));
16688 else if (nlines
< height
+ 25 || nlines
> height
* 3 + 50
16689 || linepos
== BUF_BEGV (b
))
16691 int limit
= BUF_BEGV (b
);
16692 int limit_byte
= BUF_BEGV_BYTE (b
);
16694 int distance
= (height
* 2 + 30) * line_number_display_limit_width
;
16696 if (startpos
- distance
> limit
)
16698 limit
= startpos
- distance
;
16699 limit_byte
= CHAR_TO_BYTE (limit
);
16702 nlines
= display_count_lines (startpos
, startpos_byte
,
16704 - (height
* 2 + 30),
16706 /* If we couldn't find the lines we wanted within
16707 line_number_display_limit_width chars per line,
16708 give up on line numbers for this window. */
16709 if (position
== limit_byte
&& limit
== startpos
- distance
)
16711 w
->base_line_pos
= w
->buffer
;
16712 w
->base_line_number
= Qnil
;
16716 w
->base_line_number
= make_number (topline
- nlines
);
16717 w
->base_line_pos
= make_number (BYTE_TO_CHAR (position
));
16720 /* Now count lines from the start pos to point. */
16721 nlines
= display_count_lines (startpos
, startpos_byte
,
16722 PT_BYTE
, PT
, &junk
);
16724 /* Record that we did display the line number. */
16725 line_number_displayed
= 1;
16727 /* Make the string to show. */
16728 pint2str (decode_mode_spec_buf
, field_width
, topline
+ nlines
);
16729 return decode_mode_spec_buf
;
16732 char* p
= decode_mode_spec_buf
;
16733 int pad
= field_width
- 2;
16739 return decode_mode_spec_buf
;
16745 obj
= b
->mode_name
;
16749 if (BUF_BEGV (b
) > BUF_BEG (b
) || BUF_ZV (b
) < BUF_Z (b
))
16755 int pos
= marker_position (w
->start
);
16756 int total
= BUF_ZV (b
) - BUF_BEGV (b
);
16758 if (XFASTINT (w
->window_end_pos
) <= BUF_Z (b
) - BUF_ZV (b
))
16760 if (pos
<= BUF_BEGV (b
))
16765 else if (pos
<= BUF_BEGV (b
))
16769 if (total
> 1000000)
16770 /* Do it differently for a large value, to avoid overflow. */
16771 total
= ((pos
- BUF_BEGV (b
)) + (total
/ 100) - 1) / (total
/ 100);
16773 total
= ((pos
- BUF_BEGV (b
)) * 100 + total
- 1) / total
;
16774 /* We can't normally display a 3-digit number,
16775 so get us a 2-digit number that is close. */
16778 sprintf (decode_mode_spec_buf
, "%2d%%", total
);
16779 return decode_mode_spec_buf
;
16783 /* Display percentage of size above the bottom of the screen. */
16786 int toppos
= marker_position (w
->start
);
16787 int botpos
= BUF_Z (b
) - XFASTINT (w
->window_end_pos
);
16788 int total
= BUF_ZV (b
) - BUF_BEGV (b
);
16790 if (botpos
>= BUF_ZV (b
))
16792 if (toppos
<= BUF_BEGV (b
))
16799 if (total
> 1000000)
16800 /* Do it differently for a large value, to avoid overflow. */
16801 total
= ((botpos
- BUF_BEGV (b
)) + (total
/ 100) - 1) / (total
/ 100);
16803 total
= ((botpos
- BUF_BEGV (b
)) * 100 + total
- 1) / total
;
16804 /* We can't normally display a 3-digit number,
16805 so get us a 2-digit number that is close. */
16808 if (toppos
<= BUF_BEGV (b
))
16809 sprintf (decode_mode_spec_buf
, "Top%2d%%", total
);
16811 sprintf (decode_mode_spec_buf
, "%2d%%", total
);
16812 return decode_mode_spec_buf
;
16817 /* status of process */
16818 obj
= Fget_buffer_process (Fcurrent_buffer ());
16820 return "no process";
16821 #ifdef subprocesses
16822 obj
= Fsymbol_name (Fprocess_status (obj
));
16826 case 't': /* indicate TEXT or BINARY */
16827 #ifdef MODE_LINE_BINARY_TEXT
16828 return MODE_LINE_BINARY_TEXT (b
);
16834 /* coding-system (not including end-of-line format) */
16836 /* coding-system (including end-of-line type) */
16838 int eol_flag
= (c
== 'Z');
16839 char *p
= decode_mode_spec_buf
;
16841 if (! FRAME_WINDOW_P (f
))
16843 /* No need to mention EOL here--the terminal never needs
16844 to do EOL conversion. */
16845 p
= decode_mode_spec_coding (keyboard_coding
.symbol
, p
, 0);
16846 p
= decode_mode_spec_coding (terminal_coding
.symbol
, p
, 0);
16848 p
= decode_mode_spec_coding (b
->buffer_file_coding_system
,
16851 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
16852 #ifdef subprocesses
16853 obj
= Fget_buffer_process (Fcurrent_buffer ());
16854 if (PROCESSP (obj
))
16856 p
= decode_mode_spec_coding (XPROCESS (obj
)->decode_coding_system
,
16858 p
= decode_mode_spec_coding (XPROCESS (obj
)->encode_coding_system
,
16861 #endif /* subprocesses */
16864 return decode_mode_spec_buf
;
16870 *multibyte
= STRING_MULTIBYTE (obj
);
16871 return (char *) SDATA (obj
);
16878 /* Count up to COUNT lines starting from START / START_BYTE.
16879 But don't go beyond LIMIT_BYTE.
16880 Return the number of lines thus found (always nonnegative).
16882 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
16885 display_count_lines (start
, start_byte
, limit_byte
, count
, byte_pos_ptr
)
16886 int start
, start_byte
, limit_byte
, count
;
16889 register unsigned char *cursor
;
16890 unsigned char *base
;
16892 register int ceiling
;
16893 register unsigned char *ceiling_addr
;
16894 int orig_count
= count
;
16896 /* If we are not in selective display mode,
16897 check only for newlines. */
16898 int selective_display
= (!NILP (current_buffer
->selective_display
)
16899 && !INTEGERP (current_buffer
->selective_display
));
16903 while (start_byte
< limit_byte
)
16905 ceiling
= BUFFER_CEILING_OF (start_byte
);
16906 ceiling
= min (limit_byte
- 1, ceiling
);
16907 ceiling_addr
= BYTE_POS_ADDR (ceiling
) + 1;
16908 base
= (cursor
= BYTE_POS_ADDR (start_byte
));
16911 if (selective_display
)
16912 while (*cursor
!= '\n' && *cursor
!= 015 && ++cursor
!= ceiling_addr
)
16915 while (*cursor
!= '\n' && ++cursor
!= ceiling_addr
)
16918 if (cursor
!= ceiling_addr
)
16922 start_byte
+= cursor
- base
+ 1;
16923 *byte_pos_ptr
= start_byte
;
16927 if (++cursor
== ceiling_addr
)
16933 start_byte
+= cursor
- base
;
16938 while (start_byte
> limit_byte
)
16940 ceiling
= BUFFER_FLOOR_OF (start_byte
- 1);
16941 ceiling
= max (limit_byte
, ceiling
);
16942 ceiling_addr
= BYTE_POS_ADDR (ceiling
) - 1;
16943 base
= (cursor
= BYTE_POS_ADDR (start_byte
- 1) + 1);
16946 if (selective_display
)
16947 while (--cursor
!= ceiling_addr
16948 && *cursor
!= '\n' && *cursor
!= 015)
16951 while (--cursor
!= ceiling_addr
&& *cursor
!= '\n')
16954 if (cursor
!= ceiling_addr
)
16958 start_byte
+= cursor
- base
+ 1;
16959 *byte_pos_ptr
= start_byte
;
16960 /* When scanning backwards, we should
16961 not count the newline posterior to which we stop. */
16962 return - orig_count
- 1;
16968 /* Here we add 1 to compensate for the last decrement
16969 of CURSOR, which took it past the valid range. */
16970 start_byte
+= cursor
- base
+ 1;
16974 *byte_pos_ptr
= limit_byte
;
16977 return - orig_count
+ count
;
16978 return orig_count
- count
;
16984 /***********************************************************************
16986 ***********************************************************************/
16988 /* Display a NUL-terminated string, starting with index START.
16990 If STRING is non-null, display that C string. Otherwise, the Lisp
16991 string LISP_STRING is displayed.
16993 If FACE_STRING is not nil, FACE_STRING_POS is a position in
16994 FACE_STRING. Display STRING or LISP_STRING with the face at
16995 FACE_STRING_POS in FACE_STRING:
16997 Display the string in the environment given by IT, but use the
16998 standard display table, temporarily.
17000 FIELD_WIDTH is the minimum number of output glyphs to produce.
17001 If STRING has fewer characters than FIELD_WIDTH, pad to the right
17002 with spaces. If STRING has more characters, more than FIELD_WIDTH
17003 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
17005 PRECISION is the maximum number of characters to output from
17006 STRING. PRECISION < 0 means don't truncate the string.
17008 This is roughly equivalent to printf format specifiers:
17010 FIELD_WIDTH PRECISION PRINTF
17011 ----------------------------------------
17017 MULTIBYTE zero means do not display multibyte chars, > 0 means do
17018 display them, and < 0 means obey the current buffer's value of
17019 enable_multibyte_characters.
17021 Value is the number of glyphs produced. */
17024 display_string (string
, lisp_string
, face_string
, face_string_pos
,
17025 start
, it
, field_width
, precision
, max_x
, multibyte
)
17026 unsigned char *string
;
17027 Lisp_Object lisp_string
;
17028 Lisp_Object face_string
;
17029 int face_string_pos
;
17032 int field_width
, precision
, max_x
;
17035 int hpos_at_start
= it
->hpos
;
17036 int saved_face_id
= it
->face_id
;
17037 struct glyph_row
*row
= it
->glyph_row
;
17039 /* Initialize the iterator IT for iteration over STRING beginning
17040 with index START. */
17041 reseat_to_string (it
, string
, lisp_string
, start
,
17042 precision
, field_width
, multibyte
);
17044 /* If displaying STRING, set up the face of the iterator
17045 from LISP_STRING, if that's given. */
17046 if (STRINGP (face_string
))
17052 = face_at_string_position (it
->w
, face_string
, face_string_pos
,
17053 0, it
->region_beg_charpos
,
17054 it
->region_end_charpos
,
17055 &endptr
, it
->base_face_id
, 0);
17056 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
17057 it
->face_box_p
= face
->box
!= FACE_NO_BOX
;
17060 /* Set max_x to the maximum allowed X position. Don't let it go
17061 beyond the right edge of the window. */
17063 max_x
= it
->last_visible_x
;
17065 max_x
= min (max_x
, it
->last_visible_x
);
17067 /* Skip over display elements that are not visible. because IT->w is
17069 if (it
->current_x
< it
->first_visible_x
)
17070 move_it_in_display_line_to (it
, 100000, it
->first_visible_x
,
17071 MOVE_TO_POS
| MOVE_TO_X
);
17073 row
->ascent
= it
->max_ascent
;
17074 row
->height
= it
->max_ascent
+ it
->max_descent
;
17075 row
->phys_ascent
= it
->max_phys_ascent
;
17076 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
17077 row
->extra_line_spacing
= it
->max_extra_line_spacing
;
17079 /* This condition is for the case that we are called with current_x
17080 past last_visible_x. */
17081 while (it
->current_x
< max_x
)
17083 int x_before
, x
, n_glyphs_before
, i
, nglyphs
;
17085 /* Get the next display element. */
17086 if (!get_next_display_element (it
))
17089 /* Produce glyphs. */
17090 x_before
= it
->current_x
;
17091 n_glyphs_before
= it
->glyph_row
->used
[TEXT_AREA
];
17092 PRODUCE_GLYPHS (it
);
17094 nglyphs
= it
->glyph_row
->used
[TEXT_AREA
] - n_glyphs_before
;
17097 while (i
< nglyphs
)
17099 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
17101 if (!it
->truncate_lines_p
17102 && x
+ glyph
->pixel_width
> max_x
)
17104 /* End of continued line or max_x reached. */
17105 if (CHAR_GLYPH_PADDING_P (*glyph
))
17107 /* A wide character is unbreakable. */
17108 it
->glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
;
17109 it
->current_x
= x_before
;
17113 it
->glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
+ i
;
17118 else if (x
+ glyph
->pixel_width
> it
->first_visible_x
)
17120 /* Glyph is at least partially visible. */
17122 if (x
< it
->first_visible_x
)
17123 it
->glyph_row
->x
= x
- it
->first_visible_x
;
17127 /* Glyph is off the left margin of the display area.
17128 Should not happen. */
17132 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
17133 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
17134 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
17135 row
->phys_height
= max (row
->phys_height
,
17136 it
->max_phys_ascent
+ it
->max_phys_descent
);
17137 row
->extra_line_spacing
= max (row
->extra_line_spacing
,
17138 it
->max_extra_line_spacing
);
17139 x
+= glyph
->pixel_width
;
17143 /* Stop if max_x reached. */
17147 /* Stop at line ends. */
17148 if (ITERATOR_AT_END_OF_LINE_P (it
))
17150 it
->continuation_lines_width
= 0;
17154 set_iterator_to_next (it
, 1);
17156 /* Stop if truncating at the right edge. */
17157 if (it
->truncate_lines_p
17158 && it
->current_x
>= it
->last_visible_x
)
17160 /* Add truncation mark, but don't do it if the line is
17161 truncated at a padding space. */
17162 if (IT_CHARPOS (*it
) < it
->string_nchars
)
17164 if (!FRAME_WINDOW_P (it
->f
))
17168 if (it
->current_x
> it
->last_visible_x
)
17170 for (i
= row
->used
[TEXT_AREA
] - 1; i
> 0; --i
)
17171 if (!CHAR_GLYPH_PADDING_P (row
->glyphs
[TEXT_AREA
][i
]))
17173 for (n
= row
->used
[TEXT_AREA
]; i
< n
; ++i
)
17175 row
->used
[TEXT_AREA
] = i
;
17176 produce_special_glyphs (it
, IT_TRUNCATION
);
17179 produce_special_glyphs (it
, IT_TRUNCATION
);
17181 it
->glyph_row
->truncated_on_right_p
= 1;
17187 /* Maybe insert a truncation at the left. */
17188 if (it
->first_visible_x
17189 && IT_CHARPOS (*it
) > 0)
17191 if (!FRAME_WINDOW_P (it
->f
))
17192 insert_left_trunc_glyphs (it
);
17193 it
->glyph_row
->truncated_on_left_p
= 1;
17196 it
->face_id
= saved_face_id
;
17198 /* Value is number of columns displayed. */
17199 return it
->hpos
- hpos_at_start
;
17204 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
17205 appears as an element of LIST or as the car of an element of LIST.
17206 If PROPVAL is a list, compare each element against LIST in that
17207 way, and return 1/2 if any element of PROPVAL is found in LIST.
17208 Otherwise return 0. This function cannot quit.
17209 The return value is 2 if the text is invisible but with an ellipsis
17210 and 1 if it's invisible and without an ellipsis. */
17213 invisible_p (propval
, list
)
17214 register Lisp_Object propval
;
17217 register Lisp_Object tail
, proptail
;
17219 for (tail
= list
; CONSP (tail
); tail
= XCDR (tail
))
17221 register Lisp_Object tem
;
17223 if (EQ (propval
, tem
))
17225 if (CONSP (tem
) && EQ (propval
, XCAR (tem
)))
17226 return NILP (XCDR (tem
)) ? 1 : 2;
17229 if (CONSP (propval
))
17231 for (proptail
= propval
; CONSP (proptail
); proptail
= XCDR (proptail
))
17233 Lisp_Object propelt
;
17234 propelt
= XCAR (proptail
);
17235 for (tail
= list
; CONSP (tail
); tail
= XCDR (tail
))
17237 register Lisp_Object tem
;
17239 if (EQ (propelt
, tem
))
17241 if (CONSP (tem
) && EQ (propelt
, XCAR (tem
)))
17242 return NILP (XCDR (tem
)) ? 1 : 2;
17250 /* Calculate a width or height in pixels from a specification using
17251 the following elements:
17254 NUM - a (fractional) multiple of the default font width/height
17255 (NUM) - specifies exactly NUM pixels
17256 UNIT - a fixed number of pixels, see below.
17257 ELEMENT - size of a display element in pixels, see below.
17258 (NUM . SPEC) - equals NUM * SPEC
17259 (+ SPEC SPEC ...) - add pixel values
17260 (- SPEC SPEC ...) - subtract pixel values
17261 (- SPEC) - negate pixel value
17264 INT or FLOAT - a number constant
17265 SYMBOL - use symbol's (buffer local) variable binding.
17268 in - pixels per inch *)
17269 mm - pixels per 1/1000 meter *)
17270 cm - pixels per 1/100 meter *)
17271 width - width of current font in pixels.
17272 height - height of current font in pixels.
17274 *) using the ratio(s) defined in display-pixels-per-inch.
17278 left-fringe - left fringe width in pixels
17279 right-fringe - right fringe width in pixels
17281 left-margin - left margin width in pixels
17282 right-margin - right margin width in pixels
17284 scroll-bar - scroll-bar area width in pixels
17288 Pixels corresponding to 5 inches:
17291 Total width of non-text areas on left side of window (if scroll-bar is on left):
17292 '(space :width (+ left-fringe left-margin scroll-bar))
17294 Align to first text column (in header line):
17295 '(space :align-to 0)
17297 Align to middle of text area minus half the width of variable `my-image'
17298 containing a loaded image:
17299 '(space :align-to (0.5 . (- text my-image)))
17301 Width of left margin minus width of 1 character in the default font:
17302 '(space :width (- left-margin 1))
17304 Width of left margin minus width of 2 characters in the current font:
17305 '(space :width (- left-margin (2 . width)))
17307 Center 1 character over left-margin (in header line):
17308 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
17310 Different ways to express width of left fringe plus left margin minus one pixel:
17311 '(space :width (- (+ left-fringe left-margin) (1)))
17312 '(space :width (+ left-fringe left-margin (- (1))))
17313 '(space :width (+ left-fringe left-margin (-1)))
17317 #define NUMVAL(X) \
17318 ((INTEGERP (X) || FLOATP (X)) \
17323 calc_pixel_width_or_height (res
, it
, prop
, font
, width_p
, align_to
)
17328 int width_p
, *align_to
;
17332 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
17333 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
17336 return OK_PIXELS (0);
17338 if (SYMBOLP (prop
))
17340 if (SCHARS (SYMBOL_NAME (prop
)) == 2)
17342 char *unit
= SDATA (SYMBOL_NAME (prop
));
17344 if (unit
[0] == 'i' && unit
[1] == 'n')
17346 else if (unit
[0] == 'm' && unit
[1] == 'm')
17348 else if (unit
[0] == 'c' && unit
[1] == 'm')
17355 if ((ppi
= NUMVAL (Vdisplay_pixels_per_inch
), ppi
> 0)
17356 || (CONSP (Vdisplay_pixels_per_inch
)
17358 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch
))
17359 : NUMVAL (XCDR (Vdisplay_pixels_per_inch
))),
17361 return OK_PIXELS (ppi
/ pixels
);
17367 #ifdef HAVE_WINDOW_SYSTEM
17368 if (EQ (prop
, Qheight
))
17369 return OK_PIXELS (font
? FONT_HEIGHT ((XFontStruct
*)font
) : FRAME_LINE_HEIGHT (it
->f
));
17370 if (EQ (prop
, Qwidth
))
17371 return OK_PIXELS (font
? FONT_WIDTH ((XFontStruct
*)font
) : FRAME_COLUMN_WIDTH (it
->f
));
17373 if (EQ (prop
, Qheight
) || EQ (prop
, Qwidth
))
17374 return OK_PIXELS (1);
17377 if (EQ (prop
, Qtext
))
17378 return OK_PIXELS (width_p
17379 ? window_box_width (it
->w
, TEXT_AREA
)
17380 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it
->w
));
17382 if (align_to
&& *align_to
< 0)
17385 if (EQ (prop
, Qleft
))
17386 return OK_ALIGN_TO (window_box_left_offset (it
->w
, TEXT_AREA
));
17387 if (EQ (prop
, Qright
))
17388 return OK_ALIGN_TO (window_box_right_offset (it
->w
, TEXT_AREA
));
17389 if (EQ (prop
, Qcenter
))
17390 return OK_ALIGN_TO (window_box_left_offset (it
->w
, TEXT_AREA
)
17391 + window_box_width (it
->w
, TEXT_AREA
) / 2);
17392 if (EQ (prop
, Qleft_fringe
))
17393 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it
->w
)
17394 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it
->w
)
17395 : window_box_right_offset (it
->w
, LEFT_MARGIN_AREA
));
17396 if (EQ (prop
, Qright_fringe
))
17397 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it
->w
)
17398 ? window_box_right_offset (it
->w
, RIGHT_MARGIN_AREA
)
17399 : window_box_right_offset (it
->w
, TEXT_AREA
));
17400 if (EQ (prop
, Qleft_margin
))
17401 return OK_ALIGN_TO (window_box_left_offset (it
->w
, LEFT_MARGIN_AREA
));
17402 if (EQ (prop
, Qright_margin
))
17403 return OK_ALIGN_TO (window_box_left_offset (it
->w
, RIGHT_MARGIN_AREA
));
17404 if (EQ (prop
, Qscroll_bar
))
17405 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it
->w
)
17407 : (window_box_right_offset (it
->w
, RIGHT_MARGIN_AREA
)
17408 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it
->w
)
17409 ? WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)
17414 if (EQ (prop
, Qleft_fringe
))
17415 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it
->w
));
17416 if (EQ (prop
, Qright_fringe
))
17417 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it
->w
));
17418 if (EQ (prop
, Qleft_margin
))
17419 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it
->w
));
17420 if (EQ (prop
, Qright_margin
))
17421 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it
->w
));
17422 if (EQ (prop
, Qscroll_bar
))
17423 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it
->w
));
17426 prop
= Fbuffer_local_value (prop
, it
->w
->buffer
);
17429 if (INTEGERP (prop
) || FLOATP (prop
))
17431 int base_unit
= (width_p
17432 ? FRAME_COLUMN_WIDTH (it
->f
)
17433 : FRAME_LINE_HEIGHT (it
->f
));
17434 return OK_PIXELS (XFLOATINT (prop
) * base_unit
);
17439 Lisp_Object car
= XCAR (prop
);
17440 Lisp_Object cdr
= XCDR (prop
);
17444 #ifdef HAVE_WINDOW_SYSTEM
17445 if (valid_image_p (prop
))
17447 int id
= lookup_image (it
->f
, prop
);
17448 struct image
*img
= IMAGE_FROM_ID (it
->f
, id
);
17450 return OK_PIXELS (width_p
? img
->width
: img
->height
);
17453 if (EQ (car
, Qplus
) || EQ (car
, Qminus
))
17459 while (CONSP (cdr
))
17461 if (!calc_pixel_width_or_height (&px
, it
, XCAR (cdr
),
17462 font
, width_p
, align_to
))
17465 pixels
= (EQ (car
, Qplus
) ? px
: -px
), first
= 0;
17470 if (EQ (car
, Qminus
))
17472 return OK_PIXELS (pixels
);
17475 car
= Fbuffer_local_value (car
, it
->w
->buffer
);
17478 if (INTEGERP (car
) || FLOATP (car
))
17481 pixels
= XFLOATINT (car
);
17483 return OK_PIXELS (pixels
);
17484 if (calc_pixel_width_or_height (&fact
, it
, cdr
,
17485 font
, width_p
, align_to
))
17486 return OK_PIXELS (pixels
* fact
);
17497 /***********************************************************************
17499 ***********************************************************************/
17501 #ifdef HAVE_WINDOW_SYSTEM
17506 dump_glyph_string (s
)
17507 struct glyph_string
*s
;
17509 fprintf (stderr
, "glyph string\n");
17510 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
17511 s
->x
, s
->y
, s
->width
, s
->height
);
17512 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
17513 fprintf (stderr
, " hl = %d\n", s
->hl
);
17514 fprintf (stderr
, " left overhang = %d, right = %d\n",
17515 s
->left_overhang
, s
->right_overhang
);
17516 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
17517 fprintf (stderr
, " extends to end of line = %d\n",
17518 s
->extends_to_end_of_line_p
);
17519 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
17520 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
17523 #endif /* GLYPH_DEBUG */
17525 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
17526 of XChar2b structures for S; it can't be allocated in
17527 init_glyph_string because it must be allocated via `alloca'. W
17528 is the window on which S is drawn. ROW and AREA are the glyph row
17529 and area within the row from which S is constructed. START is the
17530 index of the first glyph structure covered by S. HL is a
17531 face-override for drawing S. */
17534 #define OPTIONAL_HDC(hdc) hdc,
17535 #define DECLARE_HDC(hdc) HDC hdc;
17536 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
17537 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
17540 #ifndef OPTIONAL_HDC
17541 #define OPTIONAL_HDC(hdc)
17542 #define DECLARE_HDC(hdc)
17543 #define ALLOCATE_HDC(hdc, f)
17544 #define RELEASE_HDC(hdc, f)
17548 init_glyph_string (s
, OPTIONAL_HDC (hdc
) char2b
, w
, row
, area
, start
, hl
)
17549 struct glyph_string
*s
;
17553 struct glyph_row
*row
;
17554 enum glyph_row_area area
;
17556 enum draw_glyphs_face hl
;
17558 bzero (s
, sizeof *s
);
17560 s
->f
= XFRAME (w
->frame
);
17564 s
->display
= FRAME_X_DISPLAY (s
->f
);
17565 s
->window
= FRAME_X_WINDOW (s
->f
);
17566 s
->char2b
= char2b
;
17570 s
->first_glyph
= row
->glyphs
[area
] + start
;
17571 s
->height
= row
->height
;
17572 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
17574 /* Display the internal border below the tool-bar window. */
17575 if (WINDOWP (s
->f
->tool_bar_window
)
17576 && s
->w
== XWINDOW (s
->f
->tool_bar_window
))
17577 s
->y
-= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
17579 s
->ybase
= s
->y
+ row
->ascent
;
17583 /* Append the list of glyph strings with head H and tail T to the list
17584 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
17587 append_glyph_string_lists (head
, tail
, h
, t
)
17588 struct glyph_string
**head
, **tail
;
17589 struct glyph_string
*h
, *t
;
17603 /* Prepend the list of glyph strings with head H and tail T to the
17604 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
17608 prepend_glyph_string_lists (head
, tail
, h
, t
)
17609 struct glyph_string
**head
, **tail
;
17610 struct glyph_string
*h
, *t
;
17624 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
17625 Set *HEAD and *TAIL to the resulting list. */
17628 append_glyph_string (head
, tail
, s
)
17629 struct glyph_string
**head
, **tail
;
17630 struct glyph_string
*s
;
17632 s
->next
= s
->prev
= NULL
;
17633 append_glyph_string_lists (head
, tail
, s
, s
);
17637 /* Get face and two-byte form of character glyph GLYPH on frame F.
17638 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
17639 a pointer to a realized face that is ready for display. */
17641 static INLINE
struct face
*
17642 get_glyph_face_and_encoding (f
, glyph
, char2b
, two_byte_p
)
17644 struct glyph
*glyph
;
17650 xassert (glyph
->type
== CHAR_GLYPH
);
17651 face
= FACE_FROM_ID (f
, glyph
->face_id
);
17656 if (!glyph
->multibyte_p
)
17658 /* Unibyte case. We don't have to encode, but we have to make
17659 sure to use a face suitable for unibyte. */
17660 STORE_XCHAR2B (char2b
, 0, glyph
->u
.ch
);
17662 else if (glyph
->u
.ch
< 128
17663 && glyph
->face_id
< BASIC_FACE_ID_SENTINEL
)
17665 /* Case of ASCII in a face known to fit ASCII. */
17666 STORE_XCHAR2B (char2b
, 0, glyph
->u
.ch
);
17670 int c1
, c2
, charset
;
17672 /* Split characters into bytes. If c2 is -1 afterwards, C is
17673 really a one-byte character so that byte1 is zero. */
17674 SPLIT_CHAR (glyph
->u
.ch
, charset
, c1
, c2
);
17676 STORE_XCHAR2B (char2b
, c1
, c2
);
17678 STORE_XCHAR2B (char2b
, 0, c1
);
17680 /* Maybe encode the character in *CHAR2B. */
17681 if (charset
!= CHARSET_ASCII
)
17683 struct font_info
*font_info
17684 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
17687 = rif
->encode_char (glyph
->u
.ch
, char2b
, font_info
, two_byte_p
);
17691 /* Make sure X resources of the face are allocated. */
17692 xassert (face
!= NULL
);
17693 PREPARE_FACE_FOR_DISPLAY (f
, face
);
17698 /* Fill glyph string S with composition components specified by S->cmp.
17700 FACES is an array of faces for all components of this composition.
17701 S->gidx is the index of the first component for S.
17702 OVERLAPS_P non-zero means S should draw the foreground only, and
17703 use its physical height for clipping.
17705 Value is the index of a component not in S. */
17708 fill_composite_glyph_string (s
, faces
, overlaps_p
)
17709 struct glyph_string
*s
;
17710 struct face
**faces
;
17717 s
->for_overlaps_p
= overlaps_p
;
17719 s
->face
= faces
[s
->gidx
];
17720 s
->font
= s
->face
->font
;
17721 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
17723 /* For all glyphs of this composition, starting at the offset
17724 S->gidx, until we reach the end of the definition or encounter a
17725 glyph that requires the different face, add it to S. */
17727 for (i
= s
->gidx
+ 1; i
< s
->cmp
->glyph_len
&& faces
[i
] == s
->face
; ++i
)
17730 /* All glyph strings for the same composition has the same width,
17731 i.e. the width set for the first component of the composition. */
17733 s
->width
= s
->first_glyph
->pixel_width
;
17735 /* If the specified font could not be loaded, use the frame's
17736 default font, but record the fact that we couldn't load it in
17737 the glyph string so that we can draw rectangles for the
17738 characters of the glyph string. */
17739 if (s
->font
== NULL
)
17741 s
->font_not_found_p
= 1;
17742 s
->font
= FRAME_FONT (s
->f
);
17745 /* Adjust base line for subscript/superscript text. */
17746 s
->ybase
+= s
->first_glyph
->voffset
;
17748 xassert (s
->face
&& s
->face
->gc
);
17750 /* This glyph string must always be drawn with 16-bit functions. */
17753 return s
->gidx
+ s
->nchars
;
17757 /* Fill glyph string S from a sequence of character glyphs.
17759 FACE_ID is the face id of the string. START is the index of the
17760 first glyph to consider, END is the index of the last + 1.
17761 OVERLAPS_P non-zero means S should draw the foreground only, and
17762 use its physical height for clipping.
17764 Value is the index of the first glyph not in S. */
17767 fill_glyph_string (s
, face_id
, start
, end
, overlaps_p
)
17768 struct glyph_string
*s
;
17770 int start
, end
, overlaps_p
;
17772 struct glyph
*glyph
, *last
;
17774 int glyph_not_available_p
;
17776 xassert (s
->f
== XFRAME (s
->w
->frame
));
17777 xassert (s
->nchars
== 0);
17778 xassert (start
>= 0 && end
> start
);
17780 s
->for_overlaps_p
= overlaps_p
,
17781 glyph
= s
->row
->glyphs
[s
->area
] + start
;
17782 last
= s
->row
->glyphs
[s
->area
] + end
;
17783 voffset
= glyph
->voffset
;
17785 glyph_not_available_p
= glyph
->glyph_not_available_p
;
17787 while (glyph
< last
17788 && glyph
->type
== CHAR_GLYPH
17789 && glyph
->voffset
== voffset
17790 /* Same face id implies same font, nowadays. */
17791 && glyph
->face_id
== face_id
17792 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
17796 s
->face
= get_glyph_face_and_encoding (s
->f
, glyph
,
17797 s
->char2b
+ s
->nchars
,
17799 s
->two_byte_p
= two_byte_p
;
17801 xassert (s
->nchars
<= end
- start
);
17802 s
->width
+= glyph
->pixel_width
;
17806 s
->font
= s
->face
->font
;
17807 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
17809 /* If the specified font could not be loaded, use the frame's font,
17810 but record the fact that we couldn't load it in
17811 S->font_not_found_p so that we can draw rectangles for the
17812 characters of the glyph string. */
17813 if (s
->font
== NULL
|| glyph_not_available_p
)
17815 s
->font_not_found_p
= 1;
17816 s
->font
= FRAME_FONT (s
->f
);
17819 /* Adjust base line for subscript/superscript text. */
17820 s
->ybase
+= voffset
;
17822 xassert (s
->face
&& s
->face
->gc
);
17823 return glyph
- s
->row
->glyphs
[s
->area
];
17827 /* Fill glyph string S from image glyph S->first_glyph. */
17830 fill_image_glyph_string (s
)
17831 struct glyph_string
*s
;
17833 xassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
17834 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
17836 s
->slice
= s
->first_glyph
->slice
;
17837 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
17838 s
->font
= s
->face
->font
;
17839 s
->width
= s
->first_glyph
->pixel_width
;
17841 /* Adjust base line for subscript/superscript text. */
17842 s
->ybase
+= s
->first_glyph
->voffset
;
17846 /* Fill glyph string S from a sequence of stretch glyphs.
17848 ROW is the glyph row in which the glyphs are found, AREA is the
17849 area within the row. START is the index of the first glyph to
17850 consider, END is the index of the last + 1.
17852 Value is the index of the first glyph not in S. */
17855 fill_stretch_glyph_string (s
, row
, area
, start
, end
)
17856 struct glyph_string
*s
;
17857 struct glyph_row
*row
;
17858 enum glyph_row_area area
;
17861 struct glyph
*glyph
, *last
;
17862 int voffset
, face_id
;
17864 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
17866 glyph
= s
->row
->glyphs
[s
->area
] + start
;
17867 last
= s
->row
->glyphs
[s
->area
] + end
;
17868 face_id
= glyph
->face_id
;
17869 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
17870 s
->font
= s
->face
->font
;
17871 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
17872 s
->width
= glyph
->pixel_width
;
17873 voffset
= glyph
->voffset
;
17877 && glyph
->type
== STRETCH_GLYPH
17878 && glyph
->voffset
== voffset
17879 && glyph
->face_id
== face_id
);
17881 s
->width
+= glyph
->pixel_width
;
17883 /* Adjust base line for subscript/superscript text. */
17884 s
->ybase
+= voffset
;
17886 /* The case that face->gc == 0 is handled when drawing the glyph
17887 string by calling PREPARE_FACE_FOR_DISPLAY. */
17889 return glyph
- s
->row
->glyphs
[s
->area
];
17894 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
17895 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
17896 assumed to be zero. */
17899 x_get_glyph_overhangs (glyph
, f
, left
, right
)
17900 struct glyph
*glyph
;
17904 *left
= *right
= 0;
17906 if (glyph
->type
== CHAR_GLYPH
)
17910 struct font_info
*font_info
;
17914 face
= get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
17916 font_info
= FONT_INFO_FROM_ID (f
, face
->font_info_id
);
17917 if (font
/* ++KFS: Should this be font_info ? */
17918 && (pcm
= rif
->per_char_metric (font
, &char2b
, glyph
->font_type
)))
17920 if (pcm
->rbearing
> pcm
->width
)
17921 *right
= pcm
->rbearing
- pcm
->width
;
17922 if (pcm
->lbearing
< 0)
17923 *left
= -pcm
->lbearing
;
17929 /* Return the index of the first glyph preceding glyph string S that
17930 is overwritten by S because of S's left overhang. Value is -1
17931 if no glyphs are overwritten. */
17934 left_overwritten (s
)
17935 struct glyph_string
*s
;
17939 if (s
->left_overhang
)
17942 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
17943 int first
= s
->first_glyph
- glyphs
;
17945 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
17946 x
-= glyphs
[i
].pixel_width
;
17957 /* Return the index of the first glyph preceding glyph string S that
17958 is overwriting S because of its right overhang. Value is -1 if no
17959 glyph in front of S overwrites S. */
17962 left_overwriting (s
)
17963 struct glyph_string
*s
;
17966 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
17967 int first
= s
->first_glyph
- glyphs
;
17971 for (i
= first
- 1; i
>= 0; --i
)
17974 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
17977 x
-= glyphs
[i
].pixel_width
;
17984 /* Return the index of the last glyph following glyph string S that is
17985 not overwritten by S because of S's right overhang. Value is -1 if
17986 no such glyph is found. */
17989 right_overwritten (s
)
17990 struct glyph_string
*s
;
17994 if (s
->right_overhang
)
17997 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
17998 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
17999 int end
= s
->row
->used
[s
->area
];
18001 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
18002 x
+= glyphs
[i
].pixel_width
;
18011 /* Return the index of the last glyph following glyph string S that
18012 overwrites S because of its left overhang. Value is negative
18013 if no such glyph is found. */
18016 right_overwriting (s
)
18017 struct glyph_string
*s
;
18020 int end
= s
->row
->used
[s
->area
];
18021 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
18022 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
18026 for (i
= first
; i
< end
; ++i
)
18029 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
18032 x
+= glyphs
[i
].pixel_width
;
18039 /* Get face and two-byte form of character C in face FACE_ID on frame
18040 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
18041 means we want to display multibyte text. DISPLAY_P non-zero means
18042 make sure that X resources for the face returned are allocated.
18043 Value is a pointer to a realized face that is ready for display if
18044 DISPLAY_P is non-zero. */
18046 static INLINE
struct face
*
18047 get_char_face_and_encoding (f
, c
, face_id
, char2b
, multibyte_p
, display_p
)
18051 int multibyte_p
, display_p
;
18053 struct face
*face
= FACE_FROM_ID (f
, face_id
);
18057 /* Unibyte case. We don't have to encode, but we have to make
18058 sure to use a face suitable for unibyte. */
18059 STORE_XCHAR2B (char2b
, 0, c
);
18060 face_id
= FACE_FOR_CHAR (f
, face
, c
);
18061 face
= FACE_FROM_ID (f
, face_id
);
18063 else if (c
< 128 && face_id
< BASIC_FACE_ID_SENTINEL
)
18065 /* Case of ASCII in a face known to fit ASCII. */
18066 STORE_XCHAR2B (char2b
, 0, c
);
18070 int c1
, c2
, charset
;
18072 /* Split characters into bytes. If c2 is -1 afterwards, C is
18073 really a one-byte character so that byte1 is zero. */
18074 SPLIT_CHAR (c
, charset
, c1
, c2
);
18076 STORE_XCHAR2B (char2b
, c1
, c2
);
18078 STORE_XCHAR2B (char2b
, 0, c1
);
18080 /* Maybe encode the character in *CHAR2B. */
18081 if (face
->font
!= NULL
)
18083 struct font_info
*font_info
18084 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
18086 rif
->encode_char (c
, char2b
, font_info
, 0);
18090 /* Make sure X resources of the face are allocated. */
18091 #ifdef HAVE_X_WINDOWS
18095 xassert (face
!= NULL
);
18096 PREPARE_FACE_FOR_DISPLAY (f
, face
);
18103 /* Set background width of glyph string S. START is the index of the
18104 first glyph following S. LAST_X is the right-most x-position + 1
18105 in the drawing area. */
18108 set_glyph_string_background_width (s
, start
, last_x
)
18109 struct glyph_string
*s
;
18113 /* If the face of this glyph string has to be drawn to the end of
18114 the drawing area, set S->extends_to_end_of_line_p. */
18115 struct face
*default_face
= FACE_FROM_ID (s
->f
, DEFAULT_FACE_ID
);
18117 if (start
== s
->row
->used
[s
->area
]
18118 && s
->area
== TEXT_AREA
18119 && ((s
->hl
== DRAW_NORMAL_TEXT
18120 && (s
->row
->fill_line_p
18121 || s
->face
->background
!= default_face
->background
18122 || s
->face
->stipple
!= default_face
->stipple
18123 || s
->row
->mouse_face_p
))
18124 || s
->hl
== DRAW_MOUSE_FACE
18125 || ((s
->hl
== DRAW_IMAGE_RAISED
|| s
->hl
== DRAW_IMAGE_SUNKEN
)
18126 && s
->row
->fill_line_p
)))
18127 s
->extends_to_end_of_line_p
= 1;
18129 /* If S extends its face to the end of the line, set its
18130 background_width to the distance to the right edge of the drawing
18132 if (s
->extends_to_end_of_line_p
)
18133 s
->background_width
= last_x
- s
->x
+ 1;
18135 s
->background_width
= s
->width
;
18139 /* Compute overhangs and x-positions for glyph string S and its
18140 predecessors, or successors. X is the starting x-position for S.
18141 BACKWARD_P non-zero means process predecessors. */
18144 compute_overhangs_and_x (s
, x
, backward_p
)
18145 struct glyph_string
*s
;
18153 if (rif
->compute_glyph_string_overhangs
)
18154 rif
->compute_glyph_string_overhangs (s
);
18164 if (rif
->compute_glyph_string_overhangs
)
18165 rif
->compute_glyph_string_overhangs (s
);
18175 /* The following macros are only called from draw_glyphs below.
18176 They reference the following parameters of that function directly:
18177 `w', `row', `area', and `overlap_p'
18178 as well as the following local variables:
18179 `s', `f', and `hdc' (in W32) */
18182 /* On W32, silently add local `hdc' variable to argument list of
18183 init_glyph_string. */
18184 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
18185 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
18187 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
18188 init_glyph_string (s, char2b, w, row, area, start, hl)
18191 /* Add a glyph string for a stretch glyph to the list of strings
18192 between HEAD and TAIL. START is the index of the stretch glyph in
18193 row area AREA of glyph row ROW. END is the index of the last glyph
18194 in that glyph row area. X is the current output position assigned
18195 to the new glyph string constructed. HL overrides that face of the
18196 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
18197 is the right-most x-position of the drawing area. */
18199 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
18200 and below -- keep them on one line. */
18201 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
18204 s = (struct glyph_string *) alloca (sizeof *s); \
18205 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
18206 START = fill_stretch_glyph_string (s, row, area, START, END); \
18207 append_glyph_string (&HEAD, &TAIL, s); \
18213 /* Add a glyph string for an image glyph to the list of strings
18214 between HEAD and TAIL. START is the index of the image glyph in
18215 row area AREA of glyph row ROW. END is the index of the last glyph
18216 in that glyph row area. X is the current output position assigned
18217 to the new glyph string constructed. HL overrides that face of the
18218 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
18219 is the right-most x-position of the drawing area. */
18221 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
18224 s = (struct glyph_string *) alloca (sizeof *s); \
18225 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
18226 fill_image_glyph_string (s); \
18227 append_glyph_string (&HEAD, &TAIL, s); \
18234 /* Add a glyph string for a sequence of character glyphs to the list
18235 of strings between HEAD and TAIL. START is the index of the first
18236 glyph in row area AREA of glyph row ROW that is part of the new
18237 glyph string. END is the index of the last glyph in that glyph row
18238 area. X is the current output position assigned to the new glyph
18239 string constructed. HL overrides that face of the glyph; e.g. it
18240 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
18241 right-most x-position of the drawing area. */
18243 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
18249 c = (row)->glyphs[area][START].u.ch; \
18250 face_id = (row)->glyphs[area][START].face_id; \
18252 s = (struct glyph_string *) alloca (sizeof *s); \
18253 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
18254 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
18255 append_glyph_string (&HEAD, &TAIL, s); \
18257 START = fill_glyph_string (s, face_id, START, END, overlaps_p); \
18262 /* Add a glyph string for a composite sequence to the list of strings
18263 between HEAD and TAIL. START is the index of the first glyph in
18264 row area AREA of glyph row ROW that is part of the new glyph
18265 string. END is the index of the last glyph in that glyph row area.
18266 X is the current output position assigned to the new glyph string
18267 constructed. HL overrides that face of the glyph; e.g. it is
18268 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
18269 x-position of the drawing area. */
18271 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
18273 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
18274 int face_id = (row)->glyphs[area][START].face_id; \
18275 struct face *base_face = FACE_FROM_ID (f, face_id); \
18276 struct composition *cmp = composition_table[cmp_id]; \
18277 int glyph_len = cmp->glyph_len; \
18279 struct face **faces; \
18280 struct glyph_string *first_s = NULL; \
18283 base_face = base_face->ascii_face; \
18284 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
18285 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
18286 /* At first, fill in `char2b' and `faces'. */ \
18287 for (n = 0; n < glyph_len; n++) \
18289 int c = COMPOSITION_GLYPH (cmp, n); \
18290 int this_face_id = FACE_FOR_CHAR (f, base_face, c); \
18291 faces[n] = FACE_FROM_ID (f, this_face_id); \
18292 get_char_face_and_encoding (f, c, this_face_id, \
18293 char2b + n, 1, 1); \
18296 /* Make glyph_strings for each glyph sequence that is drawable by \
18297 the same face, and append them to HEAD/TAIL. */ \
18298 for (n = 0; n < cmp->glyph_len;) \
18300 s = (struct glyph_string *) alloca (sizeof *s); \
18301 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \
18302 append_glyph_string (&(HEAD), &(TAIL), s); \
18310 n = fill_composite_glyph_string (s, faces, overlaps_p); \
18318 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
18319 of AREA of glyph row ROW on window W between indices START and END.
18320 HL overrides the face for drawing glyph strings, e.g. it is
18321 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
18322 x-positions of the drawing area.
18324 This is an ugly monster macro construct because we must use alloca
18325 to allocate glyph strings (because draw_glyphs can be called
18326 asynchronously). */
18328 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
18331 HEAD = TAIL = NULL; \
18332 while (START < END) \
18334 struct glyph *first_glyph = (row)->glyphs[area] + START; \
18335 switch (first_glyph->type) \
18338 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
18342 case COMPOSITE_GLYPH: \
18343 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
18347 case STRETCH_GLYPH: \
18348 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
18352 case IMAGE_GLYPH: \
18353 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
18361 set_glyph_string_background_width (s, START, LAST_X); \
18368 /* Draw glyphs between START and END in AREA of ROW on window W,
18369 starting at x-position X. X is relative to AREA in W. HL is a
18370 face-override with the following meaning:
18372 DRAW_NORMAL_TEXT draw normally
18373 DRAW_CURSOR draw in cursor face
18374 DRAW_MOUSE_FACE draw in mouse face.
18375 DRAW_INVERSE_VIDEO draw in mode line face
18376 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
18377 DRAW_IMAGE_RAISED draw an image with a raised relief around it
18379 If OVERLAPS_P is non-zero, draw only the foreground of characters
18380 and clip to the physical height of ROW.
18382 Value is the x-position reached, relative to AREA of W. */
18385 draw_glyphs (w
, x
, row
, area
, start
, end
, hl
, overlaps_p
)
18388 struct glyph_row
*row
;
18389 enum glyph_row_area area
;
18391 enum draw_glyphs_face hl
;
18394 struct glyph_string
*head
, *tail
;
18395 struct glyph_string
*s
;
18396 struct glyph_string
*clip_head
= NULL
, *clip_tail
= NULL
;
18397 int last_x
, area_width
;
18400 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
18403 ALLOCATE_HDC (hdc
, f
);
18405 /* Let's rather be paranoid than getting a SEGV. */
18406 end
= min (end
, row
->used
[area
]);
18407 start
= max (0, start
);
18408 start
= min (end
, start
);
18410 /* Translate X to frame coordinates. Set last_x to the right
18411 end of the drawing area. */
18412 if (row
->full_width_p
)
18414 /* X is relative to the left edge of W, without scroll bars
18416 x
+= WINDOW_LEFT_EDGE_X (w
);
18417 last_x
= WINDOW_LEFT_EDGE_X (w
) + WINDOW_TOTAL_WIDTH (w
);
18421 int area_left
= window_box_left (w
, area
);
18423 area_width
= window_box_width (w
, area
);
18424 last_x
= area_left
+ area_width
;
18427 /* Build a doubly-linked list of glyph_string structures between
18428 head and tail from what we have to draw. Note that the macro
18429 BUILD_GLYPH_STRINGS will modify its start parameter. That's
18430 the reason we use a separate variable `i'. */
18432 BUILD_GLYPH_STRINGS (i
, end
, head
, tail
, hl
, x
, last_x
);
18434 x_reached
= tail
->x
+ tail
->background_width
;
18438 /* If there are any glyphs with lbearing < 0 or rbearing > width in
18439 the row, redraw some glyphs in front or following the glyph
18440 strings built above. */
18441 if (head
&& !overlaps_p
&& row
->contains_overlapping_glyphs_p
)
18444 struct glyph_string
*h
, *t
;
18446 /* Compute overhangs for all glyph strings. */
18447 if (rif
->compute_glyph_string_overhangs
)
18448 for (s
= head
; s
; s
= s
->next
)
18449 rif
->compute_glyph_string_overhangs (s
);
18451 /* Prepend glyph strings for glyphs in front of the first glyph
18452 string that are overwritten because of the first glyph
18453 string's left overhang. The background of all strings
18454 prepended must be drawn because the first glyph string
18456 i
= left_overwritten (head
);
18460 BUILD_GLYPH_STRINGS (j
, start
, h
, t
,
18461 DRAW_NORMAL_TEXT
, dummy_x
, last_x
);
18463 compute_overhangs_and_x (t
, head
->x
, 1);
18464 prepend_glyph_string_lists (&head
, &tail
, h
, t
);
18468 /* Prepend glyph strings for glyphs in front of the first glyph
18469 string that overwrite that glyph string because of their
18470 right overhang. For these strings, only the foreground must
18471 be drawn, because it draws over the glyph string at `head'.
18472 The background must not be drawn because this would overwrite
18473 right overhangs of preceding glyphs for which no glyph
18475 i
= left_overwriting (head
);
18479 BUILD_GLYPH_STRINGS (i
, start
, h
, t
,
18480 DRAW_NORMAL_TEXT
, dummy_x
, last_x
);
18481 for (s
= h
; s
; s
= s
->next
)
18482 s
->background_filled_p
= 1;
18483 compute_overhangs_and_x (t
, head
->x
, 1);
18484 prepend_glyph_string_lists (&head
, &tail
, h
, t
);
18487 /* Append glyphs strings for glyphs following the last glyph
18488 string tail that are overwritten by tail. The background of
18489 these strings has to be drawn because tail's foreground draws
18491 i
= right_overwritten (tail
);
18494 BUILD_GLYPH_STRINGS (end
, i
, h
, t
,
18495 DRAW_NORMAL_TEXT
, x
, last_x
);
18496 compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
18497 append_glyph_string_lists (&head
, &tail
, h
, t
);
18501 /* Append glyph strings for glyphs following the last glyph
18502 string tail that overwrite tail. The foreground of such
18503 glyphs has to be drawn because it writes into the background
18504 of tail. The background must not be drawn because it could
18505 paint over the foreground of following glyphs. */
18506 i
= right_overwriting (tail
);
18510 BUILD_GLYPH_STRINGS (end
, i
, h
, t
,
18511 DRAW_NORMAL_TEXT
, x
, last_x
);
18512 for (s
= h
; s
; s
= s
->next
)
18513 s
->background_filled_p
= 1;
18514 compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
18515 append_glyph_string_lists (&head
, &tail
, h
, t
);
18517 if (clip_head
|| clip_tail
)
18518 for (s
= head
; s
; s
= s
->next
)
18520 s
->clip_head
= clip_head
;
18521 s
->clip_tail
= clip_tail
;
18525 /* Draw all strings. */
18526 for (s
= head
; s
; s
= s
->next
)
18527 rif
->draw_glyph_string (s
);
18529 if (area
== TEXT_AREA
18530 && !row
->full_width_p
18531 /* When drawing overlapping rows, only the glyph strings'
18532 foreground is drawn, which doesn't erase a cursor
18536 int x0
= clip_head
? clip_head
->x
: (head
? head
->x
: x
);
18537 int x1
= (clip_tail
? clip_tail
->x
+ clip_tail
->background_width
18538 : (tail
? tail
->x
+ tail
->background_width
: x
));
18540 int text_left
= window_box_left (w
, TEXT_AREA
);
18544 notice_overwritten_cursor (w
, TEXT_AREA
, x0
, x1
,
18545 row
->y
, MATRIX_ROW_BOTTOM_Y (row
));
18548 /* Value is the x-position up to which drawn, relative to AREA of W.
18549 This doesn't include parts drawn because of overhangs. */
18550 if (row
->full_width_p
)
18551 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
18553 x_reached
-= window_box_left (w
, area
);
18555 RELEASE_HDC (hdc
, f
);
18560 /* Expand row matrix if too narrow. Don't expand if area
18563 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
18565 if (!fonts_changed_p \
18566 && (it->glyph_row->glyphs[area] \
18567 < it->glyph_row->glyphs[area + 1])) \
18569 it->w->ncols_scale_factor++; \
18570 fonts_changed_p = 1; \
18574 /* Store one glyph for IT->char_to_display in IT->glyph_row.
18575 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18581 struct glyph
*glyph
;
18582 enum glyph_row_area area
= it
->area
;
18584 xassert (it
->glyph_row
);
18585 xassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
18587 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
18588 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
18590 glyph
->charpos
= CHARPOS (it
->position
);
18591 glyph
->object
= it
->object
;
18592 glyph
->pixel_width
= it
->pixel_width
;
18593 glyph
->ascent
= it
->ascent
;
18594 glyph
->descent
= it
->descent
;
18595 glyph
->voffset
= it
->voffset
;
18596 glyph
->type
= CHAR_GLYPH
;
18597 glyph
->multibyte_p
= it
->multibyte_p
;
18598 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
18599 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
18600 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
18601 || it
->phys_descent
> it
->descent
);
18602 glyph
->padding_p
= 0;
18603 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
18604 glyph
->face_id
= it
->face_id
;
18605 glyph
->u
.ch
= it
->char_to_display
;
18606 glyph
->slice
= null_glyph_slice
;
18607 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
18608 ++it
->glyph_row
->used
[area
];
18611 IT_EXPAND_MATRIX_WIDTH (it
, area
);
18614 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
18615 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18618 append_composite_glyph (it
)
18621 struct glyph
*glyph
;
18622 enum glyph_row_area area
= it
->area
;
18624 xassert (it
->glyph_row
);
18626 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
18627 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
18629 glyph
->charpos
= CHARPOS (it
->position
);
18630 glyph
->object
= it
->object
;
18631 glyph
->pixel_width
= it
->pixel_width
;
18632 glyph
->ascent
= it
->ascent
;
18633 glyph
->descent
= it
->descent
;
18634 glyph
->voffset
= it
->voffset
;
18635 glyph
->type
= COMPOSITE_GLYPH
;
18636 glyph
->multibyte_p
= it
->multibyte_p
;
18637 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
18638 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
18639 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
18640 || it
->phys_descent
> it
->descent
);
18641 glyph
->padding_p
= 0;
18642 glyph
->glyph_not_available_p
= 0;
18643 glyph
->face_id
= it
->face_id
;
18644 glyph
->u
.cmp_id
= it
->cmp_id
;
18645 glyph
->slice
= null_glyph_slice
;
18646 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
18647 ++it
->glyph_row
->used
[area
];
18650 IT_EXPAND_MATRIX_WIDTH (it
, area
);
18654 /* Change IT->ascent and IT->height according to the setting of
18658 take_vertical_position_into_account (it
)
18663 if (it
->voffset
< 0)
18664 /* Increase the ascent so that we can display the text higher
18666 it
->ascent
-= it
->voffset
;
18668 /* Increase the descent so that we can display the text lower
18670 it
->descent
+= it
->voffset
;
18675 /* Produce glyphs/get display metrics for the image IT is loaded with.
18676 See the description of struct display_iterator in dispextern.h for
18677 an overview of struct display_iterator. */
18680 produce_image_glyph (it
)
18686 struct glyph_slice slice
;
18688 xassert (it
->what
== IT_IMAGE
);
18690 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
18692 /* Make sure X resources of the face is loaded. */
18693 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
18695 if (it
->image_id
< 0)
18697 /* Fringe bitmap. */
18698 it
->ascent
= it
->phys_ascent
= 0;
18699 it
->descent
= it
->phys_descent
= 0;
18700 it
->pixel_width
= 0;
18705 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
18707 /* Make sure X resources of the image is loaded. */
18708 prepare_image_for_display (it
->f
, img
);
18710 slice
.x
= slice
.y
= 0;
18711 slice
.width
= img
->width
;
18712 slice
.height
= img
->height
;
18714 if (INTEGERP (it
->slice
.x
))
18715 slice
.x
= XINT (it
->slice
.x
);
18716 else if (FLOATP (it
->slice
.x
))
18717 slice
.x
= XFLOAT_DATA (it
->slice
.x
) * img
->width
;
18719 if (INTEGERP (it
->slice
.y
))
18720 slice
.y
= XINT (it
->slice
.y
);
18721 else if (FLOATP (it
->slice
.y
))
18722 slice
.y
= XFLOAT_DATA (it
->slice
.y
) * img
->height
;
18724 if (INTEGERP (it
->slice
.width
))
18725 slice
.width
= XINT (it
->slice
.width
);
18726 else if (FLOATP (it
->slice
.width
))
18727 slice
.width
= XFLOAT_DATA (it
->slice
.width
) * img
->width
;
18729 if (INTEGERP (it
->slice
.height
))
18730 slice
.height
= XINT (it
->slice
.height
);
18731 else if (FLOATP (it
->slice
.height
))
18732 slice
.height
= XFLOAT_DATA (it
->slice
.height
) * img
->height
;
18734 if (slice
.x
>= img
->width
)
18735 slice
.x
= img
->width
;
18736 if (slice
.y
>= img
->height
)
18737 slice
.y
= img
->height
;
18738 if (slice
.x
+ slice
.width
>= img
->width
)
18739 slice
.width
= img
->width
- slice
.x
;
18740 if (slice
.y
+ slice
.height
> img
->height
)
18741 slice
.height
= img
->height
- slice
.y
;
18743 if (slice
.width
== 0 || slice
.height
== 0)
18746 it
->ascent
= it
->phys_ascent
= glyph_ascent
= image_ascent (img
, face
, &slice
);
18748 it
->descent
= slice
.height
- glyph_ascent
;
18750 it
->descent
+= img
->vmargin
;
18751 if (slice
.y
+ slice
.height
== img
->height
)
18752 it
->descent
+= img
->vmargin
;
18753 it
->phys_descent
= it
->descent
;
18755 it
->pixel_width
= slice
.width
;
18757 it
->pixel_width
+= img
->hmargin
;
18758 if (slice
.x
+ slice
.width
== img
->width
)
18759 it
->pixel_width
+= img
->hmargin
;
18761 /* It's quite possible for images to have an ascent greater than
18762 their height, so don't get confused in that case. */
18763 if (it
->descent
< 0)
18766 #if 0 /* this breaks image tiling */
18767 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
18768 int face_ascent
= face
->font
? FONT_BASE (face
->font
) : FRAME_BASELINE_OFFSET (it
->f
);
18769 if (face_ascent
> it
->ascent
)
18770 it
->ascent
= it
->phys_ascent
= face_ascent
;
18775 if (face
->box
!= FACE_NO_BOX
)
18777 if (face
->box_line_width
> 0)
18780 it
->ascent
+= face
->box_line_width
;
18781 if (slice
.y
+ slice
.height
== img
->height
)
18782 it
->descent
+= face
->box_line_width
;
18785 if (it
->start_of_box_run_p
&& slice
.x
== 0)
18786 it
->pixel_width
+= abs (face
->box_line_width
);
18787 if (it
->end_of_box_run_p
&& slice
.x
+ slice
.width
== img
->width
)
18788 it
->pixel_width
+= abs (face
->box_line_width
);
18791 take_vertical_position_into_account (it
);
18795 struct glyph
*glyph
;
18796 enum glyph_row_area area
= it
->area
;
18798 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
18799 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
18801 glyph
->charpos
= CHARPOS (it
->position
);
18802 glyph
->object
= it
->object
;
18803 glyph
->pixel_width
= it
->pixel_width
;
18804 glyph
->ascent
= glyph_ascent
;
18805 glyph
->descent
= it
->descent
;
18806 glyph
->voffset
= it
->voffset
;
18807 glyph
->type
= IMAGE_GLYPH
;
18808 glyph
->multibyte_p
= it
->multibyte_p
;
18809 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
18810 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
18811 glyph
->overlaps_vertically_p
= 0;
18812 glyph
->padding_p
= 0;
18813 glyph
->glyph_not_available_p
= 0;
18814 glyph
->face_id
= it
->face_id
;
18815 glyph
->u
.img_id
= img
->id
;
18816 glyph
->slice
= slice
;
18817 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
18818 ++it
->glyph_row
->used
[area
];
18821 IT_EXPAND_MATRIX_WIDTH (it
, area
);
18826 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
18827 of the glyph, WIDTH and HEIGHT are the width and height of the
18828 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
18831 append_stretch_glyph (it
, object
, width
, height
, ascent
)
18833 Lisp_Object object
;
18837 struct glyph
*glyph
;
18838 enum glyph_row_area area
= it
->area
;
18840 xassert (ascent
>= 0 && ascent
<= height
);
18842 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
18843 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
18845 glyph
->charpos
= CHARPOS (it
->position
);
18846 glyph
->object
= object
;
18847 glyph
->pixel_width
= width
;
18848 glyph
->ascent
= ascent
;
18849 glyph
->descent
= height
- ascent
;
18850 glyph
->voffset
= it
->voffset
;
18851 glyph
->type
= STRETCH_GLYPH
;
18852 glyph
->multibyte_p
= it
->multibyte_p
;
18853 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
18854 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
18855 glyph
->overlaps_vertically_p
= 0;
18856 glyph
->padding_p
= 0;
18857 glyph
->glyph_not_available_p
= 0;
18858 glyph
->face_id
= it
->face_id
;
18859 glyph
->u
.stretch
.ascent
= ascent
;
18860 glyph
->u
.stretch
.height
= height
;
18861 glyph
->slice
= null_glyph_slice
;
18862 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
18863 ++it
->glyph_row
->used
[area
];
18866 IT_EXPAND_MATRIX_WIDTH (it
, area
);
18870 /* Produce a stretch glyph for iterator IT. IT->object is the value
18871 of the glyph property displayed. The value must be a list
18872 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
18875 1. `:width WIDTH' specifies that the space should be WIDTH *
18876 canonical char width wide. WIDTH may be an integer or floating
18879 2. `:relative-width FACTOR' specifies that the width of the stretch
18880 should be computed from the width of the first character having the
18881 `glyph' property, and should be FACTOR times that width.
18883 3. `:align-to HPOS' specifies that the space should be wide enough
18884 to reach HPOS, a value in canonical character units.
18886 Exactly one of the above pairs must be present.
18888 4. `:height HEIGHT' specifies that the height of the stretch produced
18889 should be HEIGHT, measured in canonical character units.
18891 5. `:relative-height FACTOR' specifies that the height of the
18892 stretch should be FACTOR times the height of the characters having
18893 the glyph property.
18895 Either none or exactly one of 4 or 5 must be present.
18897 6. `:ascent ASCENT' specifies that ASCENT percent of the height
18898 of the stretch should be used for the ascent of the stretch.
18899 ASCENT must be in the range 0 <= ASCENT <= 100. */
18902 produce_stretch_glyph (it
)
18905 /* (space :width WIDTH :height HEIGHT ...) */
18906 Lisp_Object prop
, plist
;
18907 int width
= 0, height
= 0, align_to
= -1;
18908 int zero_width_ok_p
= 0, zero_height_ok_p
= 0;
18911 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
18912 XFontStruct
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
18914 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
18916 /* List should start with `space'. */
18917 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
18918 plist
= XCDR (it
->object
);
18920 /* Compute the width of the stretch. */
18921 if ((prop
= Fsafe_plist_get (plist
, QCwidth
), !NILP (prop
))
18922 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 1, 0))
18924 /* Absolute width `:width WIDTH' specified and valid. */
18925 zero_width_ok_p
= 1;
18928 else if (prop
= Fsafe_plist_get (plist
, QCrelative_width
),
18931 /* Relative width `:relative-width FACTOR' specified and valid.
18932 Compute the width of the characters having the `glyph'
18935 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
18938 if (it
->multibyte_p
)
18940 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT
? ZV
: GPT
)
18941 - IT_BYTEPOS (*it
));
18942 it2
.c
= STRING_CHAR_AND_LENGTH (p
, maxlen
, it2
.len
);
18945 it2
.c
= *p
, it2
.len
= 1;
18947 it2
.glyph_row
= NULL
;
18948 it2
.what
= IT_CHARACTER
;
18949 x_produce_glyphs (&it2
);
18950 width
= NUMVAL (prop
) * it2
.pixel_width
;
18952 else if ((prop
= Fsafe_plist_get (plist
, QCalign_to
), !NILP (prop
))
18953 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 1, &align_to
))
18955 if (it
->glyph_row
== NULL
|| !it
->glyph_row
->mode_line_p
)
18956 align_to
= (align_to
< 0
18958 : align_to
- window_box_left_offset (it
->w
, TEXT_AREA
));
18959 else if (align_to
< 0)
18960 align_to
= window_box_left_offset (it
->w
, TEXT_AREA
);
18961 width
= max (0, (int)tem
+ align_to
- it
->current_x
);
18962 zero_width_ok_p
= 1;
18965 /* Nothing specified -> width defaults to canonical char width. */
18966 width
= FRAME_COLUMN_WIDTH (it
->f
);
18968 if (width
<= 0 && (width
< 0 || !zero_width_ok_p
))
18971 /* Compute height. */
18972 if ((prop
= Fsafe_plist_get (plist
, QCheight
), !NILP (prop
))
18973 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 0, 0))
18976 zero_height_ok_p
= 1;
18978 else if (prop
= Fsafe_plist_get (plist
, QCrelative_height
),
18980 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
18982 height
= FONT_HEIGHT (font
);
18984 if (height
<= 0 && (height
< 0 || !zero_height_ok_p
))
18987 /* Compute percentage of height used for ascent. If
18988 `:ascent ASCENT' is present and valid, use that. Otherwise,
18989 derive the ascent from the font in use. */
18990 if (prop
= Fsafe_plist_get (plist
, QCascent
),
18991 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
18992 ascent
= height
* NUMVAL (prop
) / 100.0;
18993 else if (!NILP (prop
)
18994 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 0, 0))
18995 ascent
= min (max (0, (int)tem
), height
);
18997 ascent
= (height
* FONT_BASE (font
)) / FONT_HEIGHT (font
);
18999 if (width
> 0 && height
> 0 && it
->glyph_row
)
19001 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
19002 if (!STRINGP (object
))
19003 object
= it
->w
->buffer
;
19004 append_stretch_glyph (it
, object
, width
, height
, ascent
);
19007 it
->pixel_width
= width
;
19008 it
->ascent
= it
->phys_ascent
= ascent
;
19009 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
19010 it
->nglyphs
= width
> 0 && height
> 0 ? 1 : 0;
19012 if (width
> 0 && height
> 0 && face
->box
!= FACE_NO_BOX
)
19014 if (face
->box_line_width
> 0)
19016 it
->ascent
+= face
->box_line_width
;
19017 it
->descent
+= face
->box_line_width
;
19020 if (it
->start_of_box_run_p
)
19021 it
->pixel_width
+= abs (face
->box_line_width
);
19022 if (it
->end_of_box_run_p
)
19023 it
->pixel_width
+= abs (face
->box_line_width
);
19026 take_vertical_position_into_account (it
);
19029 /* Get line-height and line-spacing property at point.
19030 If line-height has format (HEIGHT TOTAL), return TOTAL
19031 in TOTAL_HEIGHT. */
19034 get_line_height_property (it
, prop
)
19038 Lisp_Object position
, val
;
19040 if (STRINGP (it
->object
))
19041 position
= make_number (IT_STRING_CHARPOS (*it
));
19042 else if (BUFFERP (it
->object
))
19043 position
= make_number (IT_CHARPOS (*it
));
19047 return Fget_char_property (position
, prop
, it
->object
);
19050 /* Calculate line-height and line-spacing properties.
19051 An integer value specifies explicit pixel value.
19052 A float value specifies relative value to current face height.
19053 A cons (float . face-name) specifies relative value to
19054 height of specified face font.
19056 Returns height in pixels, or nil. */
19060 calc_line_height_property (it
, val
, font
, boff
, override
)
19064 int boff
, override
;
19066 Lisp_Object face_name
= Qnil
;
19067 int ascent
, descent
, height
;
19069 if (NILP (val
) || INTEGERP (val
) || (override
&& EQ (val
, Qt
)))
19074 face_name
= XCAR (val
);
19076 if (!NUMBERP (val
))
19077 val
= make_number (1);
19078 if (NILP (face_name
))
19080 height
= it
->ascent
+ it
->descent
;
19085 if (NILP (face_name
))
19087 font
= FRAME_FONT (it
->f
);
19088 boff
= FRAME_BASELINE_OFFSET (it
->f
);
19090 else if (EQ (face_name
, Qt
))
19098 struct font_info
*font_info
;
19100 face_id
= lookup_named_face (it
->f
, face_name
, ' ', 0);
19102 return make_number (-1);
19104 face
= FACE_FROM_ID (it
->f
, face_id
);
19107 return make_number (-1);
19109 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
19110 boff
= font_info
->baseline_offset
;
19111 if (font_info
->vertical_centering
)
19112 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
19115 ascent
= FONT_BASE (font
) + boff
;
19116 descent
= FONT_DESCENT (font
) - boff
;
19120 it
->override_ascent
= ascent
;
19121 it
->override_descent
= descent
;
19122 it
->override_boff
= boff
;
19125 height
= ascent
+ descent
;
19129 height
= (int)(XFLOAT_DATA (val
) * height
);
19130 else if (INTEGERP (val
))
19131 height
*= XINT (val
);
19133 return make_number (height
);
19138 Produce glyphs/get display metrics for the display element IT is
19139 loaded with. See the description of struct display_iterator in
19140 dispextern.h for an overview of struct display_iterator. */
19143 x_produce_glyphs (it
)
19146 int extra_line_spacing
= it
->extra_line_spacing
;
19148 it
->glyph_not_available_p
= 0;
19150 if (it
->what
== IT_CHARACTER
)
19154 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
19156 int font_not_found_p
;
19157 struct font_info
*font_info
;
19158 int boff
; /* baseline offset */
19159 /* We may change it->multibyte_p upon unibyte<->multibyte
19160 conversion. So, save the current value now and restore it
19163 Note: It seems that we don't have to record multibyte_p in
19164 struct glyph because the character code itself tells if or
19165 not the character is multibyte. Thus, in the future, we must
19166 consider eliminating the field `multibyte_p' in the struct
19168 int saved_multibyte_p
= it
->multibyte_p
;
19170 /* Maybe translate single-byte characters to multibyte, or the
19172 it
->char_to_display
= it
->c
;
19173 if (!ASCII_BYTE_P (it
->c
))
19175 if (unibyte_display_via_language_environment
19176 && SINGLE_BYTE_CHAR_P (it
->c
)
19178 || !NILP (Vnonascii_translation_table
)))
19180 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
19181 it
->multibyte_p
= 1;
19182 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
19183 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
19185 else if (!SINGLE_BYTE_CHAR_P (it
->c
)
19186 && !it
->multibyte_p
)
19188 it
->multibyte_p
= 1;
19189 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
19190 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
19194 /* Get font to use. Encode IT->char_to_display. */
19195 get_char_face_and_encoding (it
->f
, it
->char_to_display
, it
->face_id
,
19196 &char2b
, it
->multibyte_p
, 0);
19199 /* When no suitable font found, use the default font. */
19200 font_not_found_p
= font
== NULL
;
19201 if (font_not_found_p
)
19203 font
= FRAME_FONT (it
->f
);
19204 boff
= FRAME_BASELINE_OFFSET (it
->f
);
19209 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
19210 boff
= font_info
->baseline_offset
;
19211 if (font_info
->vertical_centering
)
19212 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
19215 if (it
->char_to_display
>= ' '
19216 && (!it
->multibyte_p
|| it
->char_to_display
< 128))
19218 /* Either unibyte or ASCII. */
19223 pcm
= rif
->per_char_metric (font
, &char2b
,
19224 FONT_TYPE_FOR_UNIBYTE (font
, it
->char_to_display
));
19226 if (it
->override_ascent
>= 0)
19228 it
->ascent
= it
->override_ascent
;
19229 it
->descent
= it
->override_descent
;
19230 boff
= it
->override_boff
;
19234 it
->ascent
= FONT_BASE (font
) + boff
;
19235 it
->descent
= FONT_DESCENT (font
) - boff
;
19240 it
->phys_ascent
= pcm
->ascent
+ boff
;
19241 it
->phys_descent
= pcm
->descent
- boff
;
19242 it
->pixel_width
= pcm
->width
;
19246 it
->glyph_not_available_p
= 1;
19247 it
->phys_ascent
= it
->ascent
;
19248 it
->phys_descent
= it
->descent
;
19249 it
->pixel_width
= FONT_WIDTH (font
);
19252 if (it
->constrain_row_ascent_descent_p
)
19254 if (it
->descent
> it
->max_descent
)
19256 it
->ascent
+= it
->descent
- it
->max_descent
;
19257 it
->descent
= it
->max_descent
;
19259 if (it
->ascent
> it
->max_ascent
)
19261 it
->descent
= min (it
->max_descent
, it
->descent
+ it
->ascent
- it
->max_ascent
);
19262 it
->ascent
= it
->max_ascent
;
19264 it
->phys_ascent
= min (it
->phys_ascent
, it
->ascent
);
19265 it
->phys_descent
= min (it
->phys_descent
, it
->descent
);
19266 extra_line_spacing
= 0;
19269 /* If this is a space inside a region of text with
19270 `space-width' property, change its width. */
19271 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
19273 it
->pixel_width
*= XFLOATINT (it
->space_width
);
19275 /* If face has a box, add the box thickness to the character
19276 height. If character has a box line to the left and/or
19277 right, add the box line width to the character's width. */
19278 if (face
->box
!= FACE_NO_BOX
)
19280 int thick
= face
->box_line_width
;
19284 it
->ascent
+= thick
;
19285 it
->descent
+= thick
;
19290 if (it
->start_of_box_run_p
)
19291 it
->pixel_width
+= thick
;
19292 if (it
->end_of_box_run_p
)
19293 it
->pixel_width
+= thick
;
19296 /* If face has an overline, add the height of the overline
19297 (1 pixel) and a 1 pixel margin to the character height. */
19298 if (face
->overline_p
)
19301 if (it
->constrain_row_ascent_descent_p
)
19303 if (it
->ascent
> it
->max_ascent
)
19304 it
->ascent
= it
->max_ascent
;
19305 if (it
->descent
> it
->max_descent
)
19306 it
->descent
= it
->max_descent
;
19309 take_vertical_position_into_account (it
);
19311 /* If we have to actually produce glyphs, do it. */
19316 /* Translate a space with a `space-width' property
19317 into a stretch glyph. */
19318 int ascent
= (((it
->ascent
+ it
->descent
) * FONT_BASE (font
))
19319 / FONT_HEIGHT (font
));
19320 append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
19321 it
->ascent
+ it
->descent
, ascent
);
19326 /* If characters with lbearing or rbearing are displayed
19327 in this line, record that fact in a flag of the
19328 glyph row. This is used to optimize X output code. */
19329 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
19330 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
19333 else if (it
->char_to_display
== '\n')
19335 /* A newline has no width but we need the height of the line.
19336 But if previous part of the line set a height, don't
19337 increase that height */
19339 Lisp_Object height
;
19340 Lisp_Object total_height
= Qnil
;
19342 it
->override_ascent
= -1;
19343 it
->pixel_width
= 0;
19346 height
= get_line_height_property(it
, Qline_height
);
19347 /* Split (line-height total-height) list */
19349 && CONSP (XCDR (height
))
19350 && NILP (XCDR (XCDR (height
))))
19352 total_height
= XCAR (XCDR (height
));
19353 height
= XCAR (height
);
19355 height
= calc_line_height_property(it
, height
, font
, boff
, 1);
19357 if (it
->override_ascent
>= 0)
19359 it
->ascent
= it
->override_ascent
;
19360 it
->descent
= it
->override_descent
;
19361 boff
= it
->override_boff
;
19365 it
->ascent
= FONT_BASE (font
) + boff
;
19366 it
->descent
= FONT_DESCENT (font
) - boff
;
19369 if (EQ (height
, Qt
))
19371 if (it
->descent
> it
->max_descent
)
19373 it
->ascent
+= it
->descent
- it
->max_descent
;
19374 it
->descent
= it
->max_descent
;
19376 if (it
->ascent
> it
->max_ascent
)
19378 it
->descent
= min (it
->max_descent
, it
->descent
+ it
->ascent
- it
->max_ascent
);
19379 it
->ascent
= it
->max_ascent
;
19381 it
->phys_ascent
= min (it
->phys_ascent
, it
->ascent
);
19382 it
->phys_descent
= min (it
->phys_descent
, it
->descent
);
19383 it
->constrain_row_ascent_descent_p
= 1;
19384 extra_line_spacing
= 0;
19388 Lisp_Object spacing
;
19391 it
->phys_ascent
= it
->ascent
;
19392 it
->phys_descent
= it
->descent
;
19394 if ((it
->max_ascent
> 0 || it
->max_descent
> 0)
19395 && face
->box
!= FACE_NO_BOX
19396 && face
->box_line_width
> 0)
19398 it
->ascent
+= face
->box_line_width
;
19399 it
->descent
+= face
->box_line_width
;
19402 && XINT (height
) > it
->ascent
+ it
->descent
)
19403 it
->ascent
= XINT (height
) - it
->descent
;
19405 if (!NILP (total_height
))
19406 spacing
= calc_line_height_property(it
, total_height
, font
, boff
, 0);
19409 spacing
= get_line_height_property(it
, Qline_spacing
);
19410 spacing
= calc_line_height_property(it
, spacing
, font
, boff
, 0);
19412 if (INTEGERP (spacing
))
19414 extra_line_spacing
= XINT (spacing
);
19415 if (!NILP (total_height
))
19416 extra_line_spacing
-= (it
->phys_ascent
+ it
->phys_descent
);
19420 else if (it
->char_to_display
== '\t')
19422 int tab_width
= it
->tab_width
* FRAME_SPACE_WIDTH (it
->f
);
19423 int x
= it
->current_x
+ it
->continuation_lines_width
;
19424 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
19426 /* If the distance from the current position to the next tab
19427 stop is less than a space character width, use the
19428 tab stop after that. */
19429 if (next_tab_x
- x
< FRAME_SPACE_WIDTH (it
->f
))
19430 next_tab_x
+= tab_width
;
19432 it
->pixel_width
= next_tab_x
- x
;
19434 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
19435 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
19439 append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
19440 it
->ascent
+ it
->descent
, it
->ascent
);
19445 /* A multi-byte character. Assume that the display width of the
19446 character is the width of the character multiplied by the
19447 width of the font. */
19449 /* If we found a font, this font should give us the right
19450 metrics. If we didn't find a font, use the frame's
19451 default font and calculate the width of the character
19452 from the charset width; this is what old redisplay code
19455 pcm
= rif
->per_char_metric (font
, &char2b
,
19456 FONT_TYPE_FOR_MULTIBYTE (font
, it
->c
));
19458 if (font_not_found_p
|| !pcm
)
19460 int charset
= CHAR_CHARSET (it
->char_to_display
);
19462 it
->glyph_not_available_p
= 1;
19463 it
->pixel_width
= (FRAME_COLUMN_WIDTH (it
->f
)
19464 * CHARSET_WIDTH (charset
));
19465 it
->phys_ascent
= FONT_BASE (font
) + boff
;
19466 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
19470 it
->pixel_width
= pcm
->width
;
19471 it
->phys_ascent
= pcm
->ascent
+ boff
;
19472 it
->phys_descent
= pcm
->descent
- boff
;
19474 && (pcm
->lbearing
< 0
19475 || pcm
->rbearing
> pcm
->width
))
19476 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
19479 it
->ascent
= FONT_BASE (font
) + boff
;
19480 it
->descent
= FONT_DESCENT (font
) - boff
;
19481 if (face
->box
!= FACE_NO_BOX
)
19483 int thick
= face
->box_line_width
;
19487 it
->ascent
+= thick
;
19488 it
->descent
+= thick
;
19493 if (it
->start_of_box_run_p
)
19494 it
->pixel_width
+= thick
;
19495 if (it
->end_of_box_run_p
)
19496 it
->pixel_width
+= thick
;
19499 /* If face has an overline, add the height of the overline
19500 (1 pixel) and a 1 pixel margin to the character height. */
19501 if (face
->overline_p
)
19504 take_vertical_position_into_account (it
);
19509 it
->multibyte_p
= saved_multibyte_p
;
19511 else if (it
->what
== IT_COMPOSITION
)
19513 /* Note: A composition is represented as one glyph in the
19514 glyph matrix. There are no padding glyphs. */
19517 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
19519 int font_not_found_p
;
19520 struct font_info
*font_info
;
19521 int boff
; /* baseline offset */
19522 struct composition
*cmp
= composition_table
[it
->cmp_id
];
19524 /* Maybe translate single-byte characters to multibyte. */
19525 it
->char_to_display
= it
->c
;
19526 if (unibyte_display_via_language_environment
19527 && SINGLE_BYTE_CHAR_P (it
->c
)
19530 && !NILP (Vnonascii_translation_table
))))
19532 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
19535 /* Get face and font to use. Encode IT->char_to_display. */
19536 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
19537 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
19538 get_char_face_and_encoding (it
->f
, it
->char_to_display
, it
->face_id
,
19539 &char2b
, it
->multibyte_p
, 0);
19542 /* When no suitable font found, use the default font. */
19543 font_not_found_p
= font
== NULL
;
19544 if (font_not_found_p
)
19546 font
= FRAME_FONT (it
->f
);
19547 boff
= FRAME_BASELINE_OFFSET (it
->f
);
19552 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
19553 boff
= font_info
->baseline_offset
;
19554 if (font_info
->vertical_centering
)
19555 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
19558 /* There are no padding glyphs, so there is only one glyph to
19559 produce for the composition. Important is that pixel_width,
19560 ascent and descent are the values of what is drawn by
19561 draw_glyphs (i.e. the values of the overall glyphs composed). */
19564 /* If we have not yet calculated pixel size data of glyphs of
19565 the composition for the current face font, calculate them
19566 now. Theoretically, we have to check all fonts for the
19567 glyphs, but that requires much time and memory space. So,
19568 here we check only the font of the first glyph. This leads
19569 to incorrect display very rarely, and C-l (recenter) can
19570 correct the display anyway. */
19571 if (cmp
->font
!= (void *) font
)
19573 /* Ascent and descent of the font of the first character of
19574 this composition (adjusted by baseline offset). Ascent
19575 and descent of overall glyphs should not be less than
19576 them respectively. */
19577 int font_ascent
= FONT_BASE (font
) + boff
;
19578 int font_descent
= FONT_DESCENT (font
) - boff
;
19579 /* Bounding box of the overall glyphs. */
19580 int leftmost
, rightmost
, lowest
, highest
;
19581 int i
, width
, ascent
, descent
;
19583 cmp
->font
= (void *) font
;
19585 /* Initialize the bounding box. */
19587 && (pcm
= rif
->per_char_metric (font
, &char2b
,
19588 FONT_TYPE_FOR_MULTIBYTE (font
, it
->c
))))
19590 width
= pcm
->width
;
19591 ascent
= pcm
->ascent
;
19592 descent
= pcm
->descent
;
19596 width
= FONT_WIDTH (font
);
19597 ascent
= FONT_BASE (font
);
19598 descent
= FONT_DESCENT (font
);
19602 lowest
= - descent
+ boff
;
19603 highest
= ascent
+ boff
;
19607 && font_info
->default_ascent
19608 && CHAR_TABLE_P (Vuse_default_ascent
)
19609 && !NILP (Faref (Vuse_default_ascent
,
19610 make_number (it
->char_to_display
))))
19611 highest
= font_info
->default_ascent
+ boff
;
19613 /* Draw the first glyph at the normal position. It may be
19614 shifted to right later if some other glyphs are drawn at
19616 cmp
->offsets
[0] = 0;
19617 cmp
->offsets
[1] = boff
;
19619 /* Set cmp->offsets for the remaining glyphs. */
19620 for (i
= 1; i
< cmp
->glyph_len
; i
++)
19622 int left
, right
, btm
, top
;
19623 int ch
= COMPOSITION_GLYPH (cmp
, i
);
19624 int face_id
= FACE_FOR_CHAR (it
->f
, face
, ch
);
19626 face
= FACE_FROM_ID (it
->f
, face_id
);
19627 get_char_face_and_encoding (it
->f
, ch
, face
->id
,
19628 &char2b
, it
->multibyte_p
, 0);
19632 font
= FRAME_FONT (it
->f
);
19633 boff
= FRAME_BASELINE_OFFSET (it
->f
);
19639 = FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
19640 boff
= font_info
->baseline_offset
;
19641 if (font_info
->vertical_centering
)
19642 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
19646 && (pcm
= rif
->per_char_metric (font
, &char2b
,
19647 FONT_TYPE_FOR_MULTIBYTE (font
, ch
))))
19649 width
= pcm
->width
;
19650 ascent
= pcm
->ascent
;
19651 descent
= pcm
->descent
;
19655 width
= FONT_WIDTH (font
);
19660 if (cmp
->method
!= COMPOSITION_WITH_RULE_ALTCHARS
)
19662 /* Relative composition with or without
19663 alternate chars. */
19664 left
= (leftmost
+ rightmost
- width
) / 2;
19665 btm
= - descent
+ boff
;
19666 if (font_info
&& font_info
->relative_compose
19667 && (! CHAR_TABLE_P (Vignore_relative_composition
)
19668 || NILP (Faref (Vignore_relative_composition
,
19669 make_number (ch
)))))
19672 if (- descent
>= font_info
->relative_compose
)
19673 /* One extra pixel between two glyphs. */
19675 else if (ascent
<= 0)
19676 /* One extra pixel between two glyphs. */
19677 btm
= lowest
- 1 - ascent
- descent
;
19682 /* A composition rule is specified by an integer
19683 value that encodes global and new reference
19684 points (GREF and NREF). GREF and NREF are
19685 specified by numbers as below:
19687 0---1---2 -- ascent
19691 9--10--11 -- center
19693 ---3---4---5--- baseline
19695 6---7---8 -- descent
19697 int rule
= COMPOSITION_RULE (cmp
, i
);
19698 int gref
, nref
, grefx
, grefy
, nrefx
, nrefy
;
19700 COMPOSITION_DECODE_RULE (rule
, gref
, nref
);
19701 grefx
= gref
% 3, nrefx
= nref
% 3;
19702 grefy
= gref
/ 3, nrefy
= nref
/ 3;
19705 + grefx
* (rightmost
- leftmost
) / 2
19706 - nrefx
* width
/ 2);
19707 btm
= ((grefy
== 0 ? highest
19709 : grefy
== 2 ? lowest
19710 : (highest
+ lowest
) / 2)
19711 - (nrefy
== 0 ? ascent
+ descent
19712 : nrefy
== 1 ? descent
- boff
19714 : (ascent
+ descent
) / 2));
19717 cmp
->offsets
[i
* 2] = left
;
19718 cmp
->offsets
[i
* 2 + 1] = btm
+ descent
;
19720 /* Update the bounding box of the overall glyphs. */
19721 right
= left
+ width
;
19722 top
= btm
+ descent
+ ascent
;
19723 if (left
< leftmost
)
19725 if (right
> rightmost
)
19733 /* If there are glyphs whose x-offsets are negative,
19734 shift all glyphs to the right and make all x-offsets
19738 for (i
= 0; i
< cmp
->glyph_len
; i
++)
19739 cmp
->offsets
[i
* 2] -= leftmost
;
19740 rightmost
-= leftmost
;
19743 cmp
->pixel_width
= rightmost
;
19744 cmp
->ascent
= highest
;
19745 cmp
->descent
= - lowest
;
19746 if (cmp
->ascent
< font_ascent
)
19747 cmp
->ascent
= font_ascent
;
19748 if (cmp
->descent
< font_descent
)
19749 cmp
->descent
= font_descent
;
19752 it
->pixel_width
= cmp
->pixel_width
;
19753 it
->ascent
= it
->phys_ascent
= cmp
->ascent
;
19754 it
->descent
= it
->phys_descent
= cmp
->descent
;
19756 if (face
->box
!= FACE_NO_BOX
)
19758 int thick
= face
->box_line_width
;
19762 it
->ascent
+= thick
;
19763 it
->descent
+= thick
;
19768 if (it
->start_of_box_run_p
)
19769 it
->pixel_width
+= thick
;
19770 if (it
->end_of_box_run_p
)
19771 it
->pixel_width
+= thick
;
19774 /* If face has an overline, add the height of the overline
19775 (1 pixel) and a 1 pixel margin to the character height. */
19776 if (face
->overline_p
)
19779 take_vertical_position_into_account (it
);
19782 append_composite_glyph (it
);
19784 else if (it
->what
== IT_IMAGE
)
19785 produce_image_glyph (it
);
19786 else if (it
->what
== IT_STRETCH
)
19787 produce_stretch_glyph (it
);
19789 /* Accumulate dimensions. Note: can't assume that it->descent > 0
19790 because this isn't true for images with `:ascent 100'. */
19791 xassert (it
->ascent
>= 0 && it
->descent
>= 0);
19792 if (it
->area
== TEXT_AREA
)
19793 it
->current_x
+= it
->pixel_width
;
19795 if (extra_line_spacing
> 0)
19797 it
->descent
+= extra_line_spacing
;
19798 if (extra_line_spacing
> it
->max_extra_line_spacing
)
19799 it
->max_extra_line_spacing
= extra_line_spacing
;
19802 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
19803 it
->max_descent
= max (it
->max_descent
, it
->descent
);
19804 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
19805 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
19809 Output LEN glyphs starting at START at the nominal cursor position.
19810 Advance the nominal cursor over the text. The global variable
19811 updated_window contains the window being updated, updated_row is
19812 the glyph row being updated, and updated_area is the area of that
19813 row being updated. */
19816 x_write_glyphs (start
, len
)
19817 struct glyph
*start
;
19822 xassert (updated_window
&& updated_row
);
19825 /* Write glyphs. */
19827 hpos
= start
- updated_row
->glyphs
[updated_area
];
19828 x
= draw_glyphs (updated_window
, output_cursor
.x
,
19829 updated_row
, updated_area
,
19831 DRAW_NORMAL_TEXT
, 0);
19833 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
19834 if (updated_area
== TEXT_AREA
19835 && updated_window
->phys_cursor_on_p
19836 && updated_window
->phys_cursor
.vpos
== output_cursor
.vpos
19837 && updated_window
->phys_cursor
.hpos
>= hpos
19838 && updated_window
->phys_cursor
.hpos
< hpos
+ len
)
19839 updated_window
->phys_cursor_on_p
= 0;
19843 /* Advance the output cursor. */
19844 output_cursor
.hpos
+= len
;
19845 output_cursor
.x
= x
;
19850 Insert LEN glyphs from START at the nominal cursor position. */
19853 x_insert_glyphs (start
, len
)
19854 struct glyph
*start
;
19859 int line_height
, shift_by_width
, shifted_region_width
;
19860 struct glyph_row
*row
;
19861 struct glyph
*glyph
;
19862 int frame_x
, frame_y
, hpos
;
19864 xassert (updated_window
&& updated_row
);
19866 w
= updated_window
;
19867 f
= XFRAME (WINDOW_FRAME (w
));
19869 /* Get the height of the line we are in. */
19871 line_height
= row
->height
;
19873 /* Get the width of the glyphs to insert. */
19874 shift_by_width
= 0;
19875 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
19876 shift_by_width
+= glyph
->pixel_width
;
19878 /* Get the width of the region to shift right. */
19879 shifted_region_width
= (window_box_width (w
, updated_area
)
19884 frame_x
= window_box_left (w
, updated_area
) + output_cursor
.x
;
19885 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
19887 rif
->shift_glyphs_for_insert (f
, frame_x
, frame_y
, shifted_region_width
,
19888 line_height
, shift_by_width
);
19890 /* Write the glyphs. */
19891 hpos
= start
- row
->glyphs
[updated_area
];
19892 draw_glyphs (w
, output_cursor
.x
, row
, updated_area
,
19894 DRAW_NORMAL_TEXT
, 0);
19896 /* Advance the output cursor. */
19897 output_cursor
.hpos
+= len
;
19898 output_cursor
.x
+= shift_by_width
;
19904 Erase the current text line from the nominal cursor position
19905 (inclusive) to pixel column TO_X (exclusive). The idea is that
19906 everything from TO_X onward is already erased.
19908 TO_X is a pixel position relative to updated_area of
19909 updated_window. TO_X == -1 means clear to the end of this area. */
19912 x_clear_end_of_line (to_x
)
19916 struct window
*w
= updated_window
;
19917 int max_x
, min_y
, max_y
;
19918 int from_x
, from_y
, to_y
;
19920 xassert (updated_window
&& updated_row
);
19921 f
= XFRAME (w
->frame
);
19923 if (updated_row
->full_width_p
)
19924 max_x
= WINDOW_TOTAL_WIDTH (w
);
19926 max_x
= window_box_width (w
, updated_area
);
19927 max_y
= window_text_bottom_y (w
);
19929 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
19930 of window. For TO_X > 0, truncate to end of drawing area. */
19936 to_x
= min (to_x
, max_x
);
19938 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
19940 /* Notice if the cursor will be cleared by this operation. */
19941 if (!updated_row
->full_width_p
)
19942 notice_overwritten_cursor (w
, updated_area
,
19943 output_cursor
.x
, -1,
19945 MATRIX_ROW_BOTTOM_Y (updated_row
));
19947 from_x
= output_cursor
.x
;
19949 /* Translate to frame coordinates. */
19950 if (updated_row
->full_width_p
)
19952 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
19953 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
19957 int area_left
= window_box_left (w
, updated_area
);
19958 from_x
+= area_left
;
19962 min_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
19963 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
19964 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
19966 /* Prevent inadvertently clearing to end of the X window. */
19967 if (to_x
> from_x
&& to_y
> from_y
)
19970 rif
->clear_frame_area (f
, from_x
, from_y
,
19971 to_x
- from_x
, to_y
- from_y
);
19976 #endif /* HAVE_WINDOW_SYSTEM */
19980 /***********************************************************************
19982 ***********************************************************************/
19984 /* Value is the internal representation of the specified cursor type
19985 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
19986 of the bar cursor. */
19988 static enum text_cursor_kinds
19989 get_specified_cursor_type (arg
, width
)
19993 enum text_cursor_kinds type
;
19998 if (EQ (arg
, Qbox
))
19999 return FILLED_BOX_CURSOR
;
20001 if (EQ (arg
, Qhollow
))
20002 return HOLLOW_BOX_CURSOR
;
20004 if (EQ (arg
, Qbar
))
20011 && EQ (XCAR (arg
), Qbar
)
20012 && INTEGERP (XCDR (arg
))
20013 && XINT (XCDR (arg
)) >= 0)
20015 *width
= XINT (XCDR (arg
));
20019 if (EQ (arg
, Qhbar
))
20022 return HBAR_CURSOR
;
20026 && EQ (XCAR (arg
), Qhbar
)
20027 && INTEGERP (XCDR (arg
))
20028 && XINT (XCDR (arg
)) >= 0)
20030 *width
= XINT (XCDR (arg
));
20031 return HBAR_CURSOR
;
20034 /* Treat anything unknown as "hollow box cursor".
20035 It was bad to signal an error; people have trouble fixing
20036 .Xdefaults with Emacs, when it has something bad in it. */
20037 type
= HOLLOW_BOX_CURSOR
;
20042 /* Set the default cursor types for specified frame. */
20044 set_frame_cursor_types (f
, arg
)
20051 FRAME_DESIRED_CURSOR (f
) = get_specified_cursor_type (arg
, &width
);
20052 FRAME_CURSOR_WIDTH (f
) = width
;
20054 /* By default, set up the blink-off state depending on the on-state. */
20056 tem
= Fassoc (arg
, Vblink_cursor_alist
);
20059 FRAME_BLINK_OFF_CURSOR (f
)
20060 = get_specified_cursor_type (XCDR (tem
), &width
);
20061 FRAME_BLINK_OFF_CURSOR_WIDTH (f
) = width
;
20064 FRAME_BLINK_OFF_CURSOR (f
) = DEFAULT_CURSOR
;
20068 /* Return the cursor we want to be displayed in window W. Return
20069 width of bar/hbar cursor through WIDTH arg. Return with
20070 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
20071 (i.e. if the `system caret' should track this cursor).
20073 In a mini-buffer window, we want the cursor only to appear if we
20074 are reading input from this window. For the selected window, we
20075 want the cursor type given by the frame parameter or buffer local
20076 setting of cursor-type. If explicitly marked off, draw no cursor.
20077 In all other cases, we want a hollow box cursor. */
20079 static enum text_cursor_kinds
20080 get_window_cursor_type (w
, glyph
, width
, active_cursor
)
20082 struct glyph
*glyph
;
20084 int *active_cursor
;
20086 struct frame
*f
= XFRAME (w
->frame
);
20087 struct buffer
*b
= XBUFFER (w
->buffer
);
20088 int cursor_type
= DEFAULT_CURSOR
;
20089 Lisp_Object alt_cursor
;
20090 int non_selected
= 0;
20092 *active_cursor
= 1;
20095 if (cursor_in_echo_area
20096 && FRAME_HAS_MINIBUF_P (f
)
20097 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
20099 if (w
== XWINDOW (echo_area_window
))
20101 *width
= FRAME_CURSOR_WIDTH (f
);
20102 return FRAME_DESIRED_CURSOR (f
);
20105 *active_cursor
= 0;
20109 /* Nonselected window or nonselected frame. */
20110 else if (w
!= XWINDOW (f
->selected_window
)
20111 #ifdef HAVE_WINDOW_SYSTEM
20112 || f
!= FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
20116 *active_cursor
= 0;
20118 if (MINI_WINDOW_P (w
) && minibuf_level
== 0)
20124 /* Never display a cursor in a window in which cursor-type is nil. */
20125 if (NILP (b
->cursor_type
))
20128 /* Use cursor-in-non-selected-windows for non-selected window or frame. */
20131 alt_cursor
= Fbuffer_local_value (Qcursor_in_non_selected_windows
, w
->buffer
);
20132 return get_specified_cursor_type (alt_cursor
, width
);
20135 /* Get the normal cursor type for this window. */
20136 if (EQ (b
->cursor_type
, Qt
))
20138 cursor_type
= FRAME_DESIRED_CURSOR (f
);
20139 *width
= FRAME_CURSOR_WIDTH (f
);
20142 cursor_type
= get_specified_cursor_type (b
->cursor_type
, width
);
20144 /* Use normal cursor if not blinked off. */
20145 if (!w
->cursor_off_p
)
20147 if (glyph
!= NULL
&& glyph
->type
== IMAGE_GLYPH
) {
20148 if (cursor_type
== FILLED_BOX_CURSOR
)
20149 cursor_type
= HOLLOW_BOX_CURSOR
;
20151 return cursor_type
;
20154 /* Cursor is blinked off, so determine how to "toggle" it. */
20156 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
20157 if ((alt_cursor
= Fassoc (b
->cursor_type
, Vblink_cursor_alist
), !NILP (alt_cursor
)))
20158 return get_specified_cursor_type (XCDR (alt_cursor
), width
);
20160 /* Then see if frame has specified a specific blink off cursor type. */
20161 if (FRAME_BLINK_OFF_CURSOR (f
) != DEFAULT_CURSOR
)
20163 *width
= FRAME_BLINK_OFF_CURSOR_WIDTH (f
);
20164 return FRAME_BLINK_OFF_CURSOR (f
);
20168 /* Some people liked having a permanently visible blinking cursor,
20169 while others had very strong opinions against it. So it was
20170 decided to remove it. KFS 2003-09-03 */
20172 /* Finally perform built-in cursor blinking:
20173 filled box <-> hollow box
20174 wide [h]bar <-> narrow [h]bar
20175 narrow [h]bar <-> no cursor
20176 other type <-> no cursor */
20178 if (cursor_type
== FILLED_BOX_CURSOR
)
20179 return HOLLOW_BOX_CURSOR
;
20181 if ((cursor_type
== BAR_CURSOR
|| cursor_type
== HBAR_CURSOR
) && *width
> 1)
20184 return cursor_type
;
20192 #ifdef HAVE_WINDOW_SYSTEM
20194 /* Notice when the text cursor of window W has been completely
20195 overwritten by a drawing operation that outputs glyphs in AREA
20196 starting at X0 and ending at X1 in the line starting at Y0 and
20197 ending at Y1. X coordinates are area-relative. X1 < 0 means all
20198 the rest of the line after X0 has been written. Y coordinates
20199 are window-relative. */
20202 notice_overwritten_cursor (w
, area
, x0
, x1
, y0
, y1
)
20204 enum glyph_row_area area
;
20205 int x0
, y0
, x1
, y1
;
20207 int cx0
, cx1
, cy0
, cy1
;
20208 struct glyph_row
*row
;
20210 if (!w
->phys_cursor_on_p
)
20212 if (area
!= TEXT_AREA
)
20215 if (w
->phys_cursor
.vpos
< 0
20216 || w
->phys_cursor
.vpos
>= w
->current_matrix
->nrows
20217 || (row
= w
->current_matrix
->rows
+ w
->phys_cursor
.vpos
,
20218 !(row
->enabled_p
&& row
->displays_text_p
)))
20221 if (row
->cursor_in_fringe_p
)
20223 row
->cursor_in_fringe_p
= 0;
20224 draw_fringe_bitmap (w
, row
, 0);
20225 w
->phys_cursor_on_p
= 0;
20229 cx0
= w
->phys_cursor
.x
;
20230 cx1
= cx0
+ w
->phys_cursor_width
;
20231 if (x0
> cx0
|| (x1
>= 0 && x1
< cx1
))
20234 /* The cursor image will be completely removed from the
20235 screen if the output area intersects the cursor area in
20236 y-direction. When we draw in [y0 y1[, and some part of
20237 the cursor is at y < y0, that part must have been drawn
20238 before. When scrolling, the cursor is erased before
20239 actually scrolling, so we don't come here. When not
20240 scrolling, the rows above the old cursor row must have
20241 changed, and in this case these rows must have written
20242 over the cursor image.
20244 Likewise if part of the cursor is below y1, with the
20245 exception of the cursor being in the first blank row at
20246 the buffer and window end because update_text_area
20247 doesn't draw that row. (Except when it does, but
20248 that's handled in update_text_area.) */
20250 cy0
= w
->phys_cursor
.y
;
20251 cy1
= cy0
+ w
->phys_cursor_height
;
20252 if ((y0
< cy0
|| y0
>= cy1
) && (y1
<= cy0
|| y1
>= cy1
))
20255 w
->phys_cursor_on_p
= 0;
20258 #endif /* HAVE_WINDOW_SYSTEM */
20261 /************************************************************************
20263 ************************************************************************/
20265 #ifdef HAVE_WINDOW_SYSTEM
20268 Fix the display of area AREA of overlapping row ROW in window W. */
20271 x_fix_overlapping_area (w
, row
, area
)
20273 struct glyph_row
*row
;
20274 enum glyph_row_area area
;
20281 for (i
= 0; i
< row
->used
[area
];)
20283 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
20285 int start
= i
, start_x
= x
;
20289 x
+= row
->glyphs
[area
][i
].pixel_width
;
20292 while (i
< row
->used
[area
]
20293 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
20295 draw_glyphs (w
, start_x
, row
, area
,
20297 DRAW_NORMAL_TEXT
, 1);
20301 x
+= row
->glyphs
[area
][i
].pixel_width
;
20311 Draw the cursor glyph of window W in glyph row ROW. See the
20312 comment of draw_glyphs for the meaning of HL. */
20315 draw_phys_cursor_glyph (w
, row
, hl
)
20317 struct glyph_row
*row
;
20318 enum draw_glyphs_face hl
;
20320 /* If cursor hpos is out of bounds, don't draw garbage. This can
20321 happen in mini-buffer windows when switching between echo area
20322 glyphs and mini-buffer. */
20323 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
20325 int on_p
= w
->phys_cursor_on_p
;
20327 x1
= draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
20328 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
20330 w
->phys_cursor_on_p
= on_p
;
20332 if (hl
== DRAW_CURSOR
)
20333 w
->phys_cursor_width
= x1
- w
->phys_cursor
.x
;
20334 /* When we erase the cursor, and ROW is overlapped by other
20335 rows, make sure that these overlapping parts of other rows
20337 else if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
20339 if (row
> w
->current_matrix
->rows
20340 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
20341 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
);
20343 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
20344 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
20345 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
);
20352 Erase the image of a cursor of window W from the screen. */
20355 erase_phys_cursor (w
)
20358 struct frame
*f
= XFRAME (w
->frame
);
20359 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
20360 int hpos
= w
->phys_cursor
.hpos
;
20361 int vpos
= w
->phys_cursor
.vpos
;
20362 int mouse_face_here_p
= 0;
20363 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
20364 struct glyph_row
*cursor_row
;
20365 struct glyph
*cursor_glyph
;
20366 enum draw_glyphs_face hl
;
20368 /* No cursor displayed or row invalidated => nothing to do on the
20370 if (w
->phys_cursor_type
== NO_CURSOR
)
20371 goto mark_cursor_off
;
20373 /* VPOS >= active_glyphs->nrows means that window has been resized.
20374 Don't bother to erase the cursor. */
20375 if (vpos
>= active_glyphs
->nrows
)
20376 goto mark_cursor_off
;
20378 /* If row containing cursor is marked invalid, there is nothing we
20380 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
20381 if (!cursor_row
->enabled_p
)
20382 goto mark_cursor_off
;
20384 /* If line spacing is > 0, old cursor may only be partially visible in
20385 window after split-window. So adjust visible height. */
20386 cursor_row
->visible_height
= min (cursor_row
->visible_height
,
20387 window_text_bottom_y (w
) - cursor_row
->y
);
20389 /* If row is completely invisible, don't attempt to delete a cursor which
20390 isn't there. This can happen if cursor is at top of a window, and
20391 we switch to a buffer with a header line in that window. */
20392 if (cursor_row
->visible_height
<= 0)
20393 goto mark_cursor_off
;
20395 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
20396 if (cursor_row
->cursor_in_fringe_p
)
20398 cursor_row
->cursor_in_fringe_p
= 0;
20399 draw_fringe_bitmap (w
, cursor_row
, 0);
20400 goto mark_cursor_off
;
20403 /* This can happen when the new row is shorter than the old one.
20404 In this case, either draw_glyphs or clear_end_of_line
20405 should have cleared the cursor. Note that we wouldn't be
20406 able to erase the cursor in this case because we don't have a
20407 cursor glyph at hand. */
20408 if (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])
20409 goto mark_cursor_off
;
20411 /* If the cursor is in the mouse face area, redisplay that when
20412 we clear the cursor. */
20413 if (! NILP (dpyinfo
->mouse_face_window
)
20414 && w
== XWINDOW (dpyinfo
->mouse_face_window
)
20415 && (vpos
> dpyinfo
->mouse_face_beg_row
20416 || (vpos
== dpyinfo
->mouse_face_beg_row
20417 && hpos
>= dpyinfo
->mouse_face_beg_col
))
20418 && (vpos
< dpyinfo
->mouse_face_end_row
20419 || (vpos
== dpyinfo
->mouse_face_end_row
20420 && hpos
< dpyinfo
->mouse_face_end_col
))
20421 /* Don't redraw the cursor's spot in mouse face if it is at the
20422 end of a line (on a newline). The cursor appears there, but
20423 mouse highlighting does not. */
20424 && cursor_row
->used
[TEXT_AREA
] > hpos
)
20425 mouse_face_here_p
= 1;
20427 /* Maybe clear the display under the cursor. */
20428 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
20431 int header_line_height
= WINDOW_HEADER_LINE_HEIGHT (w
);
20434 cursor_glyph
= get_phys_cursor_glyph (w
);
20435 if (cursor_glyph
== NULL
)
20436 goto mark_cursor_off
;
20438 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
20439 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
, cursor_row
->y
));
20440 width
= min (cursor_glyph
->pixel_width
,
20441 window_box_width (w
, TEXT_AREA
) - w
->phys_cursor
.x
);
20443 rif
->clear_frame_area (f
, x
, y
, width
, cursor_row
->visible_height
);
20446 /* Erase the cursor by redrawing the character underneath it. */
20447 if (mouse_face_here_p
)
20448 hl
= DRAW_MOUSE_FACE
;
20450 hl
= DRAW_NORMAL_TEXT
;
20451 draw_phys_cursor_glyph (w
, cursor_row
, hl
);
20454 w
->phys_cursor_on_p
= 0;
20455 w
->phys_cursor_type
= NO_CURSOR
;
20460 Display or clear cursor of window W. If ON is zero, clear the
20461 cursor. If it is non-zero, display the cursor. If ON is nonzero,
20462 where to put the cursor is specified by HPOS, VPOS, X and Y. */
20465 display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
)
20467 int on
, hpos
, vpos
, x
, y
;
20469 struct frame
*f
= XFRAME (w
->frame
);
20470 int new_cursor_type
;
20471 int new_cursor_width
;
20473 struct glyph_row
*glyph_row
;
20474 struct glyph
*glyph
;
20476 /* This is pointless on invisible frames, and dangerous on garbaged
20477 windows and frames; in the latter case, the frame or window may
20478 be in the midst of changing its size, and x and y may be off the
20480 if (! FRAME_VISIBLE_P (f
)
20481 || FRAME_GARBAGED_P (f
)
20482 || vpos
>= w
->current_matrix
->nrows
20483 || hpos
>= w
->current_matrix
->matrix_w
)
20486 /* If cursor is off and we want it off, return quickly. */
20487 if (!on
&& !w
->phys_cursor_on_p
)
20490 glyph_row
= MATRIX_ROW (w
->current_matrix
, vpos
);
20491 /* If cursor row is not enabled, we don't really know where to
20492 display the cursor. */
20493 if (!glyph_row
->enabled_p
)
20495 w
->phys_cursor_on_p
= 0;
20500 if (!glyph_row
->exact_window_width_line_p
20501 || hpos
< glyph_row
->used
[TEXT_AREA
])
20502 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
20504 xassert (interrupt_input_blocked
);
20506 /* Set new_cursor_type to the cursor we want to be displayed. */
20507 new_cursor_type
= get_window_cursor_type (w
, glyph
,
20508 &new_cursor_width
, &active_cursor
);
20510 /* If cursor is currently being shown and we don't want it to be or
20511 it is in the wrong place, or the cursor type is not what we want,
20513 if (w
->phys_cursor_on_p
20515 || w
->phys_cursor
.x
!= x
20516 || w
->phys_cursor
.y
!= y
20517 || new_cursor_type
!= w
->phys_cursor_type
20518 || ((new_cursor_type
== BAR_CURSOR
|| new_cursor_type
== HBAR_CURSOR
)
20519 && new_cursor_width
!= w
->phys_cursor_width
)))
20520 erase_phys_cursor (w
);
20522 /* Don't check phys_cursor_on_p here because that flag is only set
20523 to zero in some cases where we know that the cursor has been
20524 completely erased, to avoid the extra work of erasing the cursor
20525 twice. In other words, phys_cursor_on_p can be 1 and the cursor
20526 still not be visible, or it has only been partly erased. */
20529 w
->phys_cursor_ascent
= glyph_row
->ascent
;
20530 w
->phys_cursor_height
= glyph_row
->height
;
20532 /* Set phys_cursor_.* before x_draw_.* is called because some
20533 of them may need the information. */
20534 w
->phys_cursor
.x
= x
;
20535 w
->phys_cursor
.y
= glyph_row
->y
;
20536 w
->phys_cursor
.hpos
= hpos
;
20537 w
->phys_cursor
.vpos
= vpos
;
20540 rif
->draw_window_cursor (w
, glyph_row
, x
, y
,
20541 new_cursor_type
, new_cursor_width
,
20542 on
, active_cursor
);
20546 /* Switch the display of W's cursor on or off, according to the value
20550 update_window_cursor (w
, on
)
20554 /* Don't update cursor in windows whose frame is in the process
20555 of being deleted. */
20556 if (w
->current_matrix
)
20559 display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
20560 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
20566 /* Call update_window_cursor with parameter ON_P on all leaf windows
20567 in the window tree rooted at W. */
20570 update_cursor_in_window_tree (w
, on_p
)
20576 if (!NILP (w
->hchild
))
20577 update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
20578 else if (!NILP (w
->vchild
))
20579 update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
20581 update_window_cursor (w
, on_p
);
20583 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
20589 Display the cursor on window W, or clear it, according to ON_P.
20590 Don't change the cursor's position. */
20593 x_update_cursor (f
, on_p
)
20597 update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
20602 Clear the cursor of window W to background color, and mark the
20603 cursor as not shown. This is used when the text where the cursor
20604 is is about to be rewritten. */
20610 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
20611 update_window_cursor (w
, 0);
20616 Display the active region described by mouse_face_* according to DRAW. */
20619 show_mouse_face (dpyinfo
, draw
)
20620 Display_Info
*dpyinfo
;
20621 enum draw_glyphs_face draw
;
20623 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
20624 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
20626 if (/* If window is in the process of being destroyed, don't bother
20628 w
->current_matrix
!= NULL
20629 /* Don't update mouse highlight if hidden */
20630 && (draw
!= DRAW_MOUSE_FACE
|| !dpyinfo
->mouse_face_hidden
)
20631 /* Recognize when we are called to operate on rows that don't exist
20632 anymore. This can happen when a window is split. */
20633 && dpyinfo
->mouse_face_end_row
< w
->current_matrix
->nrows
)
20635 int phys_cursor_on_p
= w
->phys_cursor_on_p
;
20636 struct glyph_row
*row
, *first
, *last
;
20638 first
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_beg_row
);
20639 last
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_end_row
);
20641 for (row
= first
; row
<= last
&& row
->enabled_p
; ++row
)
20643 int start_hpos
, end_hpos
, start_x
;
20645 /* For all but the first row, the highlight starts at column 0. */
20648 start_hpos
= dpyinfo
->mouse_face_beg_col
;
20649 start_x
= dpyinfo
->mouse_face_beg_x
;
20658 end_hpos
= dpyinfo
->mouse_face_end_col
;
20660 end_hpos
= row
->used
[TEXT_AREA
];
20662 if (end_hpos
> start_hpos
)
20664 draw_glyphs (w
, start_x
, row
, TEXT_AREA
,
20665 start_hpos
, end_hpos
,
20669 = draw
== DRAW_MOUSE_FACE
|| draw
== DRAW_IMAGE_RAISED
;
20673 /* When we've written over the cursor, arrange for it to
20674 be displayed again. */
20675 if (phys_cursor_on_p
&& !w
->phys_cursor_on_p
)
20678 display_and_set_cursor (w
, 1,
20679 w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
20680 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
20685 /* Change the mouse cursor. */
20686 if (draw
== DRAW_NORMAL_TEXT
)
20687 rif
->define_frame_cursor (f
, FRAME_X_OUTPUT (f
)->text_cursor
);
20688 else if (draw
== DRAW_MOUSE_FACE
)
20689 rif
->define_frame_cursor (f
, FRAME_X_OUTPUT (f
)->hand_cursor
);
20691 rif
->define_frame_cursor (f
, FRAME_X_OUTPUT (f
)->nontext_cursor
);
20695 Clear out the mouse-highlighted active region.
20696 Redraw it un-highlighted first. Value is non-zero if mouse
20697 face was actually drawn unhighlighted. */
20700 clear_mouse_face (dpyinfo
)
20701 Display_Info
*dpyinfo
;
20705 if (!dpyinfo
->mouse_face_hidden
&& !NILP (dpyinfo
->mouse_face_window
))
20707 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
20711 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
20712 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
20713 dpyinfo
->mouse_face_window
= Qnil
;
20714 dpyinfo
->mouse_face_overlay
= Qnil
;
20720 Non-zero if physical cursor of window W is within mouse face. */
20723 cursor_in_mouse_face_p (w
)
20726 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (XFRAME (w
->frame
));
20727 int in_mouse_face
= 0;
20729 if (WINDOWP (dpyinfo
->mouse_face_window
)
20730 && XWINDOW (dpyinfo
->mouse_face_window
) == w
)
20732 int hpos
= w
->phys_cursor
.hpos
;
20733 int vpos
= w
->phys_cursor
.vpos
;
20735 if (vpos
>= dpyinfo
->mouse_face_beg_row
20736 && vpos
<= dpyinfo
->mouse_face_end_row
20737 && (vpos
> dpyinfo
->mouse_face_beg_row
20738 || hpos
>= dpyinfo
->mouse_face_beg_col
)
20739 && (vpos
< dpyinfo
->mouse_face_end_row
20740 || hpos
< dpyinfo
->mouse_face_end_col
20741 || dpyinfo
->mouse_face_past_end
))
20745 return in_mouse_face
;
20751 /* Find the glyph matrix position of buffer position CHARPOS in window
20752 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
20753 current glyphs must be up to date. If CHARPOS is above window
20754 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
20755 of last line in W. In the row containing CHARPOS, stop before glyphs
20756 having STOP as object. */
20758 #if 1 /* This is a version of fast_find_position that's more correct
20759 in the presence of hscrolling, for example. I didn't install
20760 it right away because the problem fixed is minor, it failed
20761 in 20.x as well, and I think it's too risky to install
20762 so near the release of 21.1. 2001-09-25 gerd. */
20765 fast_find_position (w
, charpos
, hpos
, vpos
, x
, y
, stop
)
20768 int *hpos
, *vpos
, *x
, *y
;
20771 struct glyph_row
*row
, *first
;
20772 struct glyph
*glyph
, *end
;
20775 first
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
20776 if (charpos
< MATRIX_ROW_START_CHARPOS (first
))
20781 *vpos
= MATRIX_ROW_VPOS (first
, w
->current_matrix
);
20785 row
= row_containing_pos (w
, charpos
, first
, NULL
, 0);
20788 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
20792 /* If whole rows or last part of a row came from a display overlay,
20793 row_containing_pos will skip over such rows because their end pos
20794 equals the start pos of the overlay or interval.
20796 Move back if we have a STOP object and previous row's
20797 end glyph came from STOP. */
20800 struct glyph_row
*prev
;
20801 while ((prev
= row
- 1, prev
>= first
)
20802 && MATRIX_ROW_END_CHARPOS (prev
) == charpos
20803 && prev
->used
[TEXT_AREA
] > 0)
20805 struct glyph
*beg
= prev
->glyphs
[TEXT_AREA
];
20806 glyph
= beg
+ prev
->used
[TEXT_AREA
];
20807 while (--glyph
>= beg
20808 && INTEGERP (glyph
->object
));
20810 || !EQ (stop
, glyph
->object
))
20818 *vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
20820 glyph
= row
->glyphs
[TEXT_AREA
];
20821 end
= glyph
+ row
->used
[TEXT_AREA
];
20823 /* Skip over glyphs not having an object at the start of the row.
20824 These are special glyphs like truncation marks on terminal
20826 if (row
->displays_text_p
)
20828 && INTEGERP (glyph
->object
)
20829 && !EQ (stop
, glyph
->object
)
20830 && glyph
->charpos
< 0)
20832 *x
+= glyph
->pixel_width
;
20837 && !INTEGERP (glyph
->object
)
20838 && !EQ (stop
, glyph
->object
)
20839 && (!BUFFERP (glyph
->object
)
20840 || glyph
->charpos
< charpos
))
20842 *x
+= glyph
->pixel_width
;
20846 *hpos
= glyph
- row
->glyphs
[TEXT_AREA
];
20853 fast_find_position (w
, pos
, hpos
, vpos
, x
, y
, stop
)
20856 int *hpos
, *vpos
, *x
, *y
;
20861 int maybe_next_line_p
= 0;
20862 int line_start_position
;
20863 int yb
= window_text_bottom_y (w
);
20864 struct glyph_row
*row
, *best_row
;
20865 int row_vpos
, best_row_vpos
;
20868 row
= best_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
20869 row_vpos
= best_row_vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
20871 while (row
->y
< yb
)
20873 if (row
->used
[TEXT_AREA
])
20874 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
20876 line_start_position
= 0;
20878 if (line_start_position
> pos
)
20880 /* If the position sought is the end of the buffer,
20881 don't include the blank lines at the bottom of the window. */
20882 else if (line_start_position
== pos
20883 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
20885 maybe_next_line_p
= 1;
20888 else if (line_start_position
> 0)
20891 best_row_vpos
= row_vpos
;
20894 if (row
->y
+ row
->height
>= yb
)
20901 /* Find the right column within BEST_ROW. */
20903 current_x
= best_row
->x
;
20904 for (i
= 0; i
< best_row
->used
[TEXT_AREA
]; i
++)
20906 struct glyph
*glyph
= best_row
->glyphs
[TEXT_AREA
] + i
;
20907 int charpos
= glyph
->charpos
;
20909 if (BUFFERP (glyph
->object
))
20911 if (charpos
== pos
)
20914 *vpos
= best_row_vpos
;
20919 else if (charpos
> pos
)
20922 else if (EQ (glyph
->object
, stop
))
20927 current_x
+= glyph
->pixel_width
;
20930 /* If we're looking for the end of the buffer,
20931 and we didn't find it in the line we scanned,
20932 use the start of the following line. */
20933 if (maybe_next_line_p
)
20938 current_x
= best_row
->x
;
20941 *vpos
= best_row_vpos
;
20942 *hpos
= lastcol
+ 1;
20951 /* Find the position of the glyph for position POS in OBJECT in
20952 window W's current matrix, and return in *X, *Y the pixel
20953 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
20955 RIGHT_P non-zero means return the position of the right edge of the
20956 glyph, RIGHT_P zero means return the left edge position.
20958 If no glyph for POS exists in the matrix, return the position of
20959 the glyph with the next smaller position that is in the matrix, if
20960 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
20961 exists in the matrix, return the position of the glyph with the
20962 next larger position in OBJECT.
20964 Value is non-zero if a glyph was found. */
20967 fast_find_string_pos (w
, pos
, object
, hpos
, vpos
, x
, y
, right_p
)
20970 Lisp_Object object
;
20971 int *hpos
, *vpos
, *x
, *y
;
20974 int yb
= window_text_bottom_y (w
);
20975 struct glyph_row
*r
;
20976 struct glyph
*best_glyph
= NULL
;
20977 struct glyph_row
*best_row
= NULL
;
20980 for (r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
20981 r
->enabled_p
&& r
->y
< yb
;
20984 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
20985 struct glyph
*e
= g
+ r
->used
[TEXT_AREA
];
20988 for (gx
= r
->x
; g
< e
; gx
+= g
->pixel_width
, ++g
)
20989 if (EQ (g
->object
, object
))
20991 if (g
->charpos
== pos
)
20998 else if (best_glyph
== NULL
20999 || ((abs (g
->charpos
- pos
)
21000 < abs (best_glyph
->charpos
- pos
))
21003 : g
->charpos
> pos
)))
21017 *hpos
= best_glyph
- best_row
->glyphs
[TEXT_AREA
];
21021 *x
+= best_glyph
->pixel_width
;
21026 *vpos
= best_row
- w
->current_matrix
->rows
;
21029 return best_glyph
!= NULL
;
21033 /* See if position X, Y is within a hot-spot of an image. */
21036 on_hot_spot_p (hot_spot
, x
, y
)
21037 Lisp_Object hot_spot
;
21040 if (!CONSP (hot_spot
))
21043 if (EQ (XCAR (hot_spot
), Qrect
))
21045 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
21046 Lisp_Object rect
= XCDR (hot_spot
);
21050 if (!CONSP (XCAR (rect
)))
21052 if (!CONSP (XCDR (rect
)))
21054 if (!(tem
= XCAR (XCAR (rect
)), INTEGERP (tem
) && x
>= XINT (tem
)))
21056 if (!(tem
= XCDR (XCAR (rect
)), INTEGERP (tem
) && y
>= XINT (tem
)))
21058 if (!(tem
= XCAR (XCDR (rect
)), INTEGERP (tem
) && x
<= XINT (tem
)))
21060 if (!(tem
= XCDR (XCDR (rect
)), INTEGERP (tem
) && y
<= XINT (tem
)))
21064 else if (EQ (XCAR (hot_spot
), Qcircle
))
21066 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
21067 Lisp_Object circ
= XCDR (hot_spot
);
21068 Lisp_Object lr
, lx0
, ly0
;
21070 && CONSP (XCAR (circ
))
21071 && (lr
= XCDR (circ
), INTEGERP (lr
) || FLOATP (lr
))
21072 && (lx0
= XCAR (XCAR (circ
)), INTEGERP (lx0
))
21073 && (ly0
= XCDR (XCAR (circ
)), INTEGERP (ly0
)))
21075 double r
= XFLOATINT (lr
);
21076 double dx
= XINT (lx0
) - x
;
21077 double dy
= XINT (ly0
) - y
;
21078 return (dx
* dx
+ dy
* dy
<= r
* r
);
21081 else if (EQ (XCAR (hot_spot
), Qpoly
))
21083 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
21084 if (VECTORP (XCDR (hot_spot
)))
21086 struct Lisp_Vector
*v
= XVECTOR (XCDR (hot_spot
));
21087 Lisp_Object
*poly
= v
->contents
;
21091 Lisp_Object lx
, ly
;
21094 /* Need an even number of coordinates, and at least 3 edges. */
21095 if (n
< 6 || n
& 1)
21098 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
21099 If count is odd, we are inside polygon. Pixels on edges
21100 may or may not be included depending on actual geometry of the
21102 if ((lx
= poly
[n
-2], !INTEGERP (lx
))
21103 || (ly
= poly
[n
-1], !INTEGERP (lx
)))
21105 x0
= XINT (lx
), y0
= XINT (ly
);
21106 for (i
= 0; i
< n
; i
+= 2)
21108 int x1
= x0
, y1
= y0
;
21109 if ((lx
= poly
[i
], !INTEGERP (lx
))
21110 || (ly
= poly
[i
+1], !INTEGERP (ly
)))
21112 x0
= XINT (lx
), y0
= XINT (ly
);
21114 /* Does this segment cross the X line? */
21122 if (y
> y0
&& y
> y1
)
21124 if (y
< y0
+ ((y1
- y0
) * (x
- x0
)) / (x1
- x0
))
21130 /* If we don't understand the format, pretend we're not in the hot-spot. */
21135 find_hot_spot (map
, x
, y
)
21139 while (CONSP (map
))
21141 if (CONSP (XCAR (map
))
21142 && on_hot_spot_p (XCAR (XCAR (map
)), x
, y
))
21150 DEFUN ("lookup-image-map", Flookup_image_map
, Slookup_image_map
,
21152 doc
: /* Lookup in image map MAP coordinates X and Y.
21153 An image map is an alist where each element has the format (AREA ID PLIST).
21154 An AREA is specified as either a rectangle, a circle, or a polygon:
21155 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
21156 pixel coordinates of the upper left and bottom right corners.
21157 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
21158 and the radius of the circle; r may be a float or integer.
21159 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
21160 vector describes one corner in the polygon.
21161 Returns the alist element for the first matching AREA in MAP. */)
21172 return find_hot_spot (map
, XINT (x
), XINT (y
));
21176 /* Display frame CURSOR, optionally using shape defined by POINTER. */
21178 define_frame_cursor1 (f
, cursor
, pointer
)
21181 Lisp_Object pointer
;
21183 /* Do not change cursor shape while dragging mouse. */
21184 if (!NILP (do_mouse_tracking
))
21187 if (!NILP (pointer
))
21189 if (EQ (pointer
, Qarrow
))
21190 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
21191 else if (EQ (pointer
, Qhand
))
21192 cursor
= FRAME_X_OUTPUT (f
)->hand_cursor
;
21193 else if (EQ (pointer
, Qtext
))
21194 cursor
= FRAME_X_OUTPUT (f
)->text_cursor
;
21195 else if (EQ (pointer
, intern ("hdrag")))
21196 cursor
= FRAME_X_OUTPUT (f
)->horizontal_drag_cursor
;
21197 #ifdef HAVE_X_WINDOWS
21198 else if (EQ (pointer
, intern ("vdrag")))
21199 cursor
= FRAME_X_DISPLAY_INFO (f
)->vertical_scroll_bar_cursor
;
21201 else if (EQ (pointer
, intern ("hourglass")))
21202 cursor
= FRAME_X_OUTPUT (f
)->hourglass_cursor
;
21203 else if (EQ (pointer
, Qmodeline
))
21204 cursor
= FRAME_X_OUTPUT (f
)->modeline_cursor
;
21206 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
21209 if (cursor
!= No_Cursor
)
21210 rif
->define_frame_cursor (f
, cursor
);
21213 /* Take proper action when mouse has moved to the mode or header line
21214 or marginal area AREA of window W, x-position X and y-position Y.
21215 X is relative to the start of the text display area of W, so the
21216 width of bitmap areas and scroll bars must be subtracted to get a
21217 position relative to the start of the mode line. */
21220 note_mode_line_or_margin_highlight (w
, x
, y
, area
)
21223 enum window_part area
;
21225 struct frame
*f
= XFRAME (w
->frame
);
21226 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
21227 Cursor cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
21228 Lisp_Object pointer
= Qnil
;
21229 int charpos
, dx
, dy
, width
, height
;
21230 Lisp_Object string
, object
= Qnil
;
21231 Lisp_Object pos
, help
;
21233 if (area
== ON_MODE_LINE
|| area
== ON_HEADER_LINE
)
21234 string
= mode_line_string (w
, area
, &x
, &y
, &charpos
,
21235 &object
, &dx
, &dy
, &width
, &height
);
21238 x
-= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w
);
21239 string
= marginal_area_string (w
, area
, &x
, &y
, &charpos
,
21240 &object
, &dx
, &dy
, &width
, &height
);
21245 if (IMAGEP (object
))
21247 Lisp_Object image_map
, hotspot
;
21248 if ((image_map
= Fsafe_plist_get (XCDR (object
), QCmap
),
21250 && (hotspot
= find_hot_spot (image_map
, dx
, dy
),
21252 && (hotspot
= XCDR (hotspot
), CONSP (hotspot
)))
21254 Lisp_Object area_id
, plist
;
21256 area_id
= XCAR (hotspot
);
21257 /* Could check AREA_ID to see if we enter/leave this hot-spot.
21258 If so, we could look for mouse-enter, mouse-leave
21259 properties in PLIST (and do something...). */
21260 hotspot
= XCDR (hotspot
);
21261 if (CONSP (hotspot
)
21262 && (plist
= XCAR (hotspot
), CONSP (plist
)))
21264 pointer
= Fsafe_plist_get (plist
, Qpointer
);
21265 if (NILP (pointer
))
21267 help
= Fsafe_plist_get (plist
, Qhelp_echo
);
21270 help_echo_string
= help
;
21271 /* Is this correct? ++kfs */
21272 XSETWINDOW (help_echo_window
, w
);
21273 help_echo_object
= w
->buffer
;
21274 help_echo_pos
= charpos
;
21278 if (NILP (pointer
))
21279 pointer
= Fsafe_plist_get (XCDR (object
), QCpointer
);
21282 if (STRINGP (string
))
21284 pos
= make_number (charpos
);
21285 /* If we're on a string with `help-echo' text property, arrange
21286 for the help to be displayed. This is done by setting the
21287 global variable help_echo_string to the help string. */
21290 help
= Fget_text_property (pos
, Qhelp_echo
, string
);
21293 help_echo_string
= help
;
21294 XSETWINDOW (help_echo_window
, w
);
21295 help_echo_object
= string
;
21296 help_echo_pos
= charpos
;
21300 if (NILP (pointer
))
21301 pointer
= Fget_text_property (pos
, Qpointer
, string
);
21303 /* Change the mouse pointer according to what is under X/Y. */
21304 if (NILP (pointer
) && ((area
== ON_MODE_LINE
) || (area
== ON_HEADER_LINE
)))
21307 map
= Fget_text_property (pos
, Qlocal_map
, string
);
21308 if (!KEYMAPP (map
))
21309 map
= Fget_text_property (pos
, Qkeymap
, string
);
21310 if (!KEYMAPP (map
))
21311 cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
21315 define_frame_cursor1 (f
, cursor
, pointer
);
21320 Take proper action when the mouse has moved to position X, Y on
21321 frame F as regards highlighting characters that have mouse-face
21322 properties. Also de-highlighting chars where the mouse was before.
21323 X and Y can be negative or out of range. */
21326 note_mouse_highlight (f
, x
, y
)
21330 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
21331 enum window_part part
;
21332 Lisp_Object window
;
21334 Cursor cursor
= No_Cursor
;
21335 Lisp_Object pointer
= Qnil
; /* Takes precedence over cursor! */
21338 /* When a menu is active, don't highlight because this looks odd. */
21339 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
21340 if (popup_activated ())
21344 if (NILP (Vmouse_highlight
)
21345 || !f
->glyphs_initialized_p
)
21348 dpyinfo
->mouse_face_mouse_x
= x
;
21349 dpyinfo
->mouse_face_mouse_y
= y
;
21350 dpyinfo
->mouse_face_mouse_frame
= f
;
21352 if (dpyinfo
->mouse_face_defer
)
21355 if (gc_in_progress
)
21357 dpyinfo
->mouse_face_deferred_gc
= 1;
21361 /* Which window is that in? */
21362 window
= window_from_coordinates (f
, x
, y
, &part
, 0, 0, 1);
21364 /* If we were displaying active text in another window, clear that.
21365 Also clear if we move out of text area in same window. */
21366 if (! EQ (window
, dpyinfo
->mouse_face_window
)
21367 || (part
!= ON_TEXT
&& !NILP (dpyinfo
->mouse_face_window
)))
21368 clear_mouse_face (dpyinfo
);
21370 /* Not on a window -> return. */
21371 if (!WINDOWP (window
))
21374 /* Reset help_echo_string. It will get recomputed below. */
21375 help_echo_string
= Qnil
;
21377 /* Convert to window-relative pixel coordinates. */
21378 w
= XWINDOW (window
);
21379 frame_to_window_pixel_xy (w
, &x
, &y
);
21381 /* Handle tool-bar window differently since it doesn't display a
21383 if (EQ (window
, f
->tool_bar_window
))
21385 note_tool_bar_highlight (f
, x
, y
);
21389 /* Mouse is on the mode, header line or margin? */
21390 if (part
== ON_MODE_LINE
|| part
== ON_HEADER_LINE
21391 || part
== ON_LEFT_MARGIN
|| part
== ON_RIGHT_MARGIN
)
21393 note_mode_line_or_margin_highlight (w
, x
, y
, part
);
21397 if (part
== ON_VERTICAL_BORDER
)
21398 cursor
= FRAME_X_OUTPUT (f
)->horizontal_drag_cursor
;
21399 else if (part
== ON_LEFT_FRINGE
|| part
== ON_RIGHT_FRINGE
21400 || part
== ON_SCROLL_BAR
)
21401 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
21403 cursor
= FRAME_X_OUTPUT (f
)->text_cursor
;
21405 /* Are we in a window whose display is up to date?
21406 And verify the buffer's text has not changed. */
21407 b
= XBUFFER (w
->buffer
);
21408 if (part
== ON_TEXT
21409 && EQ (w
->window_end_valid
, w
->buffer
)
21410 && XFASTINT (w
->last_modified
) == BUF_MODIFF (b
)
21411 && XFASTINT (w
->last_overlay_modified
) == BUF_OVERLAY_MODIFF (b
))
21413 int hpos
, vpos
, pos
, i
, dx
, dy
, area
;
21414 struct glyph
*glyph
;
21415 Lisp_Object object
;
21416 Lisp_Object mouse_face
= Qnil
, overlay
= Qnil
, position
;
21417 Lisp_Object
*overlay_vec
= NULL
;
21419 struct buffer
*obuf
;
21420 int obegv
, ozv
, same_region
;
21422 /* Find the glyph under X/Y. */
21423 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &dx
, &dy
, &area
);
21425 /* Look for :pointer property on image. */
21426 if (glyph
!= NULL
&& glyph
->type
== IMAGE_GLYPH
)
21428 struct image
*img
= IMAGE_FROM_ID (f
, glyph
->u
.img_id
);
21429 if (img
!= NULL
&& IMAGEP (img
->spec
))
21431 Lisp_Object image_map
, hotspot
;
21432 if ((image_map
= Fsafe_plist_get (XCDR (img
->spec
), QCmap
),
21434 && (hotspot
= find_hot_spot (image_map
,
21435 glyph
->slice
.x
+ dx
,
21436 glyph
->slice
.y
+ dy
),
21438 && (hotspot
= XCDR (hotspot
), CONSP (hotspot
)))
21440 Lisp_Object area_id
, plist
;
21442 area_id
= XCAR (hotspot
);
21443 /* Could check AREA_ID to see if we enter/leave this hot-spot.
21444 If so, we could look for mouse-enter, mouse-leave
21445 properties in PLIST (and do something...). */
21446 hotspot
= XCDR (hotspot
);
21447 if (CONSP (hotspot
)
21448 && (plist
= XCAR (hotspot
), CONSP (plist
)))
21450 pointer
= Fsafe_plist_get (plist
, Qpointer
);
21451 if (NILP (pointer
))
21453 help_echo_string
= Fsafe_plist_get (plist
, Qhelp_echo
);
21454 if (!NILP (help_echo_string
))
21456 help_echo_window
= window
;
21457 help_echo_object
= glyph
->object
;
21458 help_echo_pos
= glyph
->charpos
;
21462 if (NILP (pointer
))
21463 pointer
= Fsafe_plist_get (XCDR (img
->spec
), QCpointer
);
21467 /* Clear mouse face if X/Y not over text. */
21469 || area
!= TEXT_AREA
21470 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
)
21472 if (clear_mouse_face (dpyinfo
))
21473 cursor
= No_Cursor
;
21474 if (NILP (pointer
))
21476 if (area
!= TEXT_AREA
)
21477 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
21479 pointer
= Vvoid_text_area_pointer
;
21484 pos
= glyph
->charpos
;
21485 object
= glyph
->object
;
21486 if (!STRINGP (object
) && !BUFFERP (object
))
21489 /* If we get an out-of-range value, return now; avoid an error. */
21490 if (BUFFERP (object
) && pos
> BUF_Z (b
))
21493 /* Make the window's buffer temporarily current for
21494 overlays_at and compute_char_face. */
21495 obuf
= current_buffer
;
21496 current_buffer
= b
;
21502 /* Is this char mouse-active or does it have help-echo? */
21503 position
= make_number (pos
);
21505 if (BUFFERP (object
))
21507 /* Put all the overlays we want in a vector in overlay_vec. */
21508 GET_OVERLAYS_AT (pos
, overlay_vec
, noverlays
, NULL
, 0);
21509 /* Sort overlays into increasing priority order. */
21510 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
21515 same_region
= (EQ (window
, dpyinfo
->mouse_face_window
)
21516 && vpos
>= dpyinfo
->mouse_face_beg_row
21517 && vpos
<= dpyinfo
->mouse_face_end_row
21518 && (vpos
> dpyinfo
->mouse_face_beg_row
21519 || hpos
>= dpyinfo
->mouse_face_beg_col
)
21520 && (vpos
< dpyinfo
->mouse_face_end_row
21521 || hpos
< dpyinfo
->mouse_face_end_col
21522 || dpyinfo
->mouse_face_past_end
));
21525 cursor
= No_Cursor
;
21527 /* Check mouse-face highlighting. */
21529 /* If there exists an overlay with mouse-face overlapping
21530 the one we are currently highlighting, we have to
21531 check if we enter the overlapping overlay, and then
21532 highlight only that. */
21533 || (OVERLAYP (dpyinfo
->mouse_face_overlay
)
21534 && mouse_face_overlay_overlaps (dpyinfo
->mouse_face_overlay
)))
21536 /* Find the highest priority overlay that has a mouse-face
21539 for (i
= noverlays
- 1; i
>= 0 && NILP (overlay
); --i
)
21541 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
21542 if (!NILP (mouse_face
))
21543 overlay
= overlay_vec
[i
];
21546 /* If we're actually highlighting the same overlay as
21547 before, there's no need to do that again. */
21548 if (!NILP (overlay
)
21549 && EQ (overlay
, dpyinfo
->mouse_face_overlay
))
21550 goto check_help_echo
;
21552 dpyinfo
->mouse_face_overlay
= overlay
;
21554 /* Clear the display of the old active region, if any. */
21555 if (clear_mouse_face (dpyinfo
))
21556 cursor
= No_Cursor
;
21558 /* If no overlay applies, get a text property. */
21559 if (NILP (overlay
))
21560 mouse_face
= Fget_text_property (position
, Qmouse_face
, object
);
21562 /* Handle the overlay case. */
21563 if (!NILP (overlay
))
21565 /* Find the range of text around this char that
21566 should be active. */
21567 Lisp_Object before
, after
;
21570 before
= Foverlay_start (overlay
);
21571 after
= Foverlay_end (overlay
);
21572 /* Record this as the current active region. */
21573 fast_find_position (w
, XFASTINT (before
),
21574 &dpyinfo
->mouse_face_beg_col
,
21575 &dpyinfo
->mouse_face_beg_row
,
21576 &dpyinfo
->mouse_face_beg_x
,
21577 &dpyinfo
->mouse_face_beg_y
, Qnil
);
21579 dpyinfo
->mouse_face_past_end
21580 = !fast_find_position (w
, XFASTINT (after
),
21581 &dpyinfo
->mouse_face_end_col
,
21582 &dpyinfo
->mouse_face_end_row
,
21583 &dpyinfo
->mouse_face_end_x
,
21584 &dpyinfo
->mouse_face_end_y
, Qnil
);
21585 dpyinfo
->mouse_face_window
= window
;
21587 dpyinfo
->mouse_face_face_id
21588 = face_at_buffer_position (w
, pos
, 0, 0,
21590 !dpyinfo
->mouse_face_hidden
);
21592 /* Display it as active. */
21593 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
21594 cursor
= No_Cursor
;
21596 /* Handle the text property case. */
21597 else if (!NILP (mouse_face
) && BUFFERP (object
))
21599 /* Find the range of text around this char that
21600 should be active. */
21601 Lisp_Object before
, after
, beginning
, end
;
21604 beginning
= Fmarker_position (w
->start
);
21605 end
= make_number (BUF_Z (XBUFFER (object
))
21606 - XFASTINT (w
->window_end_pos
));
21608 = Fprevious_single_property_change (make_number (pos
+ 1),
21610 object
, beginning
);
21612 = Fnext_single_property_change (position
, Qmouse_face
,
21615 /* Record this as the current active region. */
21616 fast_find_position (w
, XFASTINT (before
),
21617 &dpyinfo
->mouse_face_beg_col
,
21618 &dpyinfo
->mouse_face_beg_row
,
21619 &dpyinfo
->mouse_face_beg_x
,
21620 &dpyinfo
->mouse_face_beg_y
, Qnil
);
21621 dpyinfo
->mouse_face_past_end
21622 = !fast_find_position (w
, XFASTINT (after
),
21623 &dpyinfo
->mouse_face_end_col
,
21624 &dpyinfo
->mouse_face_end_row
,
21625 &dpyinfo
->mouse_face_end_x
,
21626 &dpyinfo
->mouse_face_end_y
, Qnil
);
21627 dpyinfo
->mouse_face_window
= window
;
21629 if (BUFFERP (object
))
21630 dpyinfo
->mouse_face_face_id
21631 = face_at_buffer_position (w
, pos
, 0, 0,
21633 !dpyinfo
->mouse_face_hidden
);
21635 /* Display it as active. */
21636 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
21637 cursor
= No_Cursor
;
21639 else if (!NILP (mouse_face
) && STRINGP (object
))
21644 b
= Fprevious_single_property_change (make_number (pos
+ 1),
21647 e
= Fnext_single_property_change (position
, Qmouse_face
,
21650 b
= make_number (0);
21652 e
= make_number (SCHARS (object
) - 1);
21653 fast_find_string_pos (w
, XINT (b
), object
,
21654 &dpyinfo
->mouse_face_beg_col
,
21655 &dpyinfo
->mouse_face_beg_row
,
21656 &dpyinfo
->mouse_face_beg_x
,
21657 &dpyinfo
->mouse_face_beg_y
, 0);
21658 fast_find_string_pos (w
, XINT (e
), object
,
21659 &dpyinfo
->mouse_face_end_col
,
21660 &dpyinfo
->mouse_face_end_row
,
21661 &dpyinfo
->mouse_face_end_x
,
21662 &dpyinfo
->mouse_face_end_y
, 1);
21663 dpyinfo
->mouse_face_past_end
= 0;
21664 dpyinfo
->mouse_face_window
= window
;
21665 dpyinfo
->mouse_face_face_id
21666 = face_at_string_position (w
, object
, pos
, 0, 0, 0, &ignore
,
21667 glyph
->face_id
, 1);
21668 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
21669 cursor
= No_Cursor
;
21671 else if (STRINGP (object
) && NILP (mouse_face
))
21673 /* A string which doesn't have mouse-face, but
21674 the text ``under'' it might have. */
21675 struct glyph_row
*r
= MATRIX_ROW (w
->current_matrix
, vpos
);
21676 int start
= MATRIX_ROW_START_CHARPOS (r
);
21678 pos
= string_buffer_position (w
, object
, start
);
21680 mouse_face
= get_char_property_and_overlay (make_number (pos
),
21684 if (!NILP (mouse_face
) && !NILP (overlay
))
21686 Lisp_Object before
= Foverlay_start (overlay
);
21687 Lisp_Object after
= Foverlay_end (overlay
);
21690 /* Note that we might not be able to find position
21691 BEFORE in the glyph matrix if the overlay is
21692 entirely covered by a `display' property. In
21693 this case, we overshoot. So let's stop in
21694 the glyph matrix before glyphs for OBJECT. */
21695 fast_find_position (w
, XFASTINT (before
),
21696 &dpyinfo
->mouse_face_beg_col
,
21697 &dpyinfo
->mouse_face_beg_row
,
21698 &dpyinfo
->mouse_face_beg_x
,
21699 &dpyinfo
->mouse_face_beg_y
,
21702 dpyinfo
->mouse_face_past_end
21703 = !fast_find_position (w
, XFASTINT (after
),
21704 &dpyinfo
->mouse_face_end_col
,
21705 &dpyinfo
->mouse_face_end_row
,
21706 &dpyinfo
->mouse_face_end_x
,
21707 &dpyinfo
->mouse_face_end_y
,
21709 dpyinfo
->mouse_face_window
= window
;
21710 dpyinfo
->mouse_face_face_id
21711 = face_at_buffer_position (w
, pos
, 0, 0,
21713 !dpyinfo
->mouse_face_hidden
);
21715 /* Display it as active. */
21716 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
21717 cursor
= No_Cursor
;
21724 /* Look for a `help-echo' property. */
21725 if (NILP (help_echo_string
)) {
21726 Lisp_Object help
, overlay
;
21728 /* Check overlays first. */
21729 help
= overlay
= Qnil
;
21730 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
21732 overlay
= overlay_vec
[i
];
21733 help
= Foverlay_get (overlay
, Qhelp_echo
);
21738 help_echo_string
= help
;
21739 help_echo_window
= window
;
21740 help_echo_object
= overlay
;
21741 help_echo_pos
= pos
;
21745 Lisp_Object object
= glyph
->object
;
21746 int charpos
= glyph
->charpos
;
21748 /* Try text properties. */
21749 if (STRINGP (object
)
21751 && charpos
< SCHARS (object
))
21753 help
= Fget_text_property (make_number (charpos
),
21754 Qhelp_echo
, object
);
21757 /* If the string itself doesn't specify a help-echo,
21758 see if the buffer text ``under'' it does. */
21759 struct glyph_row
*r
21760 = MATRIX_ROW (w
->current_matrix
, vpos
);
21761 int start
= MATRIX_ROW_START_CHARPOS (r
);
21762 int pos
= string_buffer_position (w
, object
, start
);
21765 help
= Fget_char_property (make_number (pos
),
21766 Qhelp_echo
, w
->buffer
);
21770 object
= w
->buffer
;
21775 else if (BUFFERP (object
)
21778 help
= Fget_text_property (make_number (charpos
), Qhelp_echo
,
21783 help_echo_string
= help
;
21784 help_echo_window
= window
;
21785 help_echo_object
= object
;
21786 help_echo_pos
= charpos
;
21791 /* Look for a `pointer' property. */
21792 if (NILP (pointer
))
21794 /* Check overlays first. */
21795 for (i
= noverlays
- 1; i
>= 0 && NILP (pointer
); --i
)
21796 pointer
= Foverlay_get (overlay_vec
[i
], Qpointer
);
21798 if (NILP (pointer
))
21800 Lisp_Object object
= glyph
->object
;
21801 int charpos
= glyph
->charpos
;
21803 /* Try text properties. */
21804 if (STRINGP (object
)
21806 && charpos
< SCHARS (object
))
21808 pointer
= Fget_text_property (make_number (charpos
),
21810 if (NILP (pointer
))
21812 /* If the string itself doesn't specify a pointer,
21813 see if the buffer text ``under'' it does. */
21814 struct glyph_row
*r
21815 = MATRIX_ROW (w
->current_matrix
, vpos
);
21816 int start
= MATRIX_ROW_START_CHARPOS (r
);
21817 int pos
= string_buffer_position (w
, object
, start
);
21819 pointer
= Fget_char_property (make_number (pos
),
21820 Qpointer
, w
->buffer
);
21823 else if (BUFFERP (object
)
21826 pointer
= Fget_text_property (make_number (charpos
),
21833 current_buffer
= obuf
;
21838 define_frame_cursor1 (f
, cursor
, pointer
);
21843 Clear any mouse-face on window W. This function is part of the
21844 redisplay interface, and is called from try_window_id and similar
21845 functions to ensure the mouse-highlight is off. */
21848 x_clear_window_mouse_face (w
)
21851 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (XFRAME (w
->frame
));
21852 Lisp_Object window
;
21855 XSETWINDOW (window
, w
);
21856 if (EQ (window
, dpyinfo
->mouse_face_window
))
21857 clear_mouse_face (dpyinfo
);
21863 Just discard the mouse face information for frame F, if any.
21864 This is used when the size of F is changed. */
21867 cancel_mouse_face (f
)
21870 Lisp_Object window
;
21871 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
21873 window
= dpyinfo
->mouse_face_window
;
21874 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
21876 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
21877 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
21878 dpyinfo
->mouse_face_window
= Qnil
;
21883 #endif /* HAVE_WINDOW_SYSTEM */
21886 /***********************************************************************
21888 ***********************************************************************/
21890 #ifdef HAVE_WINDOW_SYSTEM
21892 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
21893 which intersects rectangle R. R is in window-relative coordinates. */
21896 expose_area (w
, row
, r
, area
)
21898 struct glyph_row
*row
;
21900 enum glyph_row_area area
;
21902 struct glyph
*first
= row
->glyphs
[area
];
21903 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
21904 struct glyph
*last
;
21905 int first_x
, start_x
, x
;
21907 if (area
== TEXT_AREA
&& row
->fill_line_p
)
21908 /* If row extends face to end of line write the whole line. */
21909 draw_glyphs (w
, 0, row
, area
,
21910 0, row
->used
[area
],
21911 DRAW_NORMAL_TEXT
, 0);
21914 /* Set START_X to the window-relative start position for drawing glyphs of
21915 AREA. The first glyph of the text area can be partially visible.
21916 The first glyphs of other areas cannot. */
21917 start_x
= window_box_left_offset (w
, area
);
21919 if (area
== TEXT_AREA
)
21922 /* Find the first glyph that must be redrawn. */
21924 && x
+ first
->pixel_width
< r
->x
)
21926 x
+= first
->pixel_width
;
21930 /* Find the last one. */
21934 && x
< r
->x
+ r
->width
)
21936 x
+= last
->pixel_width
;
21942 draw_glyphs (w
, first_x
- start_x
, row
, area
,
21943 first
- row
->glyphs
[area
], last
- row
->glyphs
[area
],
21944 DRAW_NORMAL_TEXT
, 0);
21949 /* Redraw the parts of the glyph row ROW on window W intersecting
21950 rectangle R. R is in window-relative coordinates. Value is
21951 non-zero if mouse-face was overwritten. */
21954 expose_line (w
, row
, r
)
21956 struct glyph_row
*row
;
21959 xassert (row
->enabled_p
);
21961 if (row
->mode_line_p
|| w
->pseudo_window_p
)
21962 draw_glyphs (w
, 0, row
, TEXT_AREA
,
21963 0, row
->used
[TEXT_AREA
],
21964 DRAW_NORMAL_TEXT
, 0);
21967 if (row
->used
[LEFT_MARGIN_AREA
])
21968 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
21969 if (row
->used
[TEXT_AREA
])
21970 expose_area (w
, row
, r
, TEXT_AREA
);
21971 if (row
->used
[RIGHT_MARGIN_AREA
])
21972 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
21973 draw_row_fringe_bitmaps (w
, row
);
21976 return row
->mouse_face_p
;
21980 /* Redraw those parts of glyphs rows during expose event handling that
21981 overlap other rows. Redrawing of an exposed line writes over parts
21982 of lines overlapping that exposed line; this function fixes that.
21984 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
21985 row in W's current matrix that is exposed and overlaps other rows.
21986 LAST_OVERLAPPING_ROW is the last such row. */
21989 expose_overlaps (w
, first_overlapping_row
, last_overlapping_row
)
21991 struct glyph_row
*first_overlapping_row
;
21992 struct glyph_row
*last_overlapping_row
;
21994 struct glyph_row
*row
;
21996 for (row
= first_overlapping_row
; row
<= last_overlapping_row
; ++row
)
21997 if (row
->overlapping_p
)
21999 xassert (row
->enabled_p
&& !row
->mode_line_p
);
22001 if (row
->used
[LEFT_MARGIN_AREA
])
22002 x_fix_overlapping_area (w
, row
, LEFT_MARGIN_AREA
);
22004 if (row
->used
[TEXT_AREA
])
22005 x_fix_overlapping_area (w
, row
, TEXT_AREA
);
22007 if (row
->used
[RIGHT_MARGIN_AREA
])
22008 x_fix_overlapping_area (w
, row
, RIGHT_MARGIN_AREA
);
22013 /* Return non-zero if W's cursor intersects rectangle R. */
22016 phys_cursor_in_rect_p (w
, r
)
22020 XRectangle cr
, result
;
22021 struct glyph
*cursor_glyph
;
22023 cursor_glyph
= get_phys_cursor_glyph (w
);
22026 /* r is relative to W's box, but w->phys_cursor.x is relative
22027 to left edge of W's TEXT area. Adjust it. */
22028 cr
.x
= window_box_left_offset (w
, TEXT_AREA
) + w
->phys_cursor
.x
;
22029 cr
.y
= w
->phys_cursor
.y
;
22030 cr
.width
= cursor_glyph
->pixel_width
;
22031 cr
.height
= w
->phys_cursor_height
;
22032 /* ++KFS: W32 version used W32-specific IntersectRect here, but
22033 I assume the effect is the same -- and this is portable. */
22034 return x_intersect_rectangles (&cr
, r
, &result
);
22042 Draw a vertical window border to the right of window W if W doesn't
22043 have vertical scroll bars. */
22046 x_draw_vertical_border (w
)
22049 /* We could do better, if we knew what type of scroll-bar the adjacent
22050 windows (on either side) have... But we don't :-(
22051 However, I think this works ok. ++KFS 2003-04-25 */
22053 /* Redraw borders between horizontally adjacent windows. Don't
22054 do it for frames with vertical scroll bars because either the
22055 right scroll bar of a window, or the left scroll bar of its
22056 neighbor will suffice as a border. */
22057 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w
->frame
)))
22060 if (!WINDOW_RIGHTMOST_P (w
)
22061 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w
))
22063 int x0
, x1
, y0
, y1
;
22065 window_box_edges (w
, -1, &x0
, &y0
, &x1
, &y1
);
22068 rif
->draw_vertical_window_border (w
, x1
, y0
, y1
);
22070 else if (!WINDOW_LEFTMOST_P (w
)
22071 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w
))
22073 int x0
, x1
, y0
, y1
;
22075 window_box_edges (w
, -1, &x0
, &y0
, &x1
, &y1
);
22078 rif
->draw_vertical_window_border (w
, x0
, y0
, y1
);
22083 /* Redraw the part of window W intersection rectangle FR. Pixel
22084 coordinates in FR are frame-relative. Call this function with
22085 input blocked. Value is non-zero if the exposure overwrites
22089 expose_window (w
, fr
)
22093 struct frame
*f
= XFRAME (w
->frame
);
22095 int mouse_face_overwritten_p
= 0;
22097 /* If window is not yet fully initialized, do nothing. This can
22098 happen when toolkit scroll bars are used and a window is split.
22099 Reconfiguring the scroll bar will generate an expose for a newly
22101 if (w
->current_matrix
== NULL
)
22104 /* When we're currently updating the window, display and current
22105 matrix usually don't agree. Arrange for a thorough display
22107 if (w
== updated_window
)
22109 SET_FRAME_GARBAGED (f
);
22113 /* Frame-relative pixel rectangle of W. */
22114 wr
.x
= WINDOW_LEFT_EDGE_X (w
);
22115 wr
.y
= WINDOW_TOP_EDGE_Y (w
);
22116 wr
.width
= WINDOW_TOTAL_WIDTH (w
);
22117 wr
.height
= WINDOW_TOTAL_HEIGHT (w
);
22119 if (x_intersect_rectangles (fr
, &wr
, &r
))
22121 int yb
= window_text_bottom_y (w
);
22122 struct glyph_row
*row
;
22123 int cursor_cleared_p
;
22124 struct glyph_row
*first_overlapping_row
, *last_overlapping_row
;
22126 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
22127 r
.x
, r
.y
, r
.width
, r
.height
));
22129 /* Convert to window coordinates. */
22130 r
.x
-= WINDOW_LEFT_EDGE_X (w
);
22131 r
.y
-= WINDOW_TOP_EDGE_Y (w
);
22133 /* Turn off the cursor. */
22134 if (!w
->pseudo_window_p
22135 && phys_cursor_in_rect_p (w
, &r
))
22137 x_clear_cursor (w
);
22138 cursor_cleared_p
= 1;
22141 cursor_cleared_p
= 0;
22143 /* Update lines intersecting rectangle R. */
22144 first_overlapping_row
= last_overlapping_row
= NULL
;
22145 for (row
= w
->current_matrix
->rows
;
22150 int y1
= MATRIX_ROW_BOTTOM_Y (row
);
22152 if ((y0
>= r
.y
&& y0
< r
.y
+ r
.height
)
22153 || (y1
> r
.y
&& y1
< r
.y
+ r
.height
)
22154 || (r
.y
>= y0
&& r
.y
< y1
)
22155 || (r
.y
+ r
.height
> y0
&& r
.y
+ r
.height
< y1
))
22157 /* A header line may be overlapping, but there is no need
22158 to fix overlapping areas for them. KFS 2005-02-12 */
22159 if (row
->overlapping_p
&& !row
->mode_line_p
)
22161 if (first_overlapping_row
== NULL
)
22162 first_overlapping_row
= row
;
22163 last_overlapping_row
= row
;
22166 if (expose_line (w
, row
, &r
))
22167 mouse_face_overwritten_p
= 1;
22174 /* Display the mode line if there is one. */
22175 if (WINDOW_WANTS_MODELINE_P (w
)
22176 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
22178 && row
->y
< r
.y
+ r
.height
)
22180 if (expose_line (w
, row
, &r
))
22181 mouse_face_overwritten_p
= 1;
22184 if (!w
->pseudo_window_p
)
22186 /* Fix the display of overlapping rows. */
22187 if (first_overlapping_row
)
22188 expose_overlaps (w
, first_overlapping_row
, last_overlapping_row
);
22190 /* Draw border between windows. */
22191 x_draw_vertical_border (w
);
22193 /* Turn the cursor on again. */
22194 if (cursor_cleared_p
)
22195 update_window_cursor (w
, 1);
22199 return mouse_face_overwritten_p
;
22204 /* Redraw (parts) of all windows in the window tree rooted at W that
22205 intersect R. R contains frame pixel coordinates. Value is
22206 non-zero if the exposure overwrites mouse-face. */
22209 expose_window_tree (w
, r
)
22213 struct frame
*f
= XFRAME (w
->frame
);
22214 int mouse_face_overwritten_p
= 0;
22216 while (w
&& !FRAME_GARBAGED_P (f
))
22218 if (!NILP (w
->hchild
))
22219 mouse_face_overwritten_p
22220 |= expose_window_tree (XWINDOW (w
->hchild
), r
);
22221 else if (!NILP (w
->vchild
))
22222 mouse_face_overwritten_p
22223 |= expose_window_tree (XWINDOW (w
->vchild
), r
);
22225 mouse_face_overwritten_p
|= expose_window (w
, r
);
22227 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
22230 return mouse_face_overwritten_p
;
22235 Redisplay an exposed area of frame F. X and Y are the upper-left
22236 corner of the exposed rectangle. W and H are width and height of
22237 the exposed area. All are pixel values. W or H zero means redraw
22238 the entire frame. */
22241 expose_frame (f
, x
, y
, w
, h
)
22246 int mouse_face_overwritten_p
= 0;
22248 TRACE ((stderr
, "expose_frame "));
22250 /* No need to redraw if frame will be redrawn soon. */
22251 if (FRAME_GARBAGED_P (f
))
22253 TRACE ((stderr
, " garbaged\n"));
22257 /* If basic faces haven't been realized yet, there is no point in
22258 trying to redraw anything. This can happen when we get an expose
22259 event while Emacs is starting, e.g. by moving another window. */
22260 if (FRAME_FACE_CACHE (f
) == NULL
22261 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
22263 TRACE ((stderr
, " no faces\n"));
22267 if (w
== 0 || h
== 0)
22270 r
.width
= FRAME_COLUMN_WIDTH (f
) * FRAME_COLS (f
);
22271 r
.height
= FRAME_LINE_HEIGHT (f
) * FRAME_LINES (f
);
22281 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.x
, r
.y
, r
.width
, r
.height
));
22282 mouse_face_overwritten_p
= expose_window_tree (XWINDOW (f
->root_window
), &r
);
22284 if (WINDOWP (f
->tool_bar_window
))
22285 mouse_face_overwritten_p
22286 |= expose_window (XWINDOW (f
->tool_bar_window
), &r
);
22288 #ifdef HAVE_X_WINDOWS
22290 #ifndef USE_X_TOOLKIT
22291 if (WINDOWP (f
->menu_bar_window
))
22292 mouse_face_overwritten_p
22293 |= expose_window (XWINDOW (f
->menu_bar_window
), &r
);
22294 #endif /* not USE_X_TOOLKIT */
22298 /* Some window managers support a focus-follows-mouse style with
22299 delayed raising of frames. Imagine a partially obscured frame,
22300 and moving the mouse into partially obscured mouse-face on that
22301 frame. The visible part of the mouse-face will be highlighted,
22302 then the WM raises the obscured frame. With at least one WM, KDE
22303 2.1, Emacs is not getting any event for the raising of the frame
22304 (even tried with SubstructureRedirectMask), only Expose events.
22305 These expose events will draw text normally, i.e. not
22306 highlighted. Which means we must redo the highlight here.
22307 Subsume it under ``we love X''. --gerd 2001-08-15 */
22308 /* Included in Windows version because Windows most likely does not
22309 do the right thing if any third party tool offers
22310 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
22311 if (mouse_face_overwritten_p
&& !FRAME_GARBAGED_P (f
))
22313 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
22314 if (f
== dpyinfo
->mouse_face_mouse_frame
)
22316 int x
= dpyinfo
->mouse_face_mouse_x
;
22317 int y
= dpyinfo
->mouse_face_mouse_y
;
22318 clear_mouse_face (dpyinfo
);
22319 note_mouse_highlight (f
, x
, y
);
22326 Determine the intersection of two rectangles R1 and R2. Return
22327 the intersection in *RESULT. Value is non-zero if RESULT is not
22331 x_intersect_rectangles (r1
, r2
, result
)
22332 XRectangle
*r1
, *r2
, *result
;
22334 XRectangle
*left
, *right
;
22335 XRectangle
*upper
, *lower
;
22336 int intersection_p
= 0;
22338 /* Rearrange so that R1 is the left-most rectangle. */
22340 left
= r1
, right
= r2
;
22342 left
= r2
, right
= r1
;
22344 /* X0 of the intersection is right.x0, if this is inside R1,
22345 otherwise there is no intersection. */
22346 if (right
->x
<= left
->x
+ left
->width
)
22348 result
->x
= right
->x
;
22350 /* The right end of the intersection is the minimum of the
22351 the right ends of left and right. */
22352 result
->width
= (min (left
->x
+ left
->width
, right
->x
+ right
->width
)
22355 /* Same game for Y. */
22357 upper
= r1
, lower
= r2
;
22359 upper
= r2
, lower
= r1
;
22361 /* The upper end of the intersection is lower.y0, if this is inside
22362 of upper. Otherwise, there is no intersection. */
22363 if (lower
->y
<= upper
->y
+ upper
->height
)
22365 result
->y
= lower
->y
;
22367 /* The lower end of the intersection is the minimum of the lower
22368 ends of upper and lower. */
22369 result
->height
= (min (lower
->y
+ lower
->height
,
22370 upper
->y
+ upper
->height
)
22372 intersection_p
= 1;
22376 return intersection_p
;
22379 #endif /* HAVE_WINDOW_SYSTEM */
22382 /***********************************************************************
22384 ***********************************************************************/
22389 Vwith_echo_area_save_vector
= Qnil
;
22390 staticpro (&Vwith_echo_area_save_vector
);
22392 Vmessage_stack
= Qnil
;
22393 staticpro (&Vmessage_stack
);
22395 Qinhibit_redisplay
= intern ("inhibit-redisplay");
22396 staticpro (&Qinhibit_redisplay
);
22398 message_dolog_marker1
= Fmake_marker ();
22399 staticpro (&message_dolog_marker1
);
22400 message_dolog_marker2
= Fmake_marker ();
22401 staticpro (&message_dolog_marker2
);
22402 message_dolog_marker3
= Fmake_marker ();
22403 staticpro (&message_dolog_marker3
);
22406 defsubr (&Sdump_frame_glyph_matrix
);
22407 defsubr (&Sdump_glyph_matrix
);
22408 defsubr (&Sdump_glyph_row
);
22409 defsubr (&Sdump_tool_bar_row
);
22410 defsubr (&Strace_redisplay
);
22411 defsubr (&Strace_to_stderr
);
22413 #ifdef HAVE_WINDOW_SYSTEM
22414 defsubr (&Stool_bar_lines_needed
);
22415 defsubr (&Slookup_image_map
);
22417 defsubr (&Sformat_mode_line
);
22419 staticpro (&Qmenu_bar_update_hook
);
22420 Qmenu_bar_update_hook
= intern ("menu-bar-update-hook");
22422 staticpro (&Qoverriding_terminal_local_map
);
22423 Qoverriding_terminal_local_map
= intern ("overriding-terminal-local-map");
22425 staticpro (&Qoverriding_local_map
);
22426 Qoverriding_local_map
= intern ("overriding-local-map");
22428 staticpro (&Qwindow_scroll_functions
);
22429 Qwindow_scroll_functions
= intern ("window-scroll-functions");
22431 staticpro (&Qredisplay_end_trigger_functions
);
22432 Qredisplay_end_trigger_functions
= intern ("redisplay-end-trigger-functions");
22434 staticpro (&Qinhibit_point_motion_hooks
);
22435 Qinhibit_point_motion_hooks
= intern ("inhibit-point-motion-hooks");
22437 QCdata
= intern (":data");
22438 staticpro (&QCdata
);
22439 Qdisplay
= intern ("display");
22440 staticpro (&Qdisplay
);
22441 Qspace_width
= intern ("space-width");
22442 staticpro (&Qspace_width
);
22443 Qraise
= intern ("raise");
22444 staticpro (&Qraise
);
22445 Qslice
= intern ("slice");
22446 staticpro (&Qslice
);
22447 Qspace
= intern ("space");
22448 staticpro (&Qspace
);
22449 Qmargin
= intern ("margin");
22450 staticpro (&Qmargin
);
22451 Qpointer
= intern ("pointer");
22452 staticpro (&Qpointer
);
22453 Qleft_margin
= intern ("left-margin");
22454 staticpro (&Qleft_margin
);
22455 Qright_margin
= intern ("right-margin");
22456 staticpro (&Qright_margin
);
22457 Qcenter
= intern ("center");
22458 staticpro (&Qcenter
);
22459 Qline_height
= intern ("line-height");
22460 staticpro (&Qline_height
);
22461 QCalign_to
= intern (":align-to");
22462 staticpro (&QCalign_to
);
22463 QCrelative_width
= intern (":relative-width");
22464 staticpro (&QCrelative_width
);
22465 QCrelative_height
= intern (":relative-height");
22466 staticpro (&QCrelative_height
);
22467 QCeval
= intern (":eval");
22468 staticpro (&QCeval
);
22469 QCpropertize
= intern (":propertize");
22470 staticpro (&QCpropertize
);
22471 QCfile
= intern (":file");
22472 staticpro (&QCfile
);
22473 Qfontified
= intern ("fontified");
22474 staticpro (&Qfontified
);
22475 Qfontification_functions
= intern ("fontification-functions");
22476 staticpro (&Qfontification_functions
);
22477 Qtrailing_whitespace
= intern ("trailing-whitespace");
22478 staticpro (&Qtrailing_whitespace
);
22479 Qescape_glyph
= intern ("escape-glyph");
22480 staticpro (&Qescape_glyph
);
22481 Qimage
= intern ("image");
22482 staticpro (&Qimage
);
22483 QCmap
= intern (":map");
22484 staticpro (&QCmap
);
22485 QCpointer
= intern (":pointer");
22486 staticpro (&QCpointer
);
22487 Qrect
= intern ("rect");
22488 staticpro (&Qrect
);
22489 Qcircle
= intern ("circle");
22490 staticpro (&Qcircle
);
22491 Qpoly
= intern ("poly");
22492 staticpro (&Qpoly
);
22493 Qmessage_truncate_lines
= intern ("message-truncate-lines");
22494 staticpro (&Qmessage_truncate_lines
);
22495 Qcursor_in_non_selected_windows
= intern ("cursor-in-non-selected-windows");
22496 staticpro (&Qcursor_in_non_selected_windows
);
22497 Qgrow_only
= intern ("grow-only");
22498 staticpro (&Qgrow_only
);
22499 Qinhibit_menubar_update
= intern ("inhibit-menubar-update");
22500 staticpro (&Qinhibit_menubar_update
);
22501 Qinhibit_eval_during_redisplay
= intern ("inhibit-eval-during-redisplay");
22502 staticpro (&Qinhibit_eval_during_redisplay
);
22503 Qposition
= intern ("position");
22504 staticpro (&Qposition
);
22505 Qbuffer_position
= intern ("buffer-position");
22506 staticpro (&Qbuffer_position
);
22507 Qobject
= intern ("object");
22508 staticpro (&Qobject
);
22509 Qbar
= intern ("bar");
22511 Qhbar
= intern ("hbar");
22512 staticpro (&Qhbar
);
22513 Qbox
= intern ("box");
22515 Qhollow
= intern ("hollow");
22516 staticpro (&Qhollow
);
22517 Qhand
= intern ("hand");
22518 staticpro (&Qhand
);
22519 Qarrow
= intern ("arrow");
22520 staticpro (&Qarrow
);
22521 Qtext
= intern ("text");
22522 staticpro (&Qtext
);
22523 Qrisky_local_variable
= intern ("risky-local-variable");
22524 staticpro (&Qrisky_local_variable
);
22525 Qinhibit_free_realized_faces
= intern ("inhibit-free-realized-faces");
22526 staticpro (&Qinhibit_free_realized_faces
);
22528 list_of_error
= Fcons (Fcons (intern ("error"),
22529 Fcons (intern ("void-variable"), Qnil
)),
22531 staticpro (&list_of_error
);
22533 Qlast_arrow_position
= intern ("last-arrow-position");
22534 staticpro (&Qlast_arrow_position
);
22535 Qlast_arrow_string
= intern ("last-arrow-string");
22536 staticpro (&Qlast_arrow_string
);
22538 Qoverlay_arrow_string
= intern ("overlay-arrow-string");
22539 staticpro (&Qoverlay_arrow_string
);
22540 Qoverlay_arrow_bitmap
= intern ("overlay-arrow-bitmap");
22541 staticpro (&Qoverlay_arrow_bitmap
);
22543 echo_buffer
[0] = echo_buffer
[1] = Qnil
;
22544 staticpro (&echo_buffer
[0]);
22545 staticpro (&echo_buffer
[1]);
22547 echo_area_buffer
[0] = echo_area_buffer
[1] = Qnil
;
22548 staticpro (&echo_area_buffer
[0]);
22549 staticpro (&echo_area_buffer
[1]);
22551 Vmessages_buffer_name
= build_string ("*Messages*");
22552 staticpro (&Vmessages_buffer_name
);
22554 mode_line_proptrans_alist
= Qnil
;
22555 staticpro (&mode_line_proptrans_alist
);
22557 mode_line_string_list
= Qnil
;
22558 staticpro (&mode_line_string_list
);
22560 help_echo_string
= Qnil
;
22561 staticpro (&help_echo_string
);
22562 help_echo_object
= Qnil
;
22563 staticpro (&help_echo_object
);
22564 help_echo_window
= Qnil
;
22565 staticpro (&help_echo_window
);
22566 previous_help_echo_string
= Qnil
;
22567 staticpro (&previous_help_echo_string
);
22568 help_echo_pos
= -1;
22570 #ifdef HAVE_WINDOW_SYSTEM
22571 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
22572 doc
: /* *Non-nil means draw block cursor as wide as the glyph under it.
22573 For example, if a block cursor is over a tab, it will be drawn as
22574 wide as that tab on the display. */);
22575 x_stretch_cursor_p
= 0;
22578 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace
,
22579 doc
: /* *Non-nil means highlight trailing whitespace.
22580 The face used for trailing whitespace is `trailing-whitespace'. */);
22581 Vshow_trailing_whitespace
= Qnil
;
22583 DEFVAR_LISP ("show-nonbreak-escape", &Vshow_nonbreak_escape
,
22584 doc
: /* *Non-nil means display escape character before non-break space and hyphen. */);
22585 Vshow_nonbreak_escape
= Qt
;
22587 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer
,
22588 doc
: /* *The pointer shape to show in void text areas.
22589 Nil means to show the text pointer. Other options are `arrow', `text',
22590 `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
22591 Vvoid_text_area_pointer
= Qarrow
;
22593 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay
,
22594 doc
: /* Non-nil means don't actually do any redisplay.
22595 This is used for internal purposes. */);
22596 Vinhibit_redisplay
= Qnil
;
22598 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string
,
22599 doc
: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
22600 Vglobal_mode_string
= Qnil
;
22602 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position
,
22603 doc
: /* Marker for where to display an arrow on top of the buffer text.
22604 This must be the beginning of a line in order to work.
22605 See also `overlay-arrow-string'. */);
22606 Voverlay_arrow_position
= Qnil
;
22608 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string
,
22609 doc
: /* String to display as an arrow in non-window frames.
22610 See also `overlay-arrow-position'. */);
22611 Voverlay_arrow_string
= Qnil
;
22613 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list
,
22614 doc
: /* List of variables (symbols) which hold markers for overlay arrows.
22615 The symbols on this list are examined during redisplay to determine
22616 where to display overlay arrows. */);
22617 Voverlay_arrow_variable_list
22618 = Fcons (intern ("overlay-arrow-position"), Qnil
);
22620 DEFVAR_INT ("scroll-step", &scroll_step
,
22621 doc
: /* *The number of lines to try scrolling a window by when point moves out.
22622 If that fails to bring point back on frame, point is centered instead.
22623 If this is zero, point is always centered after it moves off frame.
22624 If you want scrolling to always be a line at a time, you should set
22625 `scroll-conservatively' to a large value rather than set this to 1. */);
22627 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively
,
22628 doc
: /* *Scroll up to this many lines, to bring point back on screen.
22629 A value of zero means to scroll the text to center point vertically
22630 in the window. */);
22631 scroll_conservatively
= 0;
22633 DEFVAR_INT ("scroll-margin", &scroll_margin
,
22634 doc
: /* *Number of lines of margin at the top and bottom of a window.
22635 Recenter the window whenever point gets within this many lines
22636 of the top or bottom of the window. */);
22639 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch
,
22640 doc
: /* Pixels per inch on current display.
22641 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
22642 Vdisplay_pixels_per_inch
= make_float (72.0);
22645 DEFVAR_INT ("debug-end-pos", &debug_end_pos
, doc
: /* Don't ask. */);
22648 DEFVAR_BOOL ("truncate-partial-width-windows",
22649 &truncate_partial_width_windows
,
22650 doc
: /* *Non-nil means truncate lines in all windows less than full frame wide. */);
22651 truncate_partial_width_windows
= 1;
22653 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video
,
22654 doc
: /* nil means display the mode-line/header-line/menu-bar in the default face.
22655 Any other value means to use the appropriate face, `mode-line',
22656 `header-line', or `menu' respectively. */);
22657 mode_line_inverse_video
= 1;
22659 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit
,
22660 doc
: /* *Maximum buffer size for which line number should be displayed.
22661 If the buffer is bigger than this, the line number does not appear
22662 in the mode line. A value of nil means no limit. */);
22663 Vline_number_display_limit
= Qnil
;
22665 DEFVAR_INT ("line-number-display-limit-width",
22666 &line_number_display_limit_width
,
22667 doc
: /* *Maximum line width (in characters) for line number display.
22668 If the average length of the lines near point is bigger than this, then the
22669 line number may be omitted from the mode line. */);
22670 line_number_display_limit_width
= 200;
22672 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows
,
22673 doc
: /* *Non-nil means highlight region even in nonselected windows. */);
22674 highlight_nonselected_windows
= 0;
22676 DEFVAR_BOOL ("multiple-frames", &multiple_frames
,
22677 doc
: /* Non-nil if more than one frame is visible on this display.
22678 Minibuffer-only frames don't count, but iconified frames do.
22679 This variable is not guaranteed to be accurate except while processing
22680 `frame-title-format' and `icon-title-format'. */);
22682 DEFVAR_LISP ("frame-title-format", &Vframe_title_format
,
22683 doc
: /* Template for displaying the title bar of visible frames.
22684 \(Assuming the window manager supports this feature.)
22685 This variable has the same structure as `mode-line-format' (which see),
22686 and is used only on frames for which no explicit name has been set
22687 \(see `modify-frame-parameters'). */);
22689 DEFVAR_LISP ("icon-title-format", &Vicon_title_format
,
22690 doc
: /* Template for displaying the title bar of an iconified frame.
22691 \(Assuming the window manager supports this feature.)
22692 This variable has the same structure as `mode-line-format' (which see),
22693 and is used only on frames for which no explicit name has been set
22694 \(see `modify-frame-parameters'). */);
22696 = Vframe_title_format
22697 = Fcons (intern ("multiple-frames"),
22698 Fcons (build_string ("%b"),
22699 Fcons (Fcons (empty_string
,
22700 Fcons (intern ("invocation-name"),
22701 Fcons (build_string ("@"),
22702 Fcons (intern ("system-name"),
22706 DEFVAR_LISP ("message-log-max", &Vmessage_log_max
,
22707 doc
: /* Maximum number of lines to keep in the message log buffer.
22708 If nil, disable message logging. If t, log messages but don't truncate
22709 the buffer when it becomes large. */);
22710 Vmessage_log_max
= make_number (50);
22712 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions
,
22713 doc
: /* Functions called before redisplay, if window sizes have changed.
22714 The value should be a list of functions that take one argument.
22715 Just before redisplay, for each frame, if any of its windows have changed
22716 size since the last redisplay, or have been split or deleted,
22717 all the functions in the list are called, with the frame as argument. */);
22718 Vwindow_size_change_functions
= Qnil
;
22720 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions
,
22721 doc
: /* List of functions to call before redisplaying a window with scrolling.
22722 Each function is called with two arguments, the window
22723 and its new display-start position. Note that the value of `window-end'
22724 is not valid when these functions are called. */);
22725 Vwindow_scroll_functions
= Qnil
;
22727 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window
,
22728 doc
: /* *Non-nil means autoselect window with mouse pointer. */);
22729 mouse_autoselect_window
= 0;
22731 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p
,
22732 doc
: /* *Non-nil means automatically resize tool-bars.
22733 This increases a tool-bar's height if not all tool-bar items are visible.
22734 It decreases a tool-bar's height when it would display blank lines
22736 auto_resize_tool_bars_p
= 1;
22738 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p
,
22739 doc
: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
22740 auto_raise_tool_bar_buttons_p
= 1;
22742 DEFVAR_BOOL ("make-cursor-line-fully-visible", &make_cursor_line_fully_visible_p
,
22743 doc
: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
22744 make_cursor_line_fully_visible_p
= 1;
22746 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin
,
22747 doc
: /* *Margin around tool-bar buttons in pixels.
22748 If an integer, use that for both horizontal and vertical margins.
22749 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
22750 HORZ specifying the horizontal margin, and VERT specifying the
22751 vertical margin. */);
22752 Vtool_bar_button_margin
= make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN
);
22754 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief
,
22755 doc
: /* *Relief thickness of tool-bar buttons. */);
22756 tool_bar_button_relief
= DEFAULT_TOOL_BAR_BUTTON_RELIEF
;
22758 DEFVAR_LISP ("fontification-functions", &Vfontification_functions
,
22759 doc
: /* List of functions to call to fontify regions of text.
22760 Each function is called with one argument POS. Functions must
22761 fontify a region starting at POS in the current buffer, and give
22762 fontified regions the property `fontified'. */);
22763 Vfontification_functions
= Qnil
;
22764 Fmake_variable_buffer_local (Qfontification_functions
);
22766 DEFVAR_BOOL ("unibyte-display-via-language-environment",
22767 &unibyte_display_via_language_environment
,
22768 doc
: /* *Non-nil means display unibyte text according to language environment.
22769 Specifically this means that unibyte non-ASCII characters
22770 are displayed by converting them to the equivalent multibyte characters
22771 according to the current language environment. As a result, they are
22772 displayed according to the current fontset. */);
22773 unibyte_display_via_language_environment
= 0;
22775 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height
,
22776 doc
: /* *Maximum height for resizing mini-windows.
22777 If a float, it specifies a fraction of the mini-window frame's height.
22778 If an integer, it specifies a number of lines. */);
22779 Vmax_mini_window_height
= make_float (0.25);
22781 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows
,
22782 doc
: /* *How to resize mini-windows.
22783 A value of nil means don't automatically resize mini-windows.
22784 A value of t means resize them to fit the text displayed in them.
22785 A value of `grow-only', the default, means let mini-windows grow
22786 only, until their display becomes empty, at which point the windows
22787 go back to their normal size. */);
22788 Vresize_mini_windows
= Qgrow_only
;
22790 DEFVAR_LISP ("cursor-in-non-selected-windows",
22791 &Vcursor_in_non_selected_windows
,
22792 doc
: /* *Cursor type to display in non-selected windows.
22793 t means to use hollow box cursor. See `cursor-type' for other values. */);
22794 Vcursor_in_non_selected_windows
= Qt
;
22796 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist
,
22797 doc
: /* Alist specifying how to blink the cursor off.
22798 Each element has the form (ON-STATE . OFF-STATE). Whenever the
22799 `cursor-type' frame-parameter or variable equals ON-STATE,
22800 comparing using `equal', Emacs uses OFF-STATE to specify
22801 how to blink it off. */);
22802 Vblink_cursor_alist
= Qnil
;
22804 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p
,
22805 doc
: /* *Non-nil means scroll the display automatically to make point visible. */);
22806 automatic_hscrolling_p
= 1;
22808 DEFVAR_INT ("hscroll-margin", &hscroll_margin
,
22809 doc
: /* *How many columns away from the window edge point is allowed to get
22810 before automatic hscrolling will horizontally scroll the window. */);
22811 hscroll_margin
= 5;
22813 DEFVAR_LISP ("hscroll-step", &Vhscroll_step
,
22814 doc
: /* *How many columns to scroll the window when point gets too close to the edge.
22815 When point is less than `automatic-hscroll-margin' columns from the window
22816 edge, automatic hscrolling will scroll the window by the amount of columns
22817 determined by this variable. If its value is a positive integer, scroll that
22818 many columns. If it's a positive floating-point number, it specifies the
22819 fraction of the window's width to scroll. If it's nil or zero, point will be
22820 centered horizontally after the scroll. Any other value, including negative
22821 numbers, are treated as if the value were zero.
22823 Automatic hscrolling always moves point outside the scroll margin, so if
22824 point was more than scroll step columns inside the margin, the window will
22825 scroll more than the value given by the scroll step.
22827 Note that the lower bound for automatic hscrolling specified by `scroll-left'
22828 and `scroll-right' overrides this variable's effect. */);
22829 Vhscroll_step
= make_number (0);
22831 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines
,
22832 doc
: /* If non-nil, messages are truncated instead of resizing the echo area.
22833 Bind this around calls to `message' to let it take effect. */);
22834 message_truncate_lines
= 0;
22836 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook
,
22837 doc
: /* Normal hook run to update the menu bar definitions.
22838 Redisplay runs this hook before it redisplays the menu bar.
22839 This is used to update submenus such as Buffers,
22840 whose contents depend on various data. */);
22841 Vmenu_bar_update_hook
= Qnil
;
22843 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update
,
22844 doc
: /* Non-nil means don't update menu bars. Internal use only. */);
22845 inhibit_menubar_update
= 0;
22847 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay
,
22848 doc
: /* Non-nil means don't eval Lisp during redisplay. */);
22849 inhibit_eval_during_redisplay
= 0;
22851 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces
,
22852 doc
: /* Non-nil means don't free realized faces. Internal use only. */);
22853 inhibit_free_realized_faces
= 0;
22856 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id
,
22857 doc
: /* Inhibit try_window_id display optimization. */);
22858 inhibit_try_window_id
= 0;
22860 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing
,
22861 doc
: /* Inhibit try_window_reusing display optimization. */);
22862 inhibit_try_window_reusing
= 0;
22864 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement
,
22865 doc
: /* Inhibit try_cursor_movement display optimization. */);
22866 inhibit_try_cursor_movement
= 0;
22867 #endif /* GLYPH_DEBUG */
22871 /* Initialize this module when Emacs starts. */
22876 Lisp_Object root_window
;
22877 struct window
*mini_w
;
22879 current_header_line_height
= current_mode_line_height
= -1;
22881 CHARPOS (this_line_start_pos
) = 0;
22883 mini_w
= XWINDOW (minibuf_window
);
22884 root_window
= FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w
)));
22886 if (!noninteractive
)
22888 struct frame
*f
= XFRAME (WINDOW_FRAME (XWINDOW (root_window
)));
22891 XWINDOW (root_window
)->top_line
= make_number (FRAME_TOP_MARGIN (f
));
22892 set_window_height (root_window
,
22893 FRAME_LINES (f
) - 1 - FRAME_TOP_MARGIN (f
),
22895 mini_w
->top_line
= make_number (FRAME_LINES (f
) - 1);
22896 set_window_height (minibuf_window
, 1, 0);
22898 XWINDOW (root_window
)->total_cols
= make_number (FRAME_COLS (f
));
22899 mini_w
->total_cols
= make_number (FRAME_COLS (f
));
22901 scratch_glyph_row
.glyphs
[TEXT_AREA
] = scratch_glyphs
;
22902 scratch_glyph_row
.glyphs
[TEXT_AREA
+ 1]
22903 = scratch_glyphs
+ MAX_SCRATCH_GLYPHS
;
22905 /* The default ellipsis glyphs `...'. */
22906 for (i
= 0; i
< 3; ++i
)
22907 default_invis_vector
[i
] = make_number ('.');
22911 /* Allocate the buffer for frame titles.
22912 Also used for `format-mode-line'. */
22914 frame_title_buf
= (char *) xmalloc (size
);
22915 frame_title_buf_end
= frame_title_buf
+ size
;
22916 frame_title_ptr
= NULL
;
22919 help_echo_showing_p
= 0;
22923 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
22924 (do not change this comment) */