1 /* Display generation from window structure and buffer text.
2 Copyright (C) 1985,86,87,88,93,94,95,97,98,99,2000,01,02,03,04
3 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* New redisplay written by Gerd Moellmann <gerd@gnu.org>.
26 Emacs separates the task of updating the display from code
27 modifying global state, e.g. buffer text. This way functions
28 operating on buffers don't also have to be concerned with updating
31 Updating the display is triggered by the Lisp interpreter when it
32 decides it's time to do it. This is done either automatically for
33 you as part of the interpreter's command loop or as the result of
34 calling Lisp functions like `sit-for'. The C function `redisplay'
35 in xdisp.c is the only entry into the inner redisplay code. (Or,
36 let's say almost---see the description of direct update
39 The following diagram shows how redisplay code is invoked. As you
40 can see, Lisp calls redisplay and vice versa. Under window systems
41 like X, some portions of the redisplay code are also called
42 asynchronously during mouse movement or expose events. It is very
43 important that these code parts do NOT use the C library (malloc,
44 free) because many C libraries under Unix are not reentrant. They
45 may also NOT call functions of the Lisp interpreter which could
46 change the interpreter's state. If you don't follow these rules,
47 you will encounter bugs which are very hard to explain.
49 (Direct functions, see below)
50 direct_output_for_insert,
51 direct_forward_char (dispnew.c)
52 +---------------------------------+
55 +--------------+ redisplay +----------------+
56 | Lisp machine |---------------->| Redisplay code |<--+
57 +--------------+ (xdisp.c) +----------------+ |
59 +----------------------------------+ |
60 Don't use this path when called |
63 expose_window (asynchronous) |
65 X expose events -----+
67 What does redisplay do? Obviously, it has to figure out somehow what
68 has been changed since the last time the display has been updated,
69 and to make these changes visible. Preferably it would do that in
70 a moderately intelligent way, i.e. fast.
72 Changes in buffer text can be deduced from window and buffer
73 structures, and from some global variables like `beg_unchanged' and
74 `end_unchanged'. The contents of the display are additionally
75 recorded in a `glyph matrix', a two-dimensional matrix of glyph
76 structures. Each row in such a matrix corresponds to a line on the
77 display, and each glyph in a row corresponds to a column displaying
78 a character, an image, or what else. This matrix is called the
79 `current glyph matrix' or `current matrix' in redisplay
82 For buffer parts that have been changed since the last update, a
83 second glyph matrix is constructed, the so called `desired glyph
84 matrix' or short `desired matrix'. Current and desired matrix are
85 then compared to find a cheap way to update the display, e.g. by
86 reusing part of the display by scrolling lines.
91 You will find a lot of redisplay optimizations when you start
92 looking at the innards of redisplay. The overall goal of all these
93 optimizations is to make redisplay fast because it is done
96 Two optimizations are not found in xdisp.c. These are the direct
97 operations mentioned above. As the name suggests they follow a
98 different principle than the rest of redisplay. Instead of
99 building a desired matrix and then comparing it with the current
100 display, they perform their actions directly on the display and on
103 One direct operation updates the display after one character has
104 been entered. The other one moves the cursor by one position
105 forward or backward. You find these functions under the names
106 `direct_output_for_insert' and `direct_output_forward_char' in
112 Desired matrices are always built per Emacs window. The function
113 `display_line' is the central function to look at if you are
114 interested. It constructs one row in a desired matrix given an
115 iterator structure containing both a buffer position and a
116 description of the environment in which the text is to be
117 displayed. But this is too early, read on.
119 Characters and pixmaps displayed for a range of buffer text depend
120 on various settings of buffers and windows, on overlays and text
121 properties, on display tables, on selective display. The good news
122 is that all this hairy stuff is hidden behind a small set of
123 interface functions taking an iterator structure (struct it)
126 Iteration over things to be displayed is then simple. It is
127 started by initializing an iterator with a call to init_iterator.
128 Calls to get_next_display_element fill the iterator structure with
129 relevant information about the next thing to display. Calls to
130 set_iterator_to_next move the iterator to the next thing.
132 Besides this, an iterator also contains information about the
133 display environment in which glyphs for display elements are to be
134 produced. It has fields for the width and height of the display,
135 the information whether long lines are truncated or continued, a
136 current X and Y position, and lots of other stuff you can better
139 Glyphs in a desired matrix are normally constructed in a loop
140 calling get_next_display_element and then produce_glyphs. The call
141 to produce_glyphs will fill the iterator structure with pixel
142 information about the element being displayed and at the same time
143 produce glyphs for it. If the display element fits on the line
144 being displayed, set_iterator_to_next is called next, otherwise the
145 glyphs produced are discarded.
150 That just couldn't be all, could it? What about terminal types not
151 supporting operations on sub-windows of the screen? To update the
152 display on such a terminal, window-based glyph matrices are not
153 well suited. To be able to reuse part of the display (scrolling
154 lines up and down), we must instead have a view of the whole
155 screen. This is what `frame matrices' are for. They are a trick.
157 Frames on terminals like above have a glyph pool. Windows on such
158 a frame sub-allocate their glyph memory from their frame's glyph
159 pool. The frame itself is given its own glyph matrices. By
160 coincidence---or maybe something else---rows in window glyph
161 matrices are slices of corresponding rows in frame matrices. Thus
162 writing to window matrices implicitly updates a frame matrix which
163 provides us with the view of the whole screen that we originally
164 wanted to have without having to move many bytes around. To be
165 honest, there is a little bit more done, but not much more. If you
166 plan to extend that code, take a look at dispnew.c. The function
167 build_frame_matrix is a good starting point. */
173 #include "keyboard.h"
176 #include "termchar.h"
177 #include "dispextern.h"
181 #include "commands.h"
185 #include "termhooks.h"
186 #include "intervals.h"
189 #include "region-cache.h"
191 #include "blockinput.h"
193 #ifdef HAVE_X_WINDOWS
205 #ifndef FRAME_X_OUTPUT
206 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
209 #define INFINITY 10000000
211 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
213 extern void set_frame_menubar
P_ ((struct frame
*f
, int, int));
214 extern int pending_menu_activation
;
217 extern int interrupt_input
;
218 extern int command_loop_level
;
220 extern int minibuffer_auto_raise
;
221 extern Lisp_Object Vminibuffer_list
;
223 extern Lisp_Object Qface
;
224 extern Lisp_Object Qmode_line
, Qmode_line_inactive
, Qheader_line
;
226 extern Lisp_Object Voverriding_local_map
;
227 extern Lisp_Object Voverriding_local_map_menu_flag
;
228 extern Lisp_Object Qmenu_item
;
229 extern Lisp_Object Qwhen
;
230 extern Lisp_Object Qhelp_echo
;
232 Lisp_Object Qoverriding_local_map
, Qoverriding_terminal_local_map
;
233 Lisp_Object Qwindow_scroll_functions
, Vwindow_scroll_functions
;
234 Lisp_Object Qredisplay_end_trigger_functions
;
235 Lisp_Object Qinhibit_point_motion_hooks
;
236 Lisp_Object QCeval
, QCfile
, QCdata
, QCpropertize
;
237 Lisp_Object Qfontified
;
238 Lisp_Object Qgrow_only
;
239 Lisp_Object Qinhibit_eval_during_redisplay
;
240 Lisp_Object Qbuffer_position
, Qposition
, Qobject
;
243 Lisp_Object Qbar
, Qhbar
, Qbox
, Qhollow
;
246 Lisp_Object Qarrow
, Qhand
, Qtext
;
248 Lisp_Object Qrisky_local_variable
;
250 /* Holds the list (error). */
251 Lisp_Object list_of_error
;
253 /* Functions called to fontify regions of text. */
255 Lisp_Object Vfontification_functions
;
256 Lisp_Object Qfontification_functions
;
258 /* Non-zero means automatically select any window when the mouse
259 cursor moves into it. */
260 int mouse_autoselect_window
;
262 /* Non-zero means draw tool bar buttons raised when the mouse moves
265 int auto_raise_tool_bar_buttons_p
;
267 /* Margin around tool bar buttons in pixels. */
269 Lisp_Object Vtool_bar_button_margin
;
271 /* Thickness of shadow to draw around tool bar buttons. */
273 EMACS_INT tool_bar_button_relief
;
275 /* Non-zero means automatically resize tool-bars so that all tool-bar
276 items are visible, and no blank lines remain. */
278 int auto_resize_tool_bars_p
;
280 /* Non-zero means draw block and hollow cursor as wide as the glyph
281 under it. For example, if a block cursor is over a tab, it will be
282 drawn as wide as that tab on the display. */
284 int x_stretch_cursor_p
;
286 /* Non-nil means don't actually do any redisplay. */
288 Lisp_Object Vinhibit_redisplay
, Qinhibit_redisplay
;
290 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
292 int inhibit_eval_during_redisplay
;
294 /* Names of text properties relevant for redisplay. */
296 Lisp_Object Qdisplay
;
297 extern Lisp_Object Qface
, Qinvisible
, Qwidth
;
299 /* Symbols used in text property values. */
301 Lisp_Object Vdisplay_pixels_per_inch
;
302 Lisp_Object Qspace
, QCalign_to
, QCrelative_width
, QCrelative_height
;
303 Lisp_Object Qleft_margin
, Qright_margin
, Qspace_width
, Qraise
;
304 Lisp_Object Qmargin
, Qpointer
;
305 extern Lisp_Object Qheight
;
306 extern Lisp_Object QCwidth
, QCheight
, QCascent
;
307 extern Lisp_Object Qscroll_bar
;
309 /* Non-nil means highlight trailing whitespace. */
311 Lisp_Object Vshow_trailing_whitespace
;
313 #ifdef HAVE_WINDOW_SYSTEM
314 extern Lisp_Object Voverflow_newline_into_fringe
;
316 /* Test if overflow newline into fringe. Called with iterator IT
317 at or past right window margin, and with IT->current_x set. */
319 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) \
320 (!NILP (Voverflow_newline_into_fringe) \
321 && FRAME_WINDOW_P (it->f) \
322 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
323 && it->current_x == it->last_visible_x)
325 #endif /* HAVE_WINDOW_SYSTEM */
327 /* Non-nil means show the text cursor in void text areas
328 i.e. in blank areas after eol and eob. This used to be
329 the default in 21.3. */
331 Lisp_Object Vvoid_text_area_pointer
;
333 /* Name of the face used to highlight trailing whitespace. */
335 Lisp_Object Qtrailing_whitespace
;
337 /* The symbol `image' which is the car of the lists used to represent
342 /* The image map types. */
343 Lisp_Object QCmap
, QCpointer
;
344 Lisp_Object Qrect
, Qcircle
, Qpoly
;
346 /* Non-zero means print newline to stdout before next mini-buffer
349 int noninteractive_need_newline
;
351 /* Non-zero means print newline to message log before next message. */
353 static int message_log_need_newline
;
355 /* Three markers that message_dolog uses.
356 It could allocate them itself, but that causes trouble
357 in handling memory-full errors. */
358 static Lisp_Object message_dolog_marker1
;
359 static Lisp_Object message_dolog_marker2
;
360 static Lisp_Object message_dolog_marker3
;
362 /* The buffer position of the first character appearing entirely or
363 partially on the line of the selected window which contains the
364 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
365 redisplay optimization in redisplay_internal. */
367 static struct text_pos this_line_start_pos
;
369 /* Number of characters past the end of the line above, including the
370 terminating newline. */
372 static struct text_pos this_line_end_pos
;
374 /* The vertical positions and the height of this line. */
376 static int this_line_vpos
;
377 static int this_line_y
;
378 static int this_line_pixel_height
;
380 /* X position at which this display line starts. Usually zero;
381 negative if first character is partially visible. */
383 static int this_line_start_x
;
385 /* Buffer that this_line_.* variables are referring to. */
387 static struct buffer
*this_line_buffer
;
389 /* Nonzero means truncate lines in all windows less wide than the
392 int truncate_partial_width_windows
;
394 /* A flag to control how to display unibyte 8-bit character. */
396 int unibyte_display_via_language_environment
;
398 /* Nonzero means we have more than one non-mini-buffer-only frame.
399 Not guaranteed to be accurate except while parsing
400 frame-title-format. */
404 Lisp_Object Vglobal_mode_string
;
406 /* Marker for where to display an arrow on top of the buffer text. */
408 Lisp_Object Voverlay_arrow_position
;
410 /* String to display for the arrow. Only used on terminal frames. */
412 Lisp_Object Voverlay_arrow_string
;
414 /* Values of those variables at last redisplay. However, if
415 Voverlay_arrow_position is a marker, last_arrow_position is its
416 numerical position. */
418 static Lisp_Object last_arrow_position
, last_arrow_string
;
420 /* Like mode-line-format, but for the title bar on a visible frame. */
422 Lisp_Object Vframe_title_format
;
424 /* Like mode-line-format, but for the title bar on an iconified frame. */
426 Lisp_Object Vicon_title_format
;
428 /* List of functions to call when a window's size changes. These
429 functions get one arg, a frame on which one or more windows' sizes
432 static Lisp_Object Vwindow_size_change_functions
;
434 Lisp_Object Qmenu_bar_update_hook
, Vmenu_bar_update_hook
;
436 /* Nonzero if overlay arrow has been displayed once in this window. */
438 static int overlay_arrow_seen
;
440 /* Nonzero means highlight the region even in nonselected windows. */
442 int highlight_nonselected_windows
;
444 /* If cursor motion alone moves point off frame, try scrolling this
445 many lines up or down if that will bring it back. */
447 static EMACS_INT scroll_step
;
449 /* Nonzero means scroll just far enough to bring point back on the
450 screen, when appropriate. */
452 static EMACS_INT scroll_conservatively
;
454 /* Recenter the window whenever point gets within this many lines of
455 the top or bottom of the window. This value is translated into a
456 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
457 that there is really a fixed pixel height scroll margin. */
459 EMACS_INT scroll_margin
;
461 /* Number of windows showing the buffer of the selected window (or
462 another buffer with the same base buffer). keyboard.c refers to
467 /* Vector containing glyphs for an ellipsis `...'. */
469 static Lisp_Object default_invis_vector
[3];
471 /* Zero means display the mode-line/header-line/menu-bar in the default face
472 (this slightly odd definition is for compatibility with previous versions
473 of emacs), non-zero means display them using their respective faces.
475 This variable is deprecated. */
477 int mode_line_inverse_video
;
479 /* Prompt to display in front of the mini-buffer contents. */
481 Lisp_Object minibuf_prompt
;
483 /* Width of current mini-buffer prompt. Only set after display_line
484 of the line that contains the prompt. */
486 int minibuf_prompt_width
;
488 /* This is the window where the echo area message was displayed. It
489 is always a mini-buffer window, but it may not be the same window
490 currently active as a mini-buffer. */
492 Lisp_Object echo_area_window
;
494 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
495 pushes the current message and the value of
496 message_enable_multibyte on the stack, the function restore_message
497 pops the stack and displays MESSAGE again. */
499 Lisp_Object Vmessage_stack
;
501 /* Nonzero means multibyte characters were enabled when the echo area
502 message was specified. */
504 int message_enable_multibyte
;
506 /* Nonzero if we should redraw the mode lines on the next redisplay. */
508 int update_mode_lines
;
510 /* Nonzero if window sizes or contents have changed since last
511 redisplay that finished. */
513 int windows_or_buffers_changed
;
515 /* Nonzero means a frame's cursor type has been changed. */
517 int cursor_type_changed
;
519 /* Nonzero after display_mode_line if %l was used and it displayed a
522 int line_number_displayed
;
524 /* Maximum buffer size for which to display line numbers. */
526 Lisp_Object Vline_number_display_limit
;
528 /* Line width to consider when repositioning for line number display. */
530 static EMACS_INT line_number_display_limit_width
;
532 /* Number of lines to keep in the message log buffer. t means
533 infinite. nil means don't log at all. */
535 Lisp_Object Vmessage_log_max
;
537 /* The name of the *Messages* buffer, a string. */
539 static Lisp_Object Vmessages_buffer_name
;
541 /* Current, index 0, and last displayed echo area message. Either
542 buffers from echo_buffers, or nil to indicate no message. */
544 Lisp_Object echo_area_buffer
[2];
546 /* The buffers referenced from echo_area_buffer. */
548 static Lisp_Object echo_buffer
[2];
550 /* A vector saved used in with_area_buffer to reduce consing. */
552 static Lisp_Object Vwith_echo_area_save_vector
;
554 /* Non-zero means display_echo_area should display the last echo area
555 message again. Set by redisplay_preserve_echo_area. */
557 static int display_last_displayed_message_p
;
559 /* Nonzero if echo area is being used by print; zero if being used by
562 int message_buf_print
;
564 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
566 Lisp_Object Qinhibit_menubar_update
;
567 int inhibit_menubar_update
;
569 /* Maximum height for resizing mini-windows. Either a float
570 specifying a fraction of the available height, or an integer
571 specifying a number of lines. */
573 Lisp_Object Vmax_mini_window_height
;
575 /* Non-zero means messages should be displayed with truncated
576 lines instead of being continued. */
578 int message_truncate_lines
;
579 Lisp_Object Qmessage_truncate_lines
;
581 /* Set to 1 in clear_message to make redisplay_internal aware
582 of an emptied echo area. */
584 static int message_cleared_p
;
586 /* Non-zero means we want a hollow cursor in windows that are not
587 selected. Zero means there's no cursor in such windows. */
589 Lisp_Object Vcursor_in_non_selected_windows
;
590 Lisp_Object Qcursor_in_non_selected_windows
;
592 /* How to blink the default frame cursor off. */
593 Lisp_Object Vblink_cursor_alist
;
595 /* A scratch glyph row with contents used for generating truncation
596 glyphs. Also used in direct_output_for_insert. */
598 #define MAX_SCRATCH_GLYPHS 100
599 struct glyph_row scratch_glyph_row
;
600 static struct glyph scratch_glyphs
[MAX_SCRATCH_GLYPHS
];
602 /* Ascent and height of the last line processed by move_it_to. */
604 static int last_max_ascent
, last_height
;
606 /* Non-zero if there's a help-echo in the echo area. */
608 int help_echo_showing_p
;
610 /* If >= 0, computed, exact values of mode-line and header-line height
611 to use in the macros CURRENT_MODE_LINE_HEIGHT and
612 CURRENT_HEADER_LINE_HEIGHT. */
614 int current_mode_line_height
, current_header_line_height
;
616 /* The maximum distance to look ahead for text properties. Values
617 that are too small let us call compute_char_face and similar
618 functions too often which is expensive. Values that are too large
619 let us call compute_char_face and alike too often because we
620 might not be interested in text properties that far away. */
622 #define TEXT_PROP_DISTANCE_LIMIT 100
626 /* Variables to turn off display optimizations from Lisp. */
628 int inhibit_try_window_id
, inhibit_try_window_reusing
;
629 int inhibit_try_cursor_movement
;
631 /* Non-zero means print traces of redisplay if compiled with
634 int trace_redisplay_p
;
636 #endif /* GLYPH_DEBUG */
638 #ifdef DEBUG_TRACE_MOVE
639 /* Non-zero means trace with TRACE_MOVE to stderr. */
642 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
644 #define TRACE_MOVE(x) (void) 0
647 /* Non-zero means automatically scroll windows horizontally to make
650 int automatic_hscrolling_p
;
652 /* How close to the margin can point get before the window is scrolled
654 EMACS_INT hscroll_margin
;
656 /* How much to scroll horizontally when point is inside the above margin. */
657 Lisp_Object Vhscroll_step
;
659 /* A list of symbols, one for each supported image type. */
661 Lisp_Object Vimage_types
;
663 /* The variable `resize-mini-windows'. If nil, don't resize
664 mini-windows. If t, always resize them to fit the text they
665 display. If `grow-only', let mini-windows grow only until they
668 Lisp_Object Vresize_mini_windows
;
670 /* Buffer being redisplayed -- for redisplay_window_error. */
672 struct buffer
*displayed_buffer
;
674 /* Value returned from text property handlers (see below). */
679 HANDLED_RECOMPUTE_PROPS
,
680 HANDLED_OVERLAY_STRING_CONSUMED
,
684 /* A description of text properties that redisplay is interested
689 /* The name of the property. */
692 /* A unique index for the property. */
695 /* A handler function called to set up iterator IT from the property
696 at IT's current position. Value is used to steer handle_stop. */
697 enum prop_handled (*handler
) P_ ((struct it
*it
));
700 static enum prop_handled handle_face_prop
P_ ((struct it
*));
701 static enum prop_handled handle_invisible_prop
P_ ((struct it
*));
702 static enum prop_handled handle_display_prop
P_ ((struct it
*));
703 static enum prop_handled handle_composition_prop
P_ ((struct it
*));
704 static enum prop_handled handle_overlay_change
P_ ((struct it
*));
705 static enum prop_handled handle_fontified_prop
P_ ((struct it
*));
707 /* Properties handled by iterators. */
709 static struct props it_props
[] =
711 {&Qfontified
, FONTIFIED_PROP_IDX
, handle_fontified_prop
},
712 /* Handle `face' before `display' because some sub-properties of
713 `display' need to know the face. */
714 {&Qface
, FACE_PROP_IDX
, handle_face_prop
},
715 {&Qdisplay
, DISPLAY_PROP_IDX
, handle_display_prop
},
716 {&Qinvisible
, INVISIBLE_PROP_IDX
, handle_invisible_prop
},
717 {&Qcomposition
, COMPOSITION_PROP_IDX
, handle_composition_prop
},
721 /* Value is the position described by X. If X is a marker, value is
722 the marker_position of X. Otherwise, value is X. */
724 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
726 /* Enumeration returned by some move_it_.* functions internally. */
730 /* Not used. Undefined value. */
733 /* Move ended at the requested buffer position or ZV. */
734 MOVE_POS_MATCH_OR_ZV
,
736 /* Move ended at the requested X pixel position. */
739 /* Move within a line ended at the end of a line that must be
743 /* Move within a line ended at the end of a line that would
744 be displayed truncated. */
747 /* Move within a line ended at a line end. */
751 /* This counter is used to clear the face cache every once in a while
752 in redisplay_internal. It is incremented for each redisplay.
753 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
756 #define CLEAR_FACE_CACHE_COUNT 500
757 static int clear_face_cache_count
;
759 /* Record the previous terminal frame we displayed. */
761 static struct frame
*previous_terminal_frame
;
763 /* Non-zero while redisplay_internal is in progress. */
767 /* Non-zero means don't free realized faces. Bound while freeing
768 realized faces is dangerous because glyph matrices might still
771 int inhibit_free_realized_faces
;
772 Lisp_Object Qinhibit_free_realized_faces
;
774 /* If a string, XTread_socket generates an event to display that string.
775 (The display is done in read_char.) */
777 Lisp_Object help_echo_string
;
778 Lisp_Object help_echo_window
;
779 Lisp_Object help_echo_object
;
782 /* Temporary variable for XTread_socket. */
784 Lisp_Object previous_help_echo_string
;
788 /* Function prototypes. */
790 static void setup_for_ellipsis
P_ ((struct it
*));
791 static void mark_window_display_accurate_1
P_ ((struct window
*, int));
792 static int single_display_prop_string_p
P_ ((Lisp_Object
, Lisp_Object
));
793 static int display_prop_string_p
P_ ((Lisp_Object
, Lisp_Object
));
794 static int cursor_row_p
P_ ((struct window
*, struct glyph_row
*));
795 static int redisplay_mode_lines
P_ ((Lisp_Object
, int));
796 static char *decode_mode_spec_coding
P_ ((Lisp_Object
, char *, int));
799 static int invisible_text_between_p
P_ ((struct it
*, int, int));
802 static int next_element_from_ellipsis
P_ ((struct it
*));
803 static void pint2str
P_ ((char *, int, int));
804 static void pint2hrstr
P_ ((char *, int, int));
805 static struct text_pos run_window_scroll_functions
P_ ((Lisp_Object
,
807 static void reconsider_clip_changes
P_ ((struct window
*, struct buffer
*));
808 static int text_outside_line_unchanged_p
P_ ((struct window
*, int, int));
809 static void store_frame_title_char
P_ ((char));
810 static int store_frame_title
P_ ((const unsigned char *, int, int));
811 static void x_consider_frame_title
P_ ((Lisp_Object
));
812 static void handle_stop
P_ ((struct it
*));
813 static int tool_bar_lines_needed
P_ ((struct frame
*));
814 static int single_display_prop_intangible_p
P_ ((Lisp_Object
));
815 static void ensure_echo_area_buffers
P_ ((void));
816 static Lisp_Object unwind_with_echo_area_buffer
P_ ((Lisp_Object
));
817 static Lisp_Object with_echo_area_buffer_unwind_data
P_ ((struct window
*));
818 static int with_echo_area_buffer
P_ ((struct window
*, int,
819 int (*) (EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
),
820 EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
821 static void clear_garbaged_frames
P_ ((void));
822 static int current_message_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
823 static int truncate_message_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
824 static int set_message_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
825 static int display_echo_area
P_ ((struct window
*));
826 static int display_echo_area_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
827 static int resize_mini_window_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
828 static Lisp_Object unwind_redisplay
P_ ((Lisp_Object
));
829 static int string_char_and_length
P_ ((const unsigned char *, int, int *));
830 static struct text_pos display_prop_end
P_ ((struct it
*, Lisp_Object
,
832 static int compute_window_start_on_continuation_line
P_ ((struct window
*));
833 static Lisp_Object safe_eval_handler
P_ ((Lisp_Object
));
834 static void insert_left_trunc_glyphs
P_ ((struct it
*));
835 static struct glyph_row
*get_overlay_arrow_glyph_row
P_ ((struct window
*));
836 static void extend_face_to_end_of_line
P_ ((struct it
*));
837 static int append_space
P_ ((struct it
*, int));
838 static int make_cursor_line_fully_visible
P_ ((struct window
*));
839 static int try_scrolling
P_ ((Lisp_Object
, int, EMACS_INT
, EMACS_INT
, int, int));
840 static int try_cursor_movement
P_ ((Lisp_Object
, struct text_pos
, int *));
841 static int trailing_whitespace_p
P_ ((int));
842 static int message_log_check_duplicate
P_ ((int, int, int, int));
843 static void push_it
P_ ((struct it
*));
844 static void pop_it
P_ ((struct it
*));
845 static void sync_frame_with_window_matrix_rows
P_ ((struct window
*));
846 static void select_frame_for_redisplay
P_ ((Lisp_Object
));
847 static void redisplay_internal
P_ ((int));
848 static int echo_area_display
P_ ((int));
849 static void redisplay_windows
P_ ((Lisp_Object
));
850 static void redisplay_window
P_ ((Lisp_Object
, int));
851 static Lisp_Object
redisplay_window_error ();
852 static Lisp_Object redisplay_window_0
P_ ((Lisp_Object
));
853 static Lisp_Object redisplay_window_1
P_ ((Lisp_Object
));
854 static void update_menu_bar
P_ ((struct frame
*, int));
855 static int try_window_reusing_current_matrix
P_ ((struct window
*));
856 static int try_window_id
P_ ((struct window
*));
857 static int display_line
P_ ((struct it
*));
858 static int display_mode_lines
P_ ((struct window
*));
859 static int display_mode_line
P_ ((struct window
*, enum face_id
, Lisp_Object
));
860 static int display_mode_element
P_ ((struct it
*, int, int, int, Lisp_Object
, Lisp_Object
, int));
861 static int store_mode_line_string
P_ ((char *, Lisp_Object
, int, int, int, Lisp_Object
));
862 static char *decode_mode_spec
P_ ((struct window
*, int, int, int, int *));
863 static void display_menu_bar
P_ ((struct window
*));
864 static int display_count_lines
P_ ((int, int, int, int, int *));
865 static int display_string
P_ ((unsigned char *, Lisp_Object
, Lisp_Object
,
866 int, int, struct it
*, int, int, int, int));
867 static void compute_line_metrics
P_ ((struct it
*));
868 static void run_redisplay_end_trigger_hook
P_ ((struct it
*));
869 static int get_overlay_strings
P_ ((struct it
*, int));
870 static void next_overlay_string
P_ ((struct it
*));
871 static void reseat
P_ ((struct it
*, struct text_pos
, int));
872 static void reseat_1
P_ ((struct it
*, struct text_pos
, int));
873 static void back_to_previous_visible_line_start
P_ ((struct it
*));
874 static void reseat_at_previous_visible_line_start
P_ ((struct it
*));
875 static void reseat_at_next_visible_line_start
P_ ((struct it
*, int));
876 static int next_element_from_display_vector
P_ ((struct it
*));
877 static int next_element_from_string
P_ ((struct it
*));
878 static int next_element_from_c_string
P_ ((struct it
*));
879 static int next_element_from_buffer
P_ ((struct it
*));
880 static int next_element_from_composition
P_ ((struct it
*));
881 static int next_element_from_image
P_ ((struct it
*));
882 static int next_element_from_stretch
P_ ((struct it
*));
883 static void load_overlay_strings
P_ ((struct it
*, int));
884 static int init_from_display_pos
P_ ((struct it
*, struct window
*,
885 struct display_pos
*));
886 static void reseat_to_string
P_ ((struct it
*, unsigned char *,
887 Lisp_Object
, int, int, int, int));
888 static enum move_it_result move_it_in_display_line_to
P_ ((struct it
*,
890 void move_it_vertically_backward
P_ ((struct it
*, int));
891 static void init_to_row_start
P_ ((struct it
*, struct window
*,
892 struct glyph_row
*));
893 static int init_to_row_end
P_ ((struct it
*, struct window
*,
894 struct glyph_row
*));
895 static void back_to_previous_line_start
P_ ((struct it
*));
896 static int forward_to_next_line_start
P_ ((struct it
*, int *));
897 static struct text_pos string_pos_nchars_ahead
P_ ((struct text_pos
,
899 static struct text_pos string_pos
P_ ((int, Lisp_Object
));
900 static struct text_pos c_string_pos
P_ ((int, unsigned char *, int));
901 static int number_of_chars
P_ ((unsigned char *, int));
902 static void compute_stop_pos
P_ ((struct it
*));
903 static void compute_string_pos
P_ ((struct text_pos
*, struct text_pos
,
905 static int face_before_or_after_it_pos
P_ ((struct it
*, int));
906 static int next_overlay_change
P_ ((int));
907 static int handle_single_display_prop
P_ ((struct it
*, Lisp_Object
,
908 Lisp_Object
, struct text_pos
*,
910 static int underlying_face_id
P_ ((struct it
*));
911 static int in_ellipses_for_invisible_text_p
P_ ((struct display_pos
*,
914 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
915 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
917 #ifdef HAVE_WINDOW_SYSTEM
919 static void update_tool_bar
P_ ((struct frame
*, int));
920 static void build_desired_tool_bar_string
P_ ((struct frame
*f
));
921 static int redisplay_tool_bar
P_ ((struct frame
*));
922 static void display_tool_bar_line
P_ ((struct it
*));
923 static void notice_overwritten_cursor
P_ ((struct window
*,
925 int, int, int, int));
929 #endif /* HAVE_WINDOW_SYSTEM */
932 /***********************************************************************
933 Window display dimensions
934 ***********************************************************************/
936 /* Return the bottom boundary y-position for text lines in window W.
937 This is the first y position at which a line cannot start.
938 It is relative to the top of the window.
940 This is the height of W minus the height of a mode line, if any. */
943 window_text_bottom_y (w
)
946 int height
= WINDOW_TOTAL_HEIGHT (w
);
948 if (WINDOW_WANTS_MODELINE_P (w
))
949 height
-= CURRENT_MODE_LINE_HEIGHT (w
);
953 /* Return the pixel width of display area AREA of window W. AREA < 0
954 means return the total width of W, not including fringes to
955 the left and right of the window. */
958 window_box_width (w
, area
)
962 int cols
= XFASTINT (w
->total_cols
);
965 if (!w
->pseudo_window_p
)
967 cols
-= WINDOW_SCROLL_BAR_COLS (w
);
969 if (area
== TEXT_AREA
)
971 if (INTEGERP (w
->left_margin_cols
))
972 cols
-= XFASTINT (w
->left_margin_cols
);
973 if (INTEGERP (w
->right_margin_cols
))
974 cols
-= XFASTINT (w
->right_margin_cols
);
975 pixels
= -WINDOW_TOTAL_FRINGE_WIDTH (w
);
977 else if (area
== LEFT_MARGIN_AREA
)
979 cols
= (INTEGERP (w
->left_margin_cols
)
980 ? XFASTINT (w
->left_margin_cols
) : 0);
983 else if (area
== RIGHT_MARGIN_AREA
)
985 cols
= (INTEGERP (w
->right_margin_cols
)
986 ? XFASTINT (w
->right_margin_cols
) : 0);
991 return cols
* WINDOW_FRAME_COLUMN_WIDTH (w
) + pixels
;
995 /* Return the pixel height of the display area of window W, not
996 including mode lines of W, if any. */
999 window_box_height (w
)
1002 struct frame
*f
= XFRAME (w
->frame
);
1003 int height
= WINDOW_TOTAL_HEIGHT (w
);
1005 xassert (height
>= 0);
1007 /* Note: the code below that determines the mode-line/header-line
1008 height is essentially the same as that contained in the macro
1009 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1010 the appropriate glyph row has its `mode_line_p' flag set,
1011 and if it doesn't, uses estimate_mode_line_height instead. */
1013 if (WINDOW_WANTS_MODELINE_P (w
))
1015 struct glyph_row
*ml_row
1016 = (w
->current_matrix
&& w
->current_matrix
->rows
1017 ? MATRIX_MODE_LINE_ROW (w
->current_matrix
)
1019 if (ml_row
&& ml_row
->mode_line_p
)
1020 height
-= ml_row
->height
;
1022 height
-= estimate_mode_line_height (f
, CURRENT_MODE_LINE_FACE_ID (w
));
1025 if (WINDOW_WANTS_HEADER_LINE_P (w
))
1027 struct glyph_row
*hl_row
1028 = (w
->current_matrix
&& w
->current_matrix
->rows
1029 ? MATRIX_HEADER_LINE_ROW (w
->current_matrix
)
1031 if (hl_row
&& hl_row
->mode_line_p
)
1032 height
-= hl_row
->height
;
1034 height
-= estimate_mode_line_height (f
, HEADER_LINE_FACE_ID
);
1037 /* With a very small font and a mode-line that's taller than
1038 default, we might end up with a negative height. */
1039 return max (0, height
);
1042 /* Return the window-relative coordinate of the left edge of display
1043 area AREA of window W. AREA < 0 means return the left edge of the
1044 whole window, to the right of the left fringe of W. */
1047 window_box_left_offset (w
, area
)
1053 if (w
->pseudo_window_p
)
1056 x
= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w
);
1058 if (area
== TEXT_AREA
)
1059 x
+= (WINDOW_LEFT_FRINGE_WIDTH (w
)
1060 + window_box_width (w
, LEFT_MARGIN_AREA
));
1061 else if (area
== RIGHT_MARGIN_AREA
)
1062 x
+= (WINDOW_LEFT_FRINGE_WIDTH (w
)
1063 + window_box_width (w
, LEFT_MARGIN_AREA
)
1064 + window_box_width (w
, TEXT_AREA
)
1065 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
1067 : WINDOW_RIGHT_FRINGE_WIDTH (w
)));
1068 else if (area
== LEFT_MARGIN_AREA
1069 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
))
1070 x
+= WINDOW_LEFT_FRINGE_WIDTH (w
);
1076 /* Return the window-relative coordinate of the right edge of display
1077 area AREA of window W. AREA < 0 means return the left edge of the
1078 whole window, to the left of the right fringe of W. */
1081 window_box_right_offset (w
, area
)
1085 return window_box_left_offset (w
, area
) + window_box_width (w
, area
);
1088 /* Return the frame-relative coordinate of the left edge of display
1089 area AREA of window W. AREA < 0 means return the left edge of the
1090 whole window, to the right of the left fringe of W. */
1093 window_box_left (w
, area
)
1097 struct frame
*f
= XFRAME (w
->frame
);
1100 if (w
->pseudo_window_p
)
1101 return FRAME_INTERNAL_BORDER_WIDTH (f
);
1103 x
= (WINDOW_LEFT_EDGE_X (w
)
1104 + window_box_left_offset (w
, area
));
1110 /* Return the frame-relative coordinate of the right edge of display
1111 area AREA of window W. AREA < 0 means return the left edge of the
1112 whole window, to the left of the right fringe of W. */
1115 window_box_right (w
, area
)
1119 return window_box_left (w
, area
) + window_box_width (w
, area
);
1122 /* Get the bounding box of the display area AREA of window W, without
1123 mode lines, in frame-relative coordinates. AREA < 0 means the
1124 whole window, not including the left and right fringes of
1125 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1126 coordinates of the upper-left corner of the box. Return in
1127 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1130 window_box (w
, area
, box_x
, box_y
, box_width
, box_height
)
1133 int *box_x
, *box_y
, *box_width
, *box_height
;
1136 *box_width
= window_box_width (w
, area
);
1138 *box_height
= window_box_height (w
);
1140 *box_x
= window_box_left (w
, area
);
1143 *box_y
= WINDOW_TOP_EDGE_Y (w
);
1144 if (WINDOW_WANTS_HEADER_LINE_P (w
))
1145 *box_y
+= CURRENT_HEADER_LINE_HEIGHT (w
);
1150 /* Get the bounding box of the display area AREA of window W, without
1151 mode lines. AREA < 0 means the whole window, not including the
1152 left and right fringe of the window. Return in *TOP_LEFT_X
1153 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1154 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1155 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1159 window_box_edges (w
, area
, top_left_x
, top_left_y
,
1160 bottom_right_x
, bottom_right_y
)
1163 int *top_left_x
, *top_left_y
, *bottom_right_x
, *bottom_right_y
;
1165 window_box (w
, area
, top_left_x
, top_left_y
, bottom_right_x
,
1167 *bottom_right_x
+= *top_left_x
;
1168 *bottom_right_y
+= *top_left_y
;
1173 /***********************************************************************
1175 ***********************************************************************/
1177 /* Return the bottom y-position of the line the iterator IT is in.
1178 This can modify IT's settings. */
1184 int line_height
= it
->max_ascent
+ it
->max_descent
;
1185 int line_top_y
= it
->current_y
;
1187 if (line_height
== 0)
1190 line_height
= last_height
;
1191 else if (IT_CHARPOS (*it
) < ZV
)
1193 move_it_by_lines (it
, 1, 1);
1194 line_height
= (it
->max_ascent
|| it
->max_descent
1195 ? it
->max_ascent
+ it
->max_descent
1200 struct glyph_row
*row
= it
->glyph_row
;
1202 /* Use the default character height. */
1203 it
->glyph_row
= NULL
;
1204 it
->what
= IT_CHARACTER
;
1207 PRODUCE_GLYPHS (it
);
1208 line_height
= it
->ascent
+ it
->descent
;
1209 it
->glyph_row
= row
;
1213 return line_top_y
+ line_height
;
1217 /* Return 1 if position CHARPOS is visible in window W. Set *FULLY to
1218 1 if POS is visible and the line containing POS is fully visible.
1219 EXACT_MODE_LINE_HEIGHTS_P non-zero means compute exact mode-line
1220 and header-lines heights. */
1223 pos_visible_p (w
, charpos
, fully
, exact_mode_line_heights_p
)
1225 int charpos
, *fully
, exact_mode_line_heights_p
;
1228 struct text_pos top
;
1230 struct buffer
*old_buffer
= NULL
;
1232 if (XBUFFER (w
->buffer
) != current_buffer
)
1234 old_buffer
= current_buffer
;
1235 set_buffer_internal_1 (XBUFFER (w
->buffer
));
1238 *fully
= visible_p
= 0;
1239 SET_TEXT_POS_FROM_MARKER (top
, w
->start
);
1241 /* Compute exact mode line heights, if requested. */
1242 if (exact_mode_line_heights_p
)
1244 if (WINDOW_WANTS_MODELINE_P (w
))
1245 current_mode_line_height
1246 = display_mode_line (w
, CURRENT_MODE_LINE_FACE_ID (w
),
1247 current_buffer
->mode_line_format
);
1249 if (WINDOW_WANTS_HEADER_LINE_P (w
))
1250 current_header_line_height
1251 = display_mode_line (w
, HEADER_LINE_FACE_ID
,
1252 current_buffer
->header_line_format
);
1255 start_display (&it
, w
, top
);
1256 move_it_to (&it
, charpos
, 0, it
.last_visible_y
, -1,
1257 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
1259 /* Note that we may overshoot because of invisible text. */
1260 if (IT_CHARPOS (it
) >= charpos
)
1262 int top_y
= it
.current_y
;
1263 int bottom_y
= line_bottom_y (&it
);
1264 int window_top_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
1266 if (top_y
< window_top_y
)
1267 visible_p
= bottom_y
> window_top_y
;
1268 else if (top_y
< it
.last_visible_y
)
1271 *fully
= bottom_y
<= it
.last_visible_y
;
1274 else if (it
.current_y
+ it
.max_ascent
+ it
.max_descent
> it
.last_visible_y
)
1276 move_it_by_lines (&it
, 1, 0);
1277 if (charpos
< IT_CHARPOS (it
))
1285 set_buffer_internal_1 (old_buffer
);
1287 current_header_line_height
= current_mode_line_height
= -1;
1292 /* Return the next character from STR which is MAXLEN bytes long.
1293 Return in *LEN the length of the character. This is like
1294 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1295 we find one, we return a `?', but with the length of the invalid
1299 string_char_and_length (str
, maxlen
, len
)
1300 const unsigned char *str
;
1305 c
= STRING_CHAR_AND_LENGTH (str
, maxlen
, *len
);
1306 if (!CHAR_VALID_P (c
, 1))
1307 /* We may not change the length here because other places in Emacs
1308 don't use this function, i.e. they silently accept invalid
1317 /* Given a position POS containing a valid character and byte position
1318 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1320 static struct text_pos
1321 string_pos_nchars_ahead (pos
, string
, nchars
)
1322 struct text_pos pos
;
1326 xassert (STRINGP (string
) && nchars
>= 0);
1328 if (STRING_MULTIBYTE (string
))
1330 int rest
= SBYTES (string
) - BYTEPOS (pos
);
1331 const unsigned char *p
= SDATA (string
) + BYTEPOS (pos
);
1336 string_char_and_length (p
, rest
, &len
);
1337 p
+= len
, rest
-= len
;
1338 xassert (rest
>= 0);
1340 BYTEPOS (pos
) += len
;
1344 SET_TEXT_POS (pos
, CHARPOS (pos
) + nchars
, BYTEPOS (pos
) + nchars
);
1350 /* Value is the text position, i.e. character and byte position,
1351 for character position CHARPOS in STRING. */
1353 static INLINE
struct text_pos
1354 string_pos (charpos
, string
)
1358 struct text_pos pos
;
1359 xassert (STRINGP (string
));
1360 xassert (charpos
>= 0);
1361 SET_TEXT_POS (pos
, charpos
, string_char_to_byte (string
, charpos
));
1366 /* Value is a text position, i.e. character and byte position, for
1367 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1368 means recognize multibyte characters. */
1370 static struct text_pos
1371 c_string_pos (charpos
, s
, multibyte_p
)
1376 struct text_pos pos
;
1378 xassert (s
!= NULL
);
1379 xassert (charpos
>= 0);
1383 int rest
= strlen (s
), len
;
1385 SET_TEXT_POS (pos
, 0, 0);
1388 string_char_and_length (s
, rest
, &len
);
1389 s
+= len
, rest
-= len
;
1390 xassert (rest
>= 0);
1392 BYTEPOS (pos
) += len
;
1396 SET_TEXT_POS (pos
, charpos
, charpos
);
1402 /* Value is the number of characters in C string S. MULTIBYTE_P
1403 non-zero means recognize multibyte characters. */
1406 number_of_chars (s
, multibyte_p
)
1414 int rest
= strlen (s
), len
;
1415 unsigned char *p
= (unsigned char *) s
;
1417 for (nchars
= 0; rest
> 0; ++nchars
)
1419 string_char_and_length (p
, rest
, &len
);
1420 rest
-= len
, p
+= len
;
1424 nchars
= strlen (s
);
1430 /* Compute byte position NEWPOS->bytepos corresponding to
1431 NEWPOS->charpos. POS is a known position in string STRING.
1432 NEWPOS->charpos must be >= POS.charpos. */
1435 compute_string_pos (newpos
, pos
, string
)
1436 struct text_pos
*newpos
, pos
;
1439 xassert (STRINGP (string
));
1440 xassert (CHARPOS (*newpos
) >= CHARPOS (pos
));
1442 if (STRING_MULTIBYTE (string
))
1443 *newpos
= string_pos_nchars_ahead (pos
, string
,
1444 CHARPOS (*newpos
) - CHARPOS (pos
));
1446 BYTEPOS (*newpos
) = CHARPOS (*newpos
);
1450 Return an estimation of the pixel height of mode or top lines on
1451 frame F. FACE_ID specifies what line's height to estimate. */
1454 estimate_mode_line_height (f
, face_id
)
1456 enum face_id face_id
;
1458 #ifdef HAVE_WINDOW_SYSTEM
1459 if (FRAME_WINDOW_P (f
))
1461 int height
= FONT_HEIGHT (FRAME_FONT (f
));
1463 /* This function is called so early when Emacs starts that the face
1464 cache and mode line face are not yet initialized. */
1465 if (FRAME_FACE_CACHE (f
))
1467 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1471 height
= FONT_HEIGHT (face
->font
);
1472 if (face
->box_line_width
> 0)
1473 height
+= 2 * face
->box_line_width
;
1484 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1485 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1486 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1487 not force the value into range. */
1490 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
, noclip
)
1492 register int pix_x
, pix_y
;
1494 NativeRectangle
*bounds
;
1498 #ifdef HAVE_WINDOW_SYSTEM
1499 if (FRAME_WINDOW_P (f
))
1501 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1502 even for negative values. */
1504 pix_x
-= FRAME_COLUMN_WIDTH (f
) - 1;
1506 pix_y
-= FRAME_LINE_HEIGHT (f
) - 1;
1508 pix_x
= FRAME_PIXEL_X_TO_COL (f
, pix_x
);
1509 pix_y
= FRAME_PIXEL_Y_TO_LINE (f
, pix_y
);
1512 STORE_NATIVE_RECT (*bounds
,
1513 FRAME_COL_TO_PIXEL_X (f
, pix_x
),
1514 FRAME_LINE_TO_PIXEL_Y (f
, pix_y
),
1515 FRAME_COLUMN_WIDTH (f
) - 1,
1516 FRAME_LINE_HEIGHT (f
) - 1);
1522 else if (pix_x
> FRAME_TOTAL_COLS (f
))
1523 pix_x
= FRAME_TOTAL_COLS (f
);
1527 else if (pix_y
> FRAME_LINES (f
))
1528 pix_y
= FRAME_LINES (f
);
1538 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1539 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1540 can't tell the positions because W's display is not up to date,
1544 glyph_to_pixel_coords (w
, hpos
, vpos
, frame_x
, frame_y
)
1547 int *frame_x
, *frame_y
;
1549 #ifdef HAVE_WINDOW_SYSTEM
1550 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w
))))
1554 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
1555 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
1557 if (display_completed
)
1559 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
1560 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
1561 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
1567 hpos
+= glyph
->pixel_width
;
1571 /* If first glyph is partially visible, its first visible position is still 0. */
1583 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, hpos
);
1584 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, vpos
);
1595 #ifdef HAVE_WINDOW_SYSTEM
1597 /* Find the glyph under window-relative coordinates X/Y in window W.
1598 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1599 strings. Return in *HPOS and *VPOS the row and column number of
1600 the glyph found. Return in *AREA the glyph area containing X.
1601 Value is a pointer to the glyph found or null if X/Y is not on
1602 text, or we can't tell because W's current matrix is not up to
1605 static struct glyph
*
1606 x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, dx
, dy
, area
)
1609 int *hpos
, *vpos
, *dx
, *dy
, *area
;
1611 struct glyph
*glyph
, *end
;
1612 struct glyph_row
*row
= NULL
;
1615 /* Find row containing Y. Give up if some row is not enabled. */
1616 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
1618 row
= MATRIX_ROW (w
->current_matrix
, i
);
1619 if (!row
->enabled_p
)
1621 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
1628 /* Give up if Y is not in the window. */
1629 if (i
== w
->current_matrix
->nrows
)
1632 /* Get the glyph area containing X. */
1633 if (w
->pseudo_window_p
)
1640 if (x
< window_box_left_offset (w
, TEXT_AREA
))
1642 *area
= LEFT_MARGIN_AREA
;
1643 x0
= window_box_left_offset (w
, LEFT_MARGIN_AREA
);
1645 else if (x
< window_box_right_offset (w
, TEXT_AREA
))
1648 x0
= window_box_left_offset (w
, TEXT_AREA
) + min (row
->x
, 0);
1652 *area
= RIGHT_MARGIN_AREA
;
1653 x0
= window_box_left_offset (w
, RIGHT_MARGIN_AREA
);
1657 /* Find glyph containing X. */
1658 glyph
= row
->glyphs
[*area
];
1659 end
= glyph
+ row
->used
[*area
];
1661 while (glyph
< end
&& x
>= glyph
->pixel_width
)
1663 x
-= glyph
->pixel_width
;
1673 *dy
= y
- (row
->y
+ row
->ascent
- glyph
->ascent
);
1676 *hpos
= glyph
- row
->glyphs
[*area
];
1682 Convert frame-relative x/y to coordinates relative to window W.
1683 Takes pseudo-windows into account. */
1686 frame_to_window_pixel_xy (w
, x
, y
)
1690 if (w
->pseudo_window_p
)
1692 /* A pseudo-window is always full-width, and starts at the
1693 left edge of the frame, plus a frame border. */
1694 struct frame
*f
= XFRAME (w
->frame
);
1695 *x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
1696 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
1700 *x
-= WINDOW_LEFT_EDGE_X (w
);
1701 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
1706 Return in *R the clipping rectangle for glyph string S. */
1709 get_glyph_string_clip_rect (s
, nr
)
1710 struct glyph_string
*s
;
1711 NativeRectangle
*nr
;
1715 if (s
->row
->full_width_p
)
1717 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1718 r
.x
= WINDOW_LEFT_EDGE_X (s
->w
);
1719 r
.width
= WINDOW_TOTAL_WIDTH (s
->w
);
1721 /* Unless displaying a mode or menu bar line, which are always
1722 fully visible, clip to the visible part of the row. */
1723 if (s
->w
->pseudo_window_p
)
1724 r
.height
= s
->row
->visible_height
;
1726 r
.height
= s
->height
;
1730 /* This is a text line that may be partially visible. */
1731 r
.x
= window_box_left (s
->w
, s
->area
);
1732 r
.width
= window_box_width (s
->w
, s
->area
);
1733 r
.height
= s
->row
->visible_height
;
1736 /* If S draws overlapping rows, it's sufficient to use the top and
1737 bottom of the window for clipping because this glyph string
1738 intentionally draws over other lines. */
1739 if (s
->for_overlaps_p
)
1741 r
.y
= WINDOW_HEADER_LINE_HEIGHT (s
->w
);
1742 r
.height
= window_text_bottom_y (s
->w
) - r
.y
;
1746 /* Don't use S->y for clipping because it doesn't take partially
1747 visible lines into account. For example, it can be negative for
1748 partially visible lines at the top of a window. */
1749 if (!s
->row
->full_width_p
1750 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
1751 r
.y
= WINDOW_HEADER_LINE_HEIGHT (s
->w
);
1753 r
.y
= max (0, s
->row
->y
);
1755 /* If drawing a tool-bar window, draw it over the internal border
1756 at the top of the window. */
1757 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
1758 r
.y
-= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
1761 r
.y
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
.y
);
1763 /* If drawing the cursor, don't let glyph draw outside its
1764 advertised boundaries. Cleartype does this under some circumstances. */
1765 if (s
->hl
== DRAW_CURSOR
)
1767 struct glyph
*glyph
= s
->first_glyph
;
1772 r
.width
-= s
->x
- r
.x
;
1775 r
.width
= min (r
.width
, glyph
->pixel_width
);
1777 /* Don't draw cursor glyph taller than our actual glyph. */
1778 height
= max (FRAME_LINE_HEIGHT (s
->f
), glyph
->ascent
+ glyph
->descent
);
1779 if (height
< r
.height
)
1781 r
.y
= s
->ybase
+ glyph
->descent
- height
;
1786 #ifdef CONVERT_FROM_XRECT
1787 CONVERT_FROM_XRECT (r
, *nr
);
1793 #endif /* HAVE_WINDOW_SYSTEM */
1796 /***********************************************************************
1797 Lisp form evaluation
1798 ***********************************************************************/
1800 /* Error handler for safe_eval and safe_call. */
1803 safe_eval_handler (arg
)
1806 add_to_log ("Error during redisplay: %s", arg
, Qnil
);
1811 /* Evaluate SEXPR and return the result, or nil if something went
1812 wrong. Prevent redisplay during the evaluation. */
1820 if (inhibit_eval_during_redisplay
)
1824 int count
= SPECPDL_INDEX ();
1825 struct gcpro gcpro1
;
1828 specbind (Qinhibit_redisplay
, Qt
);
1829 /* Use Qt to ensure debugger does not run,
1830 so there is no possibility of wanting to redisplay. */
1831 val
= internal_condition_case_1 (Feval
, sexpr
, Qt
,
1834 val
= unbind_to (count
, val
);
1841 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
1842 Return the result, or nil if something went wrong. Prevent
1843 redisplay during the evaluation. */
1846 safe_call (nargs
, args
)
1852 if (inhibit_eval_during_redisplay
)
1856 int count
= SPECPDL_INDEX ();
1857 struct gcpro gcpro1
;
1860 gcpro1
.nvars
= nargs
;
1861 specbind (Qinhibit_redisplay
, Qt
);
1862 /* Use Qt to ensure debugger does not run,
1863 so there is no possibility of wanting to redisplay. */
1864 val
= internal_condition_case_2 (Ffuncall
, nargs
, args
, Qt
,
1867 val
= unbind_to (count
, val
);
1874 /* Call function FN with one argument ARG.
1875 Return the result, or nil if something went wrong. */
1878 safe_call1 (fn
, arg
)
1879 Lisp_Object fn
, arg
;
1881 Lisp_Object args
[2];
1884 return safe_call (2, args
);
1889 /***********************************************************************
1891 ***********************************************************************/
1895 /* Define CHECK_IT to perform sanity checks on iterators.
1896 This is for debugging. It is too slow to do unconditionally. */
1902 if (it
->method
== next_element_from_string
)
1904 xassert (STRINGP (it
->string
));
1905 xassert (IT_STRING_CHARPOS (*it
) >= 0);
1907 else if (it
->method
== next_element_from_buffer
)
1909 /* Check that character and byte positions agree. */
1910 xassert (IT_CHARPOS (*it
) == BYTE_TO_CHAR (IT_BYTEPOS (*it
)));
1914 xassert (it
->current
.dpvec_index
>= 0);
1916 xassert (it
->current
.dpvec_index
< 0);
1919 #define CHECK_IT(IT) check_it ((IT))
1923 #define CHECK_IT(IT) (void) 0
1930 /* Check that the window end of window W is what we expect it
1931 to be---the last row in the current matrix displaying text. */
1934 check_window_end (w
)
1937 if (!MINI_WINDOW_P (w
)
1938 && !NILP (w
->window_end_valid
))
1940 struct glyph_row
*row
;
1941 xassert ((row
= MATRIX_ROW (w
->current_matrix
,
1942 XFASTINT (w
->window_end_vpos
)),
1944 || MATRIX_ROW_DISPLAYS_TEXT_P (row
)
1945 || MATRIX_ROW_VPOS (row
, w
->current_matrix
) == 0));
1949 #define CHECK_WINDOW_END(W) check_window_end ((W))
1951 #else /* not GLYPH_DEBUG */
1953 #define CHECK_WINDOW_END(W) (void) 0
1955 #endif /* not GLYPH_DEBUG */
1959 /***********************************************************************
1960 Iterator initialization
1961 ***********************************************************************/
1963 /* Initialize IT for displaying current_buffer in window W, starting
1964 at character position CHARPOS. CHARPOS < 0 means that no buffer
1965 position is specified which is useful when the iterator is assigned
1966 a position later. BYTEPOS is the byte position corresponding to
1967 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
1969 If ROW is not null, calls to produce_glyphs with IT as parameter
1970 will produce glyphs in that row.
1972 BASE_FACE_ID is the id of a base face to use. It must be one of
1973 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
1974 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
1975 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
1977 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
1978 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
1979 will be initialized to use the corresponding mode line glyph row of
1980 the desired matrix of W. */
1983 init_iterator (it
, w
, charpos
, bytepos
, row
, base_face_id
)
1986 int charpos
, bytepos
;
1987 struct glyph_row
*row
;
1988 enum face_id base_face_id
;
1990 int highlight_region_p
;
1992 /* Some precondition checks. */
1993 xassert (w
!= NULL
&& it
!= NULL
);
1994 xassert (charpos
< 0 || (charpos
>= BUF_BEG (current_buffer
)
1997 /* If face attributes have been changed since the last redisplay,
1998 free realized faces now because they depend on face definitions
1999 that might have changed. Don't free faces while there might be
2000 desired matrices pending which reference these faces. */
2001 if (face_change_count
&& !inhibit_free_realized_faces
)
2003 face_change_count
= 0;
2004 free_all_realized_faces (Qnil
);
2007 /* Use one of the mode line rows of W's desired matrix if
2011 if (base_face_id
== MODE_LINE_FACE_ID
2012 || base_face_id
== MODE_LINE_INACTIVE_FACE_ID
)
2013 row
= MATRIX_MODE_LINE_ROW (w
->desired_matrix
);
2014 else if (base_face_id
== HEADER_LINE_FACE_ID
)
2015 row
= MATRIX_HEADER_LINE_ROW (w
->desired_matrix
);
2019 bzero (it
, sizeof *it
);
2020 it
->current
.overlay_string_index
= -1;
2021 it
->current
.dpvec_index
= -1;
2022 it
->base_face_id
= base_face_id
;
2024 /* The window in which we iterate over current_buffer: */
2025 XSETWINDOW (it
->window
, w
);
2027 it
->f
= XFRAME (w
->frame
);
2029 /* Extra space between lines (on window systems only). */
2030 if (base_face_id
== DEFAULT_FACE_ID
2031 && FRAME_WINDOW_P (it
->f
))
2033 if (NATNUMP (current_buffer
->extra_line_spacing
))
2034 it
->extra_line_spacing
= XFASTINT (current_buffer
->extra_line_spacing
);
2035 else if (it
->f
->extra_line_spacing
> 0)
2036 it
->extra_line_spacing
= it
->f
->extra_line_spacing
;
2039 /* If realized faces have been removed, e.g. because of face
2040 attribute changes of named faces, recompute them. When running
2041 in batch mode, the face cache of Vterminal_frame is null. If
2042 we happen to get called, make a dummy face cache. */
2043 if (noninteractive
&& FRAME_FACE_CACHE (it
->f
) == NULL
)
2044 init_frame_faces (it
->f
);
2045 if (FRAME_FACE_CACHE (it
->f
)->used
== 0)
2046 recompute_basic_faces (it
->f
);
2048 /* Current value of the `space-width', and 'height' properties. */
2049 it
->space_width
= Qnil
;
2050 it
->font_height
= Qnil
;
2052 /* Are control characters displayed as `^C'? */
2053 it
->ctl_arrow_p
= !NILP (current_buffer
->ctl_arrow
);
2055 /* -1 means everything between a CR and the following line end
2056 is invisible. >0 means lines indented more than this value are
2058 it
->selective
= (INTEGERP (current_buffer
->selective_display
)
2059 ? XFASTINT (current_buffer
->selective_display
)
2060 : (!NILP (current_buffer
->selective_display
)
2062 it
->selective_display_ellipsis_p
2063 = !NILP (current_buffer
->selective_display_ellipses
);
2065 /* Display table to use. */
2066 it
->dp
= window_display_table (w
);
2068 /* Are multibyte characters enabled in current_buffer? */
2069 it
->multibyte_p
= !NILP (current_buffer
->enable_multibyte_characters
);
2071 /* Non-zero if we should highlight the region. */
2073 = (!NILP (Vtransient_mark_mode
)
2074 && !NILP (current_buffer
->mark_active
)
2075 && XMARKER (current_buffer
->mark
)->buffer
!= 0);
2077 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2078 start and end of a visible region in window IT->w. Set both to
2079 -1 to indicate no region. */
2080 if (highlight_region_p
2081 /* Maybe highlight only in selected window. */
2082 && (/* Either show region everywhere. */
2083 highlight_nonselected_windows
2084 /* Or show region in the selected window. */
2085 || w
== XWINDOW (selected_window
)
2086 /* Or show the region if we are in the mini-buffer and W is
2087 the window the mini-buffer refers to. */
2088 || (MINI_WINDOW_P (XWINDOW (selected_window
))
2089 && WINDOWP (minibuf_selected_window
)
2090 && w
== XWINDOW (minibuf_selected_window
))))
2092 int charpos
= marker_position (current_buffer
->mark
);
2093 it
->region_beg_charpos
= min (PT
, charpos
);
2094 it
->region_end_charpos
= max (PT
, charpos
);
2097 it
->region_beg_charpos
= it
->region_end_charpos
= -1;
2099 /* Get the position at which the redisplay_end_trigger hook should
2100 be run, if it is to be run at all. */
2101 if (MARKERP (w
->redisplay_end_trigger
)
2102 && XMARKER (w
->redisplay_end_trigger
)->buffer
!= 0)
2103 it
->redisplay_end_trigger_charpos
2104 = marker_position (w
->redisplay_end_trigger
);
2105 else if (INTEGERP (w
->redisplay_end_trigger
))
2106 it
->redisplay_end_trigger_charpos
= XINT (w
->redisplay_end_trigger
);
2108 /* Correct bogus values of tab_width. */
2109 it
->tab_width
= XINT (current_buffer
->tab_width
);
2110 if (it
->tab_width
<= 0 || it
->tab_width
> 1000)
2113 /* Are lines in the display truncated? */
2114 it
->truncate_lines_p
2115 = (base_face_id
!= DEFAULT_FACE_ID
2116 || XINT (it
->w
->hscroll
)
2117 || (truncate_partial_width_windows
2118 && !WINDOW_FULL_WIDTH_P (it
->w
))
2119 || !NILP (current_buffer
->truncate_lines
));
2121 /* Get dimensions of truncation and continuation glyphs. These are
2122 displayed as fringe bitmaps under X, so we don't need them for such
2124 if (!FRAME_WINDOW_P (it
->f
))
2126 if (it
->truncate_lines_p
)
2128 /* We will need the truncation glyph. */
2129 xassert (it
->glyph_row
== NULL
);
2130 produce_special_glyphs (it
, IT_TRUNCATION
);
2131 it
->truncation_pixel_width
= it
->pixel_width
;
2135 /* We will need the continuation glyph. */
2136 xassert (it
->glyph_row
== NULL
);
2137 produce_special_glyphs (it
, IT_CONTINUATION
);
2138 it
->continuation_pixel_width
= it
->pixel_width
;
2141 /* Reset these values to zero because the produce_special_glyphs
2142 above has changed them. */
2143 it
->pixel_width
= it
->ascent
= it
->descent
= 0;
2144 it
->phys_ascent
= it
->phys_descent
= 0;
2147 /* Set this after getting the dimensions of truncation and
2148 continuation glyphs, so that we don't produce glyphs when calling
2149 produce_special_glyphs, above. */
2150 it
->glyph_row
= row
;
2151 it
->area
= TEXT_AREA
;
2153 /* Get the dimensions of the display area. The display area
2154 consists of the visible window area plus a horizontally scrolled
2155 part to the left of the window. All x-values are relative to the
2156 start of this total display area. */
2157 if (base_face_id
!= DEFAULT_FACE_ID
)
2159 /* Mode lines, menu bar in terminal frames. */
2160 it
->first_visible_x
= 0;
2161 it
->last_visible_x
= WINDOW_TOTAL_WIDTH (w
);
2166 = XFASTINT (it
->w
->hscroll
) * FRAME_COLUMN_WIDTH (it
->f
);
2167 it
->last_visible_x
= (it
->first_visible_x
2168 + window_box_width (w
, TEXT_AREA
));
2170 /* If we truncate lines, leave room for the truncator glyph(s) at
2171 the right margin. Otherwise, leave room for the continuation
2172 glyph(s). Truncation and continuation glyphs are not inserted
2173 for window-based redisplay. */
2174 if (!FRAME_WINDOW_P (it
->f
))
2176 if (it
->truncate_lines_p
)
2177 it
->last_visible_x
-= it
->truncation_pixel_width
;
2179 it
->last_visible_x
-= it
->continuation_pixel_width
;
2182 it
->header_line_p
= WINDOW_WANTS_HEADER_LINE_P (w
);
2183 it
->current_y
= WINDOW_HEADER_LINE_HEIGHT (w
) + w
->vscroll
;
2186 /* Leave room for a border glyph. */
2187 if (!FRAME_WINDOW_P (it
->f
)
2188 && !WINDOW_RIGHTMOST_P (it
->w
))
2189 it
->last_visible_x
-= 1;
2191 it
->last_visible_y
= window_text_bottom_y (w
);
2193 /* For mode lines and alike, arrange for the first glyph having a
2194 left box line if the face specifies a box. */
2195 if (base_face_id
!= DEFAULT_FACE_ID
)
2199 it
->face_id
= base_face_id
;
2201 /* If we have a boxed mode line, make the first character appear
2202 with a left box line. */
2203 face
= FACE_FROM_ID (it
->f
, base_face_id
);
2204 if (face
->box
!= FACE_NO_BOX
)
2205 it
->start_of_box_run_p
= 1;
2208 /* If a buffer position was specified, set the iterator there,
2209 getting overlays and face properties from that position. */
2210 if (charpos
>= BUF_BEG (current_buffer
))
2212 it
->end_charpos
= ZV
;
2214 IT_CHARPOS (*it
) = charpos
;
2216 /* Compute byte position if not specified. */
2217 if (bytepos
< charpos
)
2218 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (charpos
);
2220 IT_BYTEPOS (*it
) = bytepos
;
2222 it
->start
= it
->current
;
2224 /* Compute faces etc. */
2225 reseat (it
, it
->current
.pos
, 1);
2232 /* Initialize IT for the display of window W with window start POS. */
2235 start_display (it
, w
, pos
)
2238 struct text_pos pos
;
2240 struct glyph_row
*row
;
2241 int first_vpos
= WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0;
2243 row
= w
->desired_matrix
->rows
+ first_vpos
;
2244 init_iterator (it
, w
, CHARPOS (pos
), BYTEPOS (pos
), row
, DEFAULT_FACE_ID
);
2245 it
->first_vpos
= first_vpos
;
2247 if (!it
->truncate_lines_p
)
2249 int start_at_line_beg_p
;
2250 int first_y
= it
->current_y
;
2252 /* If window start is not at a line start, skip forward to POS to
2253 get the correct continuation lines width. */
2254 start_at_line_beg_p
= (CHARPOS (pos
) == BEGV
2255 || FETCH_BYTE (BYTEPOS (pos
) - 1) == '\n');
2256 if (!start_at_line_beg_p
)
2260 reseat_at_previous_visible_line_start (it
);
2261 move_it_to (it
, CHARPOS (pos
), -1, -1, -1, MOVE_TO_POS
);
2263 new_x
= it
->current_x
+ it
->pixel_width
;
2265 /* If lines are continued, this line may end in the middle
2266 of a multi-glyph character (e.g. a control character
2267 displayed as \003, or in the middle of an overlay
2268 string). In this case move_it_to above will not have
2269 taken us to the start of the continuation line but to the
2270 end of the continued line. */
2271 if (it
->current_x
> 0
2272 && !it
->truncate_lines_p
/* Lines are continued. */
2273 && (/* And glyph doesn't fit on the line. */
2274 new_x
> it
->last_visible_x
2275 /* Or it fits exactly and we're on a window
2277 || (new_x
== it
->last_visible_x
2278 && FRAME_WINDOW_P (it
->f
))))
2280 if (it
->current
.dpvec_index
>= 0
2281 || it
->current
.overlay_string_index
>= 0)
2283 set_iterator_to_next (it
, 1);
2284 move_it_in_display_line_to (it
, -1, -1, 0);
2287 it
->continuation_lines_width
+= it
->current_x
;
2290 /* We're starting a new display line, not affected by the
2291 height of the continued line, so clear the appropriate
2292 fields in the iterator structure. */
2293 it
->max_ascent
= it
->max_descent
= 0;
2294 it
->max_phys_ascent
= it
->max_phys_descent
= 0;
2296 it
->current_y
= first_y
;
2298 it
->current_x
= it
->hpos
= 0;
2302 #if 0 /* Don't assert the following because start_display is sometimes
2303 called intentionally with a window start that is not at a
2304 line start. Please leave this code in as a comment. */
2306 /* Window start should be on a line start, now. */
2307 xassert (it
->continuation_lines_width
2308 || IT_CHARPOS (it
) == BEGV
2309 || FETCH_BYTE (IT_BYTEPOS (it
) - 1) == '\n');
2314 /* Return 1 if POS is a position in ellipses displayed for invisible
2315 text. W is the window we display, for text property lookup. */
2318 in_ellipses_for_invisible_text_p (pos
, w
)
2319 struct display_pos
*pos
;
2322 Lisp_Object prop
, window
;
2324 int charpos
= CHARPOS (pos
->pos
);
2326 /* If POS specifies a position in a display vector, this might
2327 be for an ellipsis displayed for invisible text. We won't
2328 get the iterator set up for delivering that ellipsis unless
2329 we make sure that it gets aware of the invisible text. */
2330 if (pos
->dpvec_index
>= 0
2331 && pos
->overlay_string_index
< 0
2332 && CHARPOS (pos
->string_pos
) < 0
2334 && (XSETWINDOW (window
, w
),
2335 prop
= Fget_char_property (make_number (charpos
),
2336 Qinvisible
, window
),
2337 !TEXT_PROP_MEANS_INVISIBLE (prop
)))
2339 prop
= Fget_char_property (make_number (charpos
- 1), Qinvisible
,
2341 ellipses_p
= 2 == TEXT_PROP_MEANS_INVISIBLE (prop
);
2348 /* Initialize IT for stepping through current_buffer in window W,
2349 starting at position POS that includes overlay string and display
2350 vector/ control character translation position information. Value
2351 is zero if there are overlay strings with newlines at POS. */
2354 init_from_display_pos (it
, w
, pos
)
2357 struct display_pos
*pos
;
2359 int charpos
= CHARPOS (pos
->pos
), bytepos
= BYTEPOS (pos
->pos
);
2360 int i
, overlay_strings_with_newlines
= 0;
2362 /* If POS specifies a position in a display vector, this might
2363 be for an ellipsis displayed for invisible text. We won't
2364 get the iterator set up for delivering that ellipsis unless
2365 we make sure that it gets aware of the invisible text. */
2366 if (in_ellipses_for_invisible_text_p (pos
, w
))
2372 /* Keep in mind: the call to reseat in init_iterator skips invisible
2373 text, so we might end up at a position different from POS. This
2374 is only a problem when POS is a row start after a newline and an
2375 overlay starts there with an after-string, and the overlay has an
2376 invisible property. Since we don't skip invisible text in
2377 display_line and elsewhere immediately after consuming the
2378 newline before the row start, such a POS will not be in a string,
2379 but the call to init_iterator below will move us to the
2381 init_iterator (it
, w
, charpos
, bytepos
, NULL
, DEFAULT_FACE_ID
);
2383 for (i
= 0; i
< it
->n_overlay_strings
; ++i
)
2385 const char *s
= SDATA (it
->overlay_strings
[i
]);
2386 const char *e
= s
+ SBYTES (it
->overlay_strings
[i
]);
2388 while (s
< e
&& *s
!= '\n')
2393 overlay_strings_with_newlines
= 1;
2398 /* If position is within an overlay string, set up IT to the right
2400 if (pos
->overlay_string_index
>= 0)
2404 /* If the first overlay string happens to have a `display'
2405 property for an image, the iterator will be set up for that
2406 image, and we have to undo that setup first before we can
2407 correct the overlay string index. */
2408 if (it
->method
== next_element_from_image
)
2411 /* We already have the first chunk of overlay strings in
2412 IT->overlay_strings. Load more until the one for
2413 pos->overlay_string_index is in IT->overlay_strings. */
2414 if (pos
->overlay_string_index
>= OVERLAY_STRING_CHUNK_SIZE
)
2416 int n
= pos
->overlay_string_index
/ OVERLAY_STRING_CHUNK_SIZE
;
2417 it
->current
.overlay_string_index
= 0;
2420 load_overlay_strings (it
, 0);
2421 it
->current
.overlay_string_index
+= OVERLAY_STRING_CHUNK_SIZE
;
2425 it
->current
.overlay_string_index
= pos
->overlay_string_index
;
2426 relative_index
= (it
->current
.overlay_string_index
2427 % OVERLAY_STRING_CHUNK_SIZE
);
2428 it
->string
= it
->overlay_strings
[relative_index
];
2429 xassert (STRINGP (it
->string
));
2430 it
->current
.string_pos
= pos
->string_pos
;
2431 it
->method
= next_element_from_string
;
2434 #if 0 /* This is bogus because POS not having an overlay string
2435 position does not mean it's after the string. Example: A
2436 line starting with a before-string and initialization of IT
2437 to the previous row's end position. */
2438 else if (it
->current
.overlay_string_index
>= 0)
2440 /* If POS says we're already after an overlay string ending at
2441 POS, make sure to pop the iterator because it will be in
2442 front of that overlay string. When POS is ZV, we've thereby
2443 also ``processed'' overlay strings at ZV. */
2446 it
->current
.overlay_string_index
= -1;
2447 it
->method
= next_element_from_buffer
;
2448 if (CHARPOS (pos
->pos
) == ZV
)
2449 it
->overlay_strings_at_end_processed_p
= 1;
2453 if (CHARPOS (pos
->string_pos
) >= 0)
2455 /* Recorded position is not in an overlay string, but in another
2456 string. This can only be a string from a `display' property.
2457 IT should already be filled with that string. */
2458 it
->current
.string_pos
= pos
->string_pos
;
2459 xassert (STRINGP (it
->string
));
2462 /* Restore position in display vector translations, control
2463 character translations or ellipses. */
2464 if (pos
->dpvec_index
>= 0)
2466 if (it
->dpvec
== NULL
)
2467 get_next_display_element (it
);
2468 xassert (it
->dpvec
&& it
->current
.dpvec_index
== 0);
2469 it
->current
.dpvec_index
= pos
->dpvec_index
;
2473 return !overlay_strings_with_newlines
;
2477 /* Initialize IT for stepping through current_buffer in window W
2478 starting at ROW->start. */
2481 init_to_row_start (it
, w
, row
)
2484 struct glyph_row
*row
;
2486 init_from_display_pos (it
, w
, &row
->start
);
2487 it
->start
= row
->start
;
2488 it
->continuation_lines_width
= row
->continuation_lines_width
;
2493 /* Initialize IT for stepping through current_buffer in window W
2494 starting in the line following ROW, i.e. starting at ROW->end.
2495 Value is zero if there are overlay strings with newlines at ROW's
2499 init_to_row_end (it
, w
, row
)
2502 struct glyph_row
*row
;
2506 if (init_from_display_pos (it
, w
, &row
->end
))
2508 if (row
->continued_p
)
2509 it
->continuation_lines_width
2510 = row
->continuation_lines_width
+ row
->pixel_width
;
2521 /***********************************************************************
2523 ***********************************************************************/
2525 /* Called when IT reaches IT->stop_charpos. Handle text property and
2526 overlay changes. Set IT->stop_charpos to the next position where
2533 enum prop_handled handled
;
2534 int handle_overlay_change_p
= 1;
2538 it
->current
.dpvec_index
= -1;
2542 handled
= HANDLED_NORMALLY
;
2544 /* Call text property handlers. */
2545 for (p
= it_props
; p
->handler
; ++p
)
2547 handled
= p
->handler (it
);
2549 if (handled
== HANDLED_RECOMPUTE_PROPS
)
2551 else if (handled
== HANDLED_RETURN
)
2553 else if (handled
== HANDLED_OVERLAY_STRING_CONSUMED
)
2554 handle_overlay_change_p
= 0;
2557 if (handled
!= HANDLED_RECOMPUTE_PROPS
)
2559 /* Don't check for overlay strings below when set to deliver
2560 characters from a display vector. */
2561 if (it
->method
== next_element_from_display_vector
)
2562 handle_overlay_change_p
= 0;
2564 /* Handle overlay changes. */
2565 if (handle_overlay_change_p
)
2566 handled
= handle_overlay_change (it
);
2568 /* Determine where to stop next. */
2569 if (handled
== HANDLED_NORMALLY
)
2570 compute_stop_pos (it
);
2573 while (handled
== HANDLED_RECOMPUTE_PROPS
);
2577 /* Compute IT->stop_charpos from text property and overlay change
2578 information for IT's current position. */
2581 compute_stop_pos (it
)
2584 register INTERVAL iv
, next_iv
;
2585 Lisp_Object object
, limit
, position
;
2587 /* If nowhere else, stop at the end. */
2588 it
->stop_charpos
= it
->end_charpos
;
2590 if (STRINGP (it
->string
))
2592 /* Strings are usually short, so don't limit the search for
2594 object
= it
->string
;
2596 position
= make_number (IT_STRING_CHARPOS (*it
));
2602 /* If next overlay change is in front of the current stop pos
2603 (which is IT->end_charpos), stop there. Note: value of
2604 next_overlay_change is point-max if no overlay change
2606 charpos
= next_overlay_change (IT_CHARPOS (*it
));
2607 if (charpos
< it
->stop_charpos
)
2608 it
->stop_charpos
= charpos
;
2610 /* If showing the region, we have to stop at the region
2611 start or end because the face might change there. */
2612 if (it
->region_beg_charpos
> 0)
2614 if (IT_CHARPOS (*it
) < it
->region_beg_charpos
)
2615 it
->stop_charpos
= min (it
->stop_charpos
, it
->region_beg_charpos
);
2616 else if (IT_CHARPOS (*it
) < it
->region_end_charpos
)
2617 it
->stop_charpos
= min (it
->stop_charpos
, it
->region_end_charpos
);
2620 /* Set up variables for computing the stop position from text
2621 property changes. */
2622 XSETBUFFER (object
, current_buffer
);
2623 limit
= make_number (IT_CHARPOS (*it
) + TEXT_PROP_DISTANCE_LIMIT
);
2624 position
= make_number (IT_CHARPOS (*it
));
2628 /* Get the interval containing IT's position. Value is a null
2629 interval if there isn't such an interval. */
2630 iv
= validate_interval_range (object
, &position
, &position
, 0);
2631 if (!NULL_INTERVAL_P (iv
))
2633 Lisp_Object values_here
[LAST_PROP_IDX
];
2636 /* Get properties here. */
2637 for (p
= it_props
; p
->handler
; ++p
)
2638 values_here
[p
->idx
] = textget (iv
->plist
, *p
->name
);
2640 /* Look for an interval following iv that has different
2642 for (next_iv
= next_interval (iv
);
2643 (!NULL_INTERVAL_P (next_iv
)
2645 || XFASTINT (limit
) > next_iv
->position
));
2646 next_iv
= next_interval (next_iv
))
2648 for (p
= it_props
; p
->handler
; ++p
)
2650 Lisp_Object new_value
;
2652 new_value
= textget (next_iv
->plist
, *p
->name
);
2653 if (!EQ (values_here
[p
->idx
], new_value
))
2661 if (!NULL_INTERVAL_P (next_iv
))
2663 if (INTEGERP (limit
)
2664 && next_iv
->position
>= XFASTINT (limit
))
2665 /* No text property change up to limit. */
2666 it
->stop_charpos
= min (XFASTINT (limit
), it
->stop_charpos
);
2668 /* Text properties change in next_iv. */
2669 it
->stop_charpos
= min (it
->stop_charpos
, next_iv
->position
);
2673 xassert (STRINGP (it
->string
)
2674 || (it
->stop_charpos
>= BEGV
2675 && it
->stop_charpos
>= IT_CHARPOS (*it
)));
2679 /* Return the position of the next overlay change after POS in
2680 current_buffer. Value is point-max if no overlay change
2681 follows. This is like `next-overlay-change' but doesn't use
2685 next_overlay_change (pos
)
2690 Lisp_Object
*overlays
;
2694 /* Get all overlays at the given position. */
2696 overlays
= (Lisp_Object
*) alloca (len
* sizeof *overlays
);
2697 noverlays
= overlays_at (pos
, 0, &overlays
, &len
, &endpos
, NULL
, 1);
2698 if (noverlays
> len
)
2701 overlays
= (Lisp_Object
*) alloca (len
* sizeof *overlays
);
2702 noverlays
= overlays_at (pos
, 0, &overlays
, &len
, &endpos
, NULL
, 1);
2705 /* If any of these overlays ends before endpos,
2706 use its ending point instead. */
2707 for (i
= 0; i
< noverlays
; ++i
)
2712 oend
= OVERLAY_END (overlays
[i
]);
2713 oendpos
= OVERLAY_POSITION (oend
);
2714 endpos
= min (endpos
, oendpos
);
2722 /***********************************************************************
2724 ***********************************************************************/
2726 /* Handle changes in the `fontified' property of the current buffer by
2727 calling hook functions from Qfontification_functions to fontify
2730 static enum prop_handled
2731 handle_fontified_prop (it
)
2734 Lisp_Object prop
, pos
;
2735 enum prop_handled handled
= HANDLED_NORMALLY
;
2737 /* Get the value of the `fontified' property at IT's current buffer
2738 position. (The `fontified' property doesn't have a special
2739 meaning in strings.) If the value is nil, call functions from
2740 Qfontification_functions. */
2741 if (!STRINGP (it
->string
)
2743 && !NILP (Vfontification_functions
)
2744 && !NILP (Vrun_hooks
)
2745 && (pos
= make_number (IT_CHARPOS (*it
)),
2746 prop
= Fget_char_property (pos
, Qfontified
, Qnil
),
2749 int count
= SPECPDL_INDEX ();
2752 val
= Vfontification_functions
;
2753 specbind (Qfontification_functions
, Qnil
);
2755 if (!CONSP (val
) || EQ (XCAR (val
), Qlambda
))
2756 safe_call1 (val
, pos
);
2759 Lisp_Object globals
, fn
;
2760 struct gcpro gcpro1
, gcpro2
;
2763 GCPRO2 (val
, globals
);
2765 for (; CONSP (val
); val
= XCDR (val
))
2771 /* A value of t indicates this hook has a local
2772 binding; it means to run the global binding too.
2773 In a global value, t should not occur. If it
2774 does, we must ignore it to avoid an endless
2776 for (globals
= Fdefault_value (Qfontification_functions
);
2778 globals
= XCDR (globals
))
2780 fn
= XCAR (globals
);
2782 safe_call1 (fn
, pos
);
2786 safe_call1 (fn
, pos
);
2792 unbind_to (count
, Qnil
);
2794 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
2795 something. This avoids an endless loop if they failed to
2796 fontify the text for which reason ever. */
2797 if (!NILP (Fget_char_property (pos
, Qfontified
, Qnil
)))
2798 handled
= HANDLED_RECOMPUTE_PROPS
;
2806 /***********************************************************************
2808 ***********************************************************************/
2810 /* Set up iterator IT from face properties at its current position.
2811 Called from handle_stop. */
2813 static enum prop_handled
2814 handle_face_prop (it
)
2817 int new_face_id
, next_stop
;
2819 if (!STRINGP (it
->string
))
2822 = face_at_buffer_position (it
->w
,
2824 it
->region_beg_charpos
,
2825 it
->region_end_charpos
,
2828 + TEXT_PROP_DISTANCE_LIMIT
),
2831 /* Is this a start of a run of characters with box face?
2832 Caveat: this can be called for a freshly initialized
2833 iterator; face_id is -1 in this case. We know that the new
2834 face will not change until limit, i.e. if the new face has a
2835 box, all characters up to limit will have one. But, as
2836 usual, we don't know whether limit is really the end. */
2837 if (new_face_id
!= it
->face_id
)
2839 struct face
*new_face
= FACE_FROM_ID (it
->f
, new_face_id
);
2841 /* If new face has a box but old face has not, this is
2842 the start of a run of characters with box, i.e. it has
2843 a shadow on the left side. The value of face_id of the
2844 iterator will be -1 if this is the initial call that gets
2845 the face. In this case, we have to look in front of IT's
2846 position and see whether there is a face != new_face_id. */
2847 it
->start_of_box_run_p
2848 = (new_face
->box
!= FACE_NO_BOX
2849 && (it
->face_id
>= 0
2850 || IT_CHARPOS (*it
) == BEG
2851 || new_face_id
!= face_before_it_pos (it
)));
2852 it
->face_box_p
= new_face
->box
!= FACE_NO_BOX
;
2857 int base_face_id
, bufpos
;
2859 if (it
->current
.overlay_string_index
>= 0)
2860 bufpos
= IT_CHARPOS (*it
);
2864 /* For strings from a buffer, i.e. overlay strings or strings
2865 from a `display' property, use the face at IT's current
2866 buffer position as the base face to merge with, so that
2867 overlay strings appear in the same face as surrounding
2868 text, unless they specify their own faces. */
2869 base_face_id
= underlying_face_id (it
);
2871 new_face_id
= face_at_string_position (it
->w
,
2873 IT_STRING_CHARPOS (*it
),
2875 it
->region_beg_charpos
,
2876 it
->region_end_charpos
,
2880 #if 0 /* This shouldn't be neccessary. Let's check it. */
2881 /* If IT is used to display a mode line we would really like to
2882 use the mode line face instead of the frame's default face. */
2883 if (it
->glyph_row
== MATRIX_MODE_LINE_ROW (it
->w
->desired_matrix
)
2884 && new_face_id
== DEFAULT_FACE_ID
)
2885 new_face_id
= CURRENT_MODE_LINE_FACE_ID (it
->w
);
2888 /* Is this a start of a run of characters with box? Caveat:
2889 this can be called for a freshly allocated iterator; face_id
2890 is -1 is this case. We know that the new face will not
2891 change until the next check pos, i.e. if the new face has a
2892 box, all characters up to that position will have a
2893 box. But, as usual, we don't know whether that position
2894 is really the end. */
2895 if (new_face_id
!= it
->face_id
)
2897 struct face
*new_face
= FACE_FROM_ID (it
->f
, new_face_id
);
2898 struct face
*old_face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2900 /* If new face has a box but old face hasn't, this is the
2901 start of a run of characters with box, i.e. it has a
2902 shadow on the left side. */
2903 it
->start_of_box_run_p
2904 = new_face
->box
&& (old_face
== NULL
|| !old_face
->box
);
2905 it
->face_box_p
= new_face
->box
!= FACE_NO_BOX
;
2909 it
->face_id
= new_face_id
;
2910 return HANDLED_NORMALLY
;
2914 /* Return the ID of the face ``underlying'' IT's current position,
2915 which is in a string. If the iterator is associated with a
2916 buffer, return the face at IT's current buffer position.
2917 Otherwise, use the iterator's base_face_id. */
2920 underlying_face_id (it
)
2923 int face_id
= it
->base_face_id
, i
;
2925 xassert (STRINGP (it
->string
));
2927 for (i
= it
->sp
- 1; i
>= 0; --i
)
2928 if (NILP (it
->stack
[i
].string
))
2929 face_id
= it
->stack
[i
].face_id
;
2935 /* Compute the face one character before or after the current position
2936 of IT. BEFORE_P non-zero means get the face in front of IT's
2937 position. Value is the id of the face. */
2940 face_before_or_after_it_pos (it
, before_p
)
2945 int next_check_charpos
;
2946 struct text_pos pos
;
2948 xassert (it
->s
== NULL
);
2950 if (STRINGP (it
->string
))
2952 int bufpos
, base_face_id
;
2954 /* No face change past the end of the string (for the case
2955 we are padding with spaces). No face change before the
2957 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
)
2958 || (IT_STRING_CHARPOS (*it
) == 0 && before_p
))
2961 /* Set pos to the position before or after IT's current position. */
2963 pos
= string_pos (IT_STRING_CHARPOS (*it
) - 1, it
->string
);
2965 /* For composition, we must check the character after the
2967 pos
= (it
->what
== IT_COMPOSITION
2968 ? string_pos (IT_STRING_CHARPOS (*it
) + it
->cmp_len
, it
->string
)
2969 : string_pos (IT_STRING_CHARPOS (*it
) + 1, it
->string
));
2971 if (it
->current
.overlay_string_index
>= 0)
2972 bufpos
= IT_CHARPOS (*it
);
2976 base_face_id
= underlying_face_id (it
);
2978 /* Get the face for ASCII, or unibyte. */
2979 face_id
= face_at_string_position (it
->w
,
2983 it
->region_beg_charpos
,
2984 it
->region_end_charpos
,
2985 &next_check_charpos
,
2988 /* Correct the face for charsets different from ASCII. Do it
2989 for the multibyte case only. The face returned above is
2990 suitable for unibyte text if IT->string is unibyte. */
2991 if (STRING_MULTIBYTE (it
->string
))
2993 const unsigned char *p
= SDATA (it
->string
) + BYTEPOS (pos
);
2994 int rest
= SBYTES (it
->string
) - BYTEPOS (pos
);
2996 struct face
*face
= FACE_FROM_ID (it
->f
, face_id
);
2998 c
= string_char_and_length (p
, rest
, &len
);
2999 face_id
= FACE_FOR_CHAR (it
->f
, face
, c
);
3004 if ((IT_CHARPOS (*it
) >= ZV
&& !before_p
)
3005 || (IT_CHARPOS (*it
) <= BEGV
&& before_p
))
3008 limit
= IT_CHARPOS (*it
) + TEXT_PROP_DISTANCE_LIMIT
;
3009 pos
= it
->current
.pos
;
3012 DEC_TEXT_POS (pos
, it
->multibyte_p
);
3015 if (it
->what
== IT_COMPOSITION
)
3016 /* For composition, we must check the position after the
3018 pos
.charpos
+= it
->cmp_len
, pos
.bytepos
+= it
->len
;
3020 INC_TEXT_POS (pos
, it
->multibyte_p
);
3023 /* Determine face for CHARSET_ASCII, or unibyte. */
3024 face_id
= face_at_buffer_position (it
->w
,
3026 it
->region_beg_charpos
,
3027 it
->region_end_charpos
,
3028 &next_check_charpos
,
3031 /* Correct the face for charsets different from ASCII. Do it
3032 for the multibyte case only. The face returned above is
3033 suitable for unibyte text if current_buffer is unibyte. */
3034 if (it
->multibyte_p
)
3036 int c
= FETCH_MULTIBYTE_CHAR (BYTEPOS (pos
));
3037 struct face
*face
= FACE_FROM_ID (it
->f
, face_id
);
3038 face_id
= FACE_FOR_CHAR (it
->f
, face
, c
);
3047 /***********************************************************************
3049 ***********************************************************************/
3051 /* Set up iterator IT from invisible properties at its current
3052 position. Called from handle_stop. */
3054 static enum prop_handled
3055 handle_invisible_prop (it
)
3058 enum prop_handled handled
= HANDLED_NORMALLY
;
3060 if (STRINGP (it
->string
))
3062 extern Lisp_Object Qinvisible
;
3063 Lisp_Object prop
, end_charpos
, limit
, charpos
;
3065 /* Get the value of the invisible text property at the
3066 current position. Value will be nil if there is no such
3068 charpos
= make_number (IT_STRING_CHARPOS (*it
));
3069 prop
= Fget_text_property (charpos
, Qinvisible
, it
->string
);
3072 && IT_STRING_CHARPOS (*it
) < it
->end_charpos
)
3074 handled
= HANDLED_RECOMPUTE_PROPS
;
3076 /* Get the position at which the next change of the
3077 invisible text property can be found in IT->string.
3078 Value will be nil if the property value is the same for
3079 all the rest of IT->string. */
3080 XSETINT (limit
, SCHARS (it
->string
));
3081 end_charpos
= Fnext_single_property_change (charpos
, Qinvisible
,
3084 /* Text at current position is invisible. The next
3085 change in the property is at position end_charpos.
3086 Move IT's current position to that position. */
3087 if (INTEGERP (end_charpos
)
3088 && XFASTINT (end_charpos
) < XFASTINT (limit
))
3090 struct text_pos old
;
3091 old
= it
->current
.string_pos
;
3092 IT_STRING_CHARPOS (*it
) = XFASTINT (end_charpos
);
3093 compute_string_pos (&it
->current
.string_pos
, old
, it
->string
);
3097 /* The rest of the string is invisible. If this is an
3098 overlay string, proceed with the next overlay string
3099 or whatever comes and return a character from there. */
3100 if (it
->current
.overlay_string_index
>= 0)
3102 next_overlay_string (it
);
3103 /* Don't check for overlay strings when we just
3104 finished processing them. */
3105 handled
= HANDLED_OVERLAY_STRING_CONSUMED
;
3109 IT_STRING_CHARPOS (*it
) = SCHARS (it
->string
);
3110 IT_STRING_BYTEPOS (*it
) = SBYTES (it
->string
);
3117 int invis_p
, newpos
, next_stop
, start_charpos
;
3118 Lisp_Object pos
, prop
, overlay
;
3120 /* First of all, is there invisible text at this position? */
3121 start_charpos
= IT_CHARPOS (*it
);
3122 pos
= make_number (IT_CHARPOS (*it
));
3123 prop
= get_char_property_and_overlay (pos
, Qinvisible
, it
->window
,
3125 invis_p
= TEXT_PROP_MEANS_INVISIBLE (prop
);
3127 /* If we are on invisible text, skip over it. */
3128 if (invis_p
&& IT_CHARPOS (*it
) < it
->end_charpos
)
3130 /* Record whether we have to display an ellipsis for the
3132 int display_ellipsis_p
= invis_p
== 2;
3134 handled
= HANDLED_RECOMPUTE_PROPS
;
3136 /* Loop skipping over invisible text. The loop is left at
3137 ZV or with IT on the first char being visible again. */
3140 /* Try to skip some invisible text. Return value is the
3141 position reached which can be equal to IT's position
3142 if there is nothing invisible here. This skips both
3143 over invisible text properties and overlays with
3144 invisible property. */
3145 newpos
= skip_invisible (IT_CHARPOS (*it
),
3146 &next_stop
, ZV
, it
->window
);
3148 /* If we skipped nothing at all we weren't at invisible
3149 text in the first place. If everything to the end of
3150 the buffer was skipped, end the loop. */
3151 if (newpos
== IT_CHARPOS (*it
) || newpos
>= ZV
)
3155 /* We skipped some characters but not necessarily
3156 all there are. Check if we ended up on visible
3157 text. Fget_char_property returns the property of
3158 the char before the given position, i.e. if we
3159 get invis_p = 0, this means that the char at
3160 newpos is visible. */
3161 pos
= make_number (newpos
);
3162 prop
= Fget_char_property (pos
, Qinvisible
, it
->window
);
3163 invis_p
= TEXT_PROP_MEANS_INVISIBLE (prop
);
3166 /* If we ended up on invisible text, proceed to
3167 skip starting with next_stop. */
3169 IT_CHARPOS (*it
) = next_stop
;
3173 /* The position newpos is now either ZV or on visible text. */
3174 IT_CHARPOS (*it
) = newpos
;
3175 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (newpos
);
3177 /* If there are before-strings at the start of invisible
3178 text, and the text is invisible because of a text
3179 property, arrange to show before-strings because 20.x did
3180 it that way. (If the text is invisible because of an
3181 overlay property instead of a text property, this is
3182 already handled in the overlay code.) */
3184 && get_overlay_strings (it
, start_charpos
))
3186 handled
= HANDLED_RECOMPUTE_PROPS
;
3187 it
->stack
[it
->sp
- 1].display_ellipsis_p
= display_ellipsis_p
;
3189 else if (display_ellipsis_p
)
3190 setup_for_ellipsis (it
);
3198 /* Make iterator IT return `...' next. */
3201 setup_for_ellipsis (it
)
3205 && VECTORP (DISP_INVIS_VECTOR (it
->dp
)))
3207 struct Lisp_Vector
*v
= XVECTOR (DISP_INVIS_VECTOR (it
->dp
));
3208 it
->dpvec
= v
->contents
;
3209 it
->dpend
= v
->contents
+ v
->size
;
3213 /* Default `...'. */
3214 it
->dpvec
= default_invis_vector
;
3215 it
->dpend
= default_invis_vector
+ 3;
3218 /* The ellipsis display does not replace the display of the
3219 character at the new position. Indicate this by setting
3220 IT->dpvec_char_len to zero. */
3221 it
->dpvec_char_len
= 0;
3223 it
->current
.dpvec_index
= 0;
3224 it
->method
= next_element_from_display_vector
;
3229 /***********************************************************************
3231 ***********************************************************************/
3233 /* Set up iterator IT from `display' property at its current position.
3234 Called from handle_stop. */
3236 static enum prop_handled
3237 handle_display_prop (it
)
3240 Lisp_Object prop
, object
;
3241 struct text_pos
*position
;
3242 int display_replaced_p
= 0;
3244 if (STRINGP (it
->string
))
3246 object
= it
->string
;
3247 position
= &it
->current
.string_pos
;
3251 object
= it
->w
->buffer
;
3252 position
= &it
->current
.pos
;
3255 /* Reset those iterator values set from display property values. */
3256 it
->font_height
= Qnil
;
3257 it
->space_width
= Qnil
;
3260 /* We don't support recursive `display' properties, i.e. string
3261 values that have a string `display' property, that have a string
3262 `display' property etc. */
3263 if (!it
->string_from_display_prop_p
)
3264 it
->area
= TEXT_AREA
;
3266 prop
= Fget_char_property (make_number (position
->charpos
),
3269 return HANDLED_NORMALLY
;
3272 /* Simple properties. */
3273 && !EQ (XCAR (prop
), Qimage
)
3274 && !EQ (XCAR (prop
), Qspace
)
3275 && !EQ (XCAR (prop
), Qwhen
)
3276 && !EQ (XCAR (prop
), Qspace_width
)
3277 && !EQ (XCAR (prop
), Qheight
)
3278 && !EQ (XCAR (prop
), Qraise
)
3279 /* Marginal area specifications. */
3280 && !(CONSP (XCAR (prop
)) && EQ (XCAR (XCAR (prop
)), Qmargin
))
3281 && !EQ (XCAR (prop
), Qleft_fringe
)
3282 && !EQ (XCAR (prop
), Qright_fringe
)
3283 && !NILP (XCAR (prop
)))
3285 for (; CONSP (prop
); prop
= XCDR (prop
))
3287 if (handle_single_display_prop (it
, XCAR (prop
), object
,
3288 position
, display_replaced_p
))
3289 display_replaced_p
= 1;
3292 else if (VECTORP (prop
))
3295 for (i
= 0; i
< ASIZE (prop
); ++i
)
3296 if (handle_single_display_prop (it
, AREF (prop
, i
), object
,
3297 position
, display_replaced_p
))
3298 display_replaced_p
= 1;
3302 if (handle_single_display_prop (it
, prop
, object
, position
, 0))
3303 display_replaced_p
= 1;
3306 return display_replaced_p
? HANDLED_RETURN
: HANDLED_NORMALLY
;
3310 /* Value is the position of the end of the `display' property starting
3311 at START_POS in OBJECT. */
3313 static struct text_pos
3314 display_prop_end (it
, object
, start_pos
)
3317 struct text_pos start_pos
;
3320 struct text_pos end_pos
;
3322 end
= Fnext_single_char_property_change (make_number (CHARPOS (start_pos
)),
3323 Qdisplay
, object
, Qnil
);
3324 CHARPOS (end_pos
) = XFASTINT (end
);
3325 if (STRINGP (object
))
3326 compute_string_pos (&end_pos
, start_pos
, it
->string
);
3328 BYTEPOS (end_pos
) = CHAR_TO_BYTE (XFASTINT (end
));
3334 /* Set up IT from a single `display' sub-property value PROP. OBJECT
3335 is the object in which the `display' property was found. *POSITION
3336 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3337 means that we previously saw a display sub-property which already
3338 replaced text display with something else, for example an image;
3339 ignore such properties after the first one has been processed.
3341 If PROP is a `space' or `image' sub-property, set *POSITION to the
3342 end position of the `display' property.
3344 Value is non-zero if something was found which replaces the display
3345 of buffer or string text. */
3348 handle_single_display_prop (it
, prop
, object
, position
,
3349 display_replaced_before_p
)
3353 struct text_pos
*position
;
3354 int display_replaced_before_p
;
3357 int replaces_text_display_p
= 0;
3360 /* If PROP is a list of the form `(when FORM . VALUE)', FORM is
3361 evaluated. If the result is nil, VALUE is ignored. */
3363 if (CONSP (prop
) && EQ (XCAR (prop
), Qwhen
))
3372 if (!NILP (form
) && !EQ (form
, Qt
))
3374 int count
= SPECPDL_INDEX ();
3375 struct gcpro gcpro1
;
3377 /* Bind `object' to the object having the `display' property, a
3378 buffer or string. Bind `position' to the position in the
3379 object where the property was found, and `buffer-position'
3380 to the current position in the buffer. */
3381 specbind (Qobject
, object
);
3382 specbind (Qposition
, make_number (CHARPOS (*position
)));
3383 specbind (Qbuffer_position
,
3384 make_number (STRINGP (object
)
3385 ? IT_CHARPOS (*it
) : CHARPOS (*position
)));
3387 form
= safe_eval (form
);
3389 unbind_to (count
, Qnil
);
3396 && EQ (XCAR (prop
), Qheight
)
3397 && CONSP (XCDR (prop
)))
3399 if (FRAME_TERMCAP_P (it
->f
) || FRAME_MSDOS_P (it
->f
))
3402 /* `(height HEIGHT)'. */
3403 it
->font_height
= XCAR (XCDR (prop
));
3404 if (!NILP (it
->font_height
))
3406 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
3407 int new_height
= -1;
3409 if (CONSP (it
->font_height
)
3410 && (EQ (XCAR (it
->font_height
), Qplus
)
3411 || EQ (XCAR (it
->font_height
), Qminus
))
3412 && CONSP (XCDR (it
->font_height
))
3413 && INTEGERP (XCAR (XCDR (it
->font_height
))))
3415 /* `(+ N)' or `(- N)' where N is an integer. */
3416 int steps
= XINT (XCAR (XCDR (it
->font_height
)));
3417 if (EQ (XCAR (it
->font_height
), Qplus
))
3419 it
->face_id
= smaller_face (it
->f
, it
->face_id
, steps
);
3421 else if (FUNCTIONP (it
->font_height
))
3423 /* Call function with current height as argument.
3424 Value is the new height. */
3426 height
= safe_call1 (it
->font_height
,
3427 face
->lface
[LFACE_HEIGHT_INDEX
]);
3428 if (NUMBERP (height
))
3429 new_height
= XFLOATINT (height
);
3431 else if (NUMBERP (it
->font_height
))
3433 /* Value is a multiple of the canonical char height. */
3436 face
= FACE_FROM_ID (it
->f
, DEFAULT_FACE_ID
);
3437 new_height
= (XFLOATINT (it
->font_height
)
3438 * XINT (face
->lface
[LFACE_HEIGHT_INDEX
]));
3442 /* Evaluate IT->font_height with `height' bound to the
3443 current specified height to get the new height. */
3445 int count
= SPECPDL_INDEX ();
3447 specbind (Qheight
, face
->lface
[LFACE_HEIGHT_INDEX
]);
3448 value
= safe_eval (it
->font_height
);
3449 unbind_to (count
, Qnil
);
3451 if (NUMBERP (value
))
3452 new_height
= XFLOATINT (value
);
3456 it
->face_id
= face_with_height (it
->f
, it
->face_id
, new_height
);
3459 else if (CONSP (prop
)
3460 && EQ (XCAR (prop
), Qspace_width
)
3461 && CONSP (XCDR (prop
)))
3463 /* `(space_width WIDTH)'. */
3464 if (FRAME_TERMCAP_P (it
->f
) || FRAME_MSDOS_P (it
->f
))
3467 value
= XCAR (XCDR (prop
));
3468 if (NUMBERP (value
) && XFLOATINT (value
) > 0)
3469 it
->space_width
= value
;
3471 else if (CONSP (prop
)
3472 && EQ (XCAR (prop
), Qraise
)
3473 && CONSP (XCDR (prop
)))
3475 /* `(raise FACTOR)'. */
3476 if (FRAME_TERMCAP_P (it
->f
) || FRAME_MSDOS_P (it
->f
))
3479 #ifdef HAVE_WINDOW_SYSTEM
3480 value
= XCAR (XCDR (prop
));
3481 if (NUMBERP (value
))
3483 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
3484 it
->voffset
= - (XFLOATINT (value
)
3485 * (FONT_HEIGHT (face
->font
)));
3487 #endif /* HAVE_WINDOW_SYSTEM */
3489 else if (CONSP (prop
)
3490 && (EQ (XCAR (prop
), Qleft_fringe
)
3491 || EQ (XCAR (prop
), Qright_fringe
))
3492 && CONSP (XCDR (prop
)))
3494 unsigned face_id
= DEFAULT_FACE_ID
;
3496 /* `(left-fringe BITMAP FACE)'. */
3497 if (FRAME_TERMCAP_P (it
->f
) || FRAME_MSDOS_P (it
->f
))
3500 #ifdef HAVE_WINDOW_SYSTEM
3501 value
= XCAR (XCDR (prop
));
3502 if (!NUMBERP (value
)
3503 || !valid_fringe_bitmap_id_p (XINT (value
)))
3506 if (CONSP (XCDR (XCDR (prop
))))
3508 Lisp_Object face_name
= XCAR (XCDR (XCDR (prop
)));
3509 face_id
= lookup_named_face (it
->f
, face_name
, 'A');
3514 if (EQ (XCAR (prop
), Qleft_fringe
))
3516 it
->left_user_fringe_bitmap
= XINT (value
);
3517 it
->left_user_fringe_face_id
= face_id
;
3521 it
->right_user_fringe_bitmap
= XINT (value
);
3522 it
->right_user_fringe_face_id
= face_id
;
3524 #endif /* HAVE_WINDOW_SYSTEM */
3526 else if (!it
->string_from_display_prop_p
)
3528 /* `((margin left-margin) VALUE)' or `((margin right-margin)
3529 VALUE) or `((margin nil) VALUE)' or VALUE. */
3530 Lisp_Object location
, value
;
3531 struct text_pos start_pos
;
3534 /* Characters having this form of property are not displayed, so
3535 we have to find the end of the property. */
3536 start_pos
= *position
;
3537 *position
= display_prop_end (it
, object
, start_pos
);
3540 /* Let's stop at the new position and assume that all
3541 text properties change there. */
3542 it
->stop_charpos
= position
->charpos
;
3544 location
= Qunbound
;
3545 if (CONSP (prop
) && CONSP (XCAR (prop
)))
3549 value
= XCDR (prop
);
3551 value
= XCAR (value
);
3554 if (EQ (XCAR (tem
), Qmargin
)
3555 && (tem
= XCDR (tem
),
3556 tem
= CONSP (tem
) ? XCAR (tem
) : Qnil
,
3558 || EQ (tem
, Qleft_margin
)
3559 || EQ (tem
, Qright_margin
))))
3563 if (EQ (location
, Qunbound
))
3569 #ifdef HAVE_WINDOW_SYSTEM
3570 if (FRAME_TERMCAP_P (it
->f
))
3571 valid_p
= STRINGP (value
);
3573 valid_p
= (STRINGP (value
)
3574 || (CONSP (value
) && EQ (XCAR (value
), Qspace
))
3575 || valid_image_p (value
));
3576 #else /* not HAVE_WINDOW_SYSTEM */
3577 valid_p
= STRINGP (value
);
3578 #endif /* not HAVE_WINDOW_SYSTEM */
3580 if ((EQ (location
, Qleft_margin
)
3581 || EQ (location
, Qright_margin
)
3584 && !display_replaced_before_p
)
3586 replaces_text_display_p
= 1;
3588 /* Save current settings of IT so that we can restore them
3589 when we are finished with the glyph property value. */
3592 if (NILP (location
))
3593 it
->area
= TEXT_AREA
;
3594 else if (EQ (location
, Qleft_margin
))
3595 it
->area
= LEFT_MARGIN_AREA
;
3597 it
->area
= RIGHT_MARGIN_AREA
;
3599 if (STRINGP (value
))
3602 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
3603 it
->current
.overlay_string_index
= -1;
3604 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = 0;
3605 it
->end_charpos
= it
->string_nchars
= SCHARS (it
->string
);
3606 it
->method
= next_element_from_string
;
3607 it
->stop_charpos
= 0;
3608 it
->string_from_display_prop_p
= 1;
3609 /* Say that we haven't consumed the characters with
3610 `display' property yet. The call to pop_it in
3611 set_iterator_to_next will clean this up. */
3612 *position
= start_pos
;
3614 else if (CONSP (value
) && EQ (XCAR (value
), Qspace
))
3616 it
->method
= next_element_from_stretch
;
3618 it
->current
.pos
= it
->position
= start_pos
;
3620 #ifdef HAVE_WINDOW_SYSTEM
3623 it
->what
= IT_IMAGE
;
3624 it
->image_id
= lookup_image (it
->f
, value
);
3625 it
->position
= start_pos
;
3626 it
->object
= NILP (object
) ? it
->w
->buffer
: object
;
3627 it
->method
= next_element_from_image
;
3629 /* Say that we haven't consumed the characters with
3630 `display' property yet. The call to pop_it in
3631 set_iterator_to_next will clean this up. */
3632 *position
= start_pos
;
3634 #endif /* HAVE_WINDOW_SYSTEM */
3637 /* Invalid property or property not supported. Restore
3638 the position to what it was before. */
3639 *position
= start_pos
;
3642 return replaces_text_display_p
;
3646 /* Check if PROP is a display sub-property value whose text should be
3647 treated as intangible. */
3650 single_display_prop_intangible_p (prop
)
3653 /* Skip over `when FORM'. */
3654 if (CONSP (prop
) && EQ (XCAR (prop
), Qwhen
))
3668 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
3669 we don't need to treat text as intangible. */
3670 if (EQ (XCAR (prop
), Qmargin
))
3678 || EQ (XCAR (prop
), Qleft_margin
)
3679 || EQ (XCAR (prop
), Qright_margin
))
3683 return (CONSP (prop
)
3684 && (EQ (XCAR (prop
), Qimage
)
3685 || EQ (XCAR (prop
), Qspace
)));
3689 /* Check if PROP is a display property value whose text should be
3690 treated as intangible. */
3693 display_prop_intangible_p (prop
)
3697 && CONSP (XCAR (prop
))
3698 && !EQ (Qmargin
, XCAR (XCAR (prop
))))
3700 /* A list of sub-properties. */
3701 while (CONSP (prop
))
3703 if (single_display_prop_intangible_p (XCAR (prop
)))
3708 else if (VECTORP (prop
))
3710 /* A vector of sub-properties. */
3712 for (i
= 0; i
< ASIZE (prop
); ++i
)
3713 if (single_display_prop_intangible_p (AREF (prop
, i
)))
3717 return single_display_prop_intangible_p (prop
);
3723 /* Return 1 if PROP is a display sub-property value containing STRING. */
3726 single_display_prop_string_p (prop
, string
)
3727 Lisp_Object prop
, string
;
3729 if (EQ (string
, prop
))
3732 /* Skip over `when FORM'. */
3733 if (CONSP (prop
) && EQ (XCAR (prop
), Qwhen
))
3742 /* Skip over `margin LOCATION'. */
3743 if (EQ (XCAR (prop
), Qmargin
))
3754 return CONSP (prop
) && EQ (XCAR (prop
), string
);
3758 /* Return 1 if STRING appears in the `display' property PROP. */
3761 display_prop_string_p (prop
, string
)
3762 Lisp_Object prop
, string
;
3765 && CONSP (XCAR (prop
))
3766 && !EQ (Qmargin
, XCAR (XCAR (prop
))))
3768 /* A list of sub-properties. */
3769 while (CONSP (prop
))
3771 if (single_display_prop_string_p (XCAR (prop
), string
))
3776 else if (VECTORP (prop
))
3778 /* A vector of sub-properties. */
3780 for (i
= 0; i
< ASIZE (prop
); ++i
)
3781 if (single_display_prop_string_p (AREF (prop
, i
), string
))
3785 return single_display_prop_string_p (prop
, string
);
3791 /* Determine from which buffer position in W's buffer STRING comes
3792 from. AROUND_CHARPOS is an approximate position where it could
3793 be from. Value is the buffer position or 0 if it couldn't be
3796 W's buffer must be current.
3798 This function is necessary because we don't record buffer positions
3799 in glyphs generated from strings (to keep struct glyph small).
3800 This function may only use code that doesn't eval because it is
3801 called asynchronously from note_mouse_highlight. */
3804 string_buffer_position (w
, string
, around_charpos
)
3809 Lisp_Object limit
, prop
, pos
;
3810 const int MAX_DISTANCE
= 1000;
3813 pos
= make_number (around_charpos
);
3814 limit
= make_number (min (XINT (pos
) + MAX_DISTANCE
, ZV
));
3815 while (!found
&& !EQ (pos
, limit
))
3817 prop
= Fget_char_property (pos
, Qdisplay
, Qnil
);
3818 if (!NILP (prop
) && display_prop_string_p (prop
, string
))
3821 pos
= Fnext_single_char_property_change (pos
, Qdisplay
, Qnil
, limit
);
3826 pos
= make_number (around_charpos
);
3827 limit
= make_number (max (XINT (pos
) - MAX_DISTANCE
, BEGV
));
3828 while (!found
&& !EQ (pos
, limit
))
3830 prop
= Fget_char_property (pos
, Qdisplay
, Qnil
);
3831 if (!NILP (prop
) && display_prop_string_p (prop
, string
))
3834 pos
= Fprevious_single_char_property_change (pos
, Qdisplay
, Qnil
,
3839 return found
? XINT (pos
) : 0;
3844 /***********************************************************************
3845 `composition' property
3846 ***********************************************************************/
3848 /* Set up iterator IT from `composition' property at its current
3849 position. Called from handle_stop. */
3851 static enum prop_handled
3852 handle_composition_prop (it
)
3855 Lisp_Object prop
, string
;
3856 int pos
, pos_byte
, end
;
3857 enum prop_handled handled
= HANDLED_NORMALLY
;
3859 if (STRINGP (it
->string
))
3861 pos
= IT_STRING_CHARPOS (*it
);
3862 pos_byte
= IT_STRING_BYTEPOS (*it
);
3863 string
= it
->string
;
3867 pos
= IT_CHARPOS (*it
);
3868 pos_byte
= IT_BYTEPOS (*it
);
3872 /* If there's a valid composition and point is not inside of the
3873 composition (in the case that the composition is from the current
3874 buffer), draw a glyph composed from the composition components. */
3875 if (find_composition (pos
, -1, &pos
, &end
, &prop
, string
)
3876 && COMPOSITION_VALID_P (pos
, end
, prop
)
3877 && (STRINGP (it
->string
) || (PT
<= pos
|| PT
>= end
)))
3879 int id
= get_composition_id (pos
, pos_byte
, end
- pos
, prop
, string
);
3883 it
->method
= next_element_from_composition
;
3885 it
->cmp_len
= COMPOSITION_LENGTH (prop
);
3886 /* For a terminal, draw only the first character of the
3888 it
->c
= COMPOSITION_GLYPH (composition_table
[id
], 0);
3889 it
->len
= (STRINGP (it
->string
)
3890 ? string_char_to_byte (it
->string
, end
)
3891 : CHAR_TO_BYTE (end
)) - pos_byte
;
3892 it
->stop_charpos
= end
;
3893 handled
= HANDLED_RETURN
;
3902 /***********************************************************************
3904 ***********************************************************************/
3906 /* The following structure is used to record overlay strings for
3907 later sorting in load_overlay_strings. */
3909 struct overlay_entry
3911 Lisp_Object overlay
;
3918 /* Set up iterator IT from overlay strings at its current position.
3919 Called from handle_stop. */
3921 static enum prop_handled
3922 handle_overlay_change (it
)
3925 if (!STRINGP (it
->string
) && get_overlay_strings (it
, 0))
3926 return HANDLED_RECOMPUTE_PROPS
;
3928 return HANDLED_NORMALLY
;
3932 /* Set up the next overlay string for delivery by IT, if there is an
3933 overlay string to deliver. Called by set_iterator_to_next when the
3934 end of the current overlay string is reached. If there are more
3935 overlay strings to display, IT->string and
3936 IT->current.overlay_string_index are set appropriately here.
3937 Otherwise IT->string is set to nil. */
3940 next_overlay_string (it
)
3943 ++it
->current
.overlay_string_index
;
3944 if (it
->current
.overlay_string_index
== it
->n_overlay_strings
)
3946 /* No more overlay strings. Restore IT's settings to what
3947 they were before overlay strings were processed, and
3948 continue to deliver from current_buffer. */
3949 int display_ellipsis_p
= it
->stack
[it
->sp
- 1].display_ellipsis_p
;
3952 xassert (it
->stop_charpos
>= BEGV
3953 && it
->stop_charpos
<= it
->end_charpos
);
3955 it
->current
.overlay_string_index
= -1;
3956 SET_TEXT_POS (it
->current
.string_pos
, -1, -1);
3957 it
->n_overlay_strings
= 0;
3958 it
->method
= next_element_from_buffer
;
3960 /* If we're at the end of the buffer, record that we have
3961 processed the overlay strings there already, so that
3962 next_element_from_buffer doesn't try it again. */
3963 if (IT_CHARPOS (*it
) >= it
->end_charpos
)
3964 it
->overlay_strings_at_end_processed_p
= 1;
3966 /* If we have to display `...' for invisible text, set
3967 the iterator up for that. */
3968 if (display_ellipsis_p
)
3969 setup_for_ellipsis (it
);
3973 /* There are more overlay strings to process. If
3974 IT->current.overlay_string_index has advanced to a position
3975 where we must load IT->overlay_strings with more strings, do
3977 int i
= it
->current
.overlay_string_index
% OVERLAY_STRING_CHUNK_SIZE
;
3979 if (it
->current
.overlay_string_index
&& i
== 0)
3980 load_overlay_strings (it
, 0);
3982 /* Initialize IT to deliver display elements from the overlay
3984 it
->string
= it
->overlay_strings
[i
];
3985 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
3986 SET_TEXT_POS (it
->current
.string_pos
, 0, 0);
3987 it
->method
= next_element_from_string
;
3988 it
->stop_charpos
= 0;
3995 /* Compare two overlay_entry structures E1 and E2. Used as a
3996 comparison function for qsort in load_overlay_strings. Overlay
3997 strings for the same position are sorted so that
3999 1. All after-strings come in front of before-strings, except
4000 when they come from the same overlay.
4002 2. Within after-strings, strings are sorted so that overlay strings
4003 from overlays with higher priorities come first.
4005 2. Within before-strings, strings are sorted so that overlay
4006 strings from overlays with higher priorities come last.
4008 Value is analogous to strcmp. */
4012 compare_overlay_entries (e1
, e2
)
4015 struct overlay_entry
*entry1
= (struct overlay_entry
*) e1
;
4016 struct overlay_entry
*entry2
= (struct overlay_entry
*) e2
;
4019 if (entry1
->after_string_p
!= entry2
->after_string_p
)
4021 /* Let after-strings appear in front of before-strings if
4022 they come from different overlays. */
4023 if (EQ (entry1
->overlay
, entry2
->overlay
))
4024 result
= entry1
->after_string_p
? 1 : -1;
4026 result
= entry1
->after_string_p
? -1 : 1;
4028 else if (entry1
->after_string_p
)
4029 /* After-strings sorted in order of decreasing priority. */
4030 result
= entry2
->priority
- entry1
->priority
;
4032 /* Before-strings sorted in order of increasing priority. */
4033 result
= entry1
->priority
- entry2
->priority
;
4039 /* Load the vector IT->overlay_strings with overlay strings from IT's
4040 current buffer position, or from CHARPOS if that is > 0. Set
4041 IT->n_overlays to the total number of overlay strings found.
4043 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4044 a time. On entry into load_overlay_strings,
4045 IT->current.overlay_string_index gives the number of overlay
4046 strings that have already been loaded by previous calls to this
4049 IT->add_overlay_start contains an additional overlay start
4050 position to consider for taking overlay strings from, if non-zero.
4051 This position comes into play when the overlay has an `invisible'
4052 property, and both before and after-strings. When we've skipped to
4053 the end of the overlay, because of its `invisible' property, we
4054 nevertheless want its before-string to appear.
4055 IT->add_overlay_start will contain the overlay start position
4058 Overlay strings are sorted so that after-string strings come in
4059 front of before-string strings. Within before and after-strings,
4060 strings are sorted by overlay priority. See also function
4061 compare_overlay_entries. */
4064 load_overlay_strings (it
, charpos
)
4068 extern Lisp_Object Qafter_string
, Qbefore_string
, Qwindow
, Qpriority
;
4069 Lisp_Object overlay
, window
, str
, invisible
;
4070 struct Lisp_Overlay
*ov
;
4073 int n
= 0, i
, j
, invis_p
;
4074 struct overlay_entry
*entries
4075 = (struct overlay_entry
*) alloca (size
* sizeof *entries
);
4078 charpos
= IT_CHARPOS (*it
);
4080 /* Append the overlay string STRING of overlay OVERLAY to vector
4081 `entries' which has size `size' and currently contains `n'
4082 elements. AFTER_P non-zero means STRING is an after-string of
4084 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4087 Lisp_Object priority; \
4091 int new_size = 2 * size; \
4092 struct overlay_entry *old = entries; \
4094 (struct overlay_entry *) alloca (new_size \
4095 * sizeof *entries); \
4096 bcopy (old, entries, size * sizeof *entries); \
4100 entries[n].string = (STRING); \
4101 entries[n].overlay = (OVERLAY); \
4102 priority = Foverlay_get ((OVERLAY), Qpriority); \
4103 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4104 entries[n].after_string_p = (AFTER_P); \
4109 /* Process overlay before the overlay center. */
4110 for (ov
= current_buffer
->overlays_before
; ov
; ov
= ov
->next
)
4112 XSETMISC (overlay
, ov
);
4113 xassert (OVERLAYP (overlay
));
4114 start
= OVERLAY_POSITION (OVERLAY_START (overlay
));
4115 end
= OVERLAY_POSITION (OVERLAY_END (overlay
));
4120 /* Skip this overlay if it doesn't start or end at IT's current
4122 if (end
!= charpos
&& start
!= charpos
)
4125 /* Skip this overlay if it doesn't apply to IT->w. */
4126 window
= Foverlay_get (overlay
, Qwindow
);
4127 if (WINDOWP (window
) && XWINDOW (window
) != it
->w
)
4130 /* If the text ``under'' the overlay is invisible, both before-
4131 and after-strings from this overlay are visible; start and
4132 end position are indistinguishable. */
4133 invisible
= Foverlay_get (overlay
, Qinvisible
);
4134 invis_p
= TEXT_PROP_MEANS_INVISIBLE (invisible
);
4136 /* If overlay has a non-empty before-string, record it. */
4137 if ((start
== charpos
|| (end
== charpos
&& invis_p
))
4138 && (str
= Foverlay_get (overlay
, Qbefore_string
), STRINGP (str
))
4140 RECORD_OVERLAY_STRING (overlay
, str
, 0);
4142 /* If overlay has a non-empty after-string, record it. */
4143 if ((end
== charpos
|| (start
== charpos
&& invis_p
))
4144 && (str
= Foverlay_get (overlay
, Qafter_string
), STRINGP (str
))
4146 RECORD_OVERLAY_STRING (overlay
, str
, 1);
4149 /* Process overlays after the overlay center. */
4150 for (ov
= current_buffer
->overlays_after
; ov
; ov
= ov
->next
)
4152 XSETMISC (overlay
, ov
);
4153 xassert (OVERLAYP (overlay
));
4154 start
= OVERLAY_POSITION (OVERLAY_START (overlay
));
4155 end
= OVERLAY_POSITION (OVERLAY_END (overlay
));
4157 if (start
> charpos
)
4160 /* Skip this overlay if it doesn't start or end at IT's current
4162 if (end
!= charpos
&& start
!= charpos
)
4165 /* Skip this overlay if it doesn't apply to IT->w. */
4166 window
= Foverlay_get (overlay
, Qwindow
);
4167 if (WINDOWP (window
) && XWINDOW (window
) != it
->w
)
4170 /* If the text ``under'' the overlay is invisible, it has a zero
4171 dimension, and both before- and after-strings apply. */
4172 invisible
= Foverlay_get (overlay
, Qinvisible
);
4173 invis_p
= TEXT_PROP_MEANS_INVISIBLE (invisible
);
4175 /* If overlay has a non-empty before-string, record it. */
4176 if ((start
== charpos
|| (end
== charpos
&& invis_p
))
4177 && (str
= Foverlay_get (overlay
, Qbefore_string
), STRINGP (str
))
4179 RECORD_OVERLAY_STRING (overlay
, str
, 0);
4181 /* If overlay has a non-empty after-string, record it. */
4182 if ((end
== charpos
|| (start
== charpos
&& invis_p
))
4183 && (str
= Foverlay_get (overlay
, Qafter_string
), STRINGP (str
))
4185 RECORD_OVERLAY_STRING (overlay
, str
, 1);
4188 #undef RECORD_OVERLAY_STRING
4192 qsort (entries
, n
, sizeof *entries
, compare_overlay_entries
);
4194 /* Record the total number of strings to process. */
4195 it
->n_overlay_strings
= n
;
4197 /* IT->current.overlay_string_index is the number of overlay strings
4198 that have already been consumed by IT. Copy some of the
4199 remaining overlay strings to IT->overlay_strings. */
4201 j
= it
->current
.overlay_string_index
;
4202 while (i
< OVERLAY_STRING_CHUNK_SIZE
&& j
< n
)
4203 it
->overlay_strings
[i
++] = entries
[j
++].string
;
4209 /* Get the first chunk of overlay strings at IT's current buffer
4210 position, or at CHARPOS if that is > 0. Value is non-zero if at
4211 least one overlay string was found. */
4214 get_overlay_strings (it
, charpos
)
4218 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4219 process. This fills IT->overlay_strings with strings, and sets
4220 IT->n_overlay_strings to the total number of strings to process.
4221 IT->pos.overlay_string_index has to be set temporarily to zero
4222 because load_overlay_strings needs this; it must be set to -1
4223 when no overlay strings are found because a zero value would
4224 indicate a position in the first overlay string. */
4225 it
->current
.overlay_string_index
= 0;
4226 load_overlay_strings (it
, charpos
);
4228 /* If we found overlay strings, set up IT to deliver display
4229 elements from the first one. Otherwise set up IT to deliver
4230 from current_buffer. */
4231 if (it
->n_overlay_strings
)
4233 /* Make sure we know settings in current_buffer, so that we can
4234 restore meaningful values when we're done with the overlay
4236 compute_stop_pos (it
);
4237 xassert (it
->face_id
>= 0);
4239 /* Save IT's settings. They are restored after all overlay
4240 strings have been processed. */
4241 xassert (it
->sp
== 0);
4244 /* Set up IT to deliver display elements from the first overlay
4246 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = 0;
4247 it
->string
= it
->overlay_strings
[0];
4248 it
->stop_charpos
= 0;
4249 xassert (STRINGP (it
->string
));
4250 it
->end_charpos
= SCHARS (it
->string
);
4251 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
4252 it
->method
= next_element_from_string
;
4257 it
->current
.overlay_string_index
= -1;
4258 it
->method
= next_element_from_buffer
;
4263 /* Value is non-zero if we found at least one overlay string. */
4264 return STRINGP (it
->string
);
4269 /***********************************************************************
4270 Saving and restoring state
4271 ***********************************************************************/
4273 /* Save current settings of IT on IT->stack. Called, for example,
4274 before setting up IT for an overlay string, to be able to restore
4275 IT's settings to what they were after the overlay string has been
4282 struct iterator_stack_entry
*p
;
4284 xassert (it
->sp
< 2);
4285 p
= it
->stack
+ it
->sp
;
4287 p
->stop_charpos
= it
->stop_charpos
;
4288 xassert (it
->face_id
>= 0);
4289 p
->face_id
= it
->face_id
;
4290 p
->string
= it
->string
;
4291 p
->pos
= it
->current
;
4292 p
->end_charpos
= it
->end_charpos
;
4293 p
->string_nchars
= it
->string_nchars
;
4295 p
->multibyte_p
= it
->multibyte_p
;
4296 p
->space_width
= it
->space_width
;
4297 p
->font_height
= it
->font_height
;
4298 p
->voffset
= it
->voffset
;
4299 p
->string_from_display_prop_p
= it
->string_from_display_prop_p
;
4300 p
->display_ellipsis_p
= 0;
4305 /* Restore IT's settings from IT->stack. Called, for example, when no
4306 more overlay strings must be processed, and we return to delivering
4307 display elements from a buffer, or when the end of a string from a
4308 `display' property is reached and we return to delivering display
4309 elements from an overlay string, or from a buffer. */
4315 struct iterator_stack_entry
*p
;
4317 xassert (it
->sp
> 0);
4319 p
= it
->stack
+ it
->sp
;
4320 it
->stop_charpos
= p
->stop_charpos
;
4321 it
->face_id
= p
->face_id
;
4322 it
->string
= p
->string
;
4323 it
->current
= p
->pos
;
4324 it
->end_charpos
= p
->end_charpos
;
4325 it
->string_nchars
= p
->string_nchars
;
4327 it
->multibyte_p
= p
->multibyte_p
;
4328 it
->space_width
= p
->space_width
;
4329 it
->font_height
= p
->font_height
;
4330 it
->voffset
= p
->voffset
;
4331 it
->string_from_display_prop_p
= p
->string_from_display_prop_p
;
4336 /***********************************************************************
4338 ***********************************************************************/
4340 /* Set IT's current position to the previous line start. */
4343 back_to_previous_line_start (it
)
4346 IT_CHARPOS (*it
) = find_next_newline_no_quit (IT_CHARPOS (*it
) - 1, -1);
4347 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (IT_CHARPOS (*it
));
4351 /* Move IT to the next line start.
4353 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
4354 we skipped over part of the text (as opposed to moving the iterator
4355 continuously over the text). Otherwise, don't change the value
4358 Newlines may come from buffer text, overlay strings, or strings
4359 displayed via the `display' property. That's the reason we can't
4360 simply use find_next_newline_no_quit.
4362 Note that this function may not skip over invisible text that is so
4363 because of text properties and immediately follows a newline. If
4364 it would, function reseat_at_next_visible_line_start, when called
4365 from set_iterator_to_next, would effectively make invisible
4366 characters following a newline part of the wrong glyph row, which
4367 leads to wrong cursor motion. */
4370 forward_to_next_line_start (it
, skipped_p
)
4374 int old_selective
, newline_found_p
, n
;
4375 const int MAX_NEWLINE_DISTANCE
= 500;
4377 /* If already on a newline, just consume it to avoid unintended
4378 skipping over invisible text below. */
4379 if (it
->what
== IT_CHARACTER
4381 && CHARPOS (it
->position
) == IT_CHARPOS (*it
))
4383 set_iterator_to_next (it
, 0);
4388 /* Don't handle selective display in the following. It's (a)
4389 unnecessary because it's done by the caller, and (b) leads to an
4390 infinite recursion because next_element_from_ellipsis indirectly
4391 calls this function. */
4392 old_selective
= it
->selective
;
4395 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
4396 from buffer text. */
4397 for (n
= newline_found_p
= 0;
4398 !newline_found_p
&& n
< MAX_NEWLINE_DISTANCE
;
4399 n
+= STRINGP (it
->string
) ? 0 : 1)
4401 if (!get_next_display_element (it
))
4403 newline_found_p
= it
->what
== IT_CHARACTER
&& it
->c
== '\n';
4404 set_iterator_to_next (it
, 0);
4407 /* If we didn't find a newline near enough, see if we can use a
4409 if (!newline_found_p
)
4411 int start
= IT_CHARPOS (*it
);
4412 int limit
= find_next_newline_no_quit (start
, 1);
4415 xassert (!STRINGP (it
->string
));
4417 /* If there isn't any `display' property in sight, and no
4418 overlays, we can just use the position of the newline in
4420 if (it
->stop_charpos
>= limit
4421 || ((pos
= Fnext_single_property_change (make_number (start
),
4423 Qnil
, make_number (limit
)),
4425 && next_overlay_change (start
) == ZV
))
4427 IT_CHARPOS (*it
) = limit
;
4428 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (limit
);
4429 *skipped_p
= newline_found_p
= 1;
4433 while (get_next_display_element (it
)
4434 && !newline_found_p
)
4436 newline_found_p
= ITERATOR_AT_END_OF_LINE_P (it
);
4437 set_iterator_to_next (it
, 0);
4442 it
->selective
= old_selective
;
4443 return newline_found_p
;
4447 /* Set IT's current position to the previous visible line start. Skip
4448 invisible text that is so either due to text properties or due to
4449 selective display. Caution: this does not change IT->current_x and
4453 back_to_previous_visible_line_start (it
)
4458 /* Go back one newline if not on BEGV already. */
4459 if (IT_CHARPOS (*it
) > BEGV
)
4460 back_to_previous_line_start (it
);
4462 /* Move over lines that are invisible because of selective display
4463 or text properties. */
4464 while (IT_CHARPOS (*it
) > BEGV
4469 /* If selective > 0, then lines indented more than that values
4471 if (it
->selective
> 0
4472 && indented_beyond_p (IT_CHARPOS (*it
), IT_BYTEPOS (*it
),
4473 (double) it
->selective
)) /* iftc */
4479 prop
= Fget_char_property (make_number (IT_CHARPOS (*it
)),
4480 Qinvisible
, it
->window
);
4481 if (TEXT_PROP_MEANS_INVISIBLE (prop
))
4485 /* Back one more newline if the current one is invisible. */
4487 back_to_previous_line_start (it
);
4490 xassert (IT_CHARPOS (*it
) >= BEGV
);
4491 xassert (IT_CHARPOS (*it
) == BEGV
4492 || FETCH_BYTE (IT_BYTEPOS (*it
) - 1) == '\n');
4497 /* Reseat iterator IT at the previous visible line start. Skip
4498 invisible text that is so either due to text properties or due to
4499 selective display. At the end, update IT's overlay information,
4500 face information etc. */
4503 reseat_at_previous_visible_line_start (it
)
4506 back_to_previous_visible_line_start (it
);
4507 reseat (it
, it
->current
.pos
, 1);
4512 /* Reseat iterator IT on the next visible line start in the current
4513 buffer. ON_NEWLINE_P non-zero means position IT on the newline
4514 preceding the line start. Skip over invisible text that is so
4515 because of selective display. Compute faces, overlays etc at the
4516 new position. Note that this function does not skip over text that
4517 is invisible because of text properties. */
4520 reseat_at_next_visible_line_start (it
, on_newline_p
)
4524 int newline_found_p
, skipped_p
= 0;
4526 newline_found_p
= forward_to_next_line_start (it
, &skipped_p
);
4528 /* Skip over lines that are invisible because they are indented
4529 more than the value of IT->selective. */
4530 if (it
->selective
> 0)
4531 while (IT_CHARPOS (*it
) < ZV
4532 && indented_beyond_p (IT_CHARPOS (*it
), IT_BYTEPOS (*it
),
4533 (double) it
->selective
)) /* iftc */
4535 xassert (FETCH_BYTE (IT_BYTEPOS (*it
) - 1) == '\n');
4536 newline_found_p
= forward_to_next_line_start (it
, &skipped_p
);
4539 /* Position on the newline if that's what's requested. */
4540 if (on_newline_p
&& newline_found_p
)
4542 if (STRINGP (it
->string
))
4544 if (IT_STRING_CHARPOS (*it
) > 0)
4546 --IT_STRING_CHARPOS (*it
);
4547 --IT_STRING_BYTEPOS (*it
);
4550 else if (IT_CHARPOS (*it
) > BEGV
)
4554 reseat (it
, it
->current
.pos
, 0);
4558 reseat (it
, it
->current
.pos
, 0);
4565 /***********************************************************************
4566 Changing an iterator's position
4567 ***********************************************************************/
4569 /* Change IT's current position to POS in current_buffer. If FORCE_P
4570 is non-zero, always check for text properties at the new position.
4571 Otherwise, text properties are only looked up if POS >=
4572 IT->check_charpos of a property. */
4575 reseat (it
, pos
, force_p
)
4577 struct text_pos pos
;
4580 int original_pos
= IT_CHARPOS (*it
);
4582 reseat_1 (it
, pos
, 0);
4584 /* Determine where to check text properties. Avoid doing it
4585 where possible because text property lookup is very expensive. */
4587 || CHARPOS (pos
) > it
->stop_charpos
4588 || CHARPOS (pos
) < original_pos
)
4595 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
4596 IT->stop_pos to POS, also. */
4599 reseat_1 (it
, pos
, set_stop_p
)
4601 struct text_pos pos
;
4604 /* Don't call this function when scanning a C string. */
4605 xassert (it
->s
== NULL
);
4607 /* POS must be a reasonable value. */
4608 xassert (CHARPOS (pos
) >= BEGV
&& CHARPOS (pos
) <= ZV
);
4610 it
->current
.pos
= it
->position
= pos
;
4611 XSETBUFFER (it
->object
, current_buffer
);
4612 it
->end_charpos
= ZV
;
4614 it
->current
.dpvec_index
= -1;
4615 it
->current
.overlay_string_index
= -1;
4616 IT_STRING_CHARPOS (*it
) = -1;
4617 IT_STRING_BYTEPOS (*it
) = -1;
4619 it
->method
= next_element_from_buffer
;
4620 /* RMS: I added this to fix a bug in move_it_vertically_backward
4621 where it->area continued to relate to the starting point
4622 for the backward motion. Bug report from
4623 Nick Roberts <nick@nick.uklinux.net> on 19 May 2003.
4624 However, I am not sure whether reseat still does the right thing
4625 in general after this change. */
4626 it
->area
= TEXT_AREA
;
4627 it
->multibyte_p
= !NILP (current_buffer
->enable_multibyte_characters
);
4629 it
->face_before_selective_p
= 0;
4632 it
->stop_charpos
= CHARPOS (pos
);
4636 /* Set up IT for displaying a string, starting at CHARPOS in window W.
4637 If S is non-null, it is a C string to iterate over. Otherwise,
4638 STRING gives a Lisp string to iterate over.
4640 If PRECISION > 0, don't return more then PRECISION number of
4641 characters from the string.
4643 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
4644 characters have been returned. FIELD_WIDTH < 0 means an infinite
4647 MULTIBYTE = 0 means disable processing of multibyte characters,
4648 MULTIBYTE > 0 means enable it,
4649 MULTIBYTE < 0 means use IT->multibyte_p.
4651 IT must be initialized via a prior call to init_iterator before
4652 calling this function. */
4655 reseat_to_string (it
, s
, string
, charpos
, precision
, field_width
, multibyte
)
4660 int precision
, field_width
, multibyte
;
4662 /* No region in strings. */
4663 it
->region_beg_charpos
= it
->region_end_charpos
= -1;
4665 /* No text property checks performed by default, but see below. */
4666 it
->stop_charpos
= -1;
4668 /* Set iterator position and end position. */
4669 bzero (&it
->current
, sizeof it
->current
);
4670 it
->current
.overlay_string_index
= -1;
4671 it
->current
.dpvec_index
= -1;
4672 xassert (charpos
>= 0);
4674 /* If STRING is specified, use its multibyteness, otherwise use the
4675 setting of MULTIBYTE, if specified. */
4677 it
->multibyte_p
= multibyte
> 0;
4681 xassert (STRINGP (string
));
4682 it
->string
= string
;
4684 it
->end_charpos
= it
->string_nchars
= SCHARS (string
);
4685 it
->method
= next_element_from_string
;
4686 it
->current
.string_pos
= string_pos (charpos
, string
);
4693 /* Note that we use IT->current.pos, not it->current.string_pos,
4694 for displaying C strings. */
4695 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = -1;
4696 if (it
->multibyte_p
)
4698 it
->current
.pos
= c_string_pos (charpos
, s
, 1);
4699 it
->end_charpos
= it
->string_nchars
= number_of_chars (s
, 1);
4703 IT_CHARPOS (*it
) = IT_BYTEPOS (*it
) = charpos
;
4704 it
->end_charpos
= it
->string_nchars
= strlen (s
);
4707 it
->method
= next_element_from_c_string
;
4710 /* PRECISION > 0 means don't return more than PRECISION characters
4712 if (precision
> 0 && it
->end_charpos
- charpos
> precision
)
4713 it
->end_charpos
= it
->string_nchars
= charpos
+ precision
;
4715 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
4716 characters have been returned. FIELD_WIDTH == 0 means don't pad,
4717 FIELD_WIDTH < 0 means infinite field width. This is useful for
4718 padding with `-' at the end of a mode line. */
4719 if (field_width
< 0)
4720 field_width
= INFINITY
;
4721 if (field_width
> it
->end_charpos
- charpos
)
4722 it
->end_charpos
= charpos
+ field_width
;
4724 /* Use the standard display table for displaying strings. */
4725 if (DISP_TABLE_P (Vstandard_display_table
))
4726 it
->dp
= XCHAR_TABLE (Vstandard_display_table
);
4728 it
->stop_charpos
= charpos
;
4734 /***********************************************************************
4736 ***********************************************************************/
4738 /* Load IT's display element fields with information about the next
4739 display element from the current position of IT. Value is zero if
4740 end of buffer (or C string) is reached. */
4743 get_next_display_element (it
)
4746 /* Non-zero means that we found a display element. Zero means that
4747 we hit the end of what we iterate over. Performance note: the
4748 function pointer `method' used here turns out to be faster than
4749 using a sequence of if-statements. */
4750 int success_p
= (*it
->method
) (it
);
4752 if (it
->what
== IT_CHARACTER
)
4754 /* Map via display table or translate control characters.
4755 IT->c, IT->len etc. have been set to the next character by
4756 the function call above. If we have a display table, and it
4757 contains an entry for IT->c, translate it. Don't do this if
4758 IT->c itself comes from a display table, otherwise we could
4759 end up in an infinite recursion. (An alternative could be to
4760 count the recursion depth of this function and signal an
4761 error when a certain maximum depth is reached.) Is it worth
4763 if (success_p
&& it
->dpvec
== NULL
)
4768 && (dv
= DISP_CHAR_VECTOR (it
->dp
, it
->c
),
4771 struct Lisp_Vector
*v
= XVECTOR (dv
);
4773 /* Return the first character from the display table
4774 entry, if not empty. If empty, don't display the
4775 current character. */
4778 it
->dpvec_char_len
= it
->len
;
4779 it
->dpvec
= v
->contents
;
4780 it
->dpend
= v
->contents
+ v
->size
;
4781 it
->current
.dpvec_index
= 0;
4782 it
->method
= next_element_from_display_vector
;
4783 success_p
= get_next_display_element (it
);
4787 set_iterator_to_next (it
, 0);
4788 success_p
= get_next_display_element (it
);
4792 /* Translate control characters into `\003' or `^C' form.
4793 Control characters coming from a display table entry are
4794 currently not translated because we use IT->dpvec to hold
4795 the translation. This could easily be changed but I
4796 don't believe that it is worth doing.
4798 If it->multibyte_p is nonzero, eight-bit characters and
4799 non-printable multibyte characters are also translated to
4802 If it->multibyte_p is zero, eight-bit characters that
4803 don't have corresponding multibyte char code are also
4804 translated to octal form. */
4805 else if ((it
->c
< ' '
4806 && (it
->area
!= TEXT_AREA
4807 || (it
->c
!= '\n' && it
->c
!= '\t')))
4811 || !CHAR_PRINTABLE_P (it
->c
))
4813 && it
->c
== unibyte_char_to_multibyte (it
->c
))))
4815 /* IT->c is a control character which must be displayed
4816 either as '\003' or as `^C' where the '\\' and '^'
4817 can be defined in the display table. Fill
4818 IT->ctl_chars with glyphs for what we have to
4819 display. Then, set IT->dpvec to these glyphs. */
4822 if (it
->c
< 128 && it
->ctl_arrow_p
)
4824 /* Set IT->ctl_chars[0] to the glyph for `^'. */
4826 && INTEGERP (DISP_CTRL_GLYPH (it
->dp
))
4827 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it
->dp
))))
4828 g
= XINT (DISP_CTRL_GLYPH (it
->dp
));
4830 g
= FAST_MAKE_GLYPH ('^', 0);
4831 XSETINT (it
->ctl_chars
[0], g
);
4833 g
= FAST_MAKE_GLYPH (it
->c
^ 0100, 0);
4834 XSETINT (it
->ctl_chars
[1], g
);
4836 /* Set up IT->dpvec and return first character from it. */
4837 it
->dpvec_char_len
= it
->len
;
4838 it
->dpvec
= it
->ctl_chars
;
4839 it
->dpend
= it
->dpvec
+ 2;
4840 it
->current
.dpvec_index
= 0;
4841 it
->method
= next_element_from_display_vector
;
4842 get_next_display_element (it
);
4846 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
4851 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
4853 && INTEGERP (DISP_ESCAPE_GLYPH (it
->dp
))
4854 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it
->dp
))))
4855 escape_glyph
= XFASTINT (DISP_ESCAPE_GLYPH (it
->dp
));
4857 escape_glyph
= FAST_MAKE_GLYPH ('\\', 0);
4859 if (SINGLE_BYTE_CHAR_P (it
->c
))
4860 str
[0] = it
->c
, len
= 1;
4863 len
= CHAR_STRING_NO_SIGNAL (it
->c
, str
);
4866 /* It's an invalid character, which
4867 shouldn't happen actually, but due to
4868 bugs it may happen. Let's print the char
4869 as is, there's not much meaningful we can
4872 str
[1] = it
->c
>> 8;
4873 str
[2] = it
->c
>> 16;
4874 str
[3] = it
->c
>> 24;
4879 for (i
= 0; i
< len
; i
++)
4881 XSETINT (it
->ctl_chars
[i
* 4], escape_glyph
);
4882 /* Insert three more glyphs into IT->ctl_chars for
4883 the octal display of the character. */
4884 g
= FAST_MAKE_GLYPH (((str
[i
] >> 6) & 7) + '0', 0);
4885 XSETINT (it
->ctl_chars
[i
* 4 + 1], g
);
4886 g
= FAST_MAKE_GLYPH (((str
[i
] >> 3) & 7) + '0', 0);
4887 XSETINT (it
->ctl_chars
[i
* 4 + 2], g
);
4888 g
= FAST_MAKE_GLYPH ((str
[i
] & 7) + '0', 0);
4889 XSETINT (it
->ctl_chars
[i
* 4 + 3], g
);
4892 /* Set up IT->dpvec and return the first character
4894 it
->dpvec_char_len
= it
->len
;
4895 it
->dpvec
= it
->ctl_chars
;
4896 it
->dpend
= it
->dpvec
+ len
* 4;
4897 it
->current
.dpvec_index
= 0;
4898 it
->method
= next_element_from_display_vector
;
4899 get_next_display_element (it
);
4904 /* Adjust face id for a multibyte character. There are no
4905 multibyte character in unibyte text. */
4908 && FRAME_WINDOW_P (it
->f
))
4910 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
4911 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->c
);
4915 /* Is this character the last one of a run of characters with
4916 box? If yes, set IT->end_of_box_run_p to 1. */
4923 it
->end_of_box_run_p
4924 = ((face_id
= face_after_it_pos (it
),
4925 face_id
!= it
->face_id
)
4926 && (face
= FACE_FROM_ID (it
->f
, face_id
),
4927 face
->box
== FACE_NO_BOX
));
4930 /* Value is 0 if end of buffer or string reached. */
4935 /* Move IT to the next display element.
4937 RESEAT_P non-zero means if called on a newline in buffer text,
4938 skip to the next visible line start.
4940 Functions get_next_display_element and set_iterator_to_next are
4941 separate because I find this arrangement easier to handle than a
4942 get_next_display_element function that also increments IT's
4943 position. The way it is we can first look at an iterator's current
4944 display element, decide whether it fits on a line, and if it does,
4945 increment the iterator position. The other way around we probably
4946 would either need a flag indicating whether the iterator has to be
4947 incremented the next time, or we would have to implement a
4948 decrement position function which would not be easy to write. */
4951 set_iterator_to_next (it
, reseat_p
)
4955 /* Reset flags indicating start and end of a sequence of characters
4956 with box. Reset them at the start of this function because
4957 moving the iterator to a new position might set them. */
4958 it
->start_of_box_run_p
= it
->end_of_box_run_p
= 0;
4960 if (it
->method
== next_element_from_buffer
)
4962 /* The current display element of IT is a character from
4963 current_buffer. Advance in the buffer, and maybe skip over
4964 invisible lines that are so because of selective display. */
4965 if (ITERATOR_AT_END_OF_LINE_P (it
) && reseat_p
)
4966 reseat_at_next_visible_line_start (it
, 0);
4969 xassert (it
->len
!= 0);
4970 IT_BYTEPOS (*it
) += it
->len
;
4971 IT_CHARPOS (*it
) += 1;
4972 xassert (IT_BYTEPOS (*it
) == CHAR_TO_BYTE (IT_CHARPOS (*it
)));
4975 else if (it
->method
== next_element_from_composition
)
4977 xassert (it
->cmp_id
>= 0 && it
->cmp_id
< n_compositions
);
4978 if (STRINGP (it
->string
))
4980 IT_STRING_BYTEPOS (*it
) += it
->len
;
4981 IT_STRING_CHARPOS (*it
) += it
->cmp_len
;
4982 it
->method
= next_element_from_string
;
4983 goto consider_string_end
;
4987 IT_BYTEPOS (*it
) += it
->len
;
4988 IT_CHARPOS (*it
) += it
->cmp_len
;
4989 it
->method
= next_element_from_buffer
;
4992 else if (it
->method
== next_element_from_c_string
)
4994 /* Current display element of IT is from a C string. */
4995 IT_BYTEPOS (*it
) += it
->len
;
4996 IT_CHARPOS (*it
) += 1;
4998 else if (it
->method
== next_element_from_display_vector
)
5000 /* Current display element of IT is from a display table entry.
5001 Advance in the display table definition. Reset it to null if
5002 end reached, and continue with characters from buffers/
5004 ++it
->current
.dpvec_index
;
5006 /* Restore face of the iterator to what they were before the
5007 display vector entry (these entries may contain faces). */
5008 it
->face_id
= it
->saved_face_id
;
5010 if (it
->dpvec
+ it
->current
.dpvec_index
== it
->dpend
)
5013 it
->method
= next_element_from_c_string
;
5014 else if (STRINGP (it
->string
))
5015 it
->method
= next_element_from_string
;
5017 it
->method
= next_element_from_buffer
;
5020 it
->current
.dpvec_index
= -1;
5022 /* Skip over characters which were displayed via IT->dpvec. */
5023 if (it
->dpvec_char_len
< 0)
5024 reseat_at_next_visible_line_start (it
, 1);
5025 else if (it
->dpvec_char_len
> 0)
5027 it
->len
= it
->dpvec_char_len
;
5028 set_iterator_to_next (it
, reseat_p
);
5032 else if (it
->method
== next_element_from_string
)
5034 /* Current display element is a character from a Lisp string. */
5035 xassert (it
->s
== NULL
&& STRINGP (it
->string
));
5036 IT_STRING_BYTEPOS (*it
) += it
->len
;
5037 IT_STRING_CHARPOS (*it
) += 1;
5039 consider_string_end
:
5041 if (it
->current
.overlay_string_index
>= 0)
5043 /* IT->string is an overlay string. Advance to the
5044 next, if there is one. */
5045 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
))
5046 next_overlay_string (it
);
5050 /* IT->string is not an overlay string. If we reached
5051 its end, and there is something on IT->stack, proceed
5052 with what is on the stack. This can be either another
5053 string, this time an overlay string, or a buffer. */
5054 if (IT_STRING_CHARPOS (*it
) == SCHARS (it
->string
)
5058 if (!STRINGP (it
->string
))
5059 it
->method
= next_element_from_buffer
;
5061 goto consider_string_end
;
5065 else if (it
->method
== next_element_from_image
5066 || it
->method
== next_element_from_stretch
)
5068 /* The position etc with which we have to proceed are on
5069 the stack. The position may be at the end of a string,
5070 if the `display' property takes up the whole string. */
5073 if (STRINGP (it
->string
))
5075 it
->method
= next_element_from_string
;
5076 goto consider_string_end
;
5079 it
->method
= next_element_from_buffer
;
5082 /* There are no other methods defined, so this should be a bug. */
5085 xassert (it
->method
!= next_element_from_string
5086 || (STRINGP (it
->string
)
5087 && IT_STRING_CHARPOS (*it
) >= 0));
5091 /* Load IT's display element fields with information about the next
5092 display element which comes from a display table entry or from the
5093 result of translating a control character to one of the forms `^C'
5094 or `\003'. IT->dpvec holds the glyphs to return as characters. */
5097 next_element_from_display_vector (it
)
5101 xassert (it
->dpvec
&& it
->current
.dpvec_index
>= 0);
5103 /* Remember the current face id in case glyphs specify faces.
5104 IT's face is restored in set_iterator_to_next. */
5105 it
->saved_face_id
= it
->face_id
;
5107 if (INTEGERP (*it
->dpvec
)
5108 && GLYPH_CHAR_VALID_P (XFASTINT (*it
->dpvec
)))
5113 g
= XFASTINT (it
->dpvec
[it
->current
.dpvec_index
]);
5114 it
->c
= FAST_GLYPH_CHAR (g
);
5115 it
->len
= CHAR_BYTES (it
->c
);
5117 /* The entry may contain a face id to use. Such a face id is
5118 the id of a Lisp face, not a realized face. A face id of
5119 zero means no face is specified. */
5120 lface_id
= FAST_GLYPH_FACE (g
);
5123 /* The function returns -1 if lface_id is invalid. */
5124 int face_id
= ascii_face_of_lisp_face (it
->f
, lface_id
);
5126 it
->face_id
= face_id
;
5130 /* Display table entry is invalid. Return a space. */
5131 it
->c
= ' ', it
->len
= 1;
5133 /* Don't change position and object of the iterator here. They are
5134 still the values of the character that had this display table
5135 entry or was translated, and that's what we want. */
5136 it
->what
= IT_CHARACTER
;
5141 /* Load IT with the next display element from Lisp string IT->string.
5142 IT->current.string_pos is the current position within the string.
5143 If IT->current.overlay_string_index >= 0, the Lisp string is an
5147 next_element_from_string (it
)
5150 struct text_pos position
;
5152 xassert (STRINGP (it
->string
));
5153 xassert (IT_STRING_CHARPOS (*it
) >= 0);
5154 position
= it
->current
.string_pos
;
5156 /* Time to check for invisible text? */
5157 if (IT_STRING_CHARPOS (*it
) < it
->end_charpos
5158 && IT_STRING_CHARPOS (*it
) == it
->stop_charpos
)
5162 /* Since a handler may have changed IT->method, we must
5164 return get_next_display_element (it
);
5167 if (it
->current
.overlay_string_index
>= 0)
5169 /* Get the next character from an overlay string. In overlay
5170 strings, There is no field width or padding with spaces to
5172 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
))
5177 else if (STRING_MULTIBYTE (it
->string
))
5179 int remaining
= SBYTES (it
->string
) - IT_STRING_BYTEPOS (*it
);
5180 const unsigned char *s
= (SDATA (it
->string
)
5181 + IT_STRING_BYTEPOS (*it
));
5182 it
->c
= string_char_and_length (s
, remaining
, &it
->len
);
5186 it
->c
= SREF (it
->string
, IT_STRING_BYTEPOS (*it
));
5192 /* Get the next character from a Lisp string that is not an
5193 overlay string. Such strings come from the mode line, for
5194 example. We may have to pad with spaces, or truncate the
5195 string. See also next_element_from_c_string. */
5196 if (IT_STRING_CHARPOS (*it
) >= it
->end_charpos
)
5201 else if (IT_STRING_CHARPOS (*it
) >= it
->string_nchars
)
5203 /* Pad with spaces. */
5204 it
->c
= ' ', it
->len
= 1;
5205 CHARPOS (position
) = BYTEPOS (position
) = -1;
5207 else if (STRING_MULTIBYTE (it
->string
))
5209 int maxlen
= SBYTES (it
->string
) - IT_STRING_BYTEPOS (*it
);
5210 const unsigned char *s
= (SDATA (it
->string
)
5211 + IT_STRING_BYTEPOS (*it
));
5212 it
->c
= string_char_and_length (s
, maxlen
, &it
->len
);
5216 it
->c
= SREF (it
->string
, IT_STRING_BYTEPOS (*it
));
5221 /* Record what we have and where it came from. Note that we store a
5222 buffer position in IT->position although it could arguably be a
5224 it
->what
= IT_CHARACTER
;
5225 it
->object
= it
->string
;
5226 it
->position
= position
;
5231 /* Load IT with next display element from C string IT->s.
5232 IT->string_nchars is the maximum number of characters to return
5233 from the string. IT->end_charpos may be greater than
5234 IT->string_nchars when this function is called, in which case we
5235 may have to return padding spaces. Value is zero if end of string
5236 reached, including padding spaces. */
5239 next_element_from_c_string (it
)
5245 it
->what
= IT_CHARACTER
;
5246 BYTEPOS (it
->position
) = CHARPOS (it
->position
) = 0;
5249 /* IT's position can be greater IT->string_nchars in case a field
5250 width or precision has been specified when the iterator was
5252 if (IT_CHARPOS (*it
) >= it
->end_charpos
)
5254 /* End of the game. */
5258 else if (IT_CHARPOS (*it
) >= it
->string_nchars
)
5260 /* Pad with spaces. */
5261 it
->c
= ' ', it
->len
= 1;
5262 BYTEPOS (it
->position
) = CHARPOS (it
->position
) = -1;
5264 else if (it
->multibyte_p
)
5266 /* Implementation note: The calls to strlen apparently aren't a
5267 performance problem because there is no noticeable performance
5268 difference between Emacs running in unibyte or multibyte mode. */
5269 int maxlen
= strlen (it
->s
) - IT_BYTEPOS (*it
);
5270 it
->c
= string_char_and_length (it
->s
+ IT_BYTEPOS (*it
),
5274 it
->c
= it
->s
[IT_BYTEPOS (*it
)], it
->len
= 1;
5280 /* Set up IT to return characters from an ellipsis, if appropriate.
5281 The definition of the ellipsis glyphs may come from a display table
5282 entry. This function Fills IT with the first glyph from the
5283 ellipsis if an ellipsis is to be displayed. */
5286 next_element_from_ellipsis (it
)
5289 if (it
->selective_display_ellipsis_p
)
5291 if (it
->dp
&& VECTORP (DISP_INVIS_VECTOR (it
->dp
)))
5293 /* Use the display table definition for `...'. Invalid glyphs
5294 will be handled by the method returning elements from dpvec. */
5295 struct Lisp_Vector
*v
= XVECTOR (DISP_INVIS_VECTOR (it
->dp
));
5296 it
->dpvec_char_len
= it
->len
;
5297 it
->dpvec
= v
->contents
;
5298 it
->dpend
= v
->contents
+ v
->size
;
5299 it
->current
.dpvec_index
= 0;
5300 it
->method
= next_element_from_display_vector
;
5304 /* Use default `...' which is stored in default_invis_vector. */
5305 it
->dpvec_char_len
= it
->len
;
5306 it
->dpvec
= default_invis_vector
;
5307 it
->dpend
= default_invis_vector
+ 3;
5308 it
->current
.dpvec_index
= 0;
5309 it
->method
= next_element_from_display_vector
;
5314 /* The face at the current position may be different from the
5315 face we find after the invisible text. Remember what it
5316 was in IT->saved_face_id, and signal that it's there by
5317 setting face_before_selective_p. */
5318 it
->saved_face_id
= it
->face_id
;
5319 it
->method
= next_element_from_buffer
;
5320 reseat_at_next_visible_line_start (it
, 1);
5321 it
->face_before_selective_p
= 1;
5324 return get_next_display_element (it
);
5328 /* Deliver an image display element. The iterator IT is already
5329 filled with image information (done in handle_display_prop). Value
5334 next_element_from_image (it
)
5337 it
->what
= IT_IMAGE
;
5342 /* Fill iterator IT with next display element from a stretch glyph
5343 property. IT->object is the value of the text property. Value is
5347 next_element_from_stretch (it
)
5350 it
->what
= IT_STRETCH
;
5355 /* Load IT with the next display element from current_buffer. Value
5356 is zero if end of buffer reached. IT->stop_charpos is the next
5357 position at which to stop and check for text properties or buffer
5361 next_element_from_buffer (it
)
5366 /* Check this assumption, otherwise, we would never enter the
5367 if-statement, below. */
5368 xassert (IT_CHARPOS (*it
) >= BEGV
5369 && IT_CHARPOS (*it
) <= it
->stop_charpos
);
5371 if (IT_CHARPOS (*it
) >= it
->stop_charpos
)
5373 if (IT_CHARPOS (*it
) >= it
->end_charpos
)
5375 int overlay_strings_follow_p
;
5377 /* End of the game, except when overlay strings follow that
5378 haven't been returned yet. */
5379 if (it
->overlay_strings_at_end_processed_p
)
5380 overlay_strings_follow_p
= 0;
5383 it
->overlay_strings_at_end_processed_p
= 1;
5384 overlay_strings_follow_p
= get_overlay_strings (it
, 0);
5387 if (overlay_strings_follow_p
)
5388 success_p
= get_next_display_element (it
);
5392 it
->position
= it
->current
.pos
;
5399 return get_next_display_element (it
);
5404 /* No face changes, overlays etc. in sight, so just return a
5405 character from current_buffer. */
5408 /* Maybe run the redisplay end trigger hook. Performance note:
5409 This doesn't seem to cost measurable time. */
5410 if (it
->redisplay_end_trigger_charpos
5412 && IT_CHARPOS (*it
) >= it
->redisplay_end_trigger_charpos
)
5413 run_redisplay_end_trigger_hook (it
);
5415 /* Get the next character, maybe multibyte. */
5416 p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
5417 if (it
->multibyte_p
&& !ASCII_BYTE_P (*p
))
5419 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT_BYTE
? ZV_BYTE
: GPT_BYTE
)
5420 - IT_BYTEPOS (*it
));
5421 it
->c
= string_char_and_length (p
, maxlen
, &it
->len
);
5424 it
->c
= *p
, it
->len
= 1;
5426 /* Record what we have and where it came from. */
5427 it
->what
= IT_CHARACTER
;;
5428 it
->object
= it
->w
->buffer
;
5429 it
->position
= it
->current
.pos
;
5431 /* Normally we return the character found above, except when we
5432 really want to return an ellipsis for selective display. */
5437 /* A value of selective > 0 means hide lines indented more
5438 than that number of columns. */
5439 if (it
->selective
> 0
5440 && IT_CHARPOS (*it
) + 1 < ZV
5441 && indented_beyond_p (IT_CHARPOS (*it
) + 1,
5442 IT_BYTEPOS (*it
) + 1,
5443 (double) it
->selective
)) /* iftc */
5445 success_p
= next_element_from_ellipsis (it
);
5446 it
->dpvec_char_len
= -1;
5449 else if (it
->c
== '\r' && it
->selective
== -1)
5451 /* A value of selective == -1 means that everything from the
5452 CR to the end of the line is invisible, with maybe an
5453 ellipsis displayed for it. */
5454 success_p
= next_element_from_ellipsis (it
);
5455 it
->dpvec_char_len
= -1;
5460 /* Value is zero if end of buffer reached. */
5461 xassert (!success_p
|| it
->what
!= IT_CHARACTER
|| it
->len
> 0);
5466 /* Run the redisplay end trigger hook for IT. */
5469 run_redisplay_end_trigger_hook (it
)
5472 Lisp_Object args
[3];
5474 /* IT->glyph_row should be non-null, i.e. we should be actually
5475 displaying something, or otherwise we should not run the hook. */
5476 xassert (it
->glyph_row
);
5478 /* Set up hook arguments. */
5479 args
[0] = Qredisplay_end_trigger_functions
;
5480 args
[1] = it
->window
;
5481 XSETINT (args
[2], it
->redisplay_end_trigger_charpos
);
5482 it
->redisplay_end_trigger_charpos
= 0;
5484 /* Since we are *trying* to run these functions, don't try to run
5485 them again, even if they get an error. */
5486 it
->w
->redisplay_end_trigger
= Qnil
;
5487 Frun_hook_with_args (3, args
);
5489 /* Notice if it changed the face of the character we are on. */
5490 handle_face_prop (it
);
5494 /* Deliver a composition display element. The iterator IT is already
5495 filled with composition information (done in
5496 handle_composition_prop). Value is always 1. */
5499 next_element_from_composition (it
)
5502 it
->what
= IT_COMPOSITION
;
5503 it
->position
= (STRINGP (it
->string
)
5504 ? it
->current
.string_pos
5511 /***********************************************************************
5512 Moving an iterator without producing glyphs
5513 ***********************************************************************/
5515 /* Move iterator IT to a specified buffer or X position within one
5516 line on the display without producing glyphs.
5518 OP should be a bit mask including some or all of these bits:
5519 MOVE_TO_X: Stop on reaching x-position TO_X.
5520 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
5521 Regardless of OP's value, stop in reaching the end of the display line.
5523 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
5524 This means, in particular, that TO_X includes window's horizontal
5527 The return value has several possible values that
5528 say what condition caused the scan to stop:
5530 MOVE_POS_MATCH_OR_ZV
5531 - when TO_POS or ZV was reached.
5534 -when TO_X was reached before TO_POS or ZV were reached.
5537 - when we reached the end of the display area and the line must
5541 - when we reached the end of the display area and the line is
5545 - when we stopped at a line end, i.e. a newline or a CR and selective
5548 static enum move_it_result
5549 move_it_in_display_line_to (it
, to_charpos
, to_x
, op
)
5551 int to_charpos
, to_x
, op
;
5553 enum move_it_result result
= MOVE_UNDEFINED
;
5554 struct glyph_row
*saved_glyph_row
;
5556 /* Don't produce glyphs in produce_glyphs. */
5557 saved_glyph_row
= it
->glyph_row
;
5558 it
->glyph_row
= NULL
;
5562 int x
, i
, ascent
= 0, descent
= 0;
5564 /* Stop when ZV or TO_CHARPOS reached. */
5565 if (!get_next_display_element (it
)
5566 || ((op
& MOVE_TO_POS
) != 0
5567 && BUFFERP (it
->object
)
5568 && IT_CHARPOS (*it
) >= to_charpos
))
5570 result
= MOVE_POS_MATCH_OR_ZV
;
5574 /* The call to produce_glyphs will get the metrics of the
5575 display element IT is loaded with. We record in x the
5576 x-position before this display element in case it does not
5580 /* Remember the line height so far in case the next element doesn't
5582 if (!it
->truncate_lines_p
)
5584 ascent
= it
->max_ascent
;
5585 descent
= it
->max_descent
;
5588 PRODUCE_GLYPHS (it
);
5590 if (it
->area
!= TEXT_AREA
)
5592 set_iterator_to_next (it
, 1);
5596 /* The number of glyphs we get back in IT->nglyphs will normally
5597 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
5598 character on a terminal frame, or (iii) a line end. For the
5599 second case, IT->nglyphs - 1 padding glyphs will be present
5600 (on X frames, there is only one glyph produced for a
5601 composite character.
5603 The behavior implemented below means, for continuation lines,
5604 that as many spaces of a TAB as fit on the current line are
5605 displayed there. For terminal frames, as many glyphs of a
5606 multi-glyph character are displayed in the current line, too.
5607 This is what the old redisplay code did, and we keep it that
5608 way. Under X, the whole shape of a complex character must
5609 fit on the line or it will be completely displayed in the
5612 Note that both for tabs and padding glyphs, all glyphs have
5616 /* More than one glyph or glyph doesn't fit on line. All
5617 glyphs have the same width. */
5618 int single_glyph_width
= it
->pixel_width
/ it
->nglyphs
;
5621 for (i
= 0; i
< it
->nglyphs
; ++i
, x
= new_x
)
5623 new_x
= x
+ single_glyph_width
;
5625 /* We want to leave anything reaching TO_X to the caller. */
5626 if ((op
& MOVE_TO_X
) && new_x
> to_x
)
5629 result
= MOVE_X_REACHED
;
5632 else if (/* Lines are continued. */
5633 !it
->truncate_lines_p
5634 && (/* And glyph doesn't fit on the line. */
5635 new_x
> it
->last_visible_x
5636 /* Or it fits exactly and we're on a window
5638 || (new_x
== it
->last_visible_x
5639 && FRAME_WINDOW_P (it
->f
))))
5641 if (/* IT->hpos == 0 means the very first glyph
5642 doesn't fit on the line, e.g. a wide image. */
5644 || (new_x
== it
->last_visible_x
5645 && FRAME_WINDOW_P (it
->f
)))
5648 it
->current_x
= new_x
;
5649 if (i
== it
->nglyphs
- 1)
5651 set_iterator_to_next (it
, 1);
5652 #ifdef HAVE_WINDOW_SYSTEM
5653 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
5655 if (!get_next_display_element (it
))
5657 result
= MOVE_POS_MATCH_OR_ZV
;
5660 if (ITERATOR_AT_END_OF_LINE_P (it
))
5662 result
= MOVE_NEWLINE_OR_CR
;
5666 #endif /* HAVE_WINDOW_SYSTEM */
5672 it
->max_ascent
= ascent
;
5673 it
->max_descent
= descent
;
5676 TRACE_MOVE ((stderr
, "move_it_in: continued at %d\n",
5678 result
= MOVE_LINE_CONTINUED
;
5681 else if (new_x
> it
->first_visible_x
)
5683 /* Glyph is visible. Increment number of glyphs that
5684 would be displayed. */
5689 /* Glyph is completely off the left margin of the display
5690 area. Nothing to do. */
5694 if (result
!= MOVE_UNDEFINED
)
5697 else if ((op
& MOVE_TO_X
) && it
->current_x
>= to_x
)
5699 /* Stop when TO_X specified and reached. This check is
5700 necessary here because of lines consisting of a line end,
5701 only. The line end will not produce any glyphs and we
5702 would never get MOVE_X_REACHED. */
5703 xassert (it
->nglyphs
== 0);
5704 result
= MOVE_X_REACHED
;
5708 /* Is this a line end? If yes, we're done. */
5709 if (ITERATOR_AT_END_OF_LINE_P (it
))
5711 result
= MOVE_NEWLINE_OR_CR
;
5715 /* The current display element has been consumed. Advance
5717 set_iterator_to_next (it
, 1);
5719 /* Stop if lines are truncated and IT's current x-position is
5720 past the right edge of the window now. */
5721 if (it
->truncate_lines_p
5722 && it
->current_x
>= it
->last_visible_x
)
5724 #ifdef HAVE_WINDOW_SYSTEM
5725 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
5727 if (!get_next_display_element (it
))
5729 result
= MOVE_POS_MATCH_OR_ZV
;
5732 if (ITERATOR_AT_END_OF_LINE_P (it
))
5734 result
= MOVE_NEWLINE_OR_CR
;
5738 #endif /* HAVE_WINDOW_SYSTEM */
5739 result
= MOVE_LINE_TRUNCATED
;
5744 /* Restore the iterator settings altered at the beginning of this
5746 it
->glyph_row
= saved_glyph_row
;
5751 /* Move IT forward until it satisfies one or more of the criteria in
5752 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
5754 OP is a bit-mask that specifies where to stop, and in particular,
5755 which of those four position arguments makes a difference. See the
5756 description of enum move_operation_enum.
5758 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
5759 screen line, this function will set IT to the next position >
5763 move_it_to (it
, to_charpos
, to_x
, to_y
, to_vpos
, op
)
5765 int to_charpos
, to_x
, to_y
, to_vpos
;
5768 enum move_it_result skip
, skip2
= MOVE_X_REACHED
;
5774 if (op
& MOVE_TO_VPOS
)
5776 /* If no TO_CHARPOS and no TO_X specified, stop at the
5777 start of the line TO_VPOS. */
5778 if ((op
& (MOVE_TO_X
| MOVE_TO_POS
)) == 0)
5780 if (it
->vpos
== to_vpos
)
5786 skip
= move_it_in_display_line_to (it
, -1, -1, 0);
5790 /* TO_VPOS >= 0 means stop at TO_X in the line at
5791 TO_VPOS, or at TO_POS, whichever comes first. */
5792 if (it
->vpos
== to_vpos
)
5798 skip
= move_it_in_display_line_to (it
, to_charpos
, to_x
, op
);
5800 if (skip
== MOVE_POS_MATCH_OR_ZV
|| it
->vpos
== to_vpos
)
5805 else if (skip
== MOVE_X_REACHED
&& it
->vpos
!= to_vpos
)
5807 /* We have reached TO_X but not in the line we want. */
5808 skip
= move_it_in_display_line_to (it
, to_charpos
,
5810 if (skip
== MOVE_POS_MATCH_OR_ZV
)
5818 else if (op
& MOVE_TO_Y
)
5820 struct it it_backup
;
5822 /* TO_Y specified means stop at TO_X in the line containing
5823 TO_Y---or at TO_CHARPOS if this is reached first. The
5824 problem is that we can't really tell whether the line
5825 contains TO_Y before we have completely scanned it, and
5826 this may skip past TO_X. What we do is to first scan to
5829 If TO_X is not specified, use a TO_X of zero. The reason
5830 is to make the outcome of this function more predictable.
5831 If we didn't use TO_X == 0, we would stop at the end of
5832 the line which is probably not what a caller would expect
5834 skip
= move_it_in_display_line_to (it
, to_charpos
,
5838 | (op
& MOVE_TO_POS
)));
5840 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
5841 if (skip
== MOVE_POS_MATCH_OR_ZV
)
5847 /* If TO_X was reached, we would like to know whether TO_Y
5848 is in the line. This can only be said if we know the
5849 total line height which requires us to scan the rest of
5851 if (skip
== MOVE_X_REACHED
)
5854 TRACE_MOVE ((stderr
, "move_it: from %d\n", IT_CHARPOS (*it
)));
5855 skip2
= move_it_in_display_line_to (it
, to_charpos
, -1,
5857 TRACE_MOVE ((stderr
, "move_it: to %d\n", IT_CHARPOS (*it
)));
5860 /* Now, decide whether TO_Y is in this line. */
5861 line_height
= it
->max_ascent
+ it
->max_descent
;
5862 TRACE_MOVE ((stderr
, "move_it: line_height = %d\n", line_height
));
5864 if (to_y
>= it
->current_y
5865 && to_y
< it
->current_y
+ line_height
)
5867 if (skip
== MOVE_X_REACHED
)
5868 /* If TO_Y is in this line and TO_X was reached above,
5869 we scanned too far. We have to restore IT's settings
5870 to the ones before skipping. */
5874 else if (skip
== MOVE_X_REACHED
)
5877 if (skip
== MOVE_POS_MATCH_OR_ZV
)
5885 skip
= move_it_in_display_line_to (it
, to_charpos
, -1, MOVE_TO_POS
);
5889 case MOVE_POS_MATCH_OR_ZV
:
5893 case MOVE_NEWLINE_OR_CR
:
5894 set_iterator_to_next (it
, 1);
5895 it
->continuation_lines_width
= 0;
5898 case MOVE_LINE_TRUNCATED
:
5899 it
->continuation_lines_width
= 0;
5900 reseat_at_next_visible_line_start (it
, 0);
5901 if ((op
& MOVE_TO_POS
) != 0
5902 && IT_CHARPOS (*it
) > to_charpos
)
5909 case MOVE_LINE_CONTINUED
:
5910 it
->continuation_lines_width
+= it
->current_x
;
5917 /* Reset/increment for the next run. */
5918 recenter_overlay_lists (current_buffer
, IT_CHARPOS (*it
));
5919 it
->current_x
= it
->hpos
= 0;
5920 it
->current_y
+= it
->max_ascent
+ it
->max_descent
;
5922 last_height
= it
->max_ascent
+ it
->max_descent
;
5923 last_max_ascent
= it
->max_ascent
;
5924 it
->max_ascent
= it
->max_descent
= 0;
5929 TRACE_MOVE ((stderr
, "move_it_to: reached %d\n", reached
));
5933 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
5935 If DY > 0, move IT backward at least that many pixels. DY = 0
5936 means move IT backward to the preceding line start or BEGV. This
5937 function may move over more than DY pixels if IT->current_y - DY
5938 ends up in the middle of a line; in this case IT->current_y will be
5939 set to the top of the line moved to. */
5942 move_it_vertically_backward (it
, dy
)
5948 int start_pos
= IT_CHARPOS (*it
);
5952 /* Estimate how many newlines we must move back. */
5953 nlines
= max (1, dy
/ FRAME_LINE_HEIGHT (it
->f
));
5955 /* Set the iterator's position that many lines back. */
5956 while (nlines
-- && IT_CHARPOS (*it
) > BEGV
)
5957 back_to_previous_visible_line_start (it
);
5959 /* Reseat the iterator here. When moving backward, we don't want
5960 reseat to skip forward over invisible text, set up the iterator
5961 to deliver from overlay strings at the new position etc. So,
5962 use reseat_1 here. */
5963 reseat_1 (it
, it
->current
.pos
, 1);
5965 /* We are now surely at a line start. */
5966 it
->current_x
= it
->hpos
= 0;
5967 it
->continuation_lines_width
= 0;
5969 /* Move forward and see what y-distance we moved. First move to the
5970 start of the next line so that we get its height. We need this
5971 height to be able to tell whether we reached the specified
5974 it2
.max_ascent
= it2
.max_descent
= 0;
5975 move_it_to (&it2
, start_pos
, -1, -1, it2
.vpos
+ 1,
5976 MOVE_TO_POS
| MOVE_TO_VPOS
);
5977 xassert (IT_CHARPOS (*it
) >= BEGV
);
5980 move_it_to (&it2
, start_pos
, -1, -1, -1, MOVE_TO_POS
);
5981 xassert (IT_CHARPOS (*it
) >= BEGV
);
5982 /* H is the actual vertical distance from the position in *IT
5983 and the starting position. */
5984 h
= it2
.current_y
- it
->current_y
;
5985 /* NLINES is the distance in number of lines. */
5986 nlines
= it2
.vpos
- it
->vpos
;
5988 /* Correct IT's y and vpos position
5989 so that they are relative to the starting point. */
5995 /* DY == 0 means move to the start of the screen line. The
5996 value of nlines is > 0 if continuation lines were involved. */
5998 move_it_by_lines (it
, nlines
, 1);
5999 xassert (IT_CHARPOS (*it
) <= start_pos
);
6003 /* The y-position we try to reach, relative to *IT.
6004 Note that H has been subtracted in front of the if-statement. */
6005 int target_y
= it
->current_y
+ h
- dy
;
6006 int y0
= it3
.current_y
;
6007 int y1
= line_bottom_y (&it3
);
6008 int line_height
= y1
- y0
;
6010 /* If we did not reach target_y, try to move further backward if
6011 we can. If we moved too far backward, try to move forward. */
6012 if (target_y
< it
->current_y
6013 /* This is heuristic. In a window that's 3 lines high, with
6014 a line height of 13 pixels each, recentering with point
6015 on the bottom line will try to move -39/2 = 19 pixels
6016 backward. Try to avoid moving into the first line. */
6017 && it
->current_y
- target_y
> line_height
/ 3 * 2
6018 && IT_CHARPOS (*it
) > BEGV
)
6020 TRACE_MOVE ((stderr
, " not far enough -> move_vert %d\n",
6021 target_y
- it
->current_y
));
6022 move_it_vertically (it
, target_y
- it
->current_y
);
6023 xassert (IT_CHARPOS (*it
) >= BEGV
);
6025 else if (target_y
>= it
->current_y
+ line_height
6026 && IT_CHARPOS (*it
) < ZV
)
6028 /* Should move forward by at least one line, maybe more.
6030 Note: Calling move_it_by_lines can be expensive on
6031 terminal frames, where compute_motion is used (via
6032 vmotion) to do the job, when there are very long lines
6033 and truncate-lines is nil. That's the reason for
6034 treating terminal frames specially here. */
6036 if (!FRAME_WINDOW_P (it
->f
))
6037 move_it_vertically (it
, target_y
- (it
->current_y
+ line_height
));
6042 move_it_by_lines (it
, 1, 1);
6044 while (target_y
>= line_bottom_y (it
) && IT_CHARPOS (*it
) < ZV
);
6047 xassert (IT_CHARPOS (*it
) >= BEGV
);
6053 /* Move IT by a specified amount of pixel lines DY. DY negative means
6054 move backwards. DY = 0 means move to start of screen line. At the
6055 end, IT will be on the start of a screen line. */
6058 move_it_vertically (it
, dy
)
6063 move_it_vertically_backward (it
, -dy
);
6066 TRACE_MOVE ((stderr
, "move_it_v: from %d, %d\n", IT_CHARPOS (*it
), dy
));
6067 move_it_to (it
, ZV
, -1, it
->current_y
+ dy
, -1,
6068 MOVE_TO_POS
| MOVE_TO_Y
);
6069 TRACE_MOVE ((stderr
, "move_it_v: to %d\n", IT_CHARPOS (*it
)));
6071 /* If buffer ends in ZV without a newline, move to the start of
6072 the line to satisfy the post-condition. */
6073 if (IT_CHARPOS (*it
) == ZV
6074 && FETCH_BYTE (IT_BYTEPOS (*it
) - 1) != '\n')
6075 move_it_by_lines (it
, 0, 0);
6080 /* Move iterator IT past the end of the text line it is in. */
6083 move_it_past_eol (it
)
6086 enum move_it_result rc
;
6088 rc
= move_it_in_display_line_to (it
, Z
, 0, MOVE_TO_POS
);
6089 if (rc
== MOVE_NEWLINE_OR_CR
)
6090 set_iterator_to_next (it
, 0);
6094 #if 0 /* Currently not used. */
6096 /* Return non-zero if some text between buffer positions START_CHARPOS
6097 and END_CHARPOS is invisible. IT->window is the window for text
6101 invisible_text_between_p (it
, start_charpos
, end_charpos
)
6103 int start_charpos
, end_charpos
;
6105 Lisp_Object prop
, limit
;
6106 int invisible_found_p
;
6108 xassert (it
!= NULL
&& start_charpos
<= end_charpos
);
6110 /* Is text at START invisible? */
6111 prop
= Fget_char_property (make_number (start_charpos
), Qinvisible
,
6113 if (TEXT_PROP_MEANS_INVISIBLE (prop
))
6114 invisible_found_p
= 1;
6117 limit
= Fnext_single_char_property_change (make_number (start_charpos
),
6119 make_number (end_charpos
));
6120 invisible_found_p
= XFASTINT (limit
) < end_charpos
;
6123 return invisible_found_p
;
6129 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
6130 negative means move up. DVPOS == 0 means move to the start of the
6131 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
6132 NEED_Y_P is zero, IT->current_y will be left unchanged.
6134 Further optimization ideas: If we would know that IT->f doesn't use
6135 a face with proportional font, we could be faster for
6136 truncate-lines nil. */
6139 move_it_by_lines (it
, dvpos
, need_y_p
)
6141 int dvpos
, need_y_p
;
6143 struct position pos
;
6145 if (!FRAME_WINDOW_P (it
->f
))
6147 struct text_pos textpos
;
6149 /* We can use vmotion on frames without proportional fonts. */
6150 pos
= *vmotion (IT_CHARPOS (*it
), dvpos
, it
->w
);
6151 SET_TEXT_POS (textpos
, pos
.bufpos
, pos
.bytepos
);
6152 reseat (it
, textpos
, 1);
6153 it
->vpos
+= pos
.vpos
;
6154 it
->current_y
+= pos
.vpos
;
6156 else if (dvpos
== 0)
6158 /* DVPOS == 0 means move to the start of the screen line. */
6159 move_it_vertically_backward (it
, 0);
6160 xassert (it
->current_x
== 0 && it
->hpos
== 0);
6163 move_it_to (it
, -1, -1, -1, it
->vpos
+ dvpos
, MOVE_TO_VPOS
);
6167 int start_charpos
, i
;
6169 /* Start at the beginning of the screen line containing IT's
6171 move_it_vertically_backward (it
, 0);
6173 /* Go back -DVPOS visible lines and reseat the iterator there. */
6174 start_charpos
= IT_CHARPOS (*it
);
6175 for (i
= -dvpos
; i
&& IT_CHARPOS (*it
) > BEGV
; --i
)
6176 back_to_previous_visible_line_start (it
);
6177 reseat (it
, it
->current
.pos
, 1);
6178 it
->current_x
= it
->hpos
= 0;
6180 /* Above call may have moved too far if continuation lines
6181 are involved. Scan forward and see if it did. */
6183 it2
.vpos
= it2
.current_y
= 0;
6184 move_it_to (&it2
, start_charpos
, -1, -1, -1, MOVE_TO_POS
);
6185 it
->vpos
-= it2
.vpos
;
6186 it
->current_y
-= it2
.current_y
;
6187 it
->current_x
= it
->hpos
= 0;
6189 /* If we moved too far, move IT some lines forward. */
6190 if (it2
.vpos
> -dvpos
)
6192 int delta
= it2
.vpos
+ dvpos
;
6193 move_it_to (it
, -1, -1, -1, it
->vpos
+ delta
, MOVE_TO_VPOS
);
6198 /* Return 1 if IT points into the middle of a display vector. */
6201 in_display_vector_p (it
)
6204 return (it
->method
== next_element_from_display_vector
6205 && it
->current
.dpvec_index
> 0
6206 && it
->dpvec
+ it
->current
.dpvec_index
!= it
->dpend
);
6210 /***********************************************************************
6212 ***********************************************************************/
6215 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
6219 add_to_log (format
, arg1
, arg2
)
6221 Lisp_Object arg1
, arg2
;
6223 Lisp_Object args
[3];
6224 Lisp_Object msg
, fmt
;
6227 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
6229 /* Do nothing if called asynchronously. Inserting text into
6230 a buffer may call after-change-functions and alike and
6231 that would means running Lisp asynchronously. */
6232 if (handling_signal
)
6236 GCPRO4 (fmt
, msg
, arg1
, arg2
);
6238 args
[0] = fmt
= build_string (format
);
6241 msg
= Fformat (3, args
);
6243 len
= SBYTES (msg
) + 1;
6244 buffer
= (char *) alloca (len
);
6245 bcopy (SDATA (msg
), buffer
, len
);
6247 message_dolog (buffer
, len
- 1, 1, 0);
6252 /* Output a newline in the *Messages* buffer if "needs" one. */
6255 message_log_maybe_newline ()
6257 if (message_log_need_newline
)
6258 message_dolog ("", 0, 1, 0);
6262 /* Add a string M of length NBYTES to the message log, optionally
6263 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
6264 nonzero, means interpret the contents of M as multibyte. This
6265 function calls low-level routines in order to bypass text property
6266 hooks, etc. which might not be safe to run. */
6269 message_dolog (m
, nbytes
, nlflag
, multibyte
)
6271 int nbytes
, nlflag
, multibyte
;
6273 if (!NILP (Vmemory_full
))
6276 if (!NILP (Vmessage_log_max
))
6278 struct buffer
*oldbuf
;
6279 Lisp_Object oldpoint
, oldbegv
, oldzv
;
6280 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
6281 int point_at_end
= 0;
6283 Lisp_Object old_deactivate_mark
, tem
;
6284 struct gcpro gcpro1
;
6286 old_deactivate_mark
= Vdeactivate_mark
;
6287 oldbuf
= current_buffer
;
6288 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name
));
6289 current_buffer
->undo_list
= Qt
;
6291 oldpoint
= message_dolog_marker1
;
6292 set_marker_restricted (oldpoint
, make_number (PT
), Qnil
);
6293 oldbegv
= message_dolog_marker2
;
6294 set_marker_restricted (oldbegv
, make_number (BEGV
), Qnil
);
6295 oldzv
= message_dolog_marker3
;
6296 set_marker_restricted (oldzv
, make_number (ZV
), Qnil
);
6297 GCPRO1 (old_deactivate_mark
);
6305 BEGV_BYTE
= BEG_BYTE
;
6308 TEMP_SET_PT_BOTH (Z
, Z_BYTE
);
6310 /* Insert the string--maybe converting multibyte to single byte
6311 or vice versa, so that all the text fits the buffer. */
6313 && NILP (current_buffer
->enable_multibyte_characters
))
6315 int i
, c
, char_bytes
;
6316 unsigned char work
[1];
6318 /* Convert a multibyte string to single-byte
6319 for the *Message* buffer. */
6320 for (i
= 0; i
< nbytes
; i
+= char_bytes
)
6322 c
= string_char_and_length (m
+ i
, nbytes
- i
, &char_bytes
);
6323 work
[0] = (SINGLE_BYTE_CHAR_P (c
)
6325 : multibyte_char_to_unibyte (c
, Qnil
));
6326 insert_1_both (work
, 1, 1, 1, 0, 0);
6329 else if (! multibyte
6330 && ! NILP (current_buffer
->enable_multibyte_characters
))
6332 int i
, c
, char_bytes
;
6333 unsigned char *msg
= (unsigned char *) m
;
6334 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
6335 /* Convert a single-byte string to multibyte
6336 for the *Message* buffer. */
6337 for (i
= 0; i
< nbytes
; i
++)
6339 c
= unibyte_char_to_multibyte (msg
[i
]);
6340 char_bytes
= CHAR_STRING (c
, str
);
6341 insert_1_both (str
, 1, char_bytes
, 1, 0, 0);
6345 insert_1 (m
, nbytes
, 1, 0, 0);
6349 int this_bol
, this_bol_byte
, prev_bol
, prev_bol_byte
, dup
;
6350 insert_1 ("\n", 1, 1, 0, 0);
6352 scan_newline (Z
, Z_BYTE
, BEG
, BEG_BYTE
, -2, 0);
6354 this_bol_byte
= PT_BYTE
;
6356 /* See if this line duplicates the previous one.
6357 If so, combine duplicates. */
6360 scan_newline (PT
, PT_BYTE
, BEG
, BEG_BYTE
, -2, 0);
6362 prev_bol_byte
= PT_BYTE
;
6364 dup
= message_log_check_duplicate (prev_bol
, prev_bol_byte
,
6365 this_bol
, this_bol_byte
);
6368 del_range_both (prev_bol
, prev_bol_byte
,
6369 this_bol
, this_bol_byte
, 0);
6375 /* If you change this format, don't forget to also
6376 change message_log_check_duplicate. */
6377 sprintf (dupstr
, " [%d times]", dup
);
6378 duplen
= strlen (dupstr
);
6379 TEMP_SET_PT_BOTH (Z
- 1, Z_BYTE
- 1);
6380 insert_1 (dupstr
, duplen
, 1, 0, 1);
6385 /* If we have more than the desired maximum number of lines
6386 in the *Messages* buffer now, delete the oldest ones.
6387 This is safe because we don't have undo in this buffer. */
6389 if (NATNUMP (Vmessage_log_max
))
6391 scan_newline (Z
, Z_BYTE
, BEG
, BEG_BYTE
,
6392 -XFASTINT (Vmessage_log_max
) - 1, 0);
6393 del_range_both (BEG
, BEG_BYTE
, PT
, PT_BYTE
, 0);
6396 BEGV
= XMARKER (oldbegv
)->charpos
;
6397 BEGV_BYTE
= marker_byte_position (oldbegv
);
6406 ZV
= XMARKER (oldzv
)->charpos
;
6407 ZV_BYTE
= marker_byte_position (oldzv
);
6411 TEMP_SET_PT_BOTH (Z
, Z_BYTE
);
6413 /* We can't do Fgoto_char (oldpoint) because it will run some
6415 TEMP_SET_PT_BOTH (XMARKER (oldpoint
)->charpos
,
6416 XMARKER (oldpoint
)->bytepos
);
6419 unchain_marker (XMARKER (oldpoint
));
6420 unchain_marker (XMARKER (oldbegv
));
6421 unchain_marker (XMARKER (oldzv
));
6423 tem
= Fget_buffer_window (Fcurrent_buffer (), Qt
);
6424 set_buffer_internal (oldbuf
);
6426 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
6427 message_log_need_newline
= !nlflag
;
6428 Vdeactivate_mark
= old_deactivate_mark
;
6433 /* We are at the end of the buffer after just having inserted a newline.
6434 (Note: We depend on the fact we won't be crossing the gap.)
6435 Check to see if the most recent message looks a lot like the previous one.
6436 Return 0 if different, 1 if the new one should just replace it, or a
6437 value N > 1 if we should also append " [N times]". */
6440 message_log_check_duplicate (prev_bol
, prev_bol_byte
, this_bol
, this_bol_byte
)
6441 int prev_bol
, this_bol
;
6442 int prev_bol_byte
, this_bol_byte
;
6445 int len
= Z_BYTE
- 1 - this_bol_byte
;
6447 unsigned char *p1
= BUF_BYTE_ADDRESS (current_buffer
, prev_bol_byte
);
6448 unsigned char *p2
= BUF_BYTE_ADDRESS (current_buffer
, this_bol_byte
);
6450 for (i
= 0; i
< len
; i
++)
6452 if (i
>= 3 && p1
[i
-3] == '.' && p1
[i
-2] == '.' && p1
[i
-1] == '.')
6460 if (*p1
++ == ' ' && *p1
++ == '[')
6463 while (*p1
>= '0' && *p1
<= '9')
6464 n
= n
* 10 + *p1
++ - '0';
6465 if (strncmp (p1
, " times]\n", 8) == 0)
6472 /* Display an echo area message M with a specified length of NBYTES
6473 bytes. The string may include null characters. If M is 0, clear
6474 out any existing message, and let the mini-buffer text show
6477 The buffer M must continue to exist until after the echo area gets
6478 cleared or some other message gets displayed there. This means do
6479 not pass text that is stored in a Lisp string; do not pass text in
6480 a buffer that was alloca'd. */
6483 message2 (m
, nbytes
, multibyte
)
6488 /* First flush out any partial line written with print. */
6489 message_log_maybe_newline ();
6491 message_dolog (m
, nbytes
, 1, multibyte
);
6492 message2_nolog (m
, nbytes
, multibyte
);
6496 /* The non-logging counterpart of message2. */
6499 message2_nolog (m
, nbytes
, multibyte
)
6501 int nbytes
, multibyte
;
6503 struct frame
*sf
= SELECTED_FRAME ();
6504 message_enable_multibyte
= multibyte
;
6508 if (noninteractive_need_newline
)
6509 putc ('\n', stderr
);
6510 noninteractive_need_newline
= 0;
6512 fwrite (m
, nbytes
, 1, stderr
);
6513 if (cursor_in_echo_area
== 0)
6514 fprintf (stderr
, "\n");
6517 /* A null message buffer means that the frame hasn't really been
6518 initialized yet. Error messages get reported properly by
6519 cmd_error, so this must be just an informative message; toss it. */
6520 else if (INTERACTIVE
6521 && sf
->glyphs_initialized_p
6522 && FRAME_MESSAGE_BUF (sf
))
6524 Lisp_Object mini_window
;
6527 /* Get the frame containing the mini-buffer
6528 that the selected frame is using. */
6529 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
6530 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
6532 FRAME_SAMPLE_VISIBILITY (f
);
6533 if (FRAME_VISIBLE_P (sf
)
6534 && ! FRAME_VISIBLE_P (f
))
6535 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window
)));
6539 set_message (m
, Qnil
, nbytes
, multibyte
);
6540 if (minibuffer_auto_raise
)
6541 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window
)));
6544 clear_message (1, 1);
6546 do_pending_window_change (0);
6547 echo_area_display (1);
6548 do_pending_window_change (0);
6549 if (frame_up_to_date_hook
!= 0 && ! gc_in_progress
)
6550 (*frame_up_to_date_hook
) (f
);
6555 /* Display an echo area message M with a specified length of NBYTES
6556 bytes. The string may include null characters. If M is not a
6557 string, clear out any existing message, and let the mini-buffer
6558 text show through. */
6561 message3 (m
, nbytes
, multibyte
)
6566 struct gcpro gcpro1
;
6570 /* First flush out any partial line written with print. */
6571 message_log_maybe_newline ();
6573 message_dolog (SDATA (m
), nbytes
, 1, multibyte
);
6574 message3_nolog (m
, nbytes
, multibyte
);
6580 /* The non-logging version of message3. */
6583 message3_nolog (m
, nbytes
, multibyte
)
6585 int nbytes
, multibyte
;
6587 struct frame
*sf
= SELECTED_FRAME ();
6588 message_enable_multibyte
= multibyte
;
6592 if (noninteractive_need_newline
)
6593 putc ('\n', stderr
);
6594 noninteractive_need_newline
= 0;
6596 fwrite (SDATA (m
), nbytes
, 1, stderr
);
6597 if (cursor_in_echo_area
== 0)
6598 fprintf (stderr
, "\n");
6601 /* A null message buffer means that the frame hasn't really been
6602 initialized yet. Error messages get reported properly by
6603 cmd_error, so this must be just an informative message; toss it. */
6604 else if (INTERACTIVE
6605 && sf
->glyphs_initialized_p
6606 && FRAME_MESSAGE_BUF (sf
))
6608 Lisp_Object mini_window
;
6612 /* Get the frame containing the mini-buffer
6613 that the selected frame is using. */
6614 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
6615 frame
= XWINDOW (mini_window
)->frame
;
6618 FRAME_SAMPLE_VISIBILITY (f
);
6619 if (FRAME_VISIBLE_P (sf
)
6620 && !FRAME_VISIBLE_P (f
))
6621 Fmake_frame_visible (frame
);
6623 if (STRINGP (m
) && SCHARS (m
) > 0)
6625 set_message (NULL
, m
, nbytes
, multibyte
);
6626 if (minibuffer_auto_raise
)
6627 Fraise_frame (frame
);
6630 clear_message (1, 1);
6632 do_pending_window_change (0);
6633 echo_area_display (1);
6634 do_pending_window_change (0);
6635 if (frame_up_to_date_hook
!= 0 && ! gc_in_progress
)
6636 (*frame_up_to_date_hook
) (f
);
6641 /* Display a null-terminated echo area message M. If M is 0, clear
6642 out any existing message, and let the mini-buffer text show through.
6644 The buffer M must continue to exist until after the echo area gets
6645 cleared or some other message gets displayed there. Do not pass
6646 text that is stored in a Lisp string. Do not pass text in a buffer
6647 that was alloca'd. */
6653 message2 (m
, (m
? strlen (m
) : 0), 0);
6657 /* The non-logging counterpart of message1. */
6663 message2_nolog (m
, (m
? strlen (m
) : 0), 0);
6666 /* Display a message M which contains a single %s
6667 which gets replaced with STRING. */
6670 message_with_string (m
, string
, log
)
6675 CHECK_STRING (string
);
6681 if (noninteractive_need_newline
)
6682 putc ('\n', stderr
);
6683 noninteractive_need_newline
= 0;
6684 fprintf (stderr
, m
, SDATA (string
));
6685 if (cursor_in_echo_area
== 0)
6686 fprintf (stderr
, "\n");
6690 else if (INTERACTIVE
)
6692 /* The frame whose minibuffer we're going to display the message on.
6693 It may be larger than the selected frame, so we need
6694 to use its buffer, not the selected frame's buffer. */
6695 Lisp_Object mini_window
;
6696 struct frame
*f
, *sf
= SELECTED_FRAME ();
6698 /* Get the frame containing the minibuffer
6699 that the selected frame is using. */
6700 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
6701 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
6703 /* A null message buffer means that the frame hasn't really been
6704 initialized yet. Error messages get reported properly by
6705 cmd_error, so this must be just an informative message; toss it. */
6706 if (FRAME_MESSAGE_BUF (f
))
6708 Lisp_Object args
[2], message
;
6709 struct gcpro gcpro1
, gcpro2
;
6711 args
[0] = build_string (m
);
6712 args
[1] = message
= string
;
6713 GCPRO2 (args
[0], message
);
6716 message
= Fformat (2, args
);
6719 message3 (message
, SBYTES (message
), STRING_MULTIBYTE (message
));
6721 message3_nolog (message
, SBYTES (message
), STRING_MULTIBYTE (message
));
6725 /* Print should start at the beginning of the message
6726 buffer next time. */
6727 message_buf_print
= 0;
6733 /* Dump an informative message to the minibuf. If M is 0, clear out
6734 any existing message, and let the mini-buffer text show through. */
6738 message (m
, a1
, a2
, a3
)
6740 EMACS_INT a1
, a2
, a3
;
6746 if (noninteractive_need_newline
)
6747 putc ('\n', stderr
);
6748 noninteractive_need_newline
= 0;
6749 fprintf (stderr
, m
, a1
, a2
, a3
);
6750 if (cursor_in_echo_area
== 0)
6751 fprintf (stderr
, "\n");
6755 else if (INTERACTIVE
)
6757 /* The frame whose mini-buffer we're going to display the message
6758 on. It may be larger than the selected frame, so we need to
6759 use its buffer, not the selected frame's buffer. */
6760 Lisp_Object mini_window
;
6761 struct frame
*f
, *sf
= SELECTED_FRAME ();
6763 /* Get the frame containing the mini-buffer
6764 that the selected frame is using. */
6765 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
6766 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
6768 /* A null message buffer means that the frame hasn't really been
6769 initialized yet. Error messages get reported properly by
6770 cmd_error, so this must be just an informative message; toss
6772 if (FRAME_MESSAGE_BUF (f
))
6783 len
= doprnt (FRAME_MESSAGE_BUF (f
),
6784 FRAME_MESSAGE_BUF_SIZE (f
), m
, (char *)0, 3, a
);
6786 len
= doprnt (FRAME_MESSAGE_BUF (f
),
6787 FRAME_MESSAGE_BUF_SIZE (f
), m
, (char *)0, 3,
6789 #endif /* NO_ARG_ARRAY */
6791 message2 (FRAME_MESSAGE_BUF (f
), len
, 0);
6796 /* Print should start at the beginning of the message
6797 buffer next time. */
6798 message_buf_print
= 0;
6804 /* The non-logging version of message. */
6807 message_nolog (m
, a1
, a2
, a3
)
6809 EMACS_INT a1
, a2
, a3
;
6811 Lisp_Object old_log_max
;
6812 old_log_max
= Vmessage_log_max
;
6813 Vmessage_log_max
= Qnil
;
6814 message (m
, a1
, a2
, a3
);
6815 Vmessage_log_max
= old_log_max
;
6819 /* Display the current message in the current mini-buffer. This is
6820 only called from error handlers in process.c, and is not time
6826 if (!NILP (echo_area_buffer
[0]))
6829 string
= Fcurrent_message ();
6830 message3 (string
, SBYTES (string
),
6831 !NILP (current_buffer
->enable_multibyte_characters
));
6836 /* Make sure echo area buffers in `echo_buffers' are live.
6837 If they aren't, make new ones. */
6840 ensure_echo_area_buffers ()
6844 for (i
= 0; i
< 2; ++i
)
6845 if (!BUFFERP (echo_buffer
[i
])
6846 || NILP (XBUFFER (echo_buffer
[i
])->name
))
6849 Lisp_Object old_buffer
;
6852 old_buffer
= echo_buffer
[i
];
6853 sprintf (name
, " *Echo Area %d*", i
);
6854 echo_buffer
[i
] = Fget_buffer_create (build_string (name
));
6855 XBUFFER (echo_buffer
[i
])->truncate_lines
= Qnil
;
6857 for (j
= 0; j
< 2; ++j
)
6858 if (EQ (old_buffer
, echo_area_buffer
[j
]))
6859 echo_area_buffer
[j
] = echo_buffer
[i
];
6864 /* Call FN with args A1..A4 with either the current or last displayed
6865 echo_area_buffer as current buffer.
6867 WHICH zero means use the current message buffer
6868 echo_area_buffer[0]. If that is nil, choose a suitable buffer
6869 from echo_buffer[] and clear it.
6871 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
6872 suitable buffer from echo_buffer[] and clear it.
6874 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
6875 that the current message becomes the last displayed one, make
6876 choose a suitable buffer for echo_area_buffer[0], and clear it.
6878 Value is what FN returns. */
6881 with_echo_area_buffer (w
, which
, fn
, a1
, a2
, a3
, a4
)
6884 int (*fn
) P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
6890 int this_one
, the_other
, clear_buffer_p
, rc
;
6891 int count
= SPECPDL_INDEX ();
6893 /* If buffers aren't live, make new ones. */
6894 ensure_echo_area_buffers ();
6899 this_one
= 0, the_other
= 1;
6901 this_one
= 1, the_other
= 0;
6904 this_one
= 0, the_other
= 1;
6907 /* We need a fresh one in case the current echo buffer equals
6908 the one containing the last displayed echo area message. */
6909 if (!NILP (echo_area_buffer
[this_one
])
6910 && EQ (echo_area_buffer
[this_one
], echo_area_buffer
[the_other
]))
6911 echo_area_buffer
[this_one
] = Qnil
;
6914 /* Choose a suitable buffer from echo_buffer[] is we don't
6916 if (NILP (echo_area_buffer
[this_one
]))
6918 echo_area_buffer
[this_one
]
6919 = (EQ (echo_area_buffer
[the_other
], echo_buffer
[this_one
])
6920 ? echo_buffer
[the_other
]
6921 : echo_buffer
[this_one
]);
6925 buffer
= echo_area_buffer
[this_one
];
6927 /* Don't get confused by reusing the buffer used for echoing
6928 for a different purpose. */
6929 if (echo_kboard
== NULL
&& EQ (buffer
, echo_message_buffer
))
6932 record_unwind_protect (unwind_with_echo_area_buffer
,
6933 with_echo_area_buffer_unwind_data (w
));
6935 /* Make the echo area buffer current. Note that for display
6936 purposes, it is not necessary that the displayed window's buffer
6937 == current_buffer, except for text property lookup. So, let's
6938 only set that buffer temporarily here without doing a full
6939 Fset_window_buffer. We must also change w->pointm, though,
6940 because otherwise an assertions in unshow_buffer fails, and Emacs
6942 set_buffer_internal_1 (XBUFFER (buffer
));
6946 set_marker_both (w
->pointm
, buffer
, BEG
, BEG_BYTE
);
6949 current_buffer
->undo_list
= Qt
;
6950 current_buffer
->read_only
= Qnil
;
6951 specbind (Qinhibit_read_only
, Qt
);
6952 specbind (Qinhibit_modification_hooks
, Qt
);
6954 if (clear_buffer_p
&& Z
> BEG
)
6957 xassert (BEGV
>= BEG
);
6958 xassert (ZV
<= Z
&& ZV
>= BEGV
);
6960 rc
= fn (a1
, a2
, a3
, a4
);
6962 xassert (BEGV
>= BEG
);
6963 xassert (ZV
<= Z
&& ZV
>= BEGV
);
6965 unbind_to (count
, Qnil
);
6970 /* Save state that should be preserved around the call to the function
6971 FN called in with_echo_area_buffer. */
6974 with_echo_area_buffer_unwind_data (w
)
6980 /* Reduce consing by keeping one vector in
6981 Vwith_echo_area_save_vector. */
6982 vector
= Vwith_echo_area_save_vector
;
6983 Vwith_echo_area_save_vector
= Qnil
;
6986 vector
= Fmake_vector (make_number (7), Qnil
);
6988 XSETBUFFER (AREF (vector
, i
), current_buffer
); ++i
;
6989 AREF (vector
, i
) = Vdeactivate_mark
, ++i
;
6990 AREF (vector
, i
) = make_number (windows_or_buffers_changed
), ++i
;
6994 XSETWINDOW (AREF (vector
, i
), w
); ++i
;
6995 AREF (vector
, i
) = w
->buffer
; ++i
;
6996 AREF (vector
, i
) = make_number (XMARKER (w
->pointm
)->charpos
); ++i
;
6997 AREF (vector
, i
) = make_number (XMARKER (w
->pointm
)->bytepos
); ++i
;
7002 for (; i
< end
; ++i
)
7003 AREF (vector
, i
) = Qnil
;
7006 xassert (i
== ASIZE (vector
));
7011 /* Restore global state from VECTOR which was created by
7012 with_echo_area_buffer_unwind_data. */
7015 unwind_with_echo_area_buffer (vector
)
7018 set_buffer_internal_1 (XBUFFER (AREF (vector
, 0)));
7019 Vdeactivate_mark
= AREF (vector
, 1);
7020 windows_or_buffers_changed
= XFASTINT (AREF (vector
, 2));
7022 if (WINDOWP (AREF (vector
, 3)))
7025 Lisp_Object buffer
, charpos
, bytepos
;
7027 w
= XWINDOW (AREF (vector
, 3));
7028 buffer
= AREF (vector
, 4);
7029 charpos
= AREF (vector
, 5);
7030 bytepos
= AREF (vector
, 6);
7033 set_marker_both (w
->pointm
, buffer
,
7034 XFASTINT (charpos
), XFASTINT (bytepos
));
7037 Vwith_echo_area_save_vector
= vector
;
7042 /* Set up the echo area for use by print functions. MULTIBYTE_P
7043 non-zero means we will print multibyte. */
7046 setup_echo_area_for_printing (multibyte_p
)
7049 /* If we can't find an echo area any more, exit. */
7050 if (! FRAME_LIVE_P (XFRAME (selected_frame
)))
7053 ensure_echo_area_buffers ();
7055 if (!message_buf_print
)
7057 /* A message has been output since the last time we printed.
7058 Choose a fresh echo area buffer. */
7059 if (EQ (echo_area_buffer
[1], echo_buffer
[0]))
7060 echo_area_buffer
[0] = echo_buffer
[1];
7062 echo_area_buffer
[0] = echo_buffer
[0];
7064 /* Switch to that buffer and clear it. */
7065 set_buffer_internal (XBUFFER (echo_area_buffer
[0]));
7066 current_buffer
->truncate_lines
= Qnil
;
7070 int count
= SPECPDL_INDEX ();
7071 specbind (Qinhibit_read_only
, Qt
);
7072 /* Note that undo recording is always disabled. */
7074 unbind_to (count
, Qnil
);
7076 TEMP_SET_PT_BOTH (BEG
, BEG_BYTE
);
7078 /* Set up the buffer for the multibyteness we need. */
7080 != !NILP (current_buffer
->enable_multibyte_characters
))
7081 Fset_buffer_multibyte (multibyte_p
? Qt
: Qnil
);
7083 /* Raise the frame containing the echo area. */
7084 if (minibuffer_auto_raise
)
7086 struct frame
*sf
= SELECTED_FRAME ();
7087 Lisp_Object mini_window
;
7088 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
7089 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window
)));
7092 message_log_maybe_newline ();
7093 message_buf_print
= 1;
7097 if (NILP (echo_area_buffer
[0]))
7099 if (EQ (echo_area_buffer
[1], echo_buffer
[0]))
7100 echo_area_buffer
[0] = echo_buffer
[1];
7102 echo_area_buffer
[0] = echo_buffer
[0];
7105 if (current_buffer
!= XBUFFER (echo_area_buffer
[0]))
7107 /* Someone switched buffers between print requests. */
7108 set_buffer_internal (XBUFFER (echo_area_buffer
[0]));
7109 current_buffer
->truncate_lines
= Qnil
;
7115 /* Display an echo area message in window W. Value is non-zero if W's
7116 height is changed. If display_last_displayed_message_p is
7117 non-zero, display the message that was last displayed, otherwise
7118 display the current message. */
7121 display_echo_area (w
)
7124 int i
, no_message_p
, window_height_changed_p
, count
;
7126 /* Temporarily disable garbage collections while displaying the echo
7127 area. This is done because a GC can print a message itself.
7128 That message would modify the echo area buffer's contents while a
7129 redisplay of the buffer is going on, and seriously confuse
7131 count
= inhibit_garbage_collection ();
7133 /* If there is no message, we must call display_echo_area_1
7134 nevertheless because it resizes the window. But we will have to
7135 reset the echo_area_buffer in question to nil at the end because
7136 with_echo_area_buffer will sets it to an empty buffer. */
7137 i
= display_last_displayed_message_p
? 1 : 0;
7138 no_message_p
= NILP (echo_area_buffer
[i
]);
7140 window_height_changed_p
7141 = with_echo_area_buffer (w
, display_last_displayed_message_p
,
7142 display_echo_area_1
,
7143 (EMACS_INT
) w
, Qnil
, 0, 0);
7146 echo_area_buffer
[i
] = Qnil
;
7148 unbind_to (count
, Qnil
);
7149 return window_height_changed_p
;
7153 /* Helper for display_echo_area. Display the current buffer which
7154 contains the current echo area message in window W, a mini-window,
7155 a pointer to which is passed in A1. A2..A4 are currently not used.
7156 Change the height of W so that all of the message is displayed.
7157 Value is non-zero if height of W was changed. */
7160 display_echo_area_1 (a1
, a2
, a3
, a4
)
7165 struct window
*w
= (struct window
*) a1
;
7167 struct text_pos start
;
7168 int window_height_changed_p
= 0;
7170 /* Do this before displaying, so that we have a large enough glyph
7171 matrix for the display. */
7172 window_height_changed_p
= resize_mini_window (w
, 0);
7175 clear_glyph_matrix (w
->desired_matrix
);
7176 XSETWINDOW (window
, w
);
7177 SET_TEXT_POS (start
, BEG
, BEG_BYTE
);
7178 try_window (window
, start
);
7180 return window_height_changed_p
;
7184 /* Resize the echo area window to exactly the size needed for the
7185 currently displayed message, if there is one. If a mini-buffer
7186 is active, don't shrink it. */
7189 resize_echo_area_exactly ()
7191 if (BUFFERP (echo_area_buffer
[0])
7192 && WINDOWP (echo_area_window
))
7194 struct window
*w
= XWINDOW (echo_area_window
);
7196 Lisp_Object resize_exactly
;
7198 if (minibuf_level
== 0)
7199 resize_exactly
= Qt
;
7201 resize_exactly
= Qnil
;
7203 resized_p
= with_echo_area_buffer (w
, 0, resize_mini_window_1
,
7204 (EMACS_INT
) w
, resize_exactly
, 0, 0);
7207 ++windows_or_buffers_changed
;
7208 ++update_mode_lines
;
7209 redisplay_internal (0);
7215 /* Callback function for with_echo_area_buffer, when used from
7216 resize_echo_area_exactly. A1 contains a pointer to the window to
7217 resize, EXACTLY non-nil means resize the mini-window exactly to the
7218 size of the text displayed. A3 and A4 are not used. Value is what
7219 resize_mini_window returns. */
7222 resize_mini_window_1 (a1
, exactly
, a3
, a4
)
7224 Lisp_Object exactly
;
7227 return resize_mini_window ((struct window
*) a1
, !NILP (exactly
));
7231 /* Resize mini-window W to fit the size of its contents. EXACT:P
7232 means size the window exactly to the size needed. Otherwise, it's
7233 only enlarged until W's buffer is empty. Value is non-zero if
7234 the window height has been changed. */
7237 resize_mini_window (w
, exact_p
)
7241 struct frame
*f
= XFRAME (w
->frame
);
7242 int window_height_changed_p
= 0;
7244 xassert (MINI_WINDOW_P (w
));
7246 /* Don't resize windows while redisplaying a window; it would
7247 confuse redisplay functions when the size of the window they are
7248 displaying changes from under them. Such a resizing can happen,
7249 for instance, when which-func prints a long message while
7250 we are running fontification-functions. We're running these
7251 functions with safe_call which binds inhibit-redisplay to t. */
7252 if (!NILP (Vinhibit_redisplay
))
7255 /* Nil means don't try to resize. */
7256 if (NILP (Vresize_mini_windows
)
7257 || (FRAME_X_P (f
) && FRAME_X_OUTPUT (f
) == NULL
))
7260 if (!FRAME_MINIBUF_ONLY_P (f
))
7263 struct window
*root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
7264 int total_height
= WINDOW_TOTAL_LINES (root
) + WINDOW_TOTAL_LINES (w
);
7265 int height
, max_height
;
7266 int unit
= FRAME_LINE_HEIGHT (f
);
7267 struct text_pos start
;
7268 struct buffer
*old_current_buffer
= NULL
;
7270 if (current_buffer
!= XBUFFER (w
->buffer
))
7272 old_current_buffer
= current_buffer
;
7273 set_buffer_internal (XBUFFER (w
->buffer
));
7276 init_iterator (&it
, w
, BEGV
, BEGV_BYTE
, NULL
, DEFAULT_FACE_ID
);
7278 /* Compute the max. number of lines specified by the user. */
7279 if (FLOATP (Vmax_mini_window_height
))
7280 max_height
= XFLOATINT (Vmax_mini_window_height
) * FRAME_LINES (f
);
7281 else if (INTEGERP (Vmax_mini_window_height
))
7282 max_height
= XINT (Vmax_mini_window_height
);
7284 max_height
= total_height
/ 4;
7286 /* Correct that max. height if it's bogus. */
7287 max_height
= max (1, max_height
);
7288 max_height
= min (total_height
, max_height
);
7290 /* Find out the height of the text in the window. */
7291 if (it
.truncate_lines_p
)
7296 move_it_to (&it
, ZV
, -1, -1, -1, MOVE_TO_POS
);
7297 if (it
.max_ascent
== 0 && it
.max_descent
== 0)
7298 height
= it
.current_y
+ last_height
;
7300 height
= it
.current_y
+ it
.max_ascent
+ it
.max_descent
;
7301 height
-= it
.extra_line_spacing
;
7302 height
= (height
+ unit
- 1) / unit
;
7305 /* Compute a suitable window start. */
7306 if (height
> max_height
)
7308 height
= max_height
;
7309 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
7310 move_it_vertically_backward (&it
, (height
- 1) * unit
);
7311 start
= it
.current
.pos
;
7314 SET_TEXT_POS (start
, BEGV
, BEGV_BYTE
);
7315 SET_MARKER_FROM_TEXT_POS (w
->start
, start
);
7317 if (EQ (Vresize_mini_windows
, Qgrow_only
))
7319 /* Let it grow only, until we display an empty message, in which
7320 case the window shrinks again. */
7321 if (height
> WINDOW_TOTAL_LINES (w
))
7323 int old_height
= WINDOW_TOTAL_LINES (w
);
7324 freeze_window_starts (f
, 1);
7325 grow_mini_window (w
, height
- WINDOW_TOTAL_LINES (w
));
7326 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
7328 else if (height
< WINDOW_TOTAL_LINES (w
)
7329 && (exact_p
|| BEGV
== ZV
))
7331 int old_height
= WINDOW_TOTAL_LINES (w
);
7332 freeze_window_starts (f
, 0);
7333 shrink_mini_window (w
);
7334 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
7339 /* Always resize to exact size needed. */
7340 if (height
> WINDOW_TOTAL_LINES (w
))
7342 int old_height
= WINDOW_TOTAL_LINES (w
);
7343 freeze_window_starts (f
, 1);
7344 grow_mini_window (w
, height
- WINDOW_TOTAL_LINES (w
));
7345 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
7347 else if (height
< WINDOW_TOTAL_LINES (w
))
7349 int old_height
= WINDOW_TOTAL_LINES (w
);
7350 freeze_window_starts (f
, 0);
7351 shrink_mini_window (w
);
7355 freeze_window_starts (f
, 1);
7356 grow_mini_window (w
, height
- WINDOW_TOTAL_LINES (w
));
7359 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
7363 if (old_current_buffer
)
7364 set_buffer_internal (old_current_buffer
);
7367 return window_height_changed_p
;
7371 /* Value is the current message, a string, or nil if there is no
7379 if (NILP (echo_area_buffer
[0]))
7383 with_echo_area_buffer (0, 0, current_message_1
,
7384 (EMACS_INT
) &msg
, Qnil
, 0, 0);
7386 echo_area_buffer
[0] = Qnil
;
7394 current_message_1 (a1
, a2
, a3
, a4
)
7399 Lisp_Object
*msg
= (Lisp_Object
*) a1
;
7402 *msg
= make_buffer_string (BEG
, Z
, 1);
7409 /* Push the current message on Vmessage_stack for later restauration
7410 by restore_message. Value is non-zero if the current message isn't
7411 empty. This is a relatively infrequent operation, so it's not
7412 worth optimizing. */
7418 msg
= current_message ();
7419 Vmessage_stack
= Fcons (msg
, Vmessage_stack
);
7420 return STRINGP (msg
);
7424 /* Restore message display from the top of Vmessage_stack. */
7431 xassert (CONSP (Vmessage_stack
));
7432 msg
= XCAR (Vmessage_stack
);
7434 message3_nolog (msg
, SBYTES (msg
), STRING_MULTIBYTE (msg
));
7436 message3_nolog (msg
, 0, 0);
7440 /* Handler for record_unwind_protect calling pop_message. */
7443 pop_message_unwind (dummy
)
7450 /* Pop the top-most entry off Vmessage_stack. */
7455 xassert (CONSP (Vmessage_stack
));
7456 Vmessage_stack
= XCDR (Vmessage_stack
);
7460 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
7461 exits. If the stack is not empty, we have a missing pop_message
7465 check_message_stack ()
7467 if (!NILP (Vmessage_stack
))
7472 /* Truncate to NCHARS what will be displayed in the echo area the next
7473 time we display it---but don't redisplay it now. */
7476 truncate_echo_area (nchars
)
7480 echo_area_buffer
[0] = Qnil
;
7481 /* A null message buffer means that the frame hasn't really been
7482 initialized yet. Error messages get reported properly by
7483 cmd_error, so this must be just an informative message; toss it. */
7484 else if (!noninteractive
7486 && !NILP (echo_area_buffer
[0]))
7488 struct frame
*sf
= SELECTED_FRAME ();
7489 if (FRAME_MESSAGE_BUF (sf
))
7490 with_echo_area_buffer (0, 0, truncate_message_1
, nchars
, Qnil
, 0, 0);
7495 /* Helper function for truncate_echo_area. Truncate the current
7496 message to at most NCHARS characters. */
7499 truncate_message_1 (nchars
, a2
, a3
, a4
)
7504 if (BEG
+ nchars
< Z
)
7505 del_range (BEG
+ nchars
, Z
);
7507 echo_area_buffer
[0] = Qnil
;
7512 /* Set the current message to a substring of S or STRING.
7514 If STRING is a Lisp string, set the message to the first NBYTES
7515 bytes from STRING. NBYTES zero means use the whole string. If
7516 STRING is multibyte, the message will be displayed multibyte.
7518 If S is not null, set the message to the first LEN bytes of S. LEN
7519 zero means use the whole string. MULTIBYTE_P non-zero means S is
7520 multibyte. Display the message multibyte in that case. */
7523 set_message (s
, string
, nbytes
, multibyte_p
)
7526 int nbytes
, multibyte_p
;
7528 message_enable_multibyte
7529 = ((s
&& multibyte_p
)
7530 || (STRINGP (string
) && STRING_MULTIBYTE (string
)));
7532 with_echo_area_buffer (0, -1, set_message_1
,
7533 (EMACS_INT
) s
, string
, nbytes
, multibyte_p
);
7534 message_buf_print
= 0;
7535 help_echo_showing_p
= 0;
7539 /* Helper function for set_message. Arguments have the same meaning
7540 as there, with A1 corresponding to S and A2 corresponding to STRING
7541 This function is called with the echo area buffer being
7545 set_message_1 (a1
, a2
, nbytes
, multibyte_p
)
7548 EMACS_INT nbytes
, multibyte_p
;
7550 const char *s
= (const char *) a1
;
7551 Lisp_Object string
= a2
;
7555 /* Change multibyteness of the echo buffer appropriately. */
7556 if (message_enable_multibyte
7557 != !NILP (current_buffer
->enable_multibyte_characters
))
7558 Fset_buffer_multibyte (message_enable_multibyte
? Qt
: Qnil
);
7560 current_buffer
->truncate_lines
= message_truncate_lines
? Qt
: Qnil
;
7562 /* Insert new message at BEG. */
7563 TEMP_SET_PT_BOTH (BEG
, BEG_BYTE
);
7565 if (STRINGP (string
))
7570 nbytes
= SBYTES (string
);
7571 nchars
= string_byte_to_char (string
, nbytes
);
7573 /* This function takes care of single/multibyte conversion. We
7574 just have to ensure that the echo area buffer has the right
7575 setting of enable_multibyte_characters. */
7576 insert_from_string (string
, 0, 0, nchars
, nbytes
, 1);
7581 nbytes
= strlen (s
);
7583 if (multibyte_p
&& NILP (current_buffer
->enable_multibyte_characters
))
7585 /* Convert from multi-byte to single-byte. */
7587 unsigned char work
[1];
7589 /* Convert a multibyte string to single-byte. */
7590 for (i
= 0; i
< nbytes
; i
+= n
)
7592 c
= string_char_and_length (s
+ i
, nbytes
- i
, &n
);
7593 work
[0] = (SINGLE_BYTE_CHAR_P (c
)
7595 : multibyte_char_to_unibyte (c
, Qnil
));
7596 insert_1_both (work
, 1, 1, 1, 0, 0);
7599 else if (!multibyte_p
7600 && !NILP (current_buffer
->enable_multibyte_characters
))
7602 /* Convert from single-byte to multi-byte. */
7604 const unsigned char *msg
= (const unsigned char *) s
;
7605 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
7607 /* Convert a single-byte string to multibyte. */
7608 for (i
= 0; i
< nbytes
; i
++)
7610 c
= unibyte_char_to_multibyte (msg
[i
]);
7611 n
= CHAR_STRING (c
, str
);
7612 insert_1_both (str
, 1, n
, 1, 0, 0);
7616 insert_1 (s
, nbytes
, 1, 0, 0);
7623 /* Clear messages. CURRENT_P non-zero means clear the current
7624 message. LAST_DISPLAYED_P non-zero means clear the message
7628 clear_message (current_p
, last_displayed_p
)
7629 int current_p
, last_displayed_p
;
7633 echo_area_buffer
[0] = Qnil
;
7634 message_cleared_p
= 1;
7637 if (last_displayed_p
)
7638 echo_area_buffer
[1] = Qnil
;
7640 message_buf_print
= 0;
7643 /* Clear garbaged frames.
7645 This function is used where the old redisplay called
7646 redraw_garbaged_frames which in turn called redraw_frame which in
7647 turn called clear_frame. The call to clear_frame was a source of
7648 flickering. I believe a clear_frame is not necessary. It should
7649 suffice in the new redisplay to invalidate all current matrices,
7650 and ensure a complete redisplay of all windows. */
7653 clear_garbaged_frames ()
7657 Lisp_Object tail
, frame
;
7658 int changed_count
= 0;
7660 FOR_EACH_FRAME (tail
, frame
)
7662 struct frame
*f
= XFRAME (frame
);
7664 if (FRAME_VISIBLE_P (f
) && FRAME_GARBAGED_P (f
))
7668 Fredraw_frame (frame
);
7669 f
->force_flush_display_p
= 1;
7671 clear_current_matrices (f
);
7680 ++windows_or_buffers_changed
;
7685 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
7686 is non-zero update selected_frame. Value is non-zero if the
7687 mini-windows height has been changed. */
7690 echo_area_display (update_frame_p
)
7693 Lisp_Object mini_window
;
7696 int window_height_changed_p
= 0;
7697 struct frame
*sf
= SELECTED_FRAME ();
7699 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
7700 w
= XWINDOW (mini_window
);
7701 f
= XFRAME (WINDOW_FRAME (w
));
7703 /* Don't display if frame is invisible or not yet initialized. */
7704 if (!FRAME_VISIBLE_P (f
) || !f
->glyphs_initialized_p
)
7707 /* The terminal frame is used as the first Emacs frame on the Mac OS. */
7709 #ifdef HAVE_WINDOW_SYSTEM
7710 /* When Emacs starts, selected_frame may be a visible terminal
7711 frame, even if we run under a window system. If we let this
7712 through, a message would be displayed on the terminal. */
7713 if (EQ (selected_frame
, Vterminal_frame
)
7714 && !NILP (Vwindow_system
))
7716 #endif /* HAVE_WINDOW_SYSTEM */
7719 /* Redraw garbaged frames. */
7721 clear_garbaged_frames ();
7723 if (!NILP (echo_area_buffer
[0]) || minibuf_level
== 0)
7725 echo_area_window
= mini_window
;
7726 window_height_changed_p
= display_echo_area (w
);
7727 w
->must_be_updated_p
= 1;
7729 /* Update the display, unless called from redisplay_internal.
7730 Also don't update the screen during redisplay itself. The
7731 update will happen at the end of redisplay, and an update
7732 here could cause confusion. */
7733 if (update_frame_p
&& !redisplaying_p
)
7737 /* If the display update has been interrupted by pending
7738 input, update mode lines in the frame. Due to the
7739 pending input, it might have been that redisplay hasn't
7740 been called, so that mode lines above the echo area are
7741 garbaged. This looks odd, so we prevent it here. */
7742 if (!display_completed
)
7743 n
= redisplay_mode_lines (FRAME_ROOT_WINDOW (f
), 0);
7745 if (window_height_changed_p
7746 /* Don't do this if Emacs is shutting down. Redisplay
7747 needs to run hooks. */
7748 && !NILP (Vrun_hooks
))
7750 /* Must update other windows. Likewise as in other
7751 cases, don't let this update be interrupted by
7753 int count
= SPECPDL_INDEX ();
7754 specbind (Qredisplay_dont_pause
, Qt
);
7755 windows_or_buffers_changed
= 1;
7756 redisplay_internal (0);
7757 unbind_to (count
, Qnil
);
7759 else if (FRAME_WINDOW_P (f
) && n
== 0)
7761 /* Window configuration is the same as before.
7762 Can do with a display update of the echo area,
7763 unless we displayed some mode lines. */
7764 update_single_window (w
, 1);
7765 rif
->flush_display (f
);
7768 update_frame (f
, 1, 1);
7770 /* If cursor is in the echo area, make sure that the next
7771 redisplay displays the minibuffer, so that the cursor will
7772 be replaced with what the minibuffer wants. */
7773 if (cursor_in_echo_area
)
7774 ++windows_or_buffers_changed
;
7777 else if (!EQ (mini_window
, selected_window
))
7778 windows_or_buffers_changed
++;
7780 /* Last displayed message is now the current message. */
7781 echo_area_buffer
[1] = echo_area_buffer
[0];
7783 /* Prevent redisplay optimization in redisplay_internal by resetting
7784 this_line_start_pos. This is done because the mini-buffer now
7785 displays the message instead of its buffer text. */
7786 if (EQ (mini_window
, selected_window
))
7787 CHARPOS (this_line_start_pos
) = 0;
7789 return window_height_changed_p
;
7794 /***********************************************************************
7796 ***********************************************************************/
7799 /* The frame title buffering code is also used by Fformat_mode_line.
7800 So it is not conditioned by HAVE_WINDOW_SYSTEM. */
7802 /* A buffer for constructing frame titles in it; allocated from the
7803 heap in init_xdisp and resized as needed in store_frame_title_char. */
7805 static char *frame_title_buf
;
7807 /* The buffer's end, and a current output position in it. */
7809 static char *frame_title_buf_end
;
7810 static char *frame_title_ptr
;
7813 /* Store a single character C for the frame title in frame_title_buf.
7814 Re-allocate frame_title_buf if necessary. */
7818 store_frame_title_char (char c
)
7820 store_frame_title_char (c
)
7824 /* If output position has reached the end of the allocated buffer,
7825 double the buffer's size. */
7826 if (frame_title_ptr
== frame_title_buf_end
)
7828 int len
= frame_title_ptr
- frame_title_buf
;
7829 int new_size
= 2 * len
* sizeof *frame_title_buf
;
7830 frame_title_buf
= (char *) xrealloc (frame_title_buf
, new_size
);
7831 frame_title_buf_end
= frame_title_buf
+ new_size
;
7832 frame_title_ptr
= frame_title_buf
+ len
;
7835 *frame_title_ptr
++ = c
;
7839 /* Store part of a frame title in frame_title_buf, beginning at
7840 frame_title_ptr. STR is the string to store. Do not copy
7841 characters that yield more columns than PRECISION; PRECISION <= 0
7842 means copy the whole string. Pad with spaces until FIELD_WIDTH
7843 number of characters have been copied; FIELD_WIDTH <= 0 means don't
7844 pad. Called from display_mode_element when it is used to build a
7848 store_frame_title (str
, field_width
, precision
)
7849 const unsigned char *str
;
7850 int field_width
, precision
;
7855 /* Copy at most PRECISION chars from STR. */
7856 nbytes
= strlen (str
);
7857 n
+= c_string_width (str
, nbytes
, precision
, &dummy
, &nbytes
);
7859 store_frame_title_char (*str
++);
7861 /* Fill up with spaces until FIELD_WIDTH reached. */
7862 while (field_width
> 0
7865 store_frame_title_char (' ');
7872 #ifdef HAVE_WINDOW_SYSTEM
7874 /* Set the title of FRAME, if it has changed. The title format is
7875 Vicon_title_format if FRAME is iconified, otherwise it is
7876 frame_title_format. */
7879 x_consider_frame_title (frame
)
7882 struct frame
*f
= XFRAME (frame
);
7884 if (FRAME_WINDOW_P (f
)
7885 || FRAME_MINIBUF_ONLY_P (f
)
7886 || f
->explicit_name
)
7888 /* Do we have more than one visible frame on this X display? */
7891 struct buffer
*obuf
;
7895 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCDR (tail
))
7897 Lisp_Object other_frame
= XCAR (tail
);
7898 struct frame
*tf
= XFRAME (other_frame
);
7901 && FRAME_KBOARD (tf
) == FRAME_KBOARD (f
)
7902 && !FRAME_MINIBUF_ONLY_P (tf
)
7903 && !EQ (other_frame
, tip_frame
)
7904 && (FRAME_VISIBLE_P (tf
) || FRAME_ICONIFIED_P (tf
)))
7908 /* Set global variable indicating that multiple frames exist. */
7909 multiple_frames
= CONSP (tail
);
7911 /* Switch to the buffer of selected window of the frame. Set up
7912 frame_title_ptr so that display_mode_element will output into it;
7913 then display the title. */
7914 obuf
= current_buffer
;
7915 set_buffer_internal_1 (XBUFFER (XWINDOW (f
->selected_window
)->buffer
));
7916 fmt
= FRAME_ICONIFIED_P (f
) ? Vicon_title_format
: Vframe_title_format
;
7917 frame_title_ptr
= frame_title_buf
;
7918 init_iterator (&it
, XWINDOW (f
->selected_window
), -1, -1,
7919 NULL
, DEFAULT_FACE_ID
);
7920 display_mode_element (&it
, 0, -1, -1, fmt
, Qnil
, 0);
7921 len
= frame_title_ptr
- frame_title_buf
;
7922 frame_title_ptr
= NULL
;
7923 set_buffer_internal_1 (obuf
);
7925 /* Set the title only if it's changed. This avoids consing in
7926 the common case where it hasn't. (If it turns out that we've
7927 already wasted too much time by walking through the list with
7928 display_mode_element, then we might need to optimize at a
7929 higher level than this.) */
7930 if (! STRINGP (f
->name
)
7931 || SBYTES (f
->name
) != len
7932 || bcmp (frame_title_buf
, SDATA (f
->name
), len
) != 0)
7933 x_implicitly_set_name (f
, make_string (frame_title_buf
, len
), Qnil
);
7937 #endif /* not HAVE_WINDOW_SYSTEM */
7942 /***********************************************************************
7944 ***********************************************************************/
7947 /* Prepare for redisplay by updating menu-bar item lists when
7948 appropriate. This can call eval. */
7951 prepare_menu_bars ()
7954 struct gcpro gcpro1
, gcpro2
;
7956 Lisp_Object tooltip_frame
;
7958 #ifdef HAVE_WINDOW_SYSTEM
7959 tooltip_frame
= tip_frame
;
7961 tooltip_frame
= Qnil
;
7964 /* Update all frame titles based on their buffer names, etc. We do
7965 this before the menu bars so that the buffer-menu will show the
7966 up-to-date frame titles. */
7967 #ifdef HAVE_WINDOW_SYSTEM
7968 if (windows_or_buffers_changed
|| update_mode_lines
)
7970 Lisp_Object tail
, frame
;
7972 FOR_EACH_FRAME (tail
, frame
)
7975 if (!EQ (frame
, tooltip_frame
)
7976 && (FRAME_VISIBLE_P (f
) || FRAME_ICONIFIED_P (f
)))
7977 x_consider_frame_title (frame
);
7980 #endif /* HAVE_WINDOW_SYSTEM */
7982 /* Update the menu bar item lists, if appropriate. This has to be
7983 done before any actual redisplay or generation of display lines. */
7984 all_windows
= (update_mode_lines
7985 || buffer_shared
> 1
7986 || windows_or_buffers_changed
);
7989 Lisp_Object tail
, frame
;
7990 int count
= SPECPDL_INDEX ();
7992 record_unwind_protect (Fset_match_data
, Fmatch_data (Qnil
, Qnil
));
7994 FOR_EACH_FRAME (tail
, frame
)
7998 /* Ignore tooltip frame. */
7999 if (EQ (frame
, tooltip_frame
))
8002 /* If a window on this frame changed size, report that to
8003 the user and clear the size-change flag. */
8004 if (FRAME_WINDOW_SIZES_CHANGED (f
))
8006 Lisp_Object functions
;
8008 /* Clear flag first in case we get an error below. */
8009 FRAME_WINDOW_SIZES_CHANGED (f
) = 0;
8010 functions
= Vwindow_size_change_functions
;
8011 GCPRO2 (tail
, functions
);
8013 while (CONSP (functions
))
8015 call1 (XCAR (functions
), frame
);
8016 functions
= XCDR (functions
);
8022 update_menu_bar (f
, 0);
8023 #ifdef HAVE_WINDOW_SYSTEM
8024 update_tool_bar (f
, 0);
8029 unbind_to (count
, Qnil
);
8033 struct frame
*sf
= SELECTED_FRAME ();
8034 update_menu_bar (sf
, 1);
8035 #ifdef HAVE_WINDOW_SYSTEM
8036 update_tool_bar (sf
, 1);
8040 /* Motif needs this. See comment in xmenu.c. Turn it off when
8041 pending_menu_activation is not defined. */
8042 #ifdef USE_X_TOOLKIT
8043 pending_menu_activation
= 0;
8048 /* Update the menu bar item list for frame F. This has to be done
8049 before we start to fill in any display lines, because it can call
8052 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
8055 update_menu_bar (f
, save_match_data
)
8057 int save_match_data
;
8060 register struct window
*w
;
8062 /* If called recursively during a menu update, do nothing. This can
8063 happen when, for instance, an activate-menubar-hook causes a
8065 if (inhibit_menubar_update
)
8068 window
= FRAME_SELECTED_WINDOW (f
);
8069 w
= XWINDOW (window
);
8071 #if 0 /* The if statement below this if statement used to include the
8072 condition !NILP (w->update_mode_line), rather than using
8073 update_mode_lines directly, and this if statement may have
8074 been added to make that condition work. Now the if
8075 statement below matches its comment, this isn't needed. */
8076 if (update_mode_lines
)
8077 w
->update_mode_line
= Qt
;
8080 if (FRAME_WINDOW_P (f
)
8082 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8083 || defined (USE_GTK)
8084 FRAME_EXTERNAL_MENU_BAR (f
)
8086 FRAME_MENU_BAR_LINES (f
) > 0
8088 : FRAME_MENU_BAR_LINES (f
) > 0)
8090 /* If the user has switched buffers or windows, we need to
8091 recompute to reflect the new bindings. But we'll
8092 recompute when update_mode_lines is set too; that means
8093 that people can use force-mode-line-update to request
8094 that the menu bar be recomputed. The adverse effect on
8095 the rest of the redisplay algorithm is about the same as
8096 windows_or_buffers_changed anyway. */
8097 if (windows_or_buffers_changed
8098 /* This used to test w->update_mode_line, but we believe
8099 there is no need to recompute the menu in that case. */
8100 || update_mode_lines
8101 || ((BUF_SAVE_MODIFF (XBUFFER (w
->buffer
))
8102 < BUF_MODIFF (XBUFFER (w
->buffer
)))
8103 != !NILP (w
->last_had_star
))
8104 || ((!NILP (Vtransient_mark_mode
)
8105 && !NILP (XBUFFER (w
->buffer
)->mark_active
))
8106 != !NILP (w
->region_showing
)))
8108 struct buffer
*prev
= current_buffer
;
8109 int count
= SPECPDL_INDEX ();
8111 specbind (Qinhibit_menubar_update
, Qt
);
8113 set_buffer_internal_1 (XBUFFER (w
->buffer
));
8114 if (save_match_data
)
8115 record_unwind_protect (Fset_match_data
, Fmatch_data (Qnil
, Qnil
));
8116 if (NILP (Voverriding_local_map_menu_flag
))
8118 specbind (Qoverriding_terminal_local_map
, Qnil
);
8119 specbind (Qoverriding_local_map
, Qnil
);
8122 /* Run the Lucid hook. */
8123 safe_run_hooks (Qactivate_menubar_hook
);
8125 /* If it has changed current-menubar from previous value,
8126 really recompute the menu-bar from the value. */
8127 if (! NILP (Vlucid_menu_bar_dirty_flag
))
8128 call0 (Qrecompute_lucid_menubar
);
8130 safe_run_hooks (Qmenu_bar_update_hook
);
8131 FRAME_MENU_BAR_ITEMS (f
) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f
));
8133 /* Redisplay the menu bar in case we changed it. */
8134 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8135 || defined (USE_GTK)
8136 if (FRAME_WINDOW_P (f
)
8137 #if defined (MAC_OS)
8138 /* All frames on Mac OS share the same menubar. So only the
8139 selected frame should be allowed to set it. */
8140 && f
== SELECTED_FRAME ()
8143 set_frame_menubar (f
, 0, 0);
8145 /* On a terminal screen, the menu bar is an ordinary screen
8146 line, and this makes it get updated. */
8147 w
->update_mode_line
= Qt
;
8148 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8149 /* In the non-toolkit version, the menu bar is an ordinary screen
8150 line, and this makes it get updated. */
8151 w
->update_mode_line
= Qt
;
8152 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8154 unbind_to (count
, Qnil
);
8155 set_buffer_internal_1 (prev
);
8162 /***********************************************************************
8164 ***********************************************************************/
8166 #ifdef HAVE_WINDOW_SYSTEM
8169 Nominal cursor position -- where to draw output.
8170 HPOS and VPOS are window relative glyph matrix coordinates.
8171 X and Y are window relative pixel coordinates. */
8173 struct cursor_pos output_cursor
;
8177 Set the global variable output_cursor to CURSOR. All cursor
8178 positions are relative to updated_window. */
8181 set_output_cursor (cursor
)
8182 struct cursor_pos
*cursor
;
8184 output_cursor
.hpos
= cursor
->hpos
;
8185 output_cursor
.vpos
= cursor
->vpos
;
8186 output_cursor
.x
= cursor
->x
;
8187 output_cursor
.y
= cursor
->y
;
8192 Set a nominal cursor position.
8194 HPOS and VPOS are column/row positions in a window glyph matrix. X
8195 and Y are window text area relative pixel positions.
8197 If this is done during an update, updated_window will contain the
8198 window that is being updated and the position is the future output
8199 cursor position for that window. If updated_window is null, use
8200 selected_window and display the cursor at the given position. */
8203 x_cursor_to (vpos
, hpos
, y
, x
)
8204 int vpos
, hpos
, y
, x
;
8208 /* If updated_window is not set, work on selected_window. */
8212 w
= XWINDOW (selected_window
);
8214 /* Set the output cursor. */
8215 output_cursor
.hpos
= hpos
;
8216 output_cursor
.vpos
= vpos
;
8217 output_cursor
.x
= x
;
8218 output_cursor
.y
= y
;
8220 /* If not called as part of an update, really display the cursor.
8221 This will also set the cursor position of W. */
8222 if (updated_window
== NULL
)
8225 display_and_set_cursor (w
, 1, hpos
, vpos
, x
, y
);
8226 if (rif
->flush_display_optional
)
8227 rif
->flush_display_optional (SELECTED_FRAME ());
8232 #endif /* HAVE_WINDOW_SYSTEM */
8235 /***********************************************************************
8237 ***********************************************************************/
8239 #ifdef HAVE_WINDOW_SYSTEM
8241 /* Where the mouse was last time we reported a mouse event. */
8243 FRAME_PTR last_mouse_frame
;
8245 /* Tool-bar item index of the item on which a mouse button was pressed
8248 int last_tool_bar_item
;
8251 /* Update the tool-bar item list for frame F. This has to be done
8252 before we start to fill in any display lines. Called from
8253 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
8254 and restore it here. */
8257 update_tool_bar (f
, save_match_data
)
8259 int save_match_data
;
8262 int do_update
= FRAME_EXTERNAL_TOOL_BAR (f
);
8264 int do_update
= WINDOWP (f
->tool_bar_window
)
8265 && WINDOW_TOTAL_LINES (XWINDOW (f
->tool_bar_window
)) > 0;
8273 window
= FRAME_SELECTED_WINDOW (f
);
8274 w
= XWINDOW (window
);
8276 /* If the user has switched buffers or windows, we need to
8277 recompute to reflect the new bindings. But we'll
8278 recompute when update_mode_lines is set too; that means
8279 that people can use force-mode-line-update to request
8280 that the menu bar be recomputed. The adverse effect on
8281 the rest of the redisplay algorithm is about the same as
8282 windows_or_buffers_changed anyway. */
8283 if (windows_or_buffers_changed
8284 || !NILP (w
->update_mode_line
)
8285 || update_mode_lines
8286 || ((BUF_SAVE_MODIFF (XBUFFER (w
->buffer
))
8287 < BUF_MODIFF (XBUFFER (w
->buffer
)))
8288 != !NILP (w
->last_had_star
))
8289 || ((!NILP (Vtransient_mark_mode
)
8290 && !NILP (XBUFFER (w
->buffer
)->mark_active
))
8291 != !NILP (w
->region_showing
)))
8293 struct buffer
*prev
= current_buffer
;
8294 int count
= SPECPDL_INDEX ();
8295 Lisp_Object old_tool_bar
;
8296 struct gcpro gcpro1
;
8298 /* Set current_buffer to the buffer of the selected
8299 window of the frame, so that we get the right local
8301 set_buffer_internal_1 (XBUFFER (w
->buffer
));
8303 /* Save match data, if we must. */
8304 if (save_match_data
)
8305 record_unwind_protect (Fset_match_data
, Fmatch_data (Qnil
, Qnil
));
8307 /* Make sure that we don't accidentally use bogus keymaps. */
8308 if (NILP (Voverriding_local_map_menu_flag
))
8310 specbind (Qoverriding_terminal_local_map
, Qnil
);
8311 specbind (Qoverriding_local_map
, Qnil
);
8314 old_tool_bar
= f
->tool_bar_items
;
8315 GCPRO1 (old_tool_bar
);
8317 /* Build desired tool-bar items from keymaps. */
8320 = tool_bar_items (f
->tool_bar_items
, &f
->n_tool_bar_items
);
8323 /* Redisplay the tool-bar if we changed it. */
8324 if (! NILP (Fequal (old_tool_bar
, f
->tool_bar_items
)))
8325 w
->update_mode_line
= Qt
;
8329 unbind_to (count
, Qnil
);
8330 set_buffer_internal_1 (prev
);
8336 /* Set F->desired_tool_bar_string to a Lisp string representing frame
8337 F's desired tool-bar contents. F->tool_bar_items must have
8338 been set up previously by calling prepare_menu_bars. */
8341 build_desired_tool_bar_string (f
)
8344 int i
, size
, size_needed
;
8345 struct gcpro gcpro1
, gcpro2
, gcpro3
;
8346 Lisp_Object image
, plist
, props
;
8348 image
= plist
= props
= Qnil
;
8349 GCPRO3 (image
, plist
, props
);
8351 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
8352 Otherwise, make a new string. */
8354 /* The size of the string we might be able to reuse. */
8355 size
= (STRINGP (f
->desired_tool_bar_string
)
8356 ? SCHARS (f
->desired_tool_bar_string
)
8359 /* We need one space in the string for each image. */
8360 size_needed
= f
->n_tool_bar_items
;
8362 /* Reuse f->desired_tool_bar_string, if possible. */
8363 if (size
< size_needed
|| NILP (f
->desired_tool_bar_string
))
8364 f
->desired_tool_bar_string
= Fmake_string (make_number (size_needed
),
8368 props
= list4 (Qdisplay
, Qnil
, Qmenu_item
, Qnil
);
8369 Fremove_text_properties (make_number (0), make_number (size
),
8370 props
, f
->desired_tool_bar_string
);
8373 /* Put a `display' property on the string for the images to display,
8374 put a `menu_item' property on tool-bar items with a value that
8375 is the index of the item in F's tool-bar item vector. */
8376 for (i
= 0; i
< f
->n_tool_bar_items
; ++i
)
8378 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
8380 int enabled_p
= !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P
));
8381 int selected_p
= !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P
));
8382 int hmargin
, vmargin
, relief
, idx
, end
;
8383 extern Lisp_Object QCrelief
, QCmargin
, QCconversion
;
8385 /* If image is a vector, choose the image according to the
8387 image
= PROP (TOOL_BAR_ITEM_IMAGES
);
8388 if (VECTORP (image
))
8392 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
8393 : TOOL_BAR_IMAGE_ENABLED_DESELECTED
);
8396 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
8397 : TOOL_BAR_IMAGE_DISABLED_DESELECTED
);
8399 xassert (ASIZE (image
) >= idx
);
8400 image
= AREF (image
, idx
);
8405 /* Ignore invalid image specifications. */
8406 if (!valid_image_p (image
))
8409 /* Display the tool-bar button pressed, or depressed. */
8410 plist
= Fcopy_sequence (XCDR (image
));
8412 /* Compute margin and relief to draw. */
8413 relief
= (tool_bar_button_relief
>= 0
8414 ? tool_bar_button_relief
8415 : DEFAULT_TOOL_BAR_BUTTON_RELIEF
);
8416 hmargin
= vmargin
= relief
;
8418 if (INTEGERP (Vtool_bar_button_margin
)
8419 && XINT (Vtool_bar_button_margin
) > 0)
8421 hmargin
+= XFASTINT (Vtool_bar_button_margin
);
8422 vmargin
+= XFASTINT (Vtool_bar_button_margin
);
8424 else if (CONSP (Vtool_bar_button_margin
))
8426 if (INTEGERP (XCAR (Vtool_bar_button_margin
))
8427 && XINT (XCAR (Vtool_bar_button_margin
)) > 0)
8428 hmargin
+= XFASTINT (XCAR (Vtool_bar_button_margin
));
8430 if (INTEGERP (XCDR (Vtool_bar_button_margin
))
8431 && XINT (XCDR (Vtool_bar_button_margin
)) > 0)
8432 vmargin
+= XFASTINT (XCDR (Vtool_bar_button_margin
));
8435 if (auto_raise_tool_bar_buttons_p
)
8437 /* Add a `:relief' property to the image spec if the item is
8441 plist
= Fplist_put (plist
, QCrelief
, make_number (-relief
));
8448 /* If image is selected, display it pressed, i.e. with a
8449 negative relief. If it's not selected, display it with a
8451 plist
= Fplist_put (plist
, QCrelief
,
8453 ? make_number (-relief
)
8454 : make_number (relief
)));
8459 /* Put a margin around the image. */
8460 if (hmargin
|| vmargin
)
8462 if (hmargin
== vmargin
)
8463 plist
= Fplist_put (plist
, QCmargin
, make_number (hmargin
));
8465 plist
= Fplist_put (plist
, QCmargin
,
8466 Fcons (make_number (hmargin
),
8467 make_number (vmargin
)));
8470 /* If button is not enabled, and we don't have special images
8471 for the disabled state, make the image appear disabled by
8472 applying an appropriate algorithm to it. */
8473 if (!enabled_p
&& idx
< 0)
8474 plist
= Fplist_put (plist
, QCconversion
, Qdisabled
);
8476 /* Put a `display' text property on the string for the image to
8477 display. Put a `menu-item' property on the string that gives
8478 the start of this item's properties in the tool-bar items
8480 image
= Fcons (Qimage
, plist
);
8481 props
= list4 (Qdisplay
, image
,
8482 Qmenu_item
, make_number (i
* TOOL_BAR_ITEM_NSLOTS
));
8484 /* Let the last image hide all remaining spaces in the tool bar
8485 string. The string can be longer than needed when we reuse a
8487 if (i
+ 1 == f
->n_tool_bar_items
)
8488 end
= SCHARS (f
->desired_tool_bar_string
);
8491 Fadd_text_properties (make_number (i
), make_number (end
),
8492 props
, f
->desired_tool_bar_string
);
8500 /* Display one line of the tool-bar of frame IT->f. */
8503 display_tool_bar_line (it
)
8506 struct glyph_row
*row
= it
->glyph_row
;
8507 int max_x
= it
->last_visible_x
;
8510 prepare_desired_row (row
);
8511 row
->y
= it
->current_y
;
8513 /* Note that this isn't made use of if the face hasn't a box,
8514 so there's no need to check the face here. */
8515 it
->start_of_box_run_p
= 1;
8517 while (it
->current_x
< max_x
)
8519 int x_before
, x
, n_glyphs_before
, i
, nglyphs
;
8521 /* Get the next display element. */
8522 if (!get_next_display_element (it
))
8525 /* Produce glyphs. */
8526 x_before
= it
->current_x
;
8527 n_glyphs_before
= it
->glyph_row
->used
[TEXT_AREA
];
8528 PRODUCE_GLYPHS (it
);
8530 nglyphs
= it
->glyph_row
->used
[TEXT_AREA
] - n_glyphs_before
;
8535 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
8537 if (x
+ glyph
->pixel_width
> max_x
)
8539 /* Glyph doesn't fit on line. */
8540 it
->glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
+ i
;
8546 x
+= glyph
->pixel_width
;
8550 /* Stop at line ends. */
8551 if (ITERATOR_AT_END_OF_LINE_P (it
))
8554 set_iterator_to_next (it
, 1);
8559 row
->displays_text_p
= row
->used
[TEXT_AREA
] != 0;
8560 extend_face_to_end_of_line (it
);
8561 last
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
] - 1;
8562 last
->right_box_line_p
= 1;
8563 if (last
== row
->glyphs
[TEXT_AREA
])
8564 last
->left_box_line_p
= 1;
8565 compute_line_metrics (it
);
8567 /* If line is empty, make it occupy the rest of the tool-bar. */
8568 if (!row
->displays_text_p
)
8570 row
->height
= row
->phys_height
= it
->last_visible_y
- row
->y
;
8571 row
->ascent
= row
->phys_ascent
= 0;
8574 row
->full_width_p
= 1;
8575 row
->continued_p
= 0;
8576 row
->truncated_on_left_p
= 0;
8577 row
->truncated_on_right_p
= 0;
8579 it
->current_x
= it
->hpos
= 0;
8580 it
->current_y
+= row
->height
;
8586 /* Value is the number of screen lines needed to make all tool-bar
8587 items of frame F visible. */
8590 tool_bar_lines_needed (f
)
8593 struct window
*w
= XWINDOW (f
->tool_bar_window
);
8596 /* Initialize an iterator for iteration over
8597 F->desired_tool_bar_string in the tool-bar window of frame F. */
8598 init_iterator (&it
, w
, -1, -1, w
->desired_matrix
->rows
, TOOL_BAR_FACE_ID
);
8599 it
.first_visible_x
= 0;
8600 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
8601 reseat_to_string (&it
, NULL
, f
->desired_tool_bar_string
, 0, 0, 0, -1);
8603 while (!ITERATOR_AT_END_P (&it
))
8605 it
.glyph_row
= w
->desired_matrix
->rows
;
8606 clear_glyph_row (it
.glyph_row
);
8607 display_tool_bar_line (&it
);
8610 return (it
.current_y
+ FRAME_LINE_HEIGHT (f
) - 1) / FRAME_LINE_HEIGHT (f
);
8614 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed
, Stool_bar_lines_needed
,
8616 doc
: /* Return the number of lines occupied by the tool bar of FRAME. */)
8625 frame
= selected_frame
;
8627 CHECK_FRAME (frame
);
8630 if (WINDOWP (f
->tool_bar_window
)
8631 || (w
= XWINDOW (f
->tool_bar_window
),
8632 WINDOW_TOTAL_LINES (w
) > 0))
8634 update_tool_bar (f
, 1);
8635 if (f
->n_tool_bar_items
)
8637 build_desired_tool_bar_string (f
);
8638 nlines
= tool_bar_lines_needed (f
);
8642 return make_number (nlines
);
8646 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
8647 height should be changed. */
8650 redisplay_tool_bar (f
)
8655 struct glyph_row
*row
;
8656 int change_height_p
= 0;
8659 if (FRAME_EXTERNAL_TOOL_BAR (f
))
8660 update_frame_tool_bar (f
);
8664 /* If frame hasn't a tool-bar window or if it is zero-height, don't
8665 do anything. This means you must start with tool-bar-lines
8666 non-zero to get the auto-sizing effect. Or in other words, you
8667 can turn off tool-bars by specifying tool-bar-lines zero. */
8668 if (!WINDOWP (f
->tool_bar_window
)
8669 || (w
= XWINDOW (f
->tool_bar_window
),
8670 WINDOW_TOTAL_LINES (w
) == 0))
8673 /* Set up an iterator for the tool-bar window. */
8674 init_iterator (&it
, w
, -1, -1, w
->desired_matrix
->rows
, TOOL_BAR_FACE_ID
);
8675 it
.first_visible_x
= 0;
8676 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
8679 /* Build a string that represents the contents of the tool-bar. */
8680 build_desired_tool_bar_string (f
);
8681 reseat_to_string (&it
, NULL
, f
->desired_tool_bar_string
, 0, 0, 0, -1);
8683 /* Display as many lines as needed to display all tool-bar items. */
8684 while (it
.current_y
< it
.last_visible_y
)
8685 display_tool_bar_line (&it
);
8687 /* It doesn't make much sense to try scrolling in the tool-bar
8688 window, so don't do it. */
8689 w
->desired_matrix
->no_scrolling_p
= 1;
8690 w
->must_be_updated_p
= 1;
8692 if (auto_resize_tool_bars_p
)
8696 /* If we couldn't display everything, change the tool-bar's
8698 if (IT_STRING_CHARPOS (it
) < it
.end_charpos
)
8699 change_height_p
= 1;
8701 /* If there are blank lines at the end, except for a partially
8702 visible blank line at the end that is smaller than
8703 FRAME_LINE_HEIGHT, change the tool-bar's height. */
8704 row
= it
.glyph_row
- 1;
8705 if (!row
->displays_text_p
8706 && row
->height
>= FRAME_LINE_HEIGHT (f
))
8707 change_height_p
= 1;
8709 /* If row displays tool-bar items, but is partially visible,
8710 change the tool-bar's height. */
8711 if (row
->displays_text_p
8712 && MATRIX_ROW_BOTTOM_Y (row
) > it
.last_visible_y
)
8713 change_height_p
= 1;
8715 /* Resize windows as needed by changing the `tool-bar-lines'
8718 && (nlines
= tool_bar_lines_needed (f
),
8719 nlines
!= WINDOW_TOTAL_LINES (w
)))
8721 extern Lisp_Object Qtool_bar_lines
;
8723 int old_height
= WINDOW_TOTAL_LINES (w
);
8725 XSETFRAME (frame
, f
);
8726 clear_glyph_matrix (w
->desired_matrix
);
8727 Fmodify_frame_parameters (frame
,
8728 Fcons (Fcons (Qtool_bar_lines
,
8729 make_number (nlines
)),
8731 if (WINDOW_TOTAL_LINES (w
) != old_height
)
8732 fonts_changed_p
= 1;
8736 return change_height_p
;
8740 /* Get information about the tool-bar item which is displayed in GLYPH
8741 on frame F. Return in *PROP_IDX the index where tool-bar item
8742 properties start in F->tool_bar_items. Value is zero if
8743 GLYPH doesn't display a tool-bar item. */
8746 tool_bar_item_info (f
, glyph
, prop_idx
)
8748 struct glyph
*glyph
;
8755 /* This function can be called asynchronously, which means we must
8756 exclude any possibility that Fget_text_property signals an
8758 charpos
= min (SCHARS (f
->current_tool_bar_string
), glyph
->charpos
);
8759 charpos
= max (0, charpos
);
8761 /* Get the text property `menu-item' at pos. The value of that
8762 property is the start index of this item's properties in
8763 F->tool_bar_items. */
8764 prop
= Fget_text_property (make_number (charpos
),
8765 Qmenu_item
, f
->current_tool_bar_string
);
8766 if (INTEGERP (prop
))
8768 *prop_idx
= XINT (prop
);
8778 /* Get information about the tool-bar item at position X/Y on frame F.
8779 Return in *GLYPH a pointer to the glyph of the tool-bar item in
8780 the current matrix of the tool-bar window of F, or NULL if not
8781 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
8782 item in F->tool_bar_items. Value is
8784 -1 if X/Y is not on a tool-bar item
8785 0 if X/Y is on the same item that was highlighted before.
8789 get_tool_bar_item (f
, x
, y
, glyph
, hpos
, vpos
, prop_idx
)
8792 struct glyph
**glyph
;
8793 int *hpos
, *vpos
, *prop_idx
;
8795 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
8796 struct window
*w
= XWINDOW (f
->tool_bar_window
);
8799 /* Find the glyph under X/Y. */
8800 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, 0, 0, &area
);
8804 /* Get the start of this tool-bar item's properties in
8805 f->tool_bar_items. */
8806 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
8809 /* Is mouse on the highlighted item? */
8810 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
8811 && *vpos
>= dpyinfo
->mouse_face_beg_row
8812 && *vpos
<= dpyinfo
->mouse_face_end_row
8813 && (*vpos
> dpyinfo
->mouse_face_beg_row
8814 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
8815 && (*vpos
< dpyinfo
->mouse_face_end_row
8816 || *hpos
< dpyinfo
->mouse_face_end_col
8817 || dpyinfo
->mouse_face_past_end
))
8825 Handle mouse button event on the tool-bar of frame F, at
8826 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
8827 0 for button release. MODIFIERS is event modifiers for button
8831 handle_tool_bar_click (f
, x
, y
, down_p
, modifiers
)
8834 unsigned int modifiers
;
8836 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
8837 struct window
*w
= XWINDOW (f
->tool_bar_window
);
8838 int hpos
, vpos
, prop_idx
;
8839 struct glyph
*glyph
;
8840 Lisp_Object enabled_p
;
8842 /* If not on the highlighted tool-bar item, return. */
8843 frame_to_window_pixel_xy (w
, &x
, &y
);
8844 if (get_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
8847 /* If item is disabled, do nothing. */
8848 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
8849 if (NILP (enabled_p
))
8854 /* Show item in pressed state. */
8855 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
8856 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
8857 last_tool_bar_item
= prop_idx
;
8861 Lisp_Object key
, frame
;
8862 struct input_event event
;
8865 /* Show item in released state. */
8866 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
8867 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
8869 key
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_KEY
);
8871 XSETFRAME (frame
, f
);
8872 event
.kind
= TOOL_BAR_EVENT
;
8873 event
.frame_or_window
= frame
;
8875 kbd_buffer_store_event (&event
);
8877 event
.kind
= TOOL_BAR_EVENT
;
8878 event
.frame_or_window
= frame
;
8880 event
.modifiers
= modifiers
;
8881 kbd_buffer_store_event (&event
);
8882 last_tool_bar_item
= -1;
8887 /* Possibly highlight a tool-bar item on frame F when mouse moves to
8888 tool-bar window-relative coordinates X/Y. Called from
8889 note_mouse_highlight. */
8892 note_tool_bar_highlight (f
, x
, y
)
8896 Lisp_Object window
= f
->tool_bar_window
;
8897 struct window
*w
= XWINDOW (window
);
8898 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
8900 struct glyph
*glyph
;
8901 struct glyph_row
*row
;
8903 Lisp_Object enabled_p
;
8905 enum draw_glyphs_face draw
= DRAW_IMAGE_RAISED
;
8906 int mouse_down_p
, rc
;
8908 /* Function note_mouse_highlight is called with negative x(y
8909 values when mouse moves outside of the frame. */
8910 if (x
<= 0 || y
<= 0)
8912 clear_mouse_face (dpyinfo
);
8916 rc
= get_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
8919 /* Not on tool-bar item. */
8920 clear_mouse_face (dpyinfo
);
8924 /* On same tool-bar item as before. */
8927 clear_mouse_face (dpyinfo
);
8929 /* Mouse is down, but on different tool-bar item? */
8930 mouse_down_p
= (dpyinfo
->grabbed
8931 && f
== last_mouse_frame
8932 && FRAME_LIVE_P (f
));
8934 && last_tool_bar_item
!= prop_idx
)
8937 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
8938 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
8940 /* If tool-bar item is not enabled, don't highlight it. */
8941 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
8942 if (!NILP (enabled_p
))
8944 /* Compute the x-position of the glyph. In front and past the
8945 image is a space. We include this in the highlighted area. */
8946 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
8947 for (i
= x
= 0; i
< hpos
; ++i
)
8948 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
8950 /* Record this as the current active region. */
8951 dpyinfo
->mouse_face_beg_col
= hpos
;
8952 dpyinfo
->mouse_face_beg_row
= vpos
;
8953 dpyinfo
->mouse_face_beg_x
= x
;
8954 dpyinfo
->mouse_face_beg_y
= row
->y
;
8955 dpyinfo
->mouse_face_past_end
= 0;
8957 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
8958 dpyinfo
->mouse_face_end_row
= vpos
;
8959 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
8960 dpyinfo
->mouse_face_end_y
= row
->y
;
8961 dpyinfo
->mouse_face_window
= window
;
8962 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
8964 /* Display it as active. */
8965 show_mouse_face (dpyinfo
, draw
);
8966 dpyinfo
->mouse_face_image_state
= draw
;
8971 /* Set help_echo_string to a help string to display for this tool-bar item.
8972 XTread_socket does the rest. */
8973 help_echo_object
= help_echo_window
= Qnil
;
8975 help_echo_string
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_HELP
);
8976 if (NILP (help_echo_string
))
8977 help_echo_string
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_CAPTION
);
8980 #endif /* HAVE_WINDOW_SYSTEM */
8984 /************************************************************************
8985 Horizontal scrolling
8986 ************************************************************************/
8988 static int hscroll_window_tree
P_ ((Lisp_Object
));
8989 static int hscroll_windows
P_ ((Lisp_Object
));
8991 /* For all leaf windows in the window tree rooted at WINDOW, set their
8992 hscroll value so that PT is (i) visible in the window, and (ii) so
8993 that it is not within a certain margin at the window's left and
8994 right border. Value is non-zero if any window's hscroll has been
8998 hscroll_window_tree (window
)
9001 int hscrolled_p
= 0;
9002 int hscroll_relative_p
= FLOATP (Vhscroll_step
);
9003 int hscroll_step_abs
= 0;
9004 double hscroll_step_rel
= 0;
9006 if (hscroll_relative_p
)
9008 hscroll_step_rel
= XFLOAT_DATA (Vhscroll_step
);
9009 if (hscroll_step_rel
< 0)
9011 hscroll_relative_p
= 0;
9012 hscroll_step_abs
= 0;
9015 else if (INTEGERP (Vhscroll_step
))
9017 hscroll_step_abs
= XINT (Vhscroll_step
);
9018 if (hscroll_step_abs
< 0)
9019 hscroll_step_abs
= 0;
9022 hscroll_step_abs
= 0;
9024 while (WINDOWP (window
))
9026 struct window
*w
= XWINDOW (window
);
9028 if (WINDOWP (w
->hchild
))
9029 hscrolled_p
|= hscroll_window_tree (w
->hchild
);
9030 else if (WINDOWP (w
->vchild
))
9031 hscrolled_p
|= hscroll_window_tree (w
->vchild
);
9032 else if (w
->cursor
.vpos
>= 0)
9035 int text_area_width
;
9036 struct glyph_row
*current_cursor_row
9037 = MATRIX_ROW (w
->current_matrix
, w
->cursor
.vpos
);
9038 struct glyph_row
*desired_cursor_row
9039 = MATRIX_ROW (w
->desired_matrix
, w
->cursor
.vpos
);
9040 struct glyph_row
*cursor_row
9041 = (desired_cursor_row
->enabled_p
9042 ? desired_cursor_row
9043 : current_cursor_row
);
9045 text_area_width
= window_box_width (w
, TEXT_AREA
);
9047 /* Scroll when cursor is inside this scroll margin. */
9048 h_margin
= hscroll_margin
* WINDOW_FRAME_COLUMN_WIDTH (w
);
9050 if ((XFASTINT (w
->hscroll
)
9051 && w
->cursor
.x
<= h_margin
)
9052 || (cursor_row
->enabled_p
9053 && cursor_row
->truncated_on_right_p
9054 && (w
->cursor
.x
>= text_area_width
- h_margin
)))
9058 struct buffer
*saved_current_buffer
;
9062 /* Find point in a display of infinite width. */
9063 saved_current_buffer
= current_buffer
;
9064 current_buffer
= XBUFFER (w
->buffer
);
9066 if (w
== XWINDOW (selected_window
))
9067 pt
= BUF_PT (current_buffer
);
9070 pt
= marker_position (w
->pointm
);
9071 pt
= max (BEGV
, pt
);
9075 /* Move iterator to pt starting at cursor_row->start in
9076 a line with infinite width. */
9077 init_to_row_start (&it
, w
, cursor_row
);
9078 it
.last_visible_x
= INFINITY
;
9079 move_it_in_display_line_to (&it
, pt
, -1, MOVE_TO_POS
);
9080 current_buffer
= saved_current_buffer
;
9082 /* Position cursor in window. */
9083 if (!hscroll_relative_p
&& hscroll_step_abs
== 0)
9084 hscroll
= max (0, (it
.current_x
9085 - (ITERATOR_AT_END_OF_LINE_P (&it
)
9086 ? (text_area_width
- 4 * FRAME_COLUMN_WIDTH (it
.f
))
9087 : (text_area_width
/ 2))))
9088 / FRAME_COLUMN_WIDTH (it
.f
);
9089 else if (w
->cursor
.x
>= text_area_width
- h_margin
)
9091 if (hscroll_relative_p
)
9092 wanted_x
= text_area_width
* (1 - hscroll_step_rel
)
9095 wanted_x
= text_area_width
9096 - hscroll_step_abs
* FRAME_COLUMN_WIDTH (it
.f
)
9099 = max (0, it
.current_x
- wanted_x
) / FRAME_COLUMN_WIDTH (it
.f
);
9103 if (hscroll_relative_p
)
9104 wanted_x
= text_area_width
* hscroll_step_rel
9107 wanted_x
= hscroll_step_abs
* FRAME_COLUMN_WIDTH (it
.f
)
9110 = max (0, it
.current_x
- wanted_x
) / FRAME_COLUMN_WIDTH (it
.f
);
9112 hscroll
= max (hscroll
, XFASTINT (w
->min_hscroll
));
9114 /* Don't call Fset_window_hscroll if value hasn't
9115 changed because it will prevent redisplay
9117 if (XFASTINT (w
->hscroll
) != hscroll
)
9119 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
9120 w
->hscroll
= make_number (hscroll
);
9129 /* Value is non-zero if hscroll of any leaf window has been changed. */
9134 /* Set hscroll so that cursor is visible and not inside horizontal
9135 scroll margins for all windows in the tree rooted at WINDOW. See
9136 also hscroll_window_tree above. Value is non-zero if any window's
9137 hscroll has been changed. If it has, desired matrices on the frame
9138 of WINDOW are cleared. */
9141 hscroll_windows (window
)
9146 if (automatic_hscrolling_p
)
9148 hscrolled_p
= hscroll_window_tree (window
);
9150 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window
))));
9159 /************************************************************************
9161 ************************************************************************/
9163 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
9164 to a non-zero value. This is sometimes handy to have in a debugger
9169 /* First and last unchanged row for try_window_id. */
9171 int debug_first_unchanged_at_end_vpos
;
9172 int debug_last_unchanged_at_beg_vpos
;
9174 /* Delta vpos and y. */
9176 int debug_dvpos
, debug_dy
;
9178 /* Delta in characters and bytes for try_window_id. */
9180 int debug_delta
, debug_delta_bytes
;
9182 /* Values of window_end_pos and window_end_vpos at the end of
9185 EMACS_INT debug_end_pos
, debug_end_vpos
;
9187 /* Append a string to W->desired_matrix->method. FMT is a printf
9188 format string. A1...A9 are a supplement for a variable-length
9189 argument list. If trace_redisplay_p is non-zero also printf the
9190 resulting string to stderr. */
9193 debug_method_add (w
, fmt
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
)
9196 int a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
;
9199 char *method
= w
->desired_matrix
->method
;
9200 int len
= strlen (method
);
9201 int size
= sizeof w
->desired_matrix
->method
;
9202 int remaining
= size
- len
- 1;
9204 sprintf (buffer
, fmt
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
);
9205 if (len
&& remaining
)
9211 strncpy (method
+ len
, buffer
, remaining
);
9213 if (trace_redisplay_p
)
9214 fprintf (stderr
, "%p (%s): %s\n",
9216 ((BUFFERP (w
->buffer
)
9217 && STRINGP (XBUFFER (w
->buffer
)->name
))
9218 ? (char *) SDATA (XBUFFER (w
->buffer
)->name
)
9223 #endif /* GLYPH_DEBUG */
9226 /* Value is non-zero if all changes in window W, which displays
9227 current_buffer, are in the text between START and END. START is a
9228 buffer position, END is given as a distance from Z. Used in
9229 redisplay_internal for display optimization. */
9232 text_outside_line_unchanged_p (w
, start
, end
)
9236 int unchanged_p
= 1;
9238 /* If text or overlays have changed, see where. */
9239 if (XFASTINT (w
->last_modified
) < MODIFF
9240 || XFASTINT (w
->last_overlay_modified
) < OVERLAY_MODIFF
)
9242 /* Gap in the line? */
9243 if (GPT
< start
|| Z
- GPT
< end
)
9246 /* Changes start in front of the line, or end after it? */
9248 && (BEG_UNCHANGED
< start
- 1
9249 || END_UNCHANGED
< end
))
9252 /* If selective display, can't optimize if changes start at the
9253 beginning of the line. */
9255 && INTEGERP (current_buffer
->selective_display
)
9256 && XINT (current_buffer
->selective_display
) > 0
9257 && (BEG_UNCHANGED
< start
|| GPT
<= start
))
9260 /* If there are overlays at the start or end of the line, these
9261 may have overlay strings with newlines in them. A change at
9262 START, for instance, may actually concern the display of such
9263 overlay strings as well, and they are displayed on different
9264 lines. So, quickly rule out this case. (For the future, it
9265 might be desirable to implement something more telling than
9266 just BEG/END_UNCHANGED.) */
9269 if (BEG
+ BEG_UNCHANGED
== start
9270 && overlay_touches_p (start
))
9272 if (END_UNCHANGED
== end
9273 && overlay_touches_p (Z
- end
))
9282 /* Do a frame update, taking possible shortcuts into account. This is
9283 the main external entry point for redisplay.
9285 If the last redisplay displayed an echo area message and that message
9286 is no longer requested, we clear the echo area or bring back the
9287 mini-buffer if that is in use. */
9292 redisplay_internal (0);
9296 /* Return 1 if point moved out of or into a composition. Otherwise
9297 return 0. PREV_BUF and PREV_PT are the last point buffer and
9298 position. BUF and PT are the current point buffer and position. */
9301 check_point_in_composition (prev_buf
, prev_pt
, buf
, pt
)
9302 struct buffer
*prev_buf
, *buf
;
9309 XSETBUFFER (buffer
, buf
);
9310 /* Check a composition at the last point if point moved within the
9312 if (prev_buf
== buf
)
9315 /* Point didn't move. */
9318 if (prev_pt
> BUF_BEGV (buf
) && prev_pt
< BUF_ZV (buf
)
9319 && find_composition (prev_pt
, -1, &start
, &end
, &prop
, buffer
)
9320 && COMPOSITION_VALID_P (start
, end
, prop
)
9321 && start
< prev_pt
&& end
> prev_pt
)
9322 /* The last point was within the composition. Return 1 iff
9323 point moved out of the composition. */
9324 return (pt
<= start
|| pt
>= end
);
9327 /* Check a composition at the current point. */
9328 return (pt
> BUF_BEGV (buf
) && pt
< BUF_ZV (buf
)
9329 && find_composition (pt
, -1, &start
, &end
, &prop
, buffer
)
9330 && COMPOSITION_VALID_P (start
, end
, prop
)
9331 && start
< pt
&& end
> pt
);
9335 /* Reconsider the setting of B->clip_changed which is displayed
9339 reconsider_clip_changes (w
, b
)
9344 && !NILP (w
->window_end_valid
)
9345 && w
->current_matrix
->buffer
== b
9346 && w
->current_matrix
->zv
== BUF_ZV (b
)
9347 && w
->current_matrix
->begv
== BUF_BEGV (b
))
9348 b
->clip_changed
= 0;
9350 /* If display wasn't paused, and W is not a tool bar window, see if
9351 point has been moved into or out of a composition. In that case,
9352 we set b->clip_changed to 1 to force updating the screen. If
9353 b->clip_changed has already been set to 1, we can skip this
9355 if (!b
->clip_changed
9356 && BUFFERP (w
->buffer
) && !NILP (w
->window_end_valid
))
9360 if (w
== XWINDOW (selected_window
))
9361 pt
= BUF_PT (current_buffer
);
9363 pt
= marker_position (w
->pointm
);
9365 if ((w
->current_matrix
->buffer
!= XBUFFER (w
->buffer
)
9366 || pt
!= XINT (w
->last_point
))
9367 && check_point_in_composition (w
->current_matrix
->buffer
,
9368 XINT (w
->last_point
),
9369 XBUFFER (w
->buffer
), pt
))
9370 b
->clip_changed
= 1;
9375 /* Select FRAME to forward the values of frame-local variables into C
9376 variables so that the redisplay routines can access those values
9380 select_frame_for_redisplay (frame
)
9383 Lisp_Object tail
, sym
, val
;
9384 Lisp_Object old
= selected_frame
;
9386 selected_frame
= frame
;
9388 for (tail
= XFRAME (frame
)->param_alist
; CONSP (tail
); tail
= XCDR (tail
))
9389 if (CONSP (XCAR (tail
))
9390 && (sym
= XCAR (XCAR (tail
)),
9392 && (sym
= indirect_variable (sym
),
9393 val
= SYMBOL_VALUE (sym
),
9394 (BUFFER_LOCAL_VALUEP (val
)
9395 || SOME_BUFFER_LOCAL_VALUEP (val
)))
9396 && XBUFFER_LOCAL_VALUE (val
)->check_frame
)
9397 Fsymbol_value (sym
);
9399 for (tail
= XFRAME (old
)->param_alist
; CONSP (tail
); tail
= XCDR (tail
))
9400 if (CONSP (XCAR (tail
))
9401 && (sym
= XCAR (XCAR (tail
)),
9403 && (sym
= indirect_variable (sym
),
9404 val
= SYMBOL_VALUE (sym
),
9405 (BUFFER_LOCAL_VALUEP (val
)
9406 || SOME_BUFFER_LOCAL_VALUEP (val
)))
9407 && XBUFFER_LOCAL_VALUE (val
)->check_frame
)
9408 Fsymbol_value (sym
);
9412 #define STOP_POLLING \
9413 do { if (! polling_stopped_here) stop_polling (); \
9414 polling_stopped_here = 1; } while (0)
9416 #define RESUME_POLLING \
9417 do { if (polling_stopped_here) start_polling (); \
9418 polling_stopped_here = 0; } while (0)
9421 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
9422 response to any user action; therefore, we should preserve the echo
9423 area. (Actually, our caller does that job.) Perhaps in the future
9424 avoid recentering windows if it is not necessary; currently that
9425 causes some problems. */
9428 redisplay_internal (preserve_echo_area
)
9429 int preserve_echo_area
;
9431 struct window
*w
= XWINDOW (selected_window
);
9432 struct frame
*f
= XFRAME (w
->frame
);
9434 int must_finish
= 0;
9435 struct text_pos tlbufpos
, tlendpos
;
9436 int number_of_visible_frames
;
9438 struct frame
*sf
= SELECTED_FRAME ();
9439 int polling_stopped_here
= 0;
9441 /* Non-zero means redisplay has to consider all windows on all
9442 frames. Zero means, only selected_window is considered. */
9443 int consider_all_windows_p
;
9445 TRACE ((stderr
, "redisplay_internal %d\n", redisplaying_p
));
9447 /* No redisplay if running in batch mode or frame is not yet fully
9448 initialized, or redisplay is explicitly turned off by setting
9449 Vinhibit_redisplay. */
9451 || !NILP (Vinhibit_redisplay
)
9452 || !f
->glyphs_initialized_p
)
9455 /* The flag redisplay_performed_directly_p is set by
9456 direct_output_for_insert when it already did the whole screen
9457 update necessary. */
9458 if (redisplay_performed_directly_p
)
9460 redisplay_performed_directly_p
= 0;
9461 if (!hscroll_windows (selected_window
))
9465 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
9466 if (popup_activated ())
9470 /* I don't think this happens but let's be paranoid. */
9474 /* Record a function that resets redisplaying_p to its old value
9475 when we leave this function. */
9476 count
= SPECPDL_INDEX ();
9477 record_unwind_protect (unwind_redisplay
,
9478 Fcons (make_number (redisplaying_p
), selected_frame
));
9480 specbind (Qinhibit_free_realized_faces
, Qnil
);
9484 reconsider_clip_changes (w
, current_buffer
);
9486 /* If new fonts have been loaded that make a glyph matrix adjustment
9487 necessary, do it. */
9488 if (fonts_changed_p
)
9490 adjust_glyphs (NULL
);
9491 ++windows_or_buffers_changed
;
9492 fonts_changed_p
= 0;
9495 /* If face_change_count is non-zero, init_iterator will free all
9496 realized faces, which includes the faces referenced from current
9497 matrices. So, we can't reuse current matrices in this case. */
9498 if (face_change_count
)
9499 ++windows_or_buffers_changed
;
9501 if (! FRAME_WINDOW_P (sf
)
9502 && previous_terminal_frame
!= sf
)
9504 /* Since frames on an ASCII terminal share the same display
9505 area, displaying a different frame means redisplay the whole
9507 windows_or_buffers_changed
++;
9508 SET_FRAME_GARBAGED (sf
);
9509 XSETFRAME (Vterminal_frame
, sf
);
9511 previous_terminal_frame
= sf
;
9513 /* Set the visible flags for all frames. Do this before checking
9514 for resized or garbaged frames; they want to know if their frames
9515 are visible. See the comment in frame.h for
9516 FRAME_SAMPLE_VISIBILITY. */
9518 Lisp_Object tail
, frame
;
9520 number_of_visible_frames
= 0;
9522 FOR_EACH_FRAME (tail
, frame
)
9524 struct frame
*f
= XFRAME (frame
);
9526 FRAME_SAMPLE_VISIBILITY (f
);
9527 if (FRAME_VISIBLE_P (f
))
9528 ++number_of_visible_frames
;
9529 clear_desired_matrices (f
);
9533 /* Notice any pending interrupt request to change frame size. */
9534 do_pending_window_change (1);
9536 /* Clear frames marked as garbaged. */
9538 clear_garbaged_frames ();
9540 /* Build menubar and tool-bar items. */
9541 prepare_menu_bars ();
9543 if (windows_or_buffers_changed
)
9544 update_mode_lines
++;
9546 /* Detect case that we need to write or remove a star in the mode line. */
9547 if ((SAVE_MODIFF
< MODIFF
) != !NILP (w
->last_had_star
))
9549 w
->update_mode_line
= Qt
;
9550 if (buffer_shared
> 1)
9551 update_mode_lines
++;
9554 /* If %c is in the mode line, update it if needed. */
9555 if (!NILP (w
->column_number_displayed
)
9556 /* This alternative quickly identifies a common case
9557 where no change is needed. */
9558 && !(PT
== XFASTINT (w
->last_point
)
9559 && XFASTINT (w
->last_modified
) >= MODIFF
9560 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
)
9561 && (XFASTINT (w
->column_number_displayed
)
9562 != (int) current_column ())) /* iftc */
9563 w
->update_mode_line
= Qt
;
9565 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w
->frame
)) = -1;
9567 /* The variable buffer_shared is set in redisplay_window and
9568 indicates that we redisplay a buffer in different windows. See
9570 consider_all_windows_p
= (update_mode_lines
|| buffer_shared
> 1
9571 || cursor_type_changed
);
9573 /* If specs for an arrow have changed, do thorough redisplay
9574 to ensure we remove any arrow that should no longer exist. */
9575 if (! EQ (COERCE_MARKER (Voverlay_arrow_position
), last_arrow_position
)
9576 || ! EQ (Voverlay_arrow_string
, last_arrow_string
))
9577 consider_all_windows_p
= windows_or_buffers_changed
= 1;
9579 /* Normally the message* functions will have already displayed and
9580 updated the echo area, but the frame may have been trashed, or
9581 the update may have been preempted, so display the echo area
9582 again here. Checking message_cleared_p captures the case that
9583 the echo area should be cleared. */
9584 if ((!NILP (echo_area_buffer
[0]) && !display_last_displayed_message_p
)
9585 || (!NILP (echo_area_buffer
[1]) && display_last_displayed_message_p
)
9586 || (message_cleared_p
9587 && minibuf_level
== 0
9588 /* If the mini-window is currently selected, this means the
9589 echo-area doesn't show through. */
9590 && !MINI_WINDOW_P (XWINDOW (selected_window
))))
9592 int window_height_changed_p
= echo_area_display (0);
9595 /* If we don't display the current message, don't clear the
9596 message_cleared_p flag, because, if we did, we wouldn't clear
9597 the echo area in the next redisplay which doesn't preserve
9599 if (!display_last_displayed_message_p
)
9600 message_cleared_p
= 0;
9602 if (fonts_changed_p
)
9604 else if (window_height_changed_p
)
9606 consider_all_windows_p
= 1;
9607 ++update_mode_lines
;
9608 ++windows_or_buffers_changed
;
9610 /* If window configuration was changed, frames may have been
9611 marked garbaged. Clear them or we will experience
9612 surprises wrt scrolling. */
9614 clear_garbaged_frames ();
9617 else if (EQ (selected_window
, minibuf_window
)
9618 && (current_buffer
->clip_changed
9619 || XFASTINT (w
->last_modified
) < MODIFF
9620 || XFASTINT (w
->last_overlay_modified
) < OVERLAY_MODIFF
)
9621 && resize_mini_window (w
, 0))
9623 /* Resized active mini-window to fit the size of what it is
9624 showing if its contents might have changed. */
9626 consider_all_windows_p
= 1;
9627 ++windows_or_buffers_changed
;
9628 ++update_mode_lines
;
9630 /* If window configuration was changed, frames may have been
9631 marked garbaged. Clear them or we will experience
9632 surprises wrt scrolling. */
9634 clear_garbaged_frames ();
9638 /* If showing the region, and mark has changed, we must redisplay
9639 the whole window. The assignment to this_line_start_pos prevents
9640 the optimization directly below this if-statement. */
9641 if (((!NILP (Vtransient_mark_mode
)
9642 && !NILP (XBUFFER (w
->buffer
)->mark_active
))
9643 != !NILP (w
->region_showing
))
9644 || (!NILP (w
->region_showing
)
9645 && !EQ (w
->region_showing
,
9646 Fmarker_position (XBUFFER (w
->buffer
)->mark
))))
9647 CHARPOS (this_line_start_pos
) = 0;
9649 /* Optimize the case that only the line containing the cursor in the
9650 selected window has changed. Variables starting with this_ are
9651 set in display_line and record information about the line
9652 containing the cursor. */
9653 tlbufpos
= this_line_start_pos
;
9654 tlendpos
= this_line_end_pos
;
9655 if (!consider_all_windows_p
9656 && CHARPOS (tlbufpos
) > 0
9657 && NILP (w
->update_mode_line
)
9658 && !current_buffer
->clip_changed
9659 && !current_buffer
->prevent_redisplay_optimizations_p
9660 && FRAME_VISIBLE_P (XFRAME (w
->frame
))
9661 && !FRAME_OBSCURED_P (XFRAME (w
->frame
))
9662 /* Make sure recorded data applies to current buffer, etc. */
9663 && this_line_buffer
== current_buffer
9664 && current_buffer
== XBUFFER (w
->buffer
)
9665 && NILP (w
->force_start
)
9666 && NILP (w
->optional_new_start
)
9667 /* Point must be on the line that we have info recorded about. */
9668 && PT
>= CHARPOS (tlbufpos
)
9669 && PT
<= Z
- CHARPOS (tlendpos
)
9670 /* All text outside that line, including its final newline,
9671 must be unchanged */
9672 && text_outside_line_unchanged_p (w
, CHARPOS (tlbufpos
),
9673 CHARPOS (tlendpos
)))
9675 if (CHARPOS (tlbufpos
) > BEGV
9676 && FETCH_BYTE (BYTEPOS (tlbufpos
) - 1) != '\n'
9677 && (CHARPOS (tlbufpos
) == ZV
9678 || FETCH_BYTE (BYTEPOS (tlbufpos
)) == '\n'))
9679 /* Former continuation line has disappeared by becoming empty */
9681 else if (XFASTINT (w
->last_modified
) < MODIFF
9682 || XFASTINT (w
->last_overlay_modified
) < OVERLAY_MODIFF
9683 || MINI_WINDOW_P (w
))
9685 /* We have to handle the case of continuation around a
9686 wide-column character (See the comment in indent.c around
9689 For instance, in the following case:
9691 -------- Insert --------
9692 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
9693 J_I_ ==> J_I_ `^^' are cursors.
9697 As we have to redraw the line above, we should goto cancel. */
9700 int line_height_before
= this_line_pixel_height
;
9702 /* Note that start_display will handle the case that the
9703 line starting at tlbufpos is a continuation lines. */
9704 start_display (&it
, w
, tlbufpos
);
9706 /* Implementation note: It this still necessary? */
9707 if (it
.current_x
!= this_line_start_x
)
9710 TRACE ((stderr
, "trying display optimization 1\n"));
9711 w
->cursor
.vpos
= -1;
9712 overlay_arrow_seen
= 0;
9713 it
.vpos
= this_line_vpos
;
9714 it
.current_y
= this_line_y
;
9715 it
.glyph_row
= MATRIX_ROW (w
->desired_matrix
, this_line_vpos
);
9718 /* If line contains point, is not continued,
9719 and ends at same distance from eob as before, we win */
9720 if (w
->cursor
.vpos
>= 0
9721 /* Line is not continued, otherwise this_line_start_pos
9722 would have been set to 0 in display_line. */
9723 && CHARPOS (this_line_start_pos
)
9724 /* Line ends as before. */
9725 && CHARPOS (this_line_end_pos
) == CHARPOS (tlendpos
)
9726 /* Line has same height as before. Otherwise other lines
9727 would have to be shifted up or down. */
9728 && this_line_pixel_height
== line_height_before
)
9730 /* If this is not the window's last line, we must adjust
9731 the charstarts of the lines below. */
9732 if (it
.current_y
< it
.last_visible_y
)
9734 struct glyph_row
*row
9735 = MATRIX_ROW (w
->current_matrix
, this_line_vpos
+ 1);
9736 int delta
, delta_bytes
;
9738 if (Z
- CHARPOS (tlendpos
) == ZV
)
9740 /* This line ends at end of (accessible part of)
9741 buffer. There is no newline to count. */
9743 - CHARPOS (tlendpos
)
9744 - MATRIX_ROW_START_CHARPOS (row
));
9745 delta_bytes
= (Z_BYTE
9746 - BYTEPOS (tlendpos
)
9747 - MATRIX_ROW_START_BYTEPOS (row
));
9751 /* This line ends in a newline. Must take
9752 account of the newline and the rest of the
9753 text that follows. */
9755 - CHARPOS (tlendpos
)
9756 - MATRIX_ROW_START_CHARPOS (row
));
9757 delta_bytes
= (Z_BYTE
9758 - BYTEPOS (tlendpos
)
9759 - MATRIX_ROW_START_BYTEPOS (row
));
9762 increment_matrix_positions (w
->current_matrix
,
9764 w
->current_matrix
->nrows
,
9765 delta
, delta_bytes
);
9768 /* If this row displays text now but previously didn't,
9769 or vice versa, w->window_end_vpos may have to be
9771 if ((it
.glyph_row
- 1)->displays_text_p
)
9773 if (XFASTINT (w
->window_end_vpos
) < this_line_vpos
)
9774 XSETINT (w
->window_end_vpos
, this_line_vpos
);
9776 else if (XFASTINT (w
->window_end_vpos
) == this_line_vpos
9777 && this_line_vpos
> 0)
9778 XSETINT (w
->window_end_vpos
, this_line_vpos
- 1);
9779 w
->window_end_valid
= Qnil
;
9781 /* Update hint: No need to try to scroll in update_window. */
9782 w
->desired_matrix
->no_scrolling_p
= 1;
9785 *w
->desired_matrix
->method
= 0;
9786 debug_method_add (w
, "optimization 1");
9788 #ifdef HAVE_WINDOW_SYSTEM
9789 update_window_fringes (w
, 0);
9796 else if (/* Cursor position hasn't changed. */
9797 PT
== XFASTINT (w
->last_point
)
9798 /* Make sure the cursor was last displayed
9799 in this window. Otherwise we have to reposition it. */
9800 && 0 <= w
->cursor
.vpos
9801 && WINDOW_TOTAL_LINES (w
) > w
->cursor
.vpos
)
9805 do_pending_window_change (1);
9807 /* We used to always goto end_of_redisplay here, but this
9808 isn't enough if we have a blinking cursor. */
9809 if (w
->cursor_off_p
== w
->last_cursor_off_p
)
9810 goto end_of_redisplay
;
9814 /* If highlighting the region, or if the cursor is in the echo area,
9815 then we can't just move the cursor. */
9816 else if (! (!NILP (Vtransient_mark_mode
)
9817 && !NILP (current_buffer
->mark_active
))
9818 && (EQ (selected_window
, current_buffer
->last_selected_window
)
9819 || highlight_nonselected_windows
)
9820 && NILP (w
->region_showing
)
9821 && NILP (Vshow_trailing_whitespace
)
9822 && !cursor_in_echo_area
)
9825 struct glyph_row
*row
;
9827 /* Skip from tlbufpos to PT and see where it is. Note that
9828 PT may be in invisible text. If so, we will end at the
9829 next visible position. */
9830 init_iterator (&it
, w
, CHARPOS (tlbufpos
), BYTEPOS (tlbufpos
),
9831 NULL
, DEFAULT_FACE_ID
);
9832 it
.current_x
= this_line_start_x
;
9833 it
.current_y
= this_line_y
;
9834 it
.vpos
= this_line_vpos
;
9836 /* The call to move_it_to stops in front of PT, but
9837 moves over before-strings. */
9838 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
9840 if (it
.vpos
== this_line_vpos
9841 && (row
= MATRIX_ROW (w
->current_matrix
, this_line_vpos
),
9844 xassert (this_line_vpos
== it
.vpos
);
9845 xassert (this_line_y
== it
.current_y
);
9846 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
9848 *w
->desired_matrix
->method
= 0;
9849 debug_method_add (w
, "optimization 3");
9858 /* Text changed drastically or point moved off of line. */
9859 SET_MATRIX_ROW_ENABLED_P (w
->desired_matrix
, this_line_vpos
, 0);
9862 CHARPOS (this_line_start_pos
) = 0;
9863 consider_all_windows_p
|= buffer_shared
> 1;
9864 ++clear_face_cache_count
;
9867 /* Build desired matrices, and update the display. If
9868 consider_all_windows_p is non-zero, do it for all windows on all
9869 frames. Otherwise do it for selected_window, only. */
9871 if (consider_all_windows_p
)
9873 Lisp_Object tail
, frame
;
9874 int i
, n
= 0, size
= 50;
9875 struct frame
**updated
9876 = (struct frame
**) alloca (size
* sizeof *updated
);
9878 /* Clear the face cache eventually. */
9879 if (clear_face_cache_count
> CLEAR_FACE_CACHE_COUNT
)
9881 clear_face_cache (0);
9882 clear_face_cache_count
= 0;
9885 /* Recompute # windows showing selected buffer. This will be
9886 incremented each time such a window is displayed. */
9889 FOR_EACH_FRAME (tail
, frame
)
9891 struct frame
*f
= XFRAME (frame
);
9893 if (FRAME_WINDOW_P (f
) || f
== sf
)
9895 if (! EQ (frame
, selected_frame
))
9896 /* Select the frame, for the sake of frame-local
9898 select_frame_for_redisplay (frame
);
9900 #ifdef HAVE_WINDOW_SYSTEM
9901 if (clear_face_cache_count
% 50 == 0
9902 && FRAME_WINDOW_P (f
))
9903 clear_image_cache (f
, 0);
9904 #endif /* HAVE_WINDOW_SYSTEM */
9906 /* Mark all the scroll bars to be removed; we'll redeem
9907 the ones we want when we redisplay their windows. */
9908 if (condemn_scroll_bars_hook
)
9909 condemn_scroll_bars_hook (f
);
9911 if (FRAME_VISIBLE_P (f
) && !FRAME_OBSCURED_P (f
))
9912 redisplay_windows (FRAME_ROOT_WINDOW (f
));
9914 /* Any scroll bars which redisplay_windows should have
9915 nuked should now go away. */
9916 if (judge_scroll_bars_hook
)
9917 judge_scroll_bars_hook (f
);
9919 /* If fonts changed, display again. */
9920 /* ??? rms: I suspect it is a mistake to jump all the way
9921 back to retry here. It should just retry this frame. */
9922 if (fonts_changed_p
)
9925 if (FRAME_VISIBLE_P (f
) && !FRAME_OBSCURED_P (f
))
9927 /* See if we have to hscroll. */
9928 if (hscroll_windows (f
->root_window
))
9931 /* Prevent various kinds of signals during display
9932 update. stdio is not robust about handling
9933 signals, which can cause an apparent I/O
9935 if (interrupt_input
)
9939 /* Update the display. */
9940 set_window_update_flags (XWINDOW (f
->root_window
), 1);
9941 pause
|= update_frame (f
, 0, 0);
9942 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
9949 int nbytes
= size
* sizeof *updated
;
9950 struct frame
**p
= (struct frame
**) alloca (2 * nbytes
);
9951 bcopy (updated
, p
, nbytes
);
9962 /* Do the mark_window_display_accurate after all windows have
9963 been redisplayed because this call resets flags in buffers
9964 which are needed for proper redisplay. */
9965 for (i
= 0; i
< n
; ++i
)
9967 struct frame
*f
= updated
[i
];
9968 mark_window_display_accurate (f
->root_window
, 1);
9969 if (frame_up_to_date_hook
)
9970 frame_up_to_date_hook (f
);
9974 else if (FRAME_VISIBLE_P (sf
) && !FRAME_OBSCURED_P (sf
))
9976 Lisp_Object mini_window
;
9977 struct frame
*mini_frame
;
9979 displayed_buffer
= XBUFFER (XWINDOW (selected_window
)->buffer
);
9980 /* Use list_of_error, not Qerror, so that
9981 we catch only errors and don't run the debugger. */
9982 internal_condition_case_1 (redisplay_window_1
, selected_window
,
9984 redisplay_window_error
);
9986 /* Compare desired and current matrices, perform output. */
9989 /* If fonts changed, display again. */
9990 if (fonts_changed_p
)
9993 /* Prevent various kinds of signals during display update.
9994 stdio is not robust about handling signals,
9995 which can cause an apparent I/O error. */
9996 if (interrupt_input
)
10000 if (FRAME_VISIBLE_P (sf
) && !FRAME_OBSCURED_P (sf
))
10002 if (hscroll_windows (selected_window
))
10005 XWINDOW (selected_window
)->must_be_updated_p
= 1;
10006 pause
= update_frame (sf
, 0, 0);
10009 /* We may have called echo_area_display at the top of this
10010 function. If the echo area is on another frame, that may
10011 have put text on a frame other than the selected one, so the
10012 above call to update_frame would not have caught it. Catch
10014 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
10015 mini_frame
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
10017 if (mini_frame
!= sf
&& FRAME_WINDOW_P (mini_frame
))
10019 XWINDOW (mini_window
)->must_be_updated_p
= 1;
10020 pause
|= update_frame (mini_frame
, 0, 0);
10021 if (!pause
&& hscroll_windows (mini_window
))
10026 /* If display was paused because of pending input, make sure we do a
10027 thorough update the next time. */
10030 /* Prevent the optimization at the beginning of
10031 redisplay_internal that tries a single-line update of the
10032 line containing the cursor in the selected window. */
10033 CHARPOS (this_line_start_pos
) = 0;
10035 /* Let the overlay arrow be updated the next time. */
10036 if (!NILP (last_arrow_position
))
10038 last_arrow_position
= Qt
;
10039 last_arrow_string
= Qt
;
10042 /* If we pause after scrolling, some rows in the current
10043 matrices of some windows are not valid. */
10044 if (!WINDOW_FULL_WIDTH_P (w
)
10045 && !FRAME_WINDOW_P (XFRAME (w
->frame
)))
10046 update_mode_lines
= 1;
10050 if (!consider_all_windows_p
)
10052 /* This has already been done above if
10053 consider_all_windows_p is set. */
10054 mark_window_display_accurate_1 (w
, 1);
10056 last_arrow_position
= COERCE_MARKER (Voverlay_arrow_position
);
10057 last_arrow_string
= Voverlay_arrow_string
;
10059 if (frame_up_to_date_hook
!= 0)
10060 frame_up_to_date_hook (sf
);
10063 update_mode_lines
= 0;
10064 windows_or_buffers_changed
= 0;
10065 cursor_type_changed
= 0;
10068 /* Start SIGIO interrupts coming again. Having them off during the
10069 code above makes it less likely one will discard output, but not
10070 impossible, since there might be stuff in the system buffer here.
10071 But it is much hairier to try to do anything about that. */
10072 if (interrupt_input
)
10076 /* If a frame has become visible which was not before, redisplay
10077 again, so that we display it. Expose events for such a frame
10078 (which it gets when becoming visible) don't call the parts of
10079 redisplay constructing glyphs, so simply exposing a frame won't
10080 display anything in this case. So, we have to display these
10081 frames here explicitly. */
10084 Lisp_Object tail
, frame
;
10087 FOR_EACH_FRAME (tail
, frame
)
10089 int this_is_visible
= 0;
10091 if (XFRAME (frame
)->visible
)
10092 this_is_visible
= 1;
10093 FRAME_SAMPLE_VISIBILITY (XFRAME (frame
));
10094 if (XFRAME (frame
)->visible
)
10095 this_is_visible
= 1;
10097 if (this_is_visible
)
10101 if (new_count
!= number_of_visible_frames
)
10102 windows_or_buffers_changed
++;
10105 /* Change frame size now if a change is pending. */
10106 do_pending_window_change (1);
10108 /* If we just did a pending size change, or have additional
10109 visible frames, redisplay again. */
10110 if (windows_or_buffers_changed
&& !pause
)
10114 unbind_to (count
, Qnil
);
10119 /* Redisplay, but leave alone any recent echo area message unless
10120 another message has been requested in its place.
10122 This is useful in situations where you need to redisplay but no
10123 user action has occurred, making it inappropriate for the message
10124 area to be cleared. See tracking_off and
10125 wait_reading_process_input for examples of these situations.
10127 FROM_WHERE is an integer saying from where this function was
10128 called. This is useful for debugging. */
10131 redisplay_preserve_echo_area (from_where
)
10134 TRACE ((stderr
, "redisplay_preserve_echo_area (%d)\n", from_where
));
10136 if (!NILP (echo_area_buffer
[1]))
10138 /* We have a previously displayed message, but no current
10139 message. Redisplay the previous message. */
10140 display_last_displayed_message_p
= 1;
10141 redisplay_internal (1);
10142 display_last_displayed_message_p
= 0;
10145 redisplay_internal (1);
10149 /* Function registered with record_unwind_protect in
10150 redisplay_internal. Reset redisplaying_p to the value it had
10151 before redisplay_internal was called, and clear
10152 prevent_freeing_realized_faces_p. It also selects the previously
10156 unwind_redisplay (val
)
10159 Lisp_Object old_redisplaying_p
, old_frame
;
10161 old_redisplaying_p
= XCAR (val
);
10162 redisplaying_p
= XFASTINT (old_redisplaying_p
);
10163 old_frame
= XCDR (val
);
10164 if (! EQ (old_frame
, selected_frame
))
10165 select_frame_for_redisplay (old_frame
);
10170 /* Mark the display of window W as accurate or inaccurate. If
10171 ACCURATE_P is non-zero mark display of W as accurate. If
10172 ACCURATE_P is zero, arrange for W to be redisplayed the next time
10173 redisplay_internal is called. */
10176 mark_window_display_accurate_1 (w
, accurate_p
)
10180 if (BUFFERP (w
->buffer
))
10182 struct buffer
*b
= XBUFFER (w
->buffer
);
10185 = make_number (accurate_p
? BUF_MODIFF (b
) : 0);
10186 w
->last_overlay_modified
10187 = make_number (accurate_p
? BUF_OVERLAY_MODIFF (b
) : 0);
10189 = BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
) ? Qt
: Qnil
;
10193 b
->clip_changed
= 0;
10194 b
->prevent_redisplay_optimizations_p
= 0;
10196 BUF_UNCHANGED_MODIFIED (b
) = BUF_MODIFF (b
);
10197 BUF_OVERLAY_UNCHANGED_MODIFIED (b
) = BUF_OVERLAY_MODIFF (b
);
10198 BUF_BEG_UNCHANGED (b
) = BUF_GPT (b
) - BUF_BEG (b
);
10199 BUF_END_UNCHANGED (b
) = BUF_Z (b
) - BUF_GPT (b
);
10201 w
->current_matrix
->buffer
= b
;
10202 w
->current_matrix
->begv
= BUF_BEGV (b
);
10203 w
->current_matrix
->zv
= BUF_ZV (b
);
10205 w
->last_cursor
= w
->cursor
;
10206 w
->last_cursor_off_p
= w
->cursor_off_p
;
10208 if (w
== XWINDOW (selected_window
))
10209 w
->last_point
= make_number (BUF_PT (b
));
10211 w
->last_point
= make_number (XMARKER (w
->pointm
)->charpos
);
10217 w
->window_end_valid
= w
->buffer
;
10218 #if 0 /* This is incorrect with variable-height lines. */
10219 xassert (XINT (w
->window_end_vpos
)
10220 < (WINDOW_TOTAL_LINES (w
)
10221 - (WINDOW_WANTS_MODELINE_P (w
) ? 1 : 0)));
10223 w
->update_mode_line
= Qnil
;
10228 /* Mark the display of windows in the window tree rooted at WINDOW as
10229 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
10230 windows as accurate. If ACCURATE_P is zero, arrange for windows to
10231 be redisplayed the next time redisplay_internal is called. */
10234 mark_window_display_accurate (window
, accurate_p
)
10235 Lisp_Object window
;
10240 for (; !NILP (window
); window
= w
->next
)
10242 w
= XWINDOW (window
);
10243 mark_window_display_accurate_1 (w
, accurate_p
);
10245 if (!NILP (w
->vchild
))
10246 mark_window_display_accurate (w
->vchild
, accurate_p
);
10247 if (!NILP (w
->hchild
))
10248 mark_window_display_accurate (w
->hchild
, accurate_p
);
10253 last_arrow_position
= COERCE_MARKER (Voverlay_arrow_position
);
10254 last_arrow_string
= Voverlay_arrow_string
;
10258 /* Force a thorough redisplay the next time by setting
10259 last_arrow_position and last_arrow_string to t, which is
10260 unequal to any useful value of Voverlay_arrow_... */
10261 last_arrow_position
= Qt
;
10262 last_arrow_string
= Qt
;
10267 /* Return value in display table DP (Lisp_Char_Table *) for character
10268 C. Since a display table doesn't have any parent, we don't have to
10269 follow parent. Do not call this function directly but use the
10270 macro DISP_CHAR_VECTOR. */
10273 disp_char_vector (dp
, c
)
10274 struct Lisp_Char_Table
*dp
;
10280 if (SINGLE_BYTE_CHAR_P (c
))
10281 return (dp
->contents
[c
]);
10283 SPLIT_CHAR (c
, code
[0], code
[1], code
[2]);
10286 else if (code
[2] < 32)
10289 /* Here, the possible range of code[0] (== charset ID) is
10290 128..max_charset. Since the top level char table contains data
10291 for multibyte characters after 256th element, we must increment
10292 code[0] by 128 to get a correct index. */
10294 code
[3] = -1; /* anchor */
10296 for (i
= 0; code
[i
] >= 0; i
++, dp
= XCHAR_TABLE (val
))
10298 val
= dp
->contents
[code
[i
]];
10299 if (!SUB_CHAR_TABLE_P (val
))
10300 return (NILP (val
) ? dp
->defalt
: val
);
10303 /* Here, val is a sub char table. We return the default value of
10305 return (dp
->defalt
);
10310 /***********************************************************************
10312 ***********************************************************************/
10314 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
10317 redisplay_windows (window
)
10318 Lisp_Object window
;
10320 while (!NILP (window
))
10322 struct window
*w
= XWINDOW (window
);
10324 if (!NILP (w
->hchild
))
10325 redisplay_windows (w
->hchild
);
10326 else if (!NILP (w
->vchild
))
10327 redisplay_windows (w
->vchild
);
10330 displayed_buffer
= XBUFFER (w
->buffer
);
10331 /* Use list_of_error, not Qerror, so that
10332 we catch only errors and don't run the debugger. */
10333 internal_condition_case_1 (redisplay_window_0
, window
,
10335 redisplay_window_error
);
10343 redisplay_window_error ()
10345 displayed_buffer
->display_error_modiff
= BUF_MODIFF (displayed_buffer
);
10350 redisplay_window_0 (window
)
10351 Lisp_Object window
;
10353 if (displayed_buffer
->display_error_modiff
< BUF_MODIFF (displayed_buffer
))
10354 redisplay_window (window
, 0);
10359 redisplay_window_1 (window
)
10360 Lisp_Object window
;
10362 if (displayed_buffer
->display_error_modiff
< BUF_MODIFF (displayed_buffer
))
10363 redisplay_window (window
, 1);
10368 /* Increment GLYPH until it reaches END or CONDITION fails while
10369 adding (GLYPH)->pixel_width to X. */
10371 #define SKIP_GLYPHS(glyph, end, x, condition) \
10374 (x) += (glyph)->pixel_width; \
10377 while ((glyph) < (end) && (condition))
10380 /* Set cursor position of W. PT is assumed to be displayed in ROW.
10381 DELTA is the number of bytes by which positions recorded in ROW
10382 differ from current buffer positions. */
10385 set_cursor_from_row (w
, row
, matrix
, delta
, delta_bytes
, dy
, dvpos
)
10387 struct glyph_row
*row
;
10388 struct glyph_matrix
*matrix
;
10389 int delta
, delta_bytes
, dy
, dvpos
;
10391 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
10392 struct glyph
*end
= glyph
+ row
->used
[TEXT_AREA
];
10393 /* The first glyph that starts a sequence of glyphs from string. */
10394 struct glyph
*string_start
;
10395 /* The X coordinate of string_start. */
10396 int string_start_x
;
10397 /* The last known character position. */
10398 int last_pos
= MATRIX_ROW_START_CHARPOS (row
) + delta
;
10399 /* The last known character position before string_start. */
10400 int string_before_pos
;
10402 int pt_old
= PT
- delta
;
10404 /* Skip over glyphs not having an object at the start of the row.
10405 These are special glyphs like truncation marks on terminal
10407 if (row
->displays_text_p
)
10409 && INTEGERP (glyph
->object
)
10410 && glyph
->charpos
< 0)
10412 x
+= glyph
->pixel_width
;
10416 string_start
= NULL
;
10418 && !INTEGERP (glyph
->object
)
10419 && (!BUFFERP (glyph
->object
)
10420 || (last_pos
= glyph
->charpos
) < pt_old
))
10422 if (! STRINGP (glyph
->object
))
10424 string_start
= NULL
;
10425 x
+= glyph
->pixel_width
;
10430 string_before_pos
= last_pos
;
10431 string_start
= glyph
;
10432 string_start_x
= x
;
10433 /* Skip all glyphs from string. */
10434 SKIP_GLYPHS (glyph
, end
, x
, STRINGP (glyph
->object
));
10439 && (glyph
== end
|| !BUFFERP (glyph
->object
) || last_pos
> pt_old
))
10441 /* We may have skipped over point because the previous glyphs
10442 are from string. As there's no easy way to know the
10443 character position of the current glyph, find the correct
10444 glyph on point by scanning from string_start again. */
10446 Lisp_Object string
;
10449 limit
= make_number (pt_old
+ 1);
10451 glyph
= string_start
;
10452 x
= string_start_x
;
10453 string
= glyph
->object
;
10454 pos
= string_buffer_position (w
, string
, string_before_pos
);
10455 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
10456 because we always put cursor after overlay strings. */
10457 while (pos
== 0 && glyph
< end
)
10459 string
= glyph
->object
;
10460 SKIP_GLYPHS (glyph
, end
, x
, EQ (glyph
->object
, string
));
10462 pos
= string_buffer_position (w
, glyph
->object
, string_before_pos
);
10465 while (glyph
< end
)
10467 pos
= XINT (Fnext_single_char_property_change
10468 (make_number (pos
), Qdisplay
, Qnil
, limit
));
10471 /* Skip glyphs from the same string. */
10472 string
= glyph
->object
;
10473 SKIP_GLYPHS (glyph
, end
, x
, EQ (glyph
->object
, string
));
10474 /* Skip glyphs from an overlay. */
10476 && ! string_buffer_position (w
, glyph
->object
, pos
))
10478 string
= glyph
->object
;
10479 SKIP_GLYPHS (glyph
, end
, x
, EQ (glyph
->object
, string
));
10484 w
->cursor
.hpos
= glyph
- row
->glyphs
[TEXT_AREA
];
10486 w
->cursor
.vpos
= MATRIX_ROW_VPOS (row
, matrix
) + dvpos
;
10487 w
->cursor
.y
= row
->y
+ dy
;
10489 if (w
== XWINDOW (selected_window
))
10491 if (!row
->continued_p
10492 && !MATRIX_ROW_CONTINUATION_LINE_P (row
)
10495 this_line_buffer
= XBUFFER (w
->buffer
);
10497 CHARPOS (this_line_start_pos
)
10498 = MATRIX_ROW_START_CHARPOS (row
) + delta
;
10499 BYTEPOS (this_line_start_pos
)
10500 = MATRIX_ROW_START_BYTEPOS (row
) + delta_bytes
;
10502 CHARPOS (this_line_end_pos
)
10503 = Z
- (MATRIX_ROW_END_CHARPOS (row
) + delta
);
10504 BYTEPOS (this_line_end_pos
)
10505 = Z_BYTE
- (MATRIX_ROW_END_BYTEPOS (row
) + delta_bytes
);
10507 this_line_y
= w
->cursor
.y
;
10508 this_line_pixel_height
= row
->height
;
10509 this_line_vpos
= w
->cursor
.vpos
;
10510 this_line_start_x
= row
->x
;
10513 CHARPOS (this_line_start_pos
) = 0;
10518 /* Run window scroll functions, if any, for WINDOW with new window
10519 start STARTP. Sets the window start of WINDOW to that position.
10521 We assume that the window's buffer is really current. */
10523 static INLINE
struct text_pos
10524 run_window_scroll_functions (window
, startp
)
10525 Lisp_Object window
;
10526 struct text_pos startp
;
10528 struct window
*w
= XWINDOW (window
);
10529 SET_MARKER_FROM_TEXT_POS (w
->start
, startp
);
10531 if (current_buffer
!= XBUFFER (w
->buffer
))
10534 if (!NILP (Vwindow_scroll_functions
))
10536 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
10537 make_number (CHARPOS (startp
)));
10538 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
10539 /* In case the hook functions switch buffers. */
10540 if (current_buffer
!= XBUFFER (w
->buffer
))
10541 set_buffer_internal_1 (XBUFFER (w
->buffer
));
10548 /* Make sure the line containing the cursor is fully visible.
10549 A value of 1 means there is nothing to be done.
10550 (Either the line is fully visible, or it cannot be made so,
10551 or we cannot tell.)
10552 A value of 0 means the caller should do scrolling
10553 as if point had gone off the screen. */
10556 make_cursor_line_fully_visible (w
)
10559 struct glyph_matrix
*matrix
;
10560 struct glyph_row
*row
;
10563 /* It's not always possible to find the cursor, e.g, when a window
10564 is full of overlay strings. Don't do anything in that case. */
10565 if (w
->cursor
.vpos
< 0)
10568 matrix
= w
->desired_matrix
;
10569 row
= MATRIX_ROW (matrix
, w
->cursor
.vpos
);
10571 /* If the cursor row is not partially visible, there's nothing to do. */
10572 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (row
))
10575 /* If the row the cursor is in is taller than the window's height,
10576 it's not clear what to do, so do nothing. */
10577 window_height
= window_box_height (w
);
10578 if (row
->height
>= window_height
)
10584 /* This code used to try to scroll the window just enough to make
10585 the line visible. It returned 0 to say that the caller should
10586 allocate larger glyph matrices. */
10588 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w
, row
))
10590 int dy
= row
->height
- row
->visible_height
;
10593 shift_glyph_matrix (w
, matrix
, 0, matrix
->nrows
, dy
);
10595 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
10597 int dy
= - (row
->height
- row
->visible_height
);
10600 shift_glyph_matrix (w
, matrix
, 0, matrix
->nrows
, dy
);
10603 /* When we change the cursor y-position of the selected window,
10604 change this_line_y as well so that the display optimization for
10605 the cursor line of the selected window in redisplay_internal uses
10606 the correct y-position. */
10607 if (w
== XWINDOW (selected_window
))
10608 this_line_y
= w
->cursor
.y
;
10610 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
10611 redisplay with larger matrices. */
10612 if (matrix
->nrows
< required_matrix_height (w
))
10614 fonts_changed_p
= 1;
10623 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
10624 non-zero means only WINDOW is redisplayed in redisplay_internal.
10625 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
10626 in redisplay_window to bring a partially visible line into view in
10627 the case that only the cursor has moved.
10629 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
10630 last screen line's vertical height extends past the end of the screen.
10634 1 if scrolling succeeded
10636 0 if scrolling didn't find point.
10638 -1 if new fonts have been loaded so that we must interrupt
10639 redisplay, adjust glyph matrices, and try again. */
10645 SCROLLING_NEED_LARGER_MATRICES
10649 try_scrolling (window
, just_this_one_p
, scroll_conservatively
,
10650 scroll_step
, temp_scroll_step
, last_line_misfit
)
10651 Lisp_Object window
;
10652 int just_this_one_p
;
10653 EMACS_INT scroll_conservatively
, scroll_step
;
10654 int temp_scroll_step
;
10655 int last_line_misfit
;
10657 struct window
*w
= XWINDOW (window
);
10658 struct frame
*f
= XFRAME (w
->frame
);
10659 struct text_pos scroll_margin_pos
;
10660 struct text_pos pos
;
10661 struct text_pos startp
;
10663 Lisp_Object window_end
;
10664 int this_scroll_margin
;
10668 int amount_to_scroll
= 0;
10669 Lisp_Object aggressive
;
10671 int end_scroll_margin
;
10674 debug_method_add (w
, "try_scrolling");
10677 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
10679 /* Compute scroll margin height in pixels. We scroll when point is
10680 within this distance from the top or bottom of the window. */
10681 if (scroll_margin
> 0)
10683 this_scroll_margin
= min (scroll_margin
, WINDOW_TOTAL_LINES (w
) / 4);
10684 this_scroll_margin
*= FRAME_LINE_HEIGHT (f
);
10687 this_scroll_margin
= 0;
10689 /* Compute how much we should try to scroll maximally to bring point
10691 if (scroll_step
|| scroll_conservatively
|| temp_scroll_step
)
10692 scroll_max
= max (scroll_step
,
10693 max (scroll_conservatively
, temp_scroll_step
));
10694 else if (NUMBERP (current_buffer
->scroll_down_aggressively
)
10695 || NUMBERP (current_buffer
->scroll_up_aggressively
))
10696 /* We're trying to scroll because of aggressive scrolling
10697 but no scroll_step is set. Choose an arbitrary one. Maybe
10698 there should be a variable for this. */
10702 scroll_max
*= FRAME_LINE_HEIGHT (f
);
10704 /* Decide whether we have to scroll down. Start at the window end
10705 and move this_scroll_margin up to find the position of the scroll
10707 window_end
= Fwindow_end (window
, Qt
);
10711 CHARPOS (scroll_margin_pos
) = XINT (window_end
);
10712 BYTEPOS (scroll_margin_pos
) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos
));
10714 end_scroll_margin
= this_scroll_margin
+ !!last_line_misfit
;
10715 if (end_scroll_margin
)
10717 start_display (&it
, w
, scroll_margin_pos
);
10718 move_it_vertically (&it
, - end_scroll_margin
);
10719 scroll_margin_pos
= it
.current
.pos
;
10722 if (PT
>= CHARPOS (scroll_margin_pos
))
10726 /* Point is in the scroll margin at the bottom of the window, or
10727 below. Compute a new window start that makes point visible. */
10729 /* Compute the distance from the scroll margin to PT.
10730 Give up if the distance is greater than scroll_max. */
10731 start_display (&it
, w
, scroll_margin_pos
);
10733 move_it_to (&it
, PT
, 0, it
.last_visible_y
, -1,
10734 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
10736 /* To make point visible, we have to move the window start
10737 down so that the line the cursor is in is visible, which
10738 means we have to add in the height of the cursor line. */
10739 dy
= line_bottom_y (&it
) - y0
;
10741 if (dy
> scroll_max
)
10742 return SCROLLING_FAILED
;
10744 /* Move the window start down. If scrolling conservatively,
10745 move it just enough down to make point visible. If
10746 scroll_step is set, move it down by scroll_step. */
10747 start_display (&it
, w
, startp
);
10749 if (scroll_conservatively
)
10750 /* Set AMOUNT_TO_SCROLL to at least one line,
10751 and at most scroll_conservatively lines. */
10753 = min (max (dy
, FRAME_LINE_HEIGHT (f
)),
10754 FRAME_LINE_HEIGHT (f
) * scroll_conservatively
);
10755 else if (scroll_step
|| temp_scroll_step
)
10756 amount_to_scroll
= scroll_max
;
10759 aggressive
= current_buffer
->scroll_up_aggressively
;
10760 height
= WINDOW_BOX_TEXT_HEIGHT (w
);
10761 if (NUMBERP (aggressive
))
10762 amount_to_scroll
= XFLOATINT (aggressive
) * height
;
10765 if (amount_to_scroll
<= 0)
10766 return SCROLLING_FAILED
;
10768 /* If moving by amount_to_scroll leaves STARTP unchanged,
10769 move it down one screen line. */
10771 move_it_vertically (&it
, amount_to_scroll
);
10772 if (CHARPOS (it
.current
.pos
) == CHARPOS (startp
))
10773 move_it_by_lines (&it
, 1, 1);
10774 startp
= it
.current
.pos
;
10778 /* See if point is inside the scroll margin at the top of the
10780 scroll_margin_pos
= startp
;
10781 if (this_scroll_margin
)
10783 start_display (&it
, w
, startp
);
10784 move_it_vertically (&it
, this_scroll_margin
);
10785 scroll_margin_pos
= it
.current
.pos
;
10788 if (PT
< CHARPOS (scroll_margin_pos
))
10790 /* Point is in the scroll margin at the top of the window or
10791 above what is displayed in the window. */
10794 /* Compute the vertical distance from PT to the scroll
10795 margin position. Give up if distance is greater than
10797 SET_TEXT_POS (pos
, PT
, PT_BYTE
);
10798 start_display (&it
, w
, pos
);
10800 move_it_to (&it
, CHARPOS (scroll_margin_pos
), 0,
10801 it
.last_visible_y
, -1,
10802 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
10803 dy
= it
.current_y
- y0
;
10804 if (dy
> scroll_max
)
10805 return SCROLLING_FAILED
;
10807 /* Compute new window start. */
10808 start_display (&it
, w
, startp
);
10810 if (scroll_conservatively
)
10812 max (dy
, FRAME_LINE_HEIGHT (f
) * max (scroll_step
, temp_scroll_step
));
10813 else if (scroll_step
|| temp_scroll_step
)
10814 amount_to_scroll
= scroll_max
;
10817 aggressive
= current_buffer
->scroll_down_aggressively
;
10818 height
= WINDOW_BOX_TEXT_HEIGHT (w
);
10819 if (NUMBERP (aggressive
))
10820 amount_to_scroll
= XFLOATINT (aggressive
) * height
;
10823 if (amount_to_scroll
<= 0)
10824 return SCROLLING_FAILED
;
10826 move_it_vertically (&it
, - amount_to_scroll
);
10827 startp
= it
.current
.pos
;
10831 /* Run window scroll functions. */
10832 startp
= run_window_scroll_functions (window
, startp
);
10834 /* Display the window. Give up if new fonts are loaded, or if point
10836 if (!try_window (window
, startp
))
10837 rc
= SCROLLING_NEED_LARGER_MATRICES
;
10838 else if (w
->cursor
.vpos
< 0)
10840 clear_glyph_matrix (w
->desired_matrix
);
10841 rc
= SCROLLING_FAILED
;
10845 /* Maybe forget recorded base line for line number display. */
10846 if (!just_this_one_p
10847 || current_buffer
->clip_changed
10848 || BEG_UNCHANGED
< CHARPOS (startp
))
10849 w
->base_line_number
= Qnil
;
10851 /* If cursor ends up on a partially visible line,
10852 treat that as being off the bottom of the screen. */
10853 if (! make_cursor_line_fully_visible (w
))
10855 clear_glyph_matrix (w
->desired_matrix
);
10856 last_line_misfit
= 1;
10859 rc
= SCROLLING_SUCCESS
;
10866 /* Compute a suitable window start for window W if display of W starts
10867 on a continuation line. Value is non-zero if a new window start
10870 The new window start will be computed, based on W's width, starting
10871 from the start of the continued line. It is the start of the
10872 screen line with the minimum distance from the old start W->start. */
10875 compute_window_start_on_continuation_line (w
)
10878 struct text_pos pos
, start_pos
;
10879 int window_start_changed_p
= 0;
10881 SET_TEXT_POS_FROM_MARKER (start_pos
, w
->start
);
10883 /* If window start is on a continuation line... Window start may be
10884 < BEGV in case there's invisible text at the start of the
10885 buffer (M-x rmail, for example). */
10886 if (CHARPOS (start_pos
) > BEGV
10887 && FETCH_BYTE (BYTEPOS (start_pos
) - 1) != '\n')
10890 struct glyph_row
*row
;
10892 /* Handle the case that the window start is out of range. */
10893 if (CHARPOS (start_pos
) < BEGV
)
10894 SET_TEXT_POS (start_pos
, BEGV
, BEGV_BYTE
);
10895 else if (CHARPOS (start_pos
) > ZV
)
10896 SET_TEXT_POS (start_pos
, ZV
, ZV_BYTE
);
10898 /* Find the start of the continued line. This should be fast
10899 because scan_buffer is fast (newline cache). */
10900 row
= w
->desired_matrix
->rows
+ (WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0);
10901 init_iterator (&it
, w
, CHARPOS (start_pos
), BYTEPOS (start_pos
),
10902 row
, DEFAULT_FACE_ID
);
10903 reseat_at_previous_visible_line_start (&it
);
10905 /* If the line start is "too far" away from the window start,
10906 say it takes too much time to compute a new window start. */
10907 if (CHARPOS (start_pos
) - IT_CHARPOS (it
)
10908 < WINDOW_TOTAL_LINES (w
) * WINDOW_TOTAL_COLS (w
))
10910 int min_distance
, distance
;
10912 /* Move forward by display lines to find the new window
10913 start. If window width was enlarged, the new start can
10914 be expected to be > the old start. If window width was
10915 decreased, the new window start will be < the old start.
10916 So, we're looking for the display line start with the
10917 minimum distance from the old window start. */
10918 pos
= it
.current
.pos
;
10919 min_distance
= INFINITY
;
10920 while ((distance
= abs (CHARPOS (start_pos
) - IT_CHARPOS (it
))),
10921 distance
< min_distance
)
10923 min_distance
= distance
;
10924 pos
= it
.current
.pos
;
10925 move_it_by_lines (&it
, 1, 0);
10928 /* Set the window start there. */
10929 SET_MARKER_FROM_TEXT_POS (w
->start
, pos
);
10930 window_start_changed_p
= 1;
10934 return window_start_changed_p
;
10938 /* Try cursor movement in case text has not changed in window WINDOW,
10939 with window start STARTP. Value is
10941 CURSOR_MOVEMENT_SUCCESS if successful
10943 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
10945 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
10946 display. *SCROLL_STEP is set to 1, under certain circumstances, if
10947 we want to scroll as if scroll-step were set to 1. See the code.
10949 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
10950 which case we have to abort this redisplay, and adjust matrices
10955 CURSOR_MOVEMENT_SUCCESS
,
10956 CURSOR_MOVEMENT_CANNOT_BE_USED
,
10957 CURSOR_MOVEMENT_MUST_SCROLL
,
10958 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
10962 try_cursor_movement (window
, startp
, scroll_step
)
10963 Lisp_Object window
;
10964 struct text_pos startp
;
10967 struct window
*w
= XWINDOW (window
);
10968 struct frame
*f
= XFRAME (w
->frame
);
10969 int rc
= CURSOR_MOVEMENT_CANNOT_BE_USED
;
10972 if (inhibit_try_cursor_movement
)
10976 /* Handle case where text has not changed, only point, and it has
10977 not moved off the frame. */
10978 if (/* Point may be in this window. */
10979 PT
>= CHARPOS (startp
)
10980 /* Selective display hasn't changed. */
10981 && !current_buffer
->clip_changed
10982 /* Function force-mode-line-update is used to force a thorough
10983 redisplay. It sets either windows_or_buffers_changed or
10984 update_mode_lines. So don't take a shortcut here for these
10986 && !update_mode_lines
10987 && !windows_or_buffers_changed
10988 && !cursor_type_changed
10989 /* Can't use this case if highlighting a region. When a
10990 region exists, cursor movement has to do more than just
10992 && !(!NILP (Vtransient_mark_mode
)
10993 && !NILP (current_buffer
->mark_active
))
10994 && NILP (w
->region_showing
)
10995 && NILP (Vshow_trailing_whitespace
)
10996 /* Right after splitting windows, last_point may be nil. */
10997 && INTEGERP (w
->last_point
)
10998 /* This code is not used for mini-buffer for the sake of the case
10999 of redisplaying to replace an echo area message; since in
11000 that case the mini-buffer contents per se are usually
11001 unchanged. This code is of no real use in the mini-buffer
11002 since the handling of this_line_start_pos, etc., in redisplay
11003 handles the same cases. */
11004 && !EQ (window
, minibuf_window
)
11005 /* When splitting windows or for new windows, it happens that
11006 redisplay is called with a nil window_end_vpos or one being
11007 larger than the window. This should really be fixed in
11008 window.c. I don't have this on my list, now, so we do
11009 approximately the same as the old redisplay code. --gerd. */
11010 && INTEGERP (w
->window_end_vpos
)
11011 && XFASTINT (w
->window_end_vpos
) < w
->current_matrix
->nrows
11012 && (FRAME_WINDOW_P (f
)
11013 || !MARKERP (Voverlay_arrow_position
)
11014 || current_buffer
!= XMARKER (Voverlay_arrow_position
)->buffer
))
11016 int this_scroll_margin
;
11017 struct glyph_row
*row
= NULL
;
11020 debug_method_add (w
, "cursor movement");
11023 /* Scroll if point within this distance from the top or bottom
11024 of the window. This is a pixel value. */
11025 this_scroll_margin
= max (0, scroll_margin
);
11026 this_scroll_margin
= min (this_scroll_margin
, WINDOW_TOTAL_LINES (w
) / 4);
11027 this_scroll_margin
*= FRAME_LINE_HEIGHT (f
);
11029 /* Start with the row the cursor was displayed during the last
11030 not paused redisplay. Give up if that row is not valid. */
11031 if (w
->last_cursor
.vpos
< 0
11032 || w
->last_cursor
.vpos
>= w
->current_matrix
->nrows
)
11033 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11036 row
= MATRIX_ROW (w
->current_matrix
, w
->last_cursor
.vpos
);
11037 if (row
->mode_line_p
)
11039 if (!row
->enabled_p
)
11040 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11043 if (rc
== CURSOR_MOVEMENT_CANNOT_BE_USED
)
11046 int last_y
= window_text_bottom_y (w
) - this_scroll_margin
;
11048 if (PT
> XFASTINT (w
->last_point
))
11050 /* Point has moved forward. */
11051 while (MATRIX_ROW_END_CHARPOS (row
) < PT
11052 && MATRIX_ROW_BOTTOM_Y (row
) < last_y
)
11054 xassert (row
->enabled_p
);
11058 /* The end position of a row equals the start position
11059 of the next row. If PT is there, we would rather
11060 display it in the next line. */
11061 while (MATRIX_ROW_BOTTOM_Y (row
) < last_y
11062 && MATRIX_ROW_END_CHARPOS (row
) == PT
11063 && !cursor_row_p (w
, row
))
11066 /* If within the scroll margin, scroll. Note that
11067 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
11068 the next line would be drawn, and that
11069 this_scroll_margin can be zero. */
11070 if (MATRIX_ROW_BOTTOM_Y (row
) > last_y
11071 || PT
> MATRIX_ROW_END_CHARPOS (row
)
11072 /* Line is completely visible last line in window
11073 and PT is to be set in the next line. */
11074 || (MATRIX_ROW_BOTTOM_Y (row
) == last_y
11075 && PT
== MATRIX_ROW_END_CHARPOS (row
)
11076 && !row
->ends_at_zv_p
11077 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
)))
11080 else if (PT
< XFASTINT (w
->last_point
))
11082 /* Cursor has to be moved backward. Note that PT >=
11083 CHARPOS (startp) because of the outer
11085 while (!row
->mode_line_p
11086 && (MATRIX_ROW_START_CHARPOS (row
) > PT
11087 || (MATRIX_ROW_START_CHARPOS (row
) == PT
11088 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row
)))
11089 && (row
->y
> this_scroll_margin
11090 || CHARPOS (startp
) == BEGV
))
11092 xassert (row
->enabled_p
);
11096 /* Consider the following case: Window starts at BEGV,
11097 there is invisible, intangible text at BEGV, so that
11098 display starts at some point START > BEGV. It can
11099 happen that we are called with PT somewhere between
11100 BEGV and START. Try to handle that case. */
11101 if (row
< w
->current_matrix
->rows
11102 || row
->mode_line_p
)
11104 row
= w
->current_matrix
->rows
;
11105 if (row
->mode_line_p
)
11109 /* Due to newlines in overlay strings, we may have to
11110 skip forward over overlay strings. */
11111 while (MATRIX_ROW_BOTTOM_Y (row
) < last_y
11112 && MATRIX_ROW_END_CHARPOS (row
) == PT
11113 && !cursor_row_p (w
, row
))
11116 /* If within the scroll margin, scroll. */
11117 if (row
->y
< this_scroll_margin
11118 && CHARPOS (startp
) != BEGV
)
11122 if (PT
< MATRIX_ROW_START_CHARPOS (row
)
11123 || PT
> MATRIX_ROW_END_CHARPOS (row
))
11125 /* if PT is not in the glyph row, give up. */
11126 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11128 else if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row
))
11130 if (PT
== MATRIX_ROW_END_CHARPOS (row
)
11131 && !row
->ends_at_zv_p
11132 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
))
11133 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11134 else if (row
->height
> window_box_height (w
))
11136 /* If we end up in a partially visible line, let's
11137 make it fully visible, except when it's taller
11138 than the window, in which case we can't do much
11141 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11145 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
11146 if (!make_cursor_line_fully_visible (w
))
11147 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11149 rc
= CURSOR_MOVEMENT_SUCCESS
;
11153 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11156 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
11157 rc
= CURSOR_MOVEMENT_SUCCESS
;
11166 set_vertical_scroll_bar (w
)
11169 int start
, end
, whole
;
11171 /* Calculate the start and end positions for the current window.
11172 At some point, it would be nice to choose between scrollbars
11173 which reflect the whole buffer size, with special markers
11174 indicating narrowing, and scrollbars which reflect only the
11177 Note that mini-buffers sometimes aren't displaying any text. */
11178 if (!MINI_WINDOW_P (w
)
11179 || (w
== XWINDOW (minibuf_window
)
11180 && NILP (echo_area_buffer
[0])))
11182 struct buffer
*buf
= XBUFFER (w
->buffer
);
11183 whole
= BUF_ZV (buf
) - BUF_BEGV (buf
);
11184 start
= marker_position (w
->start
) - BUF_BEGV (buf
);
11185 /* I don't think this is guaranteed to be right. For the
11186 moment, we'll pretend it is. */
11187 end
= BUF_Z (buf
) - XFASTINT (w
->window_end_pos
) - BUF_BEGV (buf
);
11191 if (whole
< (end
- start
))
11192 whole
= end
- start
;
11195 start
= end
= whole
= 0;
11197 /* Indicate what this scroll bar ought to be displaying now. */
11198 set_vertical_scroll_bar_hook (w
, end
- start
, whole
, start
);
11202 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
11203 selected_window is redisplayed.
11205 We can return without actually redisplaying the window if
11206 fonts_changed_p is nonzero. In that case, redisplay_internal will
11210 redisplay_window (window
, just_this_one_p
)
11211 Lisp_Object window
;
11212 int just_this_one_p
;
11214 struct window
*w
= XWINDOW (window
);
11215 struct frame
*f
= XFRAME (w
->frame
);
11216 struct buffer
*buffer
= XBUFFER (w
->buffer
);
11217 struct buffer
*old
= current_buffer
;
11218 struct text_pos lpoint
, opoint
, startp
;
11219 int update_mode_line
;
11222 /* Record it now because it's overwritten. */
11223 int current_matrix_up_to_date_p
= 0;
11224 int used_current_matrix_p
= 0;
11225 /* This is less strict than current_matrix_up_to_date_p.
11226 It indictes that the buffer contents and narrowing are unchanged. */
11227 int buffer_unchanged_p
= 0;
11228 int temp_scroll_step
= 0;
11229 int count
= SPECPDL_INDEX ();
11231 int centering_position
;
11232 int last_line_misfit
= 0;
11234 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
11237 /* W must be a leaf window here. */
11238 xassert (!NILP (w
->buffer
));
11240 *w
->desired_matrix
->method
= 0;
11243 specbind (Qinhibit_point_motion_hooks
, Qt
);
11245 reconsider_clip_changes (w
, buffer
);
11247 /* Has the mode line to be updated? */
11248 update_mode_line
= (!NILP (w
->update_mode_line
)
11249 || update_mode_lines
11250 || buffer
->clip_changed
11251 || buffer
->prevent_redisplay_optimizations_p
);
11253 if (MINI_WINDOW_P (w
))
11255 if (w
== XWINDOW (echo_area_window
)
11256 && !NILP (echo_area_buffer
[0]))
11258 if (update_mode_line
)
11259 /* We may have to update a tty frame's menu bar or a
11260 tool-bar. Example `M-x C-h C-h C-g'. */
11261 goto finish_menu_bars
;
11263 /* We've already displayed the echo area glyphs in this window. */
11264 goto finish_scroll_bars
;
11266 else if ((w
!= XWINDOW (minibuf_window
)
11267 || minibuf_level
== 0)
11268 /* When buffer is nonempty, redisplay window normally. */
11269 && BUF_Z (XBUFFER (w
->buffer
)) == BUF_BEG (XBUFFER (w
->buffer
))
11270 /* Quail displays non-mini buffers in minibuffer window.
11271 In that case, redisplay the window normally. */
11272 && !NILP (Fmemq (w
->buffer
, Vminibuffer_list
)))
11274 /* W is a mini-buffer window, but it's not active, so clear
11276 int yb
= window_text_bottom_y (w
);
11277 struct glyph_row
*row
;
11280 for (y
= 0, row
= w
->desired_matrix
->rows
;
11282 y
+= row
->height
, ++row
)
11283 blank_row (w
, row
, y
);
11284 goto finish_scroll_bars
;
11287 clear_glyph_matrix (w
->desired_matrix
);
11290 /* Otherwise set up data on this window; select its buffer and point
11292 /* Really select the buffer, for the sake of buffer-local
11294 set_buffer_internal_1 (XBUFFER (w
->buffer
));
11295 SET_TEXT_POS (opoint
, PT
, PT_BYTE
);
11297 current_matrix_up_to_date_p
11298 = (!NILP (w
->window_end_valid
)
11299 && !current_buffer
->clip_changed
11300 && !current_buffer
->prevent_redisplay_optimizations_p
11301 && XFASTINT (w
->last_modified
) >= MODIFF
11302 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
);
11305 = (!NILP (w
->window_end_valid
)
11306 && !current_buffer
->clip_changed
11307 && XFASTINT (w
->last_modified
) >= MODIFF
11308 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
);
11310 /* When windows_or_buffers_changed is non-zero, we can't rely on
11311 the window end being valid, so set it to nil there. */
11312 if (windows_or_buffers_changed
)
11314 /* If window starts on a continuation line, maybe adjust the
11315 window start in case the window's width changed. */
11316 if (XMARKER (w
->start
)->buffer
== current_buffer
)
11317 compute_window_start_on_continuation_line (w
);
11319 w
->window_end_valid
= Qnil
;
11322 /* Some sanity checks. */
11323 CHECK_WINDOW_END (w
);
11324 if (Z
== Z_BYTE
&& CHARPOS (opoint
) != BYTEPOS (opoint
))
11326 if (BYTEPOS (opoint
) < CHARPOS (opoint
))
11329 /* If %c is in mode line, update it if needed. */
11330 if (!NILP (w
->column_number_displayed
)
11331 /* This alternative quickly identifies a common case
11332 where no change is needed. */
11333 && !(PT
== XFASTINT (w
->last_point
)
11334 && XFASTINT (w
->last_modified
) >= MODIFF
11335 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
)
11336 && (XFASTINT (w
->column_number_displayed
)
11337 != (int) current_column ())) /* iftc */
11338 update_mode_line
= 1;
11340 /* Count number of windows showing the selected buffer. An indirect
11341 buffer counts as its base buffer. */
11342 if (!just_this_one_p
)
11344 struct buffer
*current_base
, *window_base
;
11345 current_base
= current_buffer
;
11346 window_base
= XBUFFER (XWINDOW (selected_window
)->buffer
);
11347 if (current_base
->base_buffer
)
11348 current_base
= current_base
->base_buffer
;
11349 if (window_base
->base_buffer
)
11350 window_base
= window_base
->base_buffer
;
11351 if (current_base
== window_base
)
11355 /* Point refers normally to the selected window. For any other
11356 window, set up appropriate value. */
11357 if (!EQ (window
, selected_window
))
11359 int new_pt
= XMARKER (w
->pointm
)->charpos
;
11360 int new_pt_byte
= marker_byte_position (w
->pointm
);
11364 new_pt_byte
= BEGV_BYTE
;
11365 set_marker_both (w
->pointm
, Qnil
, BEGV
, BEGV_BYTE
);
11367 else if (new_pt
> (ZV
- 1))
11370 new_pt_byte
= ZV_BYTE
;
11371 set_marker_both (w
->pointm
, Qnil
, ZV
, ZV_BYTE
);
11374 /* We don't use SET_PT so that the point-motion hooks don't run. */
11375 TEMP_SET_PT_BOTH (new_pt
, new_pt_byte
);
11378 /* If any of the character widths specified in the display table
11379 have changed, invalidate the width run cache. It's true that
11380 this may be a bit late to catch such changes, but the rest of
11381 redisplay goes (non-fatally) haywire when the display table is
11382 changed, so why should we worry about doing any better? */
11383 if (current_buffer
->width_run_cache
)
11385 struct Lisp_Char_Table
*disptab
= buffer_display_table ();
11387 if (! disptab_matches_widthtab (disptab
,
11388 XVECTOR (current_buffer
->width_table
)))
11390 invalidate_region_cache (current_buffer
,
11391 current_buffer
->width_run_cache
,
11393 recompute_width_table (current_buffer
, disptab
);
11397 /* If window-start is screwed up, choose a new one. */
11398 if (XMARKER (w
->start
)->buffer
!= current_buffer
)
11401 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
11403 /* If someone specified a new starting point but did not insist,
11404 check whether it can be used. */
11405 if (!NILP (w
->optional_new_start
)
11406 && CHARPOS (startp
) >= BEGV
11407 && CHARPOS (startp
) <= ZV
)
11409 w
->optional_new_start
= Qnil
;
11410 start_display (&it
, w
, startp
);
11411 move_it_to (&it
, PT
, 0, it
.last_visible_y
, -1,
11412 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
11413 if (IT_CHARPOS (it
) == PT
)
11414 w
->force_start
= Qt
;
11415 /* IT may overshoot PT if text at PT is invisible. */
11416 else if (IT_CHARPOS (it
) > PT
&& CHARPOS (startp
) <= PT
)
11417 w
->force_start
= Qt
;
11422 /* Handle case where place to start displaying has been specified,
11423 unless the specified location is outside the accessible range. */
11424 if (!NILP (w
->force_start
)
11425 || w
->frozen_window_start_p
)
11427 /* We set this later on if we have to adjust point. */
11430 w
->force_start
= Qnil
;
11432 w
->window_end_valid
= Qnil
;
11434 /* Forget any recorded base line for line number display. */
11435 if (!buffer_unchanged_p
)
11436 w
->base_line_number
= Qnil
;
11438 /* Redisplay the mode line. Select the buffer properly for that.
11439 Also, run the hook window-scroll-functions
11440 because we have scrolled. */
11441 /* Note, we do this after clearing force_start because
11442 if there's an error, it is better to forget about force_start
11443 than to get into an infinite loop calling the hook functions
11444 and having them get more errors. */
11445 if (!update_mode_line
11446 || ! NILP (Vwindow_scroll_functions
))
11448 update_mode_line
= 1;
11449 w
->update_mode_line
= Qt
;
11450 startp
= run_window_scroll_functions (window
, startp
);
11453 w
->last_modified
= make_number (0);
11454 w
->last_overlay_modified
= make_number (0);
11455 if (CHARPOS (startp
) < BEGV
)
11456 SET_TEXT_POS (startp
, BEGV
, BEGV_BYTE
);
11457 else if (CHARPOS (startp
) > ZV
)
11458 SET_TEXT_POS (startp
, ZV
, ZV_BYTE
);
11460 /* Redisplay, then check if cursor has been set during the
11461 redisplay. Give up if new fonts were loaded. */
11462 if (!try_window (window
, startp
))
11464 w
->force_start
= Qt
;
11465 clear_glyph_matrix (w
->desired_matrix
);
11466 goto need_larger_matrices
;
11469 if (w
->cursor
.vpos
< 0 && !w
->frozen_window_start_p
)
11471 /* If point does not appear, try to move point so it does
11472 appear. The desired matrix has been built above, so we
11473 can use it here. */
11474 new_vpos
= window_box_height (w
) / 2;
11477 if (!make_cursor_line_fully_visible (w
))
11479 /* Point does appear, but on a line partly visible at end of window.
11480 Move it back to a fully-visible line. */
11481 new_vpos
= window_box_height (w
);
11484 /* If we need to move point for either of the above reasons,
11485 now actually do it. */
11488 struct glyph_row
*row
;
11490 row
= MATRIX_FIRST_TEXT_ROW (w
->desired_matrix
);
11491 while (MATRIX_ROW_BOTTOM_Y (row
) < new_vpos
)
11494 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row
),
11495 MATRIX_ROW_START_BYTEPOS (row
));
11497 if (w
!= XWINDOW (selected_window
))
11498 set_marker_both (w
->pointm
, Qnil
, PT
, PT_BYTE
);
11499 else if (current_buffer
== old
)
11500 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
11502 set_cursor_from_row (w
, row
, w
->desired_matrix
, 0, 0, 0, 0);
11504 /* If we are highlighting the region, then we just changed
11505 the region, so redisplay to show it. */
11506 if (!NILP (Vtransient_mark_mode
)
11507 && !NILP (current_buffer
->mark_active
))
11509 clear_glyph_matrix (w
->desired_matrix
);
11510 if (!try_window (window
, startp
))
11511 goto need_larger_matrices
;
11516 debug_method_add (w
, "forced window start");
11521 /* Handle case where text has not changed, only point, and it has
11522 not moved off the frame, and we are not retrying after hscroll.
11523 (current_matrix_up_to_date_p is nonzero when retrying.) */
11524 if (current_matrix_up_to_date_p
11525 && (rc
= try_cursor_movement (window
, startp
, &temp_scroll_step
),
11526 rc
!= CURSOR_MOVEMENT_CANNOT_BE_USED
))
11530 case CURSOR_MOVEMENT_SUCCESS
:
11531 used_current_matrix_p
= 1;
11534 #if 0 /* try_cursor_movement never returns this value. */
11535 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES
:
11536 goto need_larger_matrices
;
11539 case CURSOR_MOVEMENT_MUST_SCROLL
:
11540 goto try_to_scroll
;
11546 /* If current starting point was originally the beginning of a line
11547 but no longer is, find a new starting point. */
11548 else if (!NILP (w
->start_at_line_beg
)
11549 && !(CHARPOS (startp
) <= BEGV
11550 || FETCH_BYTE (BYTEPOS (startp
) - 1) == '\n'))
11553 debug_method_add (w
, "recenter 1");
11558 /* Try scrolling with try_window_id. Value is > 0 if update has
11559 been done, it is -1 if we know that the same window start will
11560 not work. It is 0 if unsuccessful for some other reason. */
11561 else if ((tem
= try_window_id (w
)) != 0)
11564 debug_method_add (w
, "try_window_id %d", tem
);
11567 if (fonts_changed_p
)
11568 goto need_larger_matrices
;
11572 /* Otherwise try_window_id has returned -1 which means that we
11573 don't want the alternative below this comment to execute. */
11575 else if (CHARPOS (startp
) >= BEGV
11576 && CHARPOS (startp
) <= ZV
11577 && PT
>= CHARPOS (startp
)
11578 && (CHARPOS (startp
) < ZV
11579 /* Avoid starting at end of buffer. */
11580 || CHARPOS (startp
) == BEGV
11581 || (XFASTINT (w
->last_modified
) >= MODIFF
11582 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
)))
11585 debug_method_add (w
, "same window start");
11588 /* Try to redisplay starting at same place as before.
11589 If point has not moved off frame, accept the results. */
11590 if (!current_matrix_up_to_date_p
11591 /* Don't use try_window_reusing_current_matrix in this case
11592 because a window scroll function can have changed the
11594 || !NILP (Vwindow_scroll_functions
)
11595 || MINI_WINDOW_P (w
)
11596 || !(used_current_matrix_p
=
11597 try_window_reusing_current_matrix (w
)))
11599 IF_DEBUG (debug_method_add (w
, "1"));
11600 try_window (window
, startp
);
11603 if (fonts_changed_p
)
11604 goto need_larger_matrices
;
11606 if (w
->cursor
.vpos
>= 0)
11608 if (!just_this_one_p
11609 || current_buffer
->clip_changed
11610 || BEG_UNCHANGED
< CHARPOS (startp
))
11611 /* Forget any recorded base line for line number display. */
11612 w
->base_line_number
= Qnil
;
11614 if (!make_cursor_line_fully_visible (w
))
11616 clear_glyph_matrix (w
->desired_matrix
);
11617 last_line_misfit
= 1;
11619 /* Drop through and scroll. */
11624 clear_glyph_matrix (w
->desired_matrix
);
11629 w
->last_modified
= make_number (0);
11630 w
->last_overlay_modified
= make_number (0);
11632 /* Redisplay the mode line. Select the buffer properly for that. */
11633 if (!update_mode_line
)
11635 update_mode_line
= 1;
11636 w
->update_mode_line
= Qt
;
11639 /* Try to scroll by specified few lines. */
11640 if ((scroll_conservatively
11642 || temp_scroll_step
11643 || NUMBERP (current_buffer
->scroll_up_aggressively
)
11644 || NUMBERP (current_buffer
->scroll_down_aggressively
))
11645 && !current_buffer
->clip_changed
11646 && CHARPOS (startp
) >= BEGV
11647 && CHARPOS (startp
) <= ZV
)
11649 /* The function returns -1 if new fonts were loaded, 1 if
11650 successful, 0 if not successful. */
11651 int rc
= try_scrolling (window
, just_this_one_p
,
11652 scroll_conservatively
,
11654 temp_scroll_step
, last_line_misfit
);
11657 case SCROLLING_SUCCESS
:
11660 case SCROLLING_NEED_LARGER_MATRICES
:
11661 goto need_larger_matrices
;
11663 case SCROLLING_FAILED
:
11671 /* Finally, just choose place to start which centers point */
11674 centering_position
= window_box_height (w
) / 2;
11677 /* Jump here with centering_position already set to 0. */
11680 debug_method_add (w
, "recenter");
11683 /* w->vscroll = 0; */
11685 /* Forget any previously recorded base line for line number display. */
11686 if (!buffer_unchanged_p
)
11687 w
->base_line_number
= Qnil
;
11689 /* Move backward half the height of the window. */
11690 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
11691 it
.current_y
= it
.last_visible_y
;
11692 move_it_vertically_backward (&it
, centering_position
);
11693 xassert (IT_CHARPOS (it
) >= BEGV
);
11695 /* The function move_it_vertically_backward may move over more
11696 than the specified y-distance. If it->w is small, e.g. a
11697 mini-buffer window, we may end up in front of the window's
11698 display area. Start displaying at the start of the line
11699 containing PT in this case. */
11700 if (it
.current_y
<= 0)
11702 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
11703 move_it_vertically (&it
, 0);
11704 xassert (IT_CHARPOS (it
) <= PT
);
11708 it
.current_x
= it
.hpos
= 0;
11710 /* Set startp here explicitly in case that helps avoid an infinite loop
11711 in case the window-scroll-functions functions get errors. */
11712 set_marker_both (w
->start
, Qnil
, IT_CHARPOS (it
), IT_BYTEPOS (it
));
11714 /* Run scroll hooks. */
11715 startp
= run_window_scroll_functions (window
, it
.current
.pos
);
11717 /* Redisplay the window. */
11718 if (!current_matrix_up_to_date_p
11719 || windows_or_buffers_changed
11720 || cursor_type_changed
11721 /* Don't use try_window_reusing_current_matrix in this case
11722 because it can have changed the buffer. */
11723 || !NILP (Vwindow_scroll_functions
)
11724 || !just_this_one_p
11725 || MINI_WINDOW_P (w
)
11726 || !(used_current_matrix_p
=
11727 try_window_reusing_current_matrix (w
)))
11728 try_window (window
, startp
);
11730 /* If new fonts have been loaded (due to fontsets), give up. We
11731 have to start a new redisplay since we need to re-adjust glyph
11733 if (fonts_changed_p
)
11734 goto need_larger_matrices
;
11736 /* If cursor did not appear assume that the middle of the window is
11737 in the first line of the window. Do it again with the next line.
11738 (Imagine a window of height 100, displaying two lines of height
11739 60. Moving back 50 from it->last_visible_y will end in the first
11741 if (w
->cursor
.vpos
< 0)
11743 if (!NILP (w
->window_end_valid
)
11744 && PT
>= Z
- XFASTINT (w
->window_end_pos
))
11746 clear_glyph_matrix (w
->desired_matrix
);
11747 move_it_by_lines (&it
, 1, 0);
11748 try_window (window
, it
.current
.pos
);
11750 else if (PT
< IT_CHARPOS (it
))
11752 clear_glyph_matrix (w
->desired_matrix
);
11753 move_it_by_lines (&it
, -1, 0);
11754 try_window (window
, it
.current
.pos
);
11758 /* Not much we can do about it. */
11762 /* Consider the following case: Window starts at BEGV, there is
11763 invisible, intangible text at BEGV, so that display starts at
11764 some point START > BEGV. It can happen that we are called with
11765 PT somewhere between BEGV and START. Try to handle that case. */
11766 if (w
->cursor
.vpos
< 0)
11768 struct glyph_row
*row
= w
->current_matrix
->rows
;
11769 if (row
->mode_line_p
)
11771 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
11774 if (!make_cursor_line_fully_visible (w
))
11776 /* If vscroll is enabled, disable it and try again. */
11780 clear_glyph_matrix (w
->desired_matrix
);
11784 /* If centering point failed to make the whole line visible,
11785 put point at the top instead. That has to make the whole line
11786 visible, if it can be done. */
11787 centering_position
= 0;
11793 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
11794 w
->start_at_line_beg
= ((CHARPOS (startp
) == BEGV
11795 || FETCH_BYTE (BYTEPOS (startp
) - 1) == '\n')
11798 /* Display the mode line, if we must. */
11799 if ((update_mode_line
11800 /* If window not full width, must redo its mode line
11801 if (a) the window to its side is being redone and
11802 (b) we do a frame-based redisplay. This is a consequence
11803 of how inverted lines are drawn in frame-based redisplay. */
11804 || (!just_this_one_p
11805 && !FRAME_WINDOW_P (f
)
11806 && !WINDOW_FULL_WIDTH_P (w
))
11807 /* Line number to display. */
11808 || INTEGERP (w
->base_line_pos
)
11809 /* Column number is displayed and different from the one displayed. */
11810 || (!NILP (w
->column_number_displayed
)
11811 && (XFASTINT (w
->column_number_displayed
)
11812 != (int) current_column ()))) /* iftc */
11813 /* This means that the window has a mode line. */
11814 && (WINDOW_WANTS_MODELINE_P (w
)
11815 || WINDOW_WANTS_HEADER_LINE_P (w
)))
11817 display_mode_lines (w
);
11819 /* If mode line height has changed, arrange for a thorough
11820 immediate redisplay using the correct mode line height. */
11821 if (WINDOW_WANTS_MODELINE_P (w
)
11822 && CURRENT_MODE_LINE_HEIGHT (w
) != DESIRED_MODE_LINE_HEIGHT (w
))
11824 fonts_changed_p
= 1;
11825 MATRIX_MODE_LINE_ROW (w
->current_matrix
)->height
11826 = DESIRED_MODE_LINE_HEIGHT (w
);
11829 /* If top line height has changed, arrange for a thorough
11830 immediate redisplay using the correct mode line height. */
11831 if (WINDOW_WANTS_HEADER_LINE_P (w
)
11832 && CURRENT_HEADER_LINE_HEIGHT (w
) != DESIRED_HEADER_LINE_HEIGHT (w
))
11834 fonts_changed_p
= 1;
11835 MATRIX_HEADER_LINE_ROW (w
->current_matrix
)->height
11836 = DESIRED_HEADER_LINE_HEIGHT (w
);
11839 if (fonts_changed_p
)
11840 goto need_larger_matrices
;
11843 if (!line_number_displayed
11844 && !BUFFERP (w
->base_line_pos
))
11846 w
->base_line_pos
= Qnil
;
11847 w
->base_line_number
= Qnil
;
11852 /* When we reach a frame's selected window, redo the frame's menu bar. */
11853 if (update_mode_line
11854 && EQ (FRAME_SELECTED_WINDOW (f
), window
))
11856 int redisplay_menu_p
= 0;
11857 int redisplay_tool_bar_p
= 0;
11859 if (FRAME_WINDOW_P (f
))
11861 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
11862 || defined (USE_GTK)
11863 redisplay_menu_p
= FRAME_EXTERNAL_MENU_BAR (f
);
11865 redisplay_menu_p
= FRAME_MENU_BAR_LINES (f
) > 0;
11869 redisplay_menu_p
= FRAME_MENU_BAR_LINES (f
) > 0;
11871 if (redisplay_menu_p
)
11872 display_menu_bar (w
);
11874 #ifdef HAVE_WINDOW_SYSTEM
11876 redisplay_tool_bar_p
= FRAME_EXTERNAL_TOOL_BAR (f
);
11878 redisplay_tool_bar_p
= WINDOWP (f
->tool_bar_window
)
11879 && (FRAME_TOOL_BAR_LINES (f
) > 0
11880 || auto_resize_tool_bars_p
);
11884 if (redisplay_tool_bar_p
)
11885 redisplay_tool_bar (f
);
11889 #ifdef HAVE_WINDOW_SYSTEM
11890 if (update_window_fringes (w
, 0)
11891 && !just_this_one_p
11892 && (used_current_matrix_p
|| overlay_arrow_seen
)
11893 && !w
->pseudo_window_p
)
11897 draw_window_fringes (w
);
11901 #endif /* HAVE_WINDOW_SYSTEM */
11903 /* We go to this label, with fonts_changed_p nonzero,
11904 if it is necessary to try again using larger glyph matrices.
11905 We have to redeem the scroll bar even in this case,
11906 because the loop in redisplay_internal expects that. */
11907 need_larger_matrices
:
11909 finish_scroll_bars
:
11911 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w
))
11913 /* Set the thumb's position and size. */
11914 set_vertical_scroll_bar (w
);
11916 /* Note that we actually used the scroll bar attached to this
11917 window, so it shouldn't be deleted at the end of redisplay. */
11918 redeem_scroll_bar_hook (w
);
11921 /* Restore current_buffer and value of point in it. */
11922 TEMP_SET_PT_BOTH (CHARPOS (opoint
), BYTEPOS (opoint
));
11923 set_buffer_internal_1 (old
);
11924 TEMP_SET_PT_BOTH (CHARPOS (lpoint
), BYTEPOS (lpoint
));
11926 unbind_to (count
, Qnil
);
11930 /* Build the complete desired matrix of WINDOW with a window start
11931 buffer position POS. Value is non-zero if successful. It is zero
11932 if fonts were loaded during redisplay which makes re-adjusting
11933 glyph matrices necessary. */
11936 try_window (window
, pos
)
11937 Lisp_Object window
;
11938 struct text_pos pos
;
11940 struct window
*w
= XWINDOW (window
);
11942 struct glyph_row
*last_text_row
= NULL
;
11944 /* Make POS the new window start. */
11945 set_marker_both (w
->start
, Qnil
, CHARPOS (pos
), BYTEPOS (pos
));
11947 /* Mark cursor position as unknown. No overlay arrow seen. */
11948 w
->cursor
.vpos
= -1;
11949 overlay_arrow_seen
= 0;
11951 /* Initialize iterator and info to start at POS. */
11952 start_display (&it
, w
, pos
);
11954 /* Display all lines of W. */
11955 while (it
.current_y
< it
.last_visible_y
)
11957 if (display_line (&it
))
11958 last_text_row
= it
.glyph_row
- 1;
11959 if (fonts_changed_p
)
11963 /* If bottom moved off end of frame, change mode line percentage. */
11964 if (XFASTINT (w
->window_end_pos
) <= 0
11965 && Z
!= IT_CHARPOS (it
))
11966 w
->update_mode_line
= Qt
;
11968 /* Set window_end_pos to the offset of the last character displayed
11969 on the window from the end of current_buffer. Set
11970 window_end_vpos to its row number. */
11973 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row
));
11974 w
->window_end_bytepos
11975 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
11977 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
11979 = make_number (MATRIX_ROW_VPOS (last_text_row
, w
->desired_matrix
));
11980 xassert (MATRIX_ROW (w
->desired_matrix
, XFASTINT (w
->window_end_vpos
))
11981 ->displays_text_p
);
11985 w
->window_end_bytepos
= Z_BYTE
- ZV_BYTE
;
11986 w
->window_end_pos
= make_number (Z
- ZV
);
11987 w
->window_end_vpos
= make_number (0);
11990 /* But that is not valid info until redisplay finishes. */
11991 w
->window_end_valid
= Qnil
;
11997 /************************************************************************
11998 Window redisplay reusing current matrix when buffer has not changed
11999 ************************************************************************/
12001 /* Try redisplay of window W showing an unchanged buffer with a
12002 different window start than the last time it was displayed by
12003 reusing its current matrix. Value is non-zero if successful.
12004 W->start is the new window start. */
12007 try_window_reusing_current_matrix (w
)
12010 struct frame
*f
= XFRAME (w
->frame
);
12011 struct glyph_row
*row
, *bottom_row
;
12014 struct text_pos start
, new_start
;
12015 int nrows_scrolled
, i
;
12016 struct glyph_row
*last_text_row
;
12017 struct glyph_row
*last_reused_text_row
;
12018 struct glyph_row
*start_row
;
12019 int start_vpos
, min_y
, max_y
;
12022 if (inhibit_try_window_reusing
)
12026 if (/* This function doesn't handle terminal frames. */
12027 !FRAME_WINDOW_P (f
)
12028 /* Don't try to reuse the display if windows have been split
12030 || windows_or_buffers_changed
12031 || cursor_type_changed
)
12034 /* Can't do this if region may have changed. */
12035 if ((!NILP (Vtransient_mark_mode
)
12036 && !NILP (current_buffer
->mark_active
))
12037 || !NILP (w
->region_showing
)
12038 || !NILP (Vshow_trailing_whitespace
))
12041 /* If top-line visibility has changed, give up. */
12042 if (WINDOW_WANTS_HEADER_LINE_P (w
)
12043 != MATRIX_HEADER_LINE_ROW (w
->current_matrix
)->mode_line_p
)
12046 /* Give up if old or new display is scrolled vertically. We could
12047 make this function handle this, but right now it doesn't. */
12048 start_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
12049 if (w
->vscroll
|| MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row
))
12052 /* The variable new_start now holds the new window start. The old
12053 start `start' can be determined from the current matrix. */
12054 SET_TEXT_POS_FROM_MARKER (new_start
, w
->start
);
12055 start
= start_row
->start
.pos
;
12056 start_vpos
= MATRIX_ROW_VPOS (start_row
, w
->current_matrix
);
12058 /* Clear the desired matrix for the display below. */
12059 clear_glyph_matrix (w
->desired_matrix
);
12061 if (CHARPOS (new_start
) <= CHARPOS (start
))
12065 /* Don't use this method if the display starts with an ellipsis
12066 displayed for invisible text. It's not easy to handle that case
12067 below, and it's certainly not worth the effort since this is
12068 not a frequent case. */
12069 if (in_ellipses_for_invisible_text_p (&start_row
->start
, w
))
12072 IF_DEBUG (debug_method_add (w
, "twu1"));
12074 /* Display up to a row that can be reused. The variable
12075 last_text_row is set to the last row displayed that displays
12076 text. Note that it.vpos == 0 if or if not there is a
12077 header-line; it's not the same as the MATRIX_ROW_VPOS! */
12078 start_display (&it
, w
, new_start
);
12079 first_row_y
= it
.current_y
;
12080 w
->cursor
.vpos
= -1;
12081 last_text_row
= last_reused_text_row
= NULL
;
12083 while (it
.current_y
< it
.last_visible_y
12084 && IT_CHARPOS (it
) < CHARPOS (start
)
12085 && !fonts_changed_p
)
12086 if (display_line (&it
))
12087 last_text_row
= it
.glyph_row
- 1;
12089 /* A value of current_y < last_visible_y means that we stopped
12090 at the previous window start, which in turn means that we
12091 have at least one reusable row. */
12092 if (it
.current_y
< it
.last_visible_y
)
12094 /* IT.vpos always starts from 0; it counts text lines. */
12095 nrows_scrolled
= it
.vpos
;
12097 /* Find PT if not already found in the lines displayed. */
12098 if (w
->cursor
.vpos
< 0)
12100 int dy
= it
.current_y
- first_row_y
;
12102 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
12103 row
= row_containing_pos (w
, PT
, row
, NULL
, dy
);
12105 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0,
12106 dy
, nrows_scrolled
);
12109 clear_glyph_matrix (w
->desired_matrix
);
12114 /* Scroll the display. Do it before the current matrix is
12115 changed. The problem here is that update has not yet
12116 run, i.e. part of the current matrix is not up to date.
12117 scroll_run_hook will clear the cursor, and use the
12118 current matrix to get the height of the row the cursor is
12120 run
.current_y
= first_row_y
;
12121 run
.desired_y
= it
.current_y
;
12122 run
.height
= it
.last_visible_y
- it
.current_y
;
12124 if (run
.height
> 0 && run
.current_y
!= run
.desired_y
)
12127 rif
->update_window_begin_hook (w
);
12128 rif
->clear_window_mouse_face (w
);
12129 rif
->scroll_run_hook (w
, &run
);
12130 rif
->update_window_end_hook (w
, 0, 0);
12134 /* Shift current matrix down by nrows_scrolled lines. */
12135 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
12136 rotate_matrix (w
->current_matrix
,
12138 MATRIX_ROW_VPOS (bottom_row
, w
->current_matrix
),
12141 /* Disable lines that must be updated. */
12142 for (i
= 0; i
< it
.vpos
; ++i
)
12143 (start_row
+ i
)->enabled_p
= 0;
12145 /* Re-compute Y positions. */
12146 min_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
12147 max_y
= it
.last_visible_y
;
12148 for (row
= start_row
+ nrows_scrolled
;
12152 row
->y
= it
.current_y
;
12153 row
->visible_height
= row
->height
;
12155 if (row
->y
< min_y
)
12156 row
->visible_height
-= min_y
- row
->y
;
12157 if (row
->y
+ row
->height
> max_y
)
12158 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
12159 row
->redraw_fringe_bitmaps_p
= 1;
12161 it
.current_y
+= row
->height
;
12163 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
12164 last_reused_text_row
= row
;
12165 if (MATRIX_ROW_BOTTOM_Y (row
) >= it
.last_visible_y
)
12169 /* Disable lines in the current matrix which are now
12170 below the window. */
12171 for (++row
; row
< bottom_row
; ++row
)
12172 row
->enabled_p
= 0;
12175 /* Update window_end_pos etc.; last_reused_text_row is the last
12176 reused row from the current matrix containing text, if any.
12177 The value of last_text_row is the last displayed line
12178 containing text. */
12179 if (last_reused_text_row
)
12181 w
->window_end_bytepos
12182 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_reused_text_row
);
12184 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_reused_text_row
));
12186 = make_number (MATRIX_ROW_VPOS (last_reused_text_row
,
12187 w
->current_matrix
));
12189 else if (last_text_row
)
12191 w
->window_end_bytepos
12192 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
12194 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
12196 = make_number (MATRIX_ROW_VPOS (last_text_row
, w
->desired_matrix
));
12200 /* This window must be completely empty. */
12201 w
->window_end_bytepos
= Z_BYTE
- ZV_BYTE
;
12202 w
->window_end_pos
= make_number (Z
- ZV
);
12203 w
->window_end_vpos
= make_number (0);
12205 w
->window_end_valid
= Qnil
;
12207 /* Update hint: don't try scrolling again in update_window. */
12208 w
->desired_matrix
->no_scrolling_p
= 1;
12211 debug_method_add (w
, "try_window_reusing_current_matrix 1");
12215 else if (CHARPOS (new_start
) > CHARPOS (start
))
12217 struct glyph_row
*pt_row
, *row
;
12218 struct glyph_row
*first_reusable_row
;
12219 struct glyph_row
*first_row_to_display
;
12221 int yb
= window_text_bottom_y (w
);
12223 /* Find the row starting at new_start, if there is one. Don't
12224 reuse a partially visible line at the end. */
12225 first_reusable_row
= start_row
;
12226 while (first_reusable_row
->enabled_p
12227 && MATRIX_ROW_BOTTOM_Y (first_reusable_row
) < yb
12228 && (MATRIX_ROW_START_CHARPOS (first_reusable_row
)
12229 < CHARPOS (new_start
)))
12230 ++first_reusable_row
;
12232 /* Give up if there is no row to reuse. */
12233 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row
) >= yb
12234 || !first_reusable_row
->enabled_p
12235 || (MATRIX_ROW_START_CHARPOS (first_reusable_row
)
12236 != CHARPOS (new_start
)))
12239 /* We can reuse fully visible rows beginning with
12240 first_reusable_row to the end of the window. Set
12241 first_row_to_display to the first row that cannot be reused.
12242 Set pt_row to the row containing point, if there is any. */
12244 for (first_row_to_display
= first_reusable_row
;
12245 MATRIX_ROW_BOTTOM_Y (first_row_to_display
) < yb
;
12246 ++first_row_to_display
)
12248 if (PT
>= MATRIX_ROW_START_CHARPOS (first_row_to_display
)
12249 && PT
< MATRIX_ROW_END_CHARPOS (first_row_to_display
))
12250 pt_row
= first_row_to_display
;
12253 /* Start displaying at the start of first_row_to_display. */
12254 xassert (first_row_to_display
->y
< yb
);
12255 init_to_row_start (&it
, w
, first_row_to_display
);
12257 nrows_scrolled
= (MATRIX_ROW_VPOS (first_reusable_row
, w
->current_matrix
)
12259 it
.vpos
= (MATRIX_ROW_VPOS (first_row_to_display
, w
->current_matrix
)
12261 it
.current_y
= (first_row_to_display
->y
- first_reusable_row
->y
12262 + WINDOW_HEADER_LINE_HEIGHT (w
));
12264 /* Display lines beginning with first_row_to_display in the
12265 desired matrix. Set last_text_row to the last row displayed
12266 that displays text. */
12267 it
.glyph_row
= MATRIX_ROW (w
->desired_matrix
, it
.vpos
);
12268 if (pt_row
== NULL
)
12269 w
->cursor
.vpos
= -1;
12270 last_text_row
= NULL
;
12271 while (it
.current_y
< it
.last_visible_y
&& !fonts_changed_p
)
12272 if (display_line (&it
))
12273 last_text_row
= it
.glyph_row
- 1;
12275 /* Give up If point isn't in a row displayed or reused. */
12276 if (w
->cursor
.vpos
< 0)
12278 clear_glyph_matrix (w
->desired_matrix
);
12282 /* If point is in a reused row, adjust y and vpos of the cursor
12286 w
->cursor
.vpos
-= MATRIX_ROW_VPOS (first_reusable_row
,
12287 w
->current_matrix
);
12288 w
->cursor
.y
-= first_reusable_row
->y
;
12291 /* Scroll the display. */
12292 run
.current_y
= first_reusable_row
->y
;
12293 run
.desired_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
12294 run
.height
= it
.last_visible_y
- run
.current_y
;
12295 dy
= run
.current_y
- run
.desired_y
;
12300 rif
->update_window_begin_hook (w
);
12301 rif
->clear_window_mouse_face (w
);
12302 rif
->scroll_run_hook (w
, &run
);
12303 rif
->update_window_end_hook (w
, 0, 0);
12307 /* Adjust Y positions of reused rows. */
12308 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
12309 min_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
12310 max_y
= it
.last_visible_y
;
12311 for (row
= first_reusable_row
; row
< first_row_to_display
; ++row
)
12314 row
->visible_height
= row
->height
;
12315 if (row
->y
< min_y
)
12316 row
->visible_height
-= min_y
- row
->y
;
12317 if (row
->y
+ row
->height
> max_y
)
12318 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
12319 row
->redraw_fringe_bitmaps_p
= 1;
12322 /* Scroll the current matrix. */
12323 xassert (nrows_scrolled
> 0);
12324 rotate_matrix (w
->current_matrix
,
12326 MATRIX_ROW_VPOS (bottom_row
, w
->current_matrix
),
12329 /* Disable rows not reused. */
12330 for (row
-= nrows_scrolled
; row
< bottom_row
; ++row
)
12331 row
->enabled_p
= 0;
12333 /* Adjust window end. A null value of last_text_row means that
12334 the window end is in reused rows which in turn means that
12335 only its vpos can have changed. */
12338 w
->window_end_bytepos
12339 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
12341 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
12343 = make_number (MATRIX_ROW_VPOS (last_text_row
, w
->desired_matrix
));
12348 = make_number (XFASTINT (w
->window_end_vpos
) - nrows_scrolled
);
12351 w
->window_end_valid
= Qnil
;
12352 w
->desired_matrix
->no_scrolling_p
= 1;
12355 debug_method_add (w
, "try_window_reusing_current_matrix 2");
12365 /************************************************************************
12366 Window redisplay reusing current matrix when buffer has changed
12367 ************************************************************************/
12369 static struct glyph_row
*find_last_unchanged_at_beg_row
P_ ((struct window
*));
12370 static struct glyph_row
*find_first_unchanged_at_end_row
P_ ((struct window
*,
12372 static struct glyph_row
*
12373 find_last_row_displaying_text
P_ ((struct glyph_matrix
*, struct it
*,
12374 struct glyph_row
*));
12377 /* Return the last row in MATRIX displaying text. If row START is
12378 non-null, start searching with that row. IT gives the dimensions
12379 of the display. Value is null if matrix is empty; otherwise it is
12380 a pointer to the row found. */
12382 static struct glyph_row
*
12383 find_last_row_displaying_text (matrix
, it
, start
)
12384 struct glyph_matrix
*matrix
;
12386 struct glyph_row
*start
;
12388 struct glyph_row
*row
, *row_found
;
12390 /* Set row_found to the last row in IT->w's current matrix
12391 displaying text. The loop looks funny but think of partially
12394 row
= start
? start
: MATRIX_FIRST_TEXT_ROW (matrix
);
12395 while (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
12397 xassert (row
->enabled_p
);
12399 if (MATRIX_ROW_BOTTOM_Y (row
) >= it
->last_visible_y
)
12408 /* Return the last row in the current matrix of W that is not affected
12409 by changes at the start of current_buffer that occurred since W's
12410 current matrix was built. Value is null if no such row exists.
12412 BEG_UNCHANGED us the number of characters unchanged at the start of
12413 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
12414 first changed character in current_buffer. Characters at positions <
12415 BEG + BEG_UNCHANGED are at the same buffer positions as they were
12416 when the current matrix was built. */
12418 static struct glyph_row
*
12419 find_last_unchanged_at_beg_row (w
)
12422 int first_changed_pos
= BEG
+ BEG_UNCHANGED
;
12423 struct glyph_row
*row
;
12424 struct glyph_row
*row_found
= NULL
;
12425 int yb
= window_text_bottom_y (w
);
12427 /* Find the last row displaying unchanged text. */
12428 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
12429 while (MATRIX_ROW_DISPLAYS_TEXT_P (row
)
12430 && MATRIX_ROW_START_CHARPOS (row
) < first_changed_pos
)
12432 if (/* If row ends before first_changed_pos, it is unchanged,
12433 except in some case. */
12434 MATRIX_ROW_END_CHARPOS (row
) <= first_changed_pos
12435 /* When row ends in ZV and we write at ZV it is not
12437 && !row
->ends_at_zv_p
12438 /* When first_changed_pos is the end of a continued line,
12439 row is not unchanged because it may be no longer
12441 && !(MATRIX_ROW_END_CHARPOS (row
) == first_changed_pos
12442 && (row
->continued_p
12443 || row
->exact_window_width_line_p
)))
12446 /* Stop if last visible row. */
12447 if (MATRIX_ROW_BOTTOM_Y (row
) >= yb
)
12457 /* Find the first glyph row in the current matrix of W that is not
12458 affected by changes at the end of current_buffer since the
12459 time W's current matrix was built.
12461 Return in *DELTA the number of chars by which buffer positions in
12462 unchanged text at the end of current_buffer must be adjusted.
12464 Return in *DELTA_BYTES the corresponding number of bytes.
12466 Value is null if no such row exists, i.e. all rows are affected by
12469 static struct glyph_row
*
12470 find_first_unchanged_at_end_row (w
, delta
, delta_bytes
)
12472 int *delta
, *delta_bytes
;
12474 struct glyph_row
*row
;
12475 struct glyph_row
*row_found
= NULL
;
12477 *delta
= *delta_bytes
= 0;
12479 /* Display must not have been paused, otherwise the current matrix
12480 is not up to date. */
12481 if (NILP (w
->window_end_valid
))
12484 /* A value of window_end_pos >= END_UNCHANGED means that the window
12485 end is in the range of changed text. If so, there is no
12486 unchanged row at the end of W's current matrix. */
12487 if (XFASTINT (w
->window_end_pos
) >= END_UNCHANGED
)
12490 /* Set row to the last row in W's current matrix displaying text. */
12491 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
12493 /* If matrix is entirely empty, no unchanged row exists. */
12494 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
12496 /* The value of row is the last glyph row in the matrix having a
12497 meaningful buffer position in it. The end position of row
12498 corresponds to window_end_pos. This allows us to translate
12499 buffer positions in the current matrix to current buffer
12500 positions for characters not in changed text. */
12501 int Z_old
= MATRIX_ROW_END_CHARPOS (row
) + XFASTINT (w
->window_end_pos
);
12502 int Z_BYTE_old
= MATRIX_ROW_END_BYTEPOS (row
) + w
->window_end_bytepos
;
12503 int last_unchanged_pos
, last_unchanged_pos_old
;
12504 struct glyph_row
*first_text_row
12505 = MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
12507 *delta
= Z
- Z_old
;
12508 *delta_bytes
= Z_BYTE
- Z_BYTE_old
;
12510 /* Set last_unchanged_pos to the buffer position of the last
12511 character in the buffer that has not been changed. Z is the
12512 index + 1 of the last character in current_buffer, i.e. by
12513 subtracting END_UNCHANGED we get the index of the last
12514 unchanged character, and we have to add BEG to get its buffer
12516 last_unchanged_pos
= Z
- END_UNCHANGED
+ BEG
;
12517 last_unchanged_pos_old
= last_unchanged_pos
- *delta
;
12519 /* Search backward from ROW for a row displaying a line that
12520 starts at a minimum position >= last_unchanged_pos_old. */
12521 for (; row
> first_text_row
; --row
)
12523 if (!row
->enabled_p
|| !MATRIX_ROW_DISPLAYS_TEXT_P (row
))
12526 if (MATRIX_ROW_START_CHARPOS (row
) >= last_unchanged_pos_old
)
12531 if (row_found
&& !MATRIX_ROW_DISPLAYS_TEXT_P (row_found
))
12538 /* Make sure that glyph rows in the current matrix of window W
12539 reference the same glyph memory as corresponding rows in the
12540 frame's frame matrix. This function is called after scrolling W's
12541 current matrix on a terminal frame in try_window_id and
12542 try_window_reusing_current_matrix. */
12545 sync_frame_with_window_matrix_rows (w
)
12548 struct frame
*f
= XFRAME (w
->frame
);
12549 struct glyph_row
*window_row
, *window_row_end
, *frame_row
;
12551 /* Preconditions: W must be a leaf window and full-width. Its frame
12552 must have a frame matrix. */
12553 xassert (NILP (w
->hchild
) && NILP (w
->vchild
));
12554 xassert (WINDOW_FULL_WIDTH_P (w
));
12555 xassert (!FRAME_WINDOW_P (f
));
12557 /* If W is a full-width window, glyph pointers in W's current matrix
12558 have, by definition, to be the same as glyph pointers in the
12559 corresponding frame matrix. Note that frame matrices have no
12560 marginal areas (see build_frame_matrix). */
12561 window_row
= w
->current_matrix
->rows
;
12562 window_row_end
= window_row
+ w
->current_matrix
->nrows
;
12563 frame_row
= f
->current_matrix
->rows
+ WINDOW_TOP_EDGE_LINE (w
);
12564 while (window_row
< window_row_end
)
12566 struct glyph
*start
= window_row
->glyphs
[LEFT_MARGIN_AREA
];
12567 struct glyph
*end
= window_row
->glyphs
[LAST_AREA
];
12569 frame_row
->glyphs
[LEFT_MARGIN_AREA
] = start
;
12570 frame_row
->glyphs
[TEXT_AREA
] = start
;
12571 frame_row
->glyphs
[RIGHT_MARGIN_AREA
] = end
;
12572 frame_row
->glyphs
[LAST_AREA
] = end
;
12574 /* Disable frame rows whose corresponding window rows have
12575 been disabled in try_window_id. */
12576 if (!window_row
->enabled_p
)
12577 frame_row
->enabled_p
= 0;
12579 ++window_row
, ++frame_row
;
12584 /* Find the glyph row in window W containing CHARPOS. Consider all
12585 rows between START and END (not inclusive). END null means search
12586 all rows to the end of the display area of W. Value is the row
12587 containing CHARPOS or null. */
12590 row_containing_pos (w
, charpos
, start
, end
, dy
)
12593 struct glyph_row
*start
, *end
;
12596 struct glyph_row
*row
= start
;
12599 /* If we happen to start on a header-line, skip that. */
12600 if (row
->mode_line_p
)
12603 if ((end
&& row
>= end
) || !row
->enabled_p
)
12606 last_y
= window_text_bottom_y (w
) - dy
;
12610 /* Give up if we have gone too far. */
12611 if (end
&& row
>= end
)
12613 /* This formerly returned if they were equal.
12614 I think that both quantities are of a "last plus one" type;
12615 if so, when they are equal, the row is within the screen. -- rms. */
12616 if (MATRIX_ROW_BOTTOM_Y (row
) > last_y
)
12619 /* If it is in this row, return this row. */
12620 if (! (MATRIX_ROW_END_CHARPOS (row
) < charpos
12621 || (MATRIX_ROW_END_CHARPOS (row
) == charpos
12622 /* The end position of a row equals the start
12623 position of the next row. If CHARPOS is there, we
12624 would rather display it in the next line, except
12625 when this line ends in ZV. */
12626 && !row
->ends_at_zv_p
12627 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
)))
12628 && charpos
>= MATRIX_ROW_START_CHARPOS (row
))
12635 /* Try to redisplay window W by reusing its existing display. W's
12636 current matrix must be up to date when this function is called,
12637 i.e. window_end_valid must not be nil.
12641 1 if display has been updated
12642 0 if otherwise unsuccessful
12643 -1 if redisplay with same window start is known not to succeed
12645 The following steps are performed:
12647 1. Find the last row in the current matrix of W that is not
12648 affected by changes at the start of current_buffer. If no such row
12651 2. Find the first row in W's current matrix that is not affected by
12652 changes at the end of current_buffer. Maybe there is no such row.
12654 3. Display lines beginning with the row + 1 found in step 1 to the
12655 row found in step 2 or, if step 2 didn't find a row, to the end of
12658 4. If cursor is not known to appear on the window, give up.
12660 5. If display stopped at the row found in step 2, scroll the
12661 display and current matrix as needed.
12663 6. Maybe display some lines at the end of W, if we must. This can
12664 happen under various circumstances, like a partially visible line
12665 becoming fully visible, or because newly displayed lines are displayed
12666 in smaller font sizes.
12668 7. Update W's window end information. */
12674 struct frame
*f
= XFRAME (w
->frame
);
12675 struct glyph_matrix
*current_matrix
= w
->current_matrix
;
12676 struct glyph_matrix
*desired_matrix
= w
->desired_matrix
;
12677 struct glyph_row
*last_unchanged_at_beg_row
;
12678 struct glyph_row
*first_unchanged_at_end_row
;
12679 struct glyph_row
*row
;
12680 struct glyph_row
*bottom_row
;
12683 int delta
= 0, delta_bytes
= 0, stop_pos
, dvpos
, dy
;
12684 struct text_pos start_pos
;
12686 int first_unchanged_at_end_vpos
= 0;
12687 struct glyph_row
*last_text_row
, *last_text_row_at_end
;
12688 struct text_pos start
;
12689 int first_changed_charpos
, last_changed_charpos
;
12692 if (inhibit_try_window_id
)
12696 /* This is handy for debugging. */
12698 #define GIVE_UP(X) \
12700 fprintf (stderr, "try_window_id give up %d\n", (X)); \
12704 #define GIVE_UP(X) return 0
12707 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
12709 /* Don't use this for mini-windows because these can show
12710 messages and mini-buffers, and we don't handle that here. */
12711 if (MINI_WINDOW_P (w
))
12714 /* This flag is used to prevent redisplay optimizations. */
12715 if (windows_or_buffers_changed
|| cursor_type_changed
)
12718 /* Verify that narrowing has not changed.
12719 Also verify that we were not told to prevent redisplay optimizations.
12720 It would be nice to further
12721 reduce the number of cases where this prevents try_window_id. */
12722 if (current_buffer
->clip_changed
12723 || current_buffer
->prevent_redisplay_optimizations_p
)
12726 /* Window must either use window-based redisplay or be full width. */
12727 if (!FRAME_WINDOW_P (f
)
12728 && (!line_ins_del_ok
12729 || !WINDOW_FULL_WIDTH_P (w
)))
12732 /* Give up if point is not known NOT to appear in W. */
12733 if (PT
< CHARPOS (start
))
12736 /* Another way to prevent redisplay optimizations. */
12737 if (XFASTINT (w
->last_modified
) == 0)
12740 /* Verify that window is not hscrolled. */
12741 if (XFASTINT (w
->hscroll
) != 0)
12744 /* Verify that display wasn't paused. */
12745 if (NILP (w
->window_end_valid
))
12748 /* Can't use this if highlighting a region because a cursor movement
12749 will do more than just set the cursor. */
12750 if (!NILP (Vtransient_mark_mode
)
12751 && !NILP (current_buffer
->mark_active
))
12754 /* Likewise if highlighting trailing whitespace. */
12755 if (!NILP (Vshow_trailing_whitespace
))
12758 /* Likewise if showing a region. */
12759 if (!NILP (w
->region_showing
))
12762 /* Can use this if overlay arrow position and or string have changed. */
12763 if (!EQ (last_arrow_position
, COERCE_MARKER (Voverlay_arrow_position
))
12764 || !EQ (last_arrow_string
, Voverlay_arrow_string
))
12768 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
12769 only if buffer has really changed. The reason is that the gap is
12770 initially at Z for freshly visited files. The code below would
12771 set end_unchanged to 0 in that case. */
12772 if (MODIFF
> SAVE_MODIFF
12773 /* This seems to happen sometimes after saving a buffer. */
12774 || BEG_UNCHANGED
+ END_UNCHANGED
> Z_BYTE
)
12776 if (GPT
- BEG
< BEG_UNCHANGED
)
12777 BEG_UNCHANGED
= GPT
- BEG
;
12778 if (Z
- GPT
< END_UNCHANGED
)
12779 END_UNCHANGED
= Z
- GPT
;
12782 /* The position of the first and last character that has been changed. */
12783 first_changed_charpos
= BEG
+ BEG_UNCHANGED
;
12784 last_changed_charpos
= Z
- END_UNCHANGED
;
12786 /* If window starts after a line end, and the last change is in
12787 front of that newline, then changes don't affect the display.
12788 This case happens with stealth-fontification. Note that although
12789 the display is unchanged, glyph positions in the matrix have to
12790 be adjusted, of course. */
12791 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
12792 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
)
12793 && ((last_changed_charpos
< CHARPOS (start
)
12794 && CHARPOS (start
) == BEGV
)
12795 || (last_changed_charpos
< CHARPOS (start
) - 1
12796 && FETCH_BYTE (BYTEPOS (start
) - 1) == '\n')))
12798 int Z_old
, delta
, Z_BYTE_old
, delta_bytes
;
12799 struct glyph_row
*r0
;
12801 /* Compute how many chars/bytes have been added to or removed
12802 from the buffer. */
12803 Z_old
= MATRIX_ROW_END_CHARPOS (row
) + XFASTINT (w
->window_end_pos
);
12804 Z_BYTE_old
= MATRIX_ROW_END_BYTEPOS (row
) + w
->window_end_bytepos
;
12806 delta_bytes
= Z_BYTE
- Z_BYTE_old
;
12808 /* Give up if PT is not in the window. Note that it already has
12809 been checked at the start of try_window_id that PT is not in
12810 front of the window start. */
12811 if (PT
>= MATRIX_ROW_END_CHARPOS (row
) + delta
)
12814 /* If window start is unchanged, we can reuse the whole matrix
12815 as is, after adjusting glyph positions. No need to compute
12816 the window end again, since its offset from Z hasn't changed. */
12817 r0
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
12818 if (CHARPOS (start
) == MATRIX_ROW_START_CHARPOS (r0
) + delta
12819 && BYTEPOS (start
) == MATRIX_ROW_START_BYTEPOS (r0
) + delta_bytes
12820 /* PT must not be in a partially visible line. */
12821 && !(PT
>= MATRIX_ROW_START_CHARPOS (row
) + delta
12822 && MATRIX_ROW_BOTTOM_Y (row
) > window_text_bottom_y (w
)))
12824 /* Adjust positions in the glyph matrix. */
12825 if (delta
|| delta_bytes
)
12827 struct glyph_row
*r1
12828 = MATRIX_BOTTOM_TEXT_ROW (current_matrix
, w
);
12829 increment_matrix_positions (w
->current_matrix
,
12830 MATRIX_ROW_VPOS (r0
, current_matrix
),
12831 MATRIX_ROW_VPOS (r1
, current_matrix
),
12832 delta
, delta_bytes
);
12835 /* Set the cursor. */
12836 row
= row_containing_pos (w
, PT
, r0
, NULL
, 0);
12838 set_cursor_from_row (w
, row
, current_matrix
, 0, 0, 0, 0);
12845 /* Handle the case that changes are all below what is displayed in
12846 the window, and that PT is in the window. This shortcut cannot
12847 be taken if ZV is visible in the window, and text has been added
12848 there that is visible in the window. */
12849 if (first_changed_charpos
>= MATRIX_ROW_END_CHARPOS (row
)
12850 /* ZV is not visible in the window, or there are no
12851 changes at ZV, actually. */
12852 && (current_matrix
->zv
> MATRIX_ROW_END_CHARPOS (row
)
12853 || first_changed_charpos
== last_changed_charpos
))
12855 struct glyph_row
*r0
;
12857 /* Give up if PT is not in the window. Note that it already has
12858 been checked at the start of try_window_id that PT is not in
12859 front of the window start. */
12860 if (PT
>= MATRIX_ROW_END_CHARPOS (row
))
12863 /* If window start is unchanged, we can reuse the whole matrix
12864 as is, without changing glyph positions since no text has
12865 been added/removed in front of the window end. */
12866 r0
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
12867 if (TEXT_POS_EQUAL_P (start
, r0
->start
.pos
)
12868 /* PT must not be in a partially visible line. */
12869 && !(PT
>= MATRIX_ROW_START_CHARPOS (row
)
12870 && MATRIX_ROW_BOTTOM_Y (row
) > window_text_bottom_y (w
)))
12872 /* We have to compute the window end anew since text
12873 can have been added/removed after it. */
12875 = make_number (Z
- MATRIX_ROW_END_CHARPOS (row
));
12876 w
->window_end_bytepos
12877 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
12879 /* Set the cursor. */
12880 row
= row_containing_pos (w
, PT
, r0
, NULL
, 0);
12882 set_cursor_from_row (w
, row
, current_matrix
, 0, 0, 0, 0);
12889 /* Give up if window start is in the changed area.
12891 The condition used to read
12893 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
12895 but why that was tested escapes me at the moment. */
12896 if (CHARPOS (start
) >= first_changed_charpos
12897 && CHARPOS (start
) <= last_changed_charpos
)
12900 /* Check that window start agrees with the start of the first glyph
12901 row in its current matrix. Check this after we know the window
12902 start is not in changed text, otherwise positions would not be
12904 row
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
12905 if (!TEXT_POS_EQUAL_P (start
, row
->start
.pos
))
12908 /* Give up if the window ends in strings. Overlay strings
12909 at the end are difficult to handle, so don't try. */
12910 row
= MATRIX_ROW (current_matrix
, XFASTINT (w
->window_end_vpos
));
12911 if (MATRIX_ROW_START_CHARPOS (row
) == MATRIX_ROW_END_CHARPOS (row
))
12914 /* Compute the position at which we have to start displaying new
12915 lines. Some of the lines at the top of the window might be
12916 reusable because they are not displaying changed text. Find the
12917 last row in W's current matrix not affected by changes at the
12918 start of current_buffer. Value is null if changes start in the
12919 first line of window. */
12920 last_unchanged_at_beg_row
= find_last_unchanged_at_beg_row (w
);
12921 if (last_unchanged_at_beg_row
)
12923 /* Avoid starting to display in the moddle of a character, a TAB
12924 for instance. This is easier than to set up the iterator
12925 exactly, and it's not a frequent case, so the additional
12926 effort wouldn't really pay off. */
12927 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row
)
12928 || last_unchanged_at_beg_row
->ends_in_newline_from_string_p
)
12929 && last_unchanged_at_beg_row
> w
->current_matrix
->rows
)
12930 --last_unchanged_at_beg_row
;
12932 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row
))
12935 if (init_to_row_end (&it
, w
, last_unchanged_at_beg_row
) == 0)
12937 start_pos
= it
.current
.pos
;
12939 /* Start displaying new lines in the desired matrix at the same
12940 vpos we would use in the current matrix, i.e. below
12941 last_unchanged_at_beg_row. */
12942 it
.vpos
= 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row
,
12944 it
.glyph_row
= MATRIX_ROW (desired_matrix
, it
.vpos
);
12945 it
.current_y
= MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row
);
12947 xassert (it
.hpos
== 0 && it
.current_x
== 0);
12951 /* There are no reusable lines at the start of the window.
12952 Start displaying in the first text line. */
12953 start_display (&it
, w
, start
);
12954 it
.vpos
= it
.first_vpos
;
12955 start_pos
= it
.current
.pos
;
12958 /* Find the first row that is not affected by changes at the end of
12959 the buffer. Value will be null if there is no unchanged row, in
12960 which case we must redisplay to the end of the window. delta
12961 will be set to the value by which buffer positions beginning with
12962 first_unchanged_at_end_row have to be adjusted due to text
12964 first_unchanged_at_end_row
12965 = find_first_unchanged_at_end_row (w
, &delta
, &delta_bytes
);
12966 IF_DEBUG (debug_delta
= delta
);
12967 IF_DEBUG (debug_delta_bytes
= delta_bytes
);
12969 /* Set stop_pos to the buffer position up to which we will have to
12970 display new lines. If first_unchanged_at_end_row != NULL, this
12971 is the buffer position of the start of the line displayed in that
12972 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
12973 that we don't stop at a buffer position. */
12975 if (first_unchanged_at_end_row
)
12977 xassert (last_unchanged_at_beg_row
== NULL
12978 || first_unchanged_at_end_row
>= last_unchanged_at_beg_row
);
12980 /* If this is a continuation line, move forward to the next one
12981 that isn't. Changes in lines above affect this line.
12982 Caution: this may move first_unchanged_at_end_row to a row
12983 not displaying text. */
12984 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row
)
12985 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
)
12986 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row
)
12987 < it
.last_visible_y
))
12988 ++first_unchanged_at_end_row
;
12990 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
)
12991 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row
)
12992 >= it
.last_visible_y
))
12993 first_unchanged_at_end_row
= NULL
;
12996 stop_pos
= (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row
)
12998 first_unchanged_at_end_vpos
12999 = MATRIX_ROW_VPOS (first_unchanged_at_end_row
, current_matrix
);
13000 xassert (stop_pos
>= Z
- END_UNCHANGED
);
13003 else if (last_unchanged_at_beg_row
== NULL
)
13009 /* Either there is no unchanged row at the end, or the one we have
13010 now displays text. This is a necessary condition for the window
13011 end pos calculation at the end of this function. */
13012 xassert (first_unchanged_at_end_row
== NULL
13013 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
));
13015 debug_last_unchanged_at_beg_vpos
13016 = (last_unchanged_at_beg_row
13017 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row
, current_matrix
)
13019 debug_first_unchanged_at_end_vpos
= first_unchanged_at_end_vpos
;
13021 #endif /* GLYPH_DEBUG != 0 */
13024 /* Display new lines. Set last_text_row to the last new line
13025 displayed which has text on it, i.e. might end up as being the
13026 line where the window_end_vpos is. */
13027 w
->cursor
.vpos
= -1;
13028 last_text_row
= NULL
;
13029 overlay_arrow_seen
= 0;
13030 while (it
.current_y
< it
.last_visible_y
13031 && !fonts_changed_p
13032 && (first_unchanged_at_end_row
== NULL
13033 || IT_CHARPOS (it
) < stop_pos
))
13035 if (display_line (&it
))
13036 last_text_row
= it
.glyph_row
- 1;
13039 if (fonts_changed_p
)
13043 /* Compute differences in buffer positions, y-positions etc. for
13044 lines reused at the bottom of the window. Compute what we can
13046 if (first_unchanged_at_end_row
13047 /* No lines reused because we displayed everything up to the
13048 bottom of the window. */
13049 && it
.current_y
< it
.last_visible_y
)
13052 - MATRIX_ROW_VPOS (first_unchanged_at_end_row
,
13054 dy
= it
.current_y
- first_unchanged_at_end_row
->y
;
13055 run
.current_y
= first_unchanged_at_end_row
->y
;
13056 run
.desired_y
= run
.current_y
+ dy
;
13057 run
.height
= it
.last_visible_y
- max (run
.current_y
, run
.desired_y
);
13061 delta
= dvpos
= dy
= run
.current_y
= run
.desired_y
= run
.height
= 0;
13062 first_unchanged_at_end_row
= NULL
;
13064 IF_DEBUG (debug_dvpos
= dvpos
; debug_dy
= dy
);
13067 /* Find the cursor if not already found. We have to decide whether
13068 PT will appear on this window (it sometimes doesn't, but this is
13069 not a very frequent case.) This decision has to be made before
13070 the current matrix is altered. A value of cursor.vpos < 0 means
13071 that PT is either in one of the lines beginning at
13072 first_unchanged_at_end_row or below the window. Don't care for
13073 lines that might be displayed later at the window end; as
13074 mentioned, this is not a frequent case. */
13075 if (w
->cursor
.vpos
< 0)
13077 /* Cursor in unchanged rows at the top? */
13078 if (PT
< CHARPOS (start_pos
)
13079 && last_unchanged_at_beg_row
)
13081 row
= row_containing_pos (w
, PT
,
13082 MATRIX_FIRST_TEXT_ROW (w
->current_matrix
),
13083 last_unchanged_at_beg_row
+ 1, 0);
13085 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
13088 /* Start from first_unchanged_at_end_row looking for PT. */
13089 else if (first_unchanged_at_end_row
)
13091 row
= row_containing_pos (w
, PT
- delta
,
13092 first_unchanged_at_end_row
, NULL
, 0);
13094 set_cursor_from_row (w
, row
, w
->current_matrix
, delta
,
13095 delta_bytes
, dy
, dvpos
);
13098 /* Give up if cursor was not found. */
13099 if (w
->cursor
.vpos
< 0)
13101 clear_glyph_matrix (w
->desired_matrix
);
13106 /* Don't let the cursor end in the scroll margins. */
13108 int this_scroll_margin
, cursor_height
;
13110 this_scroll_margin
= max (0, scroll_margin
);
13111 this_scroll_margin
= min (this_scroll_margin
, WINDOW_TOTAL_LINES (w
) / 4);
13112 this_scroll_margin
*= FRAME_LINE_HEIGHT (it
.f
);
13113 cursor_height
= MATRIX_ROW (w
->desired_matrix
, w
->cursor
.vpos
)->height
;
13115 if ((w
->cursor
.y
< this_scroll_margin
13116 && CHARPOS (start
) > BEGV
)
13117 /* Don't take scroll margin into account at the bottom because
13118 old redisplay didn't do it either. */
13119 || w
->cursor
.y
+ cursor_height
> it
.last_visible_y
)
13121 w
->cursor
.vpos
= -1;
13122 clear_glyph_matrix (w
->desired_matrix
);
13127 /* Scroll the display. Do it before changing the current matrix so
13128 that xterm.c doesn't get confused about where the cursor glyph is
13130 if (dy
&& run
.height
)
13134 if (FRAME_WINDOW_P (f
))
13136 rif
->update_window_begin_hook (w
);
13137 rif
->clear_window_mouse_face (w
);
13138 rif
->scroll_run_hook (w
, &run
);
13139 rif
->update_window_end_hook (w
, 0, 0);
13143 /* Terminal frame. In this case, dvpos gives the number of
13144 lines to scroll by; dvpos < 0 means scroll up. */
13145 int first_unchanged_at_end_vpos
13146 = MATRIX_ROW_VPOS (first_unchanged_at_end_row
, w
->current_matrix
);
13147 int from
= WINDOW_TOP_EDGE_LINE (w
) + first_unchanged_at_end_vpos
;
13148 int end
= (WINDOW_TOP_EDGE_LINE (w
)
13149 + (WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0)
13150 + window_internal_height (w
));
13152 /* Perform the operation on the screen. */
13155 /* Scroll last_unchanged_at_beg_row to the end of the
13156 window down dvpos lines. */
13157 set_terminal_window (end
);
13159 /* On dumb terminals delete dvpos lines at the end
13160 before inserting dvpos empty lines. */
13161 if (!scroll_region_ok
)
13162 ins_del_lines (end
- dvpos
, -dvpos
);
13164 /* Insert dvpos empty lines in front of
13165 last_unchanged_at_beg_row. */
13166 ins_del_lines (from
, dvpos
);
13168 else if (dvpos
< 0)
13170 /* Scroll up last_unchanged_at_beg_vpos to the end of
13171 the window to last_unchanged_at_beg_vpos - |dvpos|. */
13172 set_terminal_window (end
);
13174 /* Delete dvpos lines in front of
13175 last_unchanged_at_beg_vpos. ins_del_lines will set
13176 the cursor to the given vpos and emit |dvpos| delete
13178 ins_del_lines (from
+ dvpos
, dvpos
);
13180 /* On a dumb terminal insert dvpos empty lines at the
13182 if (!scroll_region_ok
)
13183 ins_del_lines (end
+ dvpos
, -dvpos
);
13186 set_terminal_window (0);
13192 /* Shift reused rows of the current matrix to the right position.
13193 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
13195 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (current_matrix
, w
);
13196 bottom_vpos
= MATRIX_ROW_VPOS (bottom_row
, current_matrix
);
13199 rotate_matrix (current_matrix
, first_unchanged_at_end_vpos
+ dvpos
,
13200 bottom_vpos
, dvpos
);
13201 enable_glyph_matrix_rows (current_matrix
, bottom_vpos
+ dvpos
,
13204 else if (dvpos
> 0)
13206 rotate_matrix (current_matrix
, first_unchanged_at_end_vpos
,
13207 bottom_vpos
, dvpos
);
13208 enable_glyph_matrix_rows (current_matrix
, first_unchanged_at_end_vpos
,
13209 first_unchanged_at_end_vpos
+ dvpos
, 0);
13212 /* For frame-based redisplay, make sure that current frame and window
13213 matrix are in sync with respect to glyph memory. */
13214 if (!FRAME_WINDOW_P (f
))
13215 sync_frame_with_window_matrix_rows (w
);
13217 /* Adjust buffer positions in reused rows. */
13219 increment_matrix_positions (current_matrix
,
13220 first_unchanged_at_end_vpos
+ dvpos
,
13221 bottom_vpos
, delta
, delta_bytes
);
13223 /* Adjust Y positions. */
13225 shift_glyph_matrix (w
, current_matrix
,
13226 first_unchanged_at_end_vpos
+ dvpos
,
13229 if (first_unchanged_at_end_row
)
13230 first_unchanged_at_end_row
+= dvpos
;
13232 /* If scrolling up, there may be some lines to display at the end of
13234 last_text_row_at_end
= NULL
;
13237 /* Scrolling up can leave for example a partially visible line
13238 at the end of the window to be redisplayed. */
13239 /* Set last_row to the glyph row in the current matrix where the
13240 window end line is found. It has been moved up or down in
13241 the matrix by dvpos. */
13242 int last_vpos
= XFASTINT (w
->window_end_vpos
) + dvpos
;
13243 struct glyph_row
*last_row
= MATRIX_ROW (current_matrix
, last_vpos
);
13245 /* If last_row is the window end line, it should display text. */
13246 xassert (last_row
->displays_text_p
);
13248 /* If window end line was partially visible before, begin
13249 displaying at that line. Otherwise begin displaying with the
13250 line following it. */
13251 if (MATRIX_ROW_BOTTOM_Y (last_row
) - dy
>= it
.last_visible_y
)
13253 init_to_row_start (&it
, w
, last_row
);
13254 it
.vpos
= last_vpos
;
13255 it
.current_y
= last_row
->y
;
13259 init_to_row_end (&it
, w
, last_row
);
13260 it
.vpos
= 1 + last_vpos
;
13261 it
.current_y
= MATRIX_ROW_BOTTOM_Y (last_row
);
13265 /* We may start in a continuation line. If so, we have to
13266 get the right continuation_lines_width and current_x. */
13267 it
.continuation_lines_width
= last_row
->continuation_lines_width
;
13268 it
.hpos
= it
.current_x
= 0;
13270 /* Display the rest of the lines at the window end. */
13271 it
.glyph_row
= MATRIX_ROW (desired_matrix
, it
.vpos
);
13272 while (it
.current_y
< it
.last_visible_y
13273 && !fonts_changed_p
)
13275 /* Is it always sure that the display agrees with lines in
13276 the current matrix? I don't think so, so we mark rows
13277 displayed invalid in the current matrix by setting their
13278 enabled_p flag to zero. */
13279 MATRIX_ROW (w
->current_matrix
, it
.vpos
)->enabled_p
= 0;
13280 if (display_line (&it
))
13281 last_text_row_at_end
= it
.glyph_row
- 1;
13285 /* Update window_end_pos and window_end_vpos. */
13286 if (first_unchanged_at_end_row
13287 && first_unchanged_at_end_row
->y
< it
.last_visible_y
13288 && !last_text_row_at_end
)
13290 /* Window end line if one of the preserved rows from the current
13291 matrix. Set row to the last row displaying text in current
13292 matrix starting at first_unchanged_at_end_row, after
13294 xassert (first_unchanged_at_end_row
->displays_text_p
);
13295 row
= find_last_row_displaying_text (w
->current_matrix
, &it
,
13296 first_unchanged_at_end_row
);
13297 xassert (row
&& MATRIX_ROW_DISPLAYS_TEXT_P (row
));
13299 w
->window_end_pos
= make_number (Z
- MATRIX_ROW_END_CHARPOS (row
));
13300 w
->window_end_bytepos
= Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
13302 = make_number (MATRIX_ROW_VPOS (row
, w
->current_matrix
));
13303 xassert (w
->window_end_bytepos
>= 0);
13304 IF_DEBUG (debug_method_add (w
, "A"));
13306 else if (last_text_row_at_end
)
13309 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row_at_end
));
13310 w
->window_end_bytepos
13311 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row_at_end
);
13313 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end
, desired_matrix
));
13314 xassert (w
->window_end_bytepos
>= 0);
13315 IF_DEBUG (debug_method_add (w
, "B"));
13317 else if (last_text_row
)
13319 /* We have displayed either to the end of the window or at the
13320 end of the window, i.e. the last row with text is to be found
13321 in the desired matrix. */
13323 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
13324 w
->window_end_bytepos
13325 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
13327 = make_number (MATRIX_ROW_VPOS (last_text_row
, desired_matrix
));
13328 xassert (w
->window_end_bytepos
>= 0);
13330 else if (first_unchanged_at_end_row
== NULL
13331 && last_text_row
== NULL
13332 && last_text_row_at_end
== NULL
)
13334 /* Displayed to end of window, but no line containing text was
13335 displayed. Lines were deleted at the end of the window. */
13336 int first_vpos
= WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0;
13337 int vpos
= XFASTINT (w
->window_end_vpos
);
13338 struct glyph_row
*current_row
= current_matrix
->rows
+ vpos
;
13339 struct glyph_row
*desired_row
= desired_matrix
->rows
+ vpos
;
13342 row
== NULL
&& vpos
>= first_vpos
;
13343 --vpos
, --current_row
, --desired_row
)
13345 if (desired_row
->enabled_p
)
13347 if (desired_row
->displays_text_p
)
13350 else if (current_row
->displays_text_p
)
13354 xassert (row
!= NULL
);
13355 w
->window_end_vpos
= make_number (vpos
+ 1);
13356 w
->window_end_pos
= make_number (Z
- MATRIX_ROW_END_CHARPOS (row
));
13357 w
->window_end_bytepos
= Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
13358 xassert (w
->window_end_bytepos
>= 0);
13359 IF_DEBUG (debug_method_add (w
, "C"));
13364 #if 0 /* This leads to problems, for instance when the cursor is
13365 at ZV, and the cursor line displays no text. */
13366 /* Disable rows below what's displayed in the window. This makes
13367 debugging easier. */
13368 enable_glyph_matrix_rows (current_matrix
,
13369 XFASTINT (w
->window_end_vpos
) + 1,
13373 IF_DEBUG (debug_end_pos
= XFASTINT (w
->window_end_pos
);
13374 debug_end_vpos
= XFASTINT (w
->window_end_vpos
));
13376 /* Record that display has not been completed. */
13377 w
->window_end_valid
= Qnil
;
13378 w
->desired_matrix
->no_scrolling_p
= 1;
13386 /***********************************************************************
13387 More debugging support
13388 ***********************************************************************/
13392 void dump_glyph_row
P_ ((struct glyph_row
*, int, int));
13393 void dump_glyph_matrix
P_ ((struct glyph_matrix
*, int));
13394 void dump_glyph
P_ ((struct glyph_row
*, struct glyph
*, int));
13397 /* Dump the contents of glyph matrix MATRIX on stderr.
13399 GLYPHS 0 means don't show glyph contents.
13400 GLYPHS 1 means show glyphs in short form
13401 GLYPHS > 1 means show glyphs in long form. */
13404 dump_glyph_matrix (matrix
, glyphs
)
13405 struct glyph_matrix
*matrix
;
13409 for (i
= 0; i
< matrix
->nrows
; ++i
)
13410 dump_glyph_row (MATRIX_ROW (matrix
, i
), i
, glyphs
);
13414 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
13415 the glyph row and area where the glyph comes from. */
13418 dump_glyph (row
, glyph
, area
)
13419 struct glyph_row
*row
;
13420 struct glyph
*glyph
;
13423 if (glyph
->type
== CHAR_GLYPH
)
13426 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13427 glyph
- row
->glyphs
[TEXT_AREA
],
13430 (BUFFERP (glyph
->object
)
13432 : (STRINGP (glyph
->object
)
13435 glyph
->pixel_width
,
13437 (glyph
->u
.ch
< 0x80 && glyph
->u
.ch
>= ' '
13441 glyph
->left_box_line_p
,
13442 glyph
->right_box_line_p
);
13444 else if (glyph
->type
== STRETCH_GLYPH
)
13447 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13448 glyph
- row
->glyphs
[TEXT_AREA
],
13451 (BUFFERP (glyph
->object
)
13453 : (STRINGP (glyph
->object
)
13456 glyph
->pixel_width
,
13460 glyph
->left_box_line_p
,
13461 glyph
->right_box_line_p
);
13463 else if (glyph
->type
== IMAGE_GLYPH
)
13466 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13467 glyph
- row
->glyphs
[TEXT_AREA
],
13470 (BUFFERP (glyph
->object
)
13472 : (STRINGP (glyph
->object
)
13475 glyph
->pixel_width
,
13479 glyph
->left_box_line_p
,
13480 glyph
->right_box_line_p
);
13485 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
13486 GLYPHS 0 means don't show glyph contents.
13487 GLYPHS 1 means show glyphs in short form
13488 GLYPHS > 1 means show glyphs in long form. */
13491 dump_glyph_row (row
, vpos
, glyphs
)
13492 struct glyph_row
*row
;
13497 fprintf (stderr
, "Row Start End Used oEI><O\\CTZFesm X Y W H V A P\n");
13498 fprintf (stderr
, "=======================================================================\n");
13500 fprintf (stderr
, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d%1.1d\
13501 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
13503 MATRIX_ROW_START_CHARPOS (row
),
13504 MATRIX_ROW_END_CHARPOS (row
),
13505 row
->used
[TEXT_AREA
],
13506 row
->contains_overlapping_glyphs_p
,
13508 row
->truncated_on_left_p
,
13509 row
->truncated_on_right_p
,
13510 row
->overlay_arrow_p
,
13512 MATRIX_ROW_CONTINUATION_LINE_P (row
),
13513 row
->displays_text_p
,
13516 row
->ends_in_middle_of_char_p
,
13517 row
->starts_in_middle_of_char_p
,
13523 row
->visible_height
,
13526 fprintf (stderr
, "%9d %5d\t%5d\n", row
->start
.overlay_string_index
,
13527 row
->end
.overlay_string_index
,
13528 row
->continuation_lines_width
);
13529 fprintf (stderr
, "%9d %5d\n",
13530 CHARPOS (row
->start
.string_pos
),
13531 CHARPOS (row
->end
.string_pos
));
13532 fprintf (stderr
, "%9d %5d\n", row
->start
.dpvec_index
,
13533 row
->end
.dpvec_index
);
13540 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
13542 struct glyph
*glyph
= row
->glyphs
[area
];
13543 struct glyph
*glyph_end
= glyph
+ row
->used
[area
];
13545 /* Glyph for a line end in text. */
13546 if (area
== TEXT_AREA
&& glyph
== glyph_end
&& glyph
->charpos
> 0)
13549 if (glyph
< glyph_end
)
13550 fprintf (stderr
, " Glyph Type Pos O W Code C Face LR\n");
13552 for (; glyph
< glyph_end
; ++glyph
)
13553 dump_glyph (row
, glyph
, area
);
13556 else if (glyphs
== 1)
13560 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
13562 char *s
= (char *) alloca (row
->used
[area
] + 1);
13565 for (i
= 0; i
< row
->used
[area
]; ++i
)
13567 struct glyph
*glyph
= row
->glyphs
[area
] + i
;
13568 if (glyph
->type
== CHAR_GLYPH
13569 && glyph
->u
.ch
< 0x80
13570 && glyph
->u
.ch
>= ' ')
13571 s
[i
] = glyph
->u
.ch
;
13577 fprintf (stderr
, "%3d: (%d) '%s'\n", vpos
, row
->enabled_p
, s
);
13583 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix
,
13584 Sdump_glyph_matrix
, 0, 1, "p",
13585 doc
: /* Dump the current matrix of the selected window to stderr.
13586 Shows contents of glyph row structures. With non-nil
13587 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
13588 glyphs in short form, otherwise show glyphs in long form. */)
13590 Lisp_Object glyphs
;
13592 struct window
*w
= XWINDOW (selected_window
);
13593 struct buffer
*buffer
= XBUFFER (w
->buffer
);
13595 fprintf (stderr
, "PT = %d, BEGV = %d. ZV = %d\n",
13596 BUF_PT (buffer
), BUF_BEGV (buffer
), BUF_ZV (buffer
));
13597 fprintf (stderr
, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
13598 w
->cursor
.x
, w
->cursor
.y
, w
->cursor
.hpos
, w
->cursor
.vpos
);
13599 fprintf (stderr
, "=============================================\n");
13600 dump_glyph_matrix (w
->current_matrix
,
13601 NILP (glyphs
) ? 0 : XINT (glyphs
));
13606 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix
,
13607 Sdump_frame_glyph_matrix
, 0, 0, "", doc
: /* */)
13610 struct frame
*f
= XFRAME (selected_frame
);
13611 dump_glyph_matrix (f
->current_matrix
, 1);
13616 DEFUN ("dump-glyph-row", Fdump_glyph_row
, Sdump_glyph_row
, 1, 2, "",
13617 doc
: /* Dump glyph row ROW to stderr.
13618 GLYPH 0 means don't dump glyphs.
13619 GLYPH 1 means dump glyphs in short form.
13620 GLYPH > 1 or omitted means dump glyphs in long form. */)
13622 Lisp_Object row
, glyphs
;
13624 struct glyph_matrix
*matrix
;
13627 CHECK_NUMBER (row
);
13628 matrix
= XWINDOW (selected_window
)->current_matrix
;
13630 if (vpos
>= 0 && vpos
< matrix
->nrows
)
13631 dump_glyph_row (MATRIX_ROW (matrix
, vpos
),
13633 INTEGERP (glyphs
) ? XINT (glyphs
) : 2);
13638 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row
, Sdump_tool_bar_row
, 1, 2, "",
13639 doc
: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
13640 GLYPH 0 means don't dump glyphs.
13641 GLYPH 1 means dump glyphs in short form.
13642 GLYPH > 1 or omitted means dump glyphs in long form. */)
13644 Lisp_Object row
, glyphs
;
13646 struct frame
*sf
= SELECTED_FRAME ();
13647 struct glyph_matrix
*m
= XWINDOW (sf
->tool_bar_window
)->current_matrix
;
13650 CHECK_NUMBER (row
);
13652 if (vpos
>= 0 && vpos
< m
->nrows
)
13653 dump_glyph_row (MATRIX_ROW (m
, vpos
), vpos
,
13654 INTEGERP (glyphs
) ? XINT (glyphs
) : 2);
13659 DEFUN ("trace-redisplay", Ftrace_redisplay
, Strace_redisplay
, 0, 1, "P",
13660 doc
: /* Toggle tracing of redisplay.
13661 With ARG, turn tracing on if and only if ARG is positive. */)
13666 trace_redisplay_p
= !trace_redisplay_p
;
13669 arg
= Fprefix_numeric_value (arg
);
13670 trace_redisplay_p
= XINT (arg
) > 0;
13677 DEFUN ("trace-to-stderr", Ftrace_to_stderr
, Strace_to_stderr
, 1, MANY
, "",
13678 doc
: /* Like `format', but print result to stderr.
13679 usage: (trace-to-stderr STRING &rest OBJECTS) */)
13684 Lisp_Object s
= Fformat (nargs
, args
);
13685 fprintf (stderr
, "%s", SDATA (s
));
13689 #endif /* GLYPH_DEBUG */
13693 /***********************************************************************
13694 Building Desired Matrix Rows
13695 ***********************************************************************/
13697 /* Return a temporary glyph row holding the glyphs of an overlay
13698 arrow. Only used for non-window-redisplay windows. */
13700 static struct glyph_row
*
13701 get_overlay_arrow_glyph_row (w
)
13704 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
13705 struct buffer
*buffer
= XBUFFER (w
->buffer
);
13706 struct buffer
*old
= current_buffer
;
13707 const unsigned char *arrow_string
= SDATA (Voverlay_arrow_string
);
13708 int arrow_len
= SCHARS (Voverlay_arrow_string
);
13709 const unsigned char *arrow_end
= arrow_string
+ arrow_len
;
13710 const unsigned char *p
;
13713 int n_glyphs_before
;
13715 set_buffer_temp (buffer
);
13716 init_iterator (&it
, w
, -1, -1, &scratch_glyph_row
, DEFAULT_FACE_ID
);
13717 it
.glyph_row
->used
[TEXT_AREA
] = 0;
13718 SET_TEXT_POS (it
.position
, 0, 0);
13720 multibyte_p
= !NILP (buffer
->enable_multibyte_characters
);
13722 while (p
< arrow_end
)
13724 Lisp_Object face
, ilisp
;
13726 /* Get the next character. */
13728 it
.c
= string_char_and_length (p
, arrow_len
, &it
.len
);
13730 it
.c
= *p
, it
.len
= 1;
13733 /* Get its face. */
13734 ilisp
= make_number (p
- arrow_string
);
13735 face
= Fget_text_property (ilisp
, Qface
, Voverlay_arrow_string
);
13736 it
.face_id
= compute_char_face (f
, it
.c
, face
);
13738 /* Compute its width, get its glyphs. */
13739 n_glyphs_before
= it
.glyph_row
->used
[TEXT_AREA
];
13740 SET_TEXT_POS (it
.position
, -1, -1);
13741 PRODUCE_GLYPHS (&it
);
13743 /* If this character doesn't fit any more in the line, we have
13744 to remove some glyphs. */
13745 if (it
.current_x
> it
.last_visible_x
)
13747 it
.glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
;
13752 set_buffer_temp (old
);
13753 return it
.glyph_row
;
13757 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
13758 glyphs are only inserted for terminal frames since we can't really
13759 win with truncation glyphs when partially visible glyphs are
13760 involved. Which glyphs to insert is determined by
13761 produce_special_glyphs. */
13764 insert_left_trunc_glyphs (it
)
13767 struct it truncate_it
;
13768 struct glyph
*from
, *end
, *to
, *toend
;
13770 xassert (!FRAME_WINDOW_P (it
->f
));
13772 /* Get the truncation glyphs. */
13774 truncate_it
.current_x
= 0;
13775 truncate_it
.face_id
= DEFAULT_FACE_ID
;
13776 truncate_it
.glyph_row
= &scratch_glyph_row
;
13777 truncate_it
.glyph_row
->used
[TEXT_AREA
] = 0;
13778 CHARPOS (truncate_it
.position
) = BYTEPOS (truncate_it
.position
) = -1;
13779 truncate_it
.object
= make_number (0);
13780 produce_special_glyphs (&truncate_it
, IT_TRUNCATION
);
13782 /* Overwrite glyphs from IT with truncation glyphs. */
13783 from
= truncate_it
.glyph_row
->glyphs
[TEXT_AREA
];
13784 end
= from
+ truncate_it
.glyph_row
->used
[TEXT_AREA
];
13785 to
= it
->glyph_row
->glyphs
[TEXT_AREA
];
13786 toend
= to
+ it
->glyph_row
->used
[TEXT_AREA
];
13791 /* There may be padding glyphs left over. Overwrite them too. */
13792 while (to
< toend
&& CHAR_GLYPH_PADDING_P (*to
))
13794 from
= truncate_it
.glyph_row
->glyphs
[TEXT_AREA
];
13800 it
->glyph_row
->used
[TEXT_AREA
] = to
- it
->glyph_row
->glyphs
[TEXT_AREA
];
13804 /* Compute the pixel height and width of IT->glyph_row.
13806 Most of the time, ascent and height of a display line will be equal
13807 to the max_ascent and max_height values of the display iterator
13808 structure. This is not the case if
13810 1. We hit ZV without displaying anything. In this case, max_ascent
13811 and max_height will be zero.
13813 2. We have some glyphs that don't contribute to the line height.
13814 (The glyph row flag contributes_to_line_height_p is for future
13815 pixmap extensions).
13817 The first case is easily covered by using default values because in
13818 these cases, the line height does not really matter, except that it
13819 must not be zero. */
13822 compute_line_metrics (it
)
13825 struct glyph_row
*row
= it
->glyph_row
;
13828 if (FRAME_WINDOW_P (it
->f
))
13830 int i
, min_y
, max_y
;
13832 /* The line may consist of one space only, that was added to
13833 place the cursor on it. If so, the row's height hasn't been
13835 if (row
->height
== 0)
13837 if (it
->max_ascent
+ it
->max_descent
== 0)
13838 it
->max_descent
= it
->max_phys_descent
= FRAME_LINE_HEIGHT (it
->f
);
13839 row
->ascent
= it
->max_ascent
;
13840 row
->height
= it
->max_ascent
+ it
->max_descent
;
13841 row
->phys_ascent
= it
->max_phys_ascent
;
13842 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
13845 /* Compute the width of this line. */
13846 row
->pixel_width
= row
->x
;
13847 for (i
= 0; i
< row
->used
[TEXT_AREA
]; ++i
)
13848 row
->pixel_width
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
13850 xassert (row
->pixel_width
>= 0);
13851 xassert (row
->ascent
>= 0 && row
->height
> 0);
13853 row
->overlapping_p
= (MATRIX_ROW_OVERLAPS_SUCC_P (row
)
13854 || MATRIX_ROW_OVERLAPS_PRED_P (row
));
13856 /* If first line's physical ascent is larger than its logical
13857 ascent, use the physical ascent, and make the row taller.
13858 This makes accented characters fully visible. */
13859 if (row
== MATRIX_FIRST_TEXT_ROW (it
->w
->desired_matrix
)
13860 && row
->phys_ascent
> row
->ascent
)
13862 row
->height
+= row
->phys_ascent
- row
->ascent
;
13863 row
->ascent
= row
->phys_ascent
;
13866 /* Compute how much of the line is visible. */
13867 row
->visible_height
= row
->height
;
13869 min_y
= WINDOW_HEADER_LINE_HEIGHT (it
->w
);
13870 max_y
= WINDOW_BOX_HEIGHT_NO_MODE_LINE (it
->w
);
13872 if (row
->y
< min_y
)
13873 row
->visible_height
-= min_y
- row
->y
;
13874 if (row
->y
+ row
->height
> max_y
)
13875 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
13879 row
->pixel_width
= row
->used
[TEXT_AREA
];
13880 if (row
->continued_p
)
13881 row
->pixel_width
-= it
->continuation_pixel_width
;
13882 else if (row
->truncated_on_right_p
)
13883 row
->pixel_width
-= it
->truncation_pixel_width
;
13884 row
->ascent
= row
->phys_ascent
= 0;
13885 row
->height
= row
->phys_height
= row
->visible_height
= 1;
13888 /* Compute a hash code for this row. */
13890 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
13891 for (i
= 0; i
< row
->used
[area
]; ++i
)
13892 row
->hash
= ((((row
->hash
<< 4) + (row
->hash
>> 24)) & 0x0fffffff)
13893 + row
->glyphs
[area
][i
].u
.val
13894 + row
->glyphs
[area
][i
].face_id
13895 + row
->glyphs
[area
][i
].padding_p
13896 + (row
->glyphs
[area
][i
].type
<< 2));
13898 it
->max_ascent
= it
->max_descent
= 0;
13899 it
->max_phys_ascent
= it
->max_phys_descent
= 0;
13903 /* Append one space to the glyph row of iterator IT if doing a
13904 window-based redisplay. DEFAULT_FACE_P non-zero means let the
13905 space have the default face, otherwise let it have the same face as
13906 IT->face_id. Value is non-zero if a space was added.
13908 This function is called to make sure that there is always one glyph
13909 at the end of a glyph row that the cursor can be set on under
13910 window-systems. (If there weren't such a glyph we would not know
13911 how wide and tall a box cursor should be displayed).
13913 At the same time this space let's a nicely handle clearing to the
13914 end of the line if the row ends in italic text. */
13917 append_space (it
, default_face_p
)
13919 int default_face_p
;
13921 if (FRAME_WINDOW_P (it
->f
))
13923 int n
= it
->glyph_row
->used
[TEXT_AREA
];
13925 if (it
->glyph_row
->glyphs
[TEXT_AREA
] + n
13926 < it
->glyph_row
->glyphs
[1 + TEXT_AREA
])
13928 /* Save some values that must not be changed.
13929 Must save IT->c and IT->len because otherwise
13930 ITERATOR_AT_END_P wouldn't work anymore after
13931 append_space has been called. */
13932 enum display_element_type saved_what
= it
->what
;
13933 int saved_c
= it
->c
, saved_len
= it
->len
;
13934 int saved_x
= it
->current_x
;
13935 int saved_face_id
= it
->face_id
;
13936 struct text_pos saved_pos
;
13937 Lisp_Object saved_object
;
13940 saved_object
= it
->object
;
13941 saved_pos
= it
->position
;
13943 it
->what
= IT_CHARACTER
;
13944 bzero (&it
->position
, sizeof it
->position
);
13945 it
->object
= make_number (0);
13949 if (default_face_p
)
13950 it
->face_id
= DEFAULT_FACE_ID
;
13951 else if (it
->face_before_selective_p
)
13952 it
->face_id
= it
->saved_face_id
;
13953 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
13954 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, 0);
13956 PRODUCE_GLYPHS (it
);
13958 it
->current_x
= saved_x
;
13959 it
->object
= saved_object
;
13960 it
->position
= saved_pos
;
13961 it
->what
= saved_what
;
13962 it
->face_id
= saved_face_id
;
13963 it
->len
= saved_len
;
13973 /* Extend the face of the last glyph in the text area of IT->glyph_row
13974 to the end of the display line. Called from display_line.
13975 If the glyph row is empty, add a space glyph to it so that we
13976 know the face to draw. Set the glyph row flag fill_line_p. */
13979 extend_face_to_end_of_line (it
)
13983 struct frame
*f
= it
->f
;
13985 /* If line is already filled, do nothing. */
13986 if (it
->current_x
>= it
->last_visible_x
)
13989 /* Face extension extends the background and box of IT->face_id
13990 to the end of the line. If the background equals the background
13991 of the frame, we don't have to do anything. */
13992 if (it
->face_before_selective_p
)
13993 face
= FACE_FROM_ID (it
->f
, it
->saved_face_id
);
13995 face
= FACE_FROM_ID (f
, it
->face_id
);
13997 if (FRAME_WINDOW_P (f
)
13998 && face
->box
== FACE_NO_BOX
13999 && face
->background
== FRAME_BACKGROUND_PIXEL (f
)
14003 /* Set the glyph row flag indicating that the face of the last glyph
14004 in the text area has to be drawn to the end of the text area. */
14005 it
->glyph_row
->fill_line_p
= 1;
14007 /* If current character of IT is not ASCII, make sure we have the
14008 ASCII face. This will be automatically undone the next time
14009 get_next_display_element returns a multibyte character. Note
14010 that the character will always be single byte in unibyte text. */
14011 if (!SINGLE_BYTE_CHAR_P (it
->c
))
14013 it
->face_id
= FACE_FOR_CHAR (f
, face
, 0);
14016 if (FRAME_WINDOW_P (f
))
14018 /* If the row is empty, add a space with the current face of IT,
14019 so that we know which face to draw. */
14020 if (it
->glyph_row
->used
[TEXT_AREA
] == 0)
14022 it
->glyph_row
->glyphs
[TEXT_AREA
][0] = space_glyph
;
14023 it
->glyph_row
->glyphs
[TEXT_AREA
][0].face_id
= it
->face_id
;
14024 it
->glyph_row
->used
[TEXT_AREA
] = 1;
14029 /* Save some values that must not be changed. */
14030 int saved_x
= it
->current_x
;
14031 struct text_pos saved_pos
;
14032 Lisp_Object saved_object
;
14033 enum display_element_type saved_what
= it
->what
;
14034 int saved_face_id
= it
->face_id
;
14036 saved_object
= it
->object
;
14037 saved_pos
= it
->position
;
14039 it
->what
= IT_CHARACTER
;
14040 bzero (&it
->position
, sizeof it
->position
);
14041 it
->object
= make_number (0);
14044 it
->face_id
= face
->id
;
14046 PRODUCE_GLYPHS (it
);
14048 while (it
->current_x
<= it
->last_visible_x
)
14049 PRODUCE_GLYPHS (it
);
14051 /* Don't count these blanks really. It would let us insert a left
14052 truncation glyph below and make us set the cursor on them, maybe. */
14053 it
->current_x
= saved_x
;
14054 it
->object
= saved_object
;
14055 it
->position
= saved_pos
;
14056 it
->what
= saved_what
;
14057 it
->face_id
= saved_face_id
;
14062 /* Value is non-zero if text starting at CHARPOS in current_buffer is
14063 trailing whitespace. */
14066 trailing_whitespace_p (charpos
)
14069 int bytepos
= CHAR_TO_BYTE (charpos
);
14072 while (bytepos
< ZV_BYTE
14073 && (c
= FETCH_CHAR (bytepos
),
14074 c
== ' ' || c
== '\t'))
14077 if (bytepos
>= ZV_BYTE
|| c
== '\n' || c
== '\r')
14079 if (bytepos
!= PT_BYTE
)
14086 /* Highlight trailing whitespace, if any, in ROW. */
14089 highlight_trailing_whitespace (f
, row
)
14091 struct glyph_row
*row
;
14093 int used
= row
->used
[TEXT_AREA
];
14097 struct glyph
*start
= row
->glyphs
[TEXT_AREA
];
14098 struct glyph
*glyph
= start
+ used
- 1;
14100 /* Skip over glyphs inserted to display the cursor at the
14101 end of a line, for extending the face of the last glyph
14102 to the end of the line on terminals, and for truncation
14103 and continuation glyphs. */
14104 while (glyph
>= start
14105 && glyph
->type
== CHAR_GLYPH
14106 && INTEGERP (glyph
->object
))
14109 /* If last glyph is a space or stretch, and it's trailing
14110 whitespace, set the face of all trailing whitespace glyphs in
14111 IT->glyph_row to `trailing-whitespace'. */
14113 && BUFFERP (glyph
->object
)
14114 && (glyph
->type
== STRETCH_GLYPH
14115 || (glyph
->type
== CHAR_GLYPH
14116 && glyph
->u
.ch
== ' '))
14117 && trailing_whitespace_p (glyph
->charpos
))
14119 int face_id
= lookup_named_face (f
, Qtrailing_whitespace
, 0);
14121 while (glyph
>= start
14122 && BUFFERP (glyph
->object
)
14123 && (glyph
->type
== STRETCH_GLYPH
14124 || (glyph
->type
== CHAR_GLYPH
14125 && glyph
->u
.ch
== ' ')))
14126 (glyph
--)->face_id
= face_id
;
14132 /* Value is non-zero if glyph row ROW in window W should be
14133 used to hold the cursor. */
14136 cursor_row_p (w
, row
)
14138 struct glyph_row
*row
;
14140 int cursor_row_p
= 1;
14142 if (PT
== MATRIX_ROW_END_CHARPOS (row
))
14144 /* If the row ends with a newline from a string, we don't want
14145 the cursor there (if the row is continued it doesn't end in a
14147 if (CHARPOS (row
->end
.string_pos
) >= 0
14148 || MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
))
14149 cursor_row_p
= row
->continued_p
;
14151 /* If the row ends at ZV, display the cursor at the end of that
14152 row instead of at the start of the row below. */
14153 else if (row
->ends_at_zv_p
)
14159 return cursor_row_p
;
14163 /* Construct the glyph row IT->glyph_row in the desired matrix of
14164 IT->w from text at the current position of IT. See dispextern.h
14165 for an overview of struct it. Value is non-zero if
14166 IT->glyph_row displays text, as opposed to a line displaying ZV
14173 struct glyph_row
*row
= it
->glyph_row
;
14175 /* We always start displaying at hpos zero even if hscrolled. */
14176 xassert (it
->hpos
== 0 && it
->current_x
== 0);
14178 /* We must not display in a row that's not a text row. */
14179 xassert (MATRIX_ROW_VPOS (row
, it
->w
->desired_matrix
)
14180 < it
->w
->desired_matrix
->nrows
);
14182 /* Is IT->w showing the region? */
14183 it
->w
->region_showing
= it
->region_beg_charpos
> 0 ? Qt
: Qnil
;
14185 /* Clear the result glyph row and enable it. */
14186 prepare_desired_row (row
);
14188 row
->y
= it
->current_y
;
14189 row
->start
= it
->start
;
14190 row
->continuation_lines_width
= it
->continuation_lines_width
;
14191 row
->displays_text_p
= 1;
14192 row
->starts_in_middle_of_char_p
= it
->starts_in_middle_of_char_p
;
14193 it
->starts_in_middle_of_char_p
= 0;
14195 /* Arrange the overlays nicely for our purposes. Usually, we call
14196 display_line on only one line at a time, in which case this
14197 can't really hurt too much, or we call it on lines which appear
14198 one after another in the buffer, in which case all calls to
14199 recenter_overlay_lists but the first will be pretty cheap. */
14200 recenter_overlay_lists (current_buffer
, IT_CHARPOS (*it
));
14202 /* Move over display elements that are not visible because we are
14203 hscrolled. This may stop at an x-position < IT->first_visible_x
14204 if the first glyph is partially visible or if we hit a line end. */
14205 if (it
->current_x
< it
->first_visible_x
)
14206 move_it_in_display_line_to (it
, ZV
, it
->first_visible_x
,
14207 MOVE_TO_POS
| MOVE_TO_X
);
14209 /* Get the initial row height. This is either the height of the
14210 text hscrolled, if there is any, or zero. */
14211 row
->ascent
= it
->max_ascent
;
14212 row
->height
= it
->max_ascent
+ it
->max_descent
;
14213 row
->phys_ascent
= it
->max_phys_ascent
;
14214 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
14216 /* Loop generating characters. The loop is left with IT on the next
14217 character to display. */
14220 int n_glyphs_before
, hpos_before
, x_before
;
14222 int ascent
= 0, descent
= 0, phys_ascent
= 0, phys_descent
= 0;
14224 /* Retrieve the next thing to display. Value is zero if end of
14226 if (!get_next_display_element (it
))
14228 /* Maybe add a space at the end of this line that is used to
14229 display the cursor there under X. Set the charpos of the
14230 first glyph of blank lines not corresponding to any text
14232 #ifdef HAVE_WINDOW_SYSTEM
14233 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
14234 row
->exact_window_width_line_p
= 1;
14236 #endif /* HAVE_WINDOW_SYSTEM */
14237 if ((append_space (it
, 1) && row
->used
[TEXT_AREA
] == 1)
14238 || row
->used
[TEXT_AREA
] == 0)
14240 row
->glyphs
[TEXT_AREA
]->charpos
= -1;
14241 row
->displays_text_p
= 0;
14243 if (!NILP (XBUFFER (it
->w
->buffer
)->indicate_empty_lines
)
14244 && (!MINI_WINDOW_P (it
->w
)
14245 || (minibuf_level
&& EQ (it
->window
, minibuf_window
))))
14246 row
->indicate_empty_line_p
= 1;
14249 it
->continuation_lines_width
= 0;
14250 row
->ends_at_zv_p
= 1;
14254 /* Now, get the metrics of what we want to display. This also
14255 generates glyphs in `row' (which is IT->glyph_row). */
14256 n_glyphs_before
= row
->used
[TEXT_AREA
];
14259 /* Remember the line height so far in case the next element doesn't
14260 fit on the line. */
14261 if (!it
->truncate_lines_p
)
14263 ascent
= it
->max_ascent
;
14264 descent
= it
->max_descent
;
14265 phys_ascent
= it
->max_phys_ascent
;
14266 phys_descent
= it
->max_phys_descent
;
14269 PRODUCE_GLYPHS (it
);
14271 /* If this display element was in marginal areas, continue with
14273 if (it
->area
!= TEXT_AREA
)
14275 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
14276 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
14277 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
14278 row
->phys_height
= max (row
->phys_height
,
14279 it
->max_phys_ascent
+ it
->max_phys_descent
);
14280 set_iterator_to_next (it
, 1);
14284 /* Does the display element fit on the line? If we truncate
14285 lines, we should draw past the right edge of the window. If
14286 we don't truncate, we want to stop so that we can display the
14287 continuation glyph before the right margin. If lines are
14288 continued, there are two possible strategies for characters
14289 resulting in more than 1 glyph (e.g. tabs): Display as many
14290 glyphs as possible in this line and leave the rest for the
14291 continuation line, or display the whole element in the next
14292 line. Original redisplay did the former, so we do it also. */
14293 nglyphs
= row
->used
[TEXT_AREA
] - n_glyphs_before
;
14294 hpos_before
= it
->hpos
;
14297 if (/* Not a newline. */
14299 /* Glyphs produced fit entirely in the line. */
14300 && it
->current_x
< it
->last_visible_x
)
14302 it
->hpos
+= nglyphs
;
14303 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
14304 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
14305 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
14306 row
->phys_height
= max (row
->phys_height
,
14307 it
->max_phys_ascent
+ it
->max_phys_descent
);
14308 if (it
->current_x
- it
->pixel_width
< it
->first_visible_x
)
14309 row
->x
= x
- it
->first_visible_x
;
14314 struct glyph
*glyph
;
14316 for (i
= 0; i
< nglyphs
; ++i
, x
= new_x
)
14318 glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
14319 new_x
= x
+ glyph
->pixel_width
;
14321 if (/* Lines are continued. */
14322 !it
->truncate_lines_p
14323 && (/* Glyph doesn't fit on the line. */
14324 new_x
> it
->last_visible_x
14325 /* Or it fits exactly on a window system frame. */
14326 || (new_x
== it
->last_visible_x
14327 && FRAME_WINDOW_P (it
->f
))))
14329 /* End of a continued line. */
14332 || (new_x
== it
->last_visible_x
14333 && FRAME_WINDOW_P (it
->f
)))
14335 /* Current glyph is the only one on the line or
14336 fits exactly on the line. We must continue
14337 the line because we can't draw the cursor
14338 after the glyph. */
14339 row
->continued_p
= 1;
14340 it
->current_x
= new_x
;
14341 it
->continuation_lines_width
+= new_x
;
14343 if (i
== nglyphs
- 1)
14345 set_iterator_to_next (it
, 1);
14346 #ifdef HAVE_WINDOW_SYSTEM
14347 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
14349 if (!get_next_display_element (it
))
14351 row
->exact_window_width_line_p
= 1;
14352 it
->continuation_lines_width
= 0;
14353 row
->continued_p
= 0;
14354 row
->ends_at_zv_p
= 1;
14356 else if (ITERATOR_AT_END_OF_LINE_P (it
))
14358 row
->continued_p
= 0;
14359 row
->exact_window_width_line_p
= 1;
14362 #endif /* HAVE_WINDOW_SYSTEM */
14365 else if (CHAR_GLYPH_PADDING_P (*glyph
)
14366 && !FRAME_WINDOW_P (it
->f
))
14368 /* A padding glyph that doesn't fit on this line.
14369 This means the whole character doesn't fit
14371 row
->used
[TEXT_AREA
] = n_glyphs_before
;
14373 /* Fill the rest of the row with continuation
14374 glyphs like in 20.x. */
14375 while (row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
]
14376 < row
->glyphs
[1 + TEXT_AREA
])
14377 produce_special_glyphs (it
, IT_CONTINUATION
);
14379 row
->continued_p
= 1;
14380 it
->current_x
= x_before
;
14381 it
->continuation_lines_width
+= x_before
;
14383 /* Restore the height to what it was before the
14384 element not fitting on the line. */
14385 it
->max_ascent
= ascent
;
14386 it
->max_descent
= descent
;
14387 it
->max_phys_ascent
= phys_ascent
;
14388 it
->max_phys_descent
= phys_descent
;
14390 else if (it
->c
== '\t' && FRAME_WINDOW_P (it
->f
))
14392 /* A TAB that extends past the right edge of the
14393 window. This produces a single glyph on
14394 window system frames. We leave the glyph in
14395 this row and let it fill the row, but don't
14396 consume the TAB. */
14397 it
->continuation_lines_width
+= it
->last_visible_x
;
14398 row
->ends_in_middle_of_char_p
= 1;
14399 row
->continued_p
= 1;
14400 glyph
->pixel_width
= it
->last_visible_x
- x
;
14401 it
->starts_in_middle_of_char_p
= 1;
14405 /* Something other than a TAB that draws past
14406 the right edge of the window. Restore
14407 positions to values before the element. */
14408 row
->used
[TEXT_AREA
] = n_glyphs_before
+ i
;
14410 /* Display continuation glyphs. */
14411 if (!FRAME_WINDOW_P (it
->f
))
14412 produce_special_glyphs (it
, IT_CONTINUATION
);
14413 row
->continued_p
= 1;
14415 it
->continuation_lines_width
+= x
;
14417 if (nglyphs
> 1 && i
> 0)
14419 row
->ends_in_middle_of_char_p
= 1;
14420 it
->starts_in_middle_of_char_p
= 1;
14423 /* Restore the height to what it was before the
14424 element not fitting on the line. */
14425 it
->max_ascent
= ascent
;
14426 it
->max_descent
= descent
;
14427 it
->max_phys_ascent
= phys_ascent
;
14428 it
->max_phys_descent
= phys_descent
;
14433 else if (new_x
> it
->first_visible_x
)
14435 /* Increment number of glyphs actually displayed. */
14438 if (x
< it
->first_visible_x
)
14439 /* Glyph is partially visible, i.e. row starts at
14440 negative X position. */
14441 row
->x
= x
- it
->first_visible_x
;
14445 /* Glyph is completely off the left margin of the
14446 window. This should not happen because of the
14447 move_it_in_display_line at the start of this
14448 function, unless the text display area of the
14449 window is empty. */
14450 xassert (it
->first_visible_x
<= it
->last_visible_x
);
14454 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
14455 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
14456 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
14457 row
->phys_height
= max (row
->phys_height
,
14458 it
->max_phys_ascent
+ it
->max_phys_descent
);
14460 /* End of this display line if row is continued. */
14461 if (row
->continued_p
|| row
->ends_at_zv_p
)
14466 /* Is this a line end? If yes, we're also done, after making
14467 sure that a non-default face is extended up to the right
14468 margin of the window. */
14469 if (ITERATOR_AT_END_OF_LINE_P (it
))
14471 int used_before
= row
->used
[TEXT_AREA
];
14473 row
->ends_in_newline_from_string_p
= STRINGP (it
->object
);
14475 #ifdef HAVE_WINDOW_SYSTEM
14476 /* Add a space at the end of the line that is used to
14477 display the cursor there. */
14478 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
14479 append_space (it
, 0);
14480 #endif /* HAVE_WINDOW_SYSTEM */
14482 /* Extend the face to the end of the line. */
14483 extend_face_to_end_of_line (it
);
14485 /* Make sure we have the position. */
14486 if (used_before
== 0)
14487 row
->glyphs
[TEXT_AREA
]->charpos
= CHARPOS (it
->position
);
14489 /* Consume the line end. This skips over invisible lines. */
14490 set_iterator_to_next (it
, 1);
14491 it
->continuation_lines_width
= 0;
14495 /* Proceed with next display element. Note that this skips
14496 over lines invisible because of selective display. */
14497 set_iterator_to_next (it
, 1);
14499 /* If we truncate lines, we are done when the last displayed
14500 glyphs reach past the right margin of the window. */
14501 if (it
->truncate_lines_p
14502 && (FRAME_WINDOW_P (it
->f
)
14503 ? (it
->current_x
>= it
->last_visible_x
)
14504 : (it
->current_x
> it
->last_visible_x
)))
14506 /* Maybe add truncation glyphs. */
14507 if (!FRAME_WINDOW_P (it
->f
))
14511 for (i
= row
->used
[TEXT_AREA
] - 1; i
> 0; --i
)
14512 if (!CHAR_GLYPH_PADDING_P (row
->glyphs
[TEXT_AREA
][i
]))
14515 for (n
= row
->used
[TEXT_AREA
]; i
< n
; ++i
)
14517 row
->used
[TEXT_AREA
] = i
;
14518 produce_special_glyphs (it
, IT_TRUNCATION
);
14521 #ifdef HAVE_WINDOW_SYSTEM
14524 /* Don't truncate if we can overflow newline into fringe. */
14525 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
14527 if (!get_next_display_element (it
))
14529 #ifdef HAVE_WINDOW_SYSTEM
14530 it
->continuation_lines_width
= 0;
14531 row
->ends_at_zv_p
= 1;
14532 row
->exact_window_width_line_p
= 1;
14534 #endif /* HAVE_WINDOW_SYSTEM */
14536 if (ITERATOR_AT_END_OF_LINE_P (it
))
14538 row
->exact_window_width_line_p
= 1;
14539 goto at_end_of_line
;
14543 #endif /* HAVE_WINDOW_SYSTEM */
14545 row
->truncated_on_right_p
= 1;
14546 it
->continuation_lines_width
= 0;
14547 reseat_at_next_visible_line_start (it
, 0);
14548 row
->ends_at_zv_p
= FETCH_BYTE (IT_BYTEPOS (*it
) - 1) != '\n';
14549 it
->hpos
= hpos_before
;
14550 it
->current_x
= x_before
;
14555 /* If line is not empty and hscrolled, maybe insert truncation glyphs
14556 at the left window margin. */
14557 if (it
->first_visible_x
14558 && IT_CHARPOS (*it
) != MATRIX_ROW_START_CHARPOS (row
))
14560 if (!FRAME_WINDOW_P (it
->f
))
14561 insert_left_trunc_glyphs (it
);
14562 row
->truncated_on_left_p
= 1;
14565 /* If the start of this line is the overlay arrow-position, then
14566 mark this glyph row as the one containing the overlay arrow.
14567 This is clearly a mess with variable size fonts. It would be
14568 better to let it be displayed like cursors under X. */
14569 if (MARKERP (Voverlay_arrow_position
)
14570 && current_buffer
== XMARKER (Voverlay_arrow_position
)->buffer
14571 && (MATRIX_ROW_START_CHARPOS (row
)
14572 == marker_position (Voverlay_arrow_position
))
14573 && STRINGP (Voverlay_arrow_string
)
14574 && ! overlay_arrow_seen
)
14576 /* Overlay arrow in window redisplay is a fringe bitmap. */
14577 if (!FRAME_WINDOW_P (it
->f
))
14579 struct glyph_row
*arrow_row
= get_overlay_arrow_glyph_row (it
->w
);
14580 struct glyph
*glyph
= arrow_row
->glyphs
[TEXT_AREA
];
14581 struct glyph
*arrow_end
= glyph
+ arrow_row
->used
[TEXT_AREA
];
14582 struct glyph
*p
= row
->glyphs
[TEXT_AREA
];
14583 struct glyph
*p2
, *end
;
14585 /* Copy the arrow glyphs. */
14586 while (glyph
< arrow_end
)
14589 /* Throw away padding glyphs. */
14591 end
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
];
14592 while (p2
< end
&& CHAR_GLYPH_PADDING_P (*p2
))
14598 row
->used
[TEXT_AREA
] = p2
- row
->glyphs
[TEXT_AREA
];
14602 overlay_arrow_seen
= 1;
14603 row
->overlay_arrow_p
= 1;
14606 /* Compute pixel dimensions of this line. */
14607 compute_line_metrics (it
);
14609 /* Remember the position at which this line ends. */
14610 row
->end
= it
->current
;
14612 /* Save fringe bitmaps in this row. */
14613 row
->left_user_fringe_bitmap
= it
->left_user_fringe_bitmap
;
14614 row
->left_user_fringe_face_id
= it
->left_user_fringe_face_id
;
14615 row
->right_user_fringe_bitmap
= it
->right_user_fringe_bitmap
;
14616 row
->right_user_fringe_face_id
= it
->right_user_fringe_face_id
;
14618 it
->left_user_fringe_bitmap
= 0;
14619 it
->left_user_fringe_face_id
= 0;
14620 it
->right_user_fringe_bitmap
= 0;
14621 it
->right_user_fringe_face_id
= 0;
14623 /* Maybe set the cursor. */
14624 if (it
->w
->cursor
.vpos
< 0
14625 && PT
>= MATRIX_ROW_START_CHARPOS (row
)
14626 && PT
<= MATRIX_ROW_END_CHARPOS (row
)
14627 && cursor_row_p (it
->w
, row
))
14628 set_cursor_from_row (it
->w
, row
, it
->w
->desired_matrix
, 0, 0, 0, 0);
14630 /* Highlight trailing whitespace. */
14631 if (!NILP (Vshow_trailing_whitespace
))
14632 highlight_trailing_whitespace (it
->f
, it
->glyph_row
);
14634 /* Prepare for the next line. This line starts horizontally at (X
14635 HPOS) = (0 0). Vertical positions are incremented. As a
14636 convenience for the caller, IT->glyph_row is set to the next
14638 it
->current_x
= it
->hpos
= 0;
14639 it
->current_y
+= row
->height
;
14642 it
->start
= it
->current
;
14643 return row
->displays_text_p
;
14648 /***********************************************************************
14650 ***********************************************************************/
14652 /* Redisplay the menu bar in the frame for window W.
14654 The menu bar of X frames that don't have X toolkit support is
14655 displayed in a special window W->frame->menu_bar_window.
14657 The menu bar of terminal frames is treated specially as far as
14658 glyph matrices are concerned. Menu bar lines are not part of
14659 windows, so the update is done directly on the frame matrix rows
14660 for the menu bar. */
14663 display_menu_bar (w
)
14666 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
14671 /* Don't do all this for graphical frames. */
14673 if (!NILP (Vwindow_system
))
14676 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
14681 if (FRAME_MAC_P (f
))
14685 #ifdef USE_X_TOOLKIT
14686 xassert (!FRAME_WINDOW_P (f
));
14687 init_iterator (&it
, w
, -1, -1, f
->desired_matrix
->rows
, MENU_FACE_ID
);
14688 it
.first_visible_x
= 0;
14689 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
14690 #else /* not USE_X_TOOLKIT */
14691 if (FRAME_WINDOW_P (f
))
14693 /* Menu bar lines are displayed in the desired matrix of the
14694 dummy window menu_bar_window. */
14695 struct window
*menu_w
;
14696 xassert (WINDOWP (f
->menu_bar_window
));
14697 menu_w
= XWINDOW (f
->menu_bar_window
);
14698 init_iterator (&it
, menu_w
, -1, -1, menu_w
->desired_matrix
->rows
,
14700 it
.first_visible_x
= 0;
14701 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
14705 /* This is a TTY frame, i.e. character hpos/vpos are used as
14707 init_iterator (&it
, w
, -1, -1, f
->desired_matrix
->rows
,
14709 it
.first_visible_x
= 0;
14710 it
.last_visible_x
= FRAME_COLS (f
);
14712 #endif /* not USE_X_TOOLKIT */
14714 if (! mode_line_inverse_video
)
14715 /* Force the menu-bar to be displayed in the default face. */
14716 it
.base_face_id
= it
.face_id
= DEFAULT_FACE_ID
;
14718 /* Clear all rows of the menu bar. */
14719 for (i
= 0; i
< FRAME_MENU_BAR_LINES (f
); ++i
)
14721 struct glyph_row
*row
= it
.glyph_row
+ i
;
14722 clear_glyph_row (row
);
14723 row
->enabled_p
= 1;
14724 row
->full_width_p
= 1;
14727 /* Display all items of the menu bar. */
14728 items
= FRAME_MENU_BAR_ITEMS (it
.f
);
14729 for (i
= 0; i
< XVECTOR (items
)->size
; i
+= 4)
14731 Lisp_Object string
;
14733 /* Stop at nil string. */
14734 string
= AREF (items
, i
+ 1);
14738 /* Remember where item was displayed. */
14739 AREF (items
, i
+ 3) = make_number (it
.hpos
);
14741 /* Display the item, pad with one space. */
14742 if (it
.current_x
< it
.last_visible_x
)
14743 display_string (NULL
, string
, Qnil
, 0, 0, &it
,
14744 SCHARS (string
) + 1, 0, 0, -1);
14747 /* Fill out the line with spaces. */
14748 if (it
.current_x
< it
.last_visible_x
)
14749 display_string ("", Qnil
, Qnil
, 0, 0, &it
, -1, 0, 0, -1);
14751 /* Compute the total height of the lines. */
14752 compute_line_metrics (&it
);
14757 /***********************************************************************
14759 ***********************************************************************/
14761 /* Redisplay mode lines in the window tree whose root is WINDOW. If
14762 FORCE is non-zero, redisplay mode lines unconditionally.
14763 Otherwise, redisplay only mode lines that are garbaged. Value is
14764 the number of windows whose mode lines were redisplayed. */
14767 redisplay_mode_lines (window
, force
)
14768 Lisp_Object window
;
14773 while (!NILP (window
))
14775 struct window
*w
= XWINDOW (window
);
14777 if (WINDOWP (w
->hchild
))
14778 nwindows
+= redisplay_mode_lines (w
->hchild
, force
);
14779 else if (WINDOWP (w
->vchild
))
14780 nwindows
+= redisplay_mode_lines (w
->vchild
, force
);
14782 || FRAME_GARBAGED_P (XFRAME (w
->frame
))
14783 || !MATRIX_MODE_LINE_ROW (w
->current_matrix
)->enabled_p
)
14785 struct text_pos lpoint
;
14786 struct buffer
*old
= current_buffer
;
14788 /* Set the window's buffer for the mode line display. */
14789 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
14790 set_buffer_internal_1 (XBUFFER (w
->buffer
));
14792 /* Point refers normally to the selected window. For any
14793 other window, set up appropriate value. */
14794 if (!EQ (window
, selected_window
))
14796 struct text_pos pt
;
14798 SET_TEXT_POS_FROM_MARKER (pt
, w
->pointm
);
14799 if (CHARPOS (pt
) < BEGV
)
14800 TEMP_SET_PT_BOTH (BEGV
, BEGV_BYTE
);
14801 else if (CHARPOS (pt
) > (ZV
- 1))
14802 TEMP_SET_PT_BOTH (ZV
, ZV_BYTE
);
14804 TEMP_SET_PT_BOTH (CHARPOS (pt
), BYTEPOS (pt
));
14807 /* Display mode lines. */
14808 clear_glyph_matrix (w
->desired_matrix
);
14809 if (display_mode_lines (w
))
14812 w
->must_be_updated_p
= 1;
14815 /* Restore old settings. */
14816 set_buffer_internal_1 (old
);
14817 TEMP_SET_PT_BOTH (CHARPOS (lpoint
), BYTEPOS (lpoint
));
14827 /* Display the mode and/or top line of window W. Value is the number
14828 of mode lines displayed. */
14831 display_mode_lines (w
)
14834 Lisp_Object old_selected_window
, old_selected_frame
;
14837 old_selected_frame
= selected_frame
;
14838 selected_frame
= w
->frame
;
14839 old_selected_window
= selected_window
;
14840 XSETWINDOW (selected_window
, w
);
14842 /* These will be set while the mode line specs are processed. */
14843 line_number_displayed
= 0;
14844 w
->column_number_displayed
= Qnil
;
14846 if (WINDOW_WANTS_MODELINE_P (w
))
14848 struct window
*sel_w
= XWINDOW (old_selected_window
);
14850 /* Select mode line face based on the real selected window. */
14851 display_mode_line (w
, CURRENT_MODE_LINE_FACE_ID_3 (sel_w
, sel_w
, w
),
14852 current_buffer
->mode_line_format
);
14856 if (WINDOW_WANTS_HEADER_LINE_P (w
))
14858 display_mode_line (w
, HEADER_LINE_FACE_ID
,
14859 current_buffer
->header_line_format
);
14863 selected_frame
= old_selected_frame
;
14864 selected_window
= old_selected_window
;
14869 /* Display mode or top line of window W. FACE_ID specifies which line
14870 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
14871 FORMAT is the mode line format to display. Value is the pixel
14872 height of the mode line displayed. */
14875 display_mode_line (w
, face_id
, format
)
14877 enum face_id face_id
;
14878 Lisp_Object format
;
14883 init_iterator (&it
, w
, -1, -1, NULL
, face_id
);
14884 prepare_desired_row (it
.glyph_row
);
14886 if (! mode_line_inverse_video
)
14887 /* Force the mode-line to be displayed in the default face. */
14888 it
.base_face_id
= it
.face_id
= DEFAULT_FACE_ID
;
14890 /* Temporarily make frame's keyboard the current kboard so that
14891 kboard-local variables in the mode_line_format will get the right
14893 push_frame_kboard (it
.f
);
14894 display_mode_element (&it
, 0, 0, 0, format
, Qnil
, 0);
14895 pop_frame_kboard ();
14897 /* Fill up with spaces. */
14898 display_string (" ", Qnil
, Qnil
, 0, 0, &it
, 10000, -1, -1, 0);
14900 compute_line_metrics (&it
);
14901 it
.glyph_row
->full_width_p
= 1;
14902 it
.glyph_row
->mode_line_p
= 1;
14903 it
.glyph_row
->continued_p
= 0;
14904 it
.glyph_row
->truncated_on_left_p
= 0;
14905 it
.glyph_row
->truncated_on_right_p
= 0;
14907 /* Make a 3D mode-line have a shadow at its right end. */
14908 face
= FACE_FROM_ID (it
.f
, face_id
);
14909 extend_face_to_end_of_line (&it
);
14910 if (face
->box
!= FACE_NO_BOX
)
14912 struct glyph
*last
= (it
.glyph_row
->glyphs
[TEXT_AREA
]
14913 + it
.glyph_row
->used
[TEXT_AREA
] - 1);
14914 last
->right_box_line_p
= 1;
14917 return it
.glyph_row
->height
;
14920 /* Alist that caches the results of :propertize.
14921 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
14922 Lisp_Object mode_line_proptrans_alist
;
14924 /* List of strings making up the mode-line. */
14925 Lisp_Object mode_line_string_list
;
14927 /* Base face property when building propertized mode line string. */
14928 static Lisp_Object mode_line_string_face
;
14929 static Lisp_Object mode_line_string_face_prop
;
14932 /* Contribute ELT to the mode line for window IT->w. How it
14933 translates into text depends on its data type.
14935 IT describes the display environment in which we display, as usual.
14937 DEPTH is the depth in recursion. It is used to prevent
14938 infinite recursion here.
14940 FIELD_WIDTH is the number of characters the display of ELT should
14941 occupy in the mode line, and PRECISION is the maximum number of
14942 characters to display from ELT's representation. See
14943 display_string for details.
14945 Returns the hpos of the end of the text generated by ELT.
14947 PROPS is a property list to add to any string we encounter.
14949 If RISKY is nonzero, remove (disregard) any properties in any string
14950 we encounter, and ignore :eval and :propertize.
14952 If the global variable `frame_title_ptr' is non-NULL, then the output
14953 is passed to `store_frame_title' instead of `display_string'. */
14956 display_mode_element (it
, depth
, field_width
, precision
, elt
, props
, risky
)
14959 int field_width
, precision
;
14960 Lisp_Object elt
, props
;
14963 int n
= 0, field
, prec
;
14968 elt
= build_string ("*too-deep*");
14972 switch (SWITCH_ENUM_CAST (XTYPE (elt
)))
14976 /* A string: output it and check for %-constructs within it. */
14978 const unsigned char *this, *lisp_string
;
14980 if (!NILP (props
) || risky
)
14982 Lisp_Object oprops
, aelt
;
14983 oprops
= Ftext_properties_at (make_number (0), elt
);
14985 if (NILP (Fequal (props
, oprops
)) || risky
)
14987 /* If the starting string has properties,
14988 merge the specified ones onto the existing ones. */
14989 if (! NILP (oprops
) && !risky
)
14993 oprops
= Fcopy_sequence (oprops
);
14995 while (CONSP (tem
))
14997 oprops
= Fplist_put (oprops
, XCAR (tem
),
14998 XCAR (XCDR (tem
)));
14999 tem
= XCDR (XCDR (tem
));
15004 aelt
= Fassoc (elt
, mode_line_proptrans_alist
);
15005 if (! NILP (aelt
) && !NILP (Fequal (props
, XCDR (aelt
))))
15007 mode_line_proptrans_alist
15008 = Fcons (aelt
, Fdelq (aelt
, mode_line_proptrans_alist
));
15015 elt
= Fcopy_sequence (elt
);
15016 Fset_text_properties (make_number (0), Flength (elt
),
15018 /* Add this item to mode_line_proptrans_alist. */
15019 mode_line_proptrans_alist
15020 = Fcons (Fcons (elt
, props
),
15021 mode_line_proptrans_alist
);
15022 /* Truncate mode_line_proptrans_alist
15023 to at most 50 elements. */
15024 tem
= Fnthcdr (make_number (50),
15025 mode_line_proptrans_alist
);
15027 XSETCDR (tem
, Qnil
);
15032 this = SDATA (elt
);
15033 lisp_string
= this;
15037 prec
= precision
- n
;
15038 if (frame_title_ptr
)
15039 n
+= store_frame_title (SDATA (elt
), -1, prec
);
15040 else if (!NILP (mode_line_string_list
))
15041 n
+= store_mode_line_string (NULL
, elt
, 1, 0, prec
, Qnil
);
15043 n
+= display_string (NULL
, elt
, Qnil
, 0, 0, it
,
15044 0, prec
, 0, STRING_MULTIBYTE (elt
));
15049 while ((precision
<= 0 || n
< precision
)
15051 && (frame_title_ptr
15052 || !NILP (mode_line_string_list
)
15053 || it
->current_x
< it
->last_visible_x
))
15055 const unsigned char *last
= this;
15057 /* Advance to end of string or next format specifier. */
15058 while ((c
= *this++) != '\0' && c
!= '%')
15061 if (this - 1 != last
)
15063 /* Output to end of string or up to '%'. Field width
15064 is length of string. Don't output more than
15065 PRECISION allows us. */
15068 prec
= chars_in_text (last
, this - last
);
15069 if (precision
> 0 && prec
> precision
- n
)
15070 prec
= precision
- n
;
15072 if (frame_title_ptr
)
15073 n
+= store_frame_title (last
, 0, prec
);
15074 else if (!NILP (mode_line_string_list
))
15076 int bytepos
= last
- lisp_string
;
15077 int charpos
= string_byte_to_char (elt
, bytepos
);
15078 n
+= store_mode_line_string (NULL
,
15079 Fsubstring (elt
, make_number (charpos
),
15080 make_number (charpos
+ prec
)),
15085 int bytepos
= last
- lisp_string
;
15086 int charpos
= string_byte_to_char (elt
, bytepos
);
15087 n
+= display_string (NULL
, elt
, Qnil
, 0, charpos
,
15089 STRING_MULTIBYTE (elt
));
15092 else /* c == '%' */
15094 const unsigned char *percent_position
= this;
15096 /* Get the specified minimum width. Zero means
15099 while ((c
= *this++) >= '0' && c
<= '9')
15100 field
= field
* 10 + c
- '0';
15102 /* Don't pad beyond the total padding allowed. */
15103 if (field_width
- n
> 0 && field
> field_width
- n
)
15104 field
= field_width
- n
;
15106 /* Note that either PRECISION <= 0 or N < PRECISION. */
15107 prec
= precision
- n
;
15110 n
+= display_mode_element (it
, depth
, field
, prec
,
15111 Vglobal_mode_string
, props
,
15116 int bytepos
, charpos
;
15117 unsigned char *spec
;
15119 bytepos
= percent_position
- lisp_string
;
15120 charpos
= (STRING_MULTIBYTE (elt
)
15121 ? string_byte_to_char (elt
, bytepos
)
15125 = decode_mode_spec (it
->w
, c
, field
, prec
, &multibyte
);
15127 if (frame_title_ptr
)
15128 n
+= store_frame_title (spec
, field
, prec
);
15129 else if (!NILP (mode_line_string_list
))
15131 int len
= strlen (spec
);
15132 Lisp_Object tem
= make_string (spec
, len
);
15133 props
= Ftext_properties_at (make_number (charpos
), elt
);
15134 /* Should only keep face property in props */
15135 n
+= store_mode_line_string (NULL
, tem
, 0, field
, prec
, props
);
15139 int nglyphs_before
, nwritten
;
15141 nglyphs_before
= it
->glyph_row
->used
[TEXT_AREA
];
15142 nwritten
= display_string (spec
, Qnil
, elt
,
15147 /* Assign to the glyphs written above the
15148 string where the `%x' came from, position
15152 struct glyph
*glyph
15153 = (it
->glyph_row
->glyphs
[TEXT_AREA
]
15157 for (i
= 0; i
< nwritten
; ++i
)
15159 glyph
[i
].object
= elt
;
15160 glyph
[i
].charpos
= charpos
;
15175 /* A symbol: process the value of the symbol recursively
15176 as if it appeared here directly. Avoid error if symbol void.
15177 Special case: if value of symbol is a string, output the string
15180 register Lisp_Object tem
;
15182 /* If the variable is not marked as risky to set
15183 then its contents are risky to use. */
15184 if (NILP (Fget (elt
, Qrisky_local_variable
)))
15187 tem
= Fboundp (elt
);
15190 tem
= Fsymbol_value (elt
);
15191 /* If value is a string, output that string literally:
15192 don't check for % within it. */
15196 if (!EQ (tem
, elt
))
15198 /* Give up right away for nil or t. */
15208 register Lisp_Object car
, tem
;
15210 /* A cons cell: five distinct cases.
15211 If first element is :eval or :propertize, do something special.
15212 If first element is a string or a cons, process all the elements
15213 and effectively concatenate them.
15214 If first element is a negative number, truncate displaying cdr to
15215 at most that many characters. If positive, pad (with spaces)
15216 to at least that many characters.
15217 If first element is a symbol, process the cadr or caddr recursively
15218 according to whether the symbol's value is non-nil or nil. */
15220 if (EQ (car
, QCeval
))
15222 /* An element of the form (:eval FORM) means evaluate FORM
15223 and use the result as mode line elements. */
15228 if (CONSP (XCDR (elt
)))
15231 spec
= safe_eval (XCAR (XCDR (elt
)));
15232 n
+= display_mode_element (it
, depth
, field_width
- n
,
15233 precision
- n
, spec
, props
,
15237 else if (EQ (car
, QCpropertize
))
15239 /* An element of the form (:propertize ELT PROPS...)
15240 means display ELT but applying properties PROPS. */
15245 if (CONSP (XCDR (elt
)))
15246 n
+= display_mode_element (it
, depth
, field_width
- n
,
15247 precision
- n
, XCAR (XCDR (elt
)),
15248 XCDR (XCDR (elt
)), risky
);
15250 else if (SYMBOLP (car
))
15252 tem
= Fboundp (car
);
15256 /* elt is now the cdr, and we know it is a cons cell.
15257 Use its car if CAR has a non-nil value. */
15260 tem
= Fsymbol_value (car
);
15267 /* Symbol's value is nil (or symbol is unbound)
15268 Get the cddr of the original list
15269 and if possible find the caddr and use that. */
15273 else if (!CONSP (elt
))
15278 else if (INTEGERP (car
))
15280 register int lim
= XINT (car
);
15284 /* Negative int means reduce maximum width. */
15285 if (precision
<= 0)
15288 precision
= min (precision
, -lim
);
15292 /* Padding specified. Don't let it be more than
15293 current maximum. */
15295 lim
= min (precision
, lim
);
15297 /* If that's more padding than already wanted, queue it.
15298 But don't reduce padding already specified even if
15299 that is beyond the current truncation point. */
15300 field_width
= max (lim
, field_width
);
15304 else if (STRINGP (car
) || CONSP (car
))
15306 register int limit
= 50;
15307 /* Limit is to protect against circular lists. */
15310 && (precision
<= 0 || n
< precision
))
15312 n
+= display_mode_element (it
, depth
, field_width
- n
,
15313 precision
- n
, XCAR (elt
),
15323 elt
= build_string ("*invalid*");
15327 /* Pad to FIELD_WIDTH. */
15328 if (field_width
> 0 && n
< field_width
)
15330 if (frame_title_ptr
)
15331 n
+= store_frame_title ("", field_width
- n
, 0);
15332 else if (!NILP (mode_line_string_list
))
15333 n
+= store_mode_line_string ("", Qnil
, 0, field_width
- n
, 0, Qnil
);
15335 n
+= display_string ("", Qnil
, Qnil
, 0, 0, it
, field_width
- n
,
15342 /* Store a mode-line string element in mode_line_string_list.
15344 If STRING is non-null, display that C string. Otherwise, the Lisp
15345 string LISP_STRING is displayed.
15347 FIELD_WIDTH is the minimum number of output glyphs to produce.
15348 If STRING has fewer characters than FIELD_WIDTH, pad to the right
15349 with spaces. FIELD_WIDTH <= 0 means don't pad.
15351 PRECISION is the maximum number of characters to output from
15352 STRING. PRECISION <= 0 means don't truncate the string.
15354 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
15355 properties to the string.
15357 PROPS are the properties to add to the string.
15358 The mode_line_string_face face property is always added to the string.
15361 static int store_mode_line_string (string
, lisp_string
, copy_string
, field_width
, precision
, props
)
15363 Lisp_Object lisp_string
;
15372 if (string
!= NULL
)
15374 len
= strlen (string
);
15375 if (precision
> 0 && len
> precision
)
15377 lisp_string
= make_string (string
, len
);
15379 props
= mode_line_string_face_prop
;
15380 else if (!NILP (mode_line_string_face
))
15382 Lisp_Object face
= Fplist_get (props
, Qface
);
15383 props
= Fcopy_sequence (props
);
15385 face
= mode_line_string_face
;
15387 face
= Fcons (face
, Fcons (mode_line_string_face
, Qnil
));
15388 props
= Fplist_put (props
, Qface
, face
);
15390 Fadd_text_properties (make_number (0), make_number (len
),
15391 props
, lisp_string
);
15395 len
= XFASTINT (Flength (lisp_string
));
15396 if (precision
> 0 && len
> precision
)
15399 lisp_string
= Fsubstring (lisp_string
, make_number (0), make_number (len
));
15402 if (!NILP (mode_line_string_face
))
15406 props
= Ftext_properties_at (make_number (0), lisp_string
);
15407 face
= Fplist_get (props
, Qface
);
15409 face
= mode_line_string_face
;
15411 face
= Fcons (face
, Fcons (mode_line_string_face
, Qnil
));
15412 props
= Fcons (Qface
, Fcons (face
, Qnil
));
15414 lisp_string
= Fcopy_sequence (lisp_string
);
15417 Fadd_text_properties (make_number (0), make_number (len
),
15418 props
, lisp_string
);
15423 mode_line_string_list
= Fcons (lisp_string
, mode_line_string_list
);
15427 if (field_width
> len
)
15429 field_width
-= len
;
15430 lisp_string
= Fmake_string (make_number (field_width
), make_number (' '));
15432 Fadd_text_properties (make_number (0), make_number (field_width
),
15433 props
, lisp_string
);
15434 mode_line_string_list
= Fcons (lisp_string
, mode_line_string_list
);
15442 DEFUN ("format-mode-line", Fformat_mode_line
, Sformat_mode_line
,
15444 doc
: /* Return the mode-line of selected window as a string.
15445 First optional arg FORMAT specifies a different format string (see
15446 `mode-line-format' for details) to use. If FORMAT is t, return
15447 the buffer's header-line. Second optional arg WINDOW specifies a
15448 different window to use as the context for the formatting.
15449 If third optional arg NO-PROPS is non-nil, string is not propertized. */)
15450 (format
, window
, no_props
)
15451 Lisp_Object format
, window
, no_props
;
15456 struct buffer
*old_buffer
= NULL
;
15457 enum face_id face_id
= DEFAULT_FACE_ID
;
15460 window
= selected_window
;
15461 CHECK_WINDOW (window
);
15462 w
= XWINDOW (window
);
15463 CHECK_BUFFER (w
->buffer
);
15465 if (XBUFFER (w
->buffer
) != current_buffer
)
15467 old_buffer
= current_buffer
;
15468 set_buffer_internal_1 (XBUFFER (w
->buffer
));
15471 if (NILP (format
) || EQ (format
, Qt
))
15473 face_id
= NILP (format
)
15474 ? CURRENT_MODE_LINE_FACE_ID (w
) :
15475 HEADER_LINE_FACE_ID
;
15476 format
= NILP (format
)
15477 ? current_buffer
->mode_line_format
15478 : current_buffer
->header_line_format
;
15481 init_iterator (&it
, w
, -1, -1, NULL
, face_id
);
15483 if (NILP (no_props
))
15485 mode_line_string_face
=
15486 (face_id
== MODE_LINE_FACE_ID
? Qmode_line
:
15487 face_id
== MODE_LINE_INACTIVE_FACE_ID
? Qmode_line_inactive
:
15488 face_id
== HEADER_LINE_FACE_ID
? Qheader_line
: Qnil
);
15490 mode_line_string_face_prop
=
15491 NILP (mode_line_string_face
) ? Qnil
:
15492 Fcons (Qface
, Fcons (mode_line_string_face
, Qnil
));
15494 /* We need a dummy last element in mode_line_string_list to
15495 indicate we are building the propertized mode-line string.
15496 Using mode_line_string_face_prop here GC protects it. */
15497 mode_line_string_list
=
15498 Fcons (mode_line_string_face_prop
, Qnil
);
15499 frame_title_ptr
= NULL
;
15503 mode_line_string_face_prop
= Qnil
;
15504 mode_line_string_list
= Qnil
;
15505 frame_title_ptr
= frame_title_buf
;
15508 push_frame_kboard (it
.f
);
15509 display_mode_element (&it
, 0, 0, 0, format
, Qnil
, 0);
15510 pop_frame_kboard ();
15513 set_buffer_internal_1 (old_buffer
);
15515 if (NILP (no_props
))
15518 mode_line_string_list
= Fnreverse (mode_line_string_list
);
15519 str
= Fmapconcat (intern ("identity"), XCDR (mode_line_string_list
),
15520 make_string ("", 0));
15521 mode_line_string_face_prop
= Qnil
;
15522 mode_line_string_list
= Qnil
;
15526 len
= frame_title_ptr
- frame_title_buf
;
15527 if (len
> 0 && frame_title_ptr
[-1] == '-')
15529 /* Mode lines typically ends with numerous dashes; reduce to two dashes. */
15530 while (frame_title_ptr
> frame_title_buf
&& *--frame_title_ptr
== '-')
15532 frame_title_ptr
+= 3; /* restore last non-dash + two dashes */
15533 if (len
> frame_title_ptr
- frame_title_buf
)
15534 len
= frame_title_ptr
- frame_title_buf
;
15537 frame_title_ptr
= NULL
;
15538 return make_string (frame_title_buf
, len
);
15541 /* Write a null-terminated, right justified decimal representation of
15542 the positive integer D to BUF using a minimal field width WIDTH. */
15545 pint2str (buf
, width
, d
)
15546 register char *buf
;
15547 register int width
;
15550 register char *p
= buf
;
15558 *p
++ = d
% 10 + '0';
15563 for (width
-= (int) (p
- buf
); width
> 0; --width
)
15574 /* Write a null-terminated, right justified decimal and "human
15575 readable" representation of the nonnegative integer D to BUF using
15576 a minimal field width WIDTH. D should be smaller than 999.5e24. */
15578 static const char power_letter
[] =
15592 pint2hrstr (buf
, width
, d
)
15597 /* We aim to represent the nonnegative integer D as
15598 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
15601 /* -1 means: do not use TENTHS. */
15605 /* Length of QUOTIENT.TENTHS as a string. */
15611 if (1000 <= quotient
)
15613 /* Scale to the appropriate EXPONENT. */
15616 remainder
= quotient
% 1000;
15620 while (1000 <= quotient
);
15622 /* Round to nearest and decide whether to use TENTHS or not. */
15625 tenths
= remainder
/ 100;
15626 if (50 <= remainder
% 100)
15632 if (quotient
== 10)
15639 if (500 <= remainder
)
15640 if (quotient
< 999)
15650 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
15651 if (tenths
== -1 && quotient
<= 99)
15658 p
= psuffix
= buf
+ max (width
, length
);
15660 /* Print EXPONENT. */
15662 *psuffix
++ = power_letter
[exponent
];
15665 /* Print TENTHS. */
15668 *--p
= '0' + tenths
;
15672 /* Print QUOTIENT. */
15675 int digit
= quotient
% 10;
15676 *--p
= '0' + digit
;
15678 while ((quotient
/= 10) != 0);
15680 /* Print leading spaces. */
15685 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
15686 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
15687 type of CODING_SYSTEM. Return updated pointer into BUF. */
15689 static unsigned char invalid_eol_type
[] = "(*invalid*)";
15692 decode_mode_spec_coding (coding_system
, buf
, eol_flag
)
15693 Lisp_Object coding_system
;
15694 register char *buf
;
15698 int multibyte
= !NILP (current_buffer
->enable_multibyte_characters
);
15699 const unsigned char *eol_str
;
15701 /* The EOL conversion we are using. */
15702 Lisp_Object eoltype
;
15704 val
= Fget (coding_system
, Qcoding_system
);
15707 if (!VECTORP (val
)) /* Not yet decided. */
15712 eoltype
= eol_mnemonic_undecided
;
15713 /* Don't mention EOL conversion if it isn't decided. */
15717 Lisp_Object eolvalue
;
15719 eolvalue
= Fget (coding_system
, Qeol_type
);
15722 *buf
++ = XFASTINT (AREF (val
, 1));
15726 /* The EOL conversion that is normal on this system. */
15728 if (NILP (eolvalue
)) /* Not yet decided. */
15729 eoltype
= eol_mnemonic_undecided
;
15730 else if (VECTORP (eolvalue
)) /* Not yet decided. */
15731 eoltype
= eol_mnemonic_undecided
;
15732 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
15733 eoltype
= (XFASTINT (eolvalue
) == 0
15734 ? eol_mnemonic_unix
15735 : (XFASTINT (eolvalue
) == 1
15736 ? eol_mnemonic_dos
: eol_mnemonic_mac
));
15742 /* Mention the EOL conversion if it is not the usual one. */
15743 if (STRINGP (eoltype
))
15745 eol_str
= SDATA (eoltype
);
15746 eol_str_len
= SBYTES (eoltype
);
15748 else if (INTEGERP (eoltype
)
15749 && CHAR_VALID_P (XINT (eoltype
), 0))
15751 unsigned char *tmp
= (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH
);
15752 eol_str_len
= CHAR_STRING (XINT (eoltype
), tmp
);
15757 eol_str
= invalid_eol_type
;
15758 eol_str_len
= sizeof (invalid_eol_type
) - 1;
15760 bcopy (eol_str
, buf
, eol_str_len
);
15761 buf
+= eol_str_len
;
15767 /* Return a string for the output of a mode line %-spec for window W,
15768 generated by character C. PRECISION >= 0 means don't return a
15769 string longer than that value. FIELD_WIDTH > 0 means pad the
15770 string returned with spaces to that value. Return 1 in *MULTIBYTE
15771 if the result is multibyte text. */
15773 static char lots_of_dashes
[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
15776 decode_mode_spec (w
, c
, field_width
, precision
, multibyte
)
15779 int field_width
, precision
;
15783 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
15784 char *decode_mode_spec_buf
= f
->decode_mode_spec_buffer
;
15785 struct buffer
*b
= XBUFFER (w
->buffer
);
15793 if (!NILP (b
->read_only
))
15795 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
15800 /* This differs from %* only for a modified read-only buffer. */
15801 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
15803 if (!NILP (b
->read_only
))
15808 /* This differs from %* in ignoring read-only-ness. */
15809 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
15821 if (command_loop_level
> 5)
15823 p
= decode_mode_spec_buf
;
15824 for (i
= 0; i
< command_loop_level
; i
++)
15827 return decode_mode_spec_buf
;
15835 if (command_loop_level
> 5)
15837 p
= decode_mode_spec_buf
;
15838 for (i
= 0; i
< command_loop_level
; i
++)
15841 return decode_mode_spec_buf
;
15848 /* Let lots_of_dashes be a string of infinite length. */
15849 if (!NILP (mode_line_string_list
))
15851 if (field_width
<= 0
15852 || field_width
> sizeof (lots_of_dashes
))
15854 for (i
= 0; i
< FRAME_MESSAGE_BUF_SIZE (f
) - 1; ++i
)
15855 decode_mode_spec_buf
[i
] = '-';
15856 decode_mode_spec_buf
[i
] = '\0';
15857 return decode_mode_spec_buf
;
15860 return lots_of_dashes
;
15869 int col
= (int) current_column (); /* iftc */
15870 w
->column_number_displayed
= make_number (col
);
15871 pint2str (decode_mode_spec_buf
, field_width
, col
);
15872 return decode_mode_spec_buf
;
15876 /* %F displays the frame name. */
15877 if (!NILP (f
->title
))
15878 return (char *) SDATA (f
->title
);
15879 if (f
->explicit_name
|| ! FRAME_WINDOW_P (f
))
15880 return (char *) SDATA (f
->name
);
15889 int size
= ZV
- BEGV
;
15890 pint2str (decode_mode_spec_buf
, field_width
, size
);
15891 return decode_mode_spec_buf
;
15896 int size
= ZV
- BEGV
;
15897 pint2hrstr (decode_mode_spec_buf
, field_width
, size
);
15898 return decode_mode_spec_buf
;
15903 int startpos
= XMARKER (w
->start
)->charpos
;
15904 int startpos_byte
= marker_byte_position (w
->start
);
15905 int line
, linepos
, linepos_byte
, topline
;
15907 int height
= WINDOW_TOTAL_LINES (w
);
15909 /* If we decided that this buffer isn't suitable for line numbers,
15910 don't forget that too fast. */
15911 if (EQ (w
->base_line_pos
, w
->buffer
))
15913 /* But do forget it, if the window shows a different buffer now. */
15914 else if (BUFFERP (w
->base_line_pos
))
15915 w
->base_line_pos
= Qnil
;
15917 /* If the buffer is very big, don't waste time. */
15918 if (INTEGERP (Vline_number_display_limit
)
15919 && BUF_ZV (b
) - BUF_BEGV (b
) > XINT (Vline_number_display_limit
))
15921 w
->base_line_pos
= Qnil
;
15922 w
->base_line_number
= Qnil
;
15926 if (!NILP (w
->base_line_number
)
15927 && !NILP (w
->base_line_pos
)
15928 && XFASTINT (w
->base_line_pos
) <= startpos
)
15930 line
= XFASTINT (w
->base_line_number
);
15931 linepos
= XFASTINT (w
->base_line_pos
);
15932 linepos_byte
= buf_charpos_to_bytepos (b
, linepos
);
15937 linepos
= BUF_BEGV (b
);
15938 linepos_byte
= BUF_BEGV_BYTE (b
);
15941 /* Count lines from base line to window start position. */
15942 nlines
= display_count_lines (linepos
, linepos_byte
,
15946 topline
= nlines
+ line
;
15948 /* Determine a new base line, if the old one is too close
15949 or too far away, or if we did not have one.
15950 "Too close" means it's plausible a scroll-down would
15951 go back past it. */
15952 if (startpos
== BUF_BEGV (b
))
15954 w
->base_line_number
= make_number (topline
);
15955 w
->base_line_pos
= make_number (BUF_BEGV (b
));
15957 else if (nlines
< height
+ 25 || nlines
> height
* 3 + 50
15958 || linepos
== BUF_BEGV (b
))
15960 int limit
= BUF_BEGV (b
);
15961 int limit_byte
= BUF_BEGV_BYTE (b
);
15963 int distance
= (height
* 2 + 30) * line_number_display_limit_width
;
15965 if (startpos
- distance
> limit
)
15967 limit
= startpos
- distance
;
15968 limit_byte
= CHAR_TO_BYTE (limit
);
15971 nlines
= display_count_lines (startpos
, startpos_byte
,
15973 - (height
* 2 + 30),
15975 /* If we couldn't find the lines we wanted within
15976 line_number_display_limit_width chars per line,
15977 give up on line numbers for this window. */
15978 if (position
== limit_byte
&& limit
== startpos
- distance
)
15980 w
->base_line_pos
= w
->buffer
;
15981 w
->base_line_number
= Qnil
;
15985 w
->base_line_number
= make_number (topline
- nlines
);
15986 w
->base_line_pos
= make_number (BYTE_TO_CHAR (position
));
15989 /* Now count lines from the start pos to point. */
15990 nlines
= display_count_lines (startpos
, startpos_byte
,
15991 PT_BYTE
, PT
, &junk
);
15993 /* Record that we did display the line number. */
15994 line_number_displayed
= 1;
15996 /* Make the string to show. */
15997 pint2str (decode_mode_spec_buf
, field_width
, topline
+ nlines
);
15998 return decode_mode_spec_buf
;
16001 char* p
= decode_mode_spec_buf
;
16002 int pad
= field_width
- 2;
16008 return decode_mode_spec_buf
;
16014 obj
= b
->mode_name
;
16018 if (BUF_BEGV (b
) > BUF_BEG (b
) || BUF_ZV (b
) < BUF_Z (b
))
16024 int pos
= marker_position (w
->start
);
16025 int total
= BUF_ZV (b
) - BUF_BEGV (b
);
16027 if (XFASTINT (w
->window_end_pos
) <= BUF_Z (b
) - BUF_ZV (b
))
16029 if (pos
<= BUF_BEGV (b
))
16034 else if (pos
<= BUF_BEGV (b
))
16038 if (total
> 1000000)
16039 /* Do it differently for a large value, to avoid overflow. */
16040 total
= ((pos
- BUF_BEGV (b
)) + (total
/ 100) - 1) / (total
/ 100);
16042 total
= ((pos
- BUF_BEGV (b
)) * 100 + total
- 1) / total
;
16043 /* We can't normally display a 3-digit number,
16044 so get us a 2-digit number that is close. */
16047 sprintf (decode_mode_spec_buf
, "%2d%%", total
);
16048 return decode_mode_spec_buf
;
16052 /* Display percentage of size above the bottom of the screen. */
16055 int toppos
= marker_position (w
->start
);
16056 int botpos
= BUF_Z (b
) - XFASTINT (w
->window_end_pos
);
16057 int total
= BUF_ZV (b
) - BUF_BEGV (b
);
16059 if (botpos
>= BUF_ZV (b
))
16061 if (toppos
<= BUF_BEGV (b
))
16068 if (total
> 1000000)
16069 /* Do it differently for a large value, to avoid overflow. */
16070 total
= ((botpos
- BUF_BEGV (b
)) + (total
/ 100) - 1) / (total
/ 100);
16072 total
= ((botpos
- BUF_BEGV (b
)) * 100 + total
- 1) / total
;
16073 /* We can't normally display a 3-digit number,
16074 so get us a 2-digit number that is close. */
16077 if (toppos
<= BUF_BEGV (b
))
16078 sprintf (decode_mode_spec_buf
, "Top%2d%%", total
);
16080 sprintf (decode_mode_spec_buf
, "%2d%%", total
);
16081 return decode_mode_spec_buf
;
16086 /* status of process */
16087 obj
= Fget_buffer_process (w
->buffer
);
16089 return "no process";
16090 #ifdef subprocesses
16091 obj
= Fsymbol_name (Fprocess_status (obj
));
16095 case 't': /* indicate TEXT or BINARY */
16096 #ifdef MODE_LINE_BINARY_TEXT
16097 return MODE_LINE_BINARY_TEXT (b
);
16103 /* coding-system (not including end-of-line format) */
16105 /* coding-system (including end-of-line type) */
16107 int eol_flag
= (c
== 'Z');
16108 char *p
= decode_mode_spec_buf
;
16110 if (! FRAME_WINDOW_P (f
))
16112 /* No need to mention EOL here--the terminal never needs
16113 to do EOL conversion. */
16114 p
= decode_mode_spec_coding (keyboard_coding
.symbol
, p
, 0);
16115 p
= decode_mode_spec_coding (terminal_coding
.symbol
, p
, 0);
16117 p
= decode_mode_spec_coding (b
->buffer_file_coding_system
,
16120 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
16121 #ifdef subprocesses
16122 obj
= Fget_buffer_process (Fcurrent_buffer ());
16123 if (PROCESSP (obj
))
16125 p
= decode_mode_spec_coding (XPROCESS (obj
)->decode_coding_system
,
16127 p
= decode_mode_spec_coding (XPROCESS (obj
)->encode_coding_system
,
16130 #endif /* subprocesses */
16133 return decode_mode_spec_buf
;
16139 *multibyte
= STRING_MULTIBYTE (obj
);
16140 return (char *) SDATA (obj
);
16147 /* Count up to COUNT lines starting from START / START_BYTE.
16148 But don't go beyond LIMIT_BYTE.
16149 Return the number of lines thus found (always nonnegative).
16151 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
16154 display_count_lines (start
, start_byte
, limit_byte
, count
, byte_pos_ptr
)
16155 int start
, start_byte
, limit_byte
, count
;
16158 register unsigned char *cursor
;
16159 unsigned char *base
;
16161 register int ceiling
;
16162 register unsigned char *ceiling_addr
;
16163 int orig_count
= count
;
16165 /* If we are not in selective display mode,
16166 check only for newlines. */
16167 int selective_display
= (!NILP (current_buffer
->selective_display
)
16168 && !INTEGERP (current_buffer
->selective_display
));
16172 while (start_byte
< limit_byte
)
16174 ceiling
= BUFFER_CEILING_OF (start_byte
);
16175 ceiling
= min (limit_byte
- 1, ceiling
);
16176 ceiling_addr
= BYTE_POS_ADDR (ceiling
) + 1;
16177 base
= (cursor
= BYTE_POS_ADDR (start_byte
));
16180 if (selective_display
)
16181 while (*cursor
!= '\n' && *cursor
!= 015 && ++cursor
!= ceiling_addr
)
16184 while (*cursor
!= '\n' && ++cursor
!= ceiling_addr
)
16187 if (cursor
!= ceiling_addr
)
16191 start_byte
+= cursor
- base
+ 1;
16192 *byte_pos_ptr
= start_byte
;
16196 if (++cursor
== ceiling_addr
)
16202 start_byte
+= cursor
- base
;
16207 while (start_byte
> limit_byte
)
16209 ceiling
= BUFFER_FLOOR_OF (start_byte
- 1);
16210 ceiling
= max (limit_byte
, ceiling
);
16211 ceiling_addr
= BYTE_POS_ADDR (ceiling
) - 1;
16212 base
= (cursor
= BYTE_POS_ADDR (start_byte
- 1) + 1);
16215 if (selective_display
)
16216 while (--cursor
!= ceiling_addr
16217 && *cursor
!= '\n' && *cursor
!= 015)
16220 while (--cursor
!= ceiling_addr
&& *cursor
!= '\n')
16223 if (cursor
!= ceiling_addr
)
16227 start_byte
+= cursor
- base
+ 1;
16228 *byte_pos_ptr
= start_byte
;
16229 /* When scanning backwards, we should
16230 not count the newline posterior to which we stop. */
16231 return - orig_count
- 1;
16237 /* Here we add 1 to compensate for the last decrement
16238 of CURSOR, which took it past the valid range. */
16239 start_byte
+= cursor
- base
+ 1;
16243 *byte_pos_ptr
= limit_byte
;
16246 return - orig_count
+ count
;
16247 return orig_count
- count
;
16253 /***********************************************************************
16255 ***********************************************************************/
16257 /* Display a NUL-terminated string, starting with index START.
16259 If STRING is non-null, display that C string. Otherwise, the Lisp
16260 string LISP_STRING is displayed.
16262 If FACE_STRING is not nil, FACE_STRING_POS is a position in
16263 FACE_STRING. Display STRING or LISP_STRING with the face at
16264 FACE_STRING_POS in FACE_STRING:
16266 Display the string in the environment given by IT, but use the
16267 standard display table, temporarily.
16269 FIELD_WIDTH is the minimum number of output glyphs to produce.
16270 If STRING has fewer characters than FIELD_WIDTH, pad to the right
16271 with spaces. If STRING has more characters, more than FIELD_WIDTH
16272 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
16274 PRECISION is the maximum number of characters to output from
16275 STRING. PRECISION < 0 means don't truncate the string.
16277 This is roughly equivalent to printf format specifiers:
16279 FIELD_WIDTH PRECISION PRINTF
16280 ----------------------------------------
16286 MULTIBYTE zero means do not display multibyte chars, > 0 means do
16287 display them, and < 0 means obey the current buffer's value of
16288 enable_multibyte_characters.
16290 Value is the number of glyphs produced. */
16293 display_string (string
, lisp_string
, face_string
, face_string_pos
,
16294 start
, it
, field_width
, precision
, max_x
, multibyte
)
16295 unsigned char *string
;
16296 Lisp_Object lisp_string
;
16297 Lisp_Object face_string
;
16298 int face_string_pos
;
16301 int field_width
, precision
, max_x
;
16304 int hpos_at_start
= it
->hpos
;
16305 int saved_face_id
= it
->face_id
;
16306 struct glyph_row
*row
= it
->glyph_row
;
16308 /* Initialize the iterator IT for iteration over STRING beginning
16309 with index START. */
16310 reseat_to_string (it
, string
, lisp_string
, start
,
16311 precision
, field_width
, multibyte
);
16313 /* If displaying STRING, set up the face of the iterator
16314 from LISP_STRING, if that's given. */
16315 if (STRINGP (face_string
))
16321 = face_at_string_position (it
->w
, face_string
, face_string_pos
,
16322 0, it
->region_beg_charpos
,
16323 it
->region_end_charpos
,
16324 &endptr
, it
->base_face_id
, 0);
16325 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
16326 it
->face_box_p
= face
->box
!= FACE_NO_BOX
;
16329 /* Set max_x to the maximum allowed X position. Don't let it go
16330 beyond the right edge of the window. */
16332 max_x
= it
->last_visible_x
;
16334 max_x
= min (max_x
, it
->last_visible_x
);
16336 /* Skip over display elements that are not visible. because IT->w is
16338 if (it
->current_x
< it
->first_visible_x
)
16339 move_it_in_display_line_to (it
, 100000, it
->first_visible_x
,
16340 MOVE_TO_POS
| MOVE_TO_X
);
16342 row
->ascent
= it
->max_ascent
;
16343 row
->height
= it
->max_ascent
+ it
->max_descent
;
16344 row
->phys_ascent
= it
->max_phys_ascent
;
16345 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
16347 /* This condition is for the case that we are called with current_x
16348 past last_visible_x. */
16349 while (it
->current_x
< max_x
)
16351 int x_before
, x
, n_glyphs_before
, i
, nglyphs
;
16353 /* Get the next display element. */
16354 if (!get_next_display_element (it
))
16357 /* Produce glyphs. */
16358 x_before
= it
->current_x
;
16359 n_glyphs_before
= it
->glyph_row
->used
[TEXT_AREA
];
16360 PRODUCE_GLYPHS (it
);
16362 nglyphs
= it
->glyph_row
->used
[TEXT_AREA
] - n_glyphs_before
;
16365 while (i
< nglyphs
)
16367 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
16369 if (!it
->truncate_lines_p
16370 && x
+ glyph
->pixel_width
> max_x
)
16372 /* End of continued line or max_x reached. */
16373 if (CHAR_GLYPH_PADDING_P (*glyph
))
16375 /* A wide character is unbreakable. */
16376 it
->glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
;
16377 it
->current_x
= x_before
;
16381 it
->glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
+ i
;
16386 else if (x
+ glyph
->pixel_width
> it
->first_visible_x
)
16388 /* Glyph is at least partially visible. */
16390 if (x
< it
->first_visible_x
)
16391 it
->glyph_row
->x
= x
- it
->first_visible_x
;
16395 /* Glyph is off the left margin of the display area.
16396 Should not happen. */
16400 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
16401 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
16402 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
16403 row
->phys_height
= max (row
->phys_height
,
16404 it
->max_phys_ascent
+ it
->max_phys_descent
);
16405 x
+= glyph
->pixel_width
;
16409 /* Stop if max_x reached. */
16413 /* Stop at line ends. */
16414 if (ITERATOR_AT_END_OF_LINE_P (it
))
16416 it
->continuation_lines_width
= 0;
16420 set_iterator_to_next (it
, 1);
16422 /* Stop if truncating at the right edge. */
16423 if (it
->truncate_lines_p
16424 && it
->current_x
>= it
->last_visible_x
)
16426 /* Add truncation mark, but don't do it if the line is
16427 truncated at a padding space. */
16428 if (IT_CHARPOS (*it
) < it
->string_nchars
)
16430 if (!FRAME_WINDOW_P (it
->f
))
16434 if (it
->current_x
> it
->last_visible_x
)
16436 for (i
= row
->used
[TEXT_AREA
] - 1; i
> 0; --i
)
16437 if (!CHAR_GLYPH_PADDING_P (row
->glyphs
[TEXT_AREA
][i
]))
16439 for (n
= row
->used
[TEXT_AREA
]; i
< n
; ++i
)
16441 row
->used
[TEXT_AREA
] = i
;
16442 produce_special_glyphs (it
, IT_TRUNCATION
);
16445 produce_special_glyphs (it
, IT_TRUNCATION
);
16447 it
->glyph_row
->truncated_on_right_p
= 1;
16453 /* Maybe insert a truncation at the left. */
16454 if (it
->first_visible_x
16455 && IT_CHARPOS (*it
) > 0)
16457 if (!FRAME_WINDOW_P (it
->f
))
16458 insert_left_trunc_glyphs (it
);
16459 it
->glyph_row
->truncated_on_left_p
= 1;
16462 it
->face_id
= saved_face_id
;
16464 /* Value is number of columns displayed. */
16465 return it
->hpos
- hpos_at_start
;
16470 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
16471 appears as an element of LIST or as the car of an element of LIST.
16472 If PROPVAL is a list, compare each element against LIST in that
16473 way, and return 1/2 if any element of PROPVAL is found in LIST.
16474 Otherwise return 0. This function cannot quit.
16475 The return value is 2 if the text is invisible but with an ellipsis
16476 and 1 if it's invisible and without an ellipsis. */
16479 invisible_p (propval
, list
)
16480 register Lisp_Object propval
;
16483 register Lisp_Object tail
, proptail
;
16485 for (tail
= list
; CONSP (tail
); tail
= XCDR (tail
))
16487 register Lisp_Object tem
;
16489 if (EQ (propval
, tem
))
16491 if (CONSP (tem
) && EQ (propval
, XCAR (tem
)))
16492 return NILP (XCDR (tem
)) ? 1 : 2;
16495 if (CONSP (propval
))
16497 for (proptail
= propval
; CONSP (proptail
); proptail
= XCDR (proptail
))
16499 Lisp_Object propelt
;
16500 propelt
= XCAR (proptail
);
16501 for (tail
= list
; CONSP (tail
); tail
= XCDR (tail
))
16503 register Lisp_Object tem
;
16505 if (EQ (propelt
, tem
))
16507 if (CONSP (tem
) && EQ (propelt
, XCAR (tem
)))
16508 return NILP (XCDR (tem
)) ? 1 : 2;
16517 /***********************************************************************
16519 ***********************************************************************/
16521 #ifdef HAVE_WINDOW_SYSTEM
16526 dump_glyph_string (s
)
16527 struct glyph_string
*s
;
16529 fprintf (stderr
, "glyph string\n");
16530 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
16531 s
->x
, s
->y
, s
->width
, s
->height
);
16532 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
16533 fprintf (stderr
, " hl = %d\n", s
->hl
);
16534 fprintf (stderr
, " left overhang = %d, right = %d\n",
16535 s
->left_overhang
, s
->right_overhang
);
16536 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
16537 fprintf (stderr
, " extends to end of line = %d\n",
16538 s
->extends_to_end_of_line_p
);
16539 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
16540 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
16543 #endif /* GLYPH_DEBUG */
16545 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
16546 of XChar2b structures for S; it can't be allocated in
16547 init_glyph_string because it must be allocated via `alloca'. W
16548 is the window on which S is drawn. ROW and AREA are the glyph row
16549 and area within the row from which S is constructed. START is the
16550 index of the first glyph structure covered by S. HL is a
16551 face-override for drawing S. */
16554 #define OPTIONAL_HDC(hdc) hdc,
16555 #define DECLARE_HDC(hdc) HDC hdc;
16556 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
16557 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
16560 #ifndef OPTIONAL_HDC
16561 #define OPTIONAL_HDC(hdc)
16562 #define DECLARE_HDC(hdc)
16563 #define ALLOCATE_HDC(hdc, f)
16564 #define RELEASE_HDC(hdc, f)
16568 init_glyph_string (s
, OPTIONAL_HDC (hdc
) char2b
, w
, row
, area
, start
, hl
)
16569 struct glyph_string
*s
;
16573 struct glyph_row
*row
;
16574 enum glyph_row_area area
;
16576 enum draw_glyphs_face hl
;
16578 bzero (s
, sizeof *s
);
16580 s
->f
= XFRAME (w
->frame
);
16584 s
->display
= FRAME_X_DISPLAY (s
->f
);
16585 s
->window
= FRAME_X_WINDOW (s
->f
);
16586 s
->char2b
= char2b
;
16590 s
->first_glyph
= row
->glyphs
[area
] + start
;
16591 s
->height
= row
->height
;
16592 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
16594 /* Display the internal border below the tool-bar window. */
16595 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
16596 s
->y
-= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
16598 s
->ybase
= s
->y
+ row
->ascent
;
16602 /* Append the list of glyph strings with head H and tail T to the list
16603 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
16606 append_glyph_string_lists (head
, tail
, h
, t
)
16607 struct glyph_string
**head
, **tail
;
16608 struct glyph_string
*h
, *t
;
16622 /* Prepend the list of glyph strings with head H and tail T to the
16623 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
16627 prepend_glyph_string_lists (head
, tail
, h
, t
)
16628 struct glyph_string
**head
, **tail
;
16629 struct glyph_string
*h
, *t
;
16643 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
16644 Set *HEAD and *TAIL to the resulting list. */
16647 append_glyph_string (head
, tail
, s
)
16648 struct glyph_string
**head
, **tail
;
16649 struct glyph_string
*s
;
16651 s
->next
= s
->prev
= NULL
;
16652 append_glyph_string_lists (head
, tail
, s
, s
);
16656 /* Get face and two-byte form of character glyph GLYPH on frame F.
16657 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
16658 a pointer to a realized face that is ready for display. */
16660 static INLINE
struct face
*
16661 get_glyph_face_and_encoding (f
, glyph
, char2b
, two_byte_p
)
16663 struct glyph
*glyph
;
16669 xassert (glyph
->type
== CHAR_GLYPH
);
16670 face
= FACE_FROM_ID (f
, glyph
->face_id
);
16675 if (!glyph
->multibyte_p
)
16677 /* Unibyte case. We don't have to encode, but we have to make
16678 sure to use a face suitable for unibyte. */
16679 STORE_XCHAR2B (char2b
, 0, glyph
->u
.ch
);
16681 else if (glyph
->u
.ch
< 128
16682 && glyph
->face_id
< BASIC_FACE_ID_SENTINEL
)
16684 /* Case of ASCII in a face known to fit ASCII. */
16685 STORE_XCHAR2B (char2b
, 0, glyph
->u
.ch
);
16689 int c1
, c2
, charset
;
16691 /* Split characters into bytes. If c2 is -1 afterwards, C is
16692 really a one-byte character so that byte1 is zero. */
16693 SPLIT_CHAR (glyph
->u
.ch
, charset
, c1
, c2
);
16695 STORE_XCHAR2B (char2b
, c1
, c2
);
16697 STORE_XCHAR2B (char2b
, 0, c1
);
16699 /* Maybe encode the character in *CHAR2B. */
16700 if (charset
!= CHARSET_ASCII
)
16702 struct font_info
*font_info
16703 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
16706 = rif
->encode_char (glyph
->u
.ch
, char2b
, font_info
, two_byte_p
);
16710 /* Make sure X resources of the face are allocated. */
16711 xassert (face
!= NULL
);
16712 PREPARE_FACE_FOR_DISPLAY (f
, face
);
16717 /* Fill glyph string S with composition components specified by S->cmp.
16719 FACES is an array of faces for all components of this composition.
16720 S->gidx is the index of the first component for S.
16721 OVERLAPS_P non-zero means S should draw the foreground only, and
16722 use its physical height for clipping.
16724 Value is the index of a component not in S. */
16727 fill_composite_glyph_string (s
, faces
, overlaps_p
)
16728 struct glyph_string
*s
;
16729 struct face
**faces
;
16736 s
->for_overlaps_p
= overlaps_p
;
16738 s
->face
= faces
[s
->gidx
];
16739 s
->font
= s
->face
->font
;
16740 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
16742 /* For all glyphs of this composition, starting at the offset
16743 S->gidx, until we reach the end of the definition or encounter a
16744 glyph that requires the different face, add it to S. */
16746 for (i
= s
->gidx
+ 1; i
< s
->cmp
->glyph_len
&& faces
[i
] == s
->face
; ++i
)
16749 /* All glyph strings for the same composition has the same width,
16750 i.e. the width set for the first component of the composition. */
16752 s
->width
= s
->first_glyph
->pixel_width
;
16754 /* If the specified font could not be loaded, use the frame's
16755 default font, but record the fact that we couldn't load it in
16756 the glyph string so that we can draw rectangles for the
16757 characters of the glyph string. */
16758 if (s
->font
== NULL
)
16760 s
->font_not_found_p
= 1;
16761 s
->font
= FRAME_FONT (s
->f
);
16764 /* Adjust base line for subscript/superscript text. */
16765 s
->ybase
+= s
->first_glyph
->voffset
;
16767 xassert (s
->face
&& s
->face
->gc
);
16769 /* This glyph string must always be drawn with 16-bit functions. */
16772 return s
->gidx
+ s
->nchars
;
16776 /* Fill glyph string S from a sequence of character glyphs.
16778 FACE_ID is the face id of the string. START is the index of the
16779 first glyph to consider, END is the index of the last + 1.
16780 OVERLAPS_P non-zero means S should draw the foreground only, and
16781 use its physical height for clipping.
16783 Value is the index of the first glyph not in S. */
16786 fill_glyph_string (s
, face_id
, start
, end
, overlaps_p
)
16787 struct glyph_string
*s
;
16789 int start
, end
, overlaps_p
;
16791 struct glyph
*glyph
, *last
;
16793 int glyph_not_available_p
;
16795 xassert (s
->f
== XFRAME (s
->w
->frame
));
16796 xassert (s
->nchars
== 0);
16797 xassert (start
>= 0 && end
> start
);
16799 s
->for_overlaps_p
= overlaps_p
,
16800 glyph
= s
->row
->glyphs
[s
->area
] + start
;
16801 last
= s
->row
->glyphs
[s
->area
] + end
;
16802 voffset
= glyph
->voffset
;
16804 glyph_not_available_p
= glyph
->glyph_not_available_p
;
16806 while (glyph
< last
16807 && glyph
->type
== CHAR_GLYPH
16808 && glyph
->voffset
== voffset
16809 /* Same face id implies same font, nowadays. */
16810 && glyph
->face_id
== face_id
16811 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
16815 s
->face
= get_glyph_face_and_encoding (s
->f
, glyph
,
16816 s
->char2b
+ s
->nchars
,
16818 s
->two_byte_p
= two_byte_p
;
16820 xassert (s
->nchars
<= end
- start
);
16821 s
->width
+= glyph
->pixel_width
;
16825 s
->font
= s
->face
->font
;
16826 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
16828 /* If the specified font could not be loaded, use the frame's font,
16829 but record the fact that we couldn't load it in
16830 S->font_not_found_p so that we can draw rectangles for the
16831 characters of the glyph string. */
16832 if (s
->font
== NULL
|| glyph_not_available_p
)
16834 s
->font_not_found_p
= 1;
16835 s
->font
= FRAME_FONT (s
->f
);
16838 /* Adjust base line for subscript/superscript text. */
16839 s
->ybase
+= voffset
;
16841 xassert (s
->face
&& s
->face
->gc
);
16842 return glyph
- s
->row
->glyphs
[s
->area
];
16846 /* Fill glyph string S from image glyph S->first_glyph. */
16849 fill_image_glyph_string (s
)
16850 struct glyph_string
*s
;
16852 xassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
16853 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
16855 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
16856 s
->font
= s
->face
->font
;
16857 s
->width
= s
->first_glyph
->pixel_width
;
16859 /* Adjust base line for subscript/superscript text. */
16860 s
->ybase
+= s
->first_glyph
->voffset
;
16864 /* Fill glyph string S from a sequence of stretch glyphs.
16866 ROW is the glyph row in which the glyphs are found, AREA is the
16867 area within the row. START is the index of the first glyph to
16868 consider, END is the index of the last + 1.
16870 Value is the index of the first glyph not in S. */
16873 fill_stretch_glyph_string (s
, row
, area
, start
, end
)
16874 struct glyph_string
*s
;
16875 struct glyph_row
*row
;
16876 enum glyph_row_area area
;
16879 struct glyph
*glyph
, *last
;
16880 int voffset
, face_id
;
16882 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
16884 glyph
= s
->row
->glyphs
[s
->area
] + start
;
16885 last
= s
->row
->glyphs
[s
->area
] + end
;
16886 face_id
= glyph
->face_id
;
16887 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
16888 s
->font
= s
->face
->font
;
16889 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
16890 s
->width
= glyph
->pixel_width
;
16891 voffset
= glyph
->voffset
;
16895 && glyph
->type
== STRETCH_GLYPH
16896 && glyph
->voffset
== voffset
16897 && glyph
->face_id
== face_id
);
16899 s
->width
+= glyph
->pixel_width
;
16901 /* Adjust base line for subscript/superscript text. */
16902 s
->ybase
+= voffset
;
16904 /* The case that face->gc == 0 is handled when drawing the glyph
16905 string by calling PREPARE_FACE_FOR_DISPLAY. */
16907 return glyph
- s
->row
->glyphs
[s
->area
];
16912 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
16913 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
16914 assumed to be zero. */
16917 x_get_glyph_overhangs (glyph
, f
, left
, right
)
16918 struct glyph
*glyph
;
16922 *left
= *right
= 0;
16924 if (glyph
->type
== CHAR_GLYPH
)
16928 struct font_info
*font_info
;
16932 face
= get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
16934 font_info
= FONT_INFO_FROM_ID (f
, face
->font_info_id
);
16935 if (font
/* ++KFS: Should this be font_info ? */
16936 && (pcm
= rif
->per_char_metric (font
, &char2b
, glyph
->font_type
)))
16938 if (pcm
->rbearing
> pcm
->width
)
16939 *right
= pcm
->rbearing
- pcm
->width
;
16940 if (pcm
->lbearing
< 0)
16941 *left
= -pcm
->lbearing
;
16947 /* Return the index of the first glyph preceding glyph string S that
16948 is overwritten by S because of S's left overhang. Value is -1
16949 if no glyphs are overwritten. */
16952 left_overwritten (s
)
16953 struct glyph_string
*s
;
16957 if (s
->left_overhang
)
16960 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
16961 int first
= s
->first_glyph
- glyphs
;
16963 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
16964 x
-= glyphs
[i
].pixel_width
;
16975 /* Return the index of the first glyph preceding glyph string S that
16976 is overwriting S because of its right overhang. Value is -1 if no
16977 glyph in front of S overwrites S. */
16980 left_overwriting (s
)
16981 struct glyph_string
*s
;
16984 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
16985 int first
= s
->first_glyph
- glyphs
;
16989 for (i
= first
- 1; i
>= 0; --i
)
16992 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
16995 x
-= glyphs
[i
].pixel_width
;
17002 /* Return the index of the last glyph following glyph string S that is
17003 not overwritten by S because of S's right overhang. Value is -1 if
17004 no such glyph is found. */
17007 right_overwritten (s
)
17008 struct glyph_string
*s
;
17012 if (s
->right_overhang
)
17015 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
17016 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
17017 int end
= s
->row
->used
[s
->area
];
17019 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
17020 x
+= glyphs
[i
].pixel_width
;
17029 /* Return the index of the last glyph following glyph string S that
17030 overwrites S because of its left overhang. Value is negative
17031 if no such glyph is found. */
17034 right_overwriting (s
)
17035 struct glyph_string
*s
;
17038 int end
= s
->row
->used
[s
->area
];
17039 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
17040 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
17044 for (i
= first
; i
< end
; ++i
)
17047 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
17050 x
+= glyphs
[i
].pixel_width
;
17057 /* Get face and two-byte form of character C in face FACE_ID on frame
17058 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
17059 means we want to display multibyte text. DISPLAY_P non-zero means
17060 make sure that X resources for the face returned are allocated.
17061 Value is a pointer to a realized face that is ready for display if
17062 DISPLAY_P is non-zero. */
17064 static INLINE
struct face
*
17065 get_char_face_and_encoding (f
, c
, face_id
, char2b
, multibyte_p
, display_p
)
17069 int multibyte_p
, display_p
;
17071 struct face
*face
= FACE_FROM_ID (f
, face_id
);
17075 /* Unibyte case. We don't have to encode, but we have to make
17076 sure to use a face suitable for unibyte. */
17077 STORE_XCHAR2B (char2b
, 0, c
);
17078 face_id
= FACE_FOR_CHAR (f
, face
, c
);
17079 face
= FACE_FROM_ID (f
, face_id
);
17081 else if (c
< 128 && face_id
< BASIC_FACE_ID_SENTINEL
)
17083 /* Case of ASCII in a face known to fit ASCII. */
17084 STORE_XCHAR2B (char2b
, 0, c
);
17088 int c1
, c2
, charset
;
17090 /* Split characters into bytes. If c2 is -1 afterwards, C is
17091 really a one-byte character so that byte1 is zero. */
17092 SPLIT_CHAR (c
, charset
, c1
, c2
);
17094 STORE_XCHAR2B (char2b
, c1
, c2
);
17096 STORE_XCHAR2B (char2b
, 0, c1
);
17098 /* Maybe encode the character in *CHAR2B. */
17099 if (face
->font
!= NULL
)
17101 struct font_info
*font_info
17102 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
17104 rif
->encode_char (c
, char2b
, font_info
, 0);
17108 /* Make sure X resources of the face are allocated. */
17109 #ifdef HAVE_X_WINDOWS
17113 xassert (face
!= NULL
);
17114 PREPARE_FACE_FOR_DISPLAY (f
, face
);
17121 /* Set background width of glyph string S. START is the index of the
17122 first glyph following S. LAST_X is the right-most x-position + 1
17123 in the drawing area. */
17126 set_glyph_string_background_width (s
, start
, last_x
)
17127 struct glyph_string
*s
;
17131 /* If the face of this glyph string has to be drawn to the end of
17132 the drawing area, set S->extends_to_end_of_line_p. */
17133 struct face
*default_face
= FACE_FROM_ID (s
->f
, DEFAULT_FACE_ID
);
17135 if (start
== s
->row
->used
[s
->area
]
17136 && s
->area
== TEXT_AREA
17137 && ((s
->hl
== DRAW_NORMAL_TEXT
17138 && (s
->row
->fill_line_p
17139 || s
->face
->background
!= default_face
->background
17140 || s
->face
->stipple
!= default_face
->stipple
17141 || s
->row
->mouse_face_p
))
17142 || s
->hl
== DRAW_MOUSE_FACE
17143 || ((s
->hl
== DRAW_IMAGE_RAISED
|| s
->hl
== DRAW_IMAGE_SUNKEN
)
17144 && s
->row
->fill_line_p
)))
17145 s
->extends_to_end_of_line_p
= 1;
17147 /* If S extends its face to the end of the line, set its
17148 background_width to the distance to the right edge of the drawing
17150 if (s
->extends_to_end_of_line_p
)
17151 s
->background_width
= last_x
- s
->x
+ 1;
17153 s
->background_width
= s
->width
;
17157 /* Compute overhangs and x-positions for glyph string S and its
17158 predecessors, or successors. X is the starting x-position for S.
17159 BACKWARD_P non-zero means process predecessors. */
17162 compute_overhangs_and_x (s
, x
, backward_p
)
17163 struct glyph_string
*s
;
17171 if (rif
->compute_glyph_string_overhangs
)
17172 rif
->compute_glyph_string_overhangs (s
);
17182 if (rif
->compute_glyph_string_overhangs
)
17183 rif
->compute_glyph_string_overhangs (s
);
17193 /* The following macros are only called from draw_glyphs below.
17194 They reference the following parameters of that function directly:
17195 `w', `row', `area', and `overlap_p'
17196 as well as the following local variables:
17197 `s', `f', and `hdc' (in W32) */
17200 /* On W32, silently add local `hdc' variable to argument list of
17201 init_glyph_string. */
17202 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17203 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
17205 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17206 init_glyph_string (s, char2b, w, row, area, start, hl)
17209 /* Add a glyph string for a stretch glyph to the list of strings
17210 between HEAD and TAIL. START is the index of the stretch glyph in
17211 row area AREA of glyph row ROW. END is the index of the last glyph
17212 in that glyph row area. X is the current output position assigned
17213 to the new glyph string constructed. HL overrides that face of the
17214 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17215 is the right-most x-position of the drawing area. */
17217 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
17218 and below -- keep them on one line. */
17219 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17222 s = (struct glyph_string *) alloca (sizeof *s); \
17223 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17224 START = fill_stretch_glyph_string (s, row, area, START, END); \
17225 append_glyph_string (&HEAD, &TAIL, s); \
17231 /* Add a glyph string for an image glyph to the list of strings
17232 between HEAD and TAIL. START is the index of the image glyph in
17233 row area AREA of glyph row ROW. END is the index of the last glyph
17234 in that glyph row area. X is the current output position assigned
17235 to the new glyph string constructed. HL overrides that face of the
17236 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17237 is the right-most x-position of the drawing area. */
17239 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17242 s = (struct glyph_string *) alloca (sizeof *s); \
17243 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17244 fill_image_glyph_string (s); \
17245 append_glyph_string (&HEAD, &TAIL, s); \
17252 /* Add a glyph string for a sequence of character glyphs to the list
17253 of strings between HEAD and TAIL. START is the index of the first
17254 glyph in row area AREA of glyph row ROW that is part of the new
17255 glyph string. END is the index of the last glyph in that glyph row
17256 area. X is the current output position assigned to the new glyph
17257 string constructed. HL overrides that face of the glyph; e.g. it
17258 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
17259 right-most x-position of the drawing area. */
17261 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17267 c = (row)->glyphs[area][START].u.ch; \
17268 face_id = (row)->glyphs[area][START].face_id; \
17270 s = (struct glyph_string *) alloca (sizeof *s); \
17271 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
17272 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
17273 append_glyph_string (&HEAD, &TAIL, s); \
17275 START = fill_glyph_string (s, face_id, START, END, overlaps_p); \
17280 /* Add a glyph string for a composite sequence to the list of strings
17281 between HEAD and TAIL. START is the index of the first glyph in
17282 row area AREA of glyph row ROW that is part of the new glyph
17283 string. END is the index of the last glyph in that glyph row area.
17284 X is the current output position assigned to the new glyph string
17285 constructed. HL overrides that face of the glyph; e.g. it is
17286 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
17287 x-position of the drawing area. */
17289 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17291 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
17292 int face_id = (row)->glyphs[area][START].face_id; \
17293 struct face *base_face = FACE_FROM_ID (f, face_id); \
17294 struct composition *cmp = composition_table[cmp_id]; \
17295 int glyph_len = cmp->glyph_len; \
17297 struct face **faces; \
17298 struct glyph_string *first_s = NULL; \
17301 base_face = base_face->ascii_face; \
17302 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
17303 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
17304 /* At first, fill in `char2b' and `faces'. */ \
17305 for (n = 0; n < glyph_len; n++) \
17307 int c = COMPOSITION_GLYPH (cmp, n); \
17308 int this_face_id = FACE_FOR_CHAR (f, base_face, c); \
17309 faces[n] = FACE_FROM_ID (f, this_face_id); \
17310 get_char_face_and_encoding (f, c, this_face_id, \
17311 char2b + n, 1, 1); \
17314 /* Make glyph_strings for each glyph sequence that is drawable by \
17315 the same face, and append them to HEAD/TAIL. */ \
17316 for (n = 0; n < cmp->glyph_len;) \
17318 s = (struct glyph_string *) alloca (sizeof *s); \
17319 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \
17320 append_glyph_string (&(HEAD), &(TAIL), s); \
17328 n = fill_composite_glyph_string (s, faces, overlaps_p); \
17336 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
17337 of AREA of glyph row ROW on window W between indices START and END.
17338 HL overrides the face for drawing glyph strings, e.g. it is
17339 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
17340 x-positions of the drawing area.
17342 This is an ugly monster macro construct because we must use alloca
17343 to allocate glyph strings (because draw_glyphs can be called
17344 asynchronously). */
17346 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17349 HEAD = TAIL = NULL; \
17350 while (START < END) \
17352 struct glyph *first_glyph = (row)->glyphs[area] + START; \
17353 switch (first_glyph->type) \
17356 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
17360 case COMPOSITE_GLYPH: \
17361 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
17365 case STRETCH_GLYPH: \
17366 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
17370 case IMAGE_GLYPH: \
17371 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
17379 set_glyph_string_background_width (s, START, LAST_X); \
17386 /* Draw glyphs between START and END in AREA of ROW on window W,
17387 starting at x-position X. X is relative to AREA in W. HL is a
17388 face-override with the following meaning:
17390 DRAW_NORMAL_TEXT draw normally
17391 DRAW_CURSOR draw in cursor face
17392 DRAW_MOUSE_FACE draw in mouse face.
17393 DRAW_INVERSE_VIDEO draw in mode line face
17394 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
17395 DRAW_IMAGE_RAISED draw an image with a raised relief around it
17397 If OVERLAPS_P is non-zero, draw only the foreground of characters
17398 and clip to the physical height of ROW.
17400 Value is the x-position reached, relative to AREA of W. */
17403 draw_glyphs (w
, x
, row
, area
, start
, end
, hl
, overlaps_p
)
17406 struct glyph_row
*row
;
17407 enum glyph_row_area area
;
17409 enum draw_glyphs_face hl
;
17412 struct glyph_string
*head
, *tail
;
17413 struct glyph_string
*s
;
17414 int last_x
, area_width
;
17417 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
17420 ALLOCATE_HDC (hdc
, f
);
17422 /* Let's rather be paranoid than getting a SEGV. */
17423 end
= min (end
, row
->used
[area
]);
17424 start
= max (0, start
);
17425 start
= min (end
, start
);
17427 /* Translate X to frame coordinates. Set last_x to the right
17428 end of the drawing area. */
17429 if (row
->full_width_p
)
17431 /* X is relative to the left edge of W, without scroll bars
17433 x
+= WINDOW_LEFT_EDGE_X (w
);
17434 last_x
= WINDOW_LEFT_EDGE_X (w
) + WINDOW_TOTAL_WIDTH (w
);
17438 int area_left
= window_box_left (w
, area
);
17440 area_width
= window_box_width (w
, area
);
17441 last_x
= area_left
+ area_width
;
17444 /* Build a doubly-linked list of glyph_string structures between
17445 head and tail from what we have to draw. Note that the macro
17446 BUILD_GLYPH_STRINGS will modify its start parameter. That's
17447 the reason we use a separate variable `i'. */
17449 BUILD_GLYPH_STRINGS (i
, end
, head
, tail
, hl
, x
, last_x
);
17451 x_reached
= tail
->x
+ tail
->background_width
;
17455 /* If there are any glyphs with lbearing < 0 or rbearing > width in
17456 the row, redraw some glyphs in front or following the glyph
17457 strings built above. */
17458 if (head
&& !overlaps_p
&& row
->contains_overlapping_glyphs_p
)
17461 struct glyph_string
*h
, *t
;
17463 /* Compute overhangs for all glyph strings. */
17464 if (rif
->compute_glyph_string_overhangs
)
17465 for (s
= head
; s
; s
= s
->next
)
17466 rif
->compute_glyph_string_overhangs (s
);
17468 /* Prepend glyph strings for glyphs in front of the first glyph
17469 string that are overwritten because of the first glyph
17470 string's left overhang. The background of all strings
17471 prepended must be drawn because the first glyph string
17473 i
= left_overwritten (head
);
17477 BUILD_GLYPH_STRINGS (j
, start
, h
, t
,
17478 DRAW_NORMAL_TEXT
, dummy_x
, last_x
);
17480 compute_overhangs_and_x (t
, head
->x
, 1);
17481 prepend_glyph_string_lists (&head
, &tail
, h
, t
);
17484 /* Prepend glyph strings for glyphs in front of the first glyph
17485 string that overwrite that glyph string because of their
17486 right overhang. For these strings, only the foreground must
17487 be drawn, because it draws over the glyph string at `head'.
17488 The background must not be drawn because this would overwrite
17489 right overhangs of preceding glyphs for which no glyph
17491 i
= left_overwriting (head
);
17494 BUILD_GLYPH_STRINGS (i
, start
, h
, t
,
17495 DRAW_NORMAL_TEXT
, dummy_x
, last_x
);
17496 for (s
= h
; s
; s
= s
->next
)
17497 s
->background_filled_p
= 1;
17498 compute_overhangs_and_x (t
, head
->x
, 1);
17499 prepend_glyph_string_lists (&head
, &tail
, h
, t
);
17502 /* Append glyphs strings for glyphs following the last glyph
17503 string tail that are overwritten by tail. The background of
17504 these strings has to be drawn because tail's foreground draws
17506 i
= right_overwritten (tail
);
17509 BUILD_GLYPH_STRINGS (end
, i
, h
, t
,
17510 DRAW_NORMAL_TEXT
, x
, last_x
);
17511 compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
17512 append_glyph_string_lists (&head
, &tail
, h
, t
);
17515 /* Append glyph strings for glyphs following the last glyph
17516 string tail that overwrite tail. The foreground of such
17517 glyphs has to be drawn because it writes into the background
17518 of tail. The background must not be drawn because it could
17519 paint over the foreground of following glyphs. */
17520 i
= right_overwriting (tail
);
17523 BUILD_GLYPH_STRINGS (end
, i
, h
, t
,
17524 DRAW_NORMAL_TEXT
, x
, last_x
);
17525 for (s
= h
; s
; s
= s
->next
)
17526 s
->background_filled_p
= 1;
17527 compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
17528 append_glyph_string_lists (&head
, &tail
, h
, t
);
17532 /* Draw all strings. */
17533 for (s
= head
; s
; s
= s
->next
)
17534 rif
->draw_glyph_string (s
);
17536 if (area
== TEXT_AREA
17537 && !row
->full_width_p
17538 /* When drawing overlapping rows, only the glyph strings'
17539 foreground is drawn, which doesn't erase a cursor
17543 int x0
= head
? head
->x
: x
;
17544 int x1
= tail
? tail
->x
+ tail
->background_width
: x
;
17546 int text_left
= window_box_left (w
, TEXT_AREA
);
17550 notice_overwritten_cursor (w
, TEXT_AREA
, x0
, x1
,
17551 row
->y
, MATRIX_ROW_BOTTOM_Y (row
));
17554 /* Value is the x-position up to which drawn, relative to AREA of W.
17555 This doesn't include parts drawn because of overhangs. */
17556 if (row
->full_width_p
)
17557 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
17559 x_reached
-= window_box_left (w
, area
);
17561 RELEASE_HDC (hdc
, f
);
17567 /* Store one glyph for IT->char_to_display in IT->glyph_row.
17568 Called from x_produce_glyphs when IT->glyph_row is non-null. */
17574 struct glyph
*glyph
;
17575 enum glyph_row_area area
= it
->area
;
17577 xassert (it
->glyph_row
);
17578 xassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
17580 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
17581 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
17583 glyph
->charpos
= CHARPOS (it
->position
);
17584 glyph
->object
= it
->object
;
17585 glyph
->pixel_width
= it
->pixel_width
;
17586 glyph
->ascent
= it
->ascent
;
17587 glyph
->descent
= it
->descent
;
17588 glyph
->voffset
= it
->voffset
;
17589 glyph
->type
= CHAR_GLYPH
;
17590 glyph
->multibyte_p
= it
->multibyte_p
;
17591 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
17592 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
17593 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
17594 || it
->phys_descent
> it
->descent
);
17595 glyph
->padding_p
= 0;
17596 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
17597 glyph
->face_id
= it
->face_id
;
17598 glyph
->u
.ch
= it
->char_to_display
;
17599 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
17600 ++it
->glyph_row
->used
[area
];
17604 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
17605 Called from x_produce_glyphs when IT->glyph_row is non-null. */
17608 append_composite_glyph (it
)
17611 struct glyph
*glyph
;
17612 enum glyph_row_area area
= it
->area
;
17614 xassert (it
->glyph_row
);
17616 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
17617 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
17619 glyph
->charpos
= CHARPOS (it
->position
);
17620 glyph
->object
= it
->object
;
17621 glyph
->pixel_width
= it
->pixel_width
;
17622 glyph
->ascent
= it
->ascent
;
17623 glyph
->descent
= it
->descent
;
17624 glyph
->voffset
= it
->voffset
;
17625 glyph
->type
= COMPOSITE_GLYPH
;
17626 glyph
->multibyte_p
= it
->multibyte_p
;
17627 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
17628 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
17629 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
17630 || it
->phys_descent
> it
->descent
);
17631 glyph
->padding_p
= 0;
17632 glyph
->glyph_not_available_p
= 0;
17633 glyph
->face_id
= it
->face_id
;
17634 glyph
->u
.cmp_id
= it
->cmp_id
;
17635 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
17636 ++it
->glyph_row
->used
[area
];
17641 /* Change IT->ascent and IT->height according to the setting of
17645 take_vertical_position_into_account (it
)
17650 if (it
->voffset
< 0)
17651 /* Increase the ascent so that we can display the text higher
17653 it
->ascent
+= abs (it
->voffset
);
17655 /* Increase the descent so that we can display the text lower
17657 it
->descent
+= it
->voffset
;
17662 /* Produce glyphs/get display metrics for the image IT is loaded with.
17663 See the description of struct display_iterator in dispextern.h for
17664 an overview of struct display_iterator. */
17667 produce_image_glyph (it
)
17672 int face_ascent
, glyph_ascent
;
17674 xassert (it
->what
== IT_IMAGE
);
17676 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
17677 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
17680 /* Make sure X resources of the face and image are loaded. */
17681 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
17682 prepare_image_for_display (it
->f
, img
);
17684 it
->ascent
= it
->phys_ascent
= glyph_ascent
= image_ascent (img
, face
);
17685 it
->descent
= it
->phys_descent
= img
->height
+ 2 * img
->vmargin
- it
->ascent
;
17686 it
->pixel_width
= img
->width
+ 2 * img
->hmargin
;
17688 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
17689 face_ascent
= face
->font
? FONT_BASE (face
->font
) : FRAME_BASELINE_OFFSET (it
->f
);
17690 if (face_ascent
> it
->ascent
)
17691 it
->ascent
= it
->phys_ascent
= face_ascent
;
17695 if (face
->box
!= FACE_NO_BOX
)
17697 if (face
->box_line_width
> 0)
17699 it
->ascent
+= face
->box_line_width
;
17700 it
->descent
+= face
->box_line_width
;
17703 if (it
->start_of_box_run_p
)
17704 it
->pixel_width
+= abs (face
->box_line_width
);
17705 if (it
->end_of_box_run_p
)
17706 it
->pixel_width
+= abs (face
->box_line_width
);
17709 take_vertical_position_into_account (it
);
17713 struct glyph
*glyph
;
17714 enum glyph_row_area area
= it
->area
;
17716 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
17717 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
17719 glyph
->charpos
= CHARPOS (it
->position
);
17720 glyph
->object
= it
->object
;
17721 glyph
->pixel_width
= it
->pixel_width
;
17722 glyph
->ascent
= glyph_ascent
;
17723 glyph
->descent
= it
->descent
;
17724 glyph
->voffset
= it
->voffset
;
17725 glyph
->type
= IMAGE_GLYPH
;
17726 glyph
->multibyte_p
= it
->multibyte_p
;
17727 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
17728 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
17729 glyph
->overlaps_vertically_p
= 0;
17730 glyph
->padding_p
= 0;
17731 glyph
->glyph_not_available_p
= 0;
17732 glyph
->face_id
= it
->face_id
;
17733 glyph
->u
.img_id
= img
->id
;
17734 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
17735 ++it
->glyph_row
->used
[area
];
17741 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
17742 of the glyph, WIDTH and HEIGHT are the width and height of the
17743 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
17746 append_stretch_glyph (it
, object
, width
, height
, ascent
)
17748 Lisp_Object object
;
17752 struct glyph
*glyph
;
17753 enum glyph_row_area area
= it
->area
;
17755 xassert (ascent
>= 0 && ascent
<= height
);
17757 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
17758 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
17760 glyph
->charpos
= CHARPOS (it
->position
);
17761 glyph
->object
= object
;
17762 glyph
->pixel_width
= width
;
17763 glyph
->ascent
= ascent
;
17764 glyph
->descent
= height
- ascent
;
17765 glyph
->voffset
= it
->voffset
;
17766 glyph
->type
= STRETCH_GLYPH
;
17767 glyph
->multibyte_p
= it
->multibyte_p
;
17768 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
17769 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
17770 glyph
->overlaps_vertically_p
= 0;
17771 glyph
->padding_p
= 0;
17772 glyph
->glyph_not_available_p
= 0;
17773 glyph
->face_id
= it
->face_id
;
17774 glyph
->u
.stretch
.ascent
= ascent
;
17775 glyph
->u
.stretch
.height
= height
;
17776 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
17777 ++it
->glyph_row
->used
[area
];
17782 /* Calculate a width or height in pixels from a specification using
17783 the following elements:
17786 NUM - a (fractional) multiple of the default font width/height
17787 (NUM) - specifies exactly NUM pixels
17788 UNIT - a fixed number of pixels, see below.
17789 ELEMENT - size of a display element in pixels, see below.
17790 (NUM . SPEC) - equals NUM * SPEC
17791 (+ SPEC SPEC ...) - add pixel values
17792 (- SPEC SPEC ...) - subtract pixel values
17793 (- SPEC) - negate pixel value
17796 INT or FLOAT - a number constant
17797 SYMBOL - use symbol's (buffer local) variable binding.
17800 in - pixels per inch *)
17801 mm - pixels per 1/1000 meter *)
17802 cm - pixels per 1/100 meter *)
17803 width - width of current font in pixels.
17804 height - height of current font in pixels.
17806 *) using the ratio(s) defined in display-pixels-per-inch.
17810 left-fringe - left fringe width in pixels
17811 (left-fringe . nil) - left fringe width if inside margins, else 0
17812 (left-fringe . t) - left fringe width if outside margins, else 0
17814 right-fringe - right fringe width in pixels
17815 (right-fringe . nil) - right fringe width if inside margins, else 0
17816 (right-fringe . t) - right fringe width if outside margins, else 0
17818 left-margin - left margin width in pixels
17819 right-margin - right margin width in pixels
17821 scroll-bar - scroll-bar area width in pixels
17822 (scroll-bar . left) - scroll-bar width if on left, else 0
17823 (scroll-bar . right) - scroll-bar width if on right, else 0
17827 Pixels corresponding to 5 inches:
17830 Total width of non-text areas on left side of window:
17831 (+ left-fringe left-margin (scroll-bar . left))
17833 Total width of fringes if inside display margins:
17834 (+ (left-fringe) (right-fringe))
17836 Width of left margin minus width of 1 character in the default font:
17839 Width of left margin minus width of 2 characters in the current font:
17840 (- left-margin (2 . width))
17842 Width of left fringe plus left margin minus one pixel:
17843 (- (+ left-fringe left-margin) (1))
17844 (+ left-fringe left-margin (- (1)))
17845 (+ left-fringe left-margin (-1))
17849 #define NUMVAL(X) \
17850 ((INTEGERP (X) || FLOATP (X)) \
17855 calc_pixel_width_or_height (res
, it
, prop
, font
, width_p
)
17864 #define OK_PIXELS(val) ((*res = (val)), 1)
17866 if (SYMBOLP (prop
))
17868 if (SCHARS (SYMBOL_NAME (prop
)) == 2)
17870 char *unit
= SDATA (SYMBOL_NAME (prop
));
17872 if (unit
[0] == 'i' && unit
[1] == 'n')
17874 else if (unit
[0] == 'm' && unit
[1] == 'm')
17876 else if (unit
[0] == 'c' && unit
[1] == 'm')
17883 if ((ppi
= NUMVAL (Vdisplay_pixels_per_inch
), ppi
> 0)
17884 || (CONSP (Vdisplay_pixels_per_inch
)
17886 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch
))
17887 : NUMVAL (XCDR (Vdisplay_pixels_per_inch
))),
17889 return OK_PIXELS (ppi
/ pixels
);
17895 if (EQ (prop
, Qheight
))
17896 return OK_PIXELS (font
? FONT_HEIGHT (font
) : FRAME_LINE_HEIGHT (it
->f
));
17897 if (EQ (prop
, Qwidth
))
17898 return OK_PIXELS (font
? FONT_WIDTH (font
) : FRAME_COLUMN_WIDTH (it
->f
));
17899 if (EQ (prop
, Qleft_fringe
))
17900 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it
->w
));
17901 if (EQ (prop
, Qright_fringe
))
17902 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it
->w
));
17903 if (EQ (prop
, Qleft_margin
))
17904 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it
->w
));
17905 if (EQ (prop
, Qright_margin
))
17906 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it
->w
));
17907 if (EQ (prop
, Qscroll_bar
))
17908 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it
->w
));
17910 prop
= Fbuffer_local_value (prop
, it
->w
->buffer
);
17913 if (INTEGERP (prop
) || FLOATP (prop
))
17915 int base_unit
= (width_p
17916 ? FRAME_COLUMN_WIDTH (it
->f
)
17917 : FRAME_LINE_HEIGHT (it
->f
));
17918 return OK_PIXELS (XFLOATINT (prop
) * base_unit
);
17923 Lisp_Object car
= XCAR (prop
);
17924 Lisp_Object cdr
= XCDR (prop
);
17928 if (EQ (car
, Qplus
) || EQ (car
, Qminus
))
17934 while (CONSP (cdr
))
17936 if (!calc_pixel_width_or_height (&px
, it
, XCAR (cdr
), font
, width_p
))
17939 pixels
= (EQ (car
, Qplus
) ? px
: -px
), first
= 0;
17944 if (EQ (car
, Qminus
))
17946 return OK_PIXELS (pixels
);
17949 if (EQ (car
, Qleft_fringe
))
17950 return OK_PIXELS ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it
->w
)
17952 ? WINDOW_LEFT_FRINGE_WIDTH (it
->w
)
17954 if (EQ (car
, Qright_fringe
))
17955 return OK_PIXELS ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it
->w
)
17957 ? WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)
17959 if (EQ (car
, Qscroll_bar
))
17960 return OK_PIXELS ((WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it
->w
)
17961 == EQ (cdr
, Qleft
))
17962 ? WINDOW_SCROLL_BAR_AREA_WIDTH (it
->w
)
17965 car
= Fbuffer_local_value (car
, it
->w
->buffer
);
17968 if (INTEGERP (car
) || FLOATP (car
))
17971 pixels
= XFLOATINT (car
);
17973 return OK_PIXELS (pixels
);
17974 if (calc_pixel_width_or_height (&fact
, it
, cdr
, font
, width_p
))
17975 return OK_PIXELS (pixels
* fact
);
17985 /* Produce a stretch glyph for iterator IT. IT->object is the value
17986 of the glyph property displayed. The value must be a list
17987 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
17990 1. `:width WIDTH' specifies that the space should be WIDTH *
17991 canonical char width wide. WIDTH may be an integer or floating
17994 2. `:relative-width FACTOR' specifies that the width of the stretch
17995 should be computed from the width of the first character having the
17996 `glyph' property, and should be FACTOR times that width.
17998 3. `:align-to HPOS' specifies that the space should be wide enough
17999 to reach HPOS, a value in canonical character units.
18001 Exactly one of the above pairs must be present.
18003 4. `:height HEIGHT' specifies that the height of the stretch produced
18004 should be HEIGHT, measured in canonical character units.
18006 5. `:relative-height FACTOR' specifies that the height of the
18007 stretch should be FACTOR times the height of the characters having
18008 the glyph property.
18010 Either none or exactly one of 4 or 5 must be present.
18012 6. `:ascent ASCENT' specifies that ASCENT percent of the height
18013 of the stretch should be used for the ascent of the stretch.
18014 ASCENT must be in the range 0 <= ASCENT <= 100. */
18017 produce_stretch_glyph (it
)
18020 /* (space :width WIDTH :height HEIGHT ...) */
18021 Lisp_Object prop
, plist
;
18022 int width
= 0, height
= 0;
18023 int zero_width_ok_p
= 0, zero_height_ok_p
= 0;
18026 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
18027 XFontStruct
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
18029 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
18031 /* List should start with `space'. */
18032 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
18033 plist
= XCDR (it
->object
);
18035 /* Compute the width of the stretch. */
18036 if ((prop
= Fplist_get (plist
, QCwidth
), !NILP (prop
))
18037 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 1))
18039 /* Absolute width `:width WIDTH' specified and valid. */
18040 zero_width_ok_p
= 1;
18043 else if (prop
= Fplist_get (plist
, QCrelative_width
),
18046 /* Relative width `:relative-width FACTOR' specified and valid.
18047 Compute the width of the characters having the `glyph'
18050 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
18053 if (it
->multibyte_p
)
18055 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT
? ZV
: GPT
)
18056 - IT_BYTEPOS (*it
));
18057 it2
.c
= STRING_CHAR_AND_LENGTH (p
, maxlen
, it2
.len
);
18060 it2
.c
= *p
, it2
.len
= 1;
18062 it2
.glyph_row
= NULL
;
18063 it2
.what
= IT_CHARACTER
;
18064 x_produce_glyphs (&it2
);
18065 width
= NUMVAL (prop
) * it2
.pixel_width
;
18067 else if ((prop
= Fplist_get (plist
, QCalign_to
), !NILP (prop
))
18068 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 1))
18070 width
= max (0, (int)tem
- it
->current_x
);
18071 zero_width_ok_p
= 1;
18074 /* Nothing specified -> width defaults to canonical char width. */
18075 width
= FRAME_COLUMN_WIDTH (it
->f
);
18077 if (width
<= 0 && (width
< 0 || !zero_width_ok_p
))
18080 /* Compute height. */
18081 if ((prop
= Fplist_get (plist
, QCheight
), !NILP (prop
))
18082 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 0))
18085 zero_height_ok_p
= 1;
18087 else if (prop
= Fplist_get (plist
, QCrelative_height
),
18089 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
18091 height
= FONT_HEIGHT (font
);
18093 if (height
<= 0 && (height
< 0 || !zero_height_ok_p
))
18096 /* Compute percentage of height used for ascent. If
18097 `:ascent ASCENT' is present and valid, use that. Otherwise,
18098 derive the ascent from the font in use. */
18099 if (prop
= Fplist_get (plist
, QCascent
),
18100 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
18101 ascent
= height
* NUMVAL (prop
) / 100.0;
18102 else if (!NILP (prop
)
18103 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 0))
18104 ascent
= min (max (0, (int)tem
), height
);
18106 ascent
= (height
* FONT_BASE (font
)) / FONT_HEIGHT (font
);
18108 if (width
> 0 && height
> 0 && it
->glyph_row
)
18110 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
18111 if (!STRINGP (object
))
18112 object
= it
->w
->buffer
;
18113 append_stretch_glyph (it
, object
, width
, height
, ascent
);
18116 it
->pixel_width
= width
;
18117 it
->ascent
= it
->phys_ascent
= ascent
;
18118 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
18119 it
->nglyphs
= width
> 0 && height
> 0 ? 1 : 0;
18121 if (width
> 0 && height
> 0 && face
->box
!= FACE_NO_BOX
)
18123 if (face
->box_line_width
> 0)
18125 it
->ascent
+= face
->box_line_width
;
18126 it
->descent
+= face
->box_line_width
;
18129 if (it
->start_of_box_run_p
)
18130 it
->pixel_width
+= abs (face
->box_line_width
);
18131 if (it
->end_of_box_run_p
)
18132 it
->pixel_width
+= abs (face
->box_line_width
);
18135 take_vertical_position_into_account (it
);
18139 Produce glyphs/get display metrics for the display element IT is
18140 loaded with. See the description of struct display_iterator in
18141 dispextern.h for an overview of struct display_iterator. */
18144 x_produce_glyphs (it
)
18147 it
->glyph_not_available_p
= 0;
18149 if (it
->what
== IT_CHARACTER
)
18153 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
18155 int font_not_found_p
;
18156 struct font_info
*font_info
;
18157 int boff
; /* baseline offset */
18158 /* We may change it->multibyte_p upon unibyte<->multibyte
18159 conversion. So, save the current value now and restore it
18162 Note: It seems that we don't have to record multibyte_p in
18163 struct glyph because the character code itself tells if or
18164 not the character is multibyte. Thus, in the future, we must
18165 consider eliminating the field `multibyte_p' in the struct
18167 int saved_multibyte_p
= it
->multibyte_p
;
18169 /* Maybe translate single-byte characters to multibyte, or the
18171 it
->char_to_display
= it
->c
;
18172 if (!ASCII_BYTE_P (it
->c
))
18174 if (unibyte_display_via_language_environment
18175 && SINGLE_BYTE_CHAR_P (it
->c
)
18177 || !NILP (Vnonascii_translation_table
)))
18179 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
18180 it
->multibyte_p
= 1;
18181 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
18182 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
18184 else if (!SINGLE_BYTE_CHAR_P (it
->c
)
18185 && !it
->multibyte_p
)
18187 it
->multibyte_p
= 1;
18188 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
18189 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
18193 /* Get font to use. Encode IT->char_to_display. */
18194 get_char_face_and_encoding (it
->f
, it
->char_to_display
, it
->face_id
,
18195 &char2b
, it
->multibyte_p
, 0);
18198 /* When no suitable font found, use the default font. */
18199 font_not_found_p
= font
== NULL
;
18200 if (font_not_found_p
)
18202 font
= FRAME_FONT (it
->f
);
18203 boff
= FRAME_BASELINE_OFFSET (it
->f
);
18208 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
18209 boff
= font_info
->baseline_offset
;
18210 if (font_info
->vertical_centering
)
18211 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
18214 if (it
->char_to_display
>= ' '
18215 && (!it
->multibyte_p
|| it
->char_to_display
< 128))
18217 /* Either unibyte or ASCII. */
18222 pcm
= rif
->per_char_metric (font
, &char2b
,
18223 FONT_TYPE_FOR_UNIBYTE (font
, it
->char_to_display
));
18224 it
->ascent
= FONT_BASE (font
) + boff
;
18225 it
->descent
= FONT_DESCENT (font
) - boff
;
18229 it
->phys_ascent
= pcm
->ascent
+ boff
;
18230 it
->phys_descent
= pcm
->descent
- boff
;
18231 it
->pixel_width
= pcm
->width
;
18235 it
->glyph_not_available_p
= 1;
18236 it
->phys_ascent
= FONT_BASE (font
) + boff
;
18237 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
18238 it
->pixel_width
= FONT_WIDTH (font
);
18241 /* If this is a space inside a region of text with
18242 `space-width' property, change its width. */
18243 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
18245 it
->pixel_width
*= XFLOATINT (it
->space_width
);
18247 /* If face has a box, add the box thickness to the character
18248 height. If character has a box line to the left and/or
18249 right, add the box line width to the character's width. */
18250 if (face
->box
!= FACE_NO_BOX
)
18252 int thick
= face
->box_line_width
;
18256 it
->ascent
+= thick
;
18257 it
->descent
+= thick
;
18262 if (it
->start_of_box_run_p
)
18263 it
->pixel_width
+= thick
;
18264 if (it
->end_of_box_run_p
)
18265 it
->pixel_width
+= thick
;
18268 /* If face has an overline, add the height of the overline
18269 (1 pixel) and a 1 pixel margin to the character height. */
18270 if (face
->overline_p
)
18273 take_vertical_position_into_account (it
);
18275 /* If we have to actually produce glyphs, do it. */
18280 /* Translate a space with a `space-width' property
18281 into a stretch glyph. */
18282 int ascent
= (((it
->ascent
+ it
->descent
) * FONT_BASE (font
))
18283 / FONT_HEIGHT (font
));
18284 append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
18285 it
->ascent
+ it
->descent
, ascent
);
18290 /* If characters with lbearing or rbearing are displayed
18291 in this line, record that fact in a flag of the
18292 glyph row. This is used to optimize X output code. */
18293 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
18294 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
18297 else if (it
->char_to_display
== '\n')
18299 /* A newline has no width but we need the height of the line. */
18300 it
->pixel_width
= 0;
18302 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
18303 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
18305 if (face
->box
!= FACE_NO_BOX
18306 && face
->box_line_width
> 0)
18308 it
->ascent
+= face
->box_line_width
;
18309 it
->descent
+= face
->box_line_width
;
18312 else if (it
->char_to_display
== '\t')
18314 int tab_width
= it
->tab_width
* FRAME_COLUMN_WIDTH (it
->f
);
18315 int x
= it
->current_x
+ it
->continuation_lines_width
;
18316 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
18318 /* If the distance from the current position to the next tab
18319 stop is less than a canonical character width, use the
18320 tab stop after that. */
18321 if (next_tab_x
- x
< FRAME_COLUMN_WIDTH (it
->f
))
18322 next_tab_x
+= tab_width
;
18324 it
->pixel_width
= next_tab_x
- x
;
18326 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
18327 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
18331 append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
18332 it
->ascent
+ it
->descent
, it
->ascent
);
18337 /* A multi-byte character. Assume that the display width of the
18338 character is the width of the character multiplied by the
18339 width of the font. */
18341 /* If we found a font, this font should give us the right
18342 metrics. If we didn't find a font, use the frame's
18343 default font and calculate the width of the character
18344 from the charset width; this is what old redisplay code
18347 pcm
= rif
->per_char_metric (font
, &char2b
,
18348 FONT_TYPE_FOR_MULTIBYTE (font
, it
->c
));
18350 if (font_not_found_p
|| !pcm
)
18352 int charset
= CHAR_CHARSET (it
->char_to_display
);
18354 it
->glyph_not_available_p
= 1;
18355 it
->pixel_width
= (FRAME_COLUMN_WIDTH (it
->f
)
18356 * CHARSET_WIDTH (charset
));
18357 it
->phys_ascent
= FONT_BASE (font
) + boff
;
18358 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
18362 it
->pixel_width
= pcm
->width
;
18363 it
->phys_ascent
= pcm
->ascent
+ boff
;
18364 it
->phys_descent
= pcm
->descent
- boff
;
18366 && (pcm
->lbearing
< 0
18367 || pcm
->rbearing
> pcm
->width
))
18368 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
18371 it
->ascent
= FONT_BASE (font
) + boff
;
18372 it
->descent
= FONT_DESCENT (font
) - boff
;
18373 if (face
->box
!= FACE_NO_BOX
)
18375 int thick
= face
->box_line_width
;
18379 it
->ascent
+= thick
;
18380 it
->descent
+= thick
;
18385 if (it
->start_of_box_run_p
)
18386 it
->pixel_width
+= thick
;
18387 if (it
->end_of_box_run_p
)
18388 it
->pixel_width
+= thick
;
18391 /* If face has an overline, add the height of the overline
18392 (1 pixel) and a 1 pixel margin to the character height. */
18393 if (face
->overline_p
)
18396 take_vertical_position_into_account (it
);
18401 it
->multibyte_p
= saved_multibyte_p
;
18403 else if (it
->what
== IT_COMPOSITION
)
18405 /* Note: A composition is represented as one glyph in the
18406 glyph matrix. There are no padding glyphs. */
18409 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
18411 int font_not_found_p
;
18412 struct font_info
*font_info
;
18413 int boff
; /* baseline offset */
18414 struct composition
*cmp
= composition_table
[it
->cmp_id
];
18416 /* Maybe translate single-byte characters to multibyte. */
18417 it
->char_to_display
= it
->c
;
18418 if (unibyte_display_via_language_environment
18419 && SINGLE_BYTE_CHAR_P (it
->c
)
18422 && !NILP (Vnonascii_translation_table
))))
18424 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
18427 /* Get face and font to use. Encode IT->char_to_display. */
18428 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
18429 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
18430 get_char_face_and_encoding (it
->f
, it
->char_to_display
, it
->face_id
,
18431 &char2b
, it
->multibyte_p
, 0);
18434 /* When no suitable font found, use the default font. */
18435 font_not_found_p
= font
== NULL
;
18436 if (font_not_found_p
)
18438 font
= FRAME_FONT (it
->f
);
18439 boff
= FRAME_BASELINE_OFFSET (it
->f
);
18444 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
18445 boff
= font_info
->baseline_offset
;
18446 if (font_info
->vertical_centering
)
18447 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
18450 /* There are no padding glyphs, so there is only one glyph to
18451 produce for the composition. Important is that pixel_width,
18452 ascent and descent are the values of what is drawn by
18453 draw_glyphs (i.e. the values of the overall glyphs composed). */
18456 /* If we have not yet calculated pixel size data of glyphs of
18457 the composition for the current face font, calculate them
18458 now. Theoretically, we have to check all fonts for the
18459 glyphs, but that requires much time and memory space. So,
18460 here we check only the font of the first glyph. This leads
18461 to incorrect display very rarely, and C-l (recenter) can
18462 correct the display anyway. */
18463 if (cmp
->font
!= (void *) font
)
18465 /* Ascent and descent of the font of the first character of
18466 this composition (adjusted by baseline offset). Ascent
18467 and descent of overall glyphs should not be less than
18468 them respectively. */
18469 int font_ascent
= FONT_BASE (font
) + boff
;
18470 int font_descent
= FONT_DESCENT (font
) - boff
;
18471 /* Bounding box of the overall glyphs. */
18472 int leftmost
, rightmost
, lowest
, highest
;
18473 int i
, width
, ascent
, descent
;
18475 cmp
->font
= (void *) font
;
18477 /* Initialize the bounding box. */
18479 && (pcm
= rif
->per_char_metric (font
, &char2b
,
18480 FONT_TYPE_FOR_MULTIBYTE (font
, it
->c
))))
18482 width
= pcm
->width
;
18483 ascent
= pcm
->ascent
;
18484 descent
= pcm
->descent
;
18488 width
= FONT_WIDTH (font
);
18489 ascent
= FONT_BASE (font
);
18490 descent
= FONT_DESCENT (font
);
18494 lowest
= - descent
+ boff
;
18495 highest
= ascent
+ boff
;
18499 && font_info
->default_ascent
18500 && CHAR_TABLE_P (Vuse_default_ascent
)
18501 && !NILP (Faref (Vuse_default_ascent
,
18502 make_number (it
->char_to_display
))))
18503 highest
= font_info
->default_ascent
+ boff
;
18505 /* Draw the first glyph at the normal position. It may be
18506 shifted to right later if some other glyphs are drawn at
18508 cmp
->offsets
[0] = 0;
18509 cmp
->offsets
[1] = boff
;
18511 /* Set cmp->offsets for the remaining glyphs. */
18512 for (i
= 1; i
< cmp
->glyph_len
; i
++)
18514 int left
, right
, btm
, top
;
18515 int ch
= COMPOSITION_GLYPH (cmp
, i
);
18516 int face_id
= FACE_FOR_CHAR (it
->f
, face
, ch
);
18518 face
= FACE_FROM_ID (it
->f
, face_id
);
18519 get_char_face_and_encoding (it
->f
, ch
, face
->id
,
18520 &char2b
, it
->multibyte_p
, 0);
18524 font
= FRAME_FONT (it
->f
);
18525 boff
= FRAME_BASELINE_OFFSET (it
->f
);
18531 = FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
18532 boff
= font_info
->baseline_offset
;
18533 if (font_info
->vertical_centering
)
18534 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
18538 && (pcm
= rif
->per_char_metric (font
, &char2b
,
18539 FONT_TYPE_FOR_MULTIBYTE (font
, ch
))))
18541 width
= pcm
->width
;
18542 ascent
= pcm
->ascent
;
18543 descent
= pcm
->descent
;
18547 width
= FONT_WIDTH (font
);
18552 if (cmp
->method
!= COMPOSITION_WITH_RULE_ALTCHARS
)
18554 /* Relative composition with or without
18555 alternate chars. */
18556 left
= (leftmost
+ rightmost
- width
) / 2;
18557 btm
= - descent
+ boff
;
18558 if (font_info
&& font_info
->relative_compose
18559 && (! CHAR_TABLE_P (Vignore_relative_composition
)
18560 || NILP (Faref (Vignore_relative_composition
,
18561 make_number (ch
)))))
18564 if (- descent
>= font_info
->relative_compose
)
18565 /* One extra pixel between two glyphs. */
18567 else if (ascent
<= 0)
18568 /* One extra pixel between two glyphs. */
18569 btm
= lowest
- 1 - ascent
- descent
;
18574 /* A composition rule is specified by an integer
18575 value that encodes global and new reference
18576 points (GREF and NREF). GREF and NREF are
18577 specified by numbers as below:
18579 0---1---2 -- ascent
18583 9--10--11 -- center
18585 ---3---4---5--- baseline
18587 6---7---8 -- descent
18589 int rule
= COMPOSITION_RULE (cmp
, i
);
18590 int gref
, nref
, grefx
, grefy
, nrefx
, nrefy
;
18592 COMPOSITION_DECODE_RULE (rule
, gref
, nref
);
18593 grefx
= gref
% 3, nrefx
= nref
% 3;
18594 grefy
= gref
/ 3, nrefy
= nref
/ 3;
18597 + grefx
* (rightmost
- leftmost
) / 2
18598 - nrefx
* width
/ 2);
18599 btm
= ((grefy
== 0 ? highest
18601 : grefy
== 2 ? lowest
18602 : (highest
+ lowest
) / 2)
18603 - (nrefy
== 0 ? ascent
+ descent
18604 : nrefy
== 1 ? descent
- boff
18606 : (ascent
+ descent
) / 2));
18609 cmp
->offsets
[i
* 2] = left
;
18610 cmp
->offsets
[i
* 2 + 1] = btm
+ descent
;
18612 /* Update the bounding box of the overall glyphs. */
18613 right
= left
+ width
;
18614 top
= btm
+ descent
+ ascent
;
18615 if (left
< leftmost
)
18617 if (right
> rightmost
)
18625 /* If there are glyphs whose x-offsets are negative,
18626 shift all glyphs to the right and make all x-offsets
18630 for (i
= 0; i
< cmp
->glyph_len
; i
++)
18631 cmp
->offsets
[i
* 2] -= leftmost
;
18632 rightmost
-= leftmost
;
18635 cmp
->pixel_width
= rightmost
;
18636 cmp
->ascent
= highest
;
18637 cmp
->descent
= - lowest
;
18638 if (cmp
->ascent
< font_ascent
)
18639 cmp
->ascent
= font_ascent
;
18640 if (cmp
->descent
< font_descent
)
18641 cmp
->descent
= font_descent
;
18644 it
->pixel_width
= cmp
->pixel_width
;
18645 it
->ascent
= it
->phys_ascent
= cmp
->ascent
;
18646 it
->descent
= it
->phys_descent
= cmp
->descent
;
18648 if (face
->box
!= FACE_NO_BOX
)
18650 int thick
= face
->box_line_width
;
18654 it
->ascent
+= thick
;
18655 it
->descent
+= thick
;
18660 if (it
->start_of_box_run_p
)
18661 it
->pixel_width
+= thick
;
18662 if (it
->end_of_box_run_p
)
18663 it
->pixel_width
+= thick
;
18666 /* If face has an overline, add the height of the overline
18667 (1 pixel) and a 1 pixel margin to the character height. */
18668 if (face
->overline_p
)
18671 take_vertical_position_into_account (it
);
18674 append_composite_glyph (it
);
18676 else if (it
->what
== IT_IMAGE
)
18677 produce_image_glyph (it
);
18678 else if (it
->what
== IT_STRETCH
)
18679 produce_stretch_glyph (it
);
18681 /* Accumulate dimensions. Note: can't assume that it->descent > 0
18682 because this isn't true for images with `:ascent 100'. */
18683 xassert (it
->ascent
>= 0 && it
->descent
>= 0);
18684 if (it
->area
== TEXT_AREA
)
18685 it
->current_x
+= it
->pixel_width
;
18687 it
->descent
+= it
->extra_line_spacing
;
18689 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
18690 it
->max_descent
= max (it
->max_descent
, it
->descent
);
18691 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
18692 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
18696 Output LEN glyphs starting at START at the nominal cursor position.
18697 Advance the nominal cursor over the text. The global variable
18698 updated_window contains the window being updated, updated_row is
18699 the glyph row being updated, and updated_area is the area of that
18700 row being updated. */
18703 x_write_glyphs (start
, len
)
18704 struct glyph
*start
;
18709 xassert (updated_window
&& updated_row
);
18712 /* Write glyphs. */
18714 hpos
= start
- updated_row
->glyphs
[updated_area
];
18715 x
= draw_glyphs (updated_window
, output_cursor
.x
,
18716 updated_row
, updated_area
,
18718 DRAW_NORMAL_TEXT
, 0);
18720 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
18721 if (updated_area
== TEXT_AREA
18722 && updated_window
->phys_cursor_on_p
18723 && updated_window
->phys_cursor
.vpos
== output_cursor
.vpos
18724 && updated_window
->phys_cursor
.hpos
>= hpos
18725 && updated_window
->phys_cursor
.hpos
< hpos
+ len
)
18726 updated_window
->phys_cursor_on_p
= 0;
18730 /* Advance the output cursor. */
18731 output_cursor
.hpos
+= len
;
18732 output_cursor
.x
= x
;
18737 Insert LEN glyphs from START at the nominal cursor position. */
18740 x_insert_glyphs (start
, len
)
18741 struct glyph
*start
;
18746 int line_height
, shift_by_width
, shifted_region_width
;
18747 struct glyph_row
*row
;
18748 struct glyph
*glyph
;
18749 int frame_x
, frame_y
, hpos
;
18751 xassert (updated_window
&& updated_row
);
18753 w
= updated_window
;
18754 f
= XFRAME (WINDOW_FRAME (w
));
18756 /* Get the height of the line we are in. */
18758 line_height
= row
->height
;
18760 /* Get the width of the glyphs to insert. */
18761 shift_by_width
= 0;
18762 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
18763 shift_by_width
+= glyph
->pixel_width
;
18765 /* Get the width of the region to shift right. */
18766 shifted_region_width
= (window_box_width (w
, updated_area
)
18771 frame_x
= window_box_left (w
, updated_area
) + output_cursor
.x
;
18772 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
18774 rif
->shift_glyphs_for_insert (f
, frame_x
, frame_y
, shifted_region_width
,
18775 line_height
, shift_by_width
);
18777 /* Write the glyphs. */
18778 hpos
= start
- row
->glyphs
[updated_area
];
18779 draw_glyphs (w
, output_cursor
.x
, row
, updated_area
,
18781 DRAW_NORMAL_TEXT
, 0);
18783 /* Advance the output cursor. */
18784 output_cursor
.hpos
+= len
;
18785 output_cursor
.x
+= shift_by_width
;
18791 Erase the current text line from the nominal cursor position
18792 (inclusive) to pixel column TO_X (exclusive). The idea is that
18793 everything from TO_X onward is already erased.
18795 TO_X is a pixel position relative to updated_area of
18796 updated_window. TO_X == -1 means clear to the end of this area. */
18799 x_clear_end_of_line (to_x
)
18803 struct window
*w
= updated_window
;
18804 int max_x
, min_y
, max_y
;
18805 int from_x
, from_y
, to_y
;
18807 xassert (updated_window
&& updated_row
);
18808 f
= XFRAME (w
->frame
);
18810 if (updated_row
->full_width_p
)
18811 max_x
= WINDOW_TOTAL_WIDTH (w
);
18813 max_x
= window_box_width (w
, updated_area
);
18814 max_y
= window_text_bottom_y (w
);
18816 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
18817 of window. For TO_X > 0, truncate to end of drawing area. */
18823 to_x
= min (to_x
, max_x
);
18825 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
18827 /* Notice if the cursor will be cleared by this operation. */
18828 if (!updated_row
->full_width_p
)
18829 notice_overwritten_cursor (w
, updated_area
,
18830 output_cursor
.x
, -1,
18832 MATRIX_ROW_BOTTOM_Y (updated_row
));
18834 from_x
= output_cursor
.x
;
18836 /* Translate to frame coordinates. */
18837 if (updated_row
->full_width_p
)
18839 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
18840 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
18844 int area_left
= window_box_left (w
, updated_area
);
18845 from_x
+= area_left
;
18849 min_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
18850 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
18851 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
18853 /* Prevent inadvertently clearing to end of the X window. */
18854 if (to_x
> from_x
&& to_y
> from_y
)
18857 rif
->clear_frame_area (f
, from_x
, from_y
,
18858 to_x
- from_x
, to_y
- from_y
);
18863 #endif /* HAVE_WINDOW_SYSTEM */
18867 /***********************************************************************
18869 ***********************************************************************/
18871 /* Value is the internal representation of the specified cursor type
18872 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
18873 of the bar cursor. */
18875 static enum text_cursor_kinds
18876 get_specified_cursor_type (arg
, width
)
18880 enum text_cursor_kinds type
;
18885 if (EQ (arg
, Qbox
))
18886 return FILLED_BOX_CURSOR
;
18888 if (EQ (arg
, Qhollow
))
18889 return HOLLOW_BOX_CURSOR
;
18891 if (EQ (arg
, Qbar
))
18898 && EQ (XCAR (arg
), Qbar
)
18899 && INTEGERP (XCDR (arg
))
18900 && XINT (XCDR (arg
)) >= 0)
18902 *width
= XINT (XCDR (arg
));
18906 if (EQ (arg
, Qhbar
))
18909 return HBAR_CURSOR
;
18913 && EQ (XCAR (arg
), Qhbar
)
18914 && INTEGERP (XCDR (arg
))
18915 && XINT (XCDR (arg
)) >= 0)
18917 *width
= XINT (XCDR (arg
));
18918 return HBAR_CURSOR
;
18921 /* Treat anything unknown as "hollow box cursor".
18922 It was bad to signal an error; people have trouble fixing
18923 .Xdefaults with Emacs, when it has something bad in it. */
18924 type
= HOLLOW_BOX_CURSOR
;
18929 /* Set the default cursor types for specified frame. */
18931 set_frame_cursor_types (f
, arg
)
18938 FRAME_DESIRED_CURSOR (f
) = get_specified_cursor_type (arg
, &width
);
18939 FRAME_CURSOR_WIDTH (f
) = width
;
18941 /* By default, set up the blink-off state depending on the on-state. */
18943 tem
= Fassoc (arg
, Vblink_cursor_alist
);
18946 FRAME_BLINK_OFF_CURSOR (f
)
18947 = get_specified_cursor_type (XCDR (tem
), &width
);
18948 FRAME_BLINK_OFF_CURSOR_WIDTH (f
) = width
;
18951 FRAME_BLINK_OFF_CURSOR (f
) = DEFAULT_CURSOR
;
18955 /* Return the cursor we want to be displayed in window W. Return
18956 width of bar/hbar cursor through WIDTH arg. Return with
18957 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
18958 (i.e. if the `system caret' should track this cursor).
18960 In a mini-buffer window, we want the cursor only to appear if we
18961 are reading input from this window. For the selected window, we
18962 want the cursor type given by the frame parameter or buffer local
18963 setting of cursor-type. If explicitly marked off, draw no cursor.
18964 In all other cases, we want a hollow box cursor. */
18966 static enum text_cursor_kinds
18967 get_window_cursor_type (w
, glyph
, width
, active_cursor
)
18969 struct glyph
*glyph
;
18971 int *active_cursor
;
18973 struct frame
*f
= XFRAME (w
->frame
);
18974 struct buffer
*b
= XBUFFER (w
->buffer
);
18975 int cursor_type
= DEFAULT_CURSOR
;
18976 Lisp_Object alt_cursor
;
18977 int non_selected
= 0;
18979 *active_cursor
= 1;
18982 if (cursor_in_echo_area
18983 && FRAME_HAS_MINIBUF_P (f
)
18984 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
18986 if (w
== XWINDOW (echo_area_window
))
18988 *width
= FRAME_CURSOR_WIDTH (f
);
18989 return FRAME_DESIRED_CURSOR (f
);
18992 *active_cursor
= 0;
18996 /* Nonselected window or nonselected frame. */
18997 else if (w
!= XWINDOW (f
->selected_window
)
18998 #ifdef HAVE_WINDOW_SYSTEM
18999 || f
!= FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
19003 *active_cursor
= 0;
19005 if (MINI_WINDOW_P (w
) && minibuf_level
== 0)
19011 /* Never display a cursor in a window in which cursor-type is nil. */
19012 if (NILP (b
->cursor_type
))
19015 /* Use cursor-in-non-selected-windows for non-selected window or frame. */
19018 alt_cursor
= Fbuffer_local_value (Qcursor_in_non_selected_windows
, w
->buffer
);
19019 return get_specified_cursor_type (alt_cursor
, width
);
19022 /* Get the normal cursor type for this window. */
19023 if (EQ (b
->cursor_type
, Qt
))
19025 cursor_type
= FRAME_DESIRED_CURSOR (f
);
19026 *width
= FRAME_CURSOR_WIDTH (f
);
19029 cursor_type
= get_specified_cursor_type (b
->cursor_type
, width
);
19031 /* Use normal cursor if not blinked off. */
19032 if (!w
->cursor_off_p
&& glyph
!= NULL
)
19034 if (glyph
->type
== IMAGE_GLYPH
) {
19035 if (cursor_type
== FILLED_BOX_CURSOR
)
19036 cursor_type
= HOLLOW_BOX_CURSOR
;
19038 return cursor_type
;
19041 /* Cursor is blinked off, so determine how to "toggle" it. */
19043 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
19044 if ((alt_cursor
= Fassoc (b
->cursor_type
, Vblink_cursor_alist
), !NILP (alt_cursor
)))
19045 return get_specified_cursor_type (XCDR (alt_cursor
), width
);
19047 /* Then see if frame has specified a specific blink off cursor type. */
19048 if (FRAME_BLINK_OFF_CURSOR (f
) != DEFAULT_CURSOR
)
19050 *width
= FRAME_BLINK_OFF_CURSOR_WIDTH (f
);
19051 return FRAME_BLINK_OFF_CURSOR (f
);
19055 /* Some people liked having a permanently visible blinking cursor,
19056 while others had very strong opinions against it. So it was
19057 decided to remove it. KFS 2003-09-03 */
19059 /* Finally perform built-in cursor blinking:
19060 filled box <-> hollow box
19061 wide [h]bar <-> narrow [h]bar
19062 narrow [h]bar <-> no cursor
19063 other type <-> no cursor */
19065 if (cursor_type
== FILLED_BOX_CURSOR
)
19066 return HOLLOW_BOX_CURSOR
;
19068 if ((cursor_type
== BAR_CURSOR
|| cursor_type
== HBAR_CURSOR
) && *width
> 1)
19071 return cursor_type
;
19079 #ifdef HAVE_WINDOW_SYSTEM
19081 /* Notice when the text cursor of window W has been completely
19082 overwritten by a drawing operation that outputs glyphs in AREA
19083 starting at X0 and ending at X1 in the line starting at Y0 and
19084 ending at Y1. X coordinates are area-relative. X1 < 0 means all
19085 the rest of the line after X0 has been written. Y coordinates
19086 are window-relative. */
19089 notice_overwritten_cursor (w
, area
, x0
, x1
, y0
, y1
)
19091 enum glyph_row_area area
;
19092 int x0
, y0
, x1
, y1
;
19094 int cx0
, cx1
, cy0
, cy1
;
19095 struct glyph_row
*row
;
19097 if (!w
->phys_cursor_on_p
)
19099 if (area
!= TEXT_AREA
)
19102 row
= w
->current_matrix
->rows
+ w
->phys_cursor
.vpos
;
19103 if (!row
->displays_text_p
)
19106 if (row
->cursor_in_fringe_p
)
19108 row
->cursor_in_fringe_p
= 0;
19109 draw_fringe_bitmap (w
, row
, 0);
19110 w
->phys_cursor_on_p
= 0;
19114 cx0
= w
->phys_cursor
.x
;
19115 cx1
= cx0
+ w
->phys_cursor_width
;
19116 if (x0
> cx0
|| (x1
>= 0 && x1
< cx1
))
19119 /* The cursor image will be completely removed from the
19120 screen if the output area intersects the cursor area in
19121 y-direction. When we draw in [y0 y1[, and some part of
19122 the cursor is at y < y0, that part must have been drawn
19123 before. When scrolling, the cursor is erased before
19124 actually scrolling, so we don't come here. When not
19125 scrolling, the rows above the old cursor row must have
19126 changed, and in this case these rows must have written
19127 over the cursor image.
19129 Likewise if part of the cursor is below y1, with the
19130 exception of the cursor being in the first blank row at
19131 the buffer and window end because update_text_area
19132 doesn't draw that row. (Except when it does, but
19133 that's handled in update_text_area.) */
19135 cy0
= w
->phys_cursor
.y
;
19136 cy1
= cy0
+ w
->phys_cursor_height
;
19137 if ((y0
< cy0
|| y0
>= cy1
) && (y1
<= cy0
|| y1
>= cy1
))
19140 w
->phys_cursor_on_p
= 0;
19143 #endif /* HAVE_WINDOW_SYSTEM */
19146 /************************************************************************
19148 ************************************************************************/
19150 #ifdef HAVE_WINDOW_SYSTEM
19153 Fix the display of area AREA of overlapping row ROW in window W. */
19156 x_fix_overlapping_area (w
, row
, area
)
19158 struct glyph_row
*row
;
19159 enum glyph_row_area area
;
19166 for (i
= 0; i
< row
->used
[area
];)
19168 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
19170 int start
= i
, start_x
= x
;
19174 x
+= row
->glyphs
[area
][i
].pixel_width
;
19177 while (i
< row
->used
[area
]
19178 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
19180 draw_glyphs (w
, start_x
, row
, area
,
19182 DRAW_NORMAL_TEXT
, 1);
19186 x
+= row
->glyphs
[area
][i
].pixel_width
;
19196 Draw the cursor glyph of window W in glyph row ROW. See the
19197 comment of draw_glyphs for the meaning of HL. */
19200 draw_phys_cursor_glyph (w
, row
, hl
)
19202 struct glyph_row
*row
;
19203 enum draw_glyphs_face hl
;
19205 /* If cursor hpos is out of bounds, don't draw garbage. This can
19206 happen in mini-buffer windows when switching between echo area
19207 glyphs and mini-buffer. */
19208 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
19210 int on_p
= w
->phys_cursor_on_p
;
19212 x1
= draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
19213 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
19215 w
->phys_cursor_on_p
= on_p
;
19217 if (hl
== DRAW_CURSOR
)
19218 w
->phys_cursor_width
= x1
- w
->phys_cursor
.x
;
19219 /* When we erase the cursor, and ROW is overlapped by other
19220 rows, make sure that these overlapping parts of other rows
19222 else if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
19224 if (row
> w
->current_matrix
->rows
19225 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
19226 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
);
19228 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
19229 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
19230 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
);
19237 Erase the image of a cursor of window W from the screen. */
19240 erase_phys_cursor (w
)
19243 struct frame
*f
= XFRAME (w
->frame
);
19244 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
19245 int hpos
= w
->phys_cursor
.hpos
;
19246 int vpos
= w
->phys_cursor
.vpos
;
19247 int mouse_face_here_p
= 0;
19248 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
19249 struct glyph_row
*cursor_row
;
19250 struct glyph
*cursor_glyph
;
19251 enum draw_glyphs_face hl
;
19253 /* No cursor displayed or row invalidated => nothing to do on the
19255 if (w
->phys_cursor_type
== NO_CURSOR
)
19256 goto mark_cursor_off
;
19258 /* VPOS >= active_glyphs->nrows means that window has been resized.
19259 Don't bother to erase the cursor. */
19260 if (vpos
>= active_glyphs
->nrows
)
19261 goto mark_cursor_off
;
19263 /* If row containing cursor is marked invalid, there is nothing we
19265 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
19266 if (!cursor_row
->enabled_p
)
19267 goto mark_cursor_off
;
19269 /* If row is completely invisible, don't attempt to delete a cursor which
19270 isn't there. This can happen if cursor is at top of a window, and
19271 we switch to a buffer with a header line in that window. */
19272 if (cursor_row
->visible_height
<= 0)
19273 goto mark_cursor_off
;
19275 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
19276 if (cursor_row
->cursor_in_fringe_p
)
19278 cursor_row
->cursor_in_fringe_p
= 0;
19279 draw_fringe_bitmap (w
, cursor_row
, 0);
19280 goto mark_cursor_off
;
19283 /* This can happen when the new row is shorter than the old one.
19284 In this case, either draw_glyphs or clear_end_of_line
19285 should have cleared the cursor. Note that we wouldn't be
19286 able to erase the cursor in this case because we don't have a
19287 cursor glyph at hand. */
19288 if (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])
19289 goto mark_cursor_off
;
19291 /* If the cursor is in the mouse face area, redisplay that when
19292 we clear the cursor. */
19293 if (! NILP (dpyinfo
->mouse_face_window
)
19294 && w
== XWINDOW (dpyinfo
->mouse_face_window
)
19295 && (vpos
> dpyinfo
->mouse_face_beg_row
19296 || (vpos
== dpyinfo
->mouse_face_beg_row
19297 && hpos
>= dpyinfo
->mouse_face_beg_col
))
19298 && (vpos
< dpyinfo
->mouse_face_end_row
19299 || (vpos
== dpyinfo
->mouse_face_end_row
19300 && hpos
< dpyinfo
->mouse_face_end_col
))
19301 /* Don't redraw the cursor's spot in mouse face if it is at the
19302 end of a line (on a newline). The cursor appears there, but
19303 mouse highlighting does not. */
19304 && cursor_row
->used
[TEXT_AREA
] > hpos
)
19305 mouse_face_here_p
= 1;
19307 /* Maybe clear the display under the cursor. */
19308 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
19311 int header_line_height
= WINDOW_HEADER_LINE_HEIGHT (w
);
19313 cursor_glyph
= get_phys_cursor_glyph (w
);
19314 if (cursor_glyph
== NULL
)
19315 goto mark_cursor_off
;
19317 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
19318 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
, cursor_row
->y
));
19320 rif
->clear_frame_area (f
, x
, y
,
19321 cursor_glyph
->pixel_width
, cursor_row
->visible_height
);
19324 /* Erase the cursor by redrawing the character underneath it. */
19325 if (mouse_face_here_p
)
19326 hl
= DRAW_MOUSE_FACE
;
19328 hl
= DRAW_NORMAL_TEXT
;
19329 draw_phys_cursor_glyph (w
, cursor_row
, hl
);
19332 w
->phys_cursor_on_p
= 0;
19333 w
->phys_cursor_type
= NO_CURSOR
;
19338 Display or clear cursor of window W. If ON is zero, clear the
19339 cursor. If it is non-zero, display the cursor. If ON is nonzero,
19340 where to put the cursor is specified by HPOS, VPOS, X and Y. */
19343 display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
)
19345 int on
, hpos
, vpos
, x
, y
;
19347 struct frame
*f
= XFRAME (w
->frame
);
19348 int new_cursor_type
;
19349 int new_cursor_width
;
19351 struct glyph_matrix
*current_glyphs
;
19352 struct glyph_row
*glyph_row
;
19353 struct glyph
*glyph
;
19355 /* This is pointless on invisible frames, and dangerous on garbaged
19356 windows and frames; in the latter case, the frame or window may
19357 be in the midst of changing its size, and x and y may be off the
19359 if (! FRAME_VISIBLE_P (f
)
19360 || FRAME_GARBAGED_P (f
)
19361 || vpos
>= w
->current_matrix
->nrows
19362 || hpos
>= w
->current_matrix
->matrix_w
)
19365 /* If cursor is off and we want it off, return quickly. */
19366 if (!on
&& !w
->phys_cursor_on_p
)
19369 current_glyphs
= w
->current_matrix
;
19370 glyph_row
= MATRIX_ROW (current_glyphs
, vpos
);
19371 glyph
= (glyph_row
->cursor_in_fringe_p
? NULL
19372 : glyph_row
->glyphs
[TEXT_AREA
] + hpos
);
19374 /* If cursor row is not enabled, we don't really know where to
19375 display the cursor. */
19376 if (!glyph_row
->enabled_p
)
19378 w
->phys_cursor_on_p
= 0;
19382 xassert (interrupt_input_blocked
);
19384 /* Set new_cursor_type to the cursor we want to be displayed. */
19385 new_cursor_type
= get_window_cursor_type (w
, glyph
,
19386 &new_cursor_width
, &active_cursor
);
19388 /* If cursor is currently being shown and we don't want it to be or
19389 it is in the wrong place, or the cursor type is not what we want,
19391 if (w
->phys_cursor_on_p
19393 || w
->phys_cursor
.x
!= x
19394 || w
->phys_cursor
.y
!= y
19395 || new_cursor_type
!= w
->phys_cursor_type
19396 || ((new_cursor_type
== BAR_CURSOR
|| new_cursor_type
== HBAR_CURSOR
)
19397 && new_cursor_width
!= w
->phys_cursor_width
)))
19398 erase_phys_cursor (w
);
19400 /* Don't check phys_cursor_on_p here because that flag is only set
19401 to zero in some cases where we know that the cursor has been
19402 completely erased, to avoid the extra work of erasing the cursor
19403 twice. In other words, phys_cursor_on_p can be 1 and the cursor
19404 still not be visible, or it has only been partly erased. */
19407 w
->phys_cursor_ascent
= glyph_row
->ascent
;
19408 w
->phys_cursor_height
= glyph_row
->height
;
19410 /* Set phys_cursor_.* before x_draw_.* is called because some
19411 of them may need the information. */
19412 w
->phys_cursor
.x
= x
;
19413 w
->phys_cursor
.y
= glyph_row
->y
;
19414 w
->phys_cursor
.hpos
= hpos
;
19415 w
->phys_cursor
.vpos
= vpos
;
19418 rif
->draw_window_cursor (w
, glyph_row
, x
, y
,
19419 new_cursor_type
, new_cursor_width
,
19420 on
, active_cursor
);
19424 /* Switch the display of W's cursor on or off, according to the value
19428 update_window_cursor (w
, on
)
19432 /* Don't update cursor in windows whose frame is in the process
19433 of being deleted. */
19434 if (w
->current_matrix
)
19437 display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
19438 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
19444 /* Call update_window_cursor with parameter ON_P on all leaf windows
19445 in the window tree rooted at W. */
19448 update_cursor_in_window_tree (w
, on_p
)
19454 if (!NILP (w
->hchild
))
19455 update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
19456 else if (!NILP (w
->vchild
))
19457 update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
19459 update_window_cursor (w
, on_p
);
19461 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
19467 Display the cursor on window W, or clear it, according to ON_P.
19468 Don't change the cursor's position. */
19471 x_update_cursor (f
, on_p
)
19475 update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
19480 Clear the cursor of window W to background color, and mark the
19481 cursor as not shown. This is used when the text where the cursor
19482 is is about to be rewritten. */
19488 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
19489 update_window_cursor (w
, 0);
19494 Display the active region described by mouse_face_* according to DRAW. */
19497 show_mouse_face (dpyinfo
, draw
)
19498 Display_Info
*dpyinfo
;
19499 enum draw_glyphs_face draw
;
19501 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
19502 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
19504 if (/* If window is in the process of being destroyed, don't bother
19506 w
->current_matrix
!= NULL
19507 /* Don't update mouse highlight if hidden */
19508 && (draw
!= DRAW_MOUSE_FACE
|| !dpyinfo
->mouse_face_hidden
)
19509 /* Recognize when we are called to operate on rows that don't exist
19510 anymore. This can happen when a window is split. */
19511 && dpyinfo
->mouse_face_end_row
< w
->current_matrix
->nrows
)
19513 int phys_cursor_on_p
= w
->phys_cursor_on_p
;
19514 struct glyph_row
*row
, *first
, *last
;
19516 first
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_beg_row
);
19517 last
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_end_row
);
19519 for (row
= first
; row
<= last
&& row
->enabled_p
; ++row
)
19521 int start_hpos
, end_hpos
, start_x
;
19523 /* For all but the first row, the highlight starts at column 0. */
19526 start_hpos
= dpyinfo
->mouse_face_beg_col
;
19527 start_x
= dpyinfo
->mouse_face_beg_x
;
19536 end_hpos
= dpyinfo
->mouse_face_end_col
;
19538 end_hpos
= row
->used
[TEXT_AREA
];
19540 if (end_hpos
> start_hpos
)
19542 draw_glyphs (w
, start_x
, row
, TEXT_AREA
,
19543 start_hpos
, end_hpos
,
19547 = draw
== DRAW_MOUSE_FACE
|| draw
== DRAW_IMAGE_RAISED
;
19551 /* When we've written over the cursor, arrange for it to
19552 be displayed again. */
19553 if (phys_cursor_on_p
&& !w
->phys_cursor_on_p
)
19556 display_and_set_cursor (w
, 1,
19557 w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
19558 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
19563 /* Change the mouse cursor. */
19564 if (draw
== DRAW_NORMAL_TEXT
)
19565 rif
->define_frame_cursor (f
, FRAME_X_OUTPUT (f
)->text_cursor
);
19566 else if (draw
== DRAW_MOUSE_FACE
)
19567 rif
->define_frame_cursor (f
, FRAME_X_OUTPUT (f
)->hand_cursor
);
19569 rif
->define_frame_cursor (f
, FRAME_X_OUTPUT (f
)->nontext_cursor
);
19573 Clear out the mouse-highlighted active region.
19574 Redraw it un-highlighted first. Value is non-zero if mouse
19575 face was actually drawn unhighlighted. */
19578 clear_mouse_face (dpyinfo
)
19579 Display_Info
*dpyinfo
;
19583 if (!NILP (dpyinfo
->mouse_face_window
))
19585 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
19589 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
19590 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
19591 dpyinfo
->mouse_face_window
= Qnil
;
19592 dpyinfo
->mouse_face_overlay
= Qnil
;
19598 Non-zero if physical cursor of window W is within mouse face. */
19601 cursor_in_mouse_face_p (w
)
19604 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (XFRAME (w
->frame
));
19605 int in_mouse_face
= 0;
19607 if (WINDOWP (dpyinfo
->mouse_face_window
)
19608 && XWINDOW (dpyinfo
->mouse_face_window
) == w
)
19610 int hpos
= w
->phys_cursor
.hpos
;
19611 int vpos
= w
->phys_cursor
.vpos
;
19613 if (vpos
>= dpyinfo
->mouse_face_beg_row
19614 && vpos
<= dpyinfo
->mouse_face_end_row
19615 && (vpos
> dpyinfo
->mouse_face_beg_row
19616 || hpos
>= dpyinfo
->mouse_face_beg_col
)
19617 && (vpos
< dpyinfo
->mouse_face_end_row
19618 || hpos
< dpyinfo
->mouse_face_end_col
19619 || dpyinfo
->mouse_face_past_end
))
19623 return in_mouse_face
;
19629 /* Find the glyph matrix position of buffer position CHARPOS in window
19630 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
19631 current glyphs must be up to date. If CHARPOS is above window
19632 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
19633 of last line in W. In the row containing CHARPOS, stop before glyphs
19634 having STOP as object. */
19636 #if 1 /* This is a version of fast_find_position that's more correct
19637 in the presence of hscrolling, for example. I didn't install
19638 it right away because the problem fixed is minor, it failed
19639 in 20.x as well, and I think it's too risky to install
19640 so near the release of 21.1. 2001-09-25 gerd. */
19643 fast_find_position (w
, charpos
, hpos
, vpos
, x
, y
, stop
)
19646 int *hpos
, *vpos
, *x
, *y
;
19649 struct glyph_row
*row
, *first
;
19650 struct glyph
*glyph
, *end
;
19653 first
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
19654 row
= row_containing_pos (w
, charpos
, first
, NULL
, 0);
19657 if (charpos
< MATRIX_ROW_START_CHARPOS (first
))
19659 *x
= *y
= *hpos
= *vpos
= 0;
19664 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
19671 *vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
19673 glyph
= row
->glyphs
[TEXT_AREA
];
19674 end
= glyph
+ row
->used
[TEXT_AREA
];
19676 /* Skip over glyphs not having an object at the start of the row.
19677 These are special glyphs like truncation marks on terminal
19679 if (row
->displays_text_p
)
19681 && INTEGERP (glyph
->object
)
19682 && !EQ (stop
, glyph
->object
)
19683 && glyph
->charpos
< 0)
19685 *x
+= glyph
->pixel_width
;
19690 && !INTEGERP (glyph
->object
)
19691 && !EQ (stop
, glyph
->object
)
19692 && (!BUFFERP (glyph
->object
)
19693 || glyph
->charpos
< charpos
))
19695 *x
+= glyph
->pixel_width
;
19699 *hpos
= glyph
- row
->glyphs
[TEXT_AREA
];
19706 fast_find_position (w
, pos
, hpos
, vpos
, x
, y
, stop
)
19709 int *hpos
, *vpos
, *x
, *y
;
19714 int maybe_next_line_p
= 0;
19715 int line_start_position
;
19716 int yb
= window_text_bottom_y (w
);
19717 struct glyph_row
*row
, *best_row
;
19718 int row_vpos
, best_row_vpos
;
19721 row
= best_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
19722 row_vpos
= best_row_vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
19724 while (row
->y
< yb
)
19726 if (row
->used
[TEXT_AREA
])
19727 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
19729 line_start_position
= 0;
19731 if (line_start_position
> pos
)
19733 /* If the position sought is the end of the buffer,
19734 don't include the blank lines at the bottom of the window. */
19735 else if (line_start_position
== pos
19736 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
19738 maybe_next_line_p
= 1;
19741 else if (line_start_position
> 0)
19744 best_row_vpos
= row_vpos
;
19747 if (row
->y
+ row
->height
>= yb
)
19754 /* Find the right column within BEST_ROW. */
19756 current_x
= best_row
->x
;
19757 for (i
= 0; i
< best_row
->used
[TEXT_AREA
]; i
++)
19759 struct glyph
*glyph
= best_row
->glyphs
[TEXT_AREA
] + i
;
19760 int charpos
= glyph
->charpos
;
19762 if (BUFFERP (glyph
->object
))
19764 if (charpos
== pos
)
19767 *vpos
= best_row_vpos
;
19772 else if (charpos
> pos
)
19775 else if (EQ (glyph
->object
, stop
))
19780 current_x
+= glyph
->pixel_width
;
19783 /* If we're looking for the end of the buffer,
19784 and we didn't find it in the line we scanned,
19785 use the start of the following line. */
19786 if (maybe_next_line_p
)
19791 current_x
= best_row
->x
;
19794 *vpos
= best_row_vpos
;
19795 *hpos
= lastcol
+ 1;
19804 /* Find the position of the glyph for position POS in OBJECT in
19805 window W's current matrix, and return in *X, *Y the pixel
19806 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
19808 RIGHT_P non-zero means return the position of the right edge of the
19809 glyph, RIGHT_P zero means return the left edge position.
19811 If no glyph for POS exists in the matrix, return the position of
19812 the glyph with the next smaller position that is in the matrix, if
19813 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
19814 exists in the matrix, return the position of the glyph with the
19815 next larger position in OBJECT.
19817 Value is non-zero if a glyph was found. */
19820 fast_find_string_pos (w
, pos
, object
, hpos
, vpos
, x
, y
, right_p
)
19823 Lisp_Object object
;
19824 int *hpos
, *vpos
, *x
, *y
;
19827 int yb
= window_text_bottom_y (w
);
19828 struct glyph_row
*r
;
19829 struct glyph
*best_glyph
= NULL
;
19830 struct glyph_row
*best_row
= NULL
;
19833 for (r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
19834 r
->enabled_p
&& r
->y
< yb
;
19837 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
19838 struct glyph
*e
= g
+ r
->used
[TEXT_AREA
];
19841 for (gx
= r
->x
; g
< e
; gx
+= g
->pixel_width
, ++g
)
19842 if (EQ (g
->object
, object
))
19844 if (g
->charpos
== pos
)
19851 else if (best_glyph
== NULL
19852 || ((abs (g
->charpos
- pos
)
19853 < abs (best_glyph
->charpos
- pos
))
19856 : g
->charpos
> pos
)))
19870 *hpos
= best_glyph
- best_row
->glyphs
[TEXT_AREA
];
19874 *x
+= best_glyph
->pixel_width
;
19879 *vpos
= best_row
- w
->current_matrix
->rows
;
19882 return best_glyph
!= NULL
;
19886 /* See if position X, Y is within a hot-spot of an image. */
19889 on_hot_spot_p (hot_spot
, x
, y
)
19890 Lisp_Object hot_spot
;
19893 if (!CONSP (hot_spot
))
19896 if (EQ (XCAR (hot_spot
), Qrect
))
19898 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
19899 Lisp_Object rect
= XCDR (hot_spot
);
19903 if (!CONSP (XCAR (rect
)))
19905 if (!CONSP (XCDR (rect
)))
19907 if (!(tem
= XCAR (XCAR (rect
)), INTEGERP (tem
) && x
>= XINT (tem
)))
19909 if (!(tem
= XCDR (XCAR (rect
)), INTEGERP (tem
) && y
>= XINT (tem
)))
19911 if (!(tem
= XCAR (XCDR (rect
)), INTEGERP (tem
) && x
<= XINT (tem
)))
19913 if (!(tem
= XCDR (XCDR (rect
)), INTEGERP (tem
) && y
<= XINT (tem
)))
19917 else if (EQ (XCAR (hot_spot
), Qcircle
))
19919 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
19920 Lisp_Object circ
= XCDR (hot_spot
);
19921 Lisp_Object lr
, lx0
, ly0
;
19923 && CONSP (XCAR (circ
))
19924 && (lr
= XCDR (circ
), INTEGERP (lr
) || FLOATP (lr
))
19925 && (lx0
= XCAR (XCAR (circ
)), INTEGERP (lx0
))
19926 && (ly0
= XCDR (XCAR (circ
)), INTEGERP (ly0
)))
19928 double r
= XFLOATINT (lr
);
19929 double dx
= XINT (lx0
) - x
;
19930 double dy
= XINT (ly0
) - y
;
19931 return (dx
* dx
+ dy
* dy
<= r
* r
);
19934 else if (EQ (XCAR (hot_spot
), Qpoly
))
19936 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
19937 if (VECTORP (XCDR (hot_spot
)))
19939 struct Lisp_Vector
*v
= XVECTOR (XCDR (hot_spot
));
19940 Lisp_Object
*poly
= v
->contents
;
19944 Lisp_Object lx
, ly
;
19947 /* Need an even number of coordinates, and at least 3 edges. */
19948 if (n
< 6 || n
& 1)
19951 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
19952 If count is odd, we are inside polygon. Pixels on edges
19953 may or may not be included depending on actual geometry of the
19955 if ((lx
= poly
[n
-2], !INTEGERP (lx
))
19956 || (ly
= poly
[n
-1], !INTEGERP (lx
)))
19958 x0
= XINT (lx
), y0
= XINT (ly
);
19959 for (i
= 0; i
< n
; i
+= 2)
19961 int x1
= x0
, y1
= y0
;
19962 if ((lx
= poly
[i
], !INTEGERP (lx
))
19963 || (ly
= poly
[i
+1], !INTEGERP (ly
)))
19965 x0
= XINT (lx
), y0
= XINT (ly
);
19967 /* Does this segment cross the X line? */
19975 if (y
> y0
&& y
> y1
)
19977 if (y
< y0
+ ((y1
- y0
) * (x
- x0
)) / (x1
- x0
))
19988 find_hot_spot (map
, x
, y
)
19992 while (CONSP (map
))
19994 if (CONSP (XCAR (map
))
19995 && on_hot_spot_p (XCAR (XCAR (map
)), x
, y
))
20003 DEFUN ("lookup-image-map", Flookup_image_map
, Slookup_image_map
,
20005 doc
: /* Lookup in image map MAP coordinates X and Y.
20006 An image map is an alist where each element has the format (AREA ID PLIST).
20007 An AREA is specified as either a rectangle, a circle, or a polygon:
20008 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
20009 pixel coordinates of the upper left and bottom right corners.
20010 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
20011 and the radius of the circle; r may be a float or integer.
20012 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
20013 vector describes one corner in the polygon.
20014 Returns the alist element for the first matching AREA in MAP. */)
20026 return find_hot_spot (map
, XINT (x
), XINT (y
));
20030 /* Display frame CURSOR, optionally using shape defined by POINTER. */
20032 define_frame_cursor1 (f
, cursor
, pointer
)
20035 Lisp_Object pointer
;
20037 if (!NILP (pointer
))
20039 if (EQ (pointer
, Qarrow
))
20040 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
20041 else if (EQ (pointer
, Qhand
))
20042 cursor
= FRAME_X_OUTPUT (f
)->hand_cursor
;
20043 else if (EQ (pointer
, Qtext
))
20044 cursor
= FRAME_X_OUTPUT (f
)->text_cursor
;
20045 else if (EQ (pointer
, intern ("hdrag")))
20046 cursor
= FRAME_X_OUTPUT (f
)->horizontal_drag_cursor
;
20047 #ifdef HAVE_X_WINDOWS
20048 else if (EQ (pointer
, intern ("vdrag")))
20049 cursor
= FRAME_X_DISPLAY_INFO (f
)->vertical_scroll_bar_cursor
;
20051 else if (EQ (pointer
, intern ("hourglass")))
20052 cursor
= FRAME_X_OUTPUT (f
)->hourglass_cursor
;
20053 else if (EQ (pointer
, Qmodeline
))
20054 cursor
= FRAME_X_OUTPUT (f
)->modeline_cursor
;
20056 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
20059 #ifndef HAVE_CARBON
20060 if (cursor
!= No_Cursor
)
20062 if (bcmp (&cursor
, &No_Cursor
, sizeof (Cursor
)))
20064 rif
->define_frame_cursor (f
, cursor
);
20067 /* Take proper action when mouse has moved to the mode or header line
20068 or marginal area AREA of window W, x-position X and y-position Y.
20069 X is relative to the start of the text display area of W, so the
20070 width of bitmap areas and scroll bars must be subtracted to get a
20071 position relative to the start of the mode line. */
20074 note_mode_line_or_margin_highlight (w
, x
, y
, area
)
20077 enum window_part area
;
20079 struct frame
*f
= XFRAME (w
->frame
);
20080 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
20081 Cursor cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
20082 Lisp_Object pointer
= Qnil
;
20083 int charpos
, dx
, dy
, width
, height
;
20084 Lisp_Object string
, object
= Qnil
;
20085 Lisp_Object pos
, help
, image
;
20087 if (area
== ON_MODE_LINE
|| area
== ON_HEADER_LINE
)
20088 string
= mode_line_string (w
, area
, &x
, &y
, &charpos
,
20089 &object
, &dx
, &dy
, &width
, &height
);
20092 x
-= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w
);
20093 string
= marginal_area_string (w
, area
, &x
, &y
, &charpos
,
20094 &object
, &dx
, &dy
, &width
, &height
);
20099 if (IMAGEP (object
))
20101 Lisp_Object image_map
, hotspot
;
20102 if ((image_map
= Fplist_get (XCDR (object
), QCmap
),
20104 && (hotspot
= find_hot_spot (image_map
, dx
, dy
),
20106 && (hotspot
= XCDR (hotspot
), CONSP (hotspot
)))
20108 Lisp_Object area_id
, plist
;
20110 area_id
= XCAR (hotspot
);
20111 /* Could check AREA_ID to see if we enter/leave this hot-spot.
20112 If so, we could look for mouse-enter, mouse-leave
20113 properties in PLIST (and do something...). */
20114 if ((plist
= XCDR (hotspot
), CONSP (plist
)))
20116 pointer
= Fplist_get (plist
, Qpointer
);
20117 if (NILP (pointer
))
20119 help
= Fplist_get (plist
, Qhelp_echo
);
20122 help_echo_string
= help
;
20123 /* Is this correct? ++kfs */
20124 XSETWINDOW (help_echo_window
, w
);
20125 help_echo_object
= w
->buffer
;
20126 help_echo_pos
= charpos
;
20129 if (NILP (pointer
))
20130 pointer
= Fplist_get (XCDR (object
), QCpointer
);
20134 if (STRINGP (string
))
20136 pos
= make_number (charpos
);
20137 /* If we're on a string with `help-echo' text property, arrange
20138 for the help to be displayed. This is done by setting the
20139 global variable help_echo_string to the help string. */
20140 help
= Fget_text_property (pos
, Qhelp_echo
, string
);
20143 help_echo_string
= help
;
20144 XSETWINDOW (help_echo_window
, w
);
20145 help_echo_object
= string
;
20146 help_echo_pos
= charpos
;
20149 if (NILP (pointer
))
20150 pointer
= Fget_text_property (pos
, Qpointer
, string
);
20152 /* Change the mouse pointer according to what is under X/Y. */
20153 if (NILP (pointer
) && area
== ON_MODE_LINE
)
20156 map
= Fget_text_property (pos
, Qlocal_map
, string
);
20157 if (!KEYMAPP (map
))
20158 map
= Fget_text_property (pos
, Qkeymap
, string
);
20159 if (!KEYMAPP (map
))
20160 cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
20164 define_frame_cursor1 (f
, cursor
, pointer
);
20169 Take proper action when the mouse has moved to position X, Y on
20170 frame F as regards highlighting characters that have mouse-face
20171 properties. Also de-highlighting chars where the mouse was before.
20172 X and Y can be negative or out of range. */
20175 note_mouse_highlight (f
, x
, y
)
20179 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
20180 enum window_part part
;
20181 Lisp_Object window
;
20183 Cursor cursor
= No_Cursor
;
20184 Lisp_Object pointer
= Qnil
; /* Takes precedence over cursor! */
20187 /* When a menu is active, don't highlight because this looks odd. */
20188 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
20189 if (popup_activated ())
20193 if (NILP (Vmouse_highlight
)
20194 || !f
->glyphs_initialized_p
)
20197 dpyinfo
->mouse_face_mouse_x
= x
;
20198 dpyinfo
->mouse_face_mouse_y
= y
;
20199 dpyinfo
->mouse_face_mouse_frame
= f
;
20201 if (dpyinfo
->mouse_face_defer
)
20204 if (gc_in_progress
)
20206 dpyinfo
->mouse_face_deferred_gc
= 1;
20210 /* Which window is that in? */
20211 window
= window_from_coordinates (f
, x
, y
, &part
, 0, 0, 1);
20213 /* If we were displaying active text in another window, clear that. */
20214 if (! EQ (window
, dpyinfo
->mouse_face_window
))
20215 clear_mouse_face (dpyinfo
);
20217 /* Not on a window -> return. */
20218 if (!WINDOWP (window
))
20221 /* Reset help_echo_string. It will get recomputed below. */
20222 help_echo_string
= Qnil
;
20224 /* Convert to window-relative pixel coordinates. */
20225 w
= XWINDOW (window
);
20226 frame_to_window_pixel_xy (w
, &x
, &y
);
20228 /* Handle tool-bar window differently since it doesn't display a
20230 if (EQ (window
, f
->tool_bar_window
))
20232 note_tool_bar_highlight (f
, x
, y
);
20236 /* Mouse is on the mode, header line or margin? */
20237 if (part
== ON_MODE_LINE
|| part
== ON_HEADER_LINE
20238 || part
== ON_LEFT_MARGIN
|| part
== ON_RIGHT_MARGIN
)
20240 note_mode_line_or_margin_highlight (w
, x
, y
, part
);
20244 if (part
== ON_VERTICAL_BORDER
)
20245 cursor
= FRAME_X_OUTPUT (f
)->horizontal_drag_cursor
;
20246 else if (part
== ON_LEFT_FRINGE
|| part
== ON_RIGHT_FRINGE
)
20247 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
20249 cursor
= FRAME_X_OUTPUT (f
)->text_cursor
;
20251 /* Are we in a window whose display is up to date?
20252 And verify the buffer's text has not changed. */
20253 b
= XBUFFER (w
->buffer
);
20254 if (part
== ON_TEXT
20255 && EQ (w
->window_end_valid
, w
->buffer
)
20256 && XFASTINT (w
->last_modified
) == BUF_MODIFF (b
)
20257 && XFASTINT (w
->last_overlay_modified
) == BUF_OVERLAY_MODIFF (b
))
20259 int hpos
, vpos
, pos
, i
, dx
, dy
, area
;
20260 struct glyph
*glyph
;
20261 Lisp_Object object
;
20262 Lisp_Object mouse_face
= Qnil
, overlay
= Qnil
, position
;
20263 Lisp_Object
*overlay_vec
= NULL
;
20264 int len
, noverlays
;
20265 struct buffer
*obuf
;
20266 int obegv
, ozv
, same_region
;
20268 /* Find the glyph under X/Y. */
20269 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &dx
, &dy
, &area
);
20271 /* Look for :pointer property on image. */
20272 if (glyph
!= NULL
&& glyph
->type
== IMAGE_GLYPH
)
20274 struct image
*img
= IMAGE_FROM_ID (f
, glyph
->u
.img_id
);
20275 if (img
!= NULL
&& IMAGEP (img
->spec
))
20277 Lisp_Object image_map
, hotspot
;
20278 if ((image_map
= Fplist_get (XCDR (img
->spec
), QCmap
),
20280 && (hotspot
= find_hot_spot (image_map
, dx
, dy
),
20282 && (hotspot
= XCDR (hotspot
), CONSP (hotspot
)))
20284 Lisp_Object area_id
, plist
;
20286 area_id
= XCAR (hotspot
);
20287 /* Could check AREA_ID to see if we enter/leave this hot-spot.
20288 If so, we could look for mouse-enter, mouse-leave
20289 properties in PLIST (and do something...). */
20290 if ((plist
= XCDR (hotspot
), CONSP (plist
)))
20292 pointer
= Fplist_get (plist
, Qpointer
);
20293 if (NILP (pointer
))
20295 help_echo_string
= Fplist_get (plist
, Qhelp_echo
);
20296 if (!NILP (help_echo_string
))
20298 help_echo_window
= window
;
20299 help_echo_object
= glyph
->object
;
20300 help_echo_pos
= glyph
->charpos
;
20304 if (NILP (pointer
))
20305 pointer
= Fplist_get (XCDR (img
->spec
), QCpointer
);
20309 /* Clear mouse face if X/Y not over text. */
20311 || area
!= TEXT_AREA
20312 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
)
20314 if (clear_mouse_face (dpyinfo
))
20315 cursor
= No_Cursor
;
20316 if (NILP (pointer
))
20318 if (area
!= TEXT_AREA
)
20319 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
20321 pointer
= Vvoid_text_area_pointer
;
20326 pos
= glyph
->charpos
;
20327 object
= glyph
->object
;
20328 if (!STRINGP (object
) && !BUFFERP (object
))
20331 /* If we get an out-of-range value, return now; avoid an error. */
20332 if (BUFFERP (object
) && pos
> BUF_Z (b
))
20335 /* Make the window's buffer temporarily current for
20336 overlays_at and compute_char_face. */
20337 obuf
= current_buffer
;
20338 current_buffer
= b
;
20344 /* Is this char mouse-active or does it have help-echo? */
20345 position
= make_number (pos
);
20347 if (BUFFERP (object
))
20349 /* Put all the overlays we want in a vector in overlay_vec.
20350 Store the length in len. If there are more than 10, make
20351 enough space for all, and try again. */
20353 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
20354 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
, 0);
20355 if (noverlays
> len
)
20358 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
20359 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
,0);
20362 /* Sort overlays into increasing priority order. */
20363 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
20368 same_region
= (EQ (window
, dpyinfo
->mouse_face_window
)
20369 && vpos
>= dpyinfo
->mouse_face_beg_row
20370 && vpos
<= dpyinfo
->mouse_face_end_row
20371 && (vpos
> dpyinfo
->mouse_face_beg_row
20372 || hpos
>= dpyinfo
->mouse_face_beg_col
)
20373 && (vpos
< dpyinfo
->mouse_face_end_row
20374 || hpos
< dpyinfo
->mouse_face_end_col
20375 || dpyinfo
->mouse_face_past_end
));
20378 cursor
= No_Cursor
;
20380 /* Check mouse-face highlighting. */
20382 /* If there exists an overlay with mouse-face overlapping
20383 the one we are currently highlighting, we have to
20384 check if we enter the overlapping overlay, and then
20385 highlight only that. */
20386 || (OVERLAYP (dpyinfo
->mouse_face_overlay
)
20387 && mouse_face_overlay_overlaps (dpyinfo
->mouse_face_overlay
)))
20389 /* Find the highest priority overlay that has a mouse-face
20392 for (i
= noverlays
- 1; i
>= 0 && NILP (overlay
); --i
)
20394 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
20395 if (!NILP (mouse_face
))
20396 overlay
= overlay_vec
[i
];
20399 /* If we're actually highlighting the same overlay as
20400 before, there's no need to do that again. */
20401 if (!NILP (overlay
)
20402 && EQ (overlay
, dpyinfo
->mouse_face_overlay
))
20403 goto check_help_echo
;
20405 dpyinfo
->mouse_face_overlay
= overlay
;
20407 /* Clear the display of the old active region, if any. */
20408 if (clear_mouse_face (dpyinfo
))
20409 cursor
= No_Cursor
;
20411 /* If no overlay applies, get a text property. */
20412 if (NILP (overlay
))
20413 mouse_face
= Fget_text_property (position
, Qmouse_face
, object
);
20415 /* Handle the overlay case. */
20416 if (!NILP (overlay
))
20418 /* Find the range of text around this char that
20419 should be active. */
20420 Lisp_Object before
, after
;
20423 before
= Foverlay_start (overlay
);
20424 after
= Foverlay_end (overlay
);
20425 /* Record this as the current active region. */
20426 fast_find_position (w
, XFASTINT (before
),
20427 &dpyinfo
->mouse_face_beg_col
,
20428 &dpyinfo
->mouse_face_beg_row
,
20429 &dpyinfo
->mouse_face_beg_x
,
20430 &dpyinfo
->mouse_face_beg_y
, Qnil
);
20432 dpyinfo
->mouse_face_past_end
20433 = !fast_find_position (w
, XFASTINT (after
),
20434 &dpyinfo
->mouse_face_end_col
,
20435 &dpyinfo
->mouse_face_end_row
,
20436 &dpyinfo
->mouse_face_end_x
,
20437 &dpyinfo
->mouse_face_end_y
, Qnil
);
20438 dpyinfo
->mouse_face_window
= window
;
20440 dpyinfo
->mouse_face_face_id
20441 = face_at_buffer_position (w
, pos
, 0, 0,
20443 !dpyinfo
->mouse_face_hidden
);
20445 /* Display it as active. */
20446 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
20447 cursor
= No_Cursor
;
20449 /* Handle the text property case. */
20450 else if (!NILP (mouse_face
) && BUFFERP (object
))
20452 /* Find the range of text around this char that
20453 should be active. */
20454 Lisp_Object before
, after
, beginning
, end
;
20457 beginning
= Fmarker_position (w
->start
);
20458 end
= make_number (BUF_Z (XBUFFER (object
))
20459 - XFASTINT (w
->window_end_pos
));
20461 = Fprevious_single_property_change (make_number (pos
+ 1),
20463 object
, beginning
);
20465 = Fnext_single_property_change (position
, Qmouse_face
,
20468 /* Record this as the current active region. */
20469 fast_find_position (w
, XFASTINT (before
),
20470 &dpyinfo
->mouse_face_beg_col
,
20471 &dpyinfo
->mouse_face_beg_row
,
20472 &dpyinfo
->mouse_face_beg_x
,
20473 &dpyinfo
->mouse_face_beg_y
, Qnil
);
20474 dpyinfo
->mouse_face_past_end
20475 = !fast_find_position (w
, XFASTINT (after
),
20476 &dpyinfo
->mouse_face_end_col
,
20477 &dpyinfo
->mouse_face_end_row
,
20478 &dpyinfo
->mouse_face_end_x
,
20479 &dpyinfo
->mouse_face_end_y
, Qnil
);
20480 dpyinfo
->mouse_face_window
= window
;
20482 if (BUFFERP (object
))
20483 dpyinfo
->mouse_face_face_id
20484 = face_at_buffer_position (w
, pos
, 0, 0,
20486 !dpyinfo
->mouse_face_hidden
);
20488 /* Display it as active. */
20489 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
20490 cursor
= No_Cursor
;
20492 else if (!NILP (mouse_face
) && STRINGP (object
))
20497 b
= Fprevious_single_property_change (make_number (pos
+ 1),
20500 e
= Fnext_single_property_change (position
, Qmouse_face
,
20503 b
= make_number (0);
20505 e
= make_number (SCHARS (object
) - 1);
20506 fast_find_string_pos (w
, XINT (b
), object
,
20507 &dpyinfo
->mouse_face_beg_col
,
20508 &dpyinfo
->mouse_face_beg_row
,
20509 &dpyinfo
->mouse_face_beg_x
,
20510 &dpyinfo
->mouse_face_beg_y
, 0);
20511 fast_find_string_pos (w
, XINT (e
), object
,
20512 &dpyinfo
->mouse_face_end_col
,
20513 &dpyinfo
->mouse_face_end_row
,
20514 &dpyinfo
->mouse_face_end_x
,
20515 &dpyinfo
->mouse_face_end_y
, 1);
20516 dpyinfo
->mouse_face_past_end
= 0;
20517 dpyinfo
->mouse_face_window
= window
;
20518 dpyinfo
->mouse_face_face_id
20519 = face_at_string_position (w
, object
, pos
, 0, 0, 0, &ignore
,
20520 glyph
->face_id
, 1);
20521 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
20522 cursor
= No_Cursor
;
20524 else if (STRINGP (object
) && NILP (mouse_face
))
20526 /* A string which doesn't have mouse-face, but
20527 the text ``under'' it might have. */
20528 struct glyph_row
*r
= MATRIX_ROW (w
->current_matrix
, vpos
);
20529 int start
= MATRIX_ROW_START_CHARPOS (r
);
20531 pos
= string_buffer_position (w
, object
, start
);
20533 mouse_face
= get_char_property_and_overlay (make_number (pos
),
20537 if (!NILP (mouse_face
) && !NILP (overlay
))
20539 Lisp_Object before
= Foverlay_start (overlay
);
20540 Lisp_Object after
= Foverlay_end (overlay
);
20543 /* Note that we might not be able to find position
20544 BEFORE in the glyph matrix if the overlay is
20545 entirely covered by a `display' property. In
20546 this case, we overshoot. So let's stop in
20547 the glyph matrix before glyphs for OBJECT. */
20548 fast_find_position (w
, XFASTINT (before
),
20549 &dpyinfo
->mouse_face_beg_col
,
20550 &dpyinfo
->mouse_face_beg_row
,
20551 &dpyinfo
->mouse_face_beg_x
,
20552 &dpyinfo
->mouse_face_beg_y
,
20555 dpyinfo
->mouse_face_past_end
20556 = !fast_find_position (w
, XFASTINT (after
),
20557 &dpyinfo
->mouse_face_end_col
,
20558 &dpyinfo
->mouse_face_end_row
,
20559 &dpyinfo
->mouse_face_end_x
,
20560 &dpyinfo
->mouse_face_end_y
,
20562 dpyinfo
->mouse_face_window
= window
;
20563 dpyinfo
->mouse_face_face_id
20564 = face_at_buffer_position (w
, pos
, 0, 0,
20566 !dpyinfo
->mouse_face_hidden
);
20568 /* Display it as active. */
20569 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
20570 cursor
= No_Cursor
;
20577 /* Look for a `help-echo' property. */
20578 if (NILP (help_echo_string
)) {
20579 Lisp_Object help
, overlay
;
20581 /* Check overlays first. */
20582 help
= overlay
= Qnil
;
20583 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
20585 overlay
= overlay_vec
[i
];
20586 help
= Foverlay_get (overlay
, Qhelp_echo
);
20591 help_echo_string
= help
;
20592 help_echo_window
= window
;
20593 help_echo_object
= overlay
;
20594 help_echo_pos
= pos
;
20598 Lisp_Object object
= glyph
->object
;
20599 int charpos
= glyph
->charpos
;
20601 /* Try text properties. */
20602 if (STRINGP (object
)
20604 && charpos
< SCHARS (object
))
20606 help
= Fget_text_property (make_number (charpos
),
20607 Qhelp_echo
, object
);
20610 /* If the string itself doesn't specify a help-echo,
20611 see if the buffer text ``under'' it does. */
20612 struct glyph_row
*r
20613 = MATRIX_ROW (w
->current_matrix
, vpos
);
20614 int start
= MATRIX_ROW_START_CHARPOS (r
);
20615 int pos
= string_buffer_position (w
, object
, start
);
20618 help
= Fget_char_property (make_number (pos
),
20619 Qhelp_echo
, w
->buffer
);
20623 object
= w
->buffer
;
20628 else if (BUFFERP (object
)
20631 help
= Fget_text_property (make_number (charpos
), Qhelp_echo
,
20636 help_echo_string
= help
;
20637 help_echo_window
= window
;
20638 help_echo_object
= object
;
20639 help_echo_pos
= charpos
;
20644 /* Look for a `pointer' property. */
20645 if (NILP (pointer
))
20647 /* Check overlays first. */
20648 for (i
= noverlays
- 1; i
>= 0 && NILP (pointer
); --i
)
20649 pointer
= Foverlay_get (overlay_vec
[i
], Qpointer
);
20651 if (NILP (pointer
))
20653 Lisp_Object object
= glyph
->object
;
20654 int charpos
= glyph
->charpos
;
20656 /* Try text properties. */
20657 if (STRINGP (object
)
20659 && charpos
< SCHARS (object
))
20661 pointer
= Fget_text_property (make_number (charpos
),
20663 if (NILP (pointer
))
20665 /* If the string itself doesn't specify a pointer,
20666 see if the buffer text ``under'' it does. */
20667 struct glyph_row
*r
20668 = MATRIX_ROW (w
->current_matrix
, vpos
);
20669 int start
= MATRIX_ROW_START_CHARPOS (r
);
20670 int pos
= string_buffer_position (w
, object
, start
);
20672 pointer
= Fget_char_property (make_number (pos
),
20673 Qpointer
, w
->buffer
);
20676 else if (BUFFERP (object
)
20679 pointer
= Fget_text_property (make_number (charpos
),
20686 current_buffer
= obuf
;
20691 define_frame_cursor1 (f
, cursor
, pointer
);
20696 Clear any mouse-face on window W. This function is part of the
20697 redisplay interface, and is called from try_window_id and similar
20698 functions to ensure the mouse-highlight is off. */
20701 x_clear_window_mouse_face (w
)
20704 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (XFRAME (w
->frame
));
20705 Lisp_Object window
;
20708 XSETWINDOW (window
, w
);
20709 if (EQ (window
, dpyinfo
->mouse_face_window
))
20710 clear_mouse_face (dpyinfo
);
20716 Just discard the mouse face information for frame F, if any.
20717 This is used when the size of F is changed. */
20720 cancel_mouse_face (f
)
20723 Lisp_Object window
;
20724 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
20726 window
= dpyinfo
->mouse_face_window
;
20727 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
20729 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
20730 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
20731 dpyinfo
->mouse_face_window
= Qnil
;
20736 #endif /* HAVE_WINDOW_SYSTEM */
20739 /***********************************************************************
20741 ***********************************************************************/
20743 #ifdef HAVE_WINDOW_SYSTEM
20745 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
20746 which intersects rectangle R. R is in window-relative coordinates. */
20749 expose_area (w
, row
, r
, area
)
20751 struct glyph_row
*row
;
20753 enum glyph_row_area area
;
20755 struct glyph
*first
= row
->glyphs
[area
];
20756 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
20757 struct glyph
*last
;
20758 int first_x
, start_x
, x
;
20760 if (area
== TEXT_AREA
&& row
->fill_line_p
)
20761 /* If row extends face to end of line write the whole line. */
20762 draw_glyphs (w
, 0, row
, area
,
20763 0, row
->used
[area
],
20764 DRAW_NORMAL_TEXT
, 0);
20767 /* Set START_X to the window-relative start position for drawing glyphs of
20768 AREA. The first glyph of the text area can be partially visible.
20769 The first glyphs of other areas cannot. */
20770 start_x
= window_box_left_offset (w
, area
);
20772 if (area
== TEXT_AREA
)
20775 /* Find the first glyph that must be redrawn. */
20777 && x
+ first
->pixel_width
< r
->x
)
20779 x
+= first
->pixel_width
;
20783 /* Find the last one. */
20787 && x
< r
->x
+ r
->width
)
20789 x
+= last
->pixel_width
;
20795 draw_glyphs (w
, first_x
- start_x
, row
, area
,
20796 first
- row
->glyphs
[area
], last
- row
->glyphs
[area
],
20797 DRAW_NORMAL_TEXT
, 0);
20802 /* Redraw the parts of the glyph row ROW on window W intersecting
20803 rectangle R. R is in window-relative coordinates. Value is
20804 non-zero if mouse-face was overwritten. */
20807 expose_line (w
, row
, r
)
20809 struct glyph_row
*row
;
20812 xassert (row
->enabled_p
);
20814 if (row
->mode_line_p
|| w
->pseudo_window_p
)
20815 draw_glyphs (w
, 0, row
, TEXT_AREA
,
20816 0, row
->used
[TEXT_AREA
],
20817 DRAW_NORMAL_TEXT
, 0);
20820 if (row
->used
[LEFT_MARGIN_AREA
])
20821 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
20822 if (row
->used
[TEXT_AREA
])
20823 expose_area (w
, row
, r
, TEXT_AREA
);
20824 if (row
->used
[RIGHT_MARGIN_AREA
])
20825 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
20826 draw_row_fringe_bitmaps (w
, row
);
20829 return row
->mouse_face_p
;
20833 /* Redraw those parts of glyphs rows during expose event handling that
20834 overlap other rows. Redrawing of an exposed line writes over parts
20835 of lines overlapping that exposed line; this function fixes that.
20837 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
20838 row in W's current matrix that is exposed and overlaps other rows.
20839 LAST_OVERLAPPING_ROW is the last such row. */
20842 expose_overlaps (w
, first_overlapping_row
, last_overlapping_row
)
20844 struct glyph_row
*first_overlapping_row
;
20845 struct glyph_row
*last_overlapping_row
;
20847 struct glyph_row
*row
;
20849 for (row
= first_overlapping_row
; row
<= last_overlapping_row
; ++row
)
20850 if (row
->overlapping_p
)
20852 xassert (row
->enabled_p
&& !row
->mode_line_p
);
20854 if (row
->used
[LEFT_MARGIN_AREA
])
20855 x_fix_overlapping_area (w
, row
, LEFT_MARGIN_AREA
);
20857 if (row
->used
[TEXT_AREA
])
20858 x_fix_overlapping_area (w
, row
, TEXT_AREA
);
20860 if (row
->used
[RIGHT_MARGIN_AREA
])
20861 x_fix_overlapping_area (w
, row
, RIGHT_MARGIN_AREA
);
20866 /* Return non-zero if W's cursor intersects rectangle R. */
20869 phys_cursor_in_rect_p (w
, r
)
20873 XRectangle cr
, result
;
20874 struct glyph
*cursor_glyph
;
20876 cursor_glyph
= get_phys_cursor_glyph (w
);
20879 /* r is relative to W's box, but w->phys_cursor.x is relative
20880 to left edge of W's TEXT area. Adjust it. */
20881 cr
.x
= window_box_left_offset (w
, TEXT_AREA
) + w
->phys_cursor
.x
;
20882 cr
.y
= w
->phys_cursor
.y
;
20883 cr
.width
= cursor_glyph
->pixel_width
;
20884 cr
.height
= w
->phys_cursor_height
;
20885 /* ++KFS: W32 version used W32-specific IntersectRect here, but
20886 I assume the effect is the same -- and this is portable. */
20887 return x_intersect_rectangles (&cr
, r
, &result
);
20895 Draw a vertical window border to the right of window W if W doesn't
20896 have vertical scroll bars. */
20899 x_draw_vertical_border (w
)
20902 /* We could do better, if we knew what type of scroll-bar the adjacent
20903 windows (on either side) have... But we don't :-(
20904 However, I think this works ok. ++KFS 2003-04-25 */
20906 /* Redraw borders between horizontally adjacent windows. Don't
20907 do it for frames with vertical scroll bars because either the
20908 right scroll bar of a window, or the left scroll bar of its
20909 neighbor will suffice as a border. */
20910 if (!WINDOW_RIGHTMOST_P (w
)
20911 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w
))
20913 int x0
, x1
, y0
, y1
;
20915 window_box_edges (w
, -1, &x0
, &y0
, &x1
, &y1
);
20918 rif
->draw_vertical_window_border (w
, x1
, y0
, y1
);
20920 else if (!WINDOW_LEFTMOST_P (w
)
20921 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w
))
20923 int x0
, x1
, y0
, y1
;
20925 window_box_edges (w
, -1, &x0
, &y0
, &x1
, &y1
);
20928 rif
->draw_vertical_window_border (w
, x0
, y0
, y1
);
20933 /* Redraw the part of window W intersection rectangle FR. Pixel
20934 coordinates in FR are frame-relative. Call this function with
20935 input blocked. Value is non-zero if the exposure overwrites
20939 expose_window (w
, fr
)
20943 struct frame
*f
= XFRAME (w
->frame
);
20945 int mouse_face_overwritten_p
= 0;
20947 /* If window is not yet fully initialized, do nothing. This can
20948 happen when toolkit scroll bars are used and a window is split.
20949 Reconfiguring the scroll bar will generate an expose for a newly
20951 if (w
->current_matrix
== NULL
)
20954 /* When we're currently updating the window, display and current
20955 matrix usually don't agree. Arrange for a thorough display
20957 if (w
== updated_window
)
20959 SET_FRAME_GARBAGED (f
);
20963 /* Frame-relative pixel rectangle of W. */
20964 wr
.x
= WINDOW_LEFT_EDGE_X (w
);
20965 wr
.y
= WINDOW_TOP_EDGE_Y (w
);
20966 wr
.width
= WINDOW_TOTAL_WIDTH (w
);
20967 wr
.height
= WINDOW_TOTAL_HEIGHT (w
);
20969 if (x_intersect_rectangles (fr
, &wr
, &r
))
20971 int yb
= window_text_bottom_y (w
);
20972 struct glyph_row
*row
;
20973 int cursor_cleared_p
;
20974 struct glyph_row
*first_overlapping_row
, *last_overlapping_row
;
20976 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
20977 r
.x
, r
.y
, r
.width
, r
.height
));
20979 /* Convert to window coordinates. */
20980 r
.x
-= WINDOW_LEFT_EDGE_X (w
);
20981 r
.y
-= WINDOW_TOP_EDGE_Y (w
);
20983 /* Turn off the cursor. */
20984 if (!w
->pseudo_window_p
20985 && phys_cursor_in_rect_p (w
, &r
))
20987 x_clear_cursor (w
);
20988 cursor_cleared_p
= 1;
20991 cursor_cleared_p
= 0;
20993 /* Update lines intersecting rectangle R. */
20994 first_overlapping_row
= last_overlapping_row
= NULL
;
20995 for (row
= w
->current_matrix
->rows
;
21000 int y1
= MATRIX_ROW_BOTTOM_Y (row
);
21002 if ((y0
>= r
.y
&& y0
< r
.y
+ r
.height
)
21003 || (y1
> r
.y
&& y1
< r
.y
+ r
.height
)
21004 || (r
.y
>= y0
&& r
.y
< y1
)
21005 || (r
.y
+ r
.height
> y0
&& r
.y
+ r
.height
< y1
))
21007 if (row
->overlapping_p
)
21009 if (first_overlapping_row
== NULL
)
21010 first_overlapping_row
= row
;
21011 last_overlapping_row
= row
;
21014 if (expose_line (w
, row
, &r
))
21015 mouse_face_overwritten_p
= 1;
21022 /* Display the mode line if there is one. */
21023 if (WINDOW_WANTS_MODELINE_P (w
)
21024 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
21026 && row
->y
< r
.y
+ r
.height
)
21028 if (expose_line (w
, row
, &r
))
21029 mouse_face_overwritten_p
= 1;
21032 if (!w
->pseudo_window_p
)
21034 /* Fix the display of overlapping rows. */
21035 if (first_overlapping_row
)
21036 expose_overlaps (w
, first_overlapping_row
, last_overlapping_row
);
21038 /* Draw border between windows. */
21039 x_draw_vertical_border (w
);
21041 /* Turn the cursor on again. */
21042 if (cursor_cleared_p
)
21043 update_window_cursor (w
, 1);
21048 /* Display scroll bar for this window. */
21049 if (!NILP (w
->vertical_scroll_bar
))
21052 If this doesn't work here (maybe some header files are missing),
21053 make a function in macterm.c and call it to do the job! */
21055 = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (w
->vertical_scroll_bar
));
21061 return mouse_face_overwritten_p
;
21066 /* Redraw (parts) of all windows in the window tree rooted at W that
21067 intersect R. R contains frame pixel coordinates. Value is
21068 non-zero if the exposure overwrites mouse-face. */
21071 expose_window_tree (w
, r
)
21075 struct frame
*f
= XFRAME (w
->frame
);
21076 int mouse_face_overwritten_p
= 0;
21078 while (w
&& !FRAME_GARBAGED_P (f
))
21080 if (!NILP (w
->hchild
))
21081 mouse_face_overwritten_p
21082 |= expose_window_tree (XWINDOW (w
->hchild
), r
);
21083 else if (!NILP (w
->vchild
))
21084 mouse_face_overwritten_p
21085 |= expose_window_tree (XWINDOW (w
->vchild
), r
);
21087 mouse_face_overwritten_p
|= expose_window (w
, r
);
21089 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
21092 return mouse_face_overwritten_p
;
21097 Redisplay an exposed area of frame F. X and Y are the upper-left
21098 corner of the exposed rectangle. W and H are width and height of
21099 the exposed area. All are pixel values. W or H zero means redraw
21100 the entire frame. */
21103 expose_frame (f
, x
, y
, w
, h
)
21108 int mouse_face_overwritten_p
= 0;
21110 TRACE ((stderr
, "expose_frame "));
21112 /* No need to redraw if frame will be redrawn soon. */
21113 if (FRAME_GARBAGED_P (f
))
21115 TRACE ((stderr
, " garbaged\n"));
21120 /* MAC_TODO: this is a kludge, but if scroll bars are not activated
21121 or deactivated here, for unknown reasons, activated scroll bars
21122 are shown in deactivated frames in some instances. */
21123 if (f
== FRAME_MAC_DISPLAY_INFO (f
)->x_focus_frame
)
21124 activate_scroll_bars (f
);
21126 deactivate_scroll_bars (f
);
21129 /* If basic faces haven't been realized yet, there is no point in
21130 trying to redraw anything. This can happen when we get an expose
21131 event while Emacs is starting, e.g. by moving another window. */
21132 if (FRAME_FACE_CACHE (f
) == NULL
21133 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
21135 TRACE ((stderr
, " no faces\n"));
21139 if (w
== 0 || h
== 0)
21142 r
.width
= FRAME_COLUMN_WIDTH (f
) * FRAME_COLS (f
);
21143 r
.height
= FRAME_LINE_HEIGHT (f
) * FRAME_LINES (f
);
21153 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.x
, r
.y
, r
.width
, r
.height
));
21154 mouse_face_overwritten_p
= expose_window_tree (XWINDOW (f
->root_window
), &r
);
21156 if (WINDOWP (f
->tool_bar_window
))
21157 mouse_face_overwritten_p
21158 |= expose_window (XWINDOW (f
->tool_bar_window
), &r
);
21160 #ifdef HAVE_X_WINDOWS
21162 #ifndef USE_X_TOOLKIT
21163 if (WINDOWP (f
->menu_bar_window
))
21164 mouse_face_overwritten_p
21165 |= expose_window (XWINDOW (f
->menu_bar_window
), &r
);
21166 #endif /* not USE_X_TOOLKIT */
21170 /* Some window managers support a focus-follows-mouse style with
21171 delayed raising of frames. Imagine a partially obscured frame,
21172 and moving the mouse into partially obscured mouse-face on that
21173 frame. The visible part of the mouse-face will be highlighted,
21174 then the WM raises the obscured frame. With at least one WM, KDE
21175 2.1, Emacs is not getting any event for the raising of the frame
21176 (even tried with SubstructureRedirectMask), only Expose events.
21177 These expose events will draw text normally, i.e. not
21178 highlighted. Which means we must redo the highlight here.
21179 Subsume it under ``we love X''. --gerd 2001-08-15 */
21180 /* Included in Windows version because Windows most likely does not
21181 do the right thing if any third party tool offers
21182 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
21183 if (mouse_face_overwritten_p
&& !FRAME_GARBAGED_P (f
))
21185 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
21186 if (f
== dpyinfo
->mouse_face_mouse_frame
)
21188 int x
= dpyinfo
->mouse_face_mouse_x
;
21189 int y
= dpyinfo
->mouse_face_mouse_y
;
21190 clear_mouse_face (dpyinfo
);
21191 note_mouse_highlight (f
, x
, y
);
21198 Determine the intersection of two rectangles R1 and R2. Return
21199 the intersection in *RESULT. Value is non-zero if RESULT is not
21203 x_intersect_rectangles (r1
, r2
, result
)
21204 XRectangle
*r1
, *r2
, *result
;
21206 XRectangle
*left
, *right
;
21207 XRectangle
*upper
, *lower
;
21208 int intersection_p
= 0;
21210 /* Rearrange so that R1 is the left-most rectangle. */
21212 left
= r1
, right
= r2
;
21214 left
= r2
, right
= r1
;
21216 /* X0 of the intersection is right.x0, if this is inside R1,
21217 otherwise there is no intersection. */
21218 if (right
->x
<= left
->x
+ left
->width
)
21220 result
->x
= right
->x
;
21222 /* The right end of the intersection is the minimum of the
21223 the right ends of left and right. */
21224 result
->width
= (min (left
->x
+ left
->width
, right
->x
+ right
->width
)
21227 /* Same game for Y. */
21229 upper
= r1
, lower
= r2
;
21231 upper
= r2
, lower
= r1
;
21233 /* The upper end of the intersection is lower.y0, if this is inside
21234 of upper. Otherwise, there is no intersection. */
21235 if (lower
->y
<= upper
->y
+ upper
->height
)
21237 result
->y
= lower
->y
;
21239 /* The lower end of the intersection is the minimum of the lower
21240 ends of upper and lower. */
21241 result
->height
= (min (lower
->y
+ lower
->height
,
21242 upper
->y
+ upper
->height
)
21244 intersection_p
= 1;
21248 return intersection_p
;
21251 #endif /* HAVE_WINDOW_SYSTEM */
21254 /***********************************************************************
21256 ***********************************************************************/
21261 Vwith_echo_area_save_vector
= Qnil
;
21262 staticpro (&Vwith_echo_area_save_vector
);
21264 Vmessage_stack
= Qnil
;
21265 staticpro (&Vmessage_stack
);
21267 Qinhibit_redisplay
= intern ("inhibit-redisplay");
21268 staticpro (&Qinhibit_redisplay
);
21270 message_dolog_marker1
= Fmake_marker ();
21271 staticpro (&message_dolog_marker1
);
21272 message_dolog_marker2
= Fmake_marker ();
21273 staticpro (&message_dolog_marker2
);
21274 message_dolog_marker3
= Fmake_marker ();
21275 staticpro (&message_dolog_marker3
);
21278 defsubr (&Sdump_frame_glyph_matrix
);
21279 defsubr (&Sdump_glyph_matrix
);
21280 defsubr (&Sdump_glyph_row
);
21281 defsubr (&Sdump_tool_bar_row
);
21282 defsubr (&Strace_redisplay
);
21283 defsubr (&Strace_to_stderr
);
21285 #ifdef HAVE_WINDOW_SYSTEM
21286 defsubr (&Stool_bar_lines_needed
);
21287 defsubr (&Slookup_image_map
);
21289 defsubr (&Sformat_mode_line
);
21291 staticpro (&Qmenu_bar_update_hook
);
21292 Qmenu_bar_update_hook
= intern ("menu-bar-update-hook");
21294 staticpro (&Qoverriding_terminal_local_map
);
21295 Qoverriding_terminal_local_map
= intern ("overriding-terminal-local-map");
21297 staticpro (&Qoverriding_local_map
);
21298 Qoverriding_local_map
= intern ("overriding-local-map");
21300 staticpro (&Qwindow_scroll_functions
);
21301 Qwindow_scroll_functions
= intern ("window-scroll-functions");
21303 staticpro (&Qredisplay_end_trigger_functions
);
21304 Qredisplay_end_trigger_functions
= intern ("redisplay-end-trigger-functions");
21306 staticpro (&Qinhibit_point_motion_hooks
);
21307 Qinhibit_point_motion_hooks
= intern ("inhibit-point-motion-hooks");
21309 QCdata
= intern (":data");
21310 staticpro (&QCdata
);
21311 Qdisplay
= intern ("display");
21312 staticpro (&Qdisplay
);
21313 Qspace_width
= intern ("space-width");
21314 staticpro (&Qspace_width
);
21315 Qraise
= intern ("raise");
21316 staticpro (&Qraise
);
21317 Qspace
= intern ("space");
21318 staticpro (&Qspace
);
21319 Qmargin
= intern ("margin");
21320 staticpro (&Qmargin
);
21321 Qpointer
= intern ("pointer");
21322 staticpro (&Qpointer
);
21323 Qleft_margin
= intern ("left-margin");
21324 staticpro (&Qleft_margin
);
21325 Qright_margin
= intern ("right-margin");
21326 staticpro (&Qright_margin
);
21327 QCalign_to
= intern (":align-to");
21328 staticpro (&QCalign_to
);
21329 QCrelative_width
= intern (":relative-width");
21330 staticpro (&QCrelative_width
);
21331 QCrelative_height
= intern (":relative-height");
21332 staticpro (&QCrelative_height
);
21333 QCeval
= intern (":eval");
21334 staticpro (&QCeval
);
21335 QCpropertize
= intern (":propertize");
21336 staticpro (&QCpropertize
);
21337 QCfile
= intern (":file");
21338 staticpro (&QCfile
);
21339 Qfontified
= intern ("fontified");
21340 staticpro (&Qfontified
);
21341 Qfontification_functions
= intern ("fontification-functions");
21342 staticpro (&Qfontification_functions
);
21343 Qtrailing_whitespace
= intern ("trailing-whitespace");
21344 staticpro (&Qtrailing_whitespace
);
21345 Qimage
= intern ("image");
21346 staticpro (&Qimage
);
21347 QCmap
= intern (":map");
21348 staticpro (&QCmap
);
21349 QCpointer
= intern (":pointer");
21350 staticpro (&QCpointer
);
21351 Qrect
= intern ("rect");
21352 staticpro (&Qrect
);
21353 Qcircle
= intern ("circle");
21354 staticpro (&Qcircle
);
21355 Qpoly
= intern ("poly");
21356 staticpro (&Qpoly
);
21357 Qmessage_truncate_lines
= intern ("message-truncate-lines");
21358 staticpro (&Qmessage_truncate_lines
);
21359 Qcursor_in_non_selected_windows
= intern ("cursor-in-non-selected-windows");
21360 staticpro (&Qcursor_in_non_selected_windows
);
21361 Qgrow_only
= intern ("grow-only");
21362 staticpro (&Qgrow_only
);
21363 Qinhibit_menubar_update
= intern ("inhibit-menubar-update");
21364 staticpro (&Qinhibit_menubar_update
);
21365 Qinhibit_eval_during_redisplay
= intern ("inhibit-eval-during-redisplay");
21366 staticpro (&Qinhibit_eval_during_redisplay
);
21367 Qposition
= intern ("position");
21368 staticpro (&Qposition
);
21369 Qbuffer_position
= intern ("buffer-position");
21370 staticpro (&Qbuffer_position
);
21371 Qobject
= intern ("object");
21372 staticpro (&Qobject
);
21373 Qbar
= intern ("bar");
21375 Qhbar
= intern ("hbar");
21376 staticpro (&Qhbar
);
21377 Qbox
= intern ("box");
21379 Qhollow
= intern ("hollow");
21380 staticpro (&Qhollow
);
21381 Qhand
= intern ("hand");
21382 staticpro (&Qhand
);
21383 Qarrow
= intern ("arrow");
21384 staticpro (&Qarrow
);
21385 Qtext
= intern ("text");
21386 staticpro (&Qtext
);
21387 Qrisky_local_variable
= intern ("risky-local-variable");
21388 staticpro (&Qrisky_local_variable
);
21389 Qinhibit_free_realized_faces
= intern ("inhibit-free-realized-faces");
21390 staticpro (&Qinhibit_free_realized_faces
);
21392 list_of_error
= Fcons (intern ("error"), Qnil
);
21393 staticpro (&list_of_error
);
21395 last_arrow_position
= Qnil
;
21396 last_arrow_string
= Qnil
;
21397 staticpro (&last_arrow_position
);
21398 staticpro (&last_arrow_string
);
21400 echo_buffer
[0] = echo_buffer
[1] = Qnil
;
21401 staticpro (&echo_buffer
[0]);
21402 staticpro (&echo_buffer
[1]);
21404 echo_area_buffer
[0] = echo_area_buffer
[1] = Qnil
;
21405 staticpro (&echo_area_buffer
[0]);
21406 staticpro (&echo_area_buffer
[1]);
21408 Vmessages_buffer_name
= build_string ("*Messages*");
21409 staticpro (&Vmessages_buffer_name
);
21411 mode_line_proptrans_alist
= Qnil
;
21412 staticpro (&mode_line_proptrans_alist
);
21414 mode_line_string_list
= Qnil
;
21415 staticpro (&mode_line_string_list
);
21417 help_echo_string
= Qnil
;
21418 staticpro (&help_echo_string
);
21419 help_echo_object
= Qnil
;
21420 staticpro (&help_echo_object
);
21421 help_echo_window
= Qnil
;
21422 staticpro (&help_echo_window
);
21423 previous_help_echo_string
= Qnil
;
21424 staticpro (&previous_help_echo_string
);
21425 help_echo_pos
= -1;
21427 #ifdef HAVE_WINDOW_SYSTEM
21428 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
21429 doc
: /* *Non-nil means draw block cursor as wide as the glyph under it.
21430 For example, if a block cursor is over a tab, it will be drawn as
21431 wide as that tab on the display. */);
21432 x_stretch_cursor_p
= 0;
21435 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace
,
21436 doc
: /* *Non-nil means highlight trailing whitespace.
21437 The face used for trailing whitespace is `trailing-whitespace'. */);
21438 Vshow_trailing_whitespace
= Qnil
;
21440 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer
,
21441 doc
: /* *The pointer shape to show in void text areas.
21442 Nil means to show the text pointer. Other options are `arrow', `text',
21443 `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
21444 Vvoid_text_area_pointer
= Qarrow
;
21446 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay
,
21447 doc
: /* Non-nil means don't actually do any redisplay.
21448 This is used for internal purposes. */);
21449 Vinhibit_redisplay
= Qnil
;
21451 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string
,
21452 doc
: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
21453 Vglobal_mode_string
= Qnil
;
21455 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position
,
21456 doc
: /* Marker for where to display an arrow on top of the buffer text.
21457 This must be the beginning of a line in order to work.
21458 See also `overlay-arrow-string'. */);
21459 Voverlay_arrow_position
= Qnil
;
21461 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string
,
21462 doc
: /* String to display as an arrow. See also `overlay-arrow-position'. */);
21463 Voverlay_arrow_string
= Qnil
;
21465 DEFVAR_INT ("scroll-step", &scroll_step
,
21466 doc
: /* *The number of lines to try scrolling a window by when point moves out.
21467 If that fails to bring point back on frame, point is centered instead.
21468 If this is zero, point is always centered after it moves off frame.
21469 If you want scrolling to always be a line at a time, you should set
21470 `scroll-conservatively' to a large value rather than set this to 1. */);
21472 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively
,
21473 doc
: /* *Scroll up to this many lines, to bring point back on screen.
21474 A value of zero means to scroll the text to center point vertically
21475 in the window. */);
21476 scroll_conservatively
= 0;
21478 DEFVAR_INT ("scroll-margin", &scroll_margin
,
21479 doc
: /* *Number of lines of margin at the top and bottom of a window.
21480 Recenter the window whenever point gets within this many lines
21481 of the top or bottom of the window. */);
21484 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch
,
21485 doc
: /* Pixels per inch on current display.
21486 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
21487 Vdisplay_pixels_per_inch
= make_float (72.0);
21490 DEFVAR_INT ("debug-end-pos", &debug_end_pos
, doc
: /* Don't ask. */);
21493 DEFVAR_BOOL ("truncate-partial-width-windows",
21494 &truncate_partial_width_windows
,
21495 doc
: /* *Non-nil means truncate lines in all windows less than full frame wide. */);
21496 truncate_partial_width_windows
= 1;
21498 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video
,
21499 doc
: /* nil means display the mode-line/header-line/menu-bar in the default face.
21500 Any other value means to use the appropriate face, `mode-line',
21501 `header-line', or `menu' respectively. */);
21502 mode_line_inverse_video
= 1;
21504 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit
,
21505 doc
: /* *Maximum buffer size for which line number should be displayed.
21506 If the buffer is bigger than this, the line number does not appear
21507 in the mode line. A value of nil means no limit. */);
21508 Vline_number_display_limit
= Qnil
;
21510 DEFVAR_INT ("line-number-display-limit-width",
21511 &line_number_display_limit_width
,
21512 doc
: /* *Maximum line width (in characters) for line number display.
21513 If the average length of the lines near point is bigger than this, then the
21514 line number may be omitted from the mode line. */);
21515 line_number_display_limit_width
= 200;
21517 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows
,
21518 doc
: /* *Non-nil means highlight region even in nonselected windows. */);
21519 highlight_nonselected_windows
= 0;
21521 DEFVAR_BOOL ("multiple-frames", &multiple_frames
,
21522 doc
: /* Non-nil if more than one frame is visible on this display.
21523 Minibuffer-only frames don't count, but iconified frames do.
21524 This variable is not guaranteed to be accurate except while processing
21525 `frame-title-format' and `icon-title-format'. */);
21527 DEFVAR_LISP ("frame-title-format", &Vframe_title_format
,
21528 doc
: /* Template for displaying the title bar of visible frames.
21529 \(Assuming the window manager supports this feature.)
21530 This variable has the same structure as `mode-line-format' (which see),
21531 and is used only on frames for which no explicit name has been set
21532 \(see `modify-frame-parameters'). */);
21534 DEFVAR_LISP ("icon-title-format", &Vicon_title_format
,
21535 doc
: /* Template for displaying the title bar of an iconified frame.
21536 \(Assuming the window manager supports this feature.)
21537 This variable has the same structure as `mode-line-format' (which see),
21538 and is used only on frames for which no explicit name has been set
21539 \(see `modify-frame-parameters'). */);
21541 = Vframe_title_format
21542 = Fcons (intern ("multiple-frames"),
21543 Fcons (build_string ("%b"),
21544 Fcons (Fcons (empty_string
,
21545 Fcons (intern ("invocation-name"),
21546 Fcons (build_string ("@"),
21547 Fcons (intern ("system-name"),
21551 DEFVAR_LISP ("message-log-max", &Vmessage_log_max
,
21552 doc
: /* Maximum number of lines to keep in the message log buffer.
21553 If nil, disable message logging. If t, log messages but don't truncate
21554 the buffer when it becomes large. */);
21555 Vmessage_log_max
= make_number (50);
21557 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions
,
21558 doc
: /* Functions called before redisplay, if window sizes have changed.
21559 The value should be a list of functions that take one argument.
21560 Just before redisplay, for each frame, if any of its windows have changed
21561 size since the last redisplay, or have been split or deleted,
21562 all the functions in the list are called, with the frame as argument. */);
21563 Vwindow_size_change_functions
= Qnil
;
21565 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions
,
21566 doc
: /* List of Functions to call before redisplaying a window with scrolling.
21567 Each function is called with two arguments, the window
21568 and its new display-start position. Note that the value of `window-end'
21569 is not valid when these functions are called. */);
21570 Vwindow_scroll_functions
= Qnil
;
21572 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window
,
21573 doc
: /* *Non-nil means autoselect window with mouse pointer. */);
21574 mouse_autoselect_window
= 0;
21576 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p
,
21577 doc
: /* *Non-nil means automatically resize tool-bars.
21578 This increases a tool-bar's height if not all tool-bar items are visible.
21579 It decreases a tool-bar's height when it would display blank lines
21581 auto_resize_tool_bars_p
= 1;
21583 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p
,
21584 doc
: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
21585 auto_raise_tool_bar_buttons_p
= 1;
21587 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin
,
21588 doc
: /* *Margin around tool-bar buttons in pixels.
21589 If an integer, use that for both horizontal and vertical margins.
21590 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
21591 HORZ specifying the horizontal margin, and VERT specifying the
21592 vertical margin. */);
21593 Vtool_bar_button_margin
= make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN
);
21595 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief
,
21596 doc
: /* *Relief thickness of tool-bar buttons. */);
21597 tool_bar_button_relief
= DEFAULT_TOOL_BAR_BUTTON_RELIEF
;
21599 DEFVAR_LISP ("fontification-functions", &Vfontification_functions
,
21600 doc
: /* List of functions to call to fontify regions of text.
21601 Each function is called with one argument POS. Functions must
21602 fontify a region starting at POS in the current buffer, and give
21603 fontified regions the property `fontified'. */);
21604 Vfontification_functions
= Qnil
;
21605 Fmake_variable_buffer_local (Qfontification_functions
);
21607 DEFVAR_BOOL ("unibyte-display-via-language-environment",
21608 &unibyte_display_via_language_environment
,
21609 doc
: /* *Non-nil means display unibyte text according to language environment.
21610 Specifically this means that unibyte non-ASCII characters
21611 are displayed by converting them to the equivalent multibyte characters
21612 according to the current language environment. As a result, they are
21613 displayed according to the current fontset. */);
21614 unibyte_display_via_language_environment
= 0;
21616 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height
,
21617 doc
: /* *Maximum height for resizing mini-windows.
21618 If a float, it specifies a fraction of the mini-window frame's height.
21619 If an integer, it specifies a number of lines. */);
21620 Vmax_mini_window_height
= make_float (0.25);
21622 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows
,
21623 doc
: /* *How to resize mini-windows.
21624 A value of nil means don't automatically resize mini-windows.
21625 A value of t means resize them to fit the text displayed in them.
21626 A value of `grow-only', the default, means let mini-windows grow
21627 only, until their display becomes empty, at which point the windows
21628 go back to their normal size. */);
21629 Vresize_mini_windows
= Qgrow_only
;
21631 DEFVAR_LISP ("cursor-in-non-selected-windows",
21632 &Vcursor_in_non_selected_windows
,
21633 doc
: /* *Cursor type to display in non-selected windows.
21634 t means to use hollow box cursor. See `cursor-type' for other values. */);
21635 Vcursor_in_non_selected_windows
= Qt
;
21637 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist
,
21638 doc
: /* Alist specifying how to blink the cursor off.
21639 Each element has the form (ON-STATE . OFF-STATE). Whenever the
21640 `cursor-type' frame-parameter or variable equals ON-STATE,
21641 comparing using `equal', Emacs uses OFF-STATE to specify
21642 how to blink it off. */);
21643 Vblink_cursor_alist
= Qnil
;
21645 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p
,
21646 doc
: /* *Non-nil means scroll the display automatically to make point visible. */);
21647 automatic_hscrolling_p
= 1;
21649 DEFVAR_INT ("hscroll-margin", &hscroll_margin
,
21650 doc
: /* *How many columns away from the window edge point is allowed to get
21651 before automatic hscrolling will horizontally scroll the window. */);
21652 hscroll_margin
= 5;
21654 DEFVAR_LISP ("hscroll-step", &Vhscroll_step
,
21655 doc
: /* *How many columns to scroll the window when point gets too close to the edge.
21656 When point is less than `automatic-hscroll-margin' columns from the window
21657 edge, automatic hscrolling will scroll the window by the amount of columns
21658 determined by this variable. If its value is a positive integer, scroll that
21659 many columns. If it's a positive floating-point number, it specifies the
21660 fraction of the window's width to scroll. If it's nil or zero, point will be
21661 centered horizontally after the scroll. Any other value, including negative
21662 numbers, are treated as if the value were zero.
21664 Automatic hscrolling always moves point outside the scroll margin, so if
21665 point was more than scroll step columns inside the margin, the window will
21666 scroll more than the value given by the scroll step.
21668 Note that the lower bound for automatic hscrolling specified by `scroll-left'
21669 and `scroll-right' overrides this variable's effect. */);
21670 Vhscroll_step
= make_number (0);
21672 DEFVAR_LISP ("image-types", &Vimage_types
,
21673 doc
: /* List of supported image types.
21674 Each element of the list is a symbol for a supported image type. */);
21675 Vimage_types
= Qnil
;
21677 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines
,
21678 doc
: /* If non-nil, messages are truncated instead of resizing the echo area.
21679 Bind this around calls to `message' to let it take effect. */);
21680 message_truncate_lines
= 0;
21682 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook
,
21683 doc
: /* Normal hook run for clicks on menu bar, before displaying a submenu.
21684 Can be used to update submenus whose contents should vary. */);
21685 Vmenu_bar_update_hook
= Qnil
;
21687 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update
,
21688 doc
: /* Non-nil means don't update menu bars. Internal use only. */);
21689 inhibit_menubar_update
= 0;
21691 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay
,
21692 doc
: /* Non-nil means don't eval Lisp during redisplay. */);
21693 inhibit_eval_during_redisplay
= 0;
21695 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces
,
21696 doc
: /* Non-nil means don't free realized faces. Internal use only. */);
21697 inhibit_free_realized_faces
= 0;
21700 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id
,
21701 doc
: /* Inhibit try_window_id display optimization. */);
21702 inhibit_try_window_id
= 0;
21704 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing
,
21705 doc
: /* Inhibit try_window_reusing display optimization. */);
21706 inhibit_try_window_reusing
= 0;
21708 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement
,
21709 doc
: /* Inhibit try_cursor_movement display optimization. */);
21710 inhibit_try_cursor_movement
= 0;
21711 #endif /* GLYPH_DEBUG */
21715 /* Initialize this module when Emacs starts. */
21720 Lisp_Object root_window
;
21721 struct window
*mini_w
;
21723 current_header_line_height
= current_mode_line_height
= -1;
21725 CHARPOS (this_line_start_pos
) = 0;
21727 mini_w
= XWINDOW (minibuf_window
);
21728 root_window
= FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w
)));
21730 if (!noninteractive
)
21732 struct frame
*f
= XFRAME (WINDOW_FRAME (XWINDOW (root_window
)));
21735 XWINDOW (root_window
)->top_line
= make_number (FRAME_TOP_MARGIN (f
));
21736 set_window_height (root_window
,
21737 FRAME_LINES (f
) - 1 - FRAME_TOP_MARGIN (f
),
21739 mini_w
->top_line
= make_number (FRAME_LINES (f
) - 1);
21740 set_window_height (minibuf_window
, 1, 0);
21742 XWINDOW (root_window
)->total_cols
= make_number (FRAME_COLS (f
));
21743 mini_w
->total_cols
= make_number (FRAME_COLS (f
));
21745 scratch_glyph_row
.glyphs
[TEXT_AREA
] = scratch_glyphs
;
21746 scratch_glyph_row
.glyphs
[TEXT_AREA
+ 1]
21747 = scratch_glyphs
+ MAX_SCRATCH_GLYPHS
;
21749 /* The default ellipsis glyphs `...'. */
21750 for (i
= 0; i
< 3; ++i
)
21751 default_invis_vector
[i
] = make_number ('.');
21755 /* Allocate the buffer for frame titles.
21756 Also used for `format-mode-line'. */
21758 frame_title_buf
= (char *) xmalloc (size
);
21759 frame_title_buf_end
= frame_title_buf
+ size
;
21760 frame_title_ptr
= NULL
;
21763 help_echo_showing_p
= 0;
21767 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
21768 (do not change this comment) */