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 /* Non-zero while redisplay_internal is in progress. */
763 /* Non-zero means don't free realized faces. Bound while freeing
764 realized faces is dangerous because glyph matrices might still
767 int inhibit_free_realized_faces
;
768 Lisp_Object Qinhibit_free_realized_faces
;
770 /* If a string, XTread_socket generates an event to display that string.
771 (The display is done in read_char.) */
773 Lisp_Object help_echo_string
;
774 Lisp_Object help_echo_window
;
775 Lisp_Object help_echo_object
;
778 /* Temporary variable for XTread_socket. */
780 Lisp_Object previous_help_echo_string
;
784 /* Function prototypes. */
786 static void setup_for_ellipsis
P_ ((struct it
*));
787 static void mark_window_display_accurate_1
P_ ((struct window
*, int));
788 static int single_display_prop_string_p
P_ ((Lisp_Object
, Lisp_Object
));
789 static int display_prop_string_p
P_ ((Lisp_Object
, Lisp_Object
));
790 static int cursor_row_p
P_ ((struct window
*, struct glyph_row
*));
791 static int redisplay_mode_lines
P_ ((Lisp_Object
, int));
792 static char *decode_mode_spec_coding
P_ ((Lisp_Object
, char *, int));
795 static int invisible_text_between_p
P_ ((struct it
*, int, int));
798 static int next_element_from_ellipsis
P_ ((struct it
*));
799 static void pint2str
P_ ((char *, int, int));
800 static void pint2hrstr
P_ ((char *, int, int));
801 static struct text_pos run_window_scroll_functions
P_ ((Lisp_Object
,
803 static void reconsider_clip_changes
P_ ((struct window
*, struct buffer
*));
804 static int text_outside_line_unchanged_p
P_ ((struct window
*, int, int));
805 static void store_frame_title_char
P_ ((char));
806 static int store_frame_title
P_ ((const unsigned char *, int, int));
807 static void x_consider_frame_title
P_ ((Lisp_Object
));
808 static void handle_stop
P_ ((struct it
*));
809 static int tool_bar_lines_needed
P_ ((struct frame
*));
810 static int single_display_prop_intangible_p
P_ ((Lisp_Object
));
811 static void ensure_echo_area_buffers
P_ ((void));
812 static Lisp_Object unwind_with_echo_area_buffer
P_ ((Lisp_Object
));
813 static Lisp_Object with_echo_area_buffer_unwind_data
P_ ((struct window
*));
814 static int with_echo_area_buffer
P_ ((struct window
*, int,
815 int (*) (EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
),
816 EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
817 static void clear_garbaged_frames
P_ ((void));
818 static int current_message_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
819 static int truncate_message_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
820 static int set_message_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
821 static int display_echo_area
P_ ((struct window
*));
822 static int display_echo_area_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
823 static int resize_mini_window_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
824 static Lisp_Object unwind_redisplay
P_ ((Lisp_Object
));
825 static int string_char_and_length
P_ ((const unsigned char *, int, int *));
826 static struct text_pos display_prop_end
P_ ((struct it
*, Lisp_Object
,
828 static int compute_window_start_on_continuation_line
P_ ((struct window
*));
829 static Lisp_Object safe_eval_handler
P_ ((Lisp_Object
));
830 static void insert_left_trunc_glyphs
P_ ((struct it
*));
831 static struct glyph_row
*get_overlay_arrow_glyph_row
P_ ((struct window
*));
832 static void extend_face_to_end_of_line
P_ ((struct it
*));
833 static int append_space
P_ ((struct it
*, int));
834 static int make_cursor_line_fully_visible
P_ ((struct window
*));
835 static int try_scrolling
P_ ((Lisp_Object
, int, EMACS_INT
, EMACS_INT
, int, int));
836 static int try_cursor_movement
P_ ((Lisp_Object
, struct text_pos
, int *));
837 static int trailing_whitespace_p
P_ ((int));
838 static int message_log_check_duplicate
P_ ((int, int, int, int));
839 static void push_it
P_ ((struct it
*));
840 static void pop_it
P_ ((struct it
*));
841 static void sync_frame_with_window_matrix_rows
P_ ((struct window
*));
842 static void select_frame_for_redisplay
P_ ((Lisp_Object
));
843 static void redisplay_internal
P_ ((int));
844 static int echo_area_display
P_ ((int));
845 static void redisplay_windows
P_ ((Lisp_Object
));
846 static void redisplay_window
P_ ((Lisp_Object
, int));
847 static Lisp_Object
redisplay_window_error ();
848 static Lisp_Object redisplay_window_0
P_ ((Lisp_Object
));
849 static Lisp_Object redisplay_window_1
P_ ((Lisp_Object
));
850 static void update_menu_bar
P_ ((struct frame
*, int));
851 static int try_window_reusing_current_matrix
P_ ((struct window
*));
852 static int try_window_id
P_ ((struct window
*));
853 static int display_line
P_ ((struct it
*));
854 static int display_mode_lines
P_ ((struct window
*));
855 static int display_mode_line
P_ ((struct window
*, enum face_id
, Lisp_Object
));
856 static int display_mode_element
P_ ((struct it
*, int, int, int, Lisp_Object
, Lisp_Object
, int));
857 static int store_mode_line_string
P_ ((char *, Lisp_Object
, int, int, int, Lisp_Object
));
858 static char *decode_mode_spec
P_ ((struct window
*, int, int, int, int *));
859 static void display_menu_bar
P_ ((struct window
*));
860 static int display_count_lines
P_ ((int, int, int, int, int *));
861 static int display_string
P_ ((unsigned char *, Lisp_Object
, Lisp_Object
,
862 int, int, struct it
*, int, int, int, int));
863 static void compute_line_metrics
P_ ((struct it
*));
864 static void run_redisplay_end_trigger_hook
P_ ((struct it
*));
865 static int get_overlay_strings
P_ ((struct it
*, int));
866 static void next_overlay_string
P_ ((struct it
*));
867 static void reseat
P_ ((struct it
*, struct text_pos
, int));
868 static void reseat_1
P_ ((struct it
*, struct text_pos
, int));
869 static void back_to_previous_visible_line_start
P_ ((struct it
*));
870 static void reseat_at_previous_visible_line_start
P_ ((struct it
*));
871 static void reseat_at_next_visible_line_start
P_ ((struct it
*, int));
872 static int next_element_from_display_vector
P_ ((struct it
*));
873 static int next_element_from_string
P_ ((struct it
*));
874 static int next_element_from_c_string
P_ ((struct it
*));
875 static int next_element_from_buffer
P_ ((struct it
*));
876 static int next_element_from_composition
P_ ((struct it
*));
877 static int next_element_from_image
P_ ((struct it
*));
878 static int next_element_from_stretch
P_ ((struct it
*));
879 static void load_overlay_strings
P_ ((struct it
*, int));
880 static int init_from_display_pos
P_ ((struct it
*, struct window
*,
881 struct display_pos
*));
882 static void reseat_to_string
P_ ((struct it
*, unsigned char *,
883 Lisp_Object
, int, int, int, int));
884 static enum move_it_result move_it_in_display_line_to
P_ ((struct it
*,
886 void move_it_vertically_backward
P_ ((struct it
*, int));
887 static void init_to_row_start
P_ ((struct it
*, struct window
*,
888 struct glyph_row
*));
889 static int init_to_row_end
P_ ((struct it
*, struct window
*,
890 struct glyph_row
*));
891 static void back_to_previous_line_start
P_ ((struct it
*));
892 static int forward_to_next_line_start
P_ ((struct it
*, int *));
893 static struct text_pos string_pos_nchars_ahead
P_ ((struct text_pos
,
895 static struct text_pos string_pos
P_ ((int, Lisp_Object
));
896 static struct text_pos c_string_pos
P_ ((int, unsigned char *, int));
897 static int number_of_chars
P_ ((unsigned char *, int));
898 static void compute_stop_pos
P_ ((struct it
*));
899 static void compute_string_pos
P_ ((struct text_pos
*, struct text_pos
,
901 static int face_before_or_after_it_pos
P_ ((struct it
*, int));
902 static int next_overlay_change
P_ ((int));
903 static int handle_single_display_prop
P_ ((struct it
*, Lisp_Object
,
904 Lisp_Object
, struct text_pos
*,
906 static int underlying_face_id
P_ ((struct it
*));
907 static int in_ellipses_for_invisible_text_p
P_ ((struct display_pos
*,
910 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
911 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
913 #ifdef HAVE_WINDOW_SYSTEM
915 static void update_tool_bar
P_ ((struct frame
*, int));
916 static void build_desired_tool_bar_string
P_ ((struct frame
*f
));
917 static int redisplay_tool_bar
P_ ((struct frame
*));
918 static void display_tool_bar_line
P_ ((struct it
*));
919 static void notice_overwritten_cursor
P_ ((struct window
*,
921 int, int, int, int));
925 #endif /* HAVE_WINDOW_SYSTEM */
928 /***********************************************************************
929 Window display dimensions
930 ***********************************************************************/
932 /* Return the bottom boundary y-position for text lines in window W.
933 This is the first y position at which a line cannot start.
934 It is relative to the top of the window.
936 This is the height of W minus the height of a mode line, if any. */
939 window_text_bottom_y (w
)
942 int height
= WINDOW_TOTAL_HEIGHT (w
);
944 if (WINDOW_WANTS_MODELINE_P (w
))
945 height
-= CURRENT_MODE_LINE_HEIGHT (w
);
949 /* Return the pixel width of display area AREA of window W. AREA < 0
950 means return the total width of W, not including fringes to
951 the left and right of the window. */
954 window_box_width (w
, area
)
958 int cols
= XFASTINT (w
->total_cols
);
961 if (!w
->pseudo_window_p
)
963 cols
-= WINDOW_SCROLL_BAR_COLS (w
);
965 if (area
== TEXT_AREA
)
967 if (INTEGERP (w
->left_margin_cols
))
968 cols
-= XFASTINT (w
->left_margin_cols
);
969 if (INTEGERP (w
->right_margin_cols
))
970 cols
-= XFASTINT (w
->right_margin_cols
);
971 pixels
= -WINDOW_TOTAL_FRINGE_WIDTH (w
);
973 else if (area
== LEFT_MARGIN_AREA
)
975 cols
= (INTEGERP (w
->left_margin_cols
)
976 ? XFASTINT (w
->left_margin_cols
) : 0);
979 else if (area
== RIGHT_MARGIN_AREA
)
981 cols
= (INTEGERP (w
->right_margin_cols
)
982 ? XFASTINT (w
->right_margin_cols
) : 0);
987 return cols
* WINDOW_FRAME_COLUMN_WIDTH (w
) + pixels
;
991 /* Return the pixel height of the display area of window W, not
992 including mode lines of W, if any. */
995 window_box_height (w
)
998 struct frame
*f
= XFRAME (w
->frame
);
999 int height
= WINDOW_TOTAL_HEIGHT (w
);
1001 xassert (height
>= 0);
1003 /* Note: the code below that determines the mode-line/header-line
1004 height is essentially the same as that contained in the macro
1005 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1006 the appropriate glyph row has its `mode_line_p' flag set,
1007 and if it doesn't, uses estimate_mode_line_height instead. */
1009 if (WINDOW_WANTS_MODELINE_P (w
))
1011 struct glyph_row
*ml_row
1012 = (w
->current_matrix
&& w
->current_matrix
->rows
1013 ? MATRIX_MODE_LINE_ROW (w
->current_matrix
)
1015 if (ml_row
&& ml_row
->mode_line_p
)
1016 height
-= ml_row
->height
;
1018 height
-= estimate_mode_line_height (f
, CURRENT_MODE_LINE_FACE_ID (w
));
1021 if (WINDOW_WANTS_HEADER_LINE_P (w
))
1023 struct glyph_row
*hl_row
1024 = (w
->current_matrix
&& w
->current_matrix
->rows
1025 ? MATRIX_HEADER_LINE_ROW (w
->current_matrix
)
1027 if (hl_row
&& hl_row
->mode_line_p
)
1028 height
-= hl_row
->height
;
1030 height
-= estimate_mode_line_height (f
, HEADER_LINE_FACE_ID
);
1033 /* With a very small font and a mode-line that's taller than
1034 default, we might end up with a negative height. */
1035 return max (0, height
);
1038 /* Return the window-relative coordinate of the left edge of display
1039 area AREA of window W. AREA < 0 means return the left edge of the
1040 whole window, to the right of the left fringe of W. */
1043 window_box_left_offset (w
, area
)
1049 if (w
->pseudo_window_p
)
1052 x
= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w
);
1054 if (area
== TEXT_AREA
)
1055 x
+= (WINDOW_LEFT_FRINGE_WIDTH (w
)
1056 + window_box_width (w
, LEFT_MARGIN_AREA
));
1057 else if (area
== RIGHT_MARGIN_AREA
)
1058 x
+= (WINDOW_LEFT_FRINGE_WIDTH (w
)
1059 + window_box_width (w
, LEFT_MARGIN_AREA
)
1060 + window_box_width (w
, TEXT_AREA
)
1061 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
1063 : WINDOW_RIGHT_FRINGE_WIDTH (w
)));
1064 else if (area
== LEFT_MARGIN_AREA
1065 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
))
1066 x
+= WINDOW_LEFT_FRINGE_WIDTH (w
);
1072 /* Return the window-relative coordinate of the right edge of display
1073 area AREA of window W. AREA < 0 means return the left edge of the
1074 whole window, to the left of the right fringe of W. */
1077 window_box_right_offset (w
, area
)
1081 return window_box_left_offset (w
, area
) + window_box_width (w
, area
);
1084 /* Return the frame-relative coordinate of the left edge of display
1085 area AREA of window W. AREA < 0 means return the left edge of the
1086 whole window, to the right of the left fringe of W. */
1089 window_box_left (w
, area
)
1093 struct frame
*f
= XFRAME (w
->frame
);
1096 if (w
->pseudo_window_p
)
1097 return FRAME_INTERNAL_BORDER_WIDTH (f
);
1099 x
= (WINDOW_LEFT_EDGE_X (w
)
1100 + window_box_left_offset (w
, area
));
1106 /* Return the frame-relative coordinate of the right edge of display
1107 area AREA of window W. AREA < 0 means return the left edge of the
1108 whole window, to the left of the right fringe of W. */
1111 window_box_right (w
, area
)
1115 return window_box_left (w
, area
) + window_box_width (w
, area
);
1118 /* Get the bounding box of the display area AREA of window W, without
1119 mode lines, in frame-relative coordinates. AREA < 0 means the
1120 whole window, not including the left and right fringes of
1121 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1122 coordinates of the upper-left corner of the box. Return in
1123 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1126 window_box (w
, area
, box_x
, box_y
, box_width
, box_height
)
1129 int *box_x
, *box_y
, *box_width
, *box_height
;
1132 *box_width
= window_box_width (w
, area
);
1134 *box_height
= window_box_height (w
);
1136 *box_x
= window_box_left (w
, area
);
1139 *box_y
= WINDOW_TOP_EDGE_Y (w
);
1140 if (WINDOW_WANTS_HEADER_LINE_P (w
))
1141 *box_y
+= CURRENT_HEADER_LINE_HEIGHT (w
);
1146 /* Get the bounding box of the display area AREA of window W, without
1147 mode lines. AREA < 0 means the whole window, not including the
1148 left and right fringe of the window. Return in *TOP_LEFT_X
1149 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1150 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1151 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1155 window_box_edges (w
, area
, top_left_x
, top_left_y
,
1156 bottom_right_x
, bottom_right_y
)
1159 int *top_left_x
, *top_left_y
, *bottom_right_x
, *bottom_right_y
;
1161 window_box (w
, area
, top_left_x
, top_left_y
, bottom_right_x
,
1163 *bottom_right_x
+= *top_left_x
;
1164 *bottom_right_y
+= *top_left_y
;
1169 /***********************************************************************
1171 ***********************************************************************/
1173 /* Return the bottom y-position of the line the iterator IT is in.
1174 This can modify IT's settings. */
1180 int line_height
= it
->max_ascent
+ it
->max_descent
;
1181 int line_top_y
= it
->current_y
;
1183 if (line_height
== 0)
1186 line_height
= last_height
;
1187 else if (IT_CHARPOS (*it
) < ZV
)
1189 move_it_by_lines (it
, 1, 1);
1190 line_height
= (it
->max_ascent
|| it
->max_descent
1191 ? it
->max_ascent
+ it
->max_descent
1196 struct glyph_row
*row
= it
->glyph_row
;
1198 /* Use the default character height. */
1199 it
->glyph_row
= NULL
;
1200 it
->what
= IT_CHARACTER
;
1203 PRODUCE_GLYPHS (it
);
1204 line_height
= it
->ascent
+ it
->descent
;
1205 it
->glyph_row
= row
;
1209 return line_top_y
+ line_height
;
1213 /* Return 1 if position CHARPOS is visible in window W. Set *FULLY to
1214 1 if POS is visible and the line containing POS is fully visible.
1215 EXACT_MODE_LINE_HEIGHTS_P non-zero means compute exact mode-line
1216 and header-lines heights. */
1219 pos_visible_p (w
, charpos
, fully
, exact_mode_line_heights_p
)
1221 int charpos
, *fully
, exact_mode_line_heights_p
;
1224 struct text_pos top
;
1226 struct buffer
*old_buffer
= NULL
;
1228 if (XBUFFER (w
->buffer
) != current_buffer
)
1230 old_buffer
= current_buffer
;
1231 set_buffer_internal_1 (XBUFFER (w
->buffer
));
1234 *fully
= visible_p
= 0;
1235 SET_TEXT_POS_FROM_MARKER (top
, w
->start
);
1237 /* Compute exact mode line heights, if requested. */
1238 if (exact_mode_line_heights_p
)
1240 if (WINDOW_WANTS_MODELINE_P (w
))
1241 current_mode_line_height
1242 = display_mode_line (w
, CURRENT_MODE_LINE_FACE_ID (w
),
1243 current_buffer
->mode_line_format
);
1245 if (WINDOW_WANTS_HEADER_LINE_P (w
))
1246 current_header_line_height
1247 = display_mode_line (w
, HEADER_LINE_FACE_ID
,
1248 current_buffer
->header_line_format
);
1251 start_display (&it
, w
, top
);
1252 move_it_to (&it
, charpos
, 0, it
.last_visible_y
, -1,
1253 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
1255 /* Note that we may overshoot because of invisible text. */
1256 if (IT_CHARPOS (it
) >= charpos
)
1258 int top_y
= it
.current_y
;
1259 int bottom_y
= line_bottom_y (&it
);
1260 int window_top_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
1262 if (top_y
< window_top_y
)
1263 visible_p
= bottom_y
> window_top_y
;
1264 else if (top_y
< it
.last_visible_y
)
1267 *fully
= bottom_y
<= it
.last_visible_y
;
1270 else if (it
.current_y
+ it
.max_ascent
+ it
.max_descent
> it
.last_visible_y
)
1272 move_it_by_lines (&it
, 1, 0);
1273 if (charpos
< IT_CHARPOS (it
))
1281 set_buffer_internal_1 (old_buffer
);
1283 current_header_line_height
= current_mode_line_height
= -1;
1288 /* Return the next character from STR which is MAXLEN bytes long.
1289 Return in *LEN the length of the character. This is like
1290 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1291 we find one, we return a `?', but with the length of the invalid
1295 string_char_and_length (str
, maxlen
, len
)
1296 const unsigned char *str
;
1301 c
= STRING_CHAR_AND_LENGTH (str
, maxlen
, *len
);
1302 if (!CHAR_VALID_P (c
, 1))
1303 /* We may not change the length here because other places in Emacs
1304 don't use this function, i.e. they silently accept invalid
1313 /* Given a position POS containing a valid character and byte position
1314 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1316 static struct text_pos
1317 string_pos_nchars_ahead (pos
, string
, nchars
)
1318 struct text_pos pos
;
1322 xassert (STRINGP (string
) && nchars
>= 0);
1324 if (STRING_MULTIBYTE (string
))
1326 int rest
= SBYTES (string
) - BYTEPOS (pos
);
1327 const unsigned char *p
= SDATA (string
) + BYTEPOS (pos
);
1332 string_char_and_length (p
, rest
, &len
);
1333 p
+= len
, rest
-= len
;
1334 xassert (rest
>= 0);
1336 BYTEPOS (pos
) += len
;
1340 SET_TEXT_POS (pos
, CHARPOS (pos
) + nchars
, BYTEPOS (pos
) + nchars
);
1346 /* Value is the text position, i.e. character and byte position,
1347 for character position CHARPOS in STRING. */
1349 static INLINE
struct text_pos
1350 string_pos (charpos
, string
)
1354 struct text_pos pos
;
1355 xassert (STRINGP (string
));
1356 xassert (charpos
>= 0);
1357 SET_TEXT_POS (pos
, charpos
, string_char_to_byte (string
, charpos
));
1362 /* Value is a text position, i.e. character and byte position, for
1363 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1364 means recognize multibyte characters. */
1366 static struct text_pos
1367 c_string_pos (charpos
, s
, multibyte_p
)
1372 struct text_pos pos
;
1374 xassert (s
!= NULL
);
1375 xassert (charpos
>= 0);
1379 int rest
= strlen (s
), len
;
1381 SET_TEXT_POS (pos
, 0, 0);
1384 string_char_and_length (s
, rest
, &len
);
1385 s
+= len
, rest
-= len
;
1386 xassert (rest
>= 0);
1388 BYTEPOS (pos
) += len
;
1392 SET_TEXT_POS (pos
, charpos
, charpos
);
1398 /* Value is the number of characters in C string S. MULTIBYTE_P
1399 non-zero means recognize multibyte characters. */
1402 number_of_chars (s
, multibyte_p
)
1410 int rest
= strlen (s
), len
;
1411 unsigned char *p
= (unsigned char *) s
;
1413 for (nchars
= 0; rest
> 0; ++nchars
)
1415 string_char_and_length (p
, rest
, &len
);
1416 rest
-= len
, p
+= len
;
1420 nchars
= strlen (s
);
1426 /* Compute byte position NEWPOS->bytepos corresponding to
1427 NEWPOS->charpos. POS is a known position in string STRING.
1428 NEWPOS->charpos must be >= POS.charpos. */
1431 compute_string_pos (newpos
, pos
, string
)
1432 struct text_pos
*newpos
, pos
;
1435 xassert (STRINGP (string
));
1436 xassert (CHARPOS (*newpos
) >= CHARPOS (pos
));
1438 if (STRING_MULTIBYTE (string
))
1439 *newpos
= string_pos_nchars_ahead (pos
, string
,
1440 CHARPOS (*newpos
) - CHARPOS (pos
));
1442 BYTEPOS (*newpos
) = CHARPOS (*newpos
);
1446 Return an estimation of the pixel height of mode or top lines on
1447 frame F. FACE_ID specifies what line's height to estimate. */
1450 estimate_mode_line_height (f
, face_id
)
1452 enum face_id face_id
;
1454 #ifdef HAVE_WINDOW_SYSTEM
1455 if (FRAME_WINDOW_P (f
))
1457 int height
= FONT_HEIGHT (FRAME_FONT (f
));
1459 /* This function is called so early when Emacs starts that the face
1460 cache and mode line face are not yet initialized. */
1461 if (FRAME_FACE_CACHE (f
))
1463 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1467 height
= FONT_HEIGHT (face
->font
);
1468 if (face
->box_line_width
> 0)
1469 height
+= 2 * face
->box_line_width
;
1480 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1481 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1482 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1483 not force the value into range. */
1486 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
, noclip
)
1488 register int pix_x
, pix_y
;
1490 NativeRectangle
*bounds
;
1494 #ifdef HAVE_WINDOW_SYSTEM
1495 if (FRAME_WINDOW_P (f
))
1497 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1498 even for negative values. */
1500 pix_x
-= FRAME_COLUMN_WIDTH (f
) - 1;
1502 pix_y
-= FRAME_LINE_HEIGHT (f
) - 1;
1504 pix_x
= FRAME_PIXEL_X_TO_COL (f
, pix_x
);
1505 pix_y
= FRAME_PIXEL_Y_TO_LINE (f
, pix_y
);
1508 STORE_NATIVE_RECT (*bounds
,
1509 FRAME_COL_TO_PIXEL_X (f
, pix_x
),
1510 FRAME_LINE_TO_PIXEL_Y (f
, pix_y
),
1511 FRAME_COLUMN_WIDTH (f
) - 1,
1512 FRAME_LINE_HEIGHT (f
) - 1);
1518 else if (pix_x
> FRAME_TOTAL_COLS (f
))
1519 pix_x
= FRAME_TOTAL_COLS (f
);
1523 else if (pix_y
> FRAME_LINES (f
))
1524 pix_y
= FRAME_LINES (f
);
1534 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1535 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1536 can't tell the positions because W's display is not up to date,
1540 glyph_to_pixel_coords (w
, hpos
, vpos
, frame_x
, frame_y
)
1543 int *frame_x
, *frame_y
;
1545 #ifdef HAVE_WINDOW_SYSTEM
1546 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w
))))
1550 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
1551 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
1553 if (display_completed
)
1555 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
1556 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
1557 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
1563 hpos
+= glyph
->pixel_width
;
1567 /* If first glyph is partially visible, its first visible position is still 0. */
1579 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, hpos
);
1580 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, vpos
);
1591 #ifdef HAVE_WINDOW_SYSTEM
1593 /* Find the glyph under window-relative coordinates X/Y in window W.
1594 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1595 strings. Return in *HPOS and *VPOS the row and column number of
1596 the glyph found. Return in *AREA the glyph area containing X.
1597 Value is a pointer to the glyph found or null if X/Y is not on
1598 text, or we can't tell because W's current matrix is not up to
1601 static struct glyph
*
1602 x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, dx
, dy
, area
)
1605 int *hpos
, *vpos
, *dx
, *dy
, *area
;
1607 struct glyph
*glyph
, *end
;
1608 struct glyph_row
*row
= NULL
;
1611 /* Find row containing Y. Give up if some row is not enabled. */
1612 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
1614 row
= MATRIX_ROW (w
->current_matrix
, i
);
1615 if (!row
->enabled_p
)
1617 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
1624 /* Give up if Y is not in the window. */
1625 if (i
== w
->current_matrix
->nrows
)
1628 /* Get the glyph area containing X. */
1629 if (w
->pseudo_window_p
)
1636 if (x
< window_box_left_offset (w
, TEXT_AREA
))
1638 *area
= LEFT_MARGIN_AREA
;
1639 x0
= window_box_left_offset (w
, LEFT_MARGIN_AREA
);
1641 else if (x
< window_box_right_offset (w
, TEXT_AREA
))
1644 x0
= window_box_left_offset (w
, TEXT_AREA
) + min (row
->x
, 0);
1648 *area
= RIGHT_MARGIN_AREA
;
1649 x0
= window_box_left_offset (w
, RIGHT_MARGIN_AREA
);
1653 /* Find glyph containing X. */
1654 glyph
= row
->glyphs
[*area
];
1655 end
= glyph
+ row
->used
[*area
];
1657 while (glyph
< end
&& x
>= glyph
->pixel_width
)
1659 x
-= glyph
->pixel_width
;
1669 *dy
= y
- (row
->y
+ row
->ascent
- glyph
->ascent
);
1672 *hpos
= glyph
- row
->glyphs
[*area
];
1678 Convert frame-relative x/y to coordinates relative to window W.
1679 Takes pseudo-windows into account. */
1682 frame_to_window_pixel_xy (w
, x
, y
)
1686 if (w
->pseudo_window_p
)
1688 /* A pseudo-window is always full-width, and starts at the
1689 left edge of the frame, plus a frame border. */
1690 struct frame
*f
= XFRAME (w
->frame
);
1691 *x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
1692 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
1696 *x
-= WINDOW_LEFT_EDGE_X (w
);
1697 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
1702 Return in *R the clipping rectangle for glyph string S. */
1705 get_glyph_string_clip_rect (s
, nr
)
1706 struct glyph_string
*s
;
1707 NativeRectangle
*nr
;
1711 if (s
->row
->full_width_p
)
1713 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1714 r
.x
= WINDOW_LEFT_EDGE_X (s
->w
);
1715 r
.width
= WINDOW_TOTAL_WIDTH (s
->w
);
1717 /* Unless displaying a mode or menu bar line, which are always
1718 fully visible, clip to the visible part of the row. */
1719 if (s
->w
->pseudo_window_p
)
1720 r
.height
= s
->row
->visible_height
;
1722 r
.height
= s
->height
;
1726 /* This is a text line that may be partially visible. */
1727 r
.x
= window_box_left (s
->w
, s
->area
);
1728 r
.width
= window_box_width (s
->w
, s
->area
);
1729 r
.height
= s
->row
->visible_height
;
1732 /* If S draws overlapping rows, it's sufficient to use the top and
1733 bottom of the window for clipping because this glyph string
1734 intentionally draws over other lines. */
1735 if (s
->for_overlaps_p
)
1737 r
.y
= WINDOW_HEADER_LINE_HEIGHT (s
->w
);
1738 r
.height
= window_text_bottom_y (s
->w
) - r
.y
;
1742 /* Don't use S->y for clipping because it doesn't take partially
1743 visible lines into account. For example, it can be negative for
1744 partially visible lines at the top of a window. */
1745 if (!s
->row
->full_width_p
1746 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
1747 r
.y
= WINDOW_HEADER_LINE_HEIGHT (s
->w
);
1749 r
.y
= max (0, s
->row
->y
);
1751 /* If drawing a tool-bar window, draw it over the internal border
1752 at the top of the window. */
1753 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
1754 r
.y
-= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
1757 r
.y
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
.y
);
1759 /* If drawing the cursor, don't let glyph draw outside its
1760 advertised boundaries. Cleartype does this under some circumstances. */
1761 if (s
->hl
== DRAW_CURSOR
)
1763 struct glyph
*glyph
= s
->first_glyph
;
1768 r
.width
-= s
->x
- r
.x
;
1771 r
.width
= min (r
.width
, glyph
->pixel_width
);
1773 /* Don't draw cursor glyph taller than our actual glyph. */
1774 height
= max (FRAME_LINE_HEIGHT (s
->f
), glyph
->ascent
+ glyph
->descent
);
1775 if (height
< r
.height
)
1777 r
.y
= s
->ybase
+ glyph
->descent
- height
;
1782 #ifdef CONVERT_FROM_XRECT
1783 CONVERT_FROM_XRECT (r
, *nr
);
1789 #endif /* HAVE_WINDOW_SYSTEM */
1792 /***********************************************************************
1793 Lisp form evaluation
1794 ***********************************************************************/
1796 /* Error handler for safe_eval and safe_call. */
1799 safe_eval_handler (arg
)
1802 add_to_log ("Error during redisplay: %s", arg
, Qnil
);
1807 /* Evaluate SEXPR and return the result, or nil if something went
1808 wrong. Prevent redisplay during the evaluation. */
1816 if (inhibit_eval_during_redisplay
)
1820 int count
= SPECPDL_INDEX ();
1821 struct gcpro gcpro1
;
1824 specbind (Qinhibit_redisplay
, Qt
);
1825 /* Use Qt to ensure debugger does not run,
1826 so there is no possibility of wanting to redisplay. */
1827 val
= internal_condition_case_1 (Feval
, sexpr
, Qt
,
1830 val
= unbind_to (count
, val
);
1837 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
1838 Return the result, or nil if something went wrong. Prevent
1839 redisplay during the evaluation. */
1842 safe_call (nargs
, args
)
1848 if (inhibit_eval_during_redisplay
)
1852 int count
= SPECPDL_INDEX ();
1853 struct gcpro gcpro1
;
1856 gcpro1
.nvars
= nargs
;
1857 specbind (Qinhibit_redisplay
, Qt
);
1858 /* Use Qt to ensure debugger does not run,
1859 so there is no possibility of wanting to redisplay. */
1860 val
= internal_condition_case_2 (Ffuncall
, nargs
, args
, Qt
,
1863 val
= unbind_to (count
, val
);
1870 /* Call function FN with one argument ARG.
1871 Return the result, or nil if something went wrong. */
1874 safe_call1 (fn
, arg
)
1875 Lisp_Object fn
, arg
;
1877 Lisp_Object args
[2];
1880 return safe_call (2, args
);
1885 /***********************************************************************
1887 ***********************************************************************/
1891 /* Define CHECK_IT to perform sanity checks on iterators.
1892 This is for debugging. It is too slow to do unconditionally. */
1898 if (it
->method
== next_element_from_string
)
1900 xassert (STRINGP (it
->string
));
1901 xassert (IT_STRING_CHARPOS (*it
) >= 0);
1903 else if (it
->method
== next_element_from_buffer
)
1905 /* Check that character and byte positions agree. */
1906 xassert (IT_CHARPOS (*it
) == BYTE_TO_CHAR (IT_BYTEPOS (*it
)));
1910 xassert (it
->current
.dpvec_index
>= 0);
1912 xassert (it
->current
.dpvec_index
< 0);
1915 #define CHECK_IT(IT) check_it ((IT))
1919 #define CHECK_IT(IT) (void) 0
1926 /* Check that the window end of window W is what we expect it
1927 to be---the last row in the current matrix displaying text. */
1930 check_window_end (w
)
1933 if (!MINI_WINDOW_P (w
)
1934 && !NILP (w
->window_end_valid
))
1936 struct glyph_row
*row
;
1937 xassert ((row
= MATRIX_ROW (w
->current_matrix
,
1938 XFASTINT (w
->window_end_vpos
)),
1940 || MATRIX_ROW_DISPLAYS_TEXT_P (row
)
1941 || MATRIX_ROW_VPOS (row
, w
->current_matrix
) == 0));
1945 #define CHECK_WINDOW_END(W) check_window_end ((W))
1947 #else /* not GLYPH_DEBUG */
1949 #define CHECK_WINDOW_END(W) (void) 0
1951 #endif /* not GLYPH_DEBUG */
1955 /***********************************************************************
1956 Iterator initialization
1957 ***********************************************************************/
1959 /* Initialize IT for displaying current_buffer in window W, starting
1960 at character position CHARPOS. CHARPOS < 0 means that no buffer
1961 position is specified which is useful when the iterator is assigned
1962 a position later. BYTEPOS is the byte position corresponding to
1963 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
1965 If ROW is not null, calls to produce_glyphs with IT as parameter
1966 will produce glyphs in that row.
1968 BASE_FACE_ID is the id of a base face to use. It must be one of
1969 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
1970 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
1971 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
1973 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
1974 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
1975 will be initialized to use the corresponding mode line glyph row of
1976 the desired matrix of W. */
1979 init_iterator (it
, w
, charpos
, bytepos
, row
, base_face_id
)
1982 int charpos
, bytepos
;
1983 struct glyph_row
*row
;
1984 enum face_id base_face_id
;
1986 int highlight_region_p
;
1988 /* Some precondition checks. */
1989 xassert (w
!= NULL
&& it
!= NULL
);
1990 xassert (charpos
< 0 || (charpos
>= BUF_BEG (current_buffer
)
1993 /* If face attributes have been changed since the last redisplay,
1994 free realized faces now because they depend on face definitions
1995 that might have changed. Don't free faces while there might be
1996 desired matrices pending which reference these faces. */
1997 if (face_change_count
&& !inhibit_free_realized_faces
)
1999 face_change_count
= 0;
2000 free_all_realized_faces (Qnil
);
2003 /* Use one of the mode line rows of W's desired matrix if
2007 if (base_face_id
== MODE_LINE_FACE_ID
2008 || base_face_id
== MODE_LINE_INACTIVE_FACE_ID
)
2009 row
= MATRIX_MODE_LINE_ROW (w
->desired_matrix
);
2010 else if (base_face_id
== HEADER_LINE_FACE_ID
)
2011 row
= MATRIX_HEADER_LINE_ROW (w
->desired_matrix
);
2015 bzero (it
, sizeof *it
);
2016 it
->current
.overlay_string_index
= -1;
2017 it
->current
.dpvec_index
= -1;
2018 it
->base_face_id
= base_face_id
;
2020 /* The window in which we iterate over current_buffer: */
2021 XSETWINDOW (it
->window
, w
);
2023 it
->f
= XFRAME (w
->frame
);
2025 /* Extra space between lines (on window systems only). */
2026 if (base_face_id
== DEFAULT_FACE_ID
2027 && FRAME_WINDOW_P (it
->f
))
2029 if (NATNUMP (current_buffer
->extra_line_spacing
))
2030 it
->extra_line_spacing
= XFASTINT (current_buffer
->extra_line_spacing
);
2031 else if (it
->f
->extra_line_spacing
> 0)
2032 it
->extra_line_spacing
= it
->f
->extra_line_spacing
;
2035 /* If realized faces have been removed, e.g. because of face
2036 attribute changes of named faces, recompute them. When running
2037 in batch mode, the face cache of the initial frame is null. If
2038 we happen to get called, make a dummy face cache. */
2039 if (FRAME_FACE_CACHE (it
->f
) == NULL
)
2040 init_frame_faces (it
->f
);
2041 if (FRAME_FACE_CACHE (it
->f
)->used
== 0)
2042 recompute_basic_faces (it
->f
);
2044 /* Current value of the `space-width', and 'height' properties. */
2045 it
->space_width
= Qnil
;
2046 it
->font_height
= Qnil
;
2048 /* Are control characters displayed as `^C'? */
2049 it
->ctl_arrow_p
= !NILP (current_buffer
->ctl_arrow
);
2051 /* -1 means everything between a CR and the following line end
2052 is invisible. >0 means lines indented more than this value are
2054 it
->selective
= (INTEGERP (current_buffer
->selective_display
)
2055 ? XFASTINT (current_buffer
->selective_display
)
2056 : (!NILP (current_buffer
->selective_display
)
2058 it
->selective_display_ellipsis_p
2059 = !NILP (current_buffer
->selective_display_ellipses
);
2061 /* Display table to use. */
2062 it
->dp
= window_display_table (w
);
2064 /* Are multibyte characters enabled in current_buffer? */
2065 it
->multibyte_p
= !NILP (current_buffer
->enable_multibyte_characters
);
2067 /* Non-zero if we should highlight the region. */
2069 = (!NILP (Vtransient_mark_mode
)
2070 && !NILP (current_buffer
->mark_active
)
2071 && XMARKER (current_buffer
->mark
)->buffer
!= 0);
2073 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2074 start and end of a visible region in window IT->w. Set both to
2075 -1 to indicate no region. */
2076 if (highlight_region_p
2077 /* Maybe highlight only in selected window. */
2078 && (/* Either show region everywhere. */
2079 highlight_nonselected_windows
2080 /* Or show region in the selected window. */
2081 || w
== XWINDOW (selected_window
)
2082 /* Or show the region if we are in the mini-buffer and W is
2083 the window the mini-buffer refers to. */
2084 || (MINI_WINDOW_P (XWINDOW (selected_window
))
2085 && WINDOWP (minibuf_selected_window
)
2086 && w
== XWINDOW (minibuf_selected_window
))))
2088 int charpos
= marker_position (current_buffer
->mark
);
2089 it
->region_beg_charpos
= min (PT
, charpos
);
2090 it
->region_end_charpos
= max (PT
, charpos
);
2093 it
->region_beg_charpos
= it
->region_end_charpos
= -1;
2095 /* Get the position at which the redisplay_end_trigger hook should
2096 be run, if it is to be run at all. */
2097 if (MARKERP (w
->redisplay_end_trigger
)
2098 && XMARKER (w
->redisplay_end_trigger
)->buffer
!= 0)
2099 it
->redisplay_end_trigger_charpos
2100 = marker_position (w
->redisplay_end_trigger
);
2101 else if (INTEGERP (w
->redisplay_end_trigger
))
2102 it
->redisplay_end_trigger_charpos
= XINT (w
->redisplay_end_trigger
);
2104 /* Correct bogus values of tab_width. */
2105 it
->tab_width
= XINT (current_buffer
->tab_width
);
2106 if (it
->tab_width
<= 0 || it
->tab_width
> 1000)
2109 /* Are lines in the display truncated? */
2110 it
->truncate_lines_p
2111 = (base_face_id
!= DEFAULT_FACE_ID
2112 || XINT (it
->w
->hscroll
)
2113 || (truncate_partial_width_windows
2114 && !WINDOW_FULL_WIDTH_P (it
->w
))
2115 || !NILP (current_buffer
->truncate_lines
));
2117 /* Get dimensions of truncation and continuation glyphs. These are
2118 displayed as fringe bitmaps under X, so we don't need them for such
2120 if (!FRAME_WINDOW_P (it
->f
))
2122 if (it
->truncate_lines_p
)
2124 /* We will need the truncation glyph. */
2125 xassert (it
->glyph_row
== NULL
);
2126 produce_special_glyphs (it
, IT_TRUNCATION
);
2127 it
->truncation_pixel_width
= it
->pixel_width
;
2131 /* We will need the continuation glyph. */
2132 xassert (it
->glyph_row
== NULL
);
2133 produce_special_glyphs (it
, IT_CONTINUATION
);
2134 it
->continuation_pixel_width
= it
->pixel_width
;
2137 /* Reset these values to zero because the produce_special_glyphs
2138 above has changed them. */
2139 it
->pixel_width
= it
->ascent
= it
->descent
= 0;
2140 it
->phys_ascent
= it
->phys_descent
= 0;
2143 /* Set this after getting the dimensions of truncation and
2144 continuation glyphs, so that we don't produce glyphs when calling
2145 produce_special_glyphs, above. */
2146 it
->glyph_row
= row
;
2147 it
->area
= TEXT_AREA
;
2149 /* Get the dimensions of the display area. The display area
2150 consists of the visible window area plus a horizontally scrolled
2151 part to the left of the window. All x-values are relative to the
2152 start of this total display area. */
2153 if (base_face_id
!= DEFAULT_FACE_ID
)
2155 /* Mode lines, menu bar in terminal frames. */
2156 it
->first_visible_x
= 0;
2157 it
->last_visible_x
= WINDOW_TOTAL_WIDTH (w
);
2162 = XFASTINT (it
->w
->hscroll
) * FRAME_COLUMN_WIDTH (it
->f
);
2163 it
->last_visible_x
= (it
->first_visible_x
2164 + window_box_width (w
, TEXT_AREA
));
2166 /* If we truncate lines, leave room for the truncator glyph(s) at
2167 the right margin. Otherwise, leave room for the continuation
2168 glyph(s). Truncation and continuation glyphs are not inserted
2169 for window-based redisplay. */
2170 if (!FRAME_WINDOW_P (it
->f
))
2172 if (it
->truncate_lines_p
)
2173 it
->last_visible_x
-= it
->truncation_pixel_width
;
2175 it
->last_visible_x
-= it
->continuation_pixel_width
;
2178 it
->header_line_p
= WINDOW_WANTS_HEADER_LINE_P (w
);
2179 it
->current_y
= WINDOW_HEADER_LINE_HEIGHT (w
) + w
->vscroll
;
2182 /* Leave room for a border glyph. */
2183 if (!FRAME_WINDOW_P (it
->f
)
2184 && !WINDOW_RIGHTMOST_P (it
->w
))
2185 it
->last_visible_x
-= 1;
2187 it
->last_visible_y
= window_text_bottom_y (w
);
2189 /* For mode lines and alike, arrange for the first glyph having a
2190 left box line if the face specifies a box. */
2191 if (base_face_id
!= DEFAULT_FACE_ID
)
2195 it
->face_id
= base_face_id
;
2197 /* If we have a boxed mode line, make the first character appear
2198 with a left box line. */
2199 face
= FACE_FROM_ID (it
->f
, base_face_id
);
2200 if (face
->box
!= FACE_NO_BOX
)
2201 it
->start_of_box_run_p
= 1;
2204 /* If a buffer position was specified, set the iterator there,
2205 getting overlays and face properties from that position. */
2206 if (charpos
>= BUF_BEG (current_buffer
))
2208 it
->end_charpos
= ZV
;
2210 IT_CHARPOS (*it
) = charpos
;
2212 /* Compute byte position if not specified. */
2213 if (bytepos
< charpos
)
2214 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (charpos
);
2216 IT_BYTEPOS (*it
) = bytepos
;
2218 it
->start
= it
->current
;
2220 /* Compute faces etc. */
2221 reseat (it
, it
->current
.pos
, 1);
2228 /* Initialize IT for the display of window W with window start POS. */
2231 start_display (it
, w
, pos
)
2234 struct text_pos pos
;
2236 struct glyph_row
*row
;
2237 int first_vpos
= WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0;
2239 row
= w
->desired_matrix
->rows
+ first_vpos
;
2240 init_iterator (it
, w
, CHARPOS (pos
), BYTEPOS (pos
), row
, DEFAULT_FACE_ID
);
2241 it
->first_vpos
= first_vpos
;
2243 if (!it
->truncate_lines_p
)
2245 int start_at_line_beg_p
;
2246 int first_y
= it
->current_y
;
2248 /* If window start is not at a line start, skip forward to POS to
2249 get the correct continuation lines width. */
2250 start_at_line_beg_p
= (CHARPOS (pos
) == BEGV
2251 || FETCH_BYTE (BYTEPOS (pos
) - 1) == '\n');
2252 if (!start_at_line_beg_p
)
2256 reseat_at_previous_visible_line_start (it
);
2257 move_it_to (it
, CHARPOS (pos
), -1, -1, -1, MOVE_TO_POS
);
2259 new_x
= it
->current_x
+ it
->pixel_width
;
2261 /* If lines are continued, this line may end in the middle
2262 of a multi-glyph character (e.g. a control character
2263 displayed as \003, or in the middle of an overlay
2264 string). In this case move_it_to above will not have
2265 taken us to the start of the continuation line but to the
2266 end of the continued line. */
2267 if (it
->current_x
> 0
2268 && !it
->truncate_lines_p
/* Lines are continued. */
2269 && (/* And glyph doesn't fit on the line. */
2270 new_x
> it
->last_visible_x
2271 /* Or it fits exactly and we're on a window
2273 || (new_x
== it
->last_visible_x
2274 && FRAME_WINDOW_P (it
->f
))))
2276 if (it
->current
.dpvec_index
>= 0
2277 || it
->current
.overlay_string_index
>= 0)
2279 set_iterator_to_next (it
, 1);
2280 move_it_in_display_line_to (it
, -1, -1, 0);
2283 it
->continuation_lines_width
+= it
->current_x
;
2286 /* We're starting a new display line, not affected by the
2287 height of the continued line, so clear the appropriate
2288 fields in the iterator structure. */
2289 it
->max_ascent
= it
->max_descent
= 0;
2290 it
->max_phys_ascent
= it
->max_phys_descent
= 0;
2292 it
->current_y
= first_y
;
2294 it
->current_x
= it
->hpos
= 0;
2298 #if 0 /* Don't assert the following because start_display is sometimes
2299 called intentionally with a window start that is not at a
2300 line start. Please leave this code in as a comment. */
2302 /* Window start should be on a line start, now. */
2303 xassert (it
->continuation_lines_width
2304 || IT_CHARPOS (it
) == BEGV
2305 || FETCH_BYTE (IT_BYTEPOS (it
) - 1) == '\n');
2310 /* Return 1 if POS is a position in ellipses displayed for invisible
2311 text. W is the window we display, for text property lookup. */
2314 in_ellipses_for_invisible_text_p (pos
, w
)
2315 struct display_pos
*pos
;
2318 Lisp_Object prop
, window
;
2320 int charpos
= CHARPOS (pos
->pos
);
2322 /* If POS specifies a position in a display vector, this might
2323 be for an ellipsis displayed for invisible text. We won't
2324 get the iterator set up for delivering that ellipsis unless
2325 we make sure that it gets aware of the invisible text. */
2326 if (pos
->dpvec_index
>= 0
2327 && pos
->overlay_string_index
< 0
2328 && CHARPOS (pos
->string_pos
) < 0
2330 && (XSETWINDOW (window
, w
),
2331 prop
= Fget_char_property (make_number (charpos
),
2332 Qinvisible
, window
),
2333 !TEXT_PROP_MEANS_INVISIBLE (prop
)))
2335 prop
= Fget_char_property (make_number (charpos
- 1), Qinvisible
,
2337 ellipses_p
= 2 == TEXT_PROP_MEANS_INVISIBLE (prop
);
2344 /* Initialize IT for stepping through current_buffer in window W,
2345 starting at position POS that includes overlay string and display
2346 vector/ control character translation position information. Value
2347 is zero if there are overlay strings with newlines at POS. */
2350 init_from_display_pos (it
, w
, pos
)
2353 struct display_pos
*pos
;
2355 int charpos
= CHARPOS (pos
->pos
), bytepos
= BYTEPOS (pos
->pos
);
2356 int i
, overlay_strings_with_newlines
= 0;
2358 /* If POS specifies a position in a display vector, this might
2359 be for an ellipsis displayed for invisible text. We won't
2360 get the iterator set up for delivering that ellipsis unless
2361 we make sure that it gets aware of the invisible text. */
2362 if (in_ellipses_for_invisible_text_p (pos
, w
))
2368 /* Keep in mind: the call to reseat in init_iterator skips invisible
2369 text, so we might end up at a position different from POS. This
2370 is only a problem when POS is a row start after a newline and an
2371 overlay starts there with an after-string, and the overlay has an
2372 invisible property. Since we don't skip invisible text in
2373 display_line and elsewhere immediately after consuming the
2374 newline before the row start, such a POS will not be in a string,
2375 but the call to init_iterator below will move us to the
2377 init_iterator (it
, w
, charpos
, bytepos
, NULL
, DEFAULT_FACE_ID
);
2379 for (i
= 0; i
< it
->n_overlay_strings
; ++i
)
2381 const char *s
= SDATA (it
->overlay_strings
[i
]);
2382 const char *e
= s
+ SBYTES (it
->overlay_strings
[i
]);
2384 while (s
< e
&& *s
!= '\n')
2389 overlay_strings_with_newlines
= 1;
2394 /* If position is within an overlay string, set up IT to the right
2396 if (pos
->overlay_string_index
>= 0)
2400 /* If the first overlay string happens to have a `display'
2401 property for an image, the iterator will be set up for that
2402 image, and we have to undo that setup first before we can
2403 correct the overlay string index. */
2404 if (it
->method
== next_element_from_image
)
2407 /* We already have the first chunk of overlay strings in
2408 IT->overlay_strings. Load more until the one for
2409 pos->overlay_string_index is in IT->overlay_strings. */
2410 if (pos
->overlay_string_index
>= OVERLAY_STRING_CHUNK_SIZE
)
2412 int n
= pos
->overlay_string_index
/ OVERLAY_STRING_CHUNK_SIZE
;
2413 it
->current
.overlay_string_index
= 0;
2416 load_overlay_strings (it
, 0);
2417 it
->current
.overlay_string_index
+= OVERLAY_STRING_CHUNK_SIZE
;
2421 it
->current
.overlay_string_index
= pos
->overlay_string_index
;
2422 relative_index
= (it
->current
.overlay_string_index
2423 % OVERLAY_STRING_CHUNK_SIZE
);
2424 it
->string
= it
->overlay_strings
[relative_index
];
2425 xassert (STRINGP (it
->string
));
2426 it
->current
.string_pos
= pos
->string_pos
;
2427 it
->method
= next_element_from_string
;
2430 #if 0 /* This is bogus because POS not having an overlay string
2431 position does not mean it's after the string. Example: A
2432 line starting with a before-string and initialization of IT
2433 to the previous row's end position. */
2434 else if (it
->current
.overlay_string_index
>= 0)
2436 /* If POS says we're already after an overlay string ending at
2437 POS, make sure to pop the iterator because it will be in
2438 front of that overlay string. When POS is ZV, we've thereby
2439 also ``processed'' overlay strings at ZV. */
2442 it
->current
.overlay_string_index
= -1;
2443 it
->method
= next_element_from_buffer
;
2444 if (CHARPOS (pos
->pos
) == ZV
)
2445 it
->overlay_strings_at_end_processed_p
= 1;
2449 if (CHARPOS (pos
->string_pos
) >= 0)
2451 /* Recorded position is not in an overlay string, but in another
2452 string. This can only be a string from a `display' property.
2453 IT should already be filled with that string. */
2454 it
->current
.string_pos
= pos
->string_pos
;
2455 xassert (STRINGP (it
->string
));
2458 /* Restore position in display vector translations, control
2459 character translations or ellipses. */
2460 if (pos
->dpvec_index
>= 0)
2462 if (it
->dpvec
== NULL
)
2463 get_next_display_element (it
);
2464 xassert (it
->dpvec
&& it
->current
.dpvec_index
== 0);
2465 it
->current
.dpvec_index
= pos
->dpvec_index
;
2469 return !overlay_strings_with_newlines
;
2473 /* Initialize IT for stepping through current_buffer in window W
2474 starting at ROW->start. */
2477 init_to_row_start (it
, w
, row
)
2480 struct glyph_row
*row
;
2482 init_from_display_pos (it
, w
, &row
->start
);
2483 it
->start
= row
->start
;
2484 it
->continuation_lines_width
= row
->continuation_lines_width
;
2489 /* Initialize IT for stepping through current_buffer in window W
2490 starting in the line following ROW, i.e. starting at ROW->end.
2491 Value is zero if there are overlay strings with newlines at ROW's
2495 init_to_row_end (it
, w
, row
)
2498 struct glyph_row
*row
;
2502 if (init_from_display_pos (it
, w
, &row
->end
))
2504 if (row
->continued_p
)
2505 it
->continuation_lines_width
2506 = row
->continuation_lines_width
+ row
->pixel_width
;
2517 /***********************************************************************
2519 ***********************************************************************/
2521 /* Called when IT reaches IT->stop_charpos. Handle text property and
2522 overlay changes. Set IT->stop_charpos to the next position where
2529 enum prop_handled handled
;
2530 int handle_overlay_change_p
= 1;
2534 it
->current
.dpvec_index
= -1;
2538 handled
= HANDLED_NORMALLY
;
2540 /* Call text property handlers. */
2541 for (p
= it_props
; p
->handler
; ++p
)
2543 handled
= p
->handler (it
);
2545 if (handled
== HANDLED_RECOMPUTE_PROPS
)
2547 else if (handled
== HANDLED_RETURN
)
2549 else if (handled
== HANDLED_OVERLAY_STRING_CONSUMED
)
2550 handle_overlay_change_p
= 0;
2553 if (handled
!= HANDLED_RECOMPUTE_PROPS
)
2555 /* Don't check for overlay strings below when set to deliver
2556 characters from a display vector. */
2557 if (it
->method
== next_element_from_display_vector
)
2558 handle_overlay_change_p
= 0;
2560 /* Handle overlay changes. */
2561 if (handle_overlay_change_p
)
2562 handled
= handle_overlay_change (it
);
2564 /* Determine where to stop next. */
2565 if (handled
== HANDLED_NORMALLY
)
2566 compute_stop_pos (it
);
2569 while (handled
== HANDLED_RECOMPUTE_PROPS
);
2573 /* Compute IT->stop_charpos from text property and overlay change
2574 information for IT's current position. */
2577 compute_stop_pos (it
)
2580 register INTERVAL iv
, next_iv
;
2581 Lisp_Object object
, limit
, position
;
2583 /* If nowhere else, stop at the end. */
2584 it
->stop_charpos
= it
->end_charpos
;
2586 if (STRINGP (it
->string
))
2588 /* Strings are usually short, so don't limit the search for
2590 object
= it
->string
;
2592 position
= make_number (IT_STRING_CHARPOS (*it
));
2598 /* If next overlay change is in front of the current stop pos
2599 (which is IT->end_charpos), stop there. Note: value of
2600 next_overlay_change is point-max if no overlay change
2602 charpos
= next_overlay_change (IT_CHARPOS (*it
));
2603 if (charpos
< it
->stop_charpos
)
2604 it
->stop_charpos
= charpos
;
2606 /* If showing the region, we have to stop at the region
2607 start or end because the face might change there. */
2608 if (it
->region_beg_charpos
> 0)
2610 if (IT_CHARPOS (*it
) < it
->region_beg_charpos
)
2611 it
->stop_charpos
= min (it
->stop_charpos
, it
->region_beg_charpos
);
2612 else if (IT_CHARPOS (*it
) < it
->region_end_charpos
)
2613 it
->stop_charpos
= min (it
->stop_charpos
, it
->region_end_charpos
);
2616 /* Set up variables for computing the stop position from text
2617 property changes. */
2618 XSETBUFFER (object
, current_buffer
);
2619 limit
= make_number (IT_CHARPOS (*it
) + TEXT_PROP_DISTANCE_LIMIT
);
2620 position
= make_number (IT_CHARPOS (*it
));
2624 /* Get the interval containing IT's position. Value is a null
2625 interval if there isn't such an interval. */
2626 iv
= validate_interval_range (object
, &position
, &position
, 0);
2627 if (!NULL_INTERVAL_P (iv
))
2629 Lisp_Object values_here
[LAST_PROP_IDX
];
2632 /* Get properties here. */
2633 for (p
= it_props
; p
->handler
; ++p
)
2634 values_here
[p
->idx
] = textget (iv
->plist
, *p
->name
);
2636 /* Look for an interval following iv that has different
2638 for (next_iv
= next_interval (iv
);
2639 (!NULL_INTERVAL_P (next_iv
)
2641 || XFASTINT (limit
) > next_iv
->position
));
2642 next_iv
= next_interval (next_iv
))
2644 for (p
= it_props
; p
->handler
; ++p
)
2646 Lisp_Object new_value
;
2648 new_value
= textget (next_iv
->plist
, *p
->name
);
2649 if (!EQ (values_here
[p
->idx
], new_value
))
2657 if (!NULL_INTERVAL_P (next_iv
))
2659 if (INTEGERP (limit
)
2660 && next_iv
->position
>= XFASTINT (limit
))
2661 /* No text property change up to limit. */
2662 it
->stop_charpos
= min (XFASTINT (limit
), it
->stop_charpos
);
2664 /* Text properties change in next_iv. */
2665 it
->stop_charpos
= min (it
->stop_charpos
, next_iv
->position
);
2669 xassert (STRINGP (it
->string
)
2670 || (it
->stop_charpos
>= BEGV
2671 && it
->stop_charpos
>= IT_CHARPOS (*it
)));
2675 /* Return the position of the next overlay change after POS in
2676 current_buffer. Value is point-max if no overlay change
2677 follows. This is like `next-overlay-change' but doesn't use
2681 next_overlay_change (pos
)
2686 Lisp_Object
*overlays
;
2690 /* Get all overlays at the given position. */
2692 overlays
= (Lisp_Object
*) alloca (len
* sizeof *overlays
);
2693 noverlays
= overlays_at (pos
, 0, &overlays
, &len
, &endpos
, NULL
, 1);
2694 if (noverlays
> len
)
2697 overlays
= (Lisp_Object
*) alloca (len
* sizeof *overlays
);
2698 noverlays
= overlays_at (pos
, 0, &overlays
, &len
, &endpos
, NULL
, 1);
2701 /* If any of these overlays ends before endpos,
2702 use its ending point instead. */
2703 for (i
= 0; i
< noverlays
; ++i
)
2708 oend
= OVERLAY_END (overlays
[i
]);
2709 oendpos
= OVERLAY_POSITION (oend
);
2710 endpos
= min (endpos
, oendpos
);
2718 /***********************************************************************
2720 ***********************************************************************/
2722 /* Handle changes in the `fontified' property of the current buffer by
2723 calling hook functions from Qfontification_functions to fontify
2726 static enum prop_handled
2727 handle_fontified_prop (it
)
2730 Lisp_Object prop
, pos
;
2731 enum prop_handled handled
= HANDLED_NORMALLY
;
2733 /* Get the value of the `fontified' property at IT's current buffer
2734 position. (The `fontified' property doesn't have a special
2735 meaning in strings.) If the value is nil, call functions from
2736 Qfontification_functions. */
2737 if (!STRINGP (it
->string
)
2739 && !NILP (Vfontification_functions
)
2740 && !NILP (Vrun_hooks
)
2741 && (pos
= make_number (IT_CHARPOS (*it
)),
2742 prop
= Fget_char_property (pos
, Qfontified
, Qnil
),
2745 int count
= SPECPDL_INDEX ();
2748 val
= Vfontification_functions
;
2749 specbind (Qfontification_functions
, Qnil
);
2751 if (!CONSP (val
) || EQ (XCAR (val
), Qlambda
))
2752 safe_call1 (val
, pos
);
2755 Lisp_Object globals
, fn
;
2756 struct gcpro gcpro1
, gcpro2
;
2759 GCPRO2 (val
, globals
);
2761 for (; CONSP (val
); val
= XCDR (val
))
2767 /* A value of t indicates this hook has a local
2768 binding; it means to run the global binding too.
2769 In a global value, t should not occur. If it
2770 does, we must ignore it to avoid an endless
2772 for (globals
= Fdefault_value (Qfontification_functions
);
2774 globals
= XCDR (globals
))
2776 fn
= XCAR (globals
);
2778 safe_call1 (fn
, pos
);
2782 safe_call1 (fn
, pos
);
2788 unbind_to (count
, Qnil
);
2790 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
2791 something. This avoids an endless loop if they failed to
2792 fontify the text for which reason ever. */
2793 if (!NILP (Fget_char_property (pos
, Qfontified
, Qnil
)))
2794 handled
= HANDLED_RECOMPUTE_PROPS
;
2802 /***********************************************************************
2804 ***********************************************************************/
2806 /* Set up iterator IT from face properties at its current position.
2807 Called from handle_stop. */
2809 static enum prop_handled
2810 handle_face_prop (it
)
2813 int new_face_id
, next_stop
;
2815 if (!STRINGP (it
->string
))
2818 = face_at_buffer_position (it
->w
,
2820 it
->region_beg_charpos
,
2821 it
->region_end_charpos
,
2824 + TEXT_PROP_DISTANCE_LIMIT
),
2827 /* Is this a start of a run of characters with box face?
2828 Caveat: this can be called for a freshly initialized
2829 iterator; face_id is -1 in this case. We know that the new
2830 face will not change until limit, i.e. if the new face has a
2831 box, all characters up to limit will have one. But, as
2832 usual, we don't know whether limit is really the end. */
2833 if (new_face_id
!= it
->face_id
)
2835 struct face
*new_face
= FACE_FROM_ID (it
->f
, new_face_id
);
2837 /* If new face has a box but old face has not, this is
2838 the start of a run of characters with box, i.e. it has
2839 a shadow on the left side. The value of face_id of the
2840 iterator will be -1 if this is the initial call that gets
2841 the face. In this case, we have to look in front of IT's
2842 position and see whether there is a face != new_face_id. */
2843 it
->start_of_box_run_p
2844 = (new_face
->box
!= FACE_NO_BOX
2845 && (it
->face_id
>= 0
2846 || IT_CHARPOS (*it
) == BEG
2847 || new_face_id
!= face_before_it_pos (it
)));
2848 it
->face_box_p
= new_face
->box
!= FACE_NO_BOX
;
2853 int base_face_id
, bufpos
;
2855 if (it
->current
.overlay_string_index
>= 0)
2856 bufpos
= IT_CHARPOS (*it
);
2860 /* For strings from a buffer, i.e. overlay strings or strings
2861 from a `display' property, use the face at IT's current
2862 buffer position as the base face to merge with, so that
2863 overlay strings appear in the same face as surrounding
2864 text, unless they specify their own faces. */
2865 base_face_id
= underlying_face_id (it
);
2867 new_face_id
= face_at_string_position (it
->w
,
2869 IT_STRING_CHARPOS (*it
),
2871 it
->region_beg_charpos
,
2872 it
->region_end_charpos
,
2876 #if 0 /* This shouldn't be neccessary. Let's check it. */
2877 /* If IT is used to display a mode line we would really like to
2878 use the mode line face instead of the frame's default face. */
2879 if (it
->glyph_row
== MATRIX_MODE_LINE_ROW (it
->w
->desired_matrix
)
2880 && new_face_id
== DEFAULT_FACE_ID
)
2881 new_face_id
= CURRENT_MODE_LINE_FACE_ID (it
->w
);
2884 /* Is this a start of a run of characters with box? Caveat:
2885 this can be called for a freshly allocated iterator; face_id
2886 is -1 is this case. We know that the new face will not
2887 change until the next check pos, i.e. if the new face has a
2888 box, all characters up to that position will have a
2889 box. But, as usual, we don't know whether that position
2890 is really the end. */
2891 if (new_face_id
!= it
->face_id
)
2893 struct face
*new_face
= FACE_FROM_ID (it
->f
, new_face_id
);
2894 struct face
*old_face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2896 /* If new face has a box but old face hasn't, this is the
2897 start of a run of characters with box, i.e. it has a
2898 shadow on the left side. */
2899 it
->start_of_box_run_p
2900 = new_face
->box
&& (old_face
== NULL
|| !old_face
->box
);
2901 it
->face_box_p
= new_face
->box
!= FACE_NO_BOX
;
2905 it
->face_id
= new_face_id
;
2906 return HANDLED_NORMALLY
;
2910 /* Return the ID of the face ``underlying'' IT's current position,
2911 which is in a string. If the iterator is associated with a
2912 buffer, return the face at IT's current buffer position.
2913 Otherwise, use the iterator's base_face_id. */
2916 underlying_face_id (it
)
2919 int face_id
= it
->base_face_id
, i
;
2921 xassert (STRINGP (it
->string
));
2923 for (i
= it
->sp
- 1; i
>= 0; --i
)
2924 if (NILP (it
->stack
[i
].string
))
2925 face_id
= it
->stack
[i
].face_id
;
2931 /* Compute the face one character before or after the current position
2932 of IT. BEFORE_P non-zero means get the face in front of IT's
2933 position. Value is the id of the face. */
2936 face_before_or_after_it_pos (it
, before_p
)
2941 int next_check_charpos
;
2942 struct text_pos pos
;
2944 xassert (it
->s
== NULL
);
2946 if (STRINGP (it
->string
))
2948 int bufpos
, base_face_id
;
2950 /* No face change past the end of the string (for the case
2951 we are padding with spaces). No face change before the
2953 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
)
2954 || (IT_STRING_CHARPOS (*it
) == 0 && before_p
))
2957 /* Set pos to the position before or after IT's current position. */
2959 pos
= string_pos (IT_STRING_CHARPOS (*it
) - 1, it
->string
);
2961 /* For composition, we must check the character after the
2963 pos
= (it
->what
== IT_COMPOSITION
2964 ? string_pos (IT_STRING_CHARPOS (*it
) + it
->cmp_len
, it
->string
)
2965 : string_pos (IT_STRING_CHARPOS (*it
) + 1, it
->string
));
2967 if (it
->current
.overlay_string_index
>= 0)
2968 bufpos
= IT_CHARPOS (*it
);
2972 base_face_id
= underlying_face_id (it
);
2974 /* Get the face for ASCII, or unibyte. */
2975 face_id
= face_at_string_position (it
->w
,
2979 it
->region_beg_charpos
,
2980 it
->region_end_charpos
,
2981 &next_check_charpos
,
2984 /* Correct the face for charsets different from ASCII. Do it
2985 for the multibyte case only. The face returned above is
2986 suitable for unibyte text if IT->string is unibyte. */
2987 if (STRING_MULTIBYTE (it
->string
))
2989 const unsigned char *p
= SDATA (it
->string
) + BYTEPOS (pos
);
2990 int rest
= SBYTES (it
->string
) - BYTEPOS (pos
);
2992 struct face
*face
= FACE_FROM_ID (it
->f
, face_id
);
2994 c
= string_char_and_length (p
, rest
, &len
);
2995 face_id
= FACE_FOR_CHAR (it
->f
, face
, c
);
3000 if ((IT_CHARPOS (*it
) >= ZV
&& !before_p
)
3001 || (IT_CHARPOS (*it
) <= BEGV
&& before_p
))
3004 limit
= IT_CHARPOS (*it
) + TEXT_PROP_DISTANCE_LIMIT
;
3005 pos
= it
->current
.pos
;
3008 DEC_TEXT_POS (pos
, it
->multibyte_p
);
3011 if (it
->what
== IT_COMPOSITION
)
3012 /* For composition, we must check the position after the
3014 pos
.charpos
+= it
->cmp_len
, pos
.bytepos
+= it
->len
;
3016 INC_TEXT_POS (pos
, it
->multibyte_p
);
3019 /* Determine face for CHARSET_ASCII, or unibyte. */
3020 face_id
= face_at_buffer_position (it
->w
,
3022 it
->region_beg_charpos
,
3023 it
->region_end_charpos
,
3024 &next_check_charpos
,
3027 /* Correct the face for charsets different from ASCII. Do it
3028 for the multibyte case only. The face returned above is
3029 suitable for unibyte text if current_buffer is unibyte. */
3030 if (it
->multibyte_p
)
3032 int c
= FETCH_MULTIBYTE_CHAR (BYTEPOS (pos
));
3033 struct face
*face
= FACE_FROM_ID (it
->f
, face_id
);
3034 face_id
= FACE_FOR_CHAR (it
->f
, face
, c
);
3043 /***********************************************************************
3045 ***********************************************************************/
3047 /* Set up iterator IT from invisible properties at its current
3048 position. Called from handle_stop. */
3050 static enum prop_handled
3051 handle_invisible_prop (it
)
3054 enum prop_handled handled
= HANDLED_NORMALLY
;
3056 if (STRINGP (it
->string
))
3058 extern Lisp_Object Qinvisible
;
3059 Lisp_Object prop
, end_charpos
, limit
, charpos
;
3061 /* Get the value of the invisible text property at the
3062 current position. Value will be nil if there is no such
3064 charpos
= make_number (IT_STRING_CHARPOS (*it
));
3065 prop
= Fget_text_property (charpos
, Qinvisible
, it
->string
);
3068 && IT_STRING_CHARPOS (*it
) < it
->end_charpos
)
3070 handled
= HANDLED_RECOMPUTE_PROPS
;
3072 /* Get the position at which the next change of the
3073 invisible text property can be found in IT->string.
3074 Value will be nil if the property value is the same for
3075 all the rest of IT->string. */
3076 XSETINT (limit
, SCHARS (it
->string
));
3077 end_charpos
= Fnext_single_property_change (charpos
, Qinvisible
,
3080 /* Text at current position is invisible. The next
3081 change in the property is at position end_charpos.
3082 Move IT's current position to that position. */
3083 if (INTEGERP (end_charpos
)
3084 && XFASTINT (end_charpos
) < XFASTINT (limit
))
3086 struct text_pos old
;
3087 old
= it
->current
.string_pos
;
3088 IT_STRING_CHARPOS (*it
) = XFASTINT (end_charpos
);
3089 compute_string_pos (&it
->current
.string_pos
, old
, it
->string
);
3093 /* The rest of the string is invisible. If this is an
3094 overlay string, proceed with the next overlay string
3095 or whatever comes and return a character from there. */
3096 if (it
->current
.overlay_string_index
>= 0)
3098 next_overlay_string (it
);
3099 /* Don't check for overlay strings when we just
3100 finished processing them. */
3101 handled
= HANDLED_OVERLAY_STRING_CONSUMED
;
3105 IT_STRING_CHARPOS (*it
) = SCHARS (it
->string
);
3106 IT_STRING_BYTEPOS (*it
) = SBYTES (it
->string
);
3113 int invis_p
, newpos
, next_stop
, start_charpos
;
3114 Lisp_Object pos
, prop
, overlay
;
3116 /* First of all, is there invisible text at this position? */
3117 start_charpos
= IT_CHARPOS (*it
);
3118 pos
= make_number (IT_CHARPOS (*it
));
3119 prop
= get_char_property_and_overlay (pos
, Qinvisible
, it
->window
,
3121 invis_p
= TEXT_PROP_MEANS_INVISIBLE (prop
);
3123 /* If we are on invisible text, skip over it. */
3124 if (invis_p
&& IT_CHARPOS (*it
) < it
->end_charpos
)
3126 /* Record whether we have to display an ellipsis for the
3128 int display_ellipsis_p
= invis_p
== 2;
3130 handled
= HANDLED_RECOMPUTE_PROPS
;
3132 /* Loop skipping over invisible text. The loop is left at
3133 ZV or with IT on the first char being visible again. */
3136 /* Try to skip some invisible text. Return value is the
3137 position reached which can be equal to IT's position
3138 if there is nothing invisible here. This skips both
3139 over invisible text properties and overlays with
3140 invisible property. */
3141 newpos
= skip_invisible (IT_CHARPOS (*it
),
3142 &next_stop
, ZV
, it
->window
);
3144 /* If we skipped nothing at all we weren't at invisible
3145 text in the first place. If everything to the end of
3146 the buffer was skipped, end the loop. */
3147 if (newpos
== IT_CHARPOS (*it
) || newpos
>= ZV
)
3151 /* We skipped some characters but not necessarily
3152 all there are. Check if we ended up on visible
3153 text. Fget_char_property returns the property of
3154 the char before the given position, i.e. if we
3155 get invis_p = 0, this means that the char at
3156 newpos is visible. */
3157 pos
= make_number (newpos
);
3158 prop
= Fget_char_property (pos
, Qinvisible
, it
->window
);
3159 invis_p
= TEXT_PROP_MEANS_INVISIBLE (prop
);
3162 /* If we ended up on invisible text, proceed to
3163 skip starting with next_stop. */
3165 IT_CHARPOS (*it
) = next_stop
;
3169 /* The position newpos is now either ZV or on visible text. */
3170 IT_CHARPOS (*it
) = newpos
;
3171 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (newpos
);
3173 /* If there are before-strings at the start of invisible
3174 text, and the text is invisible because of a text
3175 property, arrange to show before-strings because 20.x did
3176 it that way. (If the text is invisible because of an
3177 overlay property instead of a text property, this is
3178 already handled in the overlay code.) */
3180 && get_overlay_strings (it
, start_charpos
))
3182 handled
= HANDLED_RECOMPUTE_PROPS
;
3183 it
->stack
[it
->sp
- 1].display_ellipsis_p
= display_ellipsis_p
;
3185 else if (display_ellipsis_p
)
3186 setup_for_ellipsis (it
);
3194 /* Make iterator IT return `...' next. */
3197 setup_for_ellipsis (it
)
3201 && VECTORP (DISP_INVIS_VECTOR (it
->dp
)))
3203 struct Lisp_Vector
*v
= XVECTOR (DISP_INVIS_VECTOR (it
->dp
));
3204 it
->dpvec
= v
->contents
;
3205 it
->dpend
= v
->contents
+ v
->size
;
3209 /* Default `...'. */
3210 it
->dpvec
= default_invis_vector
;
3211 it
->dpend
= default_invis_vector
+ 3;
3214 /* The ellipsis display does not replace the display of the
3215 character at the new position. Indicate this by setting
3216 IT->dpvec_char_len to zero. */
3217 it
->dpvec_char_len
= 0;
3219 it
->current
.dpvec_index
= 0;
3220 it
->method
= next_element_from_display_vector
;
3225 /***********************************************************************
3227 ***********************************************************************/
3229 /* Set up iterator IT from `display' property at its current position.
3230 Called from handle_stop. */
3232 static enum prop_handled
3233 handle_display_prop (it
)
3236 Lisp_Object prop
, object
;
3237 struct text_pos
*position
;
3238 int display_replaced_p
= 0;
3240 if (STRINGP (it
->string
))
3242 object
= it
->string
;
3243 position
= &it
->current
.string_pos
;
3247 object
= it
->w
->buffer
;
3248 position
= &it
->current
.pos
;
3251 /* Reset those iterator values set from display property values. */
3252 it
->font_height
= Qnil
;
3253 it
->space_width
= Qnil
;
3256 /* We don't support recursive `display' properties, i.e. string
3257 values that have a string `display' property, that have a string
3258 `display' property etc. */
3259 if (!it
->string_from_display_prop_p
)
3260 it
->area
= TEXT_AREA
;
3262 prop
= Fget_char_property (make_number (position
->charpos
),
3265 return HANDLED_NORMALLY
;
3268 /* Simple properties. */
3269 && !EQ (XCAR (prop
), Qimage
)
3270 && !EQ (XCAR (prop
), Qspace
)
3271 && !EQ (XCAR (prop
), Qwhen
)
3272 && !EQ (XCAR (prop
), Qspace_width
)
3273 && !EQ (XCAR (prop
), Qheight
)
3274 && !EQ (XCAR (prop
), Qraise
)
3275 /* Marginal area specifications. */
3276 && !(CONSP (XCAR (prop
)) && EQ (XCAR (XCAR (prop
)), Qmargin
))
3277 && !EQ (XCAR (prop
), Qleft_fringe
)
3278 && !EQ (XCAR (prop
), Qright_fringe
)
3279 && !NILP (XCAR (prop
)))
3281 for (; CONSP (prop
); prop
= XCDR (prop
))
3283 if (handle_single_display_prop (it
, XCAR (prop
), object
,
3284 position
, display_replaced_p
))
3285 display_replaced_p
= 1;
3288 else if (VECTORP (prop
))
3291 for (i
= 0; i
< ASIZE (prop
); ++i
)
3292 if (handle_single_display_prop (it
, AREF (prop
, i
), object
,
3293 position
, display_replaced_p
))
3294 display_replaced_p
= 1;
3298 if (handle_single_display_prop (it
, prop
, object
, position
, 0))
3299 display_replaced_p
= 1;
3302 return display_replaced_p
? HANDLED_RETURN
: HANDLED_NORMALLY
;
3306 /* Value is the position of the end of the `display' property starting
3307 at START_POS in OBJECT. */
3309 static struct text_pos
3310 display_prop_end (it
, object
, start_pos
)
3313 struct text_pos start_pos
;
3316 struct text_pos end_pos
;
3318 end
= Fnext_single_char_property_change (make_number (CHARPOS (start_pos
)),
3319 Qdisplay
, object
, Qnil
);
3320 CHARPOS (end_pos
) = XFASTINT (end
);
3321 if (STRINGP (object
))
3322 compute_string_pos (&end_pos
, start_pos
, it
->string
);
3324 BYTEPOS (end_pos
) = CHAR_TO_BYTE (XFASTINT (end
));
3330 /* Set up IT from a single `display' sub-property value PROP. OBJECT
3331 is the object in which the `display' property was found. *POSITION
3332 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3333 means that we previously saw a display sub-property which already
3334 replaced text display with something else, for example an image;
3335 ignore such properties after the first one has been processed.
3337 If PROP is a `space' or `image' sub-property, set *POSITION to the
3338 end position of the `display' property.
3340 Value is non-zero if something was found which replaces the display
3341 of buffer or string text. */
3344 handle_single_display_prop (it
, prop
, object
, position
,
3345 display_replaced_before_p
)
3349 struct text_pos
*position
;
3350 int display_replaced_before_p
;
3353 int replaces_text_display_p
= 0;
3356 /* If PROP is a list of the form `(when FORM . VALUE)', FORM is
3357 evaluated. If the result is nil, VALUE is ignored. */
3359 if (CONSP (prop
) && EQ (XCAR (prop
), Qwhen
))
3368 if (!NILP (form
) && !EQ (form
, Qt
))
3370 int count
= SPECPDL_INDEX ();
3371 struct gcpro gcpro1
;
3373 /* Bind `object' to the object having the `display' property, a
3374 buffer or string. Bind `position' to the position in the
3375 object where the property was found, and `buffer-position'
3376 to the current position in the buffer. */
3377 specbind (Qobject
, object
);
3378 specbind (Qposition
, make_number (CHARPOS (*position
)));
3379 specbind (Qbuffer_position
,
3380 make_number (STRINGP (object
)
3381 ? IT_CHARPOS (*it
) : CHARPOS (*position
)));
3383 form
= safe_eval (form
);
3385 unbind_to (count
, Qnil
);
3392 && EQ (XCAR (prop
), Qheight
)
3393 && CONSP (XCDR (prop
)))
3395 if (FRAME_TERMCAP_P (it
->f
) || FRAME_MSDOS_P (it
->f
))
3398 /* `(height HEIGHT)'. */
3399 it
->font_height
= XCAR (XCDR (prop
));
3400 if (!NILP (it
->font_height
))
3402 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
3403 int new_height
= -1;
3405 if (CONSP (it
->font_height
)
3406 && (EQ (XCAR (it
->font_height
), Qplus
)
3407 || EQ (XCAR (it
->font_height
), Qminus
))
3408 && CONSP (XCDR (it
->font_height
))
3409 && INTEGERP (XCAR (XCDR (it
->font_height
))))
3411 /* `(+ N)' or `(- N)' where N is an integer. */
3412 int steps
= XINT (XCAR (XCDR (it
->font_height
)));
3413 if (EQ (XCAR (it
->font_height
), Qplus
))
3415 it
->face_id
= smaller_face (it
->f
, it
->face_id
, steps
);
3417 else if (FUNCTIONP (it
->font_height
))
3419 /* Call function with current height as argument.
3420 Value is the new height. */
3422 height
= safe_call1 (it
->font_height
,
3423 face
->lface
[LFACE_HEIGHT_INDEX
]);
3424 if (NUMBERP (height
))
3425 new_height
= XFLOATINT (height
);
3427 else if (NUMBERP (it
->font_height
))
3429 /* Value is a multiple of the canonical char height. */
3432 face
= FACE_FROM_ID (it
->f
, DEFAULT_FACE_ID
);
3433 new_height
= (XFLOATINT (it
->font_height
)
3434 * XINT (face
->lface
[LFACE_HEIGHT_INDEX
]));
3438 /* Evaluate IT->font_height with `height' bound to the
3439 current specified height to get the new height. */
3441 int count
= SPECPDL_INDEX ();
3443 specbind (Qheight
, face
->lface
[LFACE_HEIGHT_INDEX
]);
3444 value
= safe_eval (it
->font_height
);
3445 unbind_to (count
, Qnil
);
3447 if (NUMBERP (value
))
3448 new_height
= XFLOATINT (value
);
3452 it
->face_id
= face_with_height (it
->f
, it
->face_id
, new_height
);
3455 else if (CONSP (prop
)
3456 && EQ (XCAR (prop
), Qspace_width
)
3457 && CONSP (XCDR (prop
)))
3459 /* `(space_width WIDTH)'. */
3460 if (FRAME_TERMCAP_P (it
->f
) || FRAME_MSDOS_P (it
->f
))
3463 value
= XCAR (XCDR (prop
));
3464 if (NUMBERP (value
) && XFLOATINT (value
) > 0)
3465 it
->space_width
= value
;
3467 else if (CONSP (prop
)
3468 && EQ (XCAR (prop
), Qraise
)
3469 && CONSP (XCDR (prop
)))
3471 /* `(raise FACTOR)'. */
3472 if (FRAME_TERMCAP_P (it
->f
) || FRAME_MSDOS_P (it
->f
))
3475 #ifdef HAVE_WINDOW_SYSTEM
3476 value
= XCAR (XCDR (prop
));
3477 if (NUMBERP (value
))
3479 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
3480 it
->voffset
= - (XFLOATINT (value
)
3481 * (FONT_HEIGHT (face
->font
)));
3483 #endif /* HAVE_WINDOW_SYSTEM */
3485 else if (CONSP (prop
)
3486 && (EQ (XCAR (prop
), Qleft_fringe
)
3487 || EQ (XCAR (prop
), Qright_fringe
))
3488 && CONSP (XCDR (prop
)))
3490 unsigned face_id
= DEFAULT_FACE_ID
;
3492 /* `(left-fringe BITMAP FACE)'. */
3493 if (FRAME_TERMCAP_P (it
->f
) || FRAME_MSDOS_P (it
->f
))
3496 #ifdef HAVE_WINDOW_SYSTEM
3497 value
= XCAR (XCDR (prop
));
3498 if (!NUMBERP (value
)
3499 || !valid_fringe_bitmap_id_p (XINT (value
)))
3502 if (CONSP (XCDR (XCDR (prop
))))
3504 Lisp_Object face_name
= XCAR (XCDR (XCDR (prop
)));
3505 face_id
= lookup_named_face (it
->f
, face_name
, 'A');
3510 if (EQ (XCAR (prop
), Qleft_fringe
))
3512 it
->left_user_fringe_bitmap
= XINT (value
);
3513 it
->left_user_fringe_face_id
= face_id
;
3517 it
->right_user_fringe_bitmap
= XINT (value
);
3518 it
->right_user_fringe_face_id
= face_id
;
3520 #endif /* HAVE_WINDOW_SYSTEM */
3522 else if (!it
->string_from_display_prop_p
)
3524 /* `((margin left-margin) VALUE)' or `((margin right-margin)
3525 VALUE) or `((margin nil) VALUE)' or VALUE. */
3526 Lisp_Object location
, value
;
3527 struct text_pos start_pos
;
3530 /* Characters having this form of property are not displayed, so
3531 we have to find the end of the property. */
3532 start_pos
= *position
;
3533 *position
= display_prop_end (it
, object
, start_pos
);
3536 /* Let's stop at the new position and assume that all
3537 text properties change there. */
3538 it
->stop_charpos
= position
->charpos
;
3540 location
= Qunbound
;
3541 if (CONSP (prop
) && CONSP (XCAR (prop
)))
3545 value
= XCDR (prop
);
3547 value
= XCAR (value
);
3550 if (EQ (XCAR (tem
), Qmargin
)
3551 && (tem
= XCDR (tem
),
3552 tem
= CONSP (tem
) ? XCAR (tem
) : Qnil
,
3554 || EQ (tem
, Qleft_margin
)
3555 || EQ (tem
, Qright_margin
))))
3559 if (EQ (location
, Qunbound
))
3565 #ifdef HAVE_WINDOW_SYSTEM
3566 if (FRAME_TERMCAP_P (it
->f
))
3567 valid_p
= STRINGP (value
);
3569 valid_p
= (STRINGP (value
)
3570 || (CONSP (value
) && EQ (XCAR (value
), Qspace
))
3571 || valid_image_p (value
));
3572 #else /* not HAVE_WINDOW_SYSTEM */
3573 valid_p
= STRINGP (value
);
3574 #endif /* not HAVE_WINDOW_SYSTEM */
3576 if ((EQ (location
, Qleft_margin
)
3577 || EQ (location
, Qright_margin
)
3580 && !display_replaced_before_p
)
3582 replaces_text_display_p
= 1;
3584 /* Save current settings of IT so that we can restore them
3585 when we are finished with the glyph property value. */
3588 if (NILP (location
))
3589 it
->area
= TEXT_AREA
;
3590 else if (EQ (location
, Qleft_margin
))
3591 it
->area
= LEFT_MARGIN_AREA
;
3593 it
->area
= RIGHT_MARGIN_AREA
;
3595 if (STRINGP (value
))
3598 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
3599 it
->current
.overlay_string_index
= -1;
3600 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = 0;
3601 it
->end_charpos
= it
->string_nchars
= SCHARS (it
->string
);
3602 it
->method
= next_element_from_string
;
3603 it
->stop_charpos
= 0;
3604 it
->string_from_display_prop_p
= 1;
3605 /* Say that we haven't consumed the characters with
3606 `display' property yet. The call to pop_it in
3607 set_iterator_to_next will clean this up. */
3608 *position
= start_pos
;
3610 else if (CONSP (value
) && EQ (XCAR (value
), Qspace
))
3612 it
->method
= next_element_from_stretch
;
3614 it
->current
.pos
= it
->position
= start_pos
;
3616 #ifdef HAVE_WINDOW_SYSTEM
3619 it
->what
= IT_IMAGE
;
3620 it
->image_id
= lookup_image (it
->f
, value
);
3621 it
->position
= start_pos
;
3622 it
->object
= NILP (object
) ? it
->w
->buffer
: object
;
3623 it
->method
= next_element_from_image
;
3625 /* Say that we haven't consumed the characters with
3626 `display' property yet. The call to pop_it in
3627 set_iterator_to_next will clean this up. */
3628 *position
= start_pos
;
3630 #endif /* HAVE_WINDOW_SYSTEM */
3633 /* Invalid property or property not supported. Restore
3634 the position to what it was before. */
3635 *position
= start_pos
;
3638 return replaces_text_display_p
;
3642 /* Check if PROP is a display sub-property value whose text should be
3643 treated as intangible. */
3646 single_display_prop_intangible_p (prop
)
3649 /* Skip over `when FORM'. */
3650 if (CONSP (prop
) && EQ (XCAR (prop
), Qwhen
))
3664 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
3665 we don't need to treat text as intangible. */
3666 if (EQ (XCAR (prop
), Qmargin
))
3674 || EQ (XCAR (prop
), Qleft_margin
)
3675 || EQ (XCAR (prop
), Qright_margin
))
3679 return (CONSP (prop
)
3680 && (EQ (XCAR (prop
), Qimage
)
3681 || EQ (XCAR (prop
), Qspace
)));
3685 /* Check if PROP is a display property value whose text should be
3686 treated as intangible. */
3689 display_prop_intangible_p (prop
)
3693 && CONSP (XCAR (prop
))
3694 && !EQ (Qmargin
, XCAR (XCAR (prop
))))
3696 /* A list of sub-properties. */
3697 while (CONSP (prop
))
3699 if (single_display_prop_intangible_p (XCAR (prop
)))
3704 else if (VECTORP (prop
))
3706 /* A vector of sub-properties. */
3708 for (i
= 0; i
< ASIZE (prop
); ++i
)
3709 if (single_display_prop_intangible_p (AREF (prop
, i
)))
3713 return single_display_prop_intangible_p (prop
);
3719 /* Return 1 if PROP is a display sub-property value containing STRING. */
3722 single_display_prop_string_p (prop
, string
)
3723 Lisp_Object prop
, string
;
3725 if (EQ (string
, prop
))
3728 /* Skip over `when FORM'. */
3729 if (CONSP (prop
) && EQ (XCAR (prop
), Qwhen
))
3738 /* Skip over `margin LOCATION'. */
3739 if (EQ (XCAR (prop
), Qmargin
))
3750 return CONSP (prop
) && EQ (XCAR (prop
), string
);
3754 /* Return 1 if STRING appears in the `display' property PROP. */
3757 display_prop_string_p (prop
, string
)
3758 Lisp_Object prop
, string
;
3761 && CONSP (XCAR (prop
))
3762 && !EQ (Qmargin
, XCAR (XCAR (prop
))))
3764 /* A list of sub-properties. */
3765 while (CONSP (prop
))
3767 if (single_display_prop_string_p (XCAR (prop
), string
))
3772 else if (VECTORP (prop
))
3774 /* A vector of sub-properties. */
3776 for (i
= 0; i
< ASIZE (prop
); ++i
)
3777 if (single_display_prop_string_p (AREF (prop
, i
), string
))
3781 return single_display_prop_string_p (prop
, string
);
3787 /* Determine from which buffer position in W's buffer STRING comes
3788 from. AROUND_CHARPOS is an approximate position where it could
3789 be from. Value is the buffer position or 0 if it couldn't be
3792 W's buffer must be current.
3794 This function is necessary because we don't record buffer positions
3795 in glyphs generated from strings (to keep struct glyph small).
3796 This function may only use code that doesn't eval because it is
3797 called asynchronously from note_mouse_highlight. */
3800 string_buffer_position (w
, string
, around_charpos
)
3805 Lisp_Object limit
, prop
, pos
;
3806 const int MAX_DISTANCE
= 1000;
3809 pos
= make_number (around_charpos
);
3810 limit
= make_number (min (XINT (pos
) + MAX_DISTANCE
, ZV
));
3811 while (!found
&& !EQ (pos
, limit
))
3813 prop
= Fget_char_property (pos
, Qdisplay
, Qnil
);
3814 if (!NILP (prop
) && display_prop_string_p (prop
, string
))
3817 pos
= Fnext_single_char_property_change (pos
, Qdisplay
, Qnil
, limit
);
3822 pos
= make_number (around_charpos
);
3823 limit
= make_number (max (XINT (pos
) - MAX_DISTANCE
, BEGV
));
3824 while (!found
&& !EQ (pos
, limit
))
3826 prop
= Fget_char_property (pos
, Qdisplay
, Qnil
);
3827 if (!NILP (prop
) && display_prop_string_p (prop
, string
))
3830 pos
= Fprevious_single_char_property_change (pos
, Qdisplay
, Qnil
,
3835 return found
? XINT (pos
) : 0;
3840 /***********************************************************************
3841 `composition' property
3842 ***********************************************************************/
3844 /* Set up iterator IT from `composition' property at its current
3845 position. Called from handle_stop. */
3847 static enum prop_handled
3848 handle_composition_prop (it
)
3851 Lisp_Object prop
, string
;
3852 int pos
, pos_byte
, end
;
3853 enum prop_handled handled
= HANDLED_NORMALLY
;
3855 if (STRINGP (it
->string
))
3857 pos
= IT_STRING_CHARPOS (*it
);
3858 pos_byte
= IT_STRING_BYTEPOS (*it
);
3859 string
= it
->string
;
3863 pos
= IT_CHARPOS (*it
);
3864 pos_byte
= IT_BYTEPOS (*it
);
3868 /* If there's a valid composition and point is not inside of the
3869 composition (in the case that the composition is from the current
3870 buffer), draw a glyph composed from the composition components. */
3871 if (find_composition (pos
, -1, &pos
, &end
, &prop
, string
)
3872 && COMPOSITION_VALID_P (pos
, end
, prop
)
3873 && (STRINGP (it
->string
) || (PT
<= pos
|| PT
>= end
)))
3875 int id
= get_composition_id (pos
, pos_byte
, end
- pos
, prop
, string
);
3879 it
->method
= next_element_from_composition
;
3881 it
->cmp_len
= COMPOSITION_LENGTH (prop
);
3882 /* For a terminal, draw only the first character of the
3884 it
->c
= COMPOSITION_GLYPH (composition_table
[id
], 0);
3885 it
->len
= (STRINGP (it
->string
)
3886 ? string_char_to_byte (it
->string
, end
)
3887 : CHAR_TO_BYTE (end
)) - pos_byte
;
3888 it
->stop_charpos
= end
;
3889 handled
= HANDLED_RETURN
;
3898 /***********************************************************************
3900 ***********************************************************************/
3902 /* The following structure is used to record overlay strings for
3903 later sorting in load_overlay_strings. */
3905 struct overlay_entry
3907 Lisp_Object overlay
;
3914 /* Set up iterator IT from overlay strings at its current position.
3915 Called from handle_stop. */
3917 static enum prop_handled
3918 handle_overlay_change (it
)
3921 if (!STRINGP (it
->string
) && get_overlay_strings (it
, 0))
3922 return HANDLED_RECOMPUTE_PROPS
;
3924 return HANDLED_NORMALLY
;
3928 /* Set up the next overlay string for delivery by IT, if there is an
3929 overlay string to deliver. Called by set_iterator_to_next when the
3930 end of the current overlay string is reached. If there are more
3931 overlay strings to display, IT->string and
3932 IT->current.overlay_string_index are set appropriately here.
3933 Otherwise IT->string is set to nil. */
3936 next_overlay_string (it
)
3939 ++it
->current
.overlay_string_index
;
3940 if (it
->current
.overlay_string_index
== it
->n_overlay_strings
)
3942 /* No more overlay strings. Restore IT's settings to what
3943 they were before overlay strings were processed, and
3944 continue to deliver from current_buffer. */
3945 int display_ellipsis_p
= it
->stack
[it
->sp
- 1].display_ellipsis_p
;
3948 xassert (it
->stop_charpos
>= BEGV
3949 && it
->stop_charpos
<= it
->end_charpos
);
3951 it
->current
.overlay_string_index
= -1;
3952 SET_TEXT_POS (it
->current
.string_pos
, -1, -1);
3953 it
->n_overlay_strings
= 0;
3954 it
->method
= next_element_from_buffer
;
3956 /* If we're at the end of the buffer, record that we have
3957 processed the overlay strings there already, so that
3958 next_element_from_buffer doesn't try it again. */
3959 if (IT_CHARPOS (*it
) >= it
->end_charpos
)
3960 it
->overlay_strings_at_end_processed_p
= 1;
3962 /* If we have to display `...' for invisible text, set
3963 the iterator up for that. */
3964 if (display_ellipsis_p
)
3965 setup_for_ellipsis (it
);
3969 /* There are more overlay strings to process. If
3970 IT->current.overlay_string_index has advanced to a position
3971 where we must load IT->overlay_strings with more strings, do
3973 int i
= it
->current
.overlay_string_index
% OVERLAY_STRING_CHUNK_SIZE
;
3975 if (it
->current
.overlay_string_index
&& i
== 0)
3976 load_overlay_strings (it
, 0);
3978 /* Initialize IT to deliver display elements from the overlay
3980 it
->string
= it
->overlay_strings
[i
];
3981 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
3982 SET_TEXT_POS (it
->current
.string_pos
, 0, 0);
3983 it
->method
= next_element_from_string
;
3984 it
->stop_charpos
= 0;
3991 /* Compare two overlay_entry structures E1 and E2. Used as a
3992 comparison function for qsort in load_overlay_strings. Overlay
3993 strings for the same position are sorted so that
3995 1. All after-strings come in front of before-strings, except
3996 when they come from the same overlay.
3998 2. Within after-strings, strings are sorted so that overlay strings
3999 from overlays with higher priorities come first.
4001 2. Within before-strings, strings are sorted so that overlay
4002 strings from overlays with higher priorities come last.
4004 Value is analogous to strcmp. */
4008 compare_overlay_entries (e1
, e2
)
4011 struct overlay_entry
*entry1
= (struct overlay_entry
*) e1
;
4012 struct overlay_entry
*entry2
= (struct overlay_entry
*) e2
;
4015 if (entry1
->after_string_p
!= entry2
->after_string_p
)
4017 /* Let after-strings appear in front of before-strings if
4018 they come from different overlays. */
4019 if (EQ (entry1
->overlay
, entry2
->overlay
))
4020 result
= entry1
->after_string_p
? 1 : -1;
4022 result
= entry1
->after_string_p
? -1 : 1;
4024 else if (entry1
->after_string_p
)
4025 /* After-strings sorted in order of decreasing priority. */
4026 result
= entry2
->priority
- entry1
->priority
;
4028 /* Before-strings sorted in order of increasing priority. */
4029 result
= entry1
->priority
- entry2
->priority
;
4035 /* Load the vector IT->overlay_strings with overlay strings from IT's
4036 current buffer position, or from CHARPOS if that is > 0. Set
4037 IT->n_overlays to the total number of overlay strings found.
4039 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4040 a time. On entry into load_overlay_strings,
4041 IT->current.overlay_string_index gives the number of overlay
4042 strings that have already been loaded by previous calls to this
4045 IT->add_overlay_start contains an additional overlay start
4046 position to consider for taking overlay strings from, if non-zero.
4047 This position comes into play when the overlay has an `invisible'
4048 property, and both before and after-strings. When we've skipped to
4049 the end of the overlay, because of its `invisible' property, we
4050 nevertheless want its before-string to appear.
4051 IT->add_overlay_start will contain the overlay start position
4054 Overlay strings are sorted so that after-string strings come in
4055 front of before-string strings. Within before and after-strings,
4056 strings are sorted by overlay priority. See also function
4057 compare_overlay_entries. */
4060 load_overlay_strings (it
, charpos
)
4064 extern Lisp_Object Qafter_string
, Qbefore_string
, Qwindow
, Qpriority
;
4065 Lisp_Object overlay
, window
, str
, invisible
;
4066 struct Lisp_Overlay
*ov
;
4069 int n
= 0, i
, j
, invis_p
;
4070 struct overlay_entry
*entries
4071 = (struct overlay_entry
*) alloca (size
* sizeof *entries
);
4074 charpos
= IT_CHARPOS (*it
);
4076 /* Append the overlay string STRING of overlay OVERLAY to vector
4077 `entries' which has size `size' and currently contains `n'
4078 elements. AFTER_P non-zero means STRING is an after-string of
4080 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4083 Lisp_Object priority; \
4087 int new_size = 2 * size; \
4088 struct overlay_entry *old = entries; \
4090 (struct overlay_entry *) alloca (new_size \
4091 * sizeof *entries); \
4092 bcopy (old, entries, size * sizeof *entries); \
4096 entries[n].string = (STRING); \
4097 entries[n].overlay = (OVERLAY); \
4098 priority = Foverlay_get ((OVERLAY), Qpriority); \
4099 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4100 entries[n].after_string_p = (AFTER_P); \
4105 /* Process overlay before the overlay center. */
4106 for (ov
= current_buffer
->overlays_before
; ov
; ov
= ov
->next
)
4108 XSETMISC (overlay
, ov
);
4109 xassert (OVERLAYP (overlay
));
4110 start
= OVERLAY_POSITION (OVERLAY_START (overlay
));
4111 end
= OVERLAY_POSITION (OVERLAY_END (overlay
));
4116 /* Skip this overlay if it doesn't start or end at IT's current
4118 if (end
!= charpos
&& start
!= charpos
)
4121 /* Skip this overlay if it doesn't apply to IT->w. */
4122 window
= Foverlay_get (overlay
, Qwindow
);
4123 if (WINDOWP (window
) && XWINDOW (window
) != it
->w
)
4126 /* If the text ``under'' the overlay is invisible, both before-
4127 and after-strings from this overlay are visible; start and
4128 end position are indistinguishable. */
4129 invisible
= Foverlay_get (overlay
, Qinvisible
);
4130 invis_p
= TEXT_PROP_MEANS_INVISIBLE (invisible
);
4132 /* If overlay has a non-empty before-string, record it. */
4133 if ((start
== charpos
|| (end
== charpos
&& invis_p
))
4134 && (str
= Foverlay_get (overlay
, Qbefore_string
), STRINGP (str
))
4136 RECORD_OVERLAY_STRING (overlay
, str
, 0);
4138 /* If overlay has a non-empty after-string, record it. */
4139 if ((end
== charpos
|| (start
== charpos
&& invis_p
))
4140 && (str
= Foverlay_get (overlay
, Qafter_string
), STRINGP (str
))
4142 RECORD_OVERLAY_STRING (overlay
, str
, 1);
4145 /* Process overlays after the overlay center. */
4146 for (ov
= current_buffer
->overlays_after
; ov
; ov
= ov
->next
)
4148 XSETMISC (overlay
, ov
);
4149 xassert (OVERLAYP (overlay
));
4150 start
= OVERLAY_POSITION (OVERLAY_START (overlay
));
4151 end
= OVERLAY_POSITION (OVERLAY_END (overlay
));
4153 if (start
> charpos
)
4156 /* Skip this overlay if it doesn't start or end at IT's current
4158 if (end
!= charpos
&& start
!= charpos
)
4161 /* Skip this overlay if it doesn't apply to IT->w. */
4162 window
= Foverlay_get (overlay
, Qwindow
);
4163 if (WINDOWP (window
) && XWINDOW (window
) != it
->w
)
4166 /* If the text ``under'' the overlay is invisible, it has a zero
4167 dimension, and both before- and after-strings apply. */
4168 invisible
= Foverlay_get (overlay
, Qinvisible
);
4169 invis_p
= TEXT_PROP_MEANS_INVISIBLE (invisible
);
4171 /* If overlay has a non-empty before-string, record it. */
4172 if ((start
== charpos
|| (end
== charpos
&& invis_p
))
4173 && (str
= Foverlay_get (overlay
, Qbefore_string
), STRINGP (str
))
4175 RECORD_OVERLAY_STRING (overlay
, str
, 0);
4177 /* If overlay has a non-empty after-string, record it. */
4178 if ((end
== charpos
|| (start
== charpos
&& invis_p
))
4179 && (str
= Foverlay_get (overlay
, Qafter_string
), STRINGP (str
))
4181 RECORD_OVERLAY_STRING (overlay
, str
, 1);
4184 #undef RECORD_OVERLAY_STRING
4188 qsort (entries
, n
, sizeof *entries
, compare_overlay_entries
);
4190 /* Record the total number of strings to process. */
4191 it
->n_overlay_strings
= n
;
4193 /* IT->current.overlay_string_index is the number of overlay strings
4194 that have already been consumed by IT. Copy some of the
4195 remaining overlay strings to IT->overlay_strings. */
4197 j
= it
->current
.overlay_string_index
;
4198 while (i
< OVERLAY_STRING_CHUNK_SIZE
&& j
< n
)
4199 it
->overlay_strings
[i
++] = entries
[j
++].string
;
4205 /* Get the first chunk of overlay strings at IT's current buffer
4206 position, or at CHARPOS if that is > 0. Value is non-zero if at
4207 least one overlay string was found. */
4210 get_overlay_strings (it
, charpos
)
4214 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4215 process. This fills IT->overlay_strings with strings, and sets
4216 IT->n_overlay_strings to the total number of strings to process.
4217 IT->pos.overlay_string_index has to be set temporarily to zero
4218 because load_overlay_strings needs this; it must be set to -1
4219 when no overlay strings are found because a zero value would
4220 indicate a position in the first overlay string. */
4221 it
->current
.overlay_string_index
= 0;
4222 load_overlay_strings (it
, charpos
);
4224 /* If we found overlay strings, set up IT to deliver display
4225 elements from the first one. Otherwise set up IT to deliver
4226 from current_buffer. */
4227 if (it
->n_overlay_strings
)
4229 /* Make sure we know settings in current_buffer, so that we can
4230 restore meaningful values when we're done with the overlay
4232 compute_stop_pos (it
);
4233 xassert (it
->face_id
>= 0);
4235 /* Save IT's settings. They are restored after all overlay
4236 strings have been processed. */
4237 xassert (it
->sp
== 0);
4240 /* Set up IT to deliver display elements from the first overlay
4242 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = 0;
4243 it
->string
= it
->overlay_strings
[0];
4244 it
->stop_charpos
= 0;
4245 xassert (STRINGP (it
->string
));
4246 it
->end_charpos
= SCHARS (it
->string
);
4247 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
4248 it
->method
= next_element_from_string
;
4253 it
->current
.overlay_string_index
= -1;
4254 it
->method
= next_element_from_buffer
;
4259 /* Value is non-zero if we found at least one overlay string. */
4260 return STRINGP (it
->string
);
4265 /***********************************************************************
4266 Saving and restoring state
4267 ***********************************************************************/
4269 /* Save current settings of IT on IT->stack. Called, for example,
4270 before setting up IT for an overlay string, to be able to restore
4271 IT's settings to what they were after the overlay string has been
4278 struct iterator_stack_entry
*p
;
4280 xassert (it
->sp
< 2);
4281 p
= it
->stack
+ it
->sp
;
4283 p
->stop_charpos
= it
->stop_charpos
;
4284 xassert (it
->face_id
>= 0);
4285 p
->face_id
= it
->face_id
;
4286 p
->string
= it
->string
;
4287 p
->pos
= it
->current
;
4288 p
->end_charpos
= it
->end_charpos
;
4289 p
->string_nchars
= it
->string_nchars
;
4291 p
->multibyte_p
= it
->multibyte_p
;
4292 p
->space_width
= it
->space_width
;
4293 p
->font_height
= it
->font_height
;
4294 p
->voffset
= it
->voffset
;
4295 p
->string_from_display_prop_p
= it
->string_from_display_prop_p
;
4296 p
->display_ellipsis_p
= 0;
4301 /* Restore IT's settings from IT->stack. Called, for example, when no
4302 more overlay strings must be processed, and we return to delivering
4303 display elements from a buffer, or when the end of a string from a
4304 `display' property is reached and we return to delivering display
4305 elements from an overlay string, or from a buffer. */
4311 struct iterator_stack_entry
*p
;
4313 xassert (it
->sp
> 0);
4315 p
= it
->stack
+ it
->sp
;
4316 it
->stop_charpos
= p
->stop_charpos
;
4317 it
->face_id
= p
->face_id
;
4318 it
->string
= p
->string
;
4319 it
->current
= p
->pos
;
4320 it
->end_charpos
= p
->end_charpos
;
4321 it
->string_nchars
= p
->string_nchars
;
4323 it
->multibyte_p
= p
->multibyte_p
;
4324 it
->space_width
= p
->space_width
;
4325 it
->font_height
= p
->font_height
;
4326 it
->voffset
= p
->voffset
;
4327 it
->string_from_display_prop_p
= p
->string_from_display_prop_p
;
4332 /***********************************************************************
4334 ***********************************************************************/
4336 /* Set IT's current position to the previous line start. */
4339 back_to_previous_line_start (it
)
4342 IT_CHARPOS (*it
) = find_next_newline_no_quit (IT_CHARPOS (*it
) - 1, -1);
4343 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (IT_CHARPOS (*it
));
4347 /* Move IT to the next line start.
4349 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
4350 we skipped over part of the text (as opposed to moving the iterator
4351 continuously over the text). Otherwise, don't change the value
4354 Newlines may come from buffer text, overlay strings, or strings
4355 displayed via the `display' property. That's the reason we can't
4356 simply use find_next_newline_no_quit.
4358 Note that this function may not skip over invisible text that is so
4359 because of text properties and immediately follows a newline. If
4360 it would, function reseat_at_next_visible_line_start, when called
4361 from set_iterator_to_next, would effectively make invisible
4362 characters following a newline part of the wrong glyph row, which
4363 leads to wrong cursor motion. */
4366 forward_to_next_line_start (it
, skipped_p
)
4370 int old_selective
, newline_found_p
, n
;
4371 const int MAX_NEWLINE_DISTANCE
= 500;
4373 /* If already on a newline, just consume it to avoid unintended
4374 skipping over invisible text below. */
4375 if (it
->what
== IT_CHARACTER
4377 && CHARPOS (it
->position
) == IT_CHARPOS (*it
))
4379 set_iterator_to_next (it
, 0);
4384 /* Don't handle selective display in the following. It's (a)
4385 unnecessary because it's done by the caller, and (b) leads to an
4386 infinite recursion because next_element_from_ellipsis indirectly
4387 calls this function. */
4388 old_selective
= it
->selective
;
4391 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
4392 from buffer text. */
4393 for (n
= newline_found_p
= 0;
4394 !newline_found_p
&& n
< MAX_NEWLINE_DISTANCE
;
4395 n
+= STRINGP (it
->string
) ? 0 : 1)
4397 if (!get_next_display_element (it
))
4399 newline_found_p
= it
->what
== IT_CHARACTER
&& it
->c
== '\n';
4400 set_iterator_to_next (it
, 0);
4403 /* If we didn't find a newline near enough, see if we can use a
4405 if (!newline_found_p
)
4407 int start
= IT_CHARPOS (*it
);
4408 int limit
= find_next_newline_no_quit (start
, 1);
4411 xassert (!STRINGP (it
->string
));
4413 /* If there isn't any `display' property in sight, and no
4414 overlays, we can just use the position of the newline in
4416 if (it
->stop_charpos
>= limit
4417 || ((pos
= Fnext_single_property_change (make_number (start
),
4419 Qnil
, make_number (limit
)),
4421 && next_overlay_change (start
) == ZV
))
4423 IT_CHARPOS (*it
) = limit
;
4424 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (limit
);
4425 *skipped_p
= newline_found_p
= 1;
4429 while (get_next_display_element (it
)
4430 && !newline_found_p
)
4432 newline_found_p
= ITERATOR_AT_END_OF_LINE_P (it
);
4433 set_iterator_to_next (it
, 0);
4438 it
->selective
= old_selective
;
4439 return newline_found_p
;
4443 /* Set IT's current position to the previous visible line start. Skip
4444 invisible text that is so either due to text properties or due to
4445 selective display. Caution: this does not change IT->current_x and
4449 back_to_previous_visible_line_start (it
)
4454 /* Go back one newline if not on BEGV already. */
4455 if (IT_CHARPOS (*it
) > BEGV
)
4456 back_to_previous_line_start (it
);
4458 /* Move over lines that are invisible because of selective display
4459 or text properties. */
4460 while (IT_CHARPOS (*it
) > BEGV
4465 /* If selective > 0, then lines indented more than that values
4467 if (it
->selective
> 0
4468 && indented_beyond_p (IT_CHARPOS (*it
), IT_BYTEPOS (*it
),
4469 (double) it
->selective
)) /* iftc */
4475 prop
= Fget_char_property (make_number (IT_CHARPOS (*it
)),
4476 Qinvisible
, it
->window
);
4477 if (TEXT_PROP_MEANS_INVISIBLE (prop
))
4481 /* Back one more newline if the current one is invisible. */
4483 back_to_previous_line_start (it
);
4486 xassert (IT_CHARPOS (*it
) >= BEGV
);
4487 xassert (IT_CHARPOS (*it
) == BEGV
4488 || FETCH_BYTE (IT_BYTEPOS (*it
) - 1) == '\n');
4493 /* Reseat iterator IT at the previous visible line start. Skip
4494 invisible text that is so either due to text properties or due to
4495 selective display. At the end, update IT's overlay information,
4496 face information etc. */
4499 reseat_at_previous_visible_line_start (it
)
4502 back_to_previous_visible_line_start (it
);
4503 reseat (it
, it
->current
.pos
, 1);
4508 /* Reseat iterator IT on the next visible line start in the current
4509 buffer. ON_NEWLINE_P non-zero means position IT on the newline
4510 preceding the line start. Skip over invisible text that is so
4511 because of selective display. Compute faces, overlays etc at the
4512 new position. Note that this function does not skip over text that
4513 is invisible because of text properties. */
4516 reseat_at_next_visible_line_start (it
, on_newline_p
)
4520 int newline_found_p
, skipped_p
= 0;
4522 newline_found_p
= forward_to_next_line_start (it
, &skipped_p
);
4524 /* Skip over lines that are invisible because they are indented
4525 more than the value of IT->selective. */
4526 if (it
->selective
> 0)
4527 while (IT_CHARPOS (*it
) < ZV
4528 && indented_beyond_p (IT_CHARPOS (*it
), IT_BYTEPOS (*it
),
4529 (double) it
->selective
)) /* iftc */
4531 xassert (FETCH_BYTE (IT_BYTEPOS (*it
) - 1) == '\n');
4532 newline_found_p
= forward_to_next_line_start (it
, &skipped_p
);
4535 /* Position on the newline if that's what's requested. */
4536 if (on_newline_p
&& newline_found_p
)
4538 if (STRINGP (it
->string
))
4540 if (IT_STRING_CHARPOS (*it
) > 0)
4542 --IT_STRING_CHARPOS (*it
);
4543 --IT_STRING_BYTEPOS (*it
);
4546 else if (IT_CHARPOS (*it
) > BEGV
)
4550 reseat (it
, it
->current
.pos
, 0);
4554 reseat (it
, it
->current
.pos
, 0);
4561 /***********************************************************************
4562 Changing an iterator's position
4563 ***********************************************************************/
4565 /* Change IT's current position to POS in current_buffer. If FORCE_P
4566 is non-zero, always check for text properties at the new position.
4567 Otherwise, text properties are only looked up if POS >=
4568 IT->check_charpos of a property. */
4571 reseat (it
, pos
, force_p
)
4573 struct text_pos pos
;
4576 int original_pos
= IT_CHARPOS (*it
);
4578 reseat_1 (it
, pos
, 0);
4580 /* Determine where to check text properties. Avoid doing it
4581 where possible because text property lookup is very expensive. */
4583 || CHARPOS (pos
) > it
->stop_charpos
4584 || CHARPOS (pos
) < original_pos
)
4591 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
4592 IT->stop_pos to POS, also. */
4595 reseat_1 (it
, pos
, set_stop_p
)
4597 struct text_pos pos
;
4600 /* Don't call this function when scanning a C string. */
4601 xassert (it
->s
== NULL
);
4603 /* POS must be a reasonable value. */
4604 xassert (CHARPOS (pos
) >= BEGV
&& CHARPOS (pos
) <= ZV
);
4606 it
->current
.pos
= it
->position
= pos
;
4607 XSETBUFFER (it
->object
, current_buffer
);
4608 it
->end_charpos
= ZV
;
4610 it
->current
.dpvec_index
= -1;
4611 it
->current
.overlay_string_index
= -1;
4612 IT_STRING_CHARPOS (*it
) = -1;
4613 IT_STRING_BYTEPOS (*it
) = -1;
4615 it
->method
= next_element_from_buffer
;
4616 /* RMS: I added this to fix a bug in move_it_vertically_backward
4617 where it->area continued to relate to the starting point
4618 for the backward motion. Bug report from
4619 Nick Roberts <nick@nick.uklinux.net> on 19 May 2003.
4620 However, I am not sure whether reseat still does the right thing
4621 in general after this change. */
4622 it
->area
= TEXT_AREA
;
4623 it
->multibyte_p
= !NILP (current_buffer
->enable_multibyte_characters
);
4625 it
->face_before_selective_p
= 0;
4628 it
->stop_charpos
= CHARPOS (pos
);
4632 /* Set up IT for displaying a string, starting at CHARPOS in window W.
4633 If S is non-null, it is a C string to iterate over. Otherwise,
4634 STRING gives a Lisp string to iterate over.
4636 If PRECISION > 0, don't return more then PRECISION number of
4637 characters from the string.
4639 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
4640 characters have been returned. FIELD_WIDTH < 0 means an infinite
4643 MULTIBYTE = 0 means disable processing of multibyte characters,
4644 MULTIBYTE > 0 means enable it,
4645 MULTIBYTE < 0 means use IT->multibyte_p.
4647 IT must be initialized via a prior call to init_iterator before
4648 calling this function. */
4651 reseat_to_string (it
, s
, string
, charpos
, precision
, field_width
, multibyte
)
4656 int precision
, field_width
, multibyte
;
4658 /* No region in strings. */
4659 it
->region_beg_charpos
= it
->region_end_charpos
= -1;
4661 /* No text property checks performed by default, but see below. */
4662 it
->stop_charpos
= -1;
4664 /* Set iterator position and end position. */
4665 bzero (&it
->current
, sizeof it
->current
);
4666 it
->current
.overlay_string_index
= -1;
4667 it
->current
.dpvec_index
= -1;
4668 xassert (charpos
>= 0);
4670 /* If STRING is specified, use its multibyteness, otherwise use the
4671 setting of MULTIBYTE, if specified. */
4673 it
->multibyte_p
= multibyte
> 0;
4677 xassert (STRINGP (string
));
4678 it
->string
= string
;
4680 it
->end_charpos
= it
->string_nchars
= SCHARS (string
);
4681 it
->method
= next_element_from_string
;
4682 it
->current
.string_pos
= string_pos (charpos
, string
);
4689 /* Note that we use IT->current.pos, not it->current.string_pos,
4690 for displaying C strings. */
4691 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = -1;
4692 if (it
->multibyte_p
)
4694 it
->current
.pos
= c_string_pos (charpos
, s
, 1);
4695 it
->end_charpos
= it
->string_nchars
= number_of_chars (s
, 1);
4699 IT_CHARPOS (*it
) = IT_BYTEPOS (*it
) = charpos
;
4700 it
->end_charpos
= it
->string_nchars
= strlen (s
);
4703 it
->method
= next_element_from_c_string
;
4706 /* PRECISION > 0 means don't return more than PRECISION characters
4708 if (precision
> 0 && it
->end_charpos
- charpos
> precision
)
4709 it
->end_charpos
= it
->string_nchars
= charpos
+ precision
;
4711 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
4712 characters have been returned. FIELD_WIDTH == 0 means don't pad,
4713 FIELD_WIDTH < 0 means infinite field width. This is useful for
4714 padding with `-' at the end of a mode line. */
4715 if (field_width
< 0)
4716 field_width
= INFINITY
;
4717 if (field_width
> it
->end_charpos
- charpos
)
4718 it
->end_charpos
= charpos
+ field_width
;
4720 /* Use the standard display table for displaying strings. */
4721 if (DISP_TABLE_P (Vstandard_display_table
))
4722 it
->dp
= XCHAR_TABLE (Vstandard_display_table
);
4724 it
->stop_charpos
= charpos
;
4730 /***********************************************************************
4732 ***********************************************************************/
4734 /* Load IT's display element fields with information about the next
4735 display element from the current position of IT. Value is zero if
4736 end of buffer (or C string) is reached. */
4739 get_next_display_element (it
)
4742 /* Non-zero means that we found a display element. Zero means that
4743 we hit the end of what we iterate over. Performance note: the
4744 function pointer `method' used here turns out to be faster than
4745 using a sequence of if-statements. */
4746 int success_p
= (*it
->method
) (it
);
4748 if (it
->what
== IT_CHARACTER
)
4750 /* Map via display table or translate control characters.
4751 IT->c, IT->len etc. have been set to the next character by
4752 the function call above. If we have a display table, and it
4753 contains an entry for IT->c, translate it. Don't do this if
4754 IT->c itself comes from a display table, otherwise we could
4755 end up in an infinite recursion. (An alternative could be to
4756 count the recursion depth of this function and signal an
4757 error when a certain maximum depth is reached.) Is it worth
4759 if (success_p
&& it
->dpvec
== NULL
)
4764 && (dv
= DISP_CHAR_VECTOR (it
->dp
, it
->c
),
4767 struct Lisp_Vector
*v
= XVECTOR (dv
);
4769 /* Return the first character from the display table
4770 entry, if not empty. If empty, don't display the
4771 current character. */
4774 it
->dpvec_char_len
= it
->len
;
4775 it
->dpvec
= v
->contents
;
4776 it
->dpend
= v
->contents
+ v
->size
;
4777 it
->current
.dpvec_index
= 0;
4778 it
->method
= next_element_from_display_vector
;
4779 success_p
= get_next_display_element (it
);
4783 set_iterator_to_next (it
, 0);
4784 success_p
= get_next_display_element (it
);
4788 /* Translate control characters into `\003' or `^C' form.
4789 Control characters coming from a display table entry are
4790 currently not translated because we use IT->dpvec to hold
4791 the translation. This could easily be changed but I
4792 don't believe that it is worth doing.
4794 If it->multibyte_p is nonzero, eight-bit characters and
4795 non-printable multibyte characters are also translated to
4798 If it->multibyte_p is zero, eight-bit characters that
4799 don't have corresponding multibyte char code are also
4800 translated to octal form. */
4801 else if ((it
->c
< ' '
4802 && (it
->area
!= TEXT_AREA
4803 || (it
->c
!= '\n' && it
->c
!= '\t')))
4807 || !CHAR_PRINTABLE_P (it
->c
))
4809 && it
->c
== unibyte_char_to_multibyte (it
->c
))))
4811 /* IT->c is a control character which must be displayed
4812 either as '\003' or as `^C' where the '\\' and '^'
4813 can be defined in the display table. Fill
4814 IT->ctl_chars with glyphs for what we have to
4815 display. Then, set IT->dpvec to these glyphs. */
4818 if (it
->c
< 128 && it
->ctl_arrow_p
)
4820 /* Set IT->ctl_chars[0] to the glyph for `^'. */
4822 && INTEGERP (DISP_CTRL_GLYPH (it
->dp
))
4823 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it
->dp
))))
4824 g
= XINT (DISP_CTRL_GLYPH (it
->dp
));
4826 g
= FAST_MAKE_GLYPH ('^', 0);
4827 XSETINT (it
->ctl_chars
[0], g
);
4829 g
= FAST_MAKE_GLYPH (it
->c
^ 0100, 0);
4830 XSETINT (it
->ctl_chars
[1], g
);
4832 /* Set up IT->dpvec and return first character from it. */
4833 it
->dpvec_char_len
= it
->len
;
4834 it
->dpvec
= it
->ctl_chars
;
4835 it
->dpend
= it
->dpvec
+ 2;
4836 it
->current
.dpvec_index
= 0;
4837 it
->method
= next_element_from_display_vector
;
4838 get_next_display_element (it
);
4842 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
4847 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
4849 && INTEGERP (DISP_ESCAPE_GLYPH (it
->dp
))
4850 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it
->dp
))))
4851 escape_glyph
= XFASTINT (DISP_ESCAPE_GLYPH (it
->dp
));
4853 escape_glyph
= FAST_MAKE_GLYPH ('\\', 0);
4855 if (SINGLE_BYTE_CHAR_P (it
->c
))
4856 str
[0] = it
->c
, len
= 1;
4859 len
= CHAR_STRING_NO_SIGNAL (it
->c
, str
);
4862 /* It's an invalid character, which
4863 shouldn't happen actually, but due to
4864 bugs it may happen. Let's print the char
4865 as is, there's not much meaningful we can
4868 str
[1] = it
->c
>> 8;
4869 str
[2] = it
->c
>> 16;
4870 str
[3] = it
->c
>> 24;
4875 for (i
= 0; i
< len
; i
++)
4877 XSETINT (it
->ctl_chars
[i
* 4], escape_glyph
);
4878 /* Insert three more glyphs into IT->ctl_chars for
4879 the octal display of the character. */
4880 g
= FAST_MAKE_GLYPH (((str
[i
] >> 6) & 7) + '0', 0);
4881 XSETINT (it
->ctl_chars
[i
* 4 + 1], g
);
4882 g
= FAST_MAKE_GLYPH (((str
[i
] >> 3) & 7) + '0', 0);
4883 XSETINT (it
->ctl_chars
[i
* 4 + 2], g
);
4884 g
= FAST_MAKE_GLYPH ((str
[i
] & 7) + '0', 0);
4885 XSETINT (it
->ctl_chars
[i
* 4 + 3], g
);
4888 /* Set up IT->dpvec and return the first character
4890 it
->dpvec_char_len
= it
->len
;
4891 it
->dpvec
= it
->ctl_chars
;
4892 it
->dpend
= it
->dpvec
+ len
* 4;
4893 it
->current
.dpvec_index
= 0;
4894 it
->method
= next_element_from_display_vector
;
4895 get_next_display_element (it
);
4900 /* Adjust face id for a multibyte character. There are no
4901 multibyte character in unibyte text. */
4904 && FRAME_WINDOW_P (it
->f
))
4906 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
4907 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->c
);
4911 /* Is this character the last one of a run of characters with
4912 box? If yes, set IT->end_of_box_run_p to 1. */
4919 it
->end_of_box_run_p
4920 = ((face_id
= face_after_it_pos (it
),
4921 face_id
!= it
->face_id
)
4922 && (face
= FACE_FROM_ID (it
->f
, face_id
),
4923 face
->box
== FACE_NO_BOX
));
4926 /* Value is 0 if end of buffer or string reached. */
4931 /* Move IT to the next display element.
4933 RESEAT_P non-zero means if called on a newline in buffer text,
4934 skip to the next visible line start.
4936 Functions get_next_display_element and set_iterator_to_next are
4937 separate because I find this arrangement easier to handle than a
4938 get_next_display_element function that also increments IT's
4939 position. The way it is we can first look at an iterator's current
4940 display element, decide whether it fits on a line, and if it does,
4941 increment the iterator position. The other way around we probably
4942 would either need a flag indicating whether the iterator has to be
4943 incremented the next time, or we would have to implement a
4944 decrement position function which would not be easy to write. */
4947 set_iterator_to_next (it
, reseat_p
)
4951 /* Reset flags indicating start and end of a sequence of characters
4952 with box. Reset them at the start of this function because
4953 moving the iterator to a new position might set them. */
4954 it
->start_of_box_run_p
= it
->end_of_box_run_p
= 0;
4956 if (it
->method
== next_element_from_buffer
)
4958 /* The current display element of IT is a character from
4959 current_buffer. Advance in the buffer, and maybe skip over
4960 invisible lines that are so because of selective display. */
4961 if (ITERATOR_AT_END_OF_LINE_P (it
) && reseat_p
)
4962 reseat_at_next_visible_line_start (it
, 0);
4965 xassert (it
->len
!= 0);
4966 IT_BYTEPOS (*it
) += it
->len
;
4967 IT_CHARPOS (*it
) += 1;
4968 xassert (IT_BYTEPOS (*it
) == CHAR_TO_BYTE (IT_CHARPOS (*it
)));
4971 else if (it
->method
== next_element_from_composition
)
4973 xassert (it
->cmp_id
>= 0 && it
->cmp_id
< n_compositions
);
4974 if (STRINGP (it
->string
))
4976 IT_STRING_BYTEPOS (*it
) += it
->len
;
4977 IT_STRING_CHARPOS (*it
) += it
->cmp_len
;
4978 it
->method
= next_element_from_string
;
4979 goto consider_string_end
;
4983 IT_BYTEPOS (*it
) += it
->len
;
4984 IT_CHARPOS (*it
) += it
->cmp_len
;
4985 it
->method
= next_element_from_buffer
;
4988 else if (it
->method
== next_element_from_c_string
)
4990 /* Current display element of IT is from a C string. */
4991 IT_BYTEPOS (*it
) += it
->len
;
4992 IT_CHARPOS (*it
) += 1;
4994 else if (it
->method
== next_element_from_display_vector
)
4996 /* Current display element of IT is from a display table entry.
4997 Advance in the display table definition. Reset it to null if
4998 end reached, and continue with characters from buffers/
5000 ++it
->current
.dpvec_index
;
5002 /* Restore face of the iterator to what they were before the
5003 display vector entry (these entries may contain faces). */
5004 it
->face_id
= it
->saved_face_id
;
5006 if (it
->dpvec
+ it
->current
.dpvec_index
== it
->dpend
)
5009 it
->method
= next_element_from_c_string
;
5010 else if (STRINGP (it
->string
))
5011 it
->method
= next_element_from_string
;
5013 it
->method
= next_element_from_buffer
;
5016 it
->current
.dpvec_index
= -1;
5018 /* Skip over characters which were displayed via IT->dpvec. */
5019 if (it
->dpvec_char_len
< 0)
5020 reseat_at_next_visible_line_start (it
, 1);
5021 else if (it
->dpvec_char_len
> 0)
5023 it
->len
= it
->dpvec_char_len
;
5024 set_iterator_to_next (it
, reseat_p
);
5028 else if (it
->method
== next_element_from_string
)
5030 /* Current display element is a character from a Lisp string. */
5031 xassert (it
->s
== NULL
&& STRINGP (it
->string
));
5032 IT_STRING_BYTEPOS (*it
) += it
->len
;
5033 IT_STRING_CHARPOS (*it
) += 1;
5035 consider_string_end
:
5037 if (it
->current
.overlay_string_index
>= 0)
5039 /* IT->string is an overlay string. Advance to the
5040 next, if there is one. */
5041 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
))
5042 next_overlay_string (it
);
5046 /* IT->string is not an overlay string. If we reached
5047 its end, and there is something on IT->stack, proceed
5048 with what is on the stack. This can be either another
5049 string, this time an overlay string, or a buffer. */
5050 if (IT_STRING_CHARPOS (*it
) == SCHARS (it
->string
)
5054 if (!STRINGP (it
->string
))
5055 it
->method
= next_element_from_buffer
;
5057 goto consider_string_end
;
5061 else if (it
->method
== next_element_from_image
5062 || it
->method
== next_element_from_stretch
)
5064 /* The position etc with which we have to proceed are on
5065 the stack. The position may be at the end of a string,
5066 if the `display' property takes up the whole string. */
5069 if (STRINGP (it
->string
))
5071 it
->method
= next_element_from_string
;
5072 goto consider_string_end
;
5075 it
->method
= next_element_from_buffer
;
5078 /* There are no other methods defined, so this should be a bug. */
5081 xassert (it
->method
!= next_element_from_string
5082 || (STRINGP (it
->string
)
5083 && IT_STRING_CHARPOS (*it
) >= 0));
5087 /* Load IT's display element fields with information about the next
5088 display element which comes from a display table entry or from the
5089 result of translating a control character to one of the forms `^C'
5090 or `\003'. IT->dpvec holds the glyphs to return as characters. */
5093 next_element_from_display_vector (it
)
5097 xassert (it
->dpvec
&& it
->current
.dpvec_index
>= 0);
5099 /* Remember the current face id in case glyphs specify faces.
5100 IT's face is restored in set_iterator_to_next. */
5101 it
->saved_face_id
= it
->face_id
;
5103 if (INTEGERP (*it
->dpvec
)
5104 && GLYPH_CHAR_VALID_P (XFASTINT (*it
->dpvec
)))
5109 g
= XFASTINT (it
->dpvec
[it
->current
.dpvec_index
]);
5110 it
->c
= FAST_GLYPH_CHAR (g
);
5111 it
->len
= CHAR_BYTES (it
->c
);
5113 /* The entry may contain a face id to use. Such a face id is
5114 the id of a Lisp face, not a realized face. A face id of
5115 zero means no face is specified. */
5116 lface_id
= FAST_GLYPH_FACE (g
);
5119 /* The function returns -1 if lface_id is invalid. */
5120 int face_id
= ascii_face_of_lisp_face (it
->f
, lface_id
);
5122 it
->face_id
= face_id
;
5126 /* Display table entry is invalid. Return a space. */
5127 it
->c
= ' ', it
->len
= 1;
5129 /* Don't change position and object of the iterator here. They are
5130 still the values of the character that had this display table
5131 entry or was translated, and that's what we want. */
5132 it
->what
= IT_CHARACTER
;
5137 /* Load IT with the next display element from Lisp string IT->string.
5138 IT->current.string_pos is the current position within the string.
5139 If IT->current.overlay_string_index >= 0, the Lisp string is an
5143 next_element_from_string (it
)
5146 struct text_pos position
;
5148 xassert (STRINGP (it
->string
));
5149 xassert (IT_STRING_CHARPOS (*it
) >= 0);
5150 position
= it
->current
.string_pos
;
5152 /* Time to check for invisible text? */
5153 if (IT_STRING_CHARPOS (*it
) < it
->end_charpos
5154 && IT_STRING_CHARPOS (*it
) == it
->stop_charpos
)
5158 /* Since a handler may have changed IT->method, we must
5160 return get_next_display_element (it
);
5163 if (it
->current
.overlay_string_index
>= 0)
5165 /* Get the next character from an overlay string. In overlay
5166 strings, There is no field width or padding with spaces to
5168 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
))
5173 else if (STRING_MULTIBYTE (it
->string
))
5175 int remaining
= SBYTES (it
->string
) - IT_STRING_BYTEPOS (*it
);
5176 const unsigned char *s
= (SDATA (it
->string
)
5177 + IT_STRING_BYTEPOS (*it
));
5178 it
->c
= string_char_and_length (s
, remaining
, &it
->len
);
5182 it
->c
= SREF (it
->string
, IT_STRING_BYTEPOS (*it
));
5188 /* Get the next character from a Lisp string that is not an
5189 overlay string. Such strings come from the mode line, for
5190 example. We may have to pad with spaces, or truncate the
5191 string. See also next_element_from_c_string. */
5192 if (IT_STRING_CHARPOS (*it
) >= it
->end_charpos
)
5197 else if (IT_STRING_CHARPOS (*it
) >= it
->string_nchars
)
5199 /* Pad with spaces. */
5200 it
->c
= ' ', it
->len
= 1;
5201 CHARPOS (position
) = BYTEPOS (position
) = -1;
5203 else if (STRING_MULTIBYTE (it
->string
))
5205 int maxlen
= SBYTES (it
->string
) - IT_STRING_BYTEPOS (*it
);
5206 const unsigned char *s
= (SDATA (it
->string
)
5207 + IT_STRING_BYTEPOS (*it
));
5208 it
->c
= string_char_and_length (s
, maxlen
, &it
->len
);
5212 it
->c
= SREF (it
->string
, IT_STRING_BYTEPOS (*it
));
5217 /* Record what we have and where it came from. Note that we store a
5218 buffer position in IT->position although it could arguably be a
5220 it
->what
= IT_CHARACTER
;
5221 it
->object
= it
->string
;
5222 it
->position
= position
;
5227 /* Load IT with next display element from C string IT->s.
5228 IT->string_nchars is the maximum number of characters to return
5229 from the string. IT->end_charpos may be greater than
5230 IT->string_nchars when this function is called, in which case we
5231 may have to return padding spaces. Value is zero if end of string
5232 reached, including padding spaces. */
5235 next_element_from_c_string (it
)
5241 it
->what
= IT_CHARACTER
;
5242 BYTEPOS (it
->position
) = CHARPOS (it
->position
) = 0;
5245 /* IT's position can be greater IT->string_nchars in case a field
5246 width or precision has been specified when the iterator was
5248 if (IT_CHARPOS (*it
) >= it
->end_charpos
)
5250 /* End of the game. */
5254 else if (IT_CHARPOS (*it
) >= it
->string_nchars
)
5256 /* Pad with spaces. */
5257 it
->c
= ' ', it
->len
= 1;
5258 BYTEPOS (it
->position
) = CHARPOS (it
->position
) = -1;
5260 else if (it
->multibyte_p
)
5262 /* Implementation note: The calls to strlen apparently aren't a
5263 performance problem because there is no noticeable performance
5264 difference between Emacs running in unibyte or multibyte mode. */
5265 int maxlen
= strlen (it
->s
) - IT_BYTEPOS (*it
);
5266 it
->c
= string_char_and_length (it
->s
+ IT_BYTEPOS (*it
),
5270 it
->c
= it
->s
[IT_BYTEPOS (*it
)], it
->len
= 1;
5276 /* Set up IT to return characters from an ellipsis, if appropriate.
5277 The definition of the ellipsis glyphs may come from a display table
5278 entry. This function Fills IT with the first glyph from the
5279 ellipsis if an ellipsis is to be displayed. */
5282 next_element_from_ellipsis (it
)
5285 if (it
->selective_display_ellipsis_p
)
5287 if (it
->dp
&& VECTORP (DISP_INVIS_VECTOR (it
->dp
)))
5289 /* Use the display table definition for `...'. Invalid glyphs
5290 will be handled by the method returning elements from dpvec. */
5291 struct Lisp_Vector
*v
= XVECTOR (DISP_INVIS_VECTOR (it
->dp
));
5292 it
->dpvec_char_len
= it
->len
;
5293 it
->dpvec
= v
->contents
;
5294 it
->dpend
= v
->contents
+ v
->size
;
5295 it
->current
.dpvec_index
= 0;
5296 it
->method
= next_element_from_display_vector
;
5300 /* Use default `...' which is stored in default_invis_vector. */
5301 it
->dpvec_char_len
= it
->len
;
5302 it
->dpvec
= default_invis_vector
;
5303 it
->dpend
= default_invis_vector
+ 3;
5304 it
->current
.dpvec_index
= 0;
5305 it
->method
= next_element_from_display_vector
;
5310 /* The face at the current position may be different from the
5311 face we find after the invisible text. Remember what it
5312 was in IT->saved_face_id, and signal that it's there by
5313 setting face_before_selective_p. */
5314 it
->saved_face_id
= it
->face_id
;
5315 it
->method
= next_element_from_buffer
;
5316 reseat_at_next_visible_line_start (it
, 1);
5317 it
->face_before_selective_p
= 1;
5320 return get_next_display_element (it
);
5324 /* Deliver an image display element. The iterator IT is already
5325 filled with image information (done in handle_display_prop). Value
5330 next_element_from_image (it
)
5333 it
->what
= IT_IMAGE
;
5338 /* Fill iterator IT with next display element from a stretch glyph
5339 property. IT->object is the value of the text property. Value is
5343 next_element_from_stretch (it
)
5346 it
->what
= IT_STRETCH
;
5351 /* Load IT with the next display element from current_buffer. Value
5352 is zero if end of buffer reached. IT->stop_charpos is the next
5353 position at which to stop and check for text properties or buffer
5357 next_element_from_buffer (it
)
5362 /* Check this assumption, otherwise, we would never enter the
5363 if-statement, below. */
5364 xassert (IT_CHARPOS (*it
) >= BEGV
5365 && IT_CHARPOS (*it
) <= it
->stop_charpos
);
5367 if (IT_CHARPOS (*it
) >= it
->stop_charpos
)
5369 if (IT_CHARPOS (*it
) >= it
->end_charpos
)
5371 int overlay_strings_follow_p
;
5373 /* End of the game, except when overlay strings follow that
5374 haven't been returned yet. */
5375 if (it
->overlay_strings_at_end_processed_p
)
5376 overlay_strings_follow_p
= 0;
5379 it
->overlay_strings_at_end_processed_p
= 1;
5380 overlay_strings_follow_p
= get_overlay_strings (it
, 0);
5383 if (overlay_strings_follow_p
)
5384 success_p
= get_next_display_element (it
);
5388 it
->position
= it
->current
.pos
;
5395 return get_next_display_element (it
);
5400 /* No face changes, overlays etc. in sight, so just return a
5401 character from current_buffer. */
5404 /* Maybe run the redisplay end trigger hook. Performance note:
5405 This doesn't seem to cost measurable time. */
5406 if (it
->redisplay_end_trigger_charpos
5408 && IT_CHARPOS (*it
) >= it
->redisplay_end_trigger_charpos
)
5409 run_redisplay_end_trigger_hook (it
);
5411 /* Get the next character, maybe multibyte. */
5412 p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
5413 if (it
->multibyte_p
&& !ASCII_BYTE_P (*p
))
5415 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT_BYTE
? ZV_BYTE
: GPT_BYTE
)
5416 - IT_BYTEPOS (*it
));
5417 it
->c
= string_char_and_length (p
, maxlen
, &it
->len
);
5420 it
->c
= *p
, it
->len
= 1;
5422 /* Record what we have and where it came from. */
5423 it
->what
= IT_CHARACTER
;;
5424 it
->object
= it
->w
->buffer
;
5425 it
->position
= it
->current
.pos
;
5427 /* Normally we return the character found above, except when we
5428 really want to return an ellipsis for selective display. */
5433 /* A value of selective > 0 means hide lines indented more
5434 than that number of columns. */
5435 if (it
->selective
> 0
5436 && IT_CHARPOS (*it
) + 1 < ZV
5437 && indented_beyond_p (IT_CHARPOS (*it
) + 1,
5438 IT_BYTEPOS (*it
) + 1,
5439 (double) it
->selective
)) /* iftc */
5441 success_p
= next_element_from_ellipsis (it
);
5442 it
->dpvec_char_len
= -1;
5445 else if (it
->c
== '\r' && it
->selective
== -1)
5447 /* A value of selective == -1 means that everything from the
5448 CR to the end of the line is invisible, with maybe an
5449 ellipsis displayed for it. */
5450 success_p
= next_element_from_ellipsis (it
);
5451 it
->dpvec_char_len
= -1;
5456 /* Value is zero if end of buffer reached. */
5457 xassert (!success_p
|| it
->what
!= IT_CHARACTER
|| it
->len
> 0);
5462 /* Run the redisplay end trigger hook for IT. */
5465 run_redisplay_end_trigger_hook (it
)
5468 Lisp_Object args
[3];
5470 /* IT->glyph_row should be non-null, i.e. we should be actually
5471 displaying something, or otherwise we should not run the hook. */
5472 xassert (it
->glyph_row
);
5474 /* Set up hook arguments. */
5475 args
[0] = Qredisplay_end_trigger_functions
;
5476 args
[1] = it
->window
;
5477 XSETINT (args
[2], it
->redisplay_end_trigger_charpos
);
5478 it
->redisplay_end_trigger_charpos
= 0;
5480 /* Since we are *trying* to run these functions, don't try to run
5481 them again, even if they get an error. */
5482 it
->w
->redisplay_end_trigger
= Qnil
;
5483 Frun_hook_with_args (3, args
);
5485 /* Notice if it changed the face of the character we are on. */
5486 handle_face_prop (it
);
5490 /* Deliver a composition display element. The iterator IT is already
5491 filled with composition information (done in
5492 handle_composition_prop). Value is always 1. */
5495 next_element_from_composition (it
)
5498 it
->what
= IT_COMPOSITION
;
5499 it
->position
= (STRINGP (it
->string
)
5500 ? it
->current
.string_pos
5507 /***********************************************************************
5508 Moving an iterator without producing glyphs
5509 ***********************************************************************/
5511 /* Move iterator IT to a specified buffer or X position within one
5512 line on the display without producing glyphs.
5514 OP should be a bit mask including some or all of these bits:
5515 MOVE_TO_X: Stop on reaching x-position TO_X.
5516 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
5517 Regardless of OP's value, stop in reaching the end of the display line.
5519 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
5520 This means, in particular, that TO_X includes window's horizontal
5523 The return value has several possible values that
5524 say what condition caused the scan to stop:
5526 MOVE_POS_MATCH_OR_ZV
5527 - when TO_POS or ZV was reached.
5530 -when TO_X was reached before TO_POS or ZV were reached.
5533 - when we reached the end of the display area and the line must
5537 - when we reached the end of the display area and the line is
5541 - when we stopped at a line end, i.e. a newline or a CR and selective
5544 static enum move_it_result
5545 move_it_in_display_line_to (it
, to_charpos
, to_x
, op
)
5547 int to_charpos
, to_x
, op
;
5549 enum move_it_result result
= MOVE_UNDEFINED
;
5550 struct glyph_row
*saved_glyph_row
;
5552 /* Don't produce glyphs in produce_glyphs. */
5553 saved_glyph_row
= it
->glyph_row
;
5554 it
->glyph_row
= NULL
;
5558 int x
, i
, ascent
= 0, descent
= 0;
5560 /* Stop when ZV or TO_CHARPOS reached. */
5561 if (!get_next_display_element (it
)
5562 || ((op
& MOVE_TO_POS
) != 0
5563 && BUFFERP (it
->object
)
5564 && IT_CHARPOS (*it
) >= to_charpos
))
5566 result
= MOVE_POS_MATCH_OR_ZV
;
5570 /* The call to produce_glyphs will get the metrics of the
5571 display element IT is loaded with. We record in x the
5572 x-position before this display element in case it does not
5576 /* Remember the line height so far in case the next element doesn't
5578 if (!it
->truncate_lines_p
)
5580 ascent
= it
->max_ascent
;
5581 descent
= it
->max_descent
;
5584 PRODUCE_GLYPHS (it
);
5586 if (it
->area
!= TEXT_AREA
)
5588 set_iterator_to_next (it
, 1);
5592 /* The number of glyphs we get back in IT->nglyphs will normally
5593 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
5594 character on a terminal frame, or (iii) a line end. For the
5595 second case, IT->nglyphs - 1 padding glyphs will be present
5596 (on X frames, there is only one glyph produced for a
5597 composite character.
5599 The behavior implemented below means, for continuation lines,
5600 that as many spaces of a TAB as fit on the current line are
5601 displayed there. For terminal frames, as many glyphs of a
5602 multi-glyph character are displayed in the current line, too.
5603 This is what the old redisplay code did, and we keep it that
5604 way. Under X, the whole shape of a complex character must
5605 fit on the line or it will be completely displayed in the
5608 Note that both for tabs and padding glyphs, all glyphs have
5612 /* More than one glyph or glyph doesn't fit on line. All
5613 glyphs have the same width. */
5614 int single_glyph_width
= it
->pixel_width
/ it
->nglyphs
;
5617 for (i
= 0; i
< it
->nglyphs
; ++i
, x
= new_x
)
5619 new_x
= x
+ single_glyph_width
;
5621 /* We want to leave anything reaching TO_X to the caller. */
5622 if ((op
& MOVE_TO_X
) && new_x
> to_x
)
5625 result
= MOVE_X_REACHED
;
5628 else if (/* Lines are continued. */
5629 !it
->truncate_lines_p
5630 && (/* And glyph doesn't fit on the line. */
5631 new_x
> it
->last_visible_x
5632 /* Or it fits exactly and we're on a window
5634 || (new_x
== it
->last_visible_x
5635 && FRAME_WINDOW_P (it
->f
))))
5637 if (/* IT->hpos == 0 means the very first glyph
5638 doesn't fit on the line, e.g. a wide image. */
5640 || (new_x
== it
->last_visible_x
5641 && FRAME_WINDOW_P (it
->f
)))
5644 it
->current_x
= new_x
;
5645 if (i
== it
->nglyphs
- 1)
5647 set_iterator_to_next (it
, 1);
5648 #ifdef HAVE_WINDOW_SYSTEM
5649 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
5651 if (!get_next_display_element (it
))
5653 result
= MOVE_POS_MATCH_OR_ZV
;
5656 if (ITERATOR_AT_END_OF_LINE_P (it
))
5658 result
= MOVE_NEWLINE_OR_CR
;
5662 #endif /* HAVE_WINDOW_SYSTEM */
5668 it
->max_ascent
= ascent
;
5669 it
->max_descent
= descent
;
5672 TRACE_MOVE ((stderr
, "move_it_in: continued at %d\n",
5674 result
= MOVE_LINE_CONTINUED
;
5677 else if (new_x
> it
->first_visible_x
)
5679 /* Glyph is visible. Increment number of glyphs that
5680 would be displayed. */
5685 /* Glyph is completely off the left margin of the display
5686 area. Nothing to do. */
5690 if (result
!= MOVE_UNDEFINED
)
5693 else if ((op
& MOVE_TO_X
) && it
->current_x
>= to_x
)
5695 /* Stop when TO_X specified and reached. This check is
5696 necessary here because of lines consisting of a line end,
5697 only. The line end will not produce any glyphs and we
5698 would never get MOVE_X_REACHED. */
5699 xassert (it
->nglyphs
== 0);
5700 result
= MOVE_X_REACHED
;
5704 /* Is this a line end? If yes, we're done. */
5705 if (ITERATOR_AT_END_OF_LINE_P (it
))
5707 result
= MOVE_NEWLINE_OR_CR
;
5711 /* The current display element has been consumed. Advance
5713 set_iterator_to_next (it
, 1);
5715 /* Stop if lines are truncated and IT's current x-position is
5716 past the right edge of the window now. */
5717 if (it
->truncate_lines_p
5718 && it
->current_x
>= it
->last_visible_x
)
5720 #ifdef HAVE_WINDOW_SYSTEM
5721 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
5723 if (!get_next_display_element (it
))
5725 result
= MOVE_POS_MATCH_OR_ZV
;
5728 if (ITERATOR_AT_END_OF_LINE_P (it
))
5730 result
= MOVE_NEWLINE_OR_CR
;
5734 #endif /* HAVE_WINDOW_SYSTEM */
5735 result
= MOVE_LINE_TRUNCATED
;
5740 /* Restore the iterator settings altered at the beginning of this
5742 it
->glyph_row
= saved_glyph_row
;
5747 /* Move IT forward until it satisfies one or more of the criteria in
5748 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
5750 OP is a bit-mask that specifies where to stop, and in particular,
5751 which of those four position arguments makes a difference. See the
5752 description of enum move_operation_enum.
5754 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
5755 screen line, this function will set IT to the next position >
5759 move_it_to (it
, to_charpos
, to_x
, to_y
, to_vpos
, op
)
5761 int to_charpos
, to_x
, to_y
, to_vpos
;
5764 enum move_it_result skip
, skip2
= MOVE_X_REACHED
;
5770 if (op
& MOVE_TO_VPOS
)
5772 /* If no TO_CHARPOS and no TO_X specified, stop at the
5773 start of the line TO_VPOS. */
5774 if ((op
& (MOVE_TO_X
| MOVE_TO_POS
)) == 0)
5776 if (it
->vpos
== to_vpos
)
5782 skip
= move_it_in_display_line_to (it
, -1, -1, 0);
5786 /* TO_VPOS >= 0 means stop at TO_X in the line at
5787 TO_VPOS, or at TO_POS, whichever comes first. */
5788 if (it
->vpos
== to_vpos
)
5794 skip
= move_it_in_display_line_to (it
, to_charpos
, to_x
, op
);
5796 if (skip
== MOVE_POS_MATCH_OR_ZV
|| it
->vpos
== to_vpos
)
5801 else if (skip
== MOVE_X_REACHED
&& it
->vpos
!= to_vpos
)
5803 /* We have reached TO_X but not in the line we want. */
5804 skip
= move_it_in_display_line_to (it
, to_charpos
,
5806 if (skip
== MOVE_POS_MATCH_OR_ZV
)
5814 else if (op
& MOVE_TO_Y
)
5816 struct it it_backup
;
5818 /* TO_Y specified means stop at TO_X in the line containing
5819 TO_Y---or at TO_CHARPOS if this is reached first. The
5820 problem is that we can't really tell whether the line
5821 contains TO_Y before we have completely scanned it, and
5822 this may skip past TO_X. What we do is to first scan to
5825 If TO_X is not specified, use a TO_X of zero. The reason
5826 is to make the outcome of this function more predictable.
5827 If we didn't use TO_X == 0, we would stop at the end of
5828 the line which is probably not what a caller would expect
5830 skip
= move_it_in_display_line_to (it
, to_charpos
,
5834 | (op
& MOVE_TO_POS
)));
5836 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
5837 if (skip
== MOVE_POS_MATCH_OR_ZV
)
5843 /* If TO_X was reached, we would like to know whether TO_Y
5844 is in the line. This can only be said if we know the
5845 total line height which requires us to scan the rest of
5847 if (skip
== MOVE_X_REACHED
)
5850 TRACE_MOVE ((stderr
, "move_it: from %d\n", IT_CHARPOS (*it
)));
5851 skip2
= move_it_in_display_line_to (it
, to_charpos
, -1,
5853 TRACE_MOVE ((stderr
, "move_it: to %d\n", IT_CHARPOS (*it
)));
5856 /* Now, decide whether TO_Y is in this line. */
5857 line_height
= it
->max_ascent
+ it
->max_descent
;
5858 TRACE_MOVE ((stderr
, "move_it: line_height = %d\n", line_height
));
5860 if (to_y
>= it
->current_y
5861 && to_y
< it
->current_y
+ line_height
)
5863 if (skip
== MOVE_X_REACHED
)
5864 /* If TO_Y is in this line and TO_X was reached above,
5865 we scanned too far. We have to restore IT's settings
5866 to the ones before skipping. */
5870 else if (skip
== MOVE_X_REACHED
)
5873 if (skip
== MOVE_POS_MATCH_OR_ZV
)
5881 skip
= move_it_in_display_line_to (it
, to_charpos
, -1, MOVE_TO_POS
);
5885 case MOVE_POS_MATCH_OR_ZV
:
5889 case MOVE_NEWLINE_OR_CR
:
5890 set_iterator_to_next (it
, 1);
5891 it
->continuation_lines_width
= 0;
5894 case MOVE_LINE_TRUNCATED
:
5895 it
->continuation_lines_width
= 0;
5896 reseat_at_next_visible_line_start (it
, 0);
5897 if ((op
& MOVE_TO_POS
) != 0
5898 && IT_CHARPOS (*it
) > to_charpos
)
5905 case MOVE_LINE_CONTINUED
:
5906 it
->continuation_lines_width
+= it
->current_x
;
5913 /* Reset/increment for the next run. */
5914 recenter_overlay_lists (current_buffer
, IT_CHARPOS (*it
));
5915 it
->current_x
= it
->hpos
= 0;
5916 it
->current_y
+= it
->max_ascent
+ it
->max_descent
;
5918 last_height
= it
->max_ascent
+ it
->max_descent
;
5919 last_max_ascent
= it
->max_ascent
;
5920 it
->max_ascent
= it
->max_descent
= 0;
5925 TRACE_MOVE ((stderr
, "move_it_to: reached %d\n", reached
));
5929 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
5931 If DY > 0, move IT backward at least that many pixels. DY = 0
5932 means move IT backward to the preceding line start or BEGV. This
5933 function may move over more than DY pixels if IT->current_y - DY
5934 ends up in the middle of a line; in this case IT->current_y will be
5935 set to the top of the line moved to. */
5938 move_it_vertically_backward (it
, dy
)
5944 int start_pos
= IT_CHARPOS (*it
);
5948 /* Estimate how many newlines we must move back. */
5949 nlines
= max (1, dy
/ FRAME_LINE_HEIGHT (it
->f
));
5951 /* Set the iterator's position that many lines back. */
5952 while (nlines
-- && IT_CHARPOS (*it
) > BEGV
)
5953 back_to_previous_visible_line_start (it
);
5955 /* Reseat the iterator here. When moving backward, we don't want
5956 reseat to skip forward over invisible text, set up the iterator
5957 to deliver from overlay strings at the new position etc. So,
5958 use reseat_1 here. */
5959 reseat_1 (it
, it
->current
.pos
, 1);
5961 /* We are now surely at a line start. */
5962 it
->current_x
= it
->hpos
= 0;
5963 it
->continuation_lines_width
= 0;
5965 /* Move forward and see what y-distance we moved. First move to the
5966 start of the next line so that we get its height. We need this
5967 height to be able to tell whether we reached the specified
5970 it2
.max_ascent
= it2
.max_descent
= 0;
5971 move_it_to (&it2
, start_pos
, -1, -1, it2
.vpos
+ 1,
5972 MOVE_TO_POS
| MOVE_TO_VPOS
);
5973 xassert (IT_CHARPOS (*it
) >= BEGV
);
5976 move_it_to (&it2
, start_pos
, -1, -1, -1, MOVE_TO_POS
);
5977 xassert (IT_CHARPOS (*it
) >= BEGV
);
5978 /* H is the actual vertical distance from the position in *IT
5979 and the starting position. */
5980 h
= it2
.current_y
- it
->current_y
;
5981 /* NLINES is the distance in number of lines. */
5982 nlines
= it2
.vpos
- it
->vpos
;
5984 /* Correct IT's y and vpos position
5985 so that they are relative to the starting point. */
5991 /* DY == 0 means move to the start of the screen line. The
5992 value of nlines is > 0 if continuation lines were involved. */
5994 move_it_by_lines (it
, nlines
, 1);
5995 xassert (IT_CHARPOS (*it
) <= start_pos
);
5999 /* The y-position we try to reach, relative to *IT.
6000 Note that H has been subtracted in front of the if-statement. */
6001 int target_y
= it
->current_y
+ h
- dy
;
6002 int y0
= it3
.current_y
;
6003 int y1
= line_bottom_y (&it3
);
6004 int line_height
= y1
- y0
;
6006 /* If we did not reach target_y, try to move further backward if
6007 we can. If we moved too far backward, try to move forward. */
6008 if (target_y
< it
->current_y
6009 /* This is heuristic. In a window that's 3 lines high, with
6010 a line height of 13 pixels each, recentering with point
6011 on the bottom line will try to move -39/2 = 19 pixels
6012 backward. Try to avoid moving into the first line. */
6013 && it
->current_y
- target_y
> line_height
/ 3 * 2
6014 && IT_CHARPOS (*it
) > BEGV
)
6016 TRACE_MOVE ((stderr
, " not far enough -> move_vert %d\n",
6017 target_y
- it
->current_y
));
6018 move_it_vertically (it
, target_y
- it
->current_y
);
6019 xassert (IT_CHARPOS (*it
) >= BEGV
);
6021 else if (target_y
>= it
->current_y
+ line_height
6022 && IT_CHARPOS (*it
) < ZV
)
6024 /* Should move forward by at least one line, maybe more.
6026 Note: Calling move_it_by_lines can be expensive on
6027 terminal frames, where compute_motion is used (via
6028 vmotion) to do the job, when there are very long lines
6029 and truncate-lines is nil. That's the reason for
6030 treating terminal frames specially here. */
6032 if (!FRAME_WINDOW_P (it
->f
))
6033 move_it_vertically (it
, target_y
- (it
->current_y
+ line_height
));
6038 move_it_by_lines (it
, 1, 1);
6040 while (target_y
>= line_bottom_y (it
) && IT_CHARPOS (*it
) < ZV
);
6043 xassert (IT_CHARPOS (*it
) >= BEGV
);
6049 /* Move IT by a specified amount of pixel lines DY. DY negative means
6050 move backwards. DY = 0 means move to start of screen line. At the
6051 end, IT will be on the start of a screen line. */
6054 move_it_vertically (it
, dy
)
6059 move_it_vertically_backward (it
, -dy
);
6062 TRACE_MOVE ((stderr
, "move_it_v: from %d, %d\n", IT_CHARPOS (*it
), dy
));
6063 move_it_to (it
, ZV
, -1, it
->current_y
+ dy
, -1,
6064 MOVE_TO_POS
| MOVE_TO_Y
);
6065 TRACE_MOVE ((stderr
, "move_it_v: to %d\n", IT_CHARPOS (*it
)));
6067 /* If buffer ends in ZV without a newline, move to the start of
6068 the line to satisfy the post-condition. */
6069 if (IT_CHARPOS (*it
) == ZV
6070 && FETCH_BYTE (IT_BYTEPOS (*it
) - 1) != '\n')
6071 move_it_by_lines (it
, 0, 0);
6076 /* Move iterator IT past the end of the text line it is in. */
6079 move_it_past_eol (it
)
6082 enum move_it_result rc
;
6084 rc
= move_it_in_display_line_to (it
, Z
, 0, MOVE_TO_POS
);
6085 if (rc
== MOVE_NEWLINE_OR_CR
)
6086 set_iterator_to_next (it
, 0);
6090 #if 0 /* Currently not used. */
6092 /* Return non-zero if some text between buffer positions START_CHARPOS
6093 and END_CHARPOS is invisible. IT->window is the window for text
6097 invisible_text_between_p (it
, start_charpos
, end_charpos
)
6099 int start_charpos
, end_charpos
;
6101 Lisp_Object prop
, limit
;
6102 int invisible_found_p
;
6104 xassert (it
!= NULL
&& start_charpos
<= end_charpos
);
6106 /* Is text at START invisible? */
6107 prop
= Fget_char_property (make_number (start_charpos
), Qinvisible
,
6109 if (TEXT_PROP_MEANS_INVISIBLE (prop
))
6110 invisible_found_p
= 1;
6113 limit
= Fnext_single_char_property_change (make_number (start_charpos
),
6115 make_number (end_charpos
));
6116 invisible_found_p
= XFASTINT (limit
) < end_charpos
;
6119 return invisible_found_p
;
6125 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
6126 negative means move up. DVPOS == 0 means move to the start of the
6127 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
6128 NEED_Y_P is zero, IT->current_y will be left unchanged.
6130 Further optimization ideas: If we would know that IT->f doesn't use
6131 a face with proportional font, we could be faster for
6132 truncate-lines nil. */
6135 move_it_by_lines (it
, dvpos
, need_y_p
)
6137 int dvpos
, need_y_p
;
6139 struct position pos
;
6141 if (!FRAME_WINDOW_P (it
->f
))
6143 struct text_pos textpos
;
6145 /* We can use vmotion on frames without proportional fonts. */
6146 pos
= *vmotion (IT_CHARPOS (*it
), dvpos
, it
->w
);
6147 SET_TEXT_POS (textpos
, pos
.bufpos
, pos
.bytepos
);
6148 reseat (it
, textpos
, 1);
6149 it
->vpos
+= pos
.vpos
;
6150 it
->current_y
+= pos
.vpos
;
6152 else if (dvpos
== 0)
6154 /* DVPOS == 0 means move to the start of the screen line. */
6155 move_it_vertically_backward (it
, 0);
6156 xassert (it
->current_x
== 0 && it
->hpos
== 0);
6159 move_it_to (it
, -1, -1, -1, it
->vpos
+ dvpos
, MOVE_TO_VPOS
);
6163 int start_charpos
, i
;
6165 /* Start at the beginning of the screen line containing IT's
6167 move_it_vertically_backward (it
, 0);
6169 /* Go back -DVPOS visible lines and reseat the iterator there. */
6170 start_charpos
= IT_CHARPOS (*it
);
6171 for (i
= -dvpos
; i
&& IT_CHARPOS (*it
) > BEGV
; --i
)
6172 back_to_previous_visible_line_start (it
);
6173 reseat (it
, it
->current
.pos
, 1);
6174 it
->current_x
= it
->hpos
= 0;
6176 /* Above call may have moved too far if continuation lines
6177 are involved. Scan forward and see if it did. */
6179 it2
.vpos
= it2
.current_y
= 0;
6180 move_it_to (&it2
, start_charpos
, -1, -1, -1, MOVE_TO_POS
);
6181 it
->vpos
-= it2
.vpos
;
6182 it
->current_y
-= it2
.current_y
;
6183 it
->current_x
= it
->hpos
= 0;
6185 /* If we moved too far, move IT some lines forward. */
6186 if (it2
.vpos
> -dvpos
)
6188 int delta
= it2
.vpos
+ dvpos
;
6189 move_it_to (it
, -1, -1, -1, it
->vpos
+ delta
, MOVE_TO_VPOS
);
6194 /* Return 1 if IT points into the middle of a display vector. */
6197 in_display_vector_p (it
)
6200 return (it
->method
== next_element_from_display_vector
6201 && it
->current
.dpvec_index
> 0
6202 && it
->dpvec
+ it
->current
.dpvec_index
!= it
->dpend
);
6206 /***********************************************************************
6208 ***********************************************************************/
6211 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
6215 add_to_log (format
, arg1
, arg2
)
6217 Lisp_Object arg1
, arg2
;
6219 Lisp_Object args
[3];
6220 Lisp_Object msg
, fmt
;
6223 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
6225 /* Do nothing if called asynchronously. Inserting text into
6226 a buffer may call after-change-functions and alike and
6227 that would means running Lisp asynchronously. */
6228 if (handling_signal
)
6232 GCPRO4 (fmt
, msg
, arg1
, arg2
);
6234 args
[0] = fmt
= build_string (format
);
6237 msg
= Fformat (3, args
);
6239 len
= SBYTES (msg
) + 1;
6240 buffer
= (char *) alloca (len
);
6241 bcopy (SDATA (msg
), buffer
, len
);
6243 message_dolog (buffer
, len
- 1, 1, 0);
6248 /* Output a newline in the *Messages* buffer if "needs" one. */
6251 message_log_maybe_newline ()
6253 if (message_log_need_newline
)
6254 message_dolog ("", 0, 1, 0);
6258 /* Add a string M of length NBYTES to the message log, optionally
6259 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
6260 nonzero, means interpret the contents of M as multibyte. This
6261 function calls low-level routines in order to bypass text property
6262 hooks, etc. which might not be safe to run. */
6265 message_dolog (m
, nbytes
, nlflag
, multibyte
)
6267 int nbytes
, nlflag
, multibyte
;
6269 if (!NILP (Vmemory_full
))
6272 if (!NILP (Vmessage_log_max
))
6274 struct buffer
*oldbuf
;
6275 Lisp_Object oldpoint
, oldbegv
, oldzv
;
6276 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
6277 int point_at_end
= 0;
6279 Lisp_Object old_deactivate_mark
, tem
;
6280 struct gcpro gcpro1
;
6282 old_deactivate_mark
= Vdeactivate_mark
;
6283 oldbuf
= current_buffer
;
6284 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name
));
6285 current_buffer
->undo_list
= Qt
;
6287 oldpoint
= message_dolog_marker1
;
6288 set_marker_restricted (oldpoint
, make_number (PT
), Qnil
);
6289 oldbegv
= message_dolog_marker2
;
6290 set_marker_restricted (oldbegv
, make_number (BEGV
), Qnil
);
6291 oldzv
= message_dolog_marker3
;
6292 set_marker_restricted (oldzv
, make_number (ZV
), Qnil
);
6293 GCPRO1 (old_deactivate_mark
);
6301 BEGV_BYTE
= BEG_BYTE
;
6304 TEMP_SET_PT_BOTH (Z
, Z_BYTE
);
6306 /* Insert the string--maybe converting multibyte to single byte
6307 or vice versa, so that all the text fits the buffer. */
6309 && NILP (current_buffer
->enable_multibyte_characters
))
6311 int i
, c
, char_bytes
;
6312 unsigned char work
[1];
6314 /* Convert a multibyte string to single-byte
6315 for the *Message* buffer. */
6316 for (i
= 0; i
< nbytes
; i
+= char_bytes
)
6318 c
= string_char_and_length (m
+ i
, nbytes
- i
, &char_bytes
);
6319 work
[0] = (SINGLE_BYTE_CHAR_P (c
)
6321 : multibyte_char_to_unibyte (c
, Qnil
));
6322 insert_1_both (work
, 1, 1, 1, 0, 0);
6325 else if (! multibyte
6326 && ! NILP (current_buffer
->enable_multibyte_characters
))
6328 int i
, c
, char_bytes
;
6329 unsigned char *msg
= (unsigned char *) m
;
6330 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
6331 /* Convert a single-byte string to multibyte
6332 for the *Message* buffer. */
6333 for (i
= 0; i
< nbytes
; i
++)
6335 c
= unibyte_char_to_multibyte (msg
[i
]);
6336 char_bytes
= CHAR_STRING (c
, str
);
6337 insert_1_both (str
, 1, char_bytes
, 1, 0, 0);
6341 insert_1 (m
, nbytes
, 1, 0, 0);
6345 int this_bol
, this_bol_byte
, prev_bol
, prev_bol_byte
, dup
;
6346 insert_1 ("\n", 1, 1, 0, 0);
6348 scan_newline (Z
, Z_BYTE
, BEG
, BEG_BYTE
, -2, 0);
6350 this_bol_byte
= PT_BYTE
;
6352 /* See if this line duplicates the previous one.
6353 If so, combine duplicates. */
6356 scan_newline (PT
, PT_BYTE
, BEG
, BEG_BYTE
, -2, 0);
6358 prev_bol_byte
= PT_BYTE
;
6360 dup
= message_log_check_duplicate (prev_bol
, prev_bol_byte
,
6361 this_bol
, this_bol_byte
);
6364 del_range_both (prev_bol
, prev_bol_byte
,
6365 this_bol
, this_bol_byte
, 0);
6371 /* If you change this format, don't forget to also
6372 change message_log_check_duplicate. */
6373 sprintf (dupstr
, " [%d times]", dup
);
6374 duplen
= strlen (dupstr
);
6375 TEMP_SET_PT_BOTH (Z
- 1, Z_BYTE
- 1);
6376 insert_1 (dupstr
, duplen
, 1, 0, 1);
6381 /* If we have more than the desired maximum number of lines
6382 in the *Messages* buffer now, delete the oldest ones.
6383 This is safe because we don't have undo in this buffer. */
6385 if (NATNUMP (Vmessage_log_max
))
6387 scan_newline (Z
, Z_BYTE
, BEG
, BEG_BYTE
,
6388 -XFASTINT (Vmessage_log_max
) - 1, 0);
6389 del_range_both (BEG
, BEG_BYTE
, PT
, PT_BYTE
, 0);
6392 BEGV
= XMARKER (oldbegv
)->charpos
;
6393 BEGV_BYTE
= marker_byte_position (oldbegv
);
6402 ZV
= XMARKER (oldzv
)->charpos
;
6403 ZV_BYTE
= marker_byte_position (oldzv
);
6407 TEMP_SET_PT_BOTH (Z
, Z_BYTE
);
6409 /* We can't do Fgoto_char (oldpoint) because it will run some
6411 TEMP_SET_PT_BOTH (XMARKER (oldpoint
)->charpos
,
6412 XMARKER (oldpoint
)->bytepos
);
6415 unchain_marker (XMARKER (oldpoint
));
6416 unchain_marker (XMARKER (oldbegv
));
6417 unchain_marker (XMARKER (oldzv
));
6419 tem
= Fget_buffer_window (Fcurrent_buffer (), Qt
);
6420 set_buffer_internal (oldbuf
);
6422 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
6423 message_log_need_newline
= !nlflag
;
6424 Vdeactivate_mark
= old_deactivate_mark
;
6429 /* We are at the end of the buffer after just having inserted a newline.
6430 (Note: We depend on the fact we won't be crossing the gap.)
6431 Check to see if the most recent message looks a lot like the previous one.
6432 Return 0 if different, 1 if the new one should just replace it, or a
6433 value N > 1 if we should also append " [N times]". */
6436 message_log_check_duplicate (prev_bol
, prev_bol_byte
, this_bol
, this_bol_byte
)
6437 int prev_bol
, this_bol
;
6438 int prev_bol_byte
, this_bol_byte
;
6441 int len
= Z_BYTE
- 1 - this_bol_byte
;
6443 unsigned char *p1
= BUF_BYTE_ADDRESS (current_buffer
, prev_bol_byte
);
6444 unsigned char *p2
= BUF_BYTE_ADDRESS (current_buffer
, this_bol_byte
);
6446 for (i
= 0; i
< len
; i
++)
6448 if (i
>= 3 && p1
[i
-3] == '.' && p1
[i
-2] == '.' && p1
[i
-1] == '.')
6456 if (*p1
++ == ' ' && *p1
++ == '[')
6459 while (*p1
>= '0' && *p1
<= '9')
6460 n
= n
* 10 + *p1
++ - '0';
6461 if (strncmp (p1
, " times]\n", 8) == 0)
6468 /* Display an echo area message M with a specified length of NBYTES
6469 bytes. The string may include null characters. If M is 0, clear
6470 out any existing message, and let the mini-buffer text show
6473 The buffer M must continue to exist until after the echo area gets
6474 cleared or some other message gets displayed there. This means do
6475 not pass text that is stored in a Lisp string; do not pass text in
6476 a buffer that was alloca'd. */
6479 message2 (m
, nbytes
, multibyte
)
6484 /* First flush out any partial line written with print. */
6485 message_log_maybe_newline ();
6487 message_dolog (m
, nbytes
, 1, multibyte
);
6488 message2_nolog (m
, nbytes
, multibyte
);
6492 /* The non-logging counterpart of message2. */
6495 message2_nolog (m
, nbytes
, multibyte
)
6497 int nbytes
, multibyte
;
6499 struct frame
*sf
= SELECTED_FRAME ();
6500 message_enable_multibyte
= multibyte
;
6504 if (noninteractive_need_newline
)
6505 putc ('\n', stderr
);
6506 noninteractive_need_newline
= 0;
6508 fwrite (m
, nbytes
, 1, stderr
);
6509 if (cursor_in_echo_area
== 0)
6510 fprintf (stderr
, "\n");
6513 /* A null message buffer means that the frame hasn't really been
6514 initialized yet. Error messages get reported properly by
6515 cmd_error, so this must be just an informative message; toss it. */
6516 else if (INTERACTIVE
6517 && sf
->glyphs_initialized_p
6518 && FRAME_MESSAGE_BUF (sf
))
6520 Lisp_Object mini_window
;
6523 /* Get the frame containing the mini-buffer
6524 that the selected frame is using. */
6525 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
6526 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
6528 FRAME_SAMPLE_VISIBILITY (f
);
6529 if (FRAME_VISIBLE_P (sf
)
6530 && ! FRAME_VISIBLE_P (f
))
6531 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window
)));
6535 set_message (m
, Qnil
, nbytes
, multibyte
);
6536 if (minibuffer_auto_raise
)
6537 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window
)));
6540 clear_message (1, 1);
6542 do_pending_window_change (0);
6543 echo_area_display (1);
6544 do_pending_window_change (0);
6545 if (FRAME_DISPLAY (f
)->frame_up_to_date_hook
!= 0 && ! gc_in_progress
)
6546 (*FRAME_DISPLAY (f
)->frame_up_to_date_hook
) (f
);
6551 /* Display an echo area message M with a specified length of NBYTES
6552 bytes. The string may include null characters. If M is not a
6553 string, clear out any existing message, and let the mini-buffer
6554 text show through. */
6557 message3 (m
, nbytes
, multibyte
)
6562 struct gcpro gcpro1
;
6566 /* First flush out any partial line written with print. */
6567 message_log_maybe_newline ();
6569 message_dolog (SDATA (m
), nbytes
, 1, multibyte
);
6570 message3_nolog (m
, nbytes
, multibyte
);
6576 /* The non-logging version of message3. */
6579 message3_nolog (m
, nbytes
, multibyte
)
6581 int nbytes
, multibyte
;
6583 struct frame
*sf
= SELECTED_FRAME ();
6584 message_enable_multibyte
= multibyte
;
6588 if (noninteractive_need_newline
)
6589 putc ('\n', stderr
);
6590 noninteractive_need_newline
= 0;
6592 fwrite (SDATA (m
), nbytes
, 1, stderr
);
6593 if (cursor_in_echo_area
== 0)
6594 fprintf (stderr
, "\n");
6597 /* A null message buffer means that the frame hasn't really been
6598 initialized yet. Error messages get reported properly by
6599 cmd_error, so this must be just an informative message; toss it. */
6600 else if (INTERACTIVE
6601 && sf
->glyphs_initialized_p
6602 && FRAME_MESSAGE_BUF (sf
))
6604 Lisp_Object mini_window
;
6608 /* Get the frame containing the mini-buffer
6609 that the selected frame is using. */
6610 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
6611 frame
= XWINDOW (mini_window
)->frame
;
6614 FRAME_SAMPLE_VISIBILITY (f
);
6615 if (FRAME_VISIBLE_P (sf
)
6616 && !FRAME_VISIBLE_P (f
))
6617 Fmake_frame_visible (frame
);
6619 if (STRINGP (m
) && SCHARS (m
) > 0)
6621 set_message (NULL
, m
, nbytes
, multibyte
);
6622 if (minibuffer_auto_raise
)
6623 Fraise_frame (frame
);
6626 clear_message (1, 1);
6628 do_pending_window_change (0);
6629 echo_area_display (1);
6630 do_pending_window_change (0);
6631 if (FRAME_DISPLAY (f
)->frame_up_to_date_hook
!= 0 && ! gc_in_progress
)
6632 (*FRAME_DISPLAY (f
)->frame_up_to_date_hook
) (f
);
6637 /* Display a null-terminated echo area message M. If M is 0, clear
6638 out any existing message, and let the mini-buffer text show through.
6640 The buffer M must continue to exist until after the echo area gets
6641 cleared or some other message gets displayed there. Do not pass
6642 text that is stored in a Lisp string. Do not pass text in a buffer
6643 that was alloca'd. */
6649 message2 (m
, (m
? strlen (m
) : 0), 0);
6653 /* The non-logging counterpart of message1. */
6659 message2_nolog (m
, (m
? strlen (m
) : 0), 0);
6662 /* Display a message M which contains a single %s
6663 which gets replaced with STRING. */
6666 message_with_string (m
, string
, log
)
6671 CHECK_STRING (string
);
6677 if (noninteractive_need_newline
)
6678 putc ('\n', stderr
);
6679 noninteractive_need_newline
= 0;
6680 fprintf (stderr
, m
, SDATA (string
));
6681 if (cursor_in_echo_area
== 0)
6682 fprintf (stderr
, "\n");
6686 else if (INTERACTIVE
)
6688 /* The frame whose minibuffer we're going to display the message on.
6689 It may be larger than the selected frame, so we need
6690 to use its buffer, not the selected frame's buffer. */
6691 Lisp_Object mini_window
;
6692 struct frame
*f
, *sf
= SELECTED_FRAME ();
6694 /* Get the frame containing the minibuffer
6695 that the selected frame is using. */
6696 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
6697 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
6699 /* A null message buffer means that the frame hasn't really been
6700 initialized yet. Error messages get reported properly by
6701 cmd_error, so this must be just an informative message; toss it. */
6702 if (FRAME_MESSAGE_BUF (f
))
6704 Lisp_Object args
[2], message
;
6705 struct gcpro gcpro1
, gcpro2
;
6707 args
[0] = build_string (m
);
6708 args
[1] = message
= string
;
6709 GCPRO2 (args
[0], message
);
6712 message
= Fformat (2, args
);
6715 message3 (message
, SBYTES (message
), STRING_MULTIBYTE (message
));
6717 message3_nolog (message
, SBYTES (message
), STRING_MULTIBYTE (message
));
6721 /* Print should start at the beginning of the message
6722 buffer next time. */
6723 message_buf_print
= 0;
6729 /* Dump an informative message to the minibuf. If M is 0, clear out
6730 any existing message, and let the mini-buffer text show through. */
6734 message (m
, a1
, a2
, a3
)
6736 EMACS_INT a1
, a2
, a3
;
6742 if (noninteractive_need_newline
)
6743 putc ('\n', stderr
);
6744 noninteractive_need_newline
= 0;
6745 fprintf (stderr
, m
, a1
, a2
, a3
);
6746 if (cursor_in_echo_area
== 0)
6747 fprintf (stderr
, "\n");
6751 else if (INTERACTIVE
)
6753 /* The frame whose mini-buffer we're going to display the message
6754 on. It may be larger than the selected frame, so we need to
6755 use its buffer, not the selected frame's buffer. */
6756 Lisp_Object mini_window
;
6757 struct frame
*f
, *sf
= SELECTED_FRAME ();
6759 /* Get the frame containing the mini-buffer
6760 that the selected frame is using. */
6761 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
6762 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
6764 /* A null message buffer means that the frame hasn't really been
6765 initialized yet. Error messages get reported properly by
6766 cmd_error, so this must be just an informative message; toss
6768 if (FRAME_MESSAGE_BUF (f
))
6779 len
= doprnt (FRAME_MESSAGE_BUF (f
),
6780 FRAME_MESSAGE_BUF_SIZE (f
), m
, (char *)0, 3, a
);
6782 len
= doprnt (FRAME_MESSAGE_BUF (f
),
6783 FRAME_MESSAGE_BUF_SIZE (f
), m
, (char *)0, 3,
6785 #endif /* NO_ARG_ARRAY */
6787 message2 (FRAME_MESSAGE_BUF (f
), len
, 0);
6792 /* Print should start at the beginning of the message
6793 buffer next time. */
6794 message_buf_print
= 0;
6800 /* The non-logging version of message. */
6803 message_nolog (m
, a1
, a2
, a3
)
6805 EMACS_INT a1
, a2
, a3
;
6807 Lisp_Object old_log_max
;
6808 old_log_max
= Vmessage_log_max
;
6809 Vmessage_log_max
= Qnil
;
6810 message (m
, a1
, a2
, a3
);
6811 Vmessage_log_max
= old_log_max
;
6815 /* Display the current message in the current mini-buffer. This is
6816 only called from error handlers in process.c, and is not time
6822 if (!NILP (echo_area_buffer
[0]))
6825 string
= Fcurrent_message ();
6826 message3 (string
, SBYTES (string
),
6827 !NILP (current_buffer
->enable_multibyte_characters
));
6832 /* Make sure echo area buffers in `echo_buffers' are live.
6833 If they aren't, make new ones. */
6836 ensure_echo_area_buffers ()
6840 for (i
= 0; i
< 2; ++i
)
6841 if (!BUFFERP (echo_buffer
[i
])
6842 || NILP (XBUFFER (echo_buffer
[i
])->name
))
6845 Lisp_Object old_buffer
;
6848 old_buffer
= echo_buffer
[i
];
6849 sprintf (name
, " *Echo Area %d*", i
);
6850 echo_buffer
[i
] = Fget_buffer_create (build_string (name
));
6851 XBUFFER (echo_buffer
[i
])->truncate_lines
= Qnil
;
6853 for (j
= 0; j
< 2; ++j
)
6854 if (EQ (old_buffer
, echo_area_buffer
[j
]))
6855 echo_area_buffer
[j
] = echo_buffer
[i
];
6860 /* Call FN with args A1..A4 with either the current or last displayed
6861 echo_area_buffer as current buffer.
6863 WHICH zero means use the current message buffer
6864 echo_area_buffer[0]. If that is nil, choose a suitable buffer
6865 from echo_buffer[] and clear it.
6867 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
6868 suitable buffer from echo_buffer[] and clear it.
6870 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
6871 that the current message becomes the last displayed one, make
6872 choose a suitable buffer for echo_area_buffer[0], and clear it.
6874 Value is what FN returns. */
6877 with_echo_area_buffer (w
, which
, fn
, a1
, a2
, a3
, a4
)
6880 int (*fn
) P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
6886 int this_one
, the_other
, clear_buffer_p
, rc
;
6887 int count
= SPECPDL_INDEX ();
6889 /* If buffers aren't live, make new ones. */
6890 ensure_echo_area_buffers ();
6895 this_one
= 0, the_other
= 1;
6897 this_one
= 1, the_other
= 0;
6900 this_one
= 0, the_other
= 1;
6903 /* We need a fresh one in case the current echo buffer equals
6904 the one containing the last displayed echo area message. */
6905 if (!NILP (echo_area_buffer
[this_one
])
6906 && EQ (echo_area_buffer
[this_one
], echo_area_buffer
[the_other
]))
6907 echo_area_buffer
[this_one
] = Qnil
;
6910 /* Choose a suitable buffer from echo_buffer[] is we don't
6912 if (NILP (echo_area_buffer
[this_one
]))
6914 echo_area_buffer
[this_one
]
6915 = (EQ (echo_area_buffer
[the_other
], echo_buffer
[this_one
])
6916 ? echo_buffer
[the_other
]
6917 : echo_buffer
[this_one
]);
6921 buffer
= echo_area_buffer
[this_one
];
6923 /* Don't get confused by reusing the buffer used for echoing
6924 for a different purpose. */
6925 if (echo_kboard
== NULL
&& EQ (buffer
, echo_message_buffer
))
6928 record_unwind_protect (unwind_with_echo_area_buffer
,
6929 with_echo_area_buffer_unwind_data (w
));
6931 /* Make the echo area buffer current. Note that for display
6932 purposes, it is not necessary that the displayed window's buffer
6933 == current_buffer, except for text property lookup. So, let's
6934 only set that buffer temporarily here without doing a full
6935 Fset_window_buffer. We must also change w->pointm, though,
6936 because otherwise an assertions in unshow_buffer fails, and Emacs
6938 set_buffer_internal_1 (XBUFFER (buffer
));
6942 set_marker_both (w
->pointm
, buffer
, BEG
, BEG_BYTE
);
6945 current_buffer
->undo_list
= Qt
;
6946 current_buffer
->read_only
= Qnil
;
6947 specbind (Qinhibit_read_only
, Qt
);
6948 specbind (Qinhibit_modification_hooks
, Qt
);
6950 if (clear_buffer_p
&& Z
> BEG
)
6953 xassert (BEGV
>= BEG
);
6954 xassert (ZV
<= Z
&& ZV
>= BEGV
);
6956 rc
= fn (a1
, a2
, a3
, a4
);
6958 xassert (BEGV
>= BEG
);
6959 xassert (ZV
<= Z
&& ZV
>= BEGV
);
6961 unbind_to (count
, Qnil
);
6966 /* Save state that should be preserved around the call to the function
6967 FN called in with_echo_area_buffer. */
6970 with_echo_area_buffer_unwind_data (w
)
6976 /* Reduce consing by keeping one vector in
6977 Vwith_echo_area_save_vector. */
6978 vector
= Vwith_echo_area_save_vector
;
6979 Vwith_echo_area_save_vector
= Qnil
;
6982 vector
= Fmake_vector (make_number (7), Qnil
);
6984 XSETBUFFER (AREF (vector
, i
), current_buffer
); ++i
;
6985 AREF (vector
, i
) = Vdeactivate_mark
, ++i
;
6986 AREF (vector
, i
) = make_number (windows_or_buffers_changed
), ++i
;
6990 XSETWINDOW (AREF (vector
, i
), w
); ++i
;
6991 AREF (vector
, i
) = w
->buffer
; ++i
;
6992 AREF (vector
, i
) = make_number (XMARKER (w
->pointm
)->charpos
); ++i
;
6993 AREF (vector
, i
) = make_number (XMARKER (w
->pointm
)->bytepos
); ++i
;
6998 for (; i
< end
; ++i
)
6999 AREF (vector
, i
) = Qnil
;
7002 xassert (i
== ASIZE (vector
));
7007 /* Restore global state from VECTOR which was created by
7008 with_echo_area_buffer_unwind_data. */
7011 unwind_with_echo_area_buffer (vector
)
7014 set_buffer_internal_1 (XBUFFER (AREF (vector
, 0)));
7015 Vdeactivate_mark
= AREF (vector
, 1);
7016 windows_or_buffers_changed
= XFASTINT (AREF (vector
, 2));
7018 if (WINDOWP (AREF (vector
, 3)))
7021 Lisp_Object buffer
, charpos
, bytepos
;
7023 w
= XWINDOW (AREF (vector
, 3));
7024 buffer
= AREF (vector
, 4);
7025 charpos
= AREF (vector
, 5);
7026 bytepos
= AREF (vector
, 6);
7029 set_marker_both (w
->pointm
, buffer
,
7030 XFASTINT (charpos
), XFASTINT (bytepos
));
7033 Vwith_echo_area_save_vector
= vector
;
7038 /* Set up the echo area for use by print functions. MULTIBYTE_P
7039 non-zero means we will print multibyte. */
7042 setup_echo_area_for_printing (multibyte_p
)
7045 /* If we can't find an echo area any more, exit. */
7046 if (! FRAME_LIVE_P (XFRAME (selected_frame
)))
7049 ensure_echo_area_buffers ();
7051 if (!message_buf_print
)
7053 /* A message has been output since the last time we printed.
7054 Choose a fresh echo area buffer. */
7055 if (EQ (echo_area_buffer
[1], echo_buffer
[0]))
7056 echo_area_buffer
[0] = echo_buffer
[1];
7058 echo_area_buffer
[0] = echo_buffer
[0];
7060 /* Switch to that buffer and clear it. */
7061 set_buffer_internal (XBUFFER (echo_area_buffer
[0]));
7062 current_buffer
->truncate_lines
= Qnil
;
7066 int count
= SPECPDL_INDEX ();
7067 specbind (Qinhibit_read_only
, Qt
);
7068 /* Note that undo recording is always disabled. */
7070 unbind_to (count
, Qnil
);
7072 TEMP_SET_PT_BOTH (BEG
, BEG_BYTE
);
7074 /* Set up the buffer for the multibyteness we need. */
7076 != !NILP (current_buffer
->enable_multibyte_characters
))
7077 Fset_buffer_multibyte (multibyte_p
? Qt
: Qnil
);
7079 /* Raise the frame containing the echo area. */
7080 if (minibuffer_auto_raise
)
7082 struct frame
*sf
= SELECTED_FRAME ();
7083 Lisp_Object mini_window
;
7084 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
7085 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window
)));
7088 message_log_maybe_newline ();
7089 message_buf_print
= 1;
7093 if (NILP (echo_area_buffer
[0]))
7095 if (EQ (echo_area_buffer
[1], echo_buffer
[0]))
7096 echo_area_buffer
[0] = echo_buffer
[1];
7098 echo_area_buffer
[0] = echo_buffer
[0];
7101 if (current_buffer
!= XBUFFER (echo_area_buffer
[0]))
7103 /* Someone switched buffers between print requests. */
7104 set_buffer_internal (XBUFFER (echo_area_buffer
[0]));
7105 current_buffer
->truncate_lines
= Qnil
;
7111 /* Display an echo area message in window W. Value is non-zero if W's
7112 height is changed. If display_last_displayed_message_p is
7113 non-zero, display the message that was last displayed, otherwise
7114 display the current message. */
7117 display_echo_area (w
)
7120 int i
, no_message_p
, window_height_changed_p
, count
;
7122 /* Temporarily disable garbage collections while displaying the echo
7123 area. This is done because a GC can print a message itself.
7124 That message would modify the echo area buffer's contents while a
7125 redisplay of the buffer is going on, and seriously confuse
7127 count
= inhibit_garbage_collection ();
7129 /* If there is no message, we must call display_echo_area_1
7130 nevertheless because it resizes the window. But we will have to
7131 reset the echo_area_buffer in question to nil at the end because
7132 with_echo_area_buffer will sets it to an empty buffer. */
7133 i
= display_last_displayed_message_p
? 1 : 0;
7134 no_message_p
= NILP (echo_area_buffer
[i
]);
7136 window_height_changed_p
7137 = with_echo_area_buffer (w
, display_last_displayed_message_p
,
7138 display_echo_area_1
,
7139 (EMACS_INT
) w
, Qnil
, 0, 0);
7142 echo_area_buffer
[i
] = Qnil
;
7144 unbind_to (count
, Qnil
);
7145 return window_height_changed_p
;
7149 /* Helper for display_echo_area. Display the current buffer which
7150 contains the current echo area message in window W, a mini-window,
7151 a pointer to which is passed in A1. A2..A4 are currently not used.
7152 Change the height of W so that all of the message is displayed.
7153 Value is non-zero if height of W was changed. */
7156 display_echo_area_1 (a1
, a2
, a3
, a4
)
7161 struct window
*w
= (struct window
*) a1
;
7163 struct text_pos start
;
7164 int window_height_changed_p
= 0;
7166 /* Do this before displaying, so that we have a large enough glyph
7167 matrix for the display. */
7168 window_height_changed_p
= resize_mini_window (w
, 0);
7171 clear_glyph_matrix (w
->desired_matrix
);
7172 XSETWINDOW (window
, w
);
7173 SET_TEXT_POS (start
, BEG
, BEG_BYTE
);
7174 try_window (window
, start
);
7176 return window_height_changed_p
;
7180 /* Resize the echo area window to exactly the size needed for the
7181 currently displayed message, if there is one. If a mini-buffer
7182 is active, don't shrink it. */
7185 resize_echo_area_exactly ()
7187 if (BUFFERP (echo_area_buffer
[0])
7188 && WINDOWP (echo_area_window
))
7190 struct window
*w
= XWINDOW (echo_area_window
);
7192 Lisp_Object resize_exactly
;
7194 if (minibuf_level
== 0)
7195 resize_exactly
= Qt
;
7197 resize_exactly
= Qnil
;
7199 resized_p
= with_echo_area_buffer (w
, 0, resize_mini_window_1
,
7200 (EMACS_INT
) w
, resize_exactly
, 0, 0);
7203 ++windows_or_buffers_changed
;
7204 ++update_mode_lines
;
7205 redisplay_internal (0);
7211 /* Callback function for with_echo_area_buffer, when used from
7212 resize_echo_area_exactly. A1 contains a pointer to the window to
7213 resize, EXACTLY non-nil means resize the mini-window exactly to the
7214 size of the text displayed. A3 and A4 are not used. Value is what
7215 resize_mini_window returns. */
7218 resize_mini_window_1 (a1
, exactly
, a3
, a4
)
7220 Lisp_Object exactly
;
7223 return resize_mini_window ((struct window
*) a1
, !NILP (exactly
));
7227 /* Resize mini-window W to fit the size of its contents. EXACT:P
7228 means size the window exactly to the size needed. Otherwise, it's
7229 only enlarged until W's buffer is empty. Value is non-zero if
7230 the window height has been changed. */
7233 resize_mini_window (w
, exact_p
)
7237 struct frame
*f
= XFRAME (w
->frame
);
7238 int window_height_changed_p
= 0;
7240 xassert (MINI_WINDOW_P (w
));
7242 /* Don't resize windows while redisplaying a window; it would
7243 confuse redisplay functions when the size of the window they are
7244 displaying changes from under them. Such a resizing can happen,
7245 for instance, when which-func prints a long message while
7246 we are running fontification-functions. We're running these
7247 functions with safe_call which binds inhibit-redisplay to t. */
7248 if (!NILP (Vinhibit_redisplay
))
7251 /* Nil means don't try to resize. */
7252 if (NILP (Vresize_mini_windows
)
7253 || (FRAME_X_P (f
) && FRAME_X_OUTPUT (f
) == NULL
))
7256 if (!FRAME_MINIBUF_ONLY_P (f
))
7259 struct window
*root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
7260 int total_height
= WINDOW_TOTAL_LINES (root
) + WINDOW_TOTAL_LINES (w
);
7261 int height
, max_height
;
7262 int unit
= FRAME_LINE_HEIGHT (f
);
7263 struct text_pos start
;
7264 struct buffer
*old_current_buffer
= NULL
;
7266 if (current_buffer
!= XBUFFER (w
->buffer
))
7268 old_current_buffer
= current_buffer
;
7269 set_buffer_internal (XBUFFER (w
->buffer
));
7272 init_iterator (&it
, w
, BEGV
, BEGV_BYTE
, NULL
, DEFAULT_FACE_ID
);
7274 /* Compute the max. number of lines specified by the user. */
7275 if (FLOATP (Vmax_mini_window_height
))
7276 max_height
= XFLOATINT (Vmax_mini_window_height
) * FRAME_LINES (f
);
7277 else if (INTEGERP (Vmax_mini_window_height
))
7278 max_height
= XINT (Vmax_mini_window_height
);
7280 max_height
= total_height
/ 4;
7282 /* Correct that max. height if it's bogus. */
7283 max_height
= max (1, max_height
);
7284 max_height
= min (total_height
, max_height
);
7286 /* Find out the height of the text in the window. */
7287 if (it
.truncate_lines_p
)
7292 move_it_to (&it
, ZV
, -1, -1, -1, MOVE_TO_POS
);
7293 if (it
.max_ascent
== 0 && it
.max_descent
== 0)
7294 height
= it
.current_y
+ last_height
;
7296 height
= it
.current_y
+ it
.max_ascent
+ it
.max_descent
;
7297 height
-= it
.extra_line_spacing
;
7298 height
= (height
+ unit
- 1) / unit
;
7301 /* Compute a suitable window start. */
7302 if (height
> max_height
)
7304 height
= max_height
;
7305 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
7306 move_it_vertically_backward (&it
, (height
- 1) * unit
);
7307 start
= it
.current
.pos
;
7310 SET_TEXT_POS (start
, BEGV
, BEGV_BYTE
);
7311 SET_MARKER_FROM_TEXT_POS (w
->start
, start
);
7313 if (EQ (Vresize_mini_windows
, Qgrow_only
))
7315 /* Let it grow only, until we display an empty message, in which
7316 case the window shrinks again. */
7317 if (height
> WINDOW_TOTAL_LINES (w
))
7319 int old_height
= WINDOW_TOTAL_LINES (w
);
7320 freeze_window_starts (f
, 1);
7321 grow_mini_window (w
, height
- WINDOW_TOTAL_LINES (w
));
7322 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
7324 else if (height
< WINDOW_TOTAL_LINES (w
)
7325 && (exact_p
|| BEGV
== ZV
))
7327 int old_height
= WINDOW_TOTAL_LINES (w
);
7328 freeze_window_starts (f
, 0);
7329 shrink_mini_window (w
);
7330 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
7335 /* Always resize to exact size needed. */
7336 if (height
> WINDOW_TOTAL_LINES (w
))
7338 int old_height
= WINDOW_TOTAL_LINES (w
);
7339 freeze_window_starts (f
, 1);
7340 grow_mini_window (w
, height
- WINDOW_TOTAL_LINES (w
));
7341 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
7343 else if (height
< WINDOW_TOTAL_LINES (w
))
7345 int old_height
= WINDOW_TOTAL_LINES (w
);
7346 freeze_window_starts (f
, 0);
7347 shrink_mini_window (w
);
7351 freeze_window_starts (f
, 1);
7352 grow_mini_window (w
, height
- WINDOW_TOTAL_LINES (w
));
7355 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
7359 if (old_current_buffer
)
7360 set_buffer_internal (old_current_buffer
);
7363 return window_height_changed_p
;
7367 /* Value is the current message, a string, or nil if there is no
7375 if (NILP (echo_area_buffer
[0]))
7379 with_echo_area_buffer (0, 0, current_message_1
,
7380 (EMACS_INT
) &msg
, Qnil
, 0, 0);
7382 echo_area_buffer
[0] = Qnil
;
7390 current_message_1 (a1
, a2
, a3
, a4
)
7395 Lisp_Object
*msg
= (Lisp_Object
*) a1
;
7398 *msg
= make_buffer_string (BEG
, Z
, 1);
7405 /* Push the current message on Vmessage_stack for later restauration
7406 by restore_message. Value is non-zero if the current message isn't
7407 empty. This is a relatively infrequent operation, so it's not
7408 worth optimizing. */
7414 msg
= current_message ();
7415 Vmessage_stack
= Fcons (msg
, Vmessage_stack
);
7416 return STRINGP (msg
);
7420 /* Restore message display from the top of Vmessage_stack. */
7427 xassert (CONSP (Vmessage_stack
));
7428 msg
= XCAR (Vmessage_stack
);
7430 message3_nolog (msg
, SBYTES (msg
), STRING_MULTIBYTE (msg
));
7432 message3_nolog (msg
, 0, 0);
7436 /* Handler for record_unwind_protect calling pop_message. */
7439 pop_message_unwind (dummy
)
7446 /* Pop the top-most entry off Vmessage_stack. */
7451 xassert (CONSP (Vmessage_stack
));
7452 Vmessage_stack
= XCDR (Vmessage_stack
);
7456 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
7457 exits. If the stack is not empty, we have a missing pop_message
7461 check_message_stack ()
7463 if (!NILP (Vmessage_stack
))
7468 /* Truncate to NCHARS what will be displayed in the echo area the next
7469 time we display it---but don't redisplay it now. */
7472 truncate_echo_area (nchars
)
7476 echo_area_buffer
[0] = Qnil
;
7477 /* A null message buffer means that the frame hasn't really been
7478 initialized yet. Error messages get reported properly by
7479 cmd_error, so this must be just an informative message; toss it. */
7480 else if (!noninteractive
7482 && !NILP (echo_area_buffer
[0]))
7484 struct frame
*sf
= SELECTED_FRAME ();
7485 if (FRAME_MESSAGE_BUF (sf
))
7486 with_echo_area_buffer (0, 0, truncate_message_1
, nchars
, Qnil
, 0, 0);
7491 /* Helper function for truncate_echo_area. Truncate the current
7492 message to at most NCHARS characters. */
7495 truncate_message_1 (nchars
, a2
, a3
, a4
)
7500 if (BEG
+ nchars
< Z
)
7501 del_range (BEG
+ nchars
, Z
);
7503 echo_area_buffer
[0] = Qnil
;
7508 /* Set the current message to a substring of S or STRING.
7510 If STRING is a Lisp string, set the message to the first NBYTES
7511 bytes from STRING. NBYTES zero means use the whole string. If
7512 STRING is multibyte, the message will be displayed multibyte.
7514 If S is not null, set the message to the first LEN bytes of S. LEN
7515 zero means use the whole string. MULTIBYTE_P non-zero means S is
7516 multibyte. Display the message multibyte in that case. */
7519 set_message (s
, string
, nbytes
, multibyte_p
)
7522 int nbytes
, multibyte_p
;
7524 message_enable_multibyte
7525 = ((s
&& multibyte_p
)
7526 || (STRINGP (string
) && STRING_MULTIBYTE (string
)));
7528 with_echo_area_buffer (0, -1, set_message_1
,
7529 (EMACS_INT
) s
, string
, nbytes
, multibyte_p
);
7530 message_buf_print
= 0;
7531 help_echo_showing_p
= 0;
7535 /* Helper function for set_message. Arguments have the same meaning
7536 as there, with A1 corresponding to S and A2 corresponding to STRING
7537 This function is called with the echo area buffer being
7541 set_message_1 (a1
, a2
, nbytes
, multibyte_p
)
7544 EMACS_INT nbytes
, multibyte_p
;
7546 const char *s
= (const char *) a1
;
7547 Lisp_Object string
= a2
;
7551 /* Change multibyteness of the echo buffer appropriately. */
7552 if (message_enable_multibyte
7553 != !NILP (current_buffer
->enable_multibyte_characters
))
7554 Fset_buffer_multibyte (message_enable_multibyte
? Qt
: Qnil
);
7556 current_buffer
->truncate_lines
= message_truncate_lines
? Qt
: Qnil
;
7558 /* Insert new message at BEG. */
7559 TEMP_SET_PT_BOTH (BEG
, BEG_BYTE
);
7561 if (STRINGP (string
))
7566 nbytes
= SBYTES (string
);
7567 nchars
= string_byte_to_char (string
, nbytes
);
7569 /* This function takes care of single/multibyte conversion. We
7570 just have to ensure that the echo area buffer has the right
7571 setting of enable_multibyte_characters. */
7572 insert_from_string (string
, 0, 0, nchars
, nbytes
, 1);
7577 nbytes
= strlen (s
);
7579 if (multibyte_p
&& NILP (current_buffer
->enable_multibyte_characters
))
7581 /* Convert from multi-byte to single-byte. */
7583 unsigned char work
[1];
7585 /* Convert a multibyte string to single-byte. */
7586 for (i
= 0; i
< nbytes
; i
+= n
)
7588 c
= string_char_and_length (s
+ i
, nbytes
- i
, &n
);
7589 work
[0] = (SINGLE_BYTE_CHAR_P (c
)
7591 : multibyte_char_to_unibyte (c
, Qnil
));
7592 insert_1_both (work
, 1, 1, 1, 0, 0);
7595 else if (!multibyte_p
7596 && !NILP (current_buffer
->enable_multibyte_characters
))
7598 /* Convert from single-byte to multi-byte. */
7600 const unsigned char *msg
= (const unsigned char *) s
;
7601 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
7603 /* Convert a single-byte string to multibyte. */
7604 for (i
= 0; i
< nbytes
; i
++)
7606 c
= unibyte_char_to_multibyte (msg
[i
]);
7607 n
= CHAR_STRING (c
, str
);
7608 insert_1_both (str
, 1, n
, 1, 0, 0);
7612 insert_1 (s
, nbytes
, 1, 0, 0);
7619 /* Clear messages. CURRENT_P non-zero means clear the current
7620 message. LAST_DISPLAYED_P non-zero means clear the message
7624 clear_message (current_p
, last_displayed_p
)
7625 int current_p
, last_displayed_p
;
7629 echo_area_buffer
[0] = Qnil
;
7630 message_cleared_p
= 1;
7633 if (last_displayed_p
)
7634 echo_area_buffer
[1] = Qnil
;
7636 message_buf_print
= 0;
7639 /* Clear garbaged frames.
7641 This function is used where the old redisplay called
7642 redraw_garbaged_frames which in turn called redraw_frame which in
7643 turn called clear_frame. The call to clear_frame was a source of
7644 flickering. I believe a clear_frame is not necessary. It should
7645 suffice in the new redisplay to invalidate all current matrices,
7646 and ensure a complete redisplay of all windows. */
7649 clear_garbaged_frames ()
7653 Lisp_Object tail
, frame
;
7654 int changed_count
= 0;
7656 FOR_EACH_FRAME (tail
, frame
)
7658 struct frame
*f
= XFRAME (frame
);
7660 if (FRAME_VISIBLE_P (f
) && FRAME_GARBAGED_P (f
))
7664 Fredraw_frame (frame
);
7665 f
->force_flush_display_p
= 1;
7667 clear_current_matrices (f
);
7676 ++windows_or_buffers_changed
;
7681 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
7682 is non-zero update selected_frame. Value is non-zero if the
7683 mini-windows height has been changed. */
7686 echo_area_display (update_frame_p
)
7689 Lisp_Object mini_window
;
7692 int window_height_changed_p
= 0;
7693 struct frame
*sf
= SELECTED_FRAME ();
7695 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
7696 w
= XWINDOW (mini_window
);
7697 f
= XFRAME (WINDOW_FRAME (w
));
7699 /* Don't display if frame is invisible or not yet initialized. */
7700 if (!FRAME_VISIBLE_P (f
) || !f
->glyphs_initialized_p
)
7703 /* The terminal frame is used as the first Emacs frame on the Mac OS. */
7705 #ifdef HAVE_WINDOW_SYSTEM
7706 /* When Emacs starts, selected_frame may be the initial terminal
7707 frame. If we let this through, a message would be displayed on
7709 if (FRAME_TERMCAP_P (XFRAME (selected_frame
))
7710 && FRAME_TTY (XFRAME (selected_frame
))->type
== NULL
)
7712 #endif /* HAVE_WINDOW_SYSTEM */
7715 /* Redraw garbaged frames. */
7717 clear_garbaged_frames ();
7719 if (!NILP (echo_area_buffer
[0]) || minibuf_level
== 0)
7721 echo_area_window
= mini_window
;
7722 window_height_changed_p
= display_echo_area (w
);
7723 w
->must_be_updated_p
= 1;
7725 /* Update the display, unless called from redisplay_internal.
7726 Also don't update the screen during redisplay itself. The
7727 update will happen at the end of redisplay, and an update
7728 here could cause confusion. */
7729 if (update_frame_p
&& !redisplaying_p
)
7733 /* If the display update has been interrupted by pending
7734 input, update mode lines in the frame. Due to the
7735 pending input, it might have been that redisplay hasn't
7736 been called, so that mode lines above the echo area are
7737 garbaged. This looks odd, so we prevent it here. */
7738 if (!display_completed
)
7739 n
= redisplay_mode_lines (FRAME_ROOT_WINDOW (f
), 0);
7741 if (window_height_changed_p
7742 /* Don't do this if Emacs is shutting down. Redisplay
7743 needs to run hooks. */
7744 && !NILP (Vrun_hooks
))
7746 /* Must update other windows. Likewise as in other
7747 cases, don't let this update be interrupted by
7749 int count
= SPECPDL_INDEX ();
7750 specbind (Qredisplay_dont_pause
, Qt
);
7751 windows_or_buffers_changed
= 1;
7752 redisplay_internal (0);
7753 unbind_to (count
, Qnil
);
7755 else if (FRAME_WINDOW_P (f
) && n
== 0)
7757 /* Window configuration is the same as before.
7758 Can do with a display update of the echo area,
7759 unless we displayed some mode lines. */
7760 update_single_window (w
, 1);
7761 FRAME_RIF (f
)->flush_display (f
);
7764 update_frame (f
, 1, 1);
7766 /* If cursor is in the echo area, make sure that the next
7767 redisplay displays the minibuffer, so that the cursor will
7768 be replaced with what the minibuffer wants. */
7769 if (cursor_in_echo_area
)
7770 ++windows_or_buffers_changed
;
7773 else if (!EQ (mini_window
, selected_window
))
7774 windows_or_buffers_changed
++;
7776 /* Last displayed message is now the current message. */
7777 echo_area_buffer
[1] = echo_area_buffer
[0];
7779 /* Prevent redisplay optimization in redisplay_internal by resetting
7780 this_line_start_pos. This is done because the mini-buffer now
7781 displays the message instead of its buffer text. */
7782 if (EQ (mini_window
, selected_window
))
7783 CHARPOS (this_line_start_pos
) = 0;
7785 return window_height_changed_p
;
7790 /***********************************************************************
7792 ***********************************************************************/
7795 /* The frame title buffering code is also used by Fformat_mode_line.
7796 So it is not conditioned by HAVE_WINDOW_SYSTEM. */
7798 /* A buffer for constructing frame titles in it; allocated from the
7799 heap in init_xdisp and resized as needed in store_frame_title_char. */
7801 static char *frame_title_buf
;
7803 /* The buffer's end, and a current output position in it. */
7805 static char *frame_title_buf_end
;
7806 static char *frame_title_ptr
;
7809 /* Store a single character C for the frame title in frame_title_buf.
7810 Re-allocate frame_title_buf if necessary. */
7814 store_frame_title_char (char c
)
7816 store_frame_title_char (c
)
7820 /* If output position has reached the end of the allocated buffer,
7821 double the buffer's size. */
7822 if (frame_title_ptr
== frame_title_buf_end
)
7824 int len
= frame_title_ptr
- frame_title_buf
;
7825 int new_size
= 2 * len
* sizeof *frame_title_buf
;
7826 frame_title_buf
= (char *) xrealloc (frame_title_buf
, new_size
);
7827 frame_title_buf_end
= frame_title_buf
+ new_size
;
7828 frame_title_ptr
= frame_title_buf
+ len
;
7831 *frame_title_ptr
++ = c
;
7835 /* Store part of a frame title in frame_title_buf, beginning at
7836 frame_title_ptr. STR is the string to store. Do not copy
7837 characters that yield more columns than PRECISION; PRECISION <= 0
7838 means copy the whole string. Pad with spaces until FIELD_WIDTH
7839 number of characters have been copied; FIELD_WIDTH <= 0 means don't
7840 pad. Called from display_mode_element when it is used to build a
7844 store_frame_title (str
, field_width
, precision
)
7845 const unsigned char *str
;
7846 int field_width
, precision
;
7851 /* Copy at most PRECISION chars from STR. */
7852 nbytes
= strlen (str
);
7853 n
+= c_string_width (str
, nbytes
, precision
, &dummy
, &nbytes
);
7855 store_frame_title_char (*str
++);
7857 /* Fill up with spaces until FIELD_WIDTH reached. */
7858 while (field_width
> 0
7861 store_frame_title_char (' ');
7868 #ifdef HAVE_WINDOW_SYSTEM
7870 /* Set the title of FRAME, if it has changed. The title format is
7871 Vicon_title_format if FRAME is iconified, otherwise it is
7872 frame_title_format. */
7875 x_consider_frame_title (frame
)
7878 struct frame
*f
= XFRAME (frame
);
7880 if (FRAME_WINDOW_P (f
)
7881 || FRAME_MINIBUF_ONLY_P (f
)
7882 || f
->explicit_name
)
7884 /* Do we have more than one visible frame on this X display? */
7887 struct buffer
*obuf
;
7891 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCDR (tail
))
7893 Lisp_Object other_frame
= XCAR (tail
);
7894 struct frame
*tf
= XFRAME (other_frame
);
7897 && FRAME_KBOARD (tf
) == FRAME_KBOARD (f
)
7898 && !FRAME_MINIBUF_ONLY_P (tf
)
7899 && !EQ (other_frame
, tip_frame
)
7900 && (FRAME_VISIBLE_P (tf
) || FRAME_ICONIFIED_P (tf
)))
7904 /* Set global variable indicating that multiple frames exist. */
7905 multiple_frames
= CONSP (tail
);
7907 /* Switch to the buffer of selected window of the frame. Set up
7908 frame_title_ptr so that display_mode_element will output into it;
7909 then display the title. */
7910 obuf
= current_buffer
;
7911 set_buffer_internal_1 (XBUFFER (XWINDOW (f
->selected_window
)->buffer
));
7912 fmt
= FRAME_ICONIFIED_P (f
) ? Vicon_title_format
: Vframe_title_format
;
7913 frame_title_ptr
= frame_title_buf
;
7914 init_iterator (&it
, XWINDOW (f
->selected_window
), -1, -1,
7915 NULL
, DEFAULT_FACE_ID
);
7916 display_mode_element (&it
, 0, -1, -1, fmt
, Qnil
, 0);
7917 len
= frame_title_ptr
- frame_title_buf
;
7918 frame_title_ptr
= NULL
;
7919 set_buffer_internal_1 (obuf
);
7921 /* Set the title only if it's changed. This avoids consing in
7922 the common case where it hasn't. (If it turns out that we've
7923 already wasted too much time by walking through the list with
7924 display_mode_element, then we might need to optimize at a
7925 higher level than this.) */
7926 if (! STRINGP (f
->name
)
7927 || SBYTES (f
->name
) != len
7928 || bcmp (frame_title_buf
, SDATA (f
->name
), len
) != 0)
7929 x_implicitly_set_name (f
, make_string (frame_title_buf
, len
), Qnil
);
7933 #endif /* not HAVE_WINDOW_SYSTEM */
7938 /***********************************************************************
7940 ***********************************************************************/
7943 /* Prepare for redisplay by updating menu-bar item lists when
7944 appropriate. This can call eval. */
7947 prepare_menu_bars ()
7950 struct gcpro gcpro1
, gcpro2
;
7952 Lisp_Object tooltip_frame
;
7954 #ifdef HAVE_WINDOW_SYSTEM
7955 tooltip_frame
= tip_frame
;
7957 tooltip_frame
= Qnil
;
7960 /* Update all frame titles based on their buffer names, etc. We do
7961 this before the menu bars so that the buffer-menu will show the
7962 up-to-date frame titles. */
7963 #ifdef HAVE_WINDOW_SYSTEM
7964 if (windows_or_buffers_changed
|| update_mode_lines
)
7966 Lisp_Object tail
, frame
;
7968 FOR_EACH_FRAME (tail
, frame
)
7971 if (!EQ (frame
, tooltip_frame
)
7972 && (FRAME_VISIBLE_P (f
) || FRAME_ICONIFIED_P (f
)))
7973 x_consider_frame_title (frame
);
7976 #endif /* HAVE_WINDOW_SYSTEM */
7978 /* Update the menu bar item lists, if appropriate. This has to be
7979 done before any actual redisplay or generation of display lines. */
7980 all_windows
= (update_mode_lines
7981 || buffer_shared
> 1
7982 || windows_or_buffers_changed
);
7985 Lisp_Object tail
, frame
;
7986 int count
= SPECPDL_INDEX ();
7988 record_unwind_protect (Fset_match_data
, Fmatch_data (Qnil
, Qnil
));
7990 FOR_EACH_FRAME (tail
, frame
)
7994 /* Ignore tooltip frame. */
7995 if (EQ (frame
, tooltip_frame
))
7998 /* If a window on this frame changed size, report that to
7999 the user and clear the size-change flag. */
8000 if (FRAME_WINDOW_SIZES_CHANGED (f
))
8002 Lisp_Object functions
;
8004 /* Clear flag first in case we get an error below. */
8005 FRAME_WINDOW_SIZES_CHANGED (f
) = 0;
8006 functions
= Vwindow_size_change_functions
;
8007 GCPRO2 (tail
, functions
);
8009 while (CONSP (functions
))
8011 call1 (XCAR (functions
), frame
);
8012 functions
= XCDR (functions
);
8018 update_menu_bar (f
, 0);
8019 #ifdef HAVE_WINDOW_SYSTEM
8020 update_tool_bar (f
, 0);
8025 unbind_to (count
, Qnil
);
8029 struct frame
*sf
= SELECTED_FRAME ();
8030 update_menu_bar (sf
, 1);
8031 #ifdef HAVE_WINDOW_SYSTEM
8032 update_tool_bar (sf
, 1);
8036 /* Motif needs this. See comment in xmenu.c. Turn it off when
8037 pending_menu_activation is not defined. */
8038 #ifdef USE_X_TOOLKIT
8039 pending_menu_activation
= 0;
8044 /* Update the menu bar item list for frame F. This has to be done
8045 before we start to fill in any display lines, because it can call
8048 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
8051 update_menu_bar (f
, save_match_data
)
8053 int save_match_data
;
8056 register struct window
*w
;
8058 /* If called recursively during a menu update, do nothing. This can
8059 happen when, for instance, an activate-menubar-hook causes a
8061 if (inhibit_menubar_update
)
8064 window
= FRAME_SELECTED_WINDOW (f
);
8065 w
= XWINDOW (window
);
8067 #if 0 /* The if statement below this if statement used to include the
8068 condition !NILP (w->update_mode_line), rather than using
8069 update_mode_lines directly, and this if statement may have
8070 been added to make that condition work. Now the if
8071 statement below matches its comment, this isn't needed. */
8072 if (update_mode_lines
)
8073 w
->update_mode_line
= Qt
;
8076 if (FRAME_WINDOW_P (f
)
8078 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8079 || defined (USE_GTK)
8080 FRAME_EXTERNAL_MENU_BAR (f
)
8082 FRAME_MENU_BAR_LINES (f
) > 0
8084 : FRAME_MENU_BAR_LINES (f
) > 0)
8086 /* If the user has switched buffers or windows, we need to
8087 recompute to reflect the new bindings. But we'll
8088 recompute when update_mode_lines is set too; that means
8089 that people can use force-mode-line-update to request
8090 that the menu bar be recomputed. The adverse effect on
8091 the rest of the redisplay algorithm is about the same as
8092 windows_or_buffers_changed anyway. */
8093 if (windows_or_buffers_changed
8094 /* This used to test w->update_mode_line, but we believe
8095 there is no need to recompute the menu in that case. */
8096 || update_mode_lines
8097 || ((BUF_SAVE_MODIFF (XBUFFER (w
->buffer
))
8098 < BUF_MODIFF (XBUFFER (w
->buffer
)))
8099 != !NILP (w
->last_had_star
))
8100 || ((!NILP (Vtransient_mark_mode
)
8101 && !NILP (XBUFFER (w
->buffer
)->mark_active
))
8102 != !NILP (w
->region_showing
)))
8104 struct buffer
*prev
= current_buffer
;
8105 int count
= SPECPDL_INDEX ();
8107 specbind (Qinhibit_menubar_update
, Qt
);
8109 set_buffer_internal_1 (XBUFFER (w
->buffer
));
8110 if (save_match_data
)
8111 record_unwind_protect (Fset_match_data
, Fmatch_data (Qnil
, Qnil
));
8112 if (NILP (Voverriding_local_map_menu_flag
))
8114 specbind (Qoverriding_terminal_local_map
, Qnil
);
8115 specbind (Qoverriding_local_map
, Qnil
);
8118 /* Run the Lucid hook. */
8119 safe_run_hooks (Qactivate_menubar_hook
);
8121 /* If it has changed current-menubar from previous value,
8122 really recompute the menu-bar from the value. */
8123 if (! NILP (Vlucid_menu_bar_dirty_flag
))
8124 call0 (Qrecompute_lucid_menubar
);
8126 safe_run_hooks (Qmenu_bar_update_hook
);
8127 FRAME_MENU_BAR_ITEMS (f
) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f
));
8129 /* Redisplay the menu bar in case we changed it. */
8130 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8131 || defined (USE_GTK)
8132 if (FRAME_WINDOW_P (f
)
8133 #if defined (MAC_OS)
8134 /* All frames on Mac OS share the same menubar. So only the
8135 selected frame should be allowed to set it. */
8136 && f
== SELECTED_FRAME ()
8139 set_frame_menubar (f
, 0, 0);
8141 /* On a terminal screen, the menu bar is an ordinary screen
8142 line, and this makes it get updated. */
8143 w
->update_mode_line
= Qt
;
8144 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8145 /* In the non-toolkit version, the menu bar is an ordinary screen
8146 line, and this makes it get updated. */
8147 w
->update_mode_line
= Qt
;
8148 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8150 unbind_to (count
, Qnil
);
8151 set_buffer_internal_1 (prev
);
8158 /***********************************************************************
8160 ***********************************************************************/
8162 #ifdef HAVE_WINDOW_SYSTEM
8165 Nominal cursor position -- where to draw output.
8166 HPOS and VPOS are window relative glyph matrix coordinates.
8167 X and Y are window relative pixel coordinates. */
8169 struct cursor_pos output_cursor
;
8173 Set the global variable output_cursor to CURSOR. All cursor
8174 positions are relative to updated_window. */
8177 set_output_cursor (cursor
)
8178 struct cursor_pos
*cursor
;
8180 output_cursor
.hpos
= cursor
->hpos
;
8181 output_cursor
.vpos
= cursor
->vpos
;
8182 output_cursor
.x
= cursor
->x
;
8183 output_cursor
.y
= cursor
->y
;
8188 Set a nominal cursor position.
8190 HPOS and VPOS are column/row positions in a window glyph matrix. X
8191 and Y are window text area relative pixel positions.
8193 If this is done during an update, updated_window will contain the
8194 window that is being updated and the position is the future output
8195 cursor position for that window. If updated_window is null, use
8196 selected_window and display the cursor at the given position. */
8199 x_cursor_to (vpos
, hpos
, y
, x
)
8200 int vpos
, hpos
, y
, x
;
8204 /* If updated_window is not set, work on selected_window. */
8208 w
= XWINDOW (selected_window
);
8210 /* Set the output cursor. */
8211 output_cursor
.hpos
= hpos
;
8212 output_cursor
.vpos
= vpos
;
8213 output_cursor
.x
= x
;
8214 output_cursor
.y
= y
;
8216 /* If not called as part of an update, really display the cursor.
8217 This will also set the cursor position of W. */
8218 if (updated_window
== NULL
)
8221 display_and_set_cursor (w
, 1, hpos
, vpos
, x
, y
);
8222 if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional
)
8223 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
8228 #endif /* HAVE_WINDOW_SYSTEM */
8231 /***********************************************************************
8233 ***********************************************************************/
8235 #ifdef HAVE_WINDOW_SYSTEM
8237 /* Where the mouse was last time we reported a mouse event. */
8239 FRAME_PTR last_mouse_frame
;
8241 /* Tool-bar item index of the item on which a mouse button was pressed
8244 int last_tool_bar_item
;
8247 /* Update the tool-bar item list for frame F. This has to be done
8248 before we start to fill in any display lines. Called from
8249 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
8250 and restore it here. */
8253 update_tool_bar (f
, save_match_data
)
8255 int save_match_data
;
8258 int do_update
= FRAME_EXTERNAL_TOOL_BAR (f
);
8260 int do_update
= WINDOWP (f
->tool_bar_window
)
8261 && WINDOW_TOTAL_LINES (XWINDOW (f
->tool_bar_window
)) > 0;
8269 window
= FRAME_SELECTED_WINDOW (f
);
8270 w
= XWINDOW (window
);
8272 /* If the user has switched buffers or windows, we need to
8273 recompute to reflect the new bindings. But we'll
8274 recompute when update_mode_lines is set too; that means
8275 that people can use force-mode-line-update to request
8276 that the menu bar be recomputed. The adverse effect on
8277 the rest of the redisplay algorithm is about the same as
8278 windows_or_buffers_changed anyway. */
8279 if (windows_or_buffers_changed
8280 || !NILP (w
->update_mode_line
)
8281 || update_mode_lines
8282 || ((BUF_SAVE_MODIFF (XBUFFER (w
->buffer
))
8283 < BUF_MODIFF (XBUFFER (w
->buffer
)))
8284 != !NILP (w
->last_had_star
))
8285 || ((!NILP (Vtransient_mark_mode
)
8286 && !NILP (XBUFFER (w
->buffer
)->mark_active
))
8287 != !NILP (w
->region_showing
)))
8289 struct buffer
*prev
= current_buffer
;
8290 int count
= SPECPDL_INDEX ();
8291 Lisp_Object old_tool_bar
;
8292 struct gcpro gcpro1
;
8294 /* Set current_buffer to the buffer of the selected
8295 window of the frame, so that we get the right local
8297 set_buffer_internal_1 (XBUFFER (w
->buffer
));
8299 /* Save match data, if we must. */
8300 if (save_match_data
)
8301 record_unwind_protect (Fset_match_data
, Fmatch_data (Qnil
, Qnil
));
8303 /* Make sure that we don't accidentally use bogus keymaps. */
8304 if (NILP (Voverriding_local_map_menu_flag
))
8306 specbind (Qoverriding_terminal_local_map
, Qnil
);
8307 specbind (Qoverriding_local_map
, Qnil
);
8310 old_tool_bar
= f
->tool_bar_items
;
8311 GCPRO1 (old_tool_bar
);
8313 /* Build desired tool-bar items from keymaps. */
8316 = tool_bar_items (f
->tool_bar_items
, &f
->n_tool_bar_items
);
8319 /* Redisplay the tool-bar if we changed it. */
8320 if (! NILP (Fequal (old_tool_bar
, f
->tool_bar_items
)))
8321 w
->update_mode_line
= Qt
;
8325 unbind_to (count
, Qnil
);
8326 set_buffer_internal_1 (prev
);
8332 /* Set F->desired_tool_bar_string to a Lisp string representing frame
8333 F's desired tool-bar contents. F->tool_bar_items must have
8334 been set up previously by calling prepare_menu_bars. */
8337 build_desired_tool_bar_string (f
)
8340 int i
, size
, size_needed
;
8341 struct gcpro gcpro1
, gcpro2
, gcpro3
;
8342 Lisp_Object image
, plist
, props
;
8344 image
= plist
= props
= Qnil
;
8345 GCPRO3 (image
, plist
, props
);
8347 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
8348 Otherwise, make a new string. */
8350 /* The size of the string we might be able to reuse. */
8351 size
= (STRINGP (f
->desired_tool_bar_string
)
8352 ? SCHARS (f
->desired_tool_bar_string
)
8355 /* We need one space in the string for each image. */
8356 size_needed
= f
->n_tool_bar_items
;
8358 /* Reuse f->desired_tool_bar_string, if possible. */
8359 if (size
< size_needed
|| NILP (f
->desired_tool_bar_string
))
8360 f
->desired_tool_bar_string
= Fmake_string (make_number (size_needed
),
8364 props
= list4 (Qdisplay
, Qnil
, Qmenu_item
, Qnil
);
8365 Fremove_text_properties (make_number (0), make_number (size
),
8366 props
, f
->desired_tool_bar_string
);
8369 /* Put a `display' property on the string for the images to display,
8370 put a `menu_item' property on tool-bar items with a value that
8371 is the index of the item in F's tool-bar item vector. */
8372 for (i
= 0; i
< f
->n_tool_bar_items
; ++i
)
8374 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
8376 int enabled_p
= !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P
));
8377 int selected_p
= !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P
));
8378 int hmargin
, vmargin
, relief
, idx
, end
;
8379 extern Lisp_Object QCrelief
, QCmargin
, QCconversion
;
8381 /* If image is a vector, choose the image according to the
8383 image
= PROP (TOOL_BAR_ITEM_IMAGES
);
8384 if (VECTORP (image
))
8388 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
8389 : TOOL_BAR_IMAGE_ENABLED_DESELECTED
);
8392 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
8393 : TOOL_BAR_IMAGE_DISABLED_DESELECTED
);
8395 xassert (ASIZE (image
) >= idx
);
8396 image
= AREF (image
, idx
);
8401 /* Ignore invalid image specifications. */
8402 if (!valid_image_p (image
))
8405 /* Display the tool-bar button pressed, or depressed. */
8406 plist
= Fcopy_sequence (XCDR (image
));
8408 /* Compute margin and relief to draw. */
8409 relief
= (tool_bar_button_relief
>= 0
8410 ? tool_bar_button_relief
8411 : DEFAULT_TOOL_BAR_BUTTON_RELIEF
);
8412 hmargin
= vmargin
= relief
;
8414 if (INTEGERP (Vtool_bar_button_margin
)
8415 && XINT (Vtool_bar_button_margin
) > 0)
8417 hmargin
+= XFASTINT (Vtool_bar_button_margin
);
8418 vmargin
+= XFASTINT (Vtool_bar_button_margin
);
8420 else if (CONSP (Vtool_bar_button_margin
))
8422 if (INTEGERP (XCAR (Vtool_bar_button_margin
))
8423 && XINT (XCAR (Vtool_bar_button_margin
)) > 0)
8424 hmargin
+= XFASTINT (XCAR (Vtool_bar_button_margin
));
8426 if (INTEGERP (XCDR (Vtool_bar_button_margin
))
8427 && XINT (XCDR (Vtool_bar_button_margin
)) > 0)
8428 vmargin
+= XFASTINT (XCDR (Vtool_bar_button_margin
));
8431 if (auto_raise_tool_bar_buttons_p
)
8433 /* Add a `:relief' property to the image spec if the item is
8437 plist
= Fplist_put (plist
, QCrelief
, make_number (-relief
));
8444 /* If image is selected, display it pressed, i.e. with a
8445 negative relief. If it's not selected, display it with a
8447 plist
= Fplist_put (plist
, QCrelief
,
8449 ? make_number (-relief
)
8450 : make_number (relief
)));
8455 /* Put a margin around the image. */
8456 if (hmargin
|| vmargin
)
8458 if (hmargin
== vmargin
)
8459 plist
= Fplist_put (plist
, QCmargin
, make_number (hmargin
));
8461 plist
= Fplist_put (plist
, QCmargin
,
8462 Fcons (make_number (hmargin
),
8463 make_number (vmargin
)));
8466 /* If button is not enabled, and we don't have special images
8467 for the disabled state, make the image appear disabled by
8468 applying an appropriate algorithm to it. */
8469 if (!enabled_p
&& idx
< 0)
8470 plist
= Fplist_put (plist
, QCconversion
, Qdisabled
);
8472 /* Put a `display' text property on the string for the image to
8473 display. Put a `menu-item' property on the string that gives
8474 the start of this item's properties in the tool-bar items
8476 image
= Fcons (Qimage
, plist
);
8477 props
= list4 (Qdisplay
, image
,
8478 Qmenu_item
, make_number (i
* TOOL_BAR_ITEM_NSLOTS
));
8480 /* Let the last image hide all remaining spaces in the tool bar
8481 string. The string can be longer than needed when we reuse a
8483 if (i
+ 1 == f
->n_tool_bar_items
)
8484 end
= SCHARS (f
->desired_tool_bar_string
);
8487 Fadd_text_properties (make_number (i
), make_number (end
),
8488 props
, f
->desired_tool_bar_string
);
8496 /* Display one line of the tool-bar of frame IT->f. */
8499 display_tool_bar_line (it
)
8502 struct glyph_row
*row
= it
->glyph_row
;
8503 int max_x
= it
->last_visible_x
;
8506 prepare_desired_row (row
);
8507 row
->y
= it
->current_y
;
8509 /* Note that this isn't made use of if the face hasn't a box,
8510 so there's no need to check the face here. */
8511 it
->start_of_box_run_p
= 1;
8513 while (it
->current_x
< max_x
)
8515 int x_before
, x
, n_glyphs_before
, i
, nglyphs
;
8517 /* Get the next display element. */
8518 if (!get_next_display_element (it
))
8521 /* Produce glyphs. */
8522 x_before
= it
->current_x
;
8523 n_glyphs_before
= it
->glyph_row
->used
[TEXT_AREA
];
8524 PRODUCE_GLYPHS (it
);
8526 nglyphs
= it
->glyph_row
->used
[TEXT_AREA
] - n_glyphs_before
;
8531 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
8533 if (x
+ glyph
->pixel_width
> max_x
)
8535 /* Glyph doesn't fit on line. */
8536 it
->glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
+ i
;
8542 x
+= glyph
->pixel_width
;
8546 /* Stop at line ends. */
8547 if (ITERATOR_AT_END_OF_LINE_P (it
))
8550 set_iterator_to_next (it
, 1);
8555 row
->displays_text_p
= row
->used
[TEXT_AREA
] != 0;
8556 extend_face_to_end_of_line (it
);
8557 last
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
] - 1;
8558 last
->right_box_line_p
= 1;
8559 if (last
== row
->glyphs
[TEXT_AREA
])
8560 last
->left_box_line_p
= 1;
8561 compute_line_metrics (it
);
8563 /* If line is empty, make it occupy the rest of the tool-bar. */
8564 if (!row
->displays_text_p
)
8566 row
->height
= row
->phys_height
= it
->last_visible_y
- row
->y
;
8567 row
->ascent
= row
->phys_ascent
= 0;
8570 row
->full_width_p
= 1;
8571 row
->continued_p
= 0;
8572 row
->truncated_on_left_p
= 0;
8573 row
->truncated_on_right_p
= 0;
8575 it
->current_x
= it
->hpos
= 0;
8576 it
->current_y
+= row
->height
;
8582 /* Value is the number of screen lines needed to make all tool-bar
8583 items of frame F visible. */
8586 tool_bar_lines_needed (f
)
8589 struct window
*w
= XWINDOW (f
->tool_bar_window
);
8592 /* Initialize an iterator for iteration over
8593 F->desired_tool_bar_string in the tool-bar window of frame F. */
8594 init_iterator (&it
, w
, -1, -1, w
->desired_matrix
->rows
, TOOL_BAR_FACE_ID
);
8595 it
.first_visible_x
= 0;
8596 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
8597 reseat_to_string (&it
, NULL
, f
->desired_tool_bar_string
, 0, 0, 0, -1);
8599 while (!ITERATOR_AT_END_P (&it
))
8601 it
.glyph_row
= w
->desired_matrix
->rows
;
8602 clear_glyph_row (it
.glyph_row
);
8603 display_tool_bar_line (&it
);
8606 return (it
.current_y
+ FRAME_LINE_HEIGHT (f
) - 1) / FRAME_LINE_HEIGHT (f
);
8610 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed
, Stool_bar_lines_needed
,
8612 doc
: /* Return the number of lines occupied by the tool bar of FRAME. */)
8621 frame
= selected_frame
;
8623 CHECK_FRAME (frame
);
8626 if (WINDOWP (f
->tool_bar_window
)
8627 || (w
= XWINDOW (f
->tool_bar_window
),
8628 WINDOW_TOTAL_LINES (w
) > 0))
8630 update_tool_bar (f
, 1);
8631 if (f
->n_tool_bar_items
)
8633 build_desired_tool_bar_string (f
);
8634 nlines
= tool_bar_lines_needed (f
);
8638 return make_number (nlines
);
8642 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
8643 height should be changed. */
8646 redisplay_tool_bar (f
)
8651 struct glyph_row
*row
;
8652 int change_height_p
= 0;
8655 if (FRAME_EXTERNAL_TOOL_BAR (f
))
8656 update_frame_tool_bar (f
);
8660 /* If frame hasn't a tool-bar window or if it is zero-height, don't
8661 do anything. This means you must start with tool-bar-lines
8662 non-zero to get the auto-sizing effect. Or in other words, you
8663 can turn off tool-bars by specifying tool-bar-lines zero. */
8664 if (!WINDOWP (f
->tool_bar_window
)
8665 || (w
= XWINDOW (f
->tool_bar_window
),
8666 WINDOW_TOTAL_LINES (w
) == 0))
8669 /* Set up an iterator for the tool-bar window. */
8670 init_iterator (&it
, w
, -1, -1, w
->desired_matrix
->rows
, TOOL_BAR_FACE_ID
);
8671 it
.first_visible_x
= 0;
8672 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
8675 /* Build a string that represents the contents of the tool-bar. */
8676 build_desired_tool_bar_string (f
);
8677 reseat_to_string (&it
, NULL
, f
->desired_tool_bar_string
, 0, 0, 0, -1);
8679 /* Display as many lines as needed to display all tool-bar items. */
8680 while (it
.current_y
< it
.last_visible_y
)
8681 display_tool_bar_line (&it
);
8683 /* It doesn't make much sense to try scrolling in the tool-bar
8684 window, so don't do it. */
8685 w
->desired_matrix
->no_scrolling_p
= 1;
8686 w
->must_be_updated_p
= 1;
8688 if (auto_resize_tool_bars_p
)
8692 /* If we couldn't display everything, change the tool-bar's
8694 if (IT_STRING_CHARPOS (it
) < it
.end_charpos
)
8695 change_height_p
= 1;
8697 /* If there are blank lines at the end, except for a partially
8698 visible blank line at the end that is smaller than
8699 FRAME_LINE_HEIGHT, change the tool-bar's height. */
8700 row
= it
.glyph_row
- 1;
8701 if (!row
->displays_text_p
8702 && row
->height
>= FRAME_LINE_HEIGHT (f
))
8703 change_height_p
= 1;
8705 /* If row displays tool-bar items, but is partially visible,
8706 change the tool-bar's height. */
8707 if (row
->displays_text_p
8708 && MATRIX_ROW_BOTTOM_Y (row
) > it
.last_visible_y
)
8709 change_height_p
= 1;
8711 /* Resize windows as needed by changing the `tool-bar-lines'
8714 && (nlines
= tool_bar_lines_needed (f
),
8715 nlines
!= WINDOW_TOTAL_LINES (w
)))
8717 extern Lisp_Object Qtool_bar_lines
;
8719 int old_height
= WINDOW_TOTAL_LINES (w
);
8721 XSETFRAME (frame
, f
);
8722 clear_glyph_matrix (w
->desired_matrix
);
8723 Fmodify_frame_parameters (frame
,
8724 Fcons (Fcons (Qtool_bar_lines
,
8725 make_number (nlines
)),
8727 if (WINDOW_TOTAL_LINES (w
) != old_height
)
8728 fonts_changed_p
= 1;
8732 return change_height_p
;
8736 /* Get information about the tool-bar item which is displayed in GLYPH
8737 on frame F. Return in *PROP_IDX the index where tool-bar item
8738 properties start in F->tool_bar_items. Value is zero if
8739 GLYPH doesn't display a tool-bar item. */
8742 tool_bar_item_info (f
, glyph
, prop_idx
)
8744 struct glyph
*glyph
;
8751 /* This function can be called asynchronously, which means we must
8752 exclude any possibility that Fget_text_property signals an
8754 charpos
= min (SCHARS (f
->current_tool_bar_string
), glyph
->charpos
);
8755 charpos
= max (0, charpos
);
8757 /* Get the text property `menu-item' at pos. The value of that
8758 property is the start index of this item's properties in
8759 F->tool_bar_items. */
8760 prop
= Fget_text_property (make_number (charpos
),
8761 Qmenu_item
, f
->current_tool_bar_string
);
8762 if (INTEGERP (prop
))
8764 *prop_idx
= XINT (prop
);
8774 /* Get information about the tool-bar item at position X/Y on frame F.
8775 Return in *GLYPH a pointer to the glyph of the tool-bar item in
8776 the current matrix of the tool-bar window of F, or NULL if not
8777 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
8778 item in F->tool_bar_items. Value is
8780 -1 if X/Y is not on a tool-bar item
8781 0 if X/Y is on the same item that was highlighted before.
8785 get_tool_bar_item (f
, x
, y
, glyph
, hpos
, vpos
, prop_idx
)
8788 struct glyph
**glyph
;
8789 int *hpos
, *vpos
, *prop_idx
;
8791 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
8792 struct window
*w
= XWINDOW (f
->tool_bar_window
);
8795 /* Find the glyph under X/Y. */
8796 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, 0, 0, &area
);
8800 /* Get the start of this tool-bar item's properties in
8801 f->tool_bar_items. */
8802 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
8805 /* Is mouse on the highlighted item? */
8806 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
8807 && *vpos
>= dpyinfo
->mouse_face_beg_row
8808 && *vpos
<= dpyinfo
->mouse_face_end_row
8809 && (*vpos
> dpyinfo
->mouse_face_beg_row
8810 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
8811 && (*vpos
< dpyinfo
->mouse_face_end_row
8812 || *hpos
< dpyinfo
->mouse_face_end_col
8813 || dpyinfo
->mouse_face_past_end
))
8821 Handle mouse button event on the tool-bar of frame F, at
8822 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
8823 0 for button release. MODIFIERS is event modifiers for button
8827 handle_tool_bar_click (f
, x
, y
, down_p
, modifiers
)
8830 unsigned int modifiers
;
8832 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
8833 struct window
*w
= XWINDOW (f
->tool_bar_window
);
8834 int hpos
, vpos
, prop_idx
;
8835 struct glyph
*glyph
;
8836 Lisp_Object enabled_p
;
8838 /* If not on the highlighted tool-bar item, return. */
8839 frame_to_window_pixel_xy (w
, &x
, &y
);
8840 if (get_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
8843 /* If item is disabled, do nothing. */
8844 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
8845 if (NILP (enabled_p
))
8850 /* Show item in pressed state. */
8851 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
8852 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
8853 last_tool_bar_item
= prop_idx
;
8857 Lisp_Object key
, frame
;
8858 struct input_event event
;
8861 /* Show item in released state. */
8862 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
8863 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
8865 key
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_KEY
);
8867 XSETFRAME (frame
, f
);
8868 event
.kind
= TOOL_BAR_EVENT
;
8869 event
.frame_or_window
= frame
;
8871 kbd_buffer_store_event (&event
);
8873 event
.kind
= TOOL_BAR_EVENT
;
8874 event
.frame_or_window
= frame
;
8876 event
.modifiers
= modifiers
;
8877 kbd_buffer_store_event (&event
);
8878 last_tool_bar_item
= -1;
8883 /* Possibly highlight a tool-bar item on frame F when mouse moves to
8884 tool-bar window-relative coordinates X/Y. Called from
8885 note_mouse_highlight. */
8888 note_tool_bar_highlight (f
, x
, y
)
8892 Lisp_Object window
= f
->tool_bar_window
;
8893 struct window
*w
= XWINDOW (window
);
8894 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
8896 struct glyph
*glyph
;
8897 struct glyph_row
*row
;
8899 Lisp_Object enabled_p
;
8901 enum draw_glyphs_face draw
= DRAW_IMAGE_RAISED
;
8902 int mouse_down_p
, rc
;
8904 /* Function note_mouse_highlight is called with negative x(y
8905 values when mouse moves outside of the frame. */
8906 if (x
<= 0 || y
<= 0)
8908 clear_mouse_face (dpyinfo
);
8912 rc
= get_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
8915 /* Not on tool-bar item. */
8916 clear_mouse_face (dpyinfo
);
8920 /* On same tool-bar item as before. */
8923 clear_mouse_face (dpyinfo
);
8925 /* Mouse is down, but on different tool-bar item? */
8926 mouse_down_p
= (dpyinfo
->grabbed
8927 && f
== last_mouse_frame
8928 && FRAME_LIVE_P (f
));
8930 && last_tool_bar_item
!= prop_idx
)
8933 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
8934 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
8936 /* If tool-bar item is not enabled, don't highlight it. */
8937 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
8938 if (!NILP (enabled_p
))
8940 /* Compute the x-position of the glyph. In front and past the
8941 image is a space. We include this in the highlighted area. */
8942 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
8943 for (i
= x
= 0; i
< hpos
; ++i
)
8944 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
8946 /* Record this as the current active region. */
8947 dpyinfo
->mouse_face_beg_col
= hpos
;
8948 dpyinfo
->mouse_face_beg_row
= vpos
;
8949 dpyinfo
->mouse_face_beg_x
= x
;
8950 dpyinfo
->mouse_face_beg_y
= row
->y
;
8951 dpyinfo
->mouse_face_past_end
= 0;
8953 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
8954 dpyinfo
->mouse_face_end_row
= vpos
;
8955 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
8956 dpyinfo
->mouse_face_end_y
= row
->y
;
8957 dpyinfo
->mouse_face_window
= window
;
8958 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
8960 /* Display it as active. */
8961 show_mouse_face (dpyinfo
, draw
);
8962 dpyinfo
->mouse_face_image_state
= draw
;
8967 /* Set help_echo_string to a help string to display for this tool-bar item.
8968 XTread_socket does the rest. */
8969 help_echo_object
= help_echo_window
= Qnil
;
8971 help_echo_string
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_HELP
);
8972 if (NILP (help_echo_string
))
8973 help_echo_string
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_CAPTION
);
8976 #endif /* HAVE_WINDOW_SYSTEM */
8980 /************************************************************************
8981 Horizontal scrolling
8982 ************************************************************************/
8984 static int hscroll_window_tree
P_ ((Lisp_Object
));
8985 static int hscroll_windows
P_ ((Lisp_Object
));
8987 /* For all leaf windows in the window tree rooted at WINDOW, set their
8988 hscroll value so that PT is (i) visible in the window, and (ii) so
8989 that it is not within a certain margin at the window's left and
8990 right border. Value is non-zero if any window's hscroll has been
8994 hscroll_window_tree (window
)
8997 int hscrolled_p
= 0;
8998 int hscroll_relative_p
= FLOATP (Vhscroll_step
);
8999 int hscroll_step_abs
= 0;
9000 double hscroll_step_rel
= 0;
9002 if (hscroll_relative_p
)
9004 hscroll_step_rel
= XFLOAT_DATA (Vhscroll_step
);
9005 if (hscroll_step_rel
< 0)
9007 hscroll_relative_p
= 0;
9008 hscroll_step_abs
= 0;
9011 else if (INTEGERP (Vhscroll_step
))
9013 hscroll_step_abs
= XINT (Vhscroll_step
);
9014 if (hscroll_step_abs
< 0)
9015 hscroll_step_abs
= 0;
9018 hscroll_step_abs
= 0;
9020 while (WINDOWP (window
))
9022 struct window
*w
= XWINDOW (window
);
9024 if (WINDOWP (w
->hchild
))
9025 hscrolled_p
|= hscroll_window_tree (w
->hchild
);
9026 else if (WINDOWP (w
->vchild
))
9027 hscrolled_p
|= hscroll_window_tree (w
->vchild
);
9028 else if (w
->cursor
.vpos
>= 0)
9031 int text_area_width
;
9032 struct glyph_row
*current_cursor_row
9033 = MATRIX_ROW (w
->current_matrix
, w
->cursor
.vpos
);
9034 struct glyph_row
*desired_cursor_row
9035 = MATRIX_ROW (w
->desired_matrix
, w
->cursor
.vpos
);
9036 struct glyph_row
*cursor_row
9037 = (desired_cursor_row
->enabled_p
9038 ? desired_cursor_row
9039 : current_cursor_row
);
9041 text_area_width
= window_box_width (w
, TEXT_AREA
);
9043 /* Scroll when cursor is inside this scroll margin. */
9044 h_margin
= hscroll_margin
* WINDOW_FRAME_COLUMN_WIDTH (w
);
9046 if ((XFASTINT (w
->hscroll
)
9047 && w
->cursor
.x
<= h_margin
)
9048 || (cursor_row
->enabled_p
9049 && cursor_row
->truncated_on_right_p
9050 && (w
->cursor
.x
>= text_area_width
- h_margin
)))
9054 struct buffer
*saved_current_buffer
;
9058 /* Find point in a display of infinite width. */
9059 saved_current_buffer
= current_buffer
;
9060 current_buffer
= XBUFFER (w
->buffer
);
9062 if (w
== XWINDOW (selected_window
))
9063 pt
= BUF_PT (current_buffer
);
9066 pt
= marker_position (w
->pointm
);
9067 pt
= max (BEGV
, pt
);
9071 /* Move iterator to pt starting at cursor_row->start in
9072 a line with infinite width. */
9073 init_to_row_start (&it
, w
, cursor_row
);
9074 it
.last_visible_x
= INFINITY
;
9075 move_it_in_display_line_to (&it
, pt
, -1, MOVE_TO_POS
);
9076 current_buffer
= saved_current_buffer
;
9078 /* Position cursor in window. */
9079 if (!hscroll_relative_p
&& hscroll_step_abs
== 0)
9080 hscroll
= max (0, (it
.current_x
9081 - (ITERATOR_AT_END_OF_LINE_P (&it
)
9082 ? (text_area_width
- 4 * FRAME_COLUMN_WIDTH (it
.f
))
9083 : (text_area_width
/ 2))))
9084 / FRAME_COLUMN_WIDTH (it
.f
);
9085 else if (w
->cursor
.x
>= text_area_width
- h_margin
)
9087 if (hscroll_relative_p
)
9088 wanted_x
= text_area_width
* (1 - hscroll_step_rel
)
9091 wanted_x
= text_area_width
9092 - hscroll_step_abs
* FRAME_COLUMN_WIDTH (it
.f
)
9095 = max (0, it
.current_x
- wanted_x
) / FRAME_COLUMN_WIDTH (it
.f
);
9099 if (hscroll_relative_p
)
9100 wanted_x
= text_area_width
* hscroll_step_rel
9103 wanted_x
= hscroll_step_abs
* FRAME_COLUMN_WIDTH (it
.f
)
9106 = max (0, it
.current_x
- wanted_x
) / FRAME_COLUMN_WIDTH (it
.f
);
9108 hscroll
= max (hscroll
, XFASTINT (w
->min_hscroll
));
9110 /* Don't call Fset_window_hscroll if value hasn't
9111 changed because it will prevent redisplay
9113 if (XFASTINT (w
->hscroll
) != hscroll
)
9115 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
9116 w
->hscroll
= make_number (hscroll
);
9125 /* Value is non-zero if hscroll of any leaf window has been changed. */
9130 /* Set hscroll so that cursor is visible and not inside horizontal
9131 scroll margins for all windows in the tree rooted at WINDOW. See
9132 also hscroll_window_tree above. Value is non-zero if any window's
9133 hscroll has been changed. If it has, desired matrices on the frame
9134 of WINDOW are cleared. */
9137 hscroll_windows (window
)
9142 if (automatic_hscrolling_p
)
9144 hscrolled_p
= hscroll_window_tree (window
);
9146 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window
))));
9155 /************************************************************************
9157 ************************************************************************/
9159 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
9160 to a non-zero value. This is sometimes handy to have in a debugger
9165 /* First and last unchanged row for try_window_id. */
9167 int debug_first_unchanged_at_end_vpos
;
9168 int debug_last_unchanged_at_beg_vpos
;
9170 /* Delta vpos and y. */
9172 int debug_dvpos
, debug_dy
;
9174 /* Delta in characters and bytes for try_window_id. */
9176 int debug_delta
, debug_delta_bytes
;
9178 /* Values of window_end_pos and window_end_vpos at the end of
9181 EMACS_INT debug_end_pos
, debug_end_vpos
;
9183 /* Append a string to W->desired_matrix->method. FMT is a printf
9184 format string. A1...A9 are a supplement for a variable-length
9185 argument list. If trace_redisplay_p is non-zero also printf the
9186 resulting string to stderr. */
9189 debug_method_add (w
, fmt
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
)
9192 int a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
;
9195 char *method
= w
->desired_matrix
->method
;
9196 int len
= strlen (method
);
9197 int size
= sizeof w
->desired_matrix
->method
;
9198 int remaining
= size
- len
- 1;
9200 sprintf (buffer
, fmt
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
);
9201 if (len
&& remaining
)
9207 strncpy (method
+ len
, buffer
, remaining
);
9209 if (trace_redisplay_p
)
9210 fprintf (stderr
, "%p (%s): %s\n",
9212 ((BUFFERP (w
->buffer
)
9213 && STRINGP (XBUFFER (w
->buffer
)->name
))
9214 ? (char *) SDATA (XBUFFER (w
->buffer
)->name
)
9219 #endif /* GLYPH_DEBUG */
9222 /* Value is non-zero if all changes in window W, which displays
9223 current_buffer, are in the text between START and END. START is a
9224 buffer position, END is given as a distance from Z. Used in
9225 redisplay_internal for display optimization. */
9228 text_outside_line_unchanged_p (w
, start
, end
)
9232 int unchanged_p
= 1;
9234 /* If text or overlays have changed, see where. */
9235 if (XFASTINT (w
->last_modified
) < MODIFF
9236 || XFASTINT (w
->last_overlay_modified
) < OVERLAY_MODIFF
)
9238 /* Gap in the line? */
9239 if (GPT
< start
|| Z
- GPT
< end
)
9242 /* Changes start in front of the line, or end after it? */
9244 && (BEG_UNCHANGED
< start
- 1
9245 || END_UNCHANGED
< end
))
9248 /* If selective display, can't optimize if changes start at the
9249 beginning of the line. */
9251 && INTEGERP (current_buffer
->selective_display
)
9252 && XINT (current_buffer
->selective_display
) > 0
9253 && (BEG_UNCHANGED
< start
|| GPT
<= start
))
9256 /* If there are overlays at the start or end of the line, these
9257 may have overlay strings with newlines in them. A change at
9258 START, for instance, may actually concern the display of such
9259 overlay strings as well, and they are displayed on different
9260 lines. So, quickly rule out this case. (For the future, it
9261 might be desirable to implement something more telling than
9262 just BEG/END_UNCHANGED.) */
9265 if (BEG
+ BEG_UNCHANGED
== start
9266 && overlay_touches_p (start
))
9268 if (END_UNCHANGED
== end
9269 && overlay_touches_p (Z
- end
))
9278 /* Do a frame update, taking possible shortcuts into account. This is
9279 the main external entry point for redisplay.
9281 If the last redisplay displayed an echo area message and that message
9282 is no longer requested, we clear the echo area or bring back the
9283 mini-buffer if that is in use. */
9288 redisplay_internal (0);
9292 /* Return 1 if point moved out of or into a composition. Otherwise
9293 return 0. PREV_BUF and PREV_PT are the last point buffer and
9294 position. BUF and PT are the current point buffer and position. */
9297 check_point_in_composition (prev_buf
, prev_pt
, buf
, pt
)
9298 struct buffer
*prev_buf
, *buf
;
9305 XSETBUFFER (buffer
, buf
);
9306 /* Check a composition at the last point if point moved within the
9308 if (prev_buf
== buf
)
9311 /* Point didn't move. */
9314 if (prev_pt
> BUF_BEGV (buf
) && prev_pt
< BUF_ZV (buf
)
9315 && find_composition (prev_pt
, -1, &start
, &end
, &prop
, buffer
)
9316 && COMPOSITION_VALID_P (start
, end
, prop
)
9317 && start
< prev_pt
&& end
> prev_pt
)
9318 /* The last point was within the composition. Return 1 iff
9319 point moved out of the composition. */
9320 return (pt
<= start
|| pt
>= end
);
9323 /* Check a composition at the current point. */
9324 return (pt
> BUF_BEGV (buf
) && pt
< BUF_ZV (buf
)
9325 && find_composition (pt
, -1, &start
, &end
, &prop
, buffer
)
9326 && COMPOSITION_VALID_P (start
, end
, prop
)
9327 && start
< pt
&& end
> pt
);
9331 /* Reconsider the setting of B->clip_changed which is displayed
9335 reconsider_clip_changes (w
, b
)
9340 && !NILP (w
->window_end_valid
)
9341 && w
->current_matrix
->buffer
== b
9342 && w
->current_matrix
->zv
== BUF_ZV (b
)
9343 && w
->current_matrix
->begv
== BUF_BEGV (b
))
9344 b
->clip_changed
= 0;
9346 /* If display wasn't paused, and W is not a tool bar window, see if
9347 point has been moved into or out of a composition. In that case,
9348 we set b->clip_changed to 1 to force updating the screen. If
9349 b->clip_changed has already been set to 1, we can skip this
9351 if (!b
->clip_changed
9352 && BUFFERP (w
->buffer
) && !NILP (w
->window_end_valid
))
9356 if (w
== XWINDOW (selected_window
))
9357 pt
= BUF_PT (current_buffer
);
9359 pt
= marker_position (w
->pointm
);
9361 if ((w
->current_matrix
->buffer
!= XBUFFER (w
->buffer
)
9362 || pt
!= XINT (w
->last_point
))
9363 && check_point_in_composition (w
->current_matrix
->buffer
,
9364 XINT (w
->last_point
),
9365 XBUFFER (w
->buffer
), pt
))
9366 b
->clip_changed
= 1;
9371 /* Select FRAME to forward the values of frame-local variables into C
9372 variables so that the redisplay routines can access those values
9376 select_frame_for_redisplay (frame
)
9379 Lisp_Object tail
, sym
, val
;
9380 Lisp_Object old
= selected_frame
;
9382 selected_frame
= frame
;
9384 for (tail
= XFRAME (frame
)->param_alist
; CONSP (tail
); tail
= XCDR (tail
))
9385 if (CONSP (XCAR (tail
))
9386 && (sym
= XCAR (XCAR (tail
)),
9388 && (sym
= indirect_variable (sym
),
9389 val
= SYMBOL_VALUE (sym
),
9390 (BUFFER_LOCAL_VALUEP (val
)
9391 || SOME_BUFFER_LOCAL_VALUEP (val
)))
9392 && XBUFFER_LOCAL_VALUE (val
)->check_frame
)
9393 Fsymbol_value (sym
);
9395 for (tail
= XFRAME (old
)->param_alist
; CONSP (tail
); tail
= XCDR (tail
))
9396 if (CONSP (XCAR (tail
))
9397 && (sym
= XCAR (XCAR (tail
)),
9399 && (sym
= indirect_variable (sym
),
9400 val
= SYMBOL_VALUE (sym
),
9401 (BUFFER_LOCAL_VALUEP (val
)
9402 || SOME_BUFFER_LOCAL_VALUEP (val
)))
9403 && XBUFFER_LOCAL_VALUE (val
)->check_frame
)
9404 Fsymbol_value (sym
);
9408 #define STOP_POLLING \
9409 do { if (! polling_stopped_here) stop_polling (); \
9410 polling_stopped_here = 1; } while (0)
9412 #define RESUME_POLLING \
9413 do { if (polling_stopped_here) start_polling (); \
9414 polling_stopped_here = 0; } while (0)
9417 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
9418 response to any user action; therefore, we should preserve the echo
9419 area. (Actually, our caller does that job.) Perhaps in the future
9420 avoid recentering windows if it is not necessary; currently that
9421 causes some problems. */
9424 redisplay_internal (preserve_echo_area
)
9425 int preserve_echo_area
;
9427 struct window
*w
= XWINDOW (selected_window
);
9428 struct frame
*f
= XFRAME (w
->frame
);
9430 int must_finish
= 0;
9431 struct text_pos tlbufpos
, tlendpos
;
9432 int number_of_visible_frames
;
9434 struct frame
*sf
= SELECTED_FRAME ();
9435 int polling_stopped_here
= 0;
9437 /* Non-zero means redisplay has to consider all windows on all
9438 frames. Zero means, only selected_window is considered. */
9439 int consider_all_windows_p
;
9441 TRACE ((stderr
, "redisplay_internal %d\n", redisplaying_p
));
9443 /* No redisplay if running in batch mode or frame is not yet fully
9444 initialized, or redisplay is explicitly turned off by setting
9445 Vinhibit_redisplay. */
9447 || !NILP (Vinhibit_redisplay
)
9448 || !f
->glyphs_initialized_p
)
9451 /* The flag redisplay_performed_directly_p is set by
9452 direct_output_for_insert when it already did the whole screen
9453 update necessary. */
9454 if (redisplay_performed_directly_p
)
9456 redisplay_performed_directly_p
= 0;
9457 if (!hscroll_windows (selected_window
))
9461 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
9462 if (popup_activated ())
9466 /* I don't think this happens but let's be paranoid. */
9470 /* Record a function that resets redisplaying_p to its old value
9471 when we leave this function. */
9472 count
= SPECPDL_INDEX ();
9473 record_unwind_protect (unwind_redisplay
,
9474 Fcons (make_number (redisplaying_p
), selected_frame
));
9476 specbind (Qinhibit_free_realized_faces
, Qnil
);
9480 reconsider_clip_changes (w
, current_buffer
);
9482 /* If new fonts have been loaded that make a glyph matrix adjustment
9483 necessary, do it. */
9484 if (fonts_changed_p
)
9486 adjust_glyphs (NULL
);
9487 ++windows_or_buffers_changed
;
9488 fonts_changed_p
= 0;
9491 /* If face_change_count is non-zero, init_iterator will free all
9492 realized faces, which includes the faces referenced from current
9493 matrices. So, we can't reuse current matrices in this case. */
9494 if (face_change_count
)
9495 ++windows_or_buffers_changed
;
9497 if (FRAME_TERMCAP_P (sf
)
9498 && FRAME_TTY (sf
)->previous_terminal_frame
!= sf
)
9500 /* Since frames on a single ASCII terminal share the same
9501 display area, displaying a different frame means redisplay
9503 windows_or_buffers_changed
++;
9504 SET_FRAME_GARBAGED (sf
);
9505 FRAME_TTY (sf
)->previous_terminal_frame
= sf
;
9508 /* Set the visible flags for all frames. Do this before checking
9509 for resized or garbaged frames; they want to know if their frames
9510 are visible. See the comment in frame.h for
9511 FRAME_SAMPLE_VISIBILITY. */
9513 Lisp_Object tail
, frame
;
9515 number_of_visible_frames
= 0;
9517 FOR_EACH_FRAME (tail
, frame
)
9519 struct frame
*f
= XFRAME (frame
);
9521 FRAME_SAMPLE_VISIBILITY (f
);
9522 if (FRAME_VISIBLE_P (f
))
9523 ++number_of_visible_frames
;
9524 clear_desired_matrices (f
);
9529 /* Notice any pending interrupt request to change frame size. */
9530 do_pending_window_change (1);
9532 /* Clear frames marked as garbaged. */
9534 clear_garbaged_frames ();
9536 /* Build menubar and tool-bar items. */
9537 prepare_menu_bars ();
9539 if (windows_or_buffers_changed
)
9540 update_mode_lines
++;
9542 /* Detect case that we need to write or remove a star in the mode line. */
9543 if ((SAVE_MODIFF
< MODIFF
) != !NILP (w
->last_had_star
))
9545 w
->update_mode_line
= Qt
;
9546 if (buffer_shared
> 1)
9547 update_mode_lines
++;
9550 /* If %c is in the mode line, update it if needed. */
9551 if (!NILP (w
->column_number_displayed
)
9552 /* This alternative quickly identifies a common case
9553 where no change is needed. */
9554 && !(PT
== XFASTINT (w
->last_point
)
9555 && XFASTINT (w
->last_modified
) >= MODIFF
9556 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
)
9557 && (XFASTINT (w
->column_number_displayed
)
9558 != (int) current_column ())) /* iftc */
9559 w
->update_mode_line
= Qt
;
9561 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w
->frame
)) = -1;
9563 /* The variable buffer_shared is set in redisplay_window and
9564 indicates that we redisplay a buffer in different windows. See
9566 consider_all_windows_p
= (update_mode_lines
|| buffer_shared
> 1
9567 || cursor_type_changed
);
9569 /* If specs for an arrow have changed, do thorough redisplay
9570 to ensure we remove any arrow that should no longer exist. */
9571 if (! EQ (COERCE_MARKER (Voverlay_arrow_position
), last_arrow_position
)
9572 || ! EQ (Voverlay_arrow_string
, last_arrow_string
))
9573 consider_all_windows_p
= windows_or_buffers_changed
= 1;
9575 /* Normally the message* functions will have already displayed and
9576 updated the echo area, but the frame may have been trashed, or
9577 the update may have been preempted, so display the echo area
9578 again here. Checking message_cleared_p captures the case that
9579 the echo area should be cleared. */
9580 if ((!NILP (echo_area_buffer
[0]) && !display_last_displayed_message_p
)
9581 || (!NILP (echo_area_buffer
[1]) && display_last_displayed_message_p
)
9582 || (message_cleared_p
9583 && minibuf_level
== 0
9584 /* If the mini-window is currently selected, this means the
9585 echo-area doesn't show through. */
9586 && !MINI_WINDOW_P (XWINDOW (selected_window
))))
9588 int window_height_changed_p
= echo_area_display (0);
9591 /* If we don't display the current message, don't clear the
9592 message_cleared_p flag, because, if we did, we wouldn't clear
9593 the echo area in the next redisplay which doesn't preserve
9595 if (!display_last_displayed_message_p
)
9596 message_cleared_p
= 0;
9598 if (fonts_changed_p
)
9600 else if (window_height_changed_p
)
9602 consider_all_windows_p
= 1;
9603 ++update_mode_lines
;
9604 ++windows_or_buffers_changed
;
9606 /* If window configuration was changed, frames may have been
9607 marked garbaged. Clear them or we will experience
9608 surprises wrt scrolling. */
9610 clear_garbaged_frames ();
9613 else if (EQ (selected_window
, minibuf_window
)
9614 && (current_buffer
->clip_changed
9615 || XFASTINT (w
->last_modified
) < MODIFF
9616 || XFASTINT (w
->last_overlay_modified
) < OVERLAY_MODIFF
)
9617 && resize_mini_window (w
, 0))
9619 /* Resized active mini-window to fit the size of what it is
9620 showing if its contents might have changed. */
9622 consider_all_windows_p
= 1;
9623 ++windows_or_buffers_changed
;
9624 ++update_mode_lines
;
9626 /* If window configuration was changed, frames may have been
9627 marked garbaged. Clear them or we will experience
9628 surprises wrt scrolling. */
9630 clear_garbaged_frames ();
9634 /* If showing the region, and mark has changed, we must redisplay
9635 the whole window. The assignment to this_line_start_pos prevents
9636 the optimization directly below this if-statement. */
9637 if (((!NILP (Vtransient_mark_mode
)
9638 && !NILP (XBUFFER (w
->buffer
)->mark_active
))
9639 != !NILP (w
->region_showing
))
9640 || (!NILP (w
->region_showing
)
9641 && !EQ (w
->region_showing
,
9642 Fmarker_position (XBUFFER (w
->buffer
)->mark
))))
9643 CHARPOS (this_line_start_pos
) = 0;
9645 /* Optimize the case that only the line containing the cursor in the
9646 selected window has changed. Variables starting with this_ are
9647 set in display_line and record information about the line
9648 containing the cursor. */
9649 tlbufpos
= this_line_start_pos
;
9650 tlendpos
= this_line_end_pos
;
9651 if (!consider_all_windows_p
9652 && CHARPOS (tlbufpos
) > 0
9653 && NILP (w
->update_mode_line
)
9654 && !current_buffer
->clip_changed
9655 && !current_buffer
->prevent_redisplay_optimizations_p
9656 && FRAME_VISIBLE_P (XFRAME (w
->frame
))
9657 && !FRAME_OBSCURED_P (XFRAME (w
->frame
))
9658 /* Make sure recorded data applies to current buffer, etc. */
9659 && this_line_buffer
== current_buffer
9660 && current_buffer
== XBUFFER (w
->buffer
)
9661 && NILP (w
->force_start
)
9662 && NILP (w
->optional_new_start
)
9663 /* Point must be on the line that we have info recorded about. */
9664 && PT
>= CHARPOS (tlbufpos
)
9665 && PT
<= Z
- CHARPOS (tlendpos
)
9666 /* All text outside that line, including its final newline,
9667 must be unchanged */
9668 && text_outside_line_unchanged_p (w
, CHARPOS (tlbufpos
),
9669 CHARPOS (tlendpos
)))
9671 if (CHARPOS (tlbufpos
) > BEGV
9672 && FETCH_BYTE (BYTEPOS (tlbufpos
) - 1) != '\n'
9673 && (CHARPOS (tlbufpos
) == ZV
9674 || FETCH_BYTE (BYTEPOS (tlbufpos
)) == '\n'))
9675 /* Former continuation line has disappeared by becoming empty */
9677 else if (XFASTINT (w
->last_modified
) < MODIFF
9678 || XFASTINT (w
->last_overlay_modified
) < OVERLAY_MODIFF
9679 || MINI_WINDOW_P (w
))
9681 /* We have to handle the case of continuation around a
9682 wide-column character (See the comment in indent.c around
9685 For instance, in the following case:
9687 -------- Insert --------
9688 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
9689 J_I_ ==> J_I_ `^^' are cursors.
9693 As we have to redraw the line above, we should goto cancel. */
9696 int line_height_before
= this_line_pixel_height
;
9698 /* Note that start_display will handle the case that the
9699 line starting at tlbufpos is a continuation lines. */
9700 start_display (&it
, w
, tlbufpos
);
9702 /* Implementation note: It this still necessary? */
9703 if (it
.current_x
!= this_line_start_x
)
9706 TRACE ((stderr
, "trying display optimization 1\n"));
9707 w
->cursor
.vpos
= -1;
9708 overlay_arrow_seen
= 0;
9709 it
.vpos
= this_line_vpos
;
9710 it
.current_y
= this_line_y
;
9711 it
.glyph_row
= MATRIX_ROW (w
->desired_matrix
, this_line_vpos
);
9714 /* If line contains point, is not continued,
9715 and ends at same distance from eob as before, we win */
9716 if (w
->cursor
.vpos
>= 0
9717 /* Line is not continued, otherwise this_line_start_pos
9718 would have been set to 0 in display_line. */
9719 && CHARPOS (this_line_start_pos
)
9720 /* Line ends as before. */
9721 && CHARPOS (this_line_end_pos
) == CHARPOS (tlendpos
)
9722 /* Line has same height as before. Otherwise other lines
9723 would have to be shifted up or down. */
9724 && this_line_pixel_height
== line_height_before
)
9726 /* If this is not the window's last line, we must adjust
9727 the charstarts of the lines below. */
9728 if (it
.current_y
< it
.last_visible_y
)
9730 struct glyph_row
*row
9731 = MATRIX_ROW (w
->current_matrix
, this_line_vpos
+ 1);
9732 int delta
, delta_bytes
;
9734 if (Z
- CHARPOS (tlendpos
) == ZV
)
9736 /* This line ends at end of (accessible part of)
9737 buffer. There is no newline to count. */
9739 - CHARPOS (tlendpos
)
9740 - MATRIX_ROW_START_CHARPOS (row
));
9741 delta_bytes
= (Z_BYTE
9742 - BYTEPOS (tlendpos
)
9743 - MATRIX_ROW_START_BYTEPOS (row
));
9747 /* This line ends in a newline. Must take
9748 account of the newline and the rest of the
9749 text that follows. */
9751 - CHARPOS (tlendpos
)
9752 - MATRIX_ROW_START_CHARPOS (row
));
9753 delta_bytes
= (Z_BYTE
9754 - BYTEPOS (tlendpos
)
9755 - MATRIX_ROW_START_BYTEPOS (row
));
9758 increment_matrix_positions (w
->current_matrix
,
9760 w
->current_matrix
->nrows
,
9761 delta
, delta_bytes
);
9764 /* If this row displays text now but previously didn't,
9765 or vice versa, w->window_end_vpos may have to be
9767 if ((it
.glyph_row
- 1)->displays_text_p
)
9769 if (XFASTINT (w
->window_end_vpos
) < this_line_vpos
)
9770 XSETINT (w
->window_end_vpos
, this_line_vpos
);
9772 else if (XFASTINT (w
->window_end_vpos
) == this_line_vpos
9773 && this_line_vpos
> 0)
9774 XSETINT (w
->window_end_vpos
, this_line_vpos
- 1);
9775 w
->window_end_valid
= Qnil
;
9777 /* Update hint: No need to try to scroll in update_window. */
9778 w
->desired_matrix
->no_scrolling_p
= 1;
9781 *w
->desired_matrix
->method
= 0;
9782 debug_method_add (w
, "optimization 1");
9784 #ifdef HAVE_WINDOW_SYSTEM
9785 update_window_fringes (w
, 0);
9792 else if (/* Cursor position hasn't changed. */
9793 PT
== XFASTINT (w
->last_point
)
9794 /* Make sure the cursor was last displayed
9795 in this window. Otherwise we have to reposition it. */
9796 && 0 <= w
->cursor
.vpos
9797 && WINDOW_TOTAL_LINES (w
) > w
->cursor
.vpos
)
9801 do_pending_window_change (1);
9803 /* We used to always goto end_of_redisplay here, but this
9804 isn't enough if we have a blinking cursor. */
9805 if (w
->cursor_off_p
== w
->last_cursor_off_p
)
9806 goto end_of_redisplay
;
9810 /* If highlighting the region, or if the cursor is in the echo area,
9811 then we can't just move the cursor. */
9812 else if (! (!NILP (Vtransient_mark_mode
)
9813 && !NILP (current_buffer
->mark_active
))
9814 && (EQ (selected_window
, current_buffer
->last_selected_window
)
9815 || highlight_nonselected_windows
)
9816 && NILP (w
->region_showing
)
9817 && NILP (Vshow_trailing_whitespace
)
9818 && !cursor_in_echo_area
)
9821 struct glyph_row
*row
;
9823 /* Skip from tlbufpos to PT and see where it is. Note that
9824 PT may be in invisible text. If so, we will end at the
9825 next visible position. */
9826 init_iterator (&it
, w
, CHARPOS (tlbufpos
), BYTEPOS (tlbufpos
),
9827 NULL
, DEFAULT_FACE_ID
);
9828 it
.current_x
= this_line_start_x
;
9829 it
.current_y
= this_line_y
;
9830 it
.vpos
= this_line_vpos
;
9832 /* The call to move_it_to stops in front of PT, but
9833 moves over before-strings. */
9834 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
9836 if (it
.vpos
== this_line_vpos
9837 && (row
= MATRIX_ROW (w
->current_matrix
, this_line_vpos
),
9840 xassert (this_line_vpos
== it
.vpos
);
9841 xassert (this_line_y
== it
.current_y
);
9842 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
9844 *w
->desired_matrix
->method
= 0;
9845 debug_method_add (w
, "optimization 3");
9854 /* Text changed drastically or point moved off of line. */
9855 SET_MATRIX_ROW_ENABLED_P (w
->desired_matrix
, this_line_vpos
, 0);
9858 CHARPOS (this_line_start_pos
) = 0;
9859 consider_all_windows_p
|= buffer_shared
> 1;
9860 ++clear_face_cache_count
;
9863 /* Build desired matrices, and update the display. If
9864 consider_all_windows_p is non-zero, do it for all windows on all
9865 frames. Otherwise do it for selected_window, only. */
9867 if (consider_all_windows_p
)
9869 Lisp_Object tail
, frame
;
9870 int i
, n
= 0, size
= 50;
9871 struct frame
**updated
9872 = (struct frame
**) alloca (size
* sizeof *updated
);
9874 /* Clear the face cache eventually. */
9875 if (clear_face_cache_count
> CLEAR_FACE_CACHE_COUNT
)
9877 clear_face_cache (0);
9878 clear_face_cache_count
= 0;
9881 /* Recompute # windows showing selected buffer. This will be
9882 incremented each time such a window is displayed. */
9885 FOR_EACH_FRAME (tail
, frame
)
9887 struct frame
*f
= XFRAME (frame
);
9889 if (FRAME_WINDOW_P (f
) || FRAME_TERMCAP_P (f
) || f
== sf
)
9891 if (! EQ (frame
, selected_frame
))
9892 /* Select the frame, for the sake of frame-local
9894 select_frame_for_redisplay (frame
);
9896 #ifdef HAVE_WINDOW_SYSTEM
9897 if (clear_face_cache_count
% 50 == 0
9898 && FRAME_WINDOW_P (f
))
9899 clear_image_cache (f
, 0);
9900 #endif /* HAVE_WINDOW_SYSTEM */
9902 /* Mark all the scroll bars to be removed; we'll redeem
9903 the ones we want when we redisplay their windows. */
9904 if (FRAME_DISPLAY (f
)->condemn_scroll_bars_hook
)
9905 FRAME_DISPLAY (f
)->condemn_scroll_bars_hook (f
);
9907 if (FRAME_VISIBLE_P (f
) && !FRAME_OBSCURED_P (f
))
9908 redisplay_windows (FRAME_ROOT_WINDOW (f
));
9910 /* Any scroll bars which redisplay_windows should have
9911 nuked should now go away. */
9912 if (FRAME_DISPLAY (f
)->judge_scroll_bars_hook
)
9913 FRAME_DISPLAY (f
)->judge_scroll_bars_hook (f
);
9915 /* If fonts changed, display again. */
9916 /* ??? rms: I suspect it is a mistake to jump all the way
9917 back to retry here. It should just retry this frame. */
9918 if (fonts_changed_p
)
9921 if (FRAME_VISIBLE_P (f
) && !FRAME_OBSCURED_P (f
))
9923 /* See if we have to hscroll. */
9924 if (hscroll_windows (f
->root_window
))
9927 /* Prevent various kinds of signals during display
9928 update. stdio is not robust about handling
9929 signals, which can cause an apparent I/O
9931 if (interrupt_input
)
9935 /* Update the display. */
9936 set_window_update_flags (XWINDOW (f
->root_window
), 1);
9937 pause
|= update_frame (f
, 0, 0);
9938 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
9945 int nbytes
= size
* sizeof *updated
;
9946 struct frame
**p
= (struct frame
**) alloca (2 * nbytes
);
9947 bcopy (updated
, p
, nbytes
);
9958 /* Do the mark_window_display_accurate after all windows have
9959 been redisplayed because this call resets flags in buffers
9960 which are needed for proper redisplay. */
9961 for (i
= 0; i
< n
; ++i
)
9963 struct frame
*f
= updated
[i
];
9964 mark_window_display_accurate (f
->root_window
, 1);
9965 if (FRAME_DISPLAY (f
)->frame_up_to_date_hook
)
9966 FRAME_DISPLAY (f
)->frame_up_to_date_hook (f
);
9970 else if (FRAME_VISIBLE_P (sf
) && !FRAME_OBSCURED_P (sf
))
9972 Lisp_Object mini_window
;
9973 struct frame
*mini_frame
;
9975 displayed_buffer
= XBUFFER (XWINDOW (selected_window
)->buffer
);
9976 /* Use list_of_error, not Qerror, so that
9977 we catch only errors and don't run the debugger. */
9978 internal_condition_case_1 (redisplay_window_1
, selected_window
,
9980 redisplay_window_error
);
9982 /* Compare desired and current matrices, perform output. */
9985 /* If fonts changed, display again. */
9986 if (fonts_changed_p
)
9989 /* Prevent various kinds of signals during display update.
9990 stdio is not robust about handling signals,
9991 which can cause an apparent I/O error. */
9992 if (interrupt_input
)
9996 if (FRAME_VISIBLE_P (sf
) && !FRAME_OBSCURED_P (sf
))
9998 if (hscroll_windows (selected_window
))
10001 XWINDOW (selected_window
)->must_be_updated_p
= 1;
10002 pause
= update_frame (sf
, 0, 0);
10005 /* We may have called echo_area_display at the top of this
10006 function. If the echo area is on another frame, that may
10007 have put text on a frame other than the selected one, so the
10008 above call to update_frame would not have caught it. Catch
10010 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
10011 mini_frame
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
10013 if (mini_frame
!= sf
&& FRAME_WINDOW_P (mini_frame
))
10015 XWINDOW (mini_window
)->must_be_updated_p
= 1;
10016 pause
|= update_frame (mini_frame
, 0, 0);
10017 if (!pause
&& hscroll_windows (mini_window
))
10022 /* If display was paused because of pending input, make sure we do a
10023 thorough update the next time. */
10026 /* Prevent the optimization at the beginning of
10027 redisplay_internal that tries a single-line update of the
10028 line containing the cursor in the selected window. */
10029 CHARPOS (this_line_start_pos
) = 0;
10031 /* Let the overlay arrow be updated the next time. */
10032 if (!NILP (last_arrow_position
))
10034 last_arrow_position
= Qt
;
10035 last_arrow_string
= Qt
;
10038 /* If we pause after scrolling, some rows in the current
10039 matrices of some windows are not valid. */
10040 if (!WINDOW_FULL_WIDTH_P (w
)
10041 && !FRAME_WINDOW_P (XFRAME (w
->frame
)))
10042 update_mode_lines
= 1;
10046 if (!consider_all_windows_p
)
10048 /* This has already been done above if
10049 consider_all_windows_p is set. */
10050 mark_window_display_accurate_1 (w
, 1);
10052 last_arrow_position
= COERCE_MARKER (Voverlay_arrow_position
);
10053 last_arrow_string
= Voverlay_arrow_string
;
10055 if (FRAME_DISPLAY (sf
)->frame_up_to_date_hook
!= 0)
10056 FRAME_DISPLAY (sf
)->frame_up_to_date_hook (sf
);
10059 update_mode_lines
= 0;
10060 windows_or_buffers_changed
= 0;
10061 cursor_type_changed
= 0;
10064 /* Start SIGIO interrupts coming again. Having them off during the
10065 code above makes it less likely one will discard output, but not
10066 impossible, since there might be stuff in the system buffer here.
10067 But it is much hairier to try to do anything about that. */
10068 if (interrupt_input
)
10072 /* If a frame has become visible which was not before, redisplay
10073 again, so that we display it. Expose events for such a frame
10074 (which it gets when becoming visible) don't call the parts of
10075 redisplay constructing glyphs, so simply exposing a frame won't
10076 display anything in this case. So, we have to display these
10077 frames here explicitly. */
10080 Lisp_Object tail
, frame
;
10083 FOR_EACH_FRAME (tail
, frame
)
10085 int this_is_visible
= 0;
10087 if (XFRAME (frame
)->visible
)
10088 this_is_visible
= 1;
10089 FRAME_SAMPLE_VISIBILITY (XFRAME (frame
));
10090 if (XFRAME (frame
)->visible
)
10091 this_is_visible
= 1;
10093 if (this_is_visible
)
10097 if (new_count
!= number_of_visible_frames
)
10098 windows_or_buffers_changed
++;
10101 /* Change frame size now if a change is pending. */
10102 do_pending_window_change (1);
10104 /* If we just did a pending size change, or have additional
10105 visible frames, redisplay again. */
10106 if (windows_or_buffers_changed
&& !pause
)
10110 unbind_to (count
, Qnil
);
10115 /* Redisplay, but leave alone any recent echo area message unless
10116 another message has been requested in its place.
10118 This is useful in situations where you need to redisplay but no
10119 user action has occurred, making it inappropriate for the message
10120 area to be cleared. See tracking_off and
10121 wait_reading_process_input for examples of these situations.
10123 FROM_WHERE is an integer saying from where this function was
10124 called. This is useful for debugging. */
10127 redisplay_preserve_echo_area (from_where
)
10130 TRACE ((stderr
, "redisplay_preserve_echo_area (%d)\n", from_where
));
10132 if (!NILP (echo_area_buffer
[1]))
10134 /* We have a previously displayed message, but no current
10135 message. Redisplay the previous message. */
10136 display_last_displayed_message_p
= 1;
10137 redisplay_internal (1);
10138 display_last_displayed_message_p
= 0;
10141 redisplay_internal (1);
10145 /* Function registered with record_unwind_protect in
10146 redisplay_internal. Reset redisplaying_p to the value it had
10147 before redisplay_internal was called, and clear
10148 prevent_freeing_realized_faces_p. It also selects the previously
10152 unwind_redisplay (val
)
10155 Lisp_Object old_redisplaying_p
, old_frame
;
10157 old_redisplaying_p
= XCAR (val
);
10158 redisplaying_p
= XFASTINT (old_redisplaying_p
);
10159 old_frame
= XCDR (val
);
10160 if (! EQ (old_frame
, selected_frame
))
10161 select_frame_for_redisplay (old_frame
);
10166 /* Mark the display of window W as accurate or inaccurate. If
10167 ACCURATE_P is non-zero mark display of W as accurate. If
10168 ACCURATE_P is zero, arrange for W to be redisplayed the next time
10169 redisplay_internal is called. */
10172 mark_window_display_accurate_1 (w
, accurate_p
)
10176 if (BUFFERP (w
->buffer
))
10178 struct buffer
*b
= XBUFFER (w
->buffer
);
10181 = make_number (accurate_p
? BUF_MODIFF (b
) : 0);
10182 w
->last_overlay_modified
10183 = make_number (accurate_p
? BUF_OVERLAY_MODIFF (b
) : 0);
10185 = BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
) ? Qt
: Qnil
;
10189 b
->clip_changed
= 0;
10190 b
->prevent_redisplay_optimizations_p
= 0;
10192 BUF_UNCHANGED_MODIFIED (b
) = BUF_MODIFF (b
);
10193 BUF_OVERLAY_UNCHANGED_MODIFIED (b
) = BUF_OVERLAY_MODIFF (b
);
10194 BUF_BEG_UNCHANGED (b
) = BUF_GPT (b
) - BUF_BEG (b
);
10195 BUF_END_UNCHANGED (b
) = BUF_Z (b
) - BUF_GPT (b
);
10197 w
->current_matrix
->buffer
= b
;
10198 w
->current_matrix
->begv
= BUF_BEGV (b
);
10199 w
->current_matrix
->zv
= BUF_ZV (b
);
10201 w
->last_cursor
= w
->cursor
;
10202 w
->last_cursor_off_p
= w
->cursor_off_p
;
10204 if (w
== XWINDOW (selected_window
))
10205 w
->last_point
= make_number (BUF_PT (b
));
10207 w
->last_point
= make_number (XMARKER (w
->pointm
)->charpos
);
10213 w
->window_end_valid
= w
->buffer
;
10214 #if 0 /* This is incorrect with variable-height lines. */
10215 xassert (XINT (w
->window_end_vpos
)
10216 < (WINDOW_TOTAL_LINES (w
)
10217 - (WINDOW_WANTS_MODELINE_P (w
) ? 1 : 0)));
10219 w
->update_mode_line
= Qnil
;
10224 /* Mark the display of windows in the window tree rooted at WINDOW as
10225 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
10226 windows as accurate. If ACCURATE_P is zero, arrange for windows to
10227 be redisplayed the next time redisplay_internal is called. */
10230 mark_window_display_accurate (window
, accurate_p
)
10231 Lisp_Object window
;
10236 for (; !NILP (window
); window
= w
->next
)
10238 w
= XWINDOW (window
);
10239 mark_window_display_accurate_1 (w
, accurate_p
);
10241 if (!NILP (w
->vchild
))
10242 mark_window_display_accurate (w
->vchild
, accurate_p
);
10243 if (!NILP (w
->hchild
))
10244 mark_window_display_accurate (w
->hchild
, accurate_p
);
10249 last_arrow_position
= COERCE_MARKER (Voverlay_arrow_position
);
10250 last_arrow_string
= Voverlay_arrow_string
;
10254 /* Force a thorough redisplay the next time by setting
10255 last_arrow_position and last_arrow_string to t, which is
10256 unequal to any useful value of Voverlay_arrow_... */
10257 last_arrow_position
= Qt
;
10258 last_arrow_string
= Qt
;
10263 /* Return value in display table DP (Lisp_Char_Table *) for character
10264 C. Since a display table doesn't have any parent, we don't have to
10265 follow parent. Do not call this function directly but use the
10266 macro DISP_CHAR_VECTOR. */
10269 disp_char_vector (dp
, c
)
10270 struct Lisp_Char_Table
*dp
;
10276 if (SINGLE_BYTE_CHAR_P (c
))
10277 return (dp
->contents
[c
]);
10279 SPLIT_CHAR (c
, code
[0], code
[1], code
[2]);
10282 else if (code
[2] < 32)
10285 /* Here, the possible range of code[0] (== charset ID) is
10286 128..max_charset. Since the top level char table contains data
10287 for multibyte characters after 256th element, we must increment
10288 code[0] by 128 to get a correct index. */
10290 code
[3] = -1; /* anchor */
10292 for (i
= 0; code
[i
] >= 0; i
++, dp
= XCHAR_TABLE (val
))
10294 val
= dp
->contents
[code
[i
]];
10295 if (!SUB_CHAR_TABLE_P (val
))
10296 return (NILP (val
) ? dp
->defalt
: val
);
10299 /* Here, val is a sub char table. We return the default value of
10301 return (dp
->defalt
);
10306 /***********************************************************************
10308 ***********************************************************************/
10310 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
10313 redisplay_windows (window
)
10314 Lisp_Object window
;
10316 while (!NILP (window
))
10318 struct window
*w
= XWINDOW (window
);
10320 if (!NILP (w
->hchild
))
10321 redisplay_windows (w
->hchild
);
10322 else if (!NILP (w
->vchild
))
10323 redisplay_windows (w
->vchild
);
10326 displayed_buffer
= XBUFFER (w
->buffer
);
10327 /* Use list_of_error, not Qerror, so that
10328 we catch only errors and don't run the debugger. */
10329 internal_condition_case_1 (redisplay_window_0
, window
,
10331 redisplay_window_error
);
10339 redisplay_window_error ()
10341 displayed_buffer
->display_error_modiff
= BUF_MODIFF (displayed_buffer
);
10346 redisplay_window_0 (window
)
10347 Lisp_Object window
;
10349 if (displayed_buffer
->display_error_modiff
< BUF_MODIFF (displayed_buffer
))
10350 redisplay_window (window
, 0);
10355 redisplay_window_1 (window
)
10356 Lisp_Object window
;
10358 if (displayed_buffer
->display_error_modiff
< BUF_MODIFF (displayed_buffer
))
10359 redisplay_window (window
, 1);
10364 /* Increment GLYPH until it reaches END or CONDITION fails while
10365 adding (GLYPH)->pixel_width to X. */
10367 #define SKIP_GLYPHS(glyph, end, x, condition) \
10370 (x) += (glyph)->pixel_width; \
10373 while ((glyph) < (end) && (condition))
10376 /* Set cursor position of W. PT is assumed to be displayed in ROW.
10377 DELTA is the number of bytes by which positions recorded in ROW
10378 differ from current buffer positions. */
10381 set_cursor_from_row (w
, row
, matrix
, delta
, delta_bytes
, dy
, dvpos
)
10383 struct glyph_row
*row
;
10384 struct glyph_matrix
*matrix
;
10385 int delta
, delta_bytes
, dy
, dvpos
;
10387 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
10388 struct glyph
*end
= glyph
+ row
->used
[TEXT_AREA
];
10389 /* The first glyph that starts a sequence of glyphs from string. */
10390 struct glyph
*string_start
;
10391 /* The X coordinate of string_start. */
10392 int string_start_x
;
10393 /* The last known character position. */
10394 int last_pos
= MATRIX_ROW_START_CHARPOS (row
) + delta
;
10395 /* The last known character position before string_start. */
10396 int string_before_pos
;
10398 int pt_old
= PT
- delta
;
10400 /* Skip over glyphs not having an object at the start of the row.
10401 These are special glyphs like truncation marks on terminal
10403 if (row
->displays_text_p
)
10405 && INTEGERP (glyph
->object
)
10406 && glyph
->charpos
< 0)
10408 x
+= glyph
->pixel_width
;
10412 string_start
= NULL
;
10414 && !INTEGERP (glyph
->object
)
10415 && (!BUFFERP (glyph
->object
)
10416 || (last_pos
= glyph
->charpos
) < pt_old
))
10418 if (! STRINGP (glyph
->object
))
10420 string_start
= NULL
;
10421 x
+= glyph
->pixel_width
;
10426 string_before_pos
= last_pos
;
10427 string_start
= glyph
;
10428 string_start_x
= x
;
10429 /* Skip all glyphs from string. */
10430 SKIP_GLYPHS (glyph
, end
, x
, STRINGP (glyph
->object
));
10435 && (glyph
== end
|| !BUFFERP (glyph
->object
) || last_pos
> pt_old
))
10437 /* We may have skipped over point because the previous glyphs
10438 are from string. As there's no easy way to know the
10439 character position of the current glyph, find the correct
10440 glyph on point by scanning from string_start again. */
10442 Lisp_Object string
;
10445 limit
= make_number (pt_old
+ 1);
10447 glyph
= string_start
;
10448 x
= string_start_x
;
10449 string
= glyph
->object
;
10450 pos
= string_buffer_position (w
, string
, string_before_pos
);
10451 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
10452 because we always put cursor after overlay strings. */
10453 while (pos
== 0 && glyph
< end
)
10455 string
= glyph
->object
;
10456 SKIP_GLYPHS (glyph
, end
, x
, EQ (glyph
->object
, string
));
10458 pos
= string_buffer_position (w
, glyph
->object
, string_before_pos
);
10461 while (glyph
< end
)
10463 pos
= XINT (Fnext_single_char_property_change
10464 (make_number (pos
), Qdisplay
, Qnil
, limit
));
10467 /* Skip glyphs from the same string. */
10468 string
= glyph
->object
;
10469 SKIP_GLYPHS (glyph
, end
, x
, EQ (glyph
->object
, string
));
10470 /* Skip glyphs from an overlay. */
10472 && ! string_buffer_position (w
, glyph
->object
, pos
))
10474 string
= glyph
->object
;
10475 SKIP_GLYPHS (glyph
, end
, x
, EQ (glyph
->object
, string
));
10480 w
->cursor
.hpos
= glyph
- row
->glyphs
[TEXT_AREA
];
10482 w
->cursor
.vpos
= MATRIX_ROW_VPOS (row
, matrix
) + dvpos
;
10483 w
->cursor
.y
= row
->y
+ dy
;
10485 if (w
== XWINDOW (selected_window
))
10487 if (!row
->continued_p
10488 && !MATRIX_ROW_CONTINUATION_LINE_P (row
)
10491 this_line_buffer
= XBUFFER (w
->buffer
);
10493 CHARPOS (this_line_start_pos
)
10494 = MATRIX_ROW_START_CHARPOS (row
) + delta
;
10495 BYTEPOS (this_line_start_pos
)
10496 = MATRIX_ROW_START_BYTEPOS (row
) + delta_bytes
;
10498 CHARPOS (this_line_end_pos
)
10499 = Z
- (MATRIX_ROW_END_CHARPOS (row
) + delta
);
10500 BYTEPOS (this_line_end_pos
)
10501 = Z_BYTE
- (MATRIX_ROW_END_BYTEPOS (row
) + delta_bytes
);
10503 this_line_y
= w
->cursor
.y
;
10504 this_line_pixel_height
= row
->height
;
10505 this_line_vpos
= w
->cursor
.vpos
;
10506 this_line_start_x
= row
->x
;
10509 CHARPOS (this_line_start_pos
) = 0;
10514 /* Run window scroll functions, if any, for WINDOW with new window
10515 start STARTP. Sets the window start of WINDOW to that position.
10517 We assume that the window's buffer is really current. */
10519 static INLINE
struct text_pos
10520 run_window_scroll_functions (window
, startp
)
10521 Lisp_Object window
;
10522 struct text_pos startp
;
10524 struct window
*w
= XWINDOW (window
);
10525 SET_MARKER_FROM_TEXT_POS (w
->start
, startp
);
10527 if (current_buffer
!= XBUFFER (w
->buffer
))
10530 if (!NILP (Vwindow_scroll_functions
))
10532 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
10533 make_number (CHARPOS (startp
)));
10534 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
10535 /* In case the hook functions switch buffers. */
10536 if (current_buffer
!= XBUFFER (w
->buffer
))
10537 set_buffer_internal_1 (XBUFFER (w
->buffer
));
10544 /* Make sure the line containing the cursor is fully visible.
10545 A value of 1 means there is nothing to be done.
10546 (Either the line is fully visible, or it cannot be made so,
10547 or we cannot tell.)
10548 A value of 0 means the caller should do scrolling
10549 as if point had gone off the screen. */
10552 make_cursor_line_fully_visible (w
)
10555 struct glyph_matrix
*matrix
;
10556 struct glyph_row
*row
;
10559 /* It's not always possible to find the cursor, e.g, when a window
10560 is full of overlay strings. Don't do anything in that case. */
10561 if (w
->cursor
.vpos
< 0)
10564 matrix
= w
->desired_matrix
;
10565 row
= MATRIX_ROW (matrix
, w
->cursor
.vpos
);
10567 /* If the cursor row is not partially visible, there's nothing to do. */
10568 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (row
))
10571 /* If the row the cursor is in is taller than the window's height,
10572 it's not clear what to do, so do nothing. */
10573 window_height
= window_box_height (w
);
10574 if (row
->height
>= window_height
)
10580 /* This code used to try to scroll the window just enough to make
10581 the line visible. It returned 0 to say that the caller should
10582 allocate larger glyph matrices. */
10584 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w
, row
))
10586 int dy
= row
->height
- row
->visible_height
;
10589 shift_glyph_matrix (w
, matrix
, 0, matrix
->nrows
, dy
);
10591 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
10593 int dy
= - (row
->height
- row
->visible_height
);
10596 shift_glyph_matrix (w
, matrix
, 0, matrix
->nrows
, dy
);
10599 /* When we change the cursor y-position of the selected window,
10600 change this_line_y as well so that the display optimization for
10601 the cursor line of the selected window in redisplay_internal uses
10602 the correct y-position. */
10603 if (w
== XWINDOW (selected_window
))
10604 this_line_y
= w
->cursor
.y
;
10606 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
10607 redisplay with larger matrices. */
10608 if (matrix
->nrows
< required_matrix_height (w
))
10610 fonts_changed_p
= 1;
10619 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
10620 non-zero means only WINDOW is redisplayed in redisplay_internal.
10621 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
10622 in redisplay_window to bring a partially visible line into view in
10623 the case that only the cursor has moved.
10625 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
10626 last screen line's vertical height extends past the end of the screen.
10630 1 if scrolling succeeded
10632 0 if scrolling didn't find point.
10634 -1 if new fonts have been loaded so that we must interrupt
10635 redisplay, adjust glyph matrices, and try again. */
10641 SCROLLING_NEED_LARGER_MATRICES
10645 try_scrolling (window
, just_this_one_p
, scroll_conservatively
,
10646 scroll_step
, temp_scroll_step
, last_line_misfit
)
10647 Lisp_Object window
;
10648 int just_this_one_p
;
10649 EMACS_INT scroll_conservatively
, scroll_step
;
10650 int temp_scroll_step
;
10651 int last_line_misfit
;
10653 struct window
*w
= XWINDOW (window
);
10654 struct frame
*f
= XFRAME (w
->frame
);
10655 struct text_pos scroll_margin_pos
;
10656 struct text_pos pos
;
10657 struct text_pos startp
;
10659 Lisp_Object window_end
;
10660 int this_scroll_margin
;
10664 int amount_to_scroll
= 0;
10665 Lisp_Object aggressive
;
10667 int end_scroll_margin
;
10670 debug_method_add (w
, "try_scrolling");
10673 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
10675 /* Compute scroll margin height in pixels. We scroll when point is
10676 within this distance from the top or bottom of the window. */
10677 if (scroll_margin
> 0)
10679 this_scroll_margin
= min (scroll_margin
, WINDOW_TOTAL_LINES (w
) / 4);
10680 this_scroll_margin
*= FRAME_LINE_HEIGHT (f
);
10683 this_scroll_margin
= 0;
10685 /* Compute how much we should try to scroll maximally to bring point
10687 if (scroll_step
|| scroll_conservatively
|| temp_scroll_step
)
10688 scroll_max
= max (scroll_step
,
10689 max (scroll_conservatively
, temp_scroll_step
));
10690 else if (NUMBERP (current_buffer
->scroll_down_aggressively
)
10691 || NUMBERP (current_buffer
->scroll_up_aggressively
))
10692 /* We're trying to scroll because of aggressive scrolling
10693 but no scroll_step is set. Choose an arbitrary one. Maybe
10694 there should be a variable for this. */
10698 scroll_max
*= FRAME_LINE_HEIGHT (f
);
10700 /* Decide whether we have to scroll down. Start at the window end
10701 and move this_scroll_margin up to find the position of the scroll
10703 window_end
= Fwindow_end (window
, Qt
);
10707 CHARPOS (scroll_margin_pos
) = XINT (window_end
);
10708 BYTEPOS (scroll_margin_pos
) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos
));
10710 end_scroll_margin
= this_scroll_margin
+ !!last_line_misfit
;
10711 if (end_scroll_margin
)
10713 start_display (&it
, w
, scroll_margin_pos
);
10714 move_it_vertically (&it
, - end_scroll_margin
);
10715 scroll_margin_pos
= it
.current
.pos
;
10718 if (PT
>= CHARPOS (scroll_margin_pos
))
10722 /* Point is in the scroll margin at the bottom of the window, or
10723 below. Compute a new window start that makes point visible. */
10725 /* Compute the distance from the scroll margin to PT.
10726 Give up if the distance is greater than scroll_max. */
10727 start_display (&it
, w
, scroll_margin_pos
);
10729 move_it_to (&it
, PT
, 0, it
.last_visible_y
, -1,
10730 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
10732 /* To make point visible, we have to move the window start
10733 down so that the line the cursor is in is visible, which
10734 means we have to add in the height of the cursor line. */
10735 dy
= line_bottom_y (&it
) - y0
;
10737 if (dy
> scroll_max
)
10738 return SCROLLING_FAILED
;
10740 /* Move the window start down. If scrolling conservatively,
10741 move it just enough down to make point visible. If
10742 scroll_step is set, move it down by scroll_step. */
10743 start_display (&it
, w
, startp
);
10745 if (scroll_conservatively
)
10746 /* Set AMOUNT_TO_SCROLL to at least one line,
10747 and at most scroll_conservatively lines. */
10749 = min (max (dy
, FRAME_LINE_HEIGHT (f
)),
10750 FRAME_LINE_HEIGHT (f
) * scroll_conservatively
);
10751 else if (scroll_step
|| temp_scroll_step
)
10752 amount_to_scroll
= scroll_max
;
10755 aggressive
= current_buffer
->scroll_up_aggressively
;
10756 height
= WINDOW_BOX_TEXT_HEIGHT (w
);
10757 if (NUMBERP (aggressive
))
10758 amount_to_scroll
= XFLOATINT (aggressive
) * height
;
10761 if (amount_to_scroll
<= 0)
10762 return SCROLLING_FAILED
;
10764 /* If moving by amount_to_scroll leaves STARTP unchanged,
10765 move it down one screen line. */
10767 move_it_vertically (&it
, amount_to_scroll
);
10768 if (CHARPOS (it
.current
.pos
) == CHARPOS (startp
))
10769 move_it_by_lines (&it
, 1, 1);
10770 startp
= it
.current
.pos
;
10774 /* See if point is inside the scroll margin at the top of the
10776 scroll_margin_pos
= startp
;
10777 if (this_scroll_margin
)
10779 start_display (&it
, w
, startp
);
10780 move_it_vertically (&it
, this_scroll_margin
);
10781 scroll_margin_pos
= it
.current
.pos
;
10784 if (PT
< CHARPOS (scroll_margin_pos
))
10786 /* Point is in the scroll margin at the top of the window or
10787 above what is displayed in the window. */
10790 /* Compute the vertical distance from PT to the scroll
10791 margin position. Give up if distance is greater than
10793 SET_TEXT_POS (pos
, PT
, PT_BYTE
);
10794 start_display (&it
, w
, pos
);
10796 move_it_to (&it
, CHARPOS (scroll_margin_pos
), 0,
10797 it
.last_visible_y
, -1,
10798 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
10799 dy
= it
.current_y
- y0
;
10800 if (dy
> scroll_max
)
10801 return SCROLLING_FAILED
;
10803 /* Compute new window start. */
10804 start_display (&it
, w
, startp
);
10806 if (scroll_conservatively
)
10808 max (dy
, FRAME_LINE_HEIGHT (f
) * max (scroll_step
, temp_scroll_step
));
10809 else if (scroll_step
|| temp_scroll_step
)
10810 amount_to_scroll
= scroll_max
;
10813 aggressive
= current_buffer
->scroll_down_aggressively
;
10814 height
= WINDOW_BOX_TEXT_HEIGHT (w
);
10815 if (NUMBERP (aggressive
))
10816 amount_to_scroll
= XFLOATINT (aggressive
) * height
;
10819 if (amount_to_scroll
<= 0)
10820 return SCROLLING_FAILED
;
10822 move_it_vertically (&it
, - amount_to_scroll
);
10823 startp
= it
.current
.pos
;
10827 /* Run window scroll functions. */
10828 startp
= run_window_scroll_functions (window
, startp
);
10830 /* Display the window. Give up if new fonts are loaded, or if point
10832 if (!try_window (window
, startp
))
10833 rc
= SCROLLING_NEED_LARGER_MATRICES
;
10834 else if (w
->cursor
.vpos
< 0)
10836 clear_glyph_matrix (w
->desired_matrix
);
10837 rc
= SCROLLING_FAILED
;
10841 /* Maybe forget recorded base line for line number display. */
10842 if (!just_this_one_p
10843 || current_buffer
->clip_changed
10844 || BEG_UNCHANGED
< CHARPOS (startp
))
10845 w
->base_line_number
= Qnil
;
10847 /* If cursor ends up on a partially visible line,
10848 treat that as being off the bottom of the screen. */
10849 if (! make_cursor_line_fully_visible (w
))
10851 clear_glyph_matrix (w
->desired_matrix
);
10852 last_line_misfit
= 1;
10855 rc
= SCROLLING_SUCCESS
;
10862 /* Compute a suitable window start for window W if display of W starts
10863 on a continuation line. Value is non-zero if a new window start
10866 The new window start will be computed, based on W's width, starting
10867 from the start of the continued line. It is the start of the
10868 screen line with the minimum distance from the old start W->start. */
10871 compute_window_start_on_continuation_line (w
)
10874 struct text_pos pos
, start_pos
;
10875 int window_start_changed_p
= 0;
10877 SET_TEXT_POS_FROM_MARKER (start_pos
, w
->start
);
10879 /* If window start is on a continuation line... Window start may be
10880 < BEGV in case there's invisible text at the start of the
10881 buffer (M-x rmail, for example). */
10882 if (CHARPOS (start_pos
) > BEGV
10883 && FETCH_BYTE (BYTEPOS (start_pos
) - 1) != '\n')
10886 struct glyph_row
*row
;
10888 /* Handle the case that the window start is out of range. */
10889 if (CHARPOS (start_pos
) < BEGV
)
10890 SET_TEXT_POS (start_pos
, BEGV
, BEGV_BYTE
);
10891 else if (CHARPOS (start_pos
) > ZV
)
10892 SET_TEXT_POS (start_pos
, ZV
, ZV_BYTE
);
10894 /* Find the start of the continued line. This should be fast
10895 because scan_buffer is fast (newline cache). */
10896 row
= w
->desired_matrix
->rows
+ (WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0);
10897 init_iterator (&it
, w
, CHARPOS (start_pos
), BYTEPOS (start_pos
),
10898 row
, DEFAULT_FACE_ID
);
10899 reseat_at_previous_visible_line_start (&it
);
10901 /* If the line start is "too far" away from the window start,
10902 say it takes too much time to compute a new window start. */
10903 if (CHARPOS (start_pos
) - IT_CHARPOS (it
)
10904 < WINDOW_TOTAL_LINES (w
) * WINDOW_TOTAL_COLS (w
))
10906 int min_distance
, distance
;
10908 /* Move forward by display lines to find the new window
10909 start. If window width was enlarged, the new start can
10910 be expected to be > the old start. If window width was
10911 decreased, the new window start will be < the old start.
10912 So, we're looking for the display line start with the
10913 minimum distance from the old window start. */
10914 pos
= it
.current
.pos
;
10915 min_distance
= INFINITY
;
10916 while ((distance
= abs (CHARPOS (start_pos
) - IT_CHARPOS (it
))),
10917 distance
< min_distance
)
10919 min_distance
= distance
;
10920 pos
= it
.current
.pos
;
10921 move_it_by_lines (&it
, 1, 0);
10924 /* Set the window start there. */
10925 SET_MARKER_FROM_TEXT_POS (w
->start
, pos
);
10926 window_start_changed_p
= 1;
10930 return window_start_changed_p
;
10934 /* Try cursor movement in case text has not changed in window WINDOW,
10935 with window start STARTP. Value is
10937 CURSOR_MOVEMENT_SUCCESS if successful
10939 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
10941 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
10942 display. *SCROLL_STEP is set to 1, under certain circumstances, if
10943 we want to scroll as if scroll-step were set to 1. See the code.
10945 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
10946 which case we have to abort this redisplay, and adjust matrices
10951 CURSOR_MOVEMENT_SUCCESS
,
10952 CURSOR_MOVEMENT_CANNOT_BE_USED
,
10953 CURSOR_MOVEMENT_MUST_SCROLL
,
10954 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
10958 try_cursor_movement (window
, startp
, scroll_step
)
10959 Lisp_Object window
;
10960 struct text_pos startp
;
10963 struct window
*w
= XWINDOW (window
);
10964 struct frame
*f
= XFRAME (w
->frame
);
10965 int rc
= CURSOR_MOVEMENT_CANNOT_BE_USED
;
10968 if (inhibit_try_cursor_movement
)
10972 /* Handle case where text has not changed, only point, and it has
10973 not moved off the frame. */
10974 if (/* Point may be in this window. */
10975 PT
>= CHARPOS (startp
)
10976 /* Selective display hasn't changed. */
10977 && !current_buffer
->clip_changed
10978 /* Function force-mode-line-update is used to force a thorough
10979 redisplay. It sets either windows_or_buffers_changed or
10980 update_mode_lines. So don't take a shortcut here for these
10982 && !update_mode_lines
10983 && !windows_or_buffers_changed
10984 && !cursor_type_changed
10985 /* Can't use this case if highlighting a region. When a
10986 region exists, cursor movement has to do more than just
10988 && !(!NILP (Vtransient_mark_mode
)
10989 && !NILP (current_buffer
->mark_active
))
10990 && NILP (w
->region_showing
)
10991 && NILP (Vshow_trailing_whitespace
)
10992 /* Right after splitting windows, last_point may be nil. */
10993 && INTEGERP (w
->last_point
)
10994 /* This code is not used for mini-buffer for the sake of the case
10995 of redisplaying to replace an echo area message; since in
10996 that case the mini-buffer contents per se are usually
10997 unchanged. This code is of no real use in the mini-buffer
10998 since the handling of this_line_start_pos, etc., in redisplay
10999 handles the same cases. */
11000 && !EQ (window
, minibuf_window
)
11001 /* When splitting windows or for new windows, it happens that
11002 redisplay is called with a nil window_end_vpos or one being
11003 larger than the window. This should really be fixed in
11004 window.c. I don't have this on my list, now, so we do
11005 approximately the same as the old redisplay code. --gerd. */
11006 && INTEGERP (w
->window_end_vpos
)
11007 && XFASTINT (w
->window_end_vpos
) < w
->current_matrix
->nrows
11008 && (FRAME_WINDOW_P (f
)
11009 || !MARKERP (Voverlay_arrow_position
)
11010 || current_buffer
!= XMARKER (Voverlay_arrow_position
)->buffer
))
11012 int this_scroll_margin
;
11013 struct glyph_row
*row
= NULL
;
11016 debug_method_add (w
, "cursor movement");
11019 /* Scroll if point within this distance from the top or bottom
11020 of the window. This is a pixel value. */
11021 this_scroll_margin
= max (0, scroll_margin
);
11022 this_scroll_margin
= min (this_scroll_margin
, WINDOW_TOTAL_LINES (w
) / 4);
11023 this_scroll_margin
*= FRAME_LINE_HEIGHT (f
);
11025 /* Start with the row the cursor was displayed during the last
11026 not paused redisplay. Give up if that row is not valid. */
11027 if (w
->last_cursor
.vpos
< 0
11028 || w
->last_cursor
.vpos
>= w
->current_matrix
->nrows
)
11029 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11032 row
= MATRIX_ROW (w
->current_matrix
, w
->last_cursor
.vpos
);
11033 if (row
->mode_line_p
)
11035 if (!row
->enabled_p
)
11036 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11039 if (rc
== CURSOR_MOVEMENT_CANNOT_BE_USED
)
11042 int last_y
= window_text_bottom_y (w
) - this_scroll_margin
;
11044 if (PT
> XFASTINT (w
->last_point
))
11046 /* Point has moved forward. */
11047 while (MATRIX_ROW_END_CHARPOS (row
) < PT
11048 && MATRIX_ROW_BOTTOM_Y (row
) < last_y
)
11050 xassert (row
->enabled_p
);
11054 /* The end position of a row equals the start position
11055 of the next row. If PT is there, we would rather
11056 display it in the next line. */
11057 while (MATRIX_ROW_BOTTOM_Y (row
) < last_y
11058 && MATRIX_ROW_END_CHARPOS (row
) == PT
11059 && !cursor_row_p (w
, row
))
11062 /* If within the scroll margin, scroll. Note that
11063 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
11064 the next line would be drawn, and that
11065 this_scroll_margin can be zero. */
11066 if (MATRIX_ROW_BOTTOM_Y (row
) > last_y
11067 || PT
> MATRIX_ROW_END_CHARPOS (row
)
11068 /* Line is completely visible last line in window
11069 and PT is to be set in the next line. */
11070 || (MATRIX_ROW_BOTTOM_Y (row
) == last_y
11071 && PT
== MATRIX_ROW_END_CHARPOS (row
)
11072 && !row
->ends_at_zv_p
11073 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
)))
11076 else if (PT
< XFASTINT (w
->last_point
))
11078 /* Cursor has to be moved backward. Note that PT >=
11079 CHARPOS (startp) because of the outer
11081 while (!row
->mode_line_p
11082 && (MATRIX_ROW_START_CHARPOS (row
) > PT
11083 || (MATRIX_ROW_START_CHARPOS (row
) == PT
11084 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row
)))
11085 && (row
->y
> this_scroll_margin
11086 || CHARPOS (startp
) == BEGV
))
11088 xassert (row
->enabled_p
);
11092 /* Consider the following case: Window starts at BEGV,
11093 there is invisible, intangible text at BEGV, so that
11094 display starts at some point START > BEGV. It can
11095 happen that we are called with PT somewhere between
11096 BEGV and START. Try to handle that case. */
11097 if (row
< w
->current_matrix
->rows
11098 || row
->mode_line_p
)
11100 row
= w
->current_matrix
->rows
;
11101 if (row
->mode_line_p
)
11105 /* Due to newlines in overlay strings, we may have to
11106 skip forward over overlay strings. */
11107 while (MATRIX_ROW_BOTTOM_Y (row
) < last_y
11108 && MATRIX_ROW_END_CHARPOS (row
) == PT
11109 && !cursor_row_p (w
, row
))
11112 /* If within the scroll margin, scroll. */
11113 if (row
->y
< this_scroll_margin
11114 && CHARPOS (startp
) != BEGV
)
11118 if (PT
< MATRIX_ROW_START_CHARPOS (row
)
11119 || PT
> MATRIX_ROW_END_CHARPOS (row
))
11121 /* if PT is not in the glyph row, give up. */
11122 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11124 else if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row
))
11126 if (PT
== MATRIX_ROW_END_CHARPOS (row
)
11127 && !row
->ends_at_zv_p
11128 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
))
11129 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11130 else if (row
->height
> window_box_height (w
))
11132 /* If we end up in a partially visible line, let's
11133 make it fully visible, except when it's taller
11134 than the window, in which case we can't do much
11137 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11141 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
11142 if (!make_cursor_line_fully_visible (w
))
11143 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11145 rc
= CURSOR_MOVEMENT_SUCCESS
;
11149 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11152 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
11153 rc
= CURSOR_MOVEMENT_SUCCESS
;
11162 set_vertical_scroll_bar (w
)
11165 int start
, end
, whole
;
11167 /* Calculate the start and end positions for the current window.
11168 At some point, it would be nice to choose between scrollbars
11169 which reflect the whole buffer size, with special markers
11170 indicating narrowing, and scrollbars which reflect only the
11173 Note that mini-buffers sometimes aren't displaying any text. */
11174 if (!MINI_WINDOW_P (w
)
11175 || (w
== XWINDOW (minibuf_window
)
11176 && NILP (echo_area_buffer
[0])))
11178 struct buffer
*buf
= XBUFFER (w
->buffer
);
11179 whole
= BUF_ZV (buf
) - BUF_BEGV (buf
);
11180 start
= marker_position (w
->start
) - BUF_BEGV (buf
);
11181 /* I don't think this is guaranteed to be right. For the
11182 moment, we'll pretend it is. */
11183 end
= BUF_Z (buf
) - XFASTINT (w
->window_end_pos
) - BUF_BEGV (buf
);
11187 if (whole
< (end
- start
))
11188 whole
= end
- start
;
11191 start
= end
= whole
= 0;
11193 /* Indicate what this scroll bar ought to be displaying now. */
11194 if (FRAME_DISPLAY (XFRAME (w
->frame
))->set_vertical_scroll_bar_hook
)
11195 (*FRAME_DISPLAY (XFRAME (w
->frame
))->set_vertical_scroll_bar_hook
)
11196 (w
, end
- start
, whole
, start
);
11200 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
11201 selected_window is redisplayed.
11203 We can return without actually redisplaying the window if
11204 fonts_changed_p is nonzero. In that case, redisplay_internal will
11208 redisplay_window (window
, just_this_one_p
)
11209 Lisp_Object window
;
11210 int just_this_one_p
;
11212 struct window
*w
= XWINDOW (window
);
11213 struct frame
*f
= XFRAME (w
->frame
);
11214 struct buffer
*buffer
= XBUFFER (w
->buffer
);
11215 struct buffer
*old
= current_buffer
;
11216 struct text_pos lpoint
, opoint
, startp
;
11217 int update_mode_line
;
11220 /* Record it now because it's overwritten. */
11221 int current_matrix_up_to_date_p
= 0;
11222 int used_current_matrix_p
= 0;
11223 /* This is less strict than current_matrix_up_to_date_p.
11224 It indictes that the buffer contents and narrowing are unchanged. */
11225 int buffer_unchanged_p
= 0;
11226 int temp_scroll_step
= 0;
11227 int count
= SPECPDL_INDEX ();
11229 int centering_position
;
11230 int last_line_misfit
= 0;
11232 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
11235 /* W must be a leaf window here. */
11236 xassert (!NILP (w
->buffer
));
11238 *w
->desired_matrix
->method
= 0;
11241 specbind (Qinhibit_point_motion_hooks
, Qt
);
11243 reconsider_clip_changes (w
, buffer
);
11245 /* Has the mode line to be updated? */
11246 update_mode_line
= (!NILP (w
->update_mode_line
)
11247 || update_mode_lines
11248 || buffer
->clip_changed
11249 || buffer
->prevent_redisplay_optimizations_p
);
11251 if (MINI_WINDOW_P (w
))
11253 if (w
== XWINDOW (echo_area_window
)
11254 && !NILP (echo_area_buffer
[0]))
11256 if (update_mode_line
)
11257 /* We may have to update a tty frame's menu bar or a
11258 tool-bar. Example `M-x C-h C-h C-g'. */
11259 goto finish_menu_bars
;
11261 /* We've already displayed the echo area glyphs in this window. */
11262 goto finish_scroll_bars
;
11264 else if ((w
!= XWINDOW (minibuf_window
)
11265 || minibuf_level
== 0)
11266 /* When buffer is nonempty, redisplay window normally. */
11267 && BUF_Z (XBUFFER (w
->buffer
)) == BUF_BEG (XBUFFER (w
->buffer
))
11268 /* Quail displays non-mini buffers in minibuffer window.
11269 In that case, redisplay the window normally. */
11270 && !NILP (Fmemq (w
->buffer
, Vminibuffer_list
)))
11272 /* W is a mini-buffer window, but it's not active, so clear
11274 int yb
= window_text_bottom_y (w
);
11275 struct glyph_row
*row
;
11278 for (y
= 0, row
= w
->desired_matrix
->rows
;
11280 y
+= row
->height
, ++row
)
11281 blank_row (w
, row
, y
);
11282 goto finish_scroll_bars
;
11285 clear_glyph_matrix (w
->desired_matrix
);
11288 /* Otherwise set up data on this window; select its buffer and point
11290 /* Really select the buffer, for the sake of buffer-local
11292 set_buffer_internal_1 (XBUFFER (w
->buffer
));
11293 SET_TEXT_POS (opoint
, PT
, PT_BYTE
);
11295 current_matrix_up_to_date_p
11296 = (!NILP (w
->window_end_valid
)
11297 && !current_buffer
->clip_changed
11298 && !current_buffer
->prevent_redisplay_optimizations_p
11299 && XFASTINT (w
->last_modified
) >= MODIFF
11300 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
);
11303 = (!NILP (w
->window_end_valid
)
11304 && !current_buffer
->clip_changed
11305 && XFASTINT (w
->last_modified
) >= MODIFF
11306 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
);
11308 /* When windows_or_buffers_changed is non-zero, we can't rely on
11309 the window end being valid, so set it to nil there. */
11310 if (windows_or_buffers_changed
)
11312 /* If window starts on a continuation line, maybe adjust the
11313 window start in case the window's width changed. */
11314 if (XMARKER (w
->start
)->buffer
== current_buffer
)
11315 compute_window_start_on_continuation_line (w
);
11317 w
->window_end_valid
= Qnil
;
11320 /* Some sanity checks. */
11321 CHECK_WINDOW_END (w
);
11322 if (Z
== Z_BYTE
&& CHARPOS (opoint
) != BYTEPOS (opoint
))
11324 if (BYTEPOS (opoint
) < CHARPOS (opoint
))
11327 /* If %c is in mode line, update it if needed. */
11328 if (!NILP (w
->column_number_displayed
)
11329 /* This alternative quickly identifies a common case
11330 where no change is needed. */
11331 && !(PT
== XFASTINT (w
->last_point
)
11332 && XFASTINT (w
->last_modified
) >= MODIFF
11333 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
)
11334 && (XFASTINT (w
->column_number_displayed
)
11335 != (int) current_column ())) /* iftc */
11336 update_mode_line
= 1;
11338 /* Count number of windows showing the selected buffer. An indirect
11339 buffer counts as its base buffer. */
11340 if (!just_this_one_p
)
11342 struct buffer
*current_base
, *window_base
;
11343 current_base
= current_buffer
;
11344 window_base
= XBUFFER (XWINDOW (selected_window
)->buffer
);
11345 if (current_base
->base_buffer
)
11346 current_base
= current_base
->base_buffer
;
11347 if (window_base
->base_buffer
)
11348 window_base
= window_base
->base_buffer
;
11349 if (current_base
== window_base
)
11353 /* Point refers normally to the selected window. For any other
11354 window, set up appropriate value. */
11355 if (!EQ (window
, selected_window
))
11357 int new_pt
= XMARKER (w
->pointm
)->charpos
;
11358 int new_pt_byte
= marker_byte_position (w
->pointm
);
11362 new_pt_byte
= BEGV_BYTE
;
11363 set_marker_both (w
->pointm
, Qnil
, BEGV
, BEGV_BYTE
);
11365 else if (new_pt
> (ZV
- 1))
11368 new_pt_byte
= ZV_BYTE
;
11369 set_marker_both (w
->pointm
, Qnil
, ZV
, ZV_BYTE
);
11372 /* We don't use SET_PT so that the point-motion hooks don't run. */
11373 TEMP_SET_PT_BOTH (new_pt
, new_pt_byte
);
11376 /* If any of the character widths specified in the display table
11377 have changed, invalidate the width run cache. It's true that
11378 this may be a bit late to catch such changes, but the rest of
11379 redisplay goes (non-fatally) haywire when the display table is
11380 changed, so why should we worry about doing any better? */
11381 if (current_buffer
->width_run_cache
)
11383 struct Lisp_Char_Table
*disptab
= buffer_display_table ();
11385 if (! disptab_matches_widthtab (disptab
,
11386 XVECTOR (current_buffer
->width_table
)))
11388 invalidate_region_cache (current_buffer
,
11389 current_buffer
->width_run_cache
,
11391 recompute_width_table (current_buffer
, disptab
);
11395 /* If window-start is screwed up, choose a new one. */
11396 if (XMARKER (w
->start
)->buffer
!= current_buffer
)
11399 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
11401 /* If someone specified a new starting point but did not insist,
11402 check whether it can be used. */
11403 if (!NILP (w
->optional_new_start
)
11404 && CHARPOS (startp
) >= BEGV
11405 && CHARPOS (startp
) <= ZV
)
11407 w
->optional_new_start
= Qnil
;
11408 start_display (&it
, w
, startp
);
11409 move_it_to (&it
, PT
, 0, it
.last_visible_y
, -1,
11410 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
11411 if (IT_CHARPOS (it
) == PT
)
11412 w
->force_start
= Qt
;
11413 /* IT may overshoot PT if text at PT is invisible. */
11414 else if (IT_CHARPOS (it
) > PT
&& CHARPOS (startp
) <= PT
)
11415 w
->force_start
= Qt
;
11420 /* Handle case where place to start displaying has been specified,
11421 unless the specified location is outside the accessible range. */
11422 if (!NILP (w
->force_start
)
11423 || w
->frozen_window_start_p
)
11425 /* We set this later on if we have to adjust point. */
11428 w
->force_start
= Qnil
;
11430 w
->window_end_valid
= Qnil
;
11432 /* Forget any recorded base line for line number display. */
11433 if (!buffer_unchanged_p
)
11434 w
->base_line_number
= Qnil
;
11436 /* Redisplay the mode line. Select the buffer properly for that.
11437 Also, run the hook window-scroll-functions
11438 because we have scrolled. */
11439 /* Note, we do this after clearing force_start because
11440 if there's an error, it is better to forget about force_start
11441 than to get into an infinite loop calling the hook functions
11442 and having them get more errors. */
11443 if (!update_mode_line
11444 || ! NILP (Vwindow_scroll_functions
))
11446 update_mode_line
= 1;
11447 w
->update_mode_line
= Qt
;
11448 startp
= run_window_scroll_functions (window
, startp
);
11451 w
->last_modified
= make_number (0);
11452 w
->last_overlay_modified
= make_number (0);
11453 if (CHARPOS (startp
) < BEGV
)
11454 SET_TEXT_POS (startp
, BEGV
, BEGV_BYTE
);
11455 else if (CHARPOS (startp
) > ZV
)
11456 SET_TEXT_POS (startp
, ZV
, ZV_BYTE
);
11458 /* Redisplay, then check if cursor has been set during the
11459 redisplay. Give up if new fonts were loaded. */
11460 if (!try_window (window
, startp
))
11462 w
->force_start
= Qt
;
11463 clear_glyph_matrix (w
->desired_matrix
);
11464 goto need_larger_matrices
;
11467 if (w
->cursor
.vpos
< 0 && !w
->frozen_window_start_p
)
11469 /* If point does not appear, try to move point so it does
11470 appear. The desired matrix has been built above, so we
11471 can use it here. */
11472 new_vpos
= window_box_height (w
) / 2;
11475 if (!make_cursor_line_fully_visible (w
))
11477 /* Point does appear, but on a line partly visible at end of window.
11478 Move it back to a fully-visible line. */
11479 new_vpos
= window_box_height (w
);
11482 /* If we need to move point for either of the above reasons,
11483 now actually do it. */
11486 struct glyph_row
*row
;
11488 row
= MATRIX_FIRST_TEXT_ROW (w
->desired_matrix
);
11489 while (MATRIX_ROW_BOTTOM_Y (row
) < new_vpos
)
11492 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row
),
11493 MATRIX_ROW_START_BYTEPOS (row
));
11495 if (w
!= XWINDOW (selected_window
))
11496 set_marker_both (w
->pointm
, Qnil
, PT
, PT_BYTE
);
11497 else if (current_buffer
== old
)
11498 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
11500 set_cursor_from_row (w
, row
, w
->desired_matrix
, 0, 0, 0, 0);
11502 /* If we are highlighting the region, then we just changed
11503 the region, so redisplay to show it. */
11504 if (!NILP (Vtransient_mark_mode
)
11505 && !NILP (current_buffer
->mark_active
))
11507 clear_glyph_matrix (w
->desired_matrix
);
11508 if (!try_window (window
, startp
))
11509 goto need_larger_matrices
;
11514 debug_method_add (w
, "forced window start");
11519 /* Handle case where text has not changed, only point, and it has
11520 not moved off the frame, and we are not retrying after hscroll.
11521 (current_matrix_up_to_date_p is nonzero when retrying.) */
11522 if (current_matrix_up_to_date_p
11523 && (rc
= try_cursor_movement (window
, startp
, &temp_scroll_step
),
11524 rc
!= CURSOR_MOVEMENT_CANNOT_BE_USED
))
11528 case CURSOR_MOVEMENT_SUCCESS
:
11529 used_current_matrix_p
= 1;
11532 #if 0 /* try_cursor_movement never returns this value. */
11533 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES
:
11534 goto need_larger_matrices
;
11537 case CURSOR_MOVEMENT_MUST_SCROLL
:
11538 goto try_to_scroll
;
11544 /* If current starting point was originally the beginning of a line
11545 but no longer is, find a new starting point. */
11546 else if (!NILP (w
->start_at_line_beg
)
11547 && !(CHARPOS (startp
) <= BEGV
11548 || FETCH_BYTE (BYTEPOS (startp
) - 1) == '\n'))
11551 debug_method_add (w
, "recenter 1");
11556 /* Try scrolling with try_window_id. Value is > 0 if update has
11557 been done, it is -1 if we know that the same window start will
11558 not work. It is 0 if unsuccessful for some other reason. */
11559 else if ((tem
= try_window_id (w
)) != 0)
11562 debug_method_add (w
, "try_window_id %d", tem
);
11565 if (fonts_changed_p
)
11566 goto need_larger_matrices
;
11570 /* Otherwise try_window_id has returned -1 which means that we
11571 don't want the alternative below this comment to execute. */
11573 else if (CHARPOS (startp
) >= BEGV
11574 && CHARPOS (startp
) <= ZV
11575 && PT
>= CHARPOS (startp
)
11576 && (CHARPOS (startp
) < ZV
11577 /* Avoid starting at end of buffer. */
11578 || CHARPOS (startp
) == BEGV
11579 || (XFASTINT (w
->last_modified
) >= MODIFF
11580 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
)))
11583 debug_method_add (w
, "same window start");
11586 /* Try to redisplay starting at same place as before.
11587 If point has not moved off frame, accept the results. */
11588 if (!current_matrix_up_to_date_p
11589 /* Don't use try_window_reusing_current_matrix in this case
11590 because a window scroll function can have changed the
11592 || !NILP (Vwindow_scroll_functions
)
11593 || MINI_WINDOW_P (w
)
11594 || !(used_current_matrix_p
=
11595 try_window_reusing_current_matrix (w
)))
11597 IF_DEBUG (debug_method_add (w
, "1"));
11598 try_window (window
, startp
);
11601 if (fonts_changed_p
)
11602 goto need_larger_matrices
;
11604 if (w
->cursor
.vpos
>= 0)
11606 if (!just_this_one_p
11607 || current_buffer
->clip_changed
11608 || BEG_UNCHANGED
< CHARPOS (startp
))
11609 /* Forget any recorded base line for line number display. */
11610 w
->base_line_number
= Qnil
;
11612 if (!make_cursor_line_fully_visible (w
))
11614 clear_glyph_matrix (w
->desired_matrix
);
11615 last_line_misfit
= 1;
11617 /* Drop through and scroll. */
11622 clear_glyph_matrix (w
->desired_matrix
);
11627 w
->last_modified
= make_number (0);
11628 w
->last_overlay_modified
= make_number (0);
11630 /* Redisplay the mode line. Select the buffer properly for that. */
11631 if (!update_mode_line
)
11633 update_mode_line
= 1;
11634 w
->update_mode_line
= Qt
;
11637 /* Try to scroll by specified few lines. */
11638 if ((scroll_conservatively
11640 || temp_scroll_step
11641 || NUMBERP (current_buffer
->scroll_up_aggressively
)
11642 || NUMBERP (current_buffer
->scroll_down_aggressively
))
11643 && !current_buffer
->clip_changed
11644 && CHARPOS (startp
) >= BEGV
11645 && CHARPOS (startp
) <= ZV
)
11647 /* The function returns -1 if new fonts were loaded, 1 if
11648 successful, 0 if not successful. */
11649 int rc
= try_scrolling (window
, just_this_one_p
,
11650 scroll_conservatively
,
11652 temp_scroll_step
, last_line_misfit
);
11655 case SCROLLING_SUCCESS
:
11658 case SCROLLING_NEED_LARGER_MATRICES
:
11659 goto need_larger_matrices
;
11661 case SCROLLING_FAILED
:
11669 /* Finally, just choose place to start which centers point */
11672 centering_position
= window_box_height (w
) / 2;
11675 /* Jump here with centering_position already set to 0. */
11678 debug_method_add (w
, "recenter");
11681 /* w->vscroll = 0; */
11683 /* Forget any previously recorded base line for line number display. */
11684 if (!buffer_unchanged_p
)
11685 w
->base_line_number
= Qnil
;
11687 /* Move backward half the height of the window. */
11688 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
11689 it
.current_y
= it
.last_visible_y
;
11690 move_it_vertically_backward (&it
, centering_position
);
11691 xassert (IT_CHARPOS (it
) >= BEGV
);
11693 /* The function move_it_vertically_backward may move over more
11694 than the specified y-distance. If it->w is small, e.g. a
11695 mini-buffer window, we may end up in front of the window's
11696 display area. Start displaying at the start of the line
11697 containing PT in this case. */
11698 if (it
.current_y
<= 0)
11700 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
11701 move_it_vertically (&it
, 0);
11702 xassert (IT_CHARPOS (it
) <= PT
);
11706 it
.current_x
= it
.hpos
= 0;
11708 /* Set startp here explicitly in case that helps avoid an infinite loop
11709 in case the window-scroll-functions functions get errors. */
11710 set_marker_both (w
->start
, Qnil
, IT_CHARPOS (it
), IT_BYTEPOS (it
));
11712 /* Run scroll hooks. */
11713 startp
= run_window_scroll_functions (window
, it
.current
.pos
);
11715 /* Redisplay the window. */
11716 if (!current_matrix_up_to_date_p
11717 || windows_or_buffers_changed
11718 || cursor_type_changed
11719 /* Don't use try_window_reusing_current_matrix in this case
11720 because it can have changed the buffer. */
11721 || !NILP (Vwindow_scroll_functions
)
11722 || !just_this_one_p
11723 || MINI_WINDOW_P (w
)
11724 || !(used_current_matrix_p
=
11725 try_window_reusing_current_matrix (w
)))
11726 try_window (window
, startp
);
11728 /* If new fonts have been loaded (due to fontsets), give up. We
11729 have to start a new redisplay since we need to re-adjust glyph
11731 if (fonts_changed_p
)
11732 goto need_larger_matrices
;
11734 /* If cursor did not appear assume that the middle of the window is
11735 in the first line of the window. Do it again with the next line.
11736 (Imagine a window of height 100, displaying two lines of height
11737 60. Moving back 50 from it->last_visible_y will end in the first
11739 if (w
->cursor
.vpos
< 0)
11741 if (!NILP (w
->window_end_valid
)
11742 && PT
>= Z
- XFASTINT (w
->window_end_pos
))
11744 clear_glyph_matrix (w
->desired_matrix
);
11745 move_it_by_lines (&it
, 1, 0);
11746 try_window (window
, it
.current
.pos
);
11748 else if (PT
< IT_CHARPOS (it
))
11750 clear_glyph_matrix (w
->desired_matrix
);
11751 move_it_by_lines (&it
, -1, 0);
11752 try_window (window
, it
.current
.pos
);
11756 /* Not much we can do about it. */
11760 /* Consider the following case: Window starts at BEGV, there is
11761 invisible, intangible text at BEGV, so that display starts at
11762 some point START > BEGV. It can happen that we are called with
11763 PT somewhere between BEGV and START. Try to handle that case. */
11764 if (w
->cursor
.vpos
< 0)
11766 struct glyph_row
*row
= w
->current_matrix
->rows
;
11767 if (row
->mode_line_p
)
11769 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
11772 if (!make_cursor_line_fully_visible (w
))
11774 /* If vscroll is enabled, disable it and try again. */
11778 clear_glyph_matrix (w
->desired_matrix
);
11782 /* If centering point failed to make the whole line visible,
11783 put point at the top instead. That has to make the whole line
11784 visible, if it can be done. */
11785 centering_position
= 0;
11791 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
11792 w
->start_at_line_beg
= ((CHARPOS (startp
) == BEGV
11793 || FETCH_BYTE (BYTEPOS (startp
) - 1) == '\n')
11796 /* Display the mode line, if we must. */
11797 if ((update_mode_line
11798 /* If window not full width, must redo its mode line
11799 if (a) the window to its side is being redone and
11800 (b) we do a frame-based redisplay. This is a consequence
11801 of how inverted lines are drawn in frame-based redisplay. */
11802 || (!just_this_one_p
11803 && !FRAME_WINDOW_P (f
)
11804 && !WINDOW_FULL_WIDTH_P (w
))
11805 /* Line number to display. */
11806 || INTEGERP (w
->base_line_pos
)
11807 /* Column number is displayed and different from the one displayed. */
11808 || (!NILP (w
->column_number_displayed
)
11809 && (XFASTINT (w
->column_number_displayed
)
11810 != (int) current_column ()))) /* iftc */
11811 /* This means that the window has a mode line. */
11812 && (WINDOW_WANTS_MODELINE_P (w
)
11813 || WINDOW_WANTS_HEADER_LINE_P (w
)))
11815 display_mode_lines (w
);
11817 /* If mode line height has changed, arrange for a thorough
11818 immediate redisplay using the correct mode line height. */
11819 if (WINDOW_WANTS_MODELINE_P (w
)
11820 && CURRENT_MODE_LINE_HEIGHT (w
) != DESIRED_MODE_LINE_HEIGHT (w
))
11822 fonts_changed_p
= 1;
11823 MATRIX_MODE_LINE_ROW (w
->current_matrix
)->height
11824 = DESIRED_MODE_LINE_HEIGHT (w
);
11827 /* If top line height has changed, arrange for a thorough
11828 immediate redisplay using the correct mode line height. */
11829 if (WINDOW_WANTS_HEADER_LINE_P (w
)
11830 && CURRENT_HEADER_LINE_HEIGHT (w
) != DESIRED_HEADER_LINE_HEIGHT (w
))
11832 fonts_changed_p
= 1;
11833 MATRIX_HEADER_LINE_ROW (w
->current_matrix
)->height
11834 = DESIRED_HEADER_LINE_HEIGHT (w
);
11837 if (fonts_changed_p
)
11838 goto need_larger_matrices
;
11841 if (!line_number_displayed
11842 && !BUFFERP (w
->base_line_pos
))
11844 w
->base_line_pos
= Qnil
;
11845 w
->base_line_number
= Qnil
;
11850 /* When we reach a frame's selected window, redo the frame's menu bar. */
11851 if (update_mode_line
11852 && EQ (FRAME_SELECTED_WINDOW (f
), window
))
11854 int redisplay_menu_p
= 0;
11855 int redisplay_tool_bar_p
= 0;
11857 if (FRAME_WINDOW_P (f
))
11859 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
11860 || defined (USE_GTK)
11861 redisplay_menu_p
= FRAME_EXTERNAL_MENU_BAR (f
);
11863 redisplay_menu_p
= FRAME_MENU_BAR_LINES (f
) > 0;
11867 redisplay_menu_p
= FRAME_MENU_BAR_LINES (f
) > 0;
11869 if (redisplay_menu_p
)
11870 display_menu_bar (w
);
11872 #ifdef HAVE_WINDOW_SYSTEM
11874 redisplay_tool_bar_p
= FRAME_EXTERNAL_TOOL_BAR (f
);
11876 redisplay_tool_bar_p
= WINDOWP (f
->tool_bar_window
)
11877 && (FRAME_TOOL_BAR_LINES (f
) > 0
11878 || auto_resize_tool_bars_p
);
11882 if (redisplay_tool_bar_p
)
11883 redisplay_tool_bar (f
);
11887 #ifdef HAVE_WINDOW_SYSTEM
11888 if (update_window_fringes (w
, 0)
11889 && !just_this_one_p
11890 && (used_current_matrix_p
|| overlay_arrow_seen
)
11891 && !w
->pseudo_window_p
)
11895 draw_window_fringes (w
);
11899 #endif /* HAVE_WINDOW_SYSTEM */
11901 /* We go to this label, with fonts_changed_p nonzero,
11902 if it is necessary to try again using larger glyph matrices.
11903 We have to redeem the scroll bar even in this case,
11904 because the loop in redisplay_internal expects that. */
11905 need_larger_matrices
:
11907 finish_scroll_bars
:
11909 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w
))
11911 /* Set the thumb's position and size. */
11912 set_vertical_scroll_bar (w
);
11914 /* Note that we actually used the scroll bar attached to this
11915 window, so it shouldn't be deleted at the end of redisplay. */
11916 if (FRAME_DISPLAY (f
)->redeem_scroll_bar_hook
)
11917 (*FRAME_DISPLAY (f
)->redeem_scroll_bar_hook
) (w
);
11920 /* Restore current_buffer and value of point in it. */
11921 TEMP_SET_PT_BOTH (CHARPOS (opoint
), BYTEPOS (opoint
));
11922 set_buffer_internal_1 (old
);
11923 TEMP_SET_PT_BOTH (CHARPOS (lpoint
), BYTEPOS (lpoint
));
11925 unbind_to (count
, Qnil
);
11929 /* Build the complete desired matrix of WINDOW with a window start
11930 buffer position POS. Value is non-zero if successful. It is zero
11931 if fonts were loaded during redisplay which makes re-adjusting
11932 glyph matrices necessary. */
11935 try_window (window
, pos
)
11936 Lisp_Object window
;
11937 struct text_pos pos
;
11939 struct window
*w
= XWINDOW (window
);
11941 struct glyph_row
*last_text_row
= NULL
;
11943 /* Make POS the new window start. */
11944 set_marker_both (w
->start
, Qnil
, CHARPOS (pos
), BYTEPOS (pos
));
11946 /* Mark cursor position as unknown. No overlay arrow seen. */
11947 w
->cursor
.vpos
= -1;
11948 overlay_arrow_seen
= 0;
11950 /* Initialize iterator and info to start at POS. */
11951 start_display (&it
, w
, pos
);
11953 /* Display all lines of W. */
11954 while (it
.current_y
< it
.last_visible_y
)
11956 if (display_line (&it
))
11957 last_text_row
= it
.glyph_row
- 1;
11958 if (fonts_changed_p
)
11962 /* If bottom moved off end of frame, change mode line percentage. */
11963 if (XFASTINT (w
->window_end_pos
) <= 0
11964 && Z
!= IT_CHARPOS (it
))
11965 w
->update_mode_line
= Qt
;
11967 /* Set window_end_pos to the offset of the last character displayed
11968 on the window from the end of current_buffer. Set
11969 window_end_vpos to its row number. */
11972 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row
));
11973 w
->window_end_bytepos
11974 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
11976 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
11978 = make_number (MATRIX_ROW_VPOS (last_text_row
, w
->desired_matrix
));
11979 xassert (MATRIX_ROW (w
->desired_matrix
, XFASTINT (w
->window_end_vpos
))
11980 ->displays_text_p
);
11984 w
->window_end_bytepos
= Z_BYTE
- ZV_BYTE
;
11985 w
->window_end_pos
= make_number (Z
- ZV
);
11986 w
->window_end_vpos
= make_number (0);
11989 /* But that is not valid info until redisplay finishes. */
11990 w
->window_end_valid
= Qnil
;
11996 /************************************************************************
11997 Window redisplay reusing current matrix when buffer has not changed
11998 ************************************************************************/
12000 /* Try redisplay of window W showing an unchanged buffer with a
12001 different window start than the last time it was displayed by
12002 reusing its current matrix. Value is non-zero if successful.
12003 W->start is the new window start. */
12006 try_window_reusing_current_matrix (w
)
12009 struct frame
*f
= XFRAME (w
->frame
);
12010 struct glyph_row
*row
, *bottom_row
;
12013 struct text_pos start
, new_start
;
12014 int nrows_scrolled
, i
;
12015 struct glyph_row
*last_text_row
;
12016 struct glyph_row
*last_reused_text_row
;
12017 struct glyph_row
*start_row
;
12018 int start_vpos
, min_y
, max_y
;
12021 if (inhibit_try_window_reusing
)
12025 if (/* This function doesn't handle terminal frames. */
12026 !FRAME_WINDOW_P (f
)
12027 /* Don't try to reuse the display if windows have been split
12029 || windows_or_buffers_changed
12030 || cursor_type_changed
)
12033 /* Can't do this if region may have changed. */
12034 if ((!NILP (Vtransient_mark_mode
)
12035 && !NILP (current_buffer
->mark_active
))
12036 || !NILP (w
->region_showing
)
12037 || !NILP (Vshow_trailing_whitespace
))
12040 /* If top-line visibility has changed, give up. */
12041 if (WINDOW_WANTS_HEADER_LINE_P (w
)
12042 != MATRIX_HEADER_LINE_ROW (w
->current_matrix
)->mode_line_p
)
12045 /* Give up if old or new display is scrolled vertically. We could
12046 make this function handle this, but right now it doesn't. */
12047 start_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
12048 if (w
->vscroll
|| MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row
))
12051 /* The variable new_start now holds the new window start. The old
12052 start `start' can be determined from the current matrix. */
12053 SET_TEXT_POS_FROM_MARKER (new_start
, w
->start
);
12054 start
= start_row
->start
.pos
;
12055 start_vpos
= MATRIX_ROW_VPOS (start_row
, w
->current_matrix
);
12057 /* Clear the desired matrix for the display below. */
12058 clear_glyph_matrix (w
->desired_matrix
);
12060 if (CHARPOS (new_start
) <= CHARPOS (start
))
12064 /* Don't use this method if the display starts with an ellipsis
12065 displayed for invisible text. It's not easy to handle that case
12066 below, and it's certainly not worth the effort since this is
12067 not a frequent case. */
12068 if (in_ellipses_for_invisible_text_p (&start_row
->start
, w
))
12071 IF_DEBUG (debug_method_add (w
, "twu1"));
12073 /* Display up to a row that can be reused. The variable
12074 last_text_row is set to the last row displayed that displays
12075 text. Note that it.vpos == 0 if or if not there is a
12076 header-line; it's not the same as the MATRIX_ROW_VPOS! */
12077 start_display (&it
, w
, new_start
);
12078 first_row_y
= it
.current_y
;
12079 w
->cursor
.vpos
= -1;
12080 last_text_row
= last_reused_text_row
= NULL
;
12082 while (it
.current_y
< it
.last_visible_y
12083 && IT_CHARPOS (it
) < CHARPOS (start
)
12084 && !fonts_changed_p
)
12085 if (display_line (&it
))
12086 last_text_row
= it
.glyph_row
- 1;
12088 /* A value of current_y < last_visible_y means that we stopped
12089 at the previous window start, which in turn means that we
12090 have at least one reusable row. */
12091 if (it
.current_y
< it
.last_visible_y
)
12093 /* IT.vpos always starts from 0; it counts text lines. */
12094 nrows_scrolled
= it
.vpos
;
12096 /* Find PT if not already found in the lines displayed. */
12097 if (w
->cursor
.vpos
< 0)
12099 int dy
= it
.current_y
- first_row_y
;
12101 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
12102 row
= row_containing_pos (w
, PT
, row
, NULL
, dy
);
12104 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0,
12105 dy
, nrows_scrolled
);
12108 clear_glyph_matrix (w
->desired_matrix
);
12113 /* Scroll the display. Do it before the current matrix is
12114 changed. The problem here is that update has not yet
12115 run, i.e. part of the current matrix is not up to date.
12116 scroll_run_hook will clear the cursor, and use the
12117 current matrix to get the height of the row the cursor is
12119 run
.current_y
= first_row_y
;
12120 run
.desired_y
= it
.current_y
;
12121 run
.height
= it
.last_visible_y
- it
.current_y
;
12123 if (run
.height
> 0 && run
.current_y
!= run
.desired_y
)
12126 FRAME_RIF (f
)->update_window_begin_hook (w
);
12127 FRAME_RIF (f
)->clear_window_mouse_face (w
);
12128 FRAME_RIF (f
)->scroll_run_hook (w
, &run
);
12129 FRAME_RIF (f
)->update_window_end_hook (w
, 0, 0);
12133 /* Shift current matrix down by nrows_scrolled lines. */
12134 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
12135 rotate_matrix (w
->current_matrix
,
12137 MATRIX_ROW_VPOS (bottom_row
, w
->current_matrix
),
12140 /* Disable lines that must be updated. */
12141 for (i
= 0; i
< it
.vpos
; ++i
)
12142 (start_row
+ i
)->enabled_p
= 0;
12144 /* Re-compute Y positions. */
12145 min_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
12146 max_y
= it
.last_visible_y
;
12147 for (row
= start_row
+ nrows_scrolled
;
12151 row
->y
= it
.current_y
;
12152 row
->visible_height
= row
->height
;
12154 if (row
->y
< min_y
)
12155 row
->visible_height
-= min_y
- row
->y
;
12156 if (row
->y
+ row
->height
> max_y
)
12157 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
12158 row
->redraw_fringe_bitmaps_p
= 1;
12160 it
.current_y
+= row
->height
;
12162 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
12163 last_reused_text_row
= row
;
12164 if (MATRIX_ROW_BOTTOM_Y (row
) >= it
.last_visible_y
)
12168 /* Disable lines in the current matrix which are now
12169 below the window. */
12170 for (++row
; row
< bottom_row
; ++row
)
12171 row
->enabled_p
= 0;
12174 /* Update window_end_pos etc.; last_reused_text_row is the last
12175 reused row from the current matrix containing text, if any.
12176 The value of last_text_row is the last displayed line
12177 containing text. */
12178 if (last_reused_text_row
)
12180 w
->window_end_bytepos
12181 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_reused_text_row
);
12183 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_reused_text_row
));
12185 = make_number (MATRIX_ROW_VPOS (last_reused_text_row
,
12186 w
->current_matrix
));
12188 else if (last_text_row
)
12190 w
->window_end_bytepos
12191 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
12193 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
12195 = make_number (MATRIX_ROW_VPOS (last_text_row
, w
->desired_matrix
));
12199 /* This window must be completely empty. */
12200 w
->window_end_bytepos
= Z_BYTE
- ZV_BYTE
;
12201 w
->window_end_pos
= make_number (Z
- ZV
);
12202 w
->window_end_vpos
= make_number (0);
12204 w
->window_end_valid
= Qnil
;
12206 /* Update hint: don't try scrolling again in update_window. */
12207 w
->desired_matrix
->no_scrolling_p
= 1;
12210 debug_method_add (w
, "try_window_reusing_current_matrix 1");
12214 else if (CHARPOS (new_start
) > CHARPOS (start
))
12216 struct glyph_row
*pt_row
, *row
;
12217 struct glyph_row
*first_reusable_row
;
12218 struct glyph_row
*first_row_to_display
;
12220 int yb
= window_text_bottom_y (w
);
12222 /* Find the row starting at new_start, if there is one. Don't
12223 reuse a partially visible line at the end. */
12224 first_reusable_row
= start_row
;
12225 while (first_reusable_row
->enabled_p
12226 && MATRIX_ROW_BOTTOM_Y (first_reusable_row
) < yb
12227 && (MATRIX_ROW_START_CHARPOS (first_reusable_row
)
12228 < CHARPOS (new_start
)))
12229 ++first_reusable_row
;
12231 /* Give up if there is no row to reuse. */
12232 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row
) >= yb
12233 || !first_reusable_row
->enabled_p
12234 || (MATRIX_ROW_START_CHARPOS (first_reusable_row
)
12235 != CHARPOS (new_start
)))
12238 /* We can reuse fully visible rows beginning with
12239 first_reusable_row to the end of the window. Set
12240 first_row_to_display to the first row that cannot be reused.
12241 Set pt_row to the row containing point, if there is any. */
12243 for (first_row_to_display
= first_reusable_row
;
12244 MATRIX_ROW_BOTTOM_Y (first_row_to_display
) < yb
;
12245 ++first_row_to_display
)
12247 if (PT
>= MATRIX_ROW_START_CHARPOS (first_row_to_display
)
12248 && PT
< MATRIX_ROW_END_CHARPOS (first_row_to_display
))
12249 pt_row
= first_row_to_display
;
12252 /* Start displaying at the start of first_row_to_display. */
12253 xassert (first_row_to_display
->y
< yb
);
12254 init_to_row_start (&it
, w
, first_row_to_display
);
12256 nrows_scrolled
= (MATRIX_ROW_VPOS (first_reusable_row
, w
->current_matrix
)
12258 it
.vpos
= (MATRIX_ROW_VPOS (first_row_to_display
, w
->current_matrix
)
12260 it
.current_y
= (first_row_to_display
->y
- first_reusable_row
->y
12261 + WINDOW_HEADER_LINE_HEIGHT (w
));
12263 /* Display lines beginning with first_row_to_display in the
12264 desired matrix. Set last_text_row to the last row displayed
12265 that displays text. */
12266 it
.glyph_row
= MATRIX_ROW (w
->desired_matrix
, it
.vpos
);
12267 if (pt_row
== NULL
)
12268 w
->cursor
.vpos
= -1;
12269 last_text_row
= NULL
;
12270 while (it
.current_y
< it
.last_visible_y
&& !fonts_changed_p
)
12271 if (display_line (&it
))
12272 last_text_row
= it
.glyph_row
- 1;
12274 /* Give up If point isn't in a row displayed or reused. */
12275 if (w
->cursor
.vpos
< 0)
12277 clear_glyph_matrix (w
->desired_matrix
);
12281 /* If point is in a reused row, adjust y and vpos of the cursor
12285 w
->cursor
.vpos
-= MATRIX_ROW_VPOS (first_reusable_row
,
12286 w
->current_matrix
);
12287 w
->cursor
.y
-= first_reusable_row
->y
;
12290 /* Scroll the display. */
12291 run
.current_y
= first_reusable_row
->y
;
12292 run
.desired_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
12293 run
.height
= it
.last_visible_y
- run
.current_y
;
12294 dy
= run
.current_y
- run
.desired_y
;
12299 FRAME_RIF (f
)->update_window_begin_hook (w
);
12300 FRAME_RIF (f
)->clear_window_mouse_face (w
);
12301 FRAME_RIF (f
)->scroll_run_hook (w
, &run
);
12302 FRAME_RIF (f
)->update_window_end_hook (w
, 0, 0);
12306 /* Adjust Y positions of reused rows. */
12307 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
12308 min_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
12309 max_y
= it
.last_visible_y
;
12310 for (row
= first_reusable_row
; row
< first_row_to_display
; ++row
)
12313 row
->visible_height
= row
->height
;
12314 if (row
->y
< min_y
)
12315 row
->visible_height
-= min_y
- row
->y
;
12316 if (row
->y
+ row
->height
> max_y
)
12317 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
12318 row
->redraw_fringe_bitmaps_p
= 1;
12321 /* Scroll the current matrix. */
12322 xassert (nrows_scrolled
> 0);
12323 rotate_matrix (w
->current_matrix
,
12325 MATRIX_ROW_VPOS (bottom_row
, w
->current_matrix
),
12328 /* Disable rows not reused. */
12329 for (row
-= nrows_scrolled
; row
< bottom_row
; ++row
)
12330 row
->enabled_p
= 0;
12332 /* Adjust window end. A null value of last_text_row means that
12333 the window end is in reused rows which in turn means that
12334 only its vpos can have changed. */
12337 w
->window_end_bytepos
12338 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
12340 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
12342 = make_number (MATRIX_ROW_VPOS (last_text_row
, w
->desired_matrix
));
12347 = make_number (XFASTINT (w
->window_end_vpos
) - nrows_scrolled
);
12350 w
->window_end_valid
= Qnil
;
12351 w
->desired_matrix
->no_scrolling_p
= 1;
12354 debug_method_add (w
, "try_window_reusing_current_matrix 2");
12364 /************************************************************************
12365 Window redisplay reusing current matrix when buffer has changed
12366 ************************************************************************/
12368 static struct glyph_row
*find_last_unchanged_at_beg_row
P_ ((struct window
*));
12369 static struct glyph_row
*find_first_unchanged_at_end_row
P_ ((struct window
*,
12371 static struct glyph_row
*
12372 find_last_row_displaying_text
P_ ((struct glyph_matrix
*, struct it
*,
12373 struct glyph_row
*));
12376 /* Return the last row in MATRIX displaying text. If row START is
12377 non-null, start searching with that row. IT gives the dimensions
12378 of the display. Value is null if matrix is empty; otherwise it is
12379 a pointer to the row found. */
12381 static struct glyph_row
*
12382 find_last_row_displaying_text (matrix
, it
, start
)
12383 struct glyph_matrix
*matrix
;
12385 struct glyph_row
*start
;
12387 struct glyph_row
*row
, *row_found
;
12389 /* Set row_found to the last row in IT->w's current matrix
12390 displaying text. The loop looks funny but think of partially
12393 row
= start
? start
: MATRIX_FIRST_TEXT_ROW (matrix
);
12394 while (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
12396 xassert (row
->enabled_p
);
12398 if (MATRIX_ROW_BOTTOM_Y (row
) >= it
->last_visible_y
)
12407 /* Return the last row in the current matrix of W that is not affected
12408 by changes at the start of current_buffer that occurred since W's
12409 current matrix was built. Value is null if no such row exists.
12411 BEG_UNCHANGED us the number of characters unchanged at the start of
12412 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
12413 first changed character in current_buffer. Characters at positions <
12414 BEG + BEG_UNCHANGED are at the same buffer positions as they were
12415 when the current matrix was built. */
12417 static struct glyph_row
*
12418 find_last_unchanged_at_beg_row (w
)
12421 int first_changed_pos
= BEG
+ BEG_UNCHANGED
;
12422 struct glyph_row
*row
;
12423 struct glyph_row
*row_found
= NULL
;
12424 int yb
= window_text_bottom_y (w
);
12426 /* Find the last row displaying unchanged text. */
12427 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
12428 while (MATRIX_ROW_DISPLAYS_TEXT_P (row
)
12429 && MATRIX_ROW_START_CHARPOS (row
) < first_changed_pos
)
12431 if (/* If row ends before first_changed_pos, it is unchanged,
12432 except in some case. */
12433 MATRIX_ROW_END_CHARPOS (row
) <= first_changed_pos
12434 /* When row ends in ZV and we write at ZV it is not
12436 && !row
->ends_at_zv_p
12437 /* When first_changed_pos is the end of a continued line,
12438 row is not unchanged because it may be no longer
12440 && !(MATRIX_ROW_END_CHARPOS (row
) == first_changed_pos
12441 && (row
->continued_p
12442 || row
->exact_window_width_line_p
)))
12445 /* Stop if last visible row. */
12446 if (MATRIX_ROW_BOTTOM_Y (row
) >= yb
)
12456 /* Find the first glyph row in the current matrix of W that is not
12457 affected by changes at the end of current_buffer since the
12458 time W's current matrix was built.
12460 Return in *DELTA the number of chars by which buffer positions in
12461 unchanged text at the end of current_buffer must be adjusted.
12463 Return in *DELTA_BYTES the corresponding number of bytes.
12465 Value is null if no such row exists, i.e. all rows are affected by
12468 static struct glyph_row
*
12469 find_first_unchanged_at_end_row (w
, delta
, delta_bytes
)
12471 int *delta
, *delta_bytes
;
12473 struct glyph_row
*row
;
12474 struct glyph_row
*row_found
= NULL
;
12476 *delta
= *delta_bytes
= 0;
12478 /* Display must not have been paused, otherwise the current matrix
12479 is not up to date. */
12480 if (NILP (w
->window_end_valid
))
12483 /* A value of window_end_pos >= END_UNCHANGED means that the window
12484 end is in the range of changed text. If so, there is no
12485 unchanged row at the end of W's current matrix. */
12486 if (XFASTINT (w
->window_end_pos
) >= END_UNCHANGED
)
12489 /* Set row to the last row in W's current matrix displaying text. */
12490 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
12492 /* If matrix is entirely empty, no unchanged row exists. */
12493 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
12495 /* The value of row is the last glyph row in the matrix having a
12496 meaningful buffer position in it. The end position of row
12497 corresponds to window_end_pos. This allows us to translate
12498 buffer positions in the current matrix to current buffer
12499 positions for characters not in changed text. */
12500 int Z_old
= MATRIX_ROW_END_CHARPOS (row
) + XFASTINT (w
->window_end_pos
);
12501 int Z_BYTE_old
= MATRIX_ROW_END_BYTEPOS (row
) + w
->window_end_bytepos
;
12502 int last_unchanged_pos
, last_unchanged_pos_old
;
12503 struct glyph_row
*first_text_row
12504 = MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
12506 *delta
= Z
- Z_old
;
12507 *delta_bytes
= Z_BYTE
- Z_BYTE_old
;
12509 /* Set last_unchanged_pos to the buffer position of the last
12510 character in the buffer that has not been changed. Z is the
12511 index + 1 of the last character in current_buffer, i.e. by
12512 subtracting END_UNCHANGED we get the index of the last
12513 unchanged character, and we have to add BEG to get its buffer
12515 last_unchanged_pos
= Z
- END_UNCHANGED
+ BEG
;
12516 last_unchanged_pos_old
= last_unchanged_pos
- *delta
;
12518 /* Search backward from ROW for a row displaying a line that
12519 starts at a minimum position >= last_unchanged_pos_old. */
12520 for (; row
> first_text_row
; --row
)
12522 if (!row
->enabled_p
|| !MATRIX_ROW_DISPLAYS_TEXT_P (row
))
12525 if (MATRIX_ROW_START_CHARPOS (row
) >= last_unchanged_pos_old
)
12530 if (row_found
&& !MATRIX_ROW_DISPLAYS_TEXT_P (row_found
))
12537 /* Make sure that glyph rows in the current matrix of window W
12538 reference the same glyph memory as corresponding rows in the
12539 frame's frame matrix. This function is called after scrolling W's
12540 current matrix on a terminal frame in try_window_id and
12541 try_window_reusing_current_matrix. */
12544 sync_frame_with_window_matrix_rows (w
)
12547 struct frame
*f
= XFRAME (w
->frame
);
12548 struct glyph_row
*window_row
, *window_row_end
, *frame_row
;
12550 /* Preconditions: W must be a leaf window and full-width. Its frame
12551 must have a frame matrix. */
12552 xassert (NILP (w
->hchild
) && NILP (w
->vchild
));
12553 xassert (WINDOW_FULL_WIDTH_P (w
));
12554 xassert (!FRAME_WINDOW_P (f
));
12556 /* If W is a full-width window, glyph pointers in W's current matrix
12557 have, by definition, to be the same as glyph pointers in the
12558 corresponding frame matrix. Note that frame matrices have no
12559 marginal areas (see build_frame_matrix). */
12560 window_row
= w
->current_matrix
->rows
;
12561 window_row_end
= window_row
+ w
->current_matrix
->nrows
;
12562 frame_row
= f
->current_matrix
->rows
+ WINDOW_TOP_EDGE_LINE (w
);
12563 while (window_row
< window_row_end
)
12565 struct glyph
*start
= window_row
->glyphs
[LEFT_MARGIN_AREA
];
12566 struct glyph
*end
= window_row
->glyphs
[LAST_AREA
];
12568 frame_row
->glyphs
[LEFT_MARGIN_AREA
] = start
;
12569 frame_row
->glyphs
[TEXT_AREA
] = start
;
12570 frame_row
->glyphs
[RIGHT_MARGIN_AREA
] = end
;
12571 frame_row
->glyphs
[LAST_AREA
] = end
;
12573 /* Disable frame rows whose corresponding window rows have
12574 been disabled in try_window_id. */
12575 if (!window_row
->enabled_p
)
12576 frame_row
->enabled_p
= 0;
12578 ++window_row
, ++frame_row
;
12583 /* Find the glyph row in window W containing CHARPOS. Consider all
12584 rows between START and END (not inclusive). END null means search
12585 all rows to the end of the display area of W. Value is the row
12586 containing CHARPOS or null. */
12589 row_containing_pos (w
, charpos
, start
, end
, dy
)
12592 struct glyph_row
*start
, *end
;
12595 struct glyph_row
*row
= start
;
12598 /* If we happen to start on a header-line, skip that. */
12599 if (row
->mode_line_p
)
12602 if ((end
&& row
>= end
) || !row
->enabled_p
)
12605 last_y
= window_text_bottom_y (w
) - dy
;
12609 /* Give up if we have gone too far. */
12610 if (end
&& row
>= end
)
12612 /* This formerly returned if they were equal.
12613 I think that both quantities are of a "last plus one" type;
12614 if so, when they are equal, the row is within the screen. -- rms. */
12615 if (MATRIX_ROW_BOTTOM_Y (row
) > last_y
)
12618 /* If it is in this row, return this row. */
12619 if (! (MATRIX_ROW_END_CHARPOS (row
) < charpos
12620 || (MATRIX_ROW_END_CHARPOS (row
) == charpos
12621 /* The end position of a row equals the start
12622 position of the next row. If CHARPOS is there, we
12623 would rather display it in the next line, except
12624 when this line ends in ZV. */
12625 && !row
->ends_at_zv_p
12626 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
)))
12627 && charpos
>= MATRIX_ROW_START_CHARPOS (row
))
12634 /* Try to redisplay window W by reusing its existing display. W's
12635 current matrix must be up to date when this function is called,
12636 i.e. window_end_valid must not be nil.
12640 1 if display has been updated
12641 0 if otherwise unsuccessful
12642 -1 if redisplay with same window start is known not to succeed
12644 The following steps are performed:
12646 1. Find the last row in the current matrix of W that is not
12647 affected by changes at the start of current_buffer. If no such row
12650 2. Find the first row in W's current matrix that is not affected by
12651 changes at the end of current_buffer. Maybe there is no such row.
12653 3. Display lines beginning with the row + 1 found in step 1 to the
12654 row found in step 2 or, if step 2 didn't find a row, to the end of
12657 4. If cursor is not known to appear on the window, give up.
12659 5. If display stopped at the row found in step 2, scroll the
12660 display and current matrix as needed.
12662 6. Maybe display some lines at the end of W, if we must. This can
12663 happen under various circumstances, like a partially visible line
12664 becoming fully visible, or because newly displayed lines are displayed
12665 in smaller font sizes.
12667 7. Update W's window end information. */
12673 struct frame
*f
= XFRAME (w
->frame
);
12674 struct glyph_matrix
*current_matrix
= w
->current_matrix
;
12675 struct glyph_matrix
*desired_matrix
= w
->desired_matrix
;
12676 struct glyph_row
*last_unchanged_at_beg_row
;
12677 struct glyph_row
*first_unchanged_at_end_row
;
12678 struct glyph_row
*row
;
12679 struct glyph_row
*bottom_row
;
12682 int delta
= 0, delta_bytes
= 0, stop_pos
, dvpos
, dy
;
12683 struct text_pos start_pos
;
12685 int first_unchanged_at_end_vpos
= 0;
12686 struct glyph_row
*last_text_row
, *last_text_row_at_end
;
12687 struct text_pos start
;
12688 int first_changed_charpos
, last_changed_charpos
;
12691 if (inhibit_try_window_id
)
12695 /* This is handy for debugging. */
12697 #define GIVE_UP(X) \
12699 fprintf (stderr, "try_window_id give up %d\n", (X)); \
12703 #define GIVE_UP(X) return 0
12706 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
12708 /* Don't use this for mini-windows because these can show
12709 messages and mini-buffers, and we don't handle that here. */
12710 if (MINI_WINDOW_P (w
))
12713 /* This flag is used to prevent redisplay optimizations. */
12714 if (windows_or_buffers_changed
|| cursor_type_changed
)
12717 /* Verify that narrowing has not changed.
12718 Also verify that we were not told to prevent redisplay optimizations.
12719 It would be nice to further
12720 reduce the number of cases where this prevents try_window_id. */
12721 if (current_buffer
->clip_changed
12722 || current_buffer
->prevent_redisplay_optimizations_p
)
12725 /* Window must either use window-based redisplay or be full width. */
12726 if (!FRAME_WINDOW_P (f
)
12727 && (!FRAME_LINE_INS_DEL_OK (f
)
12728 || !WINDOW_FULL_WIDTH_P (w
)))
12731 /* Give up if point is not known NOT to appear in W. */
12732 if (PT
< CHARPOS (start
))
12735 /* Another way to prevent redisplay optimizations. */
12736 if (XFASTINT (w
->last_modified
) == 0)
12739 /* Verify that window is not hscrolled. */
12740 if (XFASTINT (w
->hscroll
) != 0)
12743 /* Verify that display wasn't paused. */
12744 if (NILP (w
->window_end_valid
))
12747 /* Can't use this if highlighting a region because a cursor movement
12748 will do more than just set the cursor. */
12749 if (!NILP (Vtransient_mark_mode
)
12750 && !NILP (current_buffer
->mark_active
))
12753 /* Likewise if highlighting trailing whitespace. */
12754 if (!NILP (Vshow_trailing_whitespace
))
12757 /* Likewise if showing a region. */
12758 if (!NILP (w
->region_showing
))
12761 /* Can use this if overlay arrow position and or string have changed. */
12762 if (!EQ (last_arrow_position
, COERCE_MARKER (Voverlay_arrow_position
))
12763 || !EQ (last_arrow_string
, Voverlay_arrow_string
))
12767 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
12768 only if buffer has really changed. The reason is that the gap is
12769 initially at Z for freshly visited files. The code below would
12770 set end_unchanged to 0 in that case. */
12771 if (MODIFF
> SAVE_MODIFF
12772 /* This seems to happen sometimes after saving a buffer. */
12773 || BEG_UNCHANGED
+ END_UNCHANGED
> Z_BYTE
)
12775 if (GPT
- BEG
< BEG_UNCHANGED
)
12776 BEG_UNCHANGED
= GPT
- BEG
;
12777 if (Z
- GPT
< END_UNCHANGED
)
12778 END_UNCHANGED
= Z
- GPT
;
12781 /* The position of the first and last character that has been changed. */
12782 first_changed_charpos
= BEG
+ BEG_UNCHANGED
;
12783 last_changed_charpos
= Z
- END_UNCHANGED
;
12785 /* If window starts after a line end, and the last change is in
12786 front of that newline, then changes don't affect the display.
12787 This case happens with stealth-fontification. Note that although
12788 the display is unchanged, glyph positions in the matrix have to
12789 be adjusted, of course. */
12790 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
12791 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
)
12792 && ((last_changed_charpos
< CHARPOS (start
)
12793 && CHARPOS (start
) == BEGV
)
12794 || (last_changed_charpos
< CHARPOS (start
) - 1
12795 && FETCH_BYTE (BYTEPOS (start
) - 1) == '\n')))
12797 int Z_old
, delta
, Z_BYTE_old
, delta_bytes
;
12798 struct glyph_row
*r0
;
12800 /* Compute how many chars/bytes have been added to or removed
12801 from the buffer. */
12802 Z_old
= MATRIX_ROW_END_CHARPOS (row
) + XFASTINT (w
->window_end_pos
);
12803 Z_BYTE_old
= MATRIX_ROW_END_BYTEPOS (row
) + w
->window_end_bytepos
;
12805 delta_bytes
= Z_BYTE
- Z_BYTE_old
;
12807 /* Give up if PT is not in the window. Note that it already has
12808 been checked at the start of try_window_id that PT is not in
12809 front of the window start. */
12810 if (PT
>= MATRIX_ROW_END_CHARPOS (row
) + delta
)
12813 /* If window start is unchanged, we can reuse the whole matrix
12814 as is, after adjusting glyph positions. No need to compute
12815 the window end again, since its offset from Z hasn't changed. */
12816 r0
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
12817 if (CHARPOS (start
) == MATRIX_ROW_START_CHARPOS (r0
) + delta
12818 && BYTEPOS (start
) == MATRIX_ROW_START_BYTEPOS (r0
) + delta_bytes
12819 /* PT must not be in a partially visible line. */
12820 && !(PT
>= MATRIX_ROW_START_CHARPOS (row
) + delta
12821 && MATRIX_ROW_BOTTOM_Y (row
) > window_text_bottom_y (w
)))
12823 /* Adjust positions in the glyph matrix. */
12824 if (delta
|| delta_bytes
)
12826 struct glyph_row
*r1
12827 = MATRIX_BOTTOM_TEXT_ROW (current_matrix
, w
);
12828 increment_matrix_positions (w
->current_matrix
,
12829 MATRIX_ROW_VPOS (r0
, current_matrix
),
12830 MATRIX_ROW_VPOS (r1
, current_matrix
),
12831 delta
, delta_bytes
);
12834 /* Set the cursor. */
12835 row
= row_containing_pos (w
, PT
, r0
, NULL
, 0);
12837 set_cursor_from_row (w
, row
, current_matrix
, 0, 0, 0, 0);
12844 /* Handle the case that changes are all below what is displayed in
12845 the window, and that PT is in the window. This shortcut cannot
12846 be taken if ZV is visible in the window, and text has been added
12847 there that is visible in the window. */
12848 if (first_changed_charpos
>= MATRIX_ROW_END_CHARPOS (row
)
12849 /* ZV is not visible in the window, or there are no
12850 changes at ZV, actually. */
12851 && (current_matrix
->zv
> MATRIX_ROW_END_CHARPOS (row
)
12852 || first_changed_charpos
== last_changed_charpos
))
12854 struct glyph_row
*r0
;
12856 /* Give up if PT is not in the window. Note that it already has
12857 been checked at the start of try_window_id that PT is not in
12858 front of the window start. */
12859 if (PT
>= MATRIX_ROW_END_CHARPOS (row
))
12862 /* If window start is unchanged, we can reuse the whole matrix
12863 as is, without changing glyph positions since no text has
12864 been added/removed in front of the window end. */
12865 r0
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
12866 if (TEXT_POS_EQUAL_P (start
, r0
->start
.pos
)
12867 /* PT must not be in a partially visible line. */
12868 && !(PT
>= MATRIX_ROW_START_CHARPOS (row
)
12869 && MATRIX_ROW_BOTTOM_Y (row
) > window_text_bottom_y (w
)))
12871 /* We have to compute the window end anew since text
12872 can have been added/removed after it. */
12874 = make_number (Z
- MATRIX_ROW_END_CHARPOS (row
));
12875 w
->window_end_bytepos
12876 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
12878 /* Set the cursor. */
12879 row
= row_containing_pos (w
, PT
, r0
, NULL
, 0);
12881 set_cursor_from_row (w
, row
, current_matrix
, 0, 0, 0, 0);
12888 /* Give up if window start is in the changed area.
12890 The condition used to read
12892 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
12894 but why that was tested escapes me at the moment. */
12895 if (CHARPOS (start
) >= first_changed_charpos
12896 && CHARPOS (start
) <= last_changed_charpos
)
12899 /* Check that window start agrees with the start of the first glyph
12900 row in its current matrix. Check this after we know the window
12901 start is not in changed text, otherwise positions would not be
12903 row
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
12904 if (!TEXT_POS_EQUAL_P (start
, row
->start
.pos
))
12907 /* Give up if the window ends in strings. Overlay strings
12908 at the end are difficult to handle, so don't try. */
12909 row
= MATRIX_ROW (current_matrix
, XFASTINT (w
->window_end_vpos
));
12910 if (MATRIX_ROW_START_CHARPOS (row
) == MATRIX_ROW_END_CHARPOS (row
))
12913 /* Compute the position at which we have to start displaying new
12914 lines. Some of the lines at the top of the window might be
12915 reusable because they are not displaying changed text. Find the
12916 last row in W's current matrix not affected by changes at the
12917 start of current_buffer. Value is null if changes start in the
12918 first line of window. */
12919 last_unchanged_at_beg_row
= find_last_unchanged_at_beg_row (w
);
12920 if (last_unchanged_at_beg_row
)
12922 /* Avoid starting to display in the moddle of a character, a TAB
12923 for instance. This is easier than to set up the iterator
12924 exactly, and it's not a frequent case, so the additional
12925 effort wouldn't really pay off. */
12926 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row
)
12927 || last_unchanged_at_beg_row
->ends_in_newline_from_string_p
)
12928 && last_unchanged_at_beg_row
> w
->current_matrix
->rows
)
12929 --last_unchanged_at_beg_row
;
12931 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row
))
12934 if (init_to_row_end (&it
, w
, last_unchanged_at_beg_row
) == 0)
12936 start_pos
= it
.current
.pos
;
12938 /* Start displaying new lines in the desired matrix at the same
12939 vpos we would use in the current matrix, i.e. below
12940 last_unchanged_at_beg_row. */
12941 it
.vpos
= 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row
,
12943 it
.glyph_row
= MATRIX_ROW (desired_matrix
, it
.vpos
);
12944 it
.current_y
= MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row
);
12946 xassert (it
.hpos
== 0 && it
.current_x
== 0);
12950 /* There are no reusable lines at the start of the window.
12951 Start displaying in the first text line. */
12952 start_display (&it
, w
, start
);
12953 it
.vpos
= it
.first_vpos
;
12954 start_pos
= it
.current
.pos
;
12957 /* Find the first row that is not affected by changes at the end of
12958 the buffer. Value will be null if there is no unchanged row, in
12959 which case we must redisplay to the end of the window. delta
12960 will be set to the value by which buffer positions beginning with
12961 first_unchanged_at_end_row have to be adjusted due to text
12963 first_unchanged_at_end_row
12964 = find_first_unchanged_at_end_row (w
, &delta
, &delta_bytes
);
12965 IF_DEBUG (debug_delta
= delta
);
12966 IF_DEBUG (debug_delta_bytes
= delta_bytes
);
12968 /* Set stop_pos to the buffer position up to which we will have to
12969 display new lines. If first_unchanged_at_end_row != NULL, this
12970 is the buffer position of the start of the line displayed in that
12971 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
12972 that we don't stop at a buffer position. */
12974 if (first_unchanged_at_end_row
)
12976 xassert (last_unchanged_at_beg_row
== NULL
12977 || first_unchanged_at_end_row
>= last_unchanged_at_beg_row
);
12979 /* If this is a continuation line, move forward to the next one
12980 that isn't. Changes in lines above affect this line.
12981 Caution: this may move first_unchanged_at_end_row to a row
12982 not displaying text. */
12983 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row
)
12984 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
)
12985 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row
)
12986 < it
.last_visible_y
))
12987 ++first_unchanged_at_end_row
;
12989 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
)
12990 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row
)
12991 >= it
.last_visible_y
))
12992 first_unchanged_at_end_row
= NULL
;
12995 stop_pos
= (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row
)
12997 first_unchanged_at_end_vpos
12998 = MATRIX_ROW_VPOS (first_unchanged_at_end_row
, current_matrix
);
12999 xassert (stop_pos
>= Z
- END_UNCHANGED
);
13002 else if (last_unchanged_at_beg_row
== NULL
)
13008 /* Either there is no unchanged row at the end, or the one we have
13009 now displays text. This is a necessary condition for the window
13010 end pos calculation at the end of this function. */
13011 xassert (first_unchanged_at_end_row
== NULL
13012 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
));
13014 debug_last_unchanged_at_beg_vpos
13015 = (last_unchanged_at_beg_row
13016 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row
, current_matrix
)
13018 debug_first_unchanged_at_end_vpos
= first_unchanged_at_end_vpos
;
13020 #endif /* GLYPH_DEBUG != 0 */
13023 /* Display new lines. Set last_text_row to the last new line
13024 displayed which has text on it, i.e. might end up as being the
13025 line where the window_end_vpos is. */
13026 w
->cursor
.vpos
= -1;
13027 last_text_row
= NULL
;
13028 overlay_arrow_seen
= 0;
13029 while (it
.current_y
< it
.last_visible_y
13030 && !fonts_changed_p
13031 && (first_unchanged_at_end_row
== NULL
13032 || IT_CHARPOS (it
) < stop_pos
))
13034 if (display_line (&it
))
13035 last_text_row
= it
.glyph_row
- 1;
13038 if (fonts_changed_p
)
13042 /* Compute differences in buffer positions, y-positions etc. for
13043 lines reused at the bottom of the window. Compute what we can
13045 if (first_unchanged_at_end_row
13046 /* No lines reused because we displayed everything up to the
13047 bottom of the window. */
13048 && it
.current_y
< it
.last_visible_y
)
13051 - MATRIX_ROW_VPOS (first_unchanged_at_end_row
,
13053 dy
= it
.current_y
- first_unchanged_at_end_row
->y
;
13054 run
.current_y
= first_unchanged_at_end_row
->y
;
13055 run
.desired_y
= run
.current_y
+ dy
;
13056 run
.height
= it
.last_visible_y
- max (run
.current_y
, run
.desired_y
);
13060 delta
= dvpos
= dy
= run
.current_y
= run
.desired_y
= run
.height
= 0;
13061 first_unchanged_at_end_row
= NULL
;
13063 IF_DEBUG (debug_dvpos
= dvpos
; debug_dy
= dy
);
13066 /* Find the cursor if not already found. We have to decide whether
13067 PT will appear on this window (it sometimes doesn't, but this is
13068 not a very frequent case.) This decision has to be made before
13069 the current matrix is altered. A value of cursor.vpos < 0 means
13070 that PT is either in one of the lines beginning at
13071 first_unchanged_at_end_row or below the window. Don't care for
13072 lines that might be displayed later at the window end; as
13073 mentioned, this is not a frequent case. */
13074 if (w
->cursor
.vpos
< 0)
13076 /* Cursor in unchanged rows at the top? */
13077 if (PT
< CHARPOS (start_pos
)
13078 && last_unchanged_at_beg_row
)
13080 row
= row_containing_pos (w
, PT
,
13081 MATRIX_FIRST_TEXT_ROW (w
->current_matrix
),
13082 last_unchanged_at_beg_row
+ 1, 0);
13084 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
13087 /* Start from first_unchanged_at_end_row looking for PT. */
13088 else if (first_unchanged_at_end_row
)
13090 row
= row_containing_pos (w
, PT
- delta
,
13091 first_unchanged_at_end_row
, NULL
, 0);
13093 set_cursor_from_row (w
, row
, w
->current_matrix
, delta
,
13094 delta_bytes
, dy
, dvpos
);
13097 /* Give up if cursor was not found. */
13098 if (w
->cursor
.vpos
< 0)
13100 clear_glyph_matrix (w
->desired_matrix
);
13105 /* Don't let the cursor end in the scroll margins. */
13107 int this_scroll_margin
, cursor_height
;
13109 this_scroll_margin
= max (0, scroll_margin
);
13110 this_scroll_margin
= min (this_scroll_margin
, WINDOW_TOTAL_LINES (w
) / 4);
13111 this_scroll_margin
*= FRAME_LINE_HEIGHT (it
.f
);
13112 cursor_height
= MATRIX_ROW (w
->desired_matrix
, w
->cursor
.vpos
)->height
;
13114 if ((w
->cursor
.y
< this_scroll_margin
13115 && CHARPOS (start
) > BEGV
)
13116 /* Don't take scroll margin into account at the bottom because
13117 old redisplay didn't do it either. */
13118 || w
->cursor
.y
+ cursor_height
> it
.last_visible_y
)
13120 w
->cursor
.vpos
= -1;
13121 clear_glyph_matrix (w
->desired_matrix
);
13126 /* Scroll the display. Do it before changing the current matrix so
13127 that xterm.c doesn't get confused about where the cursor glyph is
13129 if (dy
&& run
.height
)
13133 if (FRAME_WINDOW_P (f
))
13135 FRAME_RIF (f
)->update_window_begin_hook (w
);
13136 FRAME_RIF (f
)->clear_window_mouse_face (w
);
13137 FRAME_RIF (f
)->scroll_run_hook (w
, &run
);
13138 FRAME_RIF (f
)->update_window_end_hook (w
, 0, 0);
13142 /* Terminal frame. In this case, dvpos gives the number of
13143 lines to scroll by; dvpos < 0 means scroll up. */
13144 int first_unchanged_at_end_vpos
13145 = MATRIX_ROW_VPOS (first_unchanged_at_end_row
, w
->current_matrix
);
13146 int from
= WINDOW_TOP_EDGE_LINE (w
) + first_unchanged_at_end_vpos
;
13147 int end
= (WINDOW_TOP_EDGE_LINE (w
)
13148 + (WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0)
13149 + window_internal_height (w
));
13151 /* Perform the operation on the screen. */
13154 /* Scroll last_unchanged_at_beg_row to the end of the
13155 window down dvpos lines. */
13156 set_terminal_window (end
);
13158 /* On dumb terminals delete dvpos lines at the end
13159 before inserting dvpos empty lines. */
13160 if (!FRAME_SCROLL_REGION_OK (f
))
13161 ins_del_lines (end
- dvpos
, -dvpos
);
13163 /* Insert dvpos empty lines in front of
13164 last_unchanged_at_beg_row. */
13165 ins_del_lines (from
, dvpos
);
13167 else if (dvpos
< 0)
13169 /* Scroll up last_unchanged_at_beg_vpos to the end of
13170 the window to last_unchanged_at_beg_vpos - |dvpos|. */
13171 set_terminal_window (end
);
13173 /* Delete dvpos lines in front of
13174 last_unchanged_at_beg_vpos. ins_del_lines will set
13175 the cursor to the given vpos and emit |dvpos| delete
13177 ins_del_lines (from
+ dvpos
, dvpos
);
13179 /* On a dumb terminal insert dvpos empty lines at the
13181 if (!FRAME_SCROLL_REGION_OK (f
))
13182 ins_del_lines (end
+ dvpos
, -dvpos
);
13185 set_terminal_window (0);
13191 /* Shift reused rows of the current matrix to the right position.
13192 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
13194 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (current_matrix
, w
);
13195 bottom_vpos
= MATRIX_ROW_VPOS (bottom_row
, current_matrix
);
13198 rotate_matrix (current_matrix
, first_unchanged_at_end_vpos
+ dvpos
,
13199 bottom_vpos
, dvpos
);
13200 enable_glyph_matrix_rows (current_matrix
, bottom_vpos
+ dvpos
,
13203 else if (dvpos
> 0)
13205 rotate_matrix (current_matrix
, first_unchanged_at_end_vpos
,
13206 bottom_vpos
, dvpos
);
13207 enable_glyph_matrix_rows (current_matrix
, first_unchanged_at_end_vpos
,
13208 first_unchanged_at_end_vpos
+ dvpos
, 0);
13211 /* For frame-based redisplay, make sure that current frame and window
13212 matrix are in sync with respect to glyph memory. */
13213 if (!FRAME_WINDOW_P (f
))
13214 sync_frame_with_window_matrix_rows (w
);
13216 /* Adjust buffer positions in reused rows. */
13218 increment_matrix_positions (current_matrix
,
13219 first_unchanged_at_end_vpos
+ dvpos
,
13220 bottom_vpos
, delta
, delta_bytes
);
13222 /* Adjust Y positions. */
13224 shift_glyph_matrix (w
, current_matrix
,
13225 first_unchanged_at_end_vpos
+ dvpos
,
13228 if (first_unchanged_at_end_row
)
13229 first_unchanged_at_end_row
+= dvpos
;
13231 /* If scrolling up, there may be some lines to display at the end of
13233 last_text_row_at_end
= NULL
;
13236 /* Scrolling up can leave for example a partially visible line
13237 at the end of the window to be redisplayed. */
13238 /* Set last_row to the glyph row in the current matrix where the
13239 window end line is found. It has been moved up or down in
13240 the matrix by dvpos. */
13241 int last_vpos
= XFASTINT (w
->window_end_vpos
) + dvpos
;
13242 struct glyph_row
*last_row
= MATRIX_ROW (current_matrix
, last_vpos
);
13244 /* If last_row is the window end line, it should display text. */
13245 xassert (last_row
->displays_text_p
);
13247 /* If window end line was partially visible before, begin
13248 displaying at that line. Otherwise begin displaying with the
13249 line following it. */
13250 if (MATRIX_ROW_BOTTOM_Y (last_row
) - dy
>= it
.last_visible_y
)
13252 init_to_row_start (&it
, w
, last_row
);
13253 it
.vpos
= last_vpos
;
13254 it
.current_y
= last_row
->y
;
13258 init_to_row_end (&it
, w
, last_row
);
13259 it
.vpos
= 1 + last_vpos
;
13260 it
.current_y
= MATRIX_ROW_BOTTOM_Y (last_row
);
13264 /* We may start in a continuation line. If so, we have to
13265 get the right continuation_lines_width and current_x. */
13266 it
.continuation_lines_width
= last_row
->continuation_lines_width
;
13267 it
.hpos
= it
.current_x
= 0;
13269 /* Display the rest of the lines at the window end. */
13270 it
.glyph_row
= MATRIX_ROW (desired_matrix
, it
.vpos
);
13271 while (it
.current_y
< it
.last_visible_y
13272 && !fonts_changed_p
)
13274 /* Is it always sure that the display agrees with lines in
13275 the current matrix? I don't think so, so we mark rows
13276 displayed invalid in the current matrix by setting their
13277 enabled_p flag to zero. */
13278 MATRIX_ROW (w
->current_matrix
, it
.vpos
)->enabled_p
= 0;
13279 if (display_line (&it
))
13280 last_text_row_at_end
= it
.glyph_row
- 1;
13284 /* Update window_end_pos and window_end_vpos. */
13285 if (first_unchanged_at_end_row
13286 && first_unchanged_at_end_row
->y
< it
.last_visible_y
13287 && !last_text_row_at_end
)
13289 /* Window end line if one of the preserved rows from the current
13290 matrix. Set row to the last row displaying text in current
13291 matrix starting at first_unchanged_at_end_row, after
13293 xassert (first_unchanged_at_end_row
->displays_text_p
);
13294 row
= find_last_row_displaying_text (w
->current_matrix
, &it
,
13295 first_unchanged_at_end_row
);
13296 xassert (row
&& MATRIX_ROW_DISPLAYS_TEXT_P (row
));
13298 w
->window_end_pos
= make_number (Z
- MATRIX_ROW_END_CHARPOS (row
));
13299 w
->window_end_bytepos
= Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
13301 = make_number (MATRIX_ROW_VPOS (row
, w
->current_matrix
));
13302 xassert (w
->window_end_bytepos
>= 0);
13303 IF_DEBUG (debug_method_add (w
, "A"));
13305 else if (last_text_row_at_end
)
13308 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row_at_end
));
13309 w
->window_end_bytepos
13310 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row_at_end
);
13312 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end
, desired_matrix
));
13313 xassert (w
->window_end_bytepos
>= 0);
13314 IF_DEBUG (debug_method_add (w
, "B"));
13316 else if (last_text_row
)
13318 /* We have displayed either to the end of the window or at the
13319 end of the window, i.e. the last row with text is to be found
13320 in the desired matrix. */
13322 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
13323 w
->window_end_bytepos
13324 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
13326 = make_number (MATRIX_ROW_VPOS (last_text_row
, desired_matrix
));
13327 xassert (w
->window_end_bytepos
>= 0);
13329 else if (first_unchanged_at_end_row
== NULL
13330 && last_text_row
== NULL
13331 && last_text_row_at_end
== NULL
)
13333 /* Displayed to end of window, but no line containing text was
13334 displayed. Lines were deleted at the end of the window. */
13335 int first_vpos
= WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0;
13336 int vpos
= XFASTINT (w
->window_end_vpos
);
13337 struct glyph_row
*current_row
= current_matrix
->rows
+ vpos
;
13338 struct glyph_row
*desired_row
= desired_matrix
->rows
+ vpos
;
13341 row
== NULL
&& vpos
>= first_vpos
;
13342 --vpos
, --current_row
, --desired_row
)
13344 if (desired_row
->enabled_p
)
13346 if (desired_row
->displays_text_p
)
13349 else if (current_row
->displays_text_p
)
13353 xassert (row
!= NULL
);
13354 w
->window_end_vpos
= make_number (vpos
+ 1);
13355 w
->window_end_pos
= make_number (Z
- MATRIX_ROW_END_CHARPOS (row
));
13356 w
->window_end_bytepos
= Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
13357 xassert (w
->window_end_bytepos
>= 0);
13358 IF_DEBUG (debug_method_add (w
, "C"));
13363 #if 0 /* This leads to problems, for instance when the cursor is
13364 at ZV, and the cursor line displays no text. */
13365 /* Disable rows below what's displayed in the window. This makes
13366 debugging easier. */
13367 enable_glyph_matrix_rows (current_matrix
,
13368 XFASTINT (w
->window_end_vpos
) + 1,
13372 IF_DEBUG (debug_end_pos
= XFASTINT (w
->window_end_pos
);
13373 debug_end_vpos
= XFASTINT (w
->window_end_vpos
));
13375 /* Record that display has not been completed. */
13376 w
->window_end_valid
= Qnil
;
13377 w
->desired_matrix
->no_scrolling_p
= 1;
13385 /***********************************************************************
13386 More debugging support
13387 ***********************************************************************/
13391 void dump_glyph_row
P_ ((struct glyph_row
*, int, int));
13392 void dump_glyph_matrix
P_ ((struct glyph_matrix
*, int));
13393 void dump_glyph
P_ ((struct glyph_row
*, struct glyph
*, int));
13396 /* Dump the contents of glyph matrix MATRIX on stderr.
13398 GLYPHS 0 means don't show glyph contents.
13399 GLYPHS 1 means show glyphs in short form
13400 GLYPHS > 1 means show glyphs in long form. */
13403 dump_glyph_matrix (matrix
, glyphs
)
13404 struct glyph_matrix
*matrix
;
13408 for (i
= 0; i
< matrix
->nrows
; ++i
)
13409 dump_glyph_row (MATRIX_ROW (matrix
, i
), i
, glyphs
);
13413 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
13414 the glyph row and area where the glyph comes from. */
13417 dump_glyph (row
, glyph
, area
)
13418 struct glyph_row
*row
;
13419 struct glyph
*glyph
;
13422 if (glyph
->type
== CHAR_GLYPH
)
13425 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13426 glyph
- row
->glyphs
[TEXT_AREA
],
13429 (BUFFERP (glyph
->object
)
13431 : (STRINGP (glyph
->object
)
13434 glyph
->pixel_width
,
13436 (glyph
->u
.ch
< 0x80 && glyph
->u
.ch
>= ' '
13440 glyph
->left_box_line_p
,
13441 glyph
->right_box_line_p
);
13443 else if (glyph
->type
== STRETCH_GLYPH
)
13446 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13447 glyph
- row
->glyphs
[TEXT_AREA
],
13450 (BUFFERP (glyph
->object
)
13452 : (STRINGP (glyph
->object
)
13455 glyph
->pixel_width
,
13459 glyph
->left_box_line_p
,
13460 glyph
->right_box_line_p
);
13462 else if (glyph
->type
== IMAGE_GLYPH
)
13465 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13466 glyph
- row
->glyphs
[TEXT_AREA
],
13469 (BUFFERP (glyph
->object
)
13471 : (STRINGP (glyph
->object
)
13474 glyph
->pixel_width
,
13478 glyph
->left_box_line_p
,
13479 glyph
->right_box_line_p
);
13484 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
13485 GLYPHS 0 means don't show glyph contents.
13486 GLYPHS 1 means show glyphs in short form
13487 GLYPHS > 1 means show glyphs in long form. */
13490 dump_glyph_row (row
, vpos
, glyphs
)
13491 struct glyph_row
*row
;
13496 fprintf (stderr
, "Row Start End Used oEI><O\\CTZFesm X Y W H V A P\n");
13497 fprintf (stderr
, "=======================================================================\n");
13499 fprintf (stderr
, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d%1.1d\
13500 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
13502 MATRIX_ROW_START_CHARPOS (row
),
13503 MATRIX_ROW_END_CHARPOS (row
),
13504 row
->used
[TEXT_AREA
],
13505 row
->contains_overlapping_glyphs_p
,
13507 row
->truncated_on_left_p
,
13508 row
->truncated_on_right_p
,
13509 row
->overlay_arrow_p
,
13511 MATRIX_ROW_CONTINUATION_LINE_P (row
),
13512 row
->displays_text_p
,
13515 row
->ends_in_middle_of_char_p
,
13516 row
->starts_in_middle_of_char_p
,
13522 row
->visible_height
,
13525 fprintf (stderr
, "%9d %5d\t%5d\n", row
->start
.overlay_string_index
,
13526 row
->end
.overlay_string_index
,
13527 row
->continuation_lines_width
);
13528 fprintf (stderr
, "%9d %5d\n",
13529 CHARPOS (row
->start
.string_pos
),
13530 CHARPOS (row
->end
.string_pos
));
13531 fprintf (stderr
, "%9d %5d\n", row
->start
.dpvec_index
,
13532 row
->end
.dpvec_index
);
13539 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
13541 struct glyph
*glyph
= row
->glyphs
[area
];
13542 struct glyph
*glyph_end
= glyph
+ row
->used
[area
];
13544 /* Glyph for a line end in text. */
13545 if (area
== TEXT_AREA
&& glyph
== glyph_end
&& glyph
->charpos
> 0)
13548 if (glyph
< glyph_end
)
13549 fprintf (stderr
, " Glyph Type Pos O W Code C Face LR\n");
13551 for (; glyph
< glyph_end
; ++glyph
)
13552 dump_glyph (row
, glyph
, area
);
13555 else if (glyphs
== 1)
13559 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
13561 char *s
= (char *) alloca (row
->used
[area
] + 1);
13564 for (i
= 0; i
< row
->used
[area
]; ++i
)
13566 struct glyph
*glyph
= row
->glyphs
[area
] + i
;
13567 if (glyph
->type
== CHAR_GLYPH
13568 && glyph
->u
.ch
< 0x80
13569 && glyph
->u
.ch
>= ' ')
13570 s
[i
] = glyph
->u
.ch
;
13576 fprintf (stderr
, "%3d: (%d) '%s'\n", vpos
, row
->enabled_p
, s
);
13582 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix
,
13583 Sdump_glyph_matrix
, 0, 1, "p",
13584 doc
: /* Dump the current matrix of the selected window to stderr.
13585 Shows contents of glyph row structures. With non-nil
13586 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
13587 glyphs in short form, otherwise show glyphs in long form. */)
13589 Lisp_Object glyphs
;
13591 struct window
*w
= XWINDOW (selected_window
);
13592 struct buffer
*buffer
= XBUFFER (w
->buffer
);
13594 fprintf (stderr
, "PT = %d, BEGV = %d. ZV = %d\n",
13595 BUF_PT (buffer
), BUF_BEGV (buffer
), BUF_ZV (buffer
));
13596 fprintf (stderr
, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
13597 w
->cursor
.x
, w
->cursor
.y
, w
->cursor
.hpos
, w
->cursor
.vpos
);
13598 fprintf (stderr
, "=============================================\n");
13599 dump_glyph_matrix (w
->current_matrix
,
13600 NILP (glyphs
) ? 0 : XINT (glyphs
));
13605 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix
,
13606 Sdump_frame_glyph_matrix
, 0, 0, "", doc
: /* */)
13609 struct frame
*f
= XFRAME (selected_frame
);
13610 dump_glyph_matrix (f
->current_matrix
, 1);
13615 DEFUN ("dump-glyph-row", Fdump_glyph_row
, Sdump_glyph_row
, 1, 2, "",
13616 doc
: /* Dump glyph row ROW to stderr.
13617 GLYPH 0 means don't dump glyphs.
13618 GLYPH 1 means dump glyphs in short form.
13619 GLYPH > 1 or omitted means dump glyphs in long form. */)
13621 Lisp_Object row
, glyphs
;
13623 struct glyph_matrix
*matrix
;
13626 CHECK_NUMBER (row
);
13627 matrix
= XWINDOW (selected_window
)->current_matrix
;
13629 if (vpos
>= 0 && vpos
< matrix
->nrows
)
13630 dump_glyph_row (MATRIX_ROW (matrix
, vpos
),
13632 INTEGERP (glyphs
) ? XINT (glyphs
) : 2);
13637 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row
, Sdump_tool_bar_row
, 1, 2, "",
13638 doc
: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
13639 GLYPH 0 means don't dump glyphs.
13640 GLYPH 1 means dump glyphs in short form.
13641 GLYPH > 1 or omitted means dump glyphs in long form. */)
13643 Lisp_Object row
, glyphs
;
13645 struct frame
*sf
= SELECTED_FRAME ();
13646 struct glyph_matrix
*m
= XWINDOW (sf
->tool_bar_window
)->current_matrix
;
13649 CHECK_NUMBER (row
);
13651 if (vpos
>= 0 && vpos
< m
->nrows
)
13652 dump_glyph_row (MATRIX_ROW (m
, vpos
), vpos
,
13653 INTEGERP (glyphs
) ? XINT (glyphs
) : 2);
13658 DEFUN ("trace-redisplay", Ftrace_redisplay
, Strace_redisplay
, 0, 1, "P",
13659 doc
: /* Toggle tracing of redisplay.
13660 With ARG, turn tracing on if and only if ARG is positive. */)
13665 trace_redisplay_p
= !trace_redisplay_p
;
13668 arg
= Fprefix_numeric_value (arg
);
13669 trace_redisplay_p
= XINT (arg
) > 0;
13676 DEFUN ("trace-to-stderr", Ftrace_to_stderr
, Strace_to_stderr
, 1, MANY
, "",
13677 doc
: /* Like `format', but print result to stderr.
13678 usage: (trace-to-stderr STRING &rest OBJECTS) */)
13683 Lisp_Object s
= Fformat (nargs
, args
);
13684 fprintf (stderr
, "%s", SDATA (s
));
13688 #endif /* GLYPH_DEBUG */
13692 /***********************************************************************
13693 Building Desired Matrix Rows
13694 ***********************************************************************/
13696 /* Return a temporary glyph row holding the glyphs of an overlay
13697 arrow. Only used for non-window-redisplay windows. */
13699 static struct glyph_row
*
13700 get_overlay_arrow_glyph_row (w
)
13703 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
13704 struct buffer
*buffer
= XBUFFER (w
->buffer
);
13705 struct buffer
*old
= current_buffer
;
13706 const unsigned char *arrow_string
= SDATA (Voverlay_arrow_string
);
13707 int arrow_len
= SCHARS (Voverlay_arrow_string
);
13708 const unsigned char *arrow_end
= arrow_string
+ arrow_len
;
13709 const unsigned char *p
;
13712 int n_glyphs_before
;
13714 set_buffer_temp (buffer
);
13715 init_iterator (&it
, w
, -1, -1, &scratch_glyph_row
, DEFAULT_FACE_ID
);
13716 it
.glyph_row
->used
[TEXT_AREA
] = 0;
13717 SET_TEXT_POS (it
.position
, 0, 0);
13719 multibyte_p
= !NILP (buffer
->enable_multibyte_characters
);
13721 while (p
< arrow_end
)
13723 Lisp_Object face
, ilisp
;
13725 /* Get the next character. */
13727 it
.c
= string_char_and_length (p
, arrow_len
, &it
.len
);
13729 it
.c
= *p
, it
.len
= 1;
13732 /* Get its face. */
13733 ilisp
= make_number (p
- arrow_string
);
13734 face
= Fget_text_property (ilisp
, Qface
, Voverlay_arrow_string
);
13735 it
.face_id
= compute_char_face (f
, it
.c
, face
);
13737 /* Compute its width, get its glyphs. */
13738 n_glyphs_before
= it
.glyph_row
->used
[TEXT_AREA
];
13739 SET_TEXT_POS (it
.position
, -1, -1);
13740 PRODUCE_GLYPHS (&it
);
13742 /* If this character doesn't fit any more in the line, we have
13743 to remove some glyphs. */
13744 if (it
.current_x
> it
.last_visible_x
)
13746 it
.glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
;
13751 set_buffer_temp (old
);
13752 return it
.glyph_row
;
13756 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
13757 glyphs are only inserted for terminal frames since we can't really
13758 win with truncation glyphs when partially visible glyphs are
13759 involved. Which glyphs to insert is determined by
13760 produce_special_glyphs. */
13763 insert_left_trunc_glyphs (it
)
13766 struct it truncate_it
;
13767 struct glyph
*from
, *end
, *to
, *toend
;
13769 xassert (!FRAME_WINDOW_P (it
->f
));
13771 /* Get the truncation glyphs. */
13773 truncate_it
.current_x
= 0;
13774 truncate_it
.face_id
= DEFAULT_FACE_ID
;
13775 truncate_it
.glyph_row
= &scratch_glyph_row
;
13776 truncate_it
.glyph_row
->used
[TEXT_AREA
] = 0;
13777 CHARPOS (truncate_it
.position
) = BYTEPOS (truncate_it
.position
) = -1;
13778 truncate_it
.object
= make_number (0);
13779 produce_special_glyphs (&truncate_it
, IT_TRUNCATION
);
13781 /* Overwrite glyphs from IT with truncation glyphs. */
13782 from
= truncate_it
.glyph_row
->glyphs
[TEXT_AREA
];
13783 end
= from
+ truncate_it
.glyph_row
->used
[TEXT_AREA
];
13784 to
= it
->glyph_row
->glyphs
[TEXT_AREA
];
13785 toend
= to
+ it
->glyph_row
->used
[TEXT_AREA
];
13790 /* There may be padding glyphs left over. Overwrite them too. */
13791 while (to
< toend
&& CHAR_GLYPH_PADDING_P (*to
))
13793 from
= truncate_it
.glyph_row
->glyphs
[TEXT_AREA
];
13799 it
->glyph_row
->used
[TEXT_AREA
] = to
- it
->glyph_row
->glyphs
[TEXT_AREA
];
13803 /* Compute the pixel height and width of IT->glyph_row.
13805 Most of the time, ascent and height of a display line will be equal
13806 to the max_ascent and max_height values of the display iterator
13807 structure. This is not the case if
13809 1. We hit ZV without displaying anything. In this case, max_ascent
13810 and max_height will be zero.
13812 2. We have some glyphs that don't contribute to the line height.
13813 (The glyph row flag contributes_to_line_height_p is for future
13814 pixmap extensions).
13816 The first case is easily covered by using default values because in
13817 these cases, the line height does not really matter, except that it
13818 must not be zero. */
13821 compute_line_metrics (it
)
13824 struct glyph_row
*row
= it
->glyph_row
;
13827 if (FRAME_WINDOW_P (it
->f
))
13829 int i
, min_y
, max_y
;
13831 /* The line may consist of one space only, that was added to
13832 place the cursor on it. If so, the row's height hasn't been
13834 if (row
->height
== 0)
13836 if (it
->max_ascent
+ it
->max_descent
== 0)
13837 it
->max_descent
= it
->max_phys_descent
= FRAME_LINE_HEIGHT (it
->f
);
13838 row
->ascent
= it
->max_ascent
;
13839 row
->height
= it
->max_ascent
+ it
->max_descent
;
13840 row
->phys_ascent
= it
->max_phys_ascent
;
13841 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
13844 /* Compute the width of this line. */
13845 row
->pixel_width
= row
->x
;
13846 for (i
= 0; i
< row
->used
[TEXT_AREA
]; ++i
)
13847 row
->pixel_width
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
13849 xassert (row
->pixel_width
>= 0);
13850 xassert (row
->ascent
>= 0 && row
->height
> 0);
13852 row
->overlapping_p
= (MATRIX_ROW_OVERLAPS_SUCC_P (row
)
13853 || MATRIX_ROW_OVERLAPS_PRED_P (row
));
13855 /* If first line's physical ascent is larger than its logical
13856 ascent, use the physical ascent, and make the row taller.
13857 This makes accented characters fully visible. */
13858 if (row
== MATRIX_FIRST_TEXT_ROW (it
->w
->desired_matrix
)
13859 && row
->phys_ascent
> row
->ascent
)
13861 row
->height
+= row
->phys_ascent
- row
->ascent
;
13862 row
->ascent
= row
->phys_ascent
;
13865 /* Compute how much of the line is visible. */
13866 row
->visible_height
= row
->height
;
13868 min_y
= WINDOW_HEADER_LINE_HEIGHT (it
->w
);
13869 max_y
= WINDOW_BOX_HEIGHT_NO_MODE_LINE (it
->w
);
13871 if (row
->y
< min_y
)
13872 row
->visible_height
-= min_y
- row
->y
;
13873 if (row
->y
+ row
->height
> max_y
)
13874 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
13878 row
->pixel_width
= row
->used
[TEXT_AREA
];
13879 if (row
->continued_p
)
13880 row
->pixel_width
-= it
->continuation_pixel_width
;
13881 else if (row
->truncated_on_right_p
)
13882 row
->pixel_width
-= it
->truncation_pixel_width
;
13883 row
->ascent
= row
->phys_ascent
= 0;
13884 row
->height
= row
->phys_height
= row
->visible_height
= 1;
13887 /* Compute a hash code for this row. */
13889 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
13890 for (i
= 0; i
< row
->used
[area
]; ++i
)
13891 row
->hash
= ((((row
->hash
<< 4) + (row
->hash
>> 24)) & 0x0fffffff)
13892 + row
->glyphs
[area
][i
].u
.val
13893 + row
->glyphs
[area
][i
].face_id
13894 + row
->glyphs
[area
][i
].padding_p
13895 + (row
->glyphs
[area
][i
].type
<< 2));
13897 it
->max_ascent
= it
->max_descent
= 0;
13898 it
->max_phys_ascent
= it
->max_phys_descent
= 0;
13902 /* Append one space to the glyph row of iterator IT if doing a
13903 window-based redisplay. DEFAULT_FACE_P non-zero means let the
13904 space have the default face, otherwise let it have the same face as
13905 IT->face_id. Value is non-zero if a space was added.
13907 This function is called to make sure that there is always one glyph
13908 at the end of a glyph row that the cursor can be set on under
13909 window-systems. (If there weren't such a glyph we would not know
13910 how wide and tall a box cursor should be displayed).
13912 At the same time this space let's a nicely handle clearing to the
13913 end of the line if the row ends in italic text. */
13916 append_space (it
, default_face_p
)
13918 int default_face_p
;
13920 if (FRAME_WINDOW_P (it
->f
))
13922 int n
= it
->glyph_row
->used
[TEXT_AREA
];
13924 if (it
->glyph_row
->glyphs
[TEXT_AREA
] + n
13925 < it
->glyph_row
->glyphs
[1 + TEXT_AREA
])
13927 /* Save some values that must not be changed.
13928 Must save IT->c and IT->len because otherwise
13929 ITERATOR_AT_END_P wouldn't work anymore after
13930 append_space has been called. */
13931 enum display_element_type saved_what
= it
->what
;
13932 int saved_c
= it
->c
, saved_len
= it
->len
;
13933 int saved_x
= it
->current_x
;
13934 int saved_face_id
= it
->face_id
;
13935 struct text_pos saved_pos
;
13936 Lisp_Object saved_object
;
13939 saved_object
= it
->object
;
13940 saved_pos
= it
->position
;
13942 it
->what
= IT_CHARACTER
;
13943 bzero (&it
->position
, sizeof it
->position
);
13944 it
->object
= make_number (0);
13948 if (default_face_p
)
13949 it
->face_id
= DEFAULT_FACE_ID
;
13950 else if (it
->face_before_selective_p
)
13951 it
->face_id
= it
->saved_face_id
;
13952 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
13953 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, 0);
13955 PRODUCE_GLYPHS (it
);
13957 it
->current_x
= saved_x
;
13958 it
->object
= saved_object
;
13959 it
->position
= saved_pos
;
13960 it
->what
= saved_what
;
13961 it
->face_id
= saved_face_id
;
13962 it
->len
= saved_len
;
13972 /* Extend the face of the last glyph in the text area of IT->glyph_row
13973 to the end of the display line. Called from display_line.
13974 If the glyph row is empty, add a space glyph to it so that we
13975 know the face to draw. Set the glyph row flag fill_line_p. */
13978 extend_face_to_end_of_line (it
)
13982 struct frame
*f
= it
->f
;
13984 /* If line is already filled, do nothing. */
13985 if (it
->current_x
>= it
->last_visible_x
)
13988 /* Face extension extends the background and box of IT->face_id
13989 to the end of the line. If the background equals the background
13990 of the frame, we don't have to do anything. */
13991 if (it
->face_before_selective_p
)
13992 face
= FACE_FROM_ID (it
->f
, it
->saved_face_id
);
13994 face
= FACE_FROM_ID (f
, it
->face_id
);
13996 if (FRAME_WINDOW_P (f
)
13997 && face
->box
== FACE_NO_BOX
13998 && face
->background
== FRAME_BACKGROUND_PIXEL (f
)
14002 /* Set the glyph row flag indicating that the face of the last glyph
14003 in the text area has to be drawn to the end of the text area. */
14004 it
->glyph_row
->fill_line_p
= 1;
14006 /* If current character of IT is not ASCII, make sure we have the
14007 ASCII face. This will be automatically undone the next time
14008 get_next_display_element returns a multibyte character. Note
14009 that the character will always be single byte in unibyte text. */
14010 if (!SINGLE_BYTE_CHAR_P (it
->c
))
14012 it
->face_id
= FACE_FOR_CHAR (f
, face
, 0);
14015 if (FRAME_WINDOW_P (f
))
14017 /* If the row is empty, add a space with the current face of IT,
14018 so that we know which face to draw. */
14019 if (it
->glyph_row
->used
[TEXT_AREA
] == 0)
14021 it
->glyph_row
->glyphs
[TEXT_AREA
][0] = space_glyph
;
14022 it
->glyph_row
->glyphs
[TEXT_AREA
][0].face_id
= it
->face_id
;
14023 it
->glyph_row
->used
[TEXT_AREA
] = 1;
14028 /* Save some values that must not be changed. */
14029 int saved_x
= it
->current_x
;
14030 struct text_pos saved_pos
;
14031 Lisp_Object saved_object
;
14032 enum display_element_type saved_what
= it
->what
;
14033 int saved_face_id
= it
->face_id
;
14035 saved_object
= it
->object
;
14036 saved_pos
= it
->position
;
14038 it
->what
= IT_CHARACTER
;
14039 bzero (&it
->position
, sizeof it
->position
);
14040 it
->object
= make_number (0);
14043 it
->face_id
= face
->id
;
14045 PRODUCE_GLYPHS (it
);
14047 while (it
->current_x
<= it
->last_visible_x
)
14048 PRODUCE_GLYPHS (it
);
14050 /* Don't count these blanks really. It would let us insert a left
14051 truncation glyph below and make us set the cursor on them, maybe. */
14052 it
->current_x
= saved_x
;
14053 it
->object
= saved_object
;
14054 it
->position
= saved_pos
;
14055 it
->what
= saved_what
;
14056 it
->face_id
= saved_face_id
;
14061 /* Value is non-zero if text starting at CHARPOS in current_buffer is
14062 trailing whitespace. */
14065 trailing_whitespace_p (charpos
)
14068 int bytepos
= CHAR_TO_BYTE (charpos
);
14071 while (bytepos
< ZV_BYTE
14072 && (c
= FETCH_CHAR (bytepos
),
14073 c
== ' ' || c
== '\t'))
14076 if (bytepos
>= ZV_BYTE
|| c
== '\n' || c
== '\r')
14078 if (bytepos
!= PT_BYTE
)
14085 /* Highlight trailing whitespace, if any, in ROW. */
14088 highlight_trailing_whitespace (f
, row
)
14090 struct glyph_row
*row
;
14092 int used
= row
->used
[TEXT_AREA
];
14096 struct glyph
*start
= row
->glyphs
[TEXT_AREA
];
14097 struct glyph
*glyph
= start
+ used
- 1;
14099 /* Skip over glyphs inserted to display the cursor at the
14100 end of a line, for extending the face of the last glyph
14101 to the end of the line on terminals, and for truncation
14102 and continuation glyphs. */
14103 while (glyph
>= start
14104 && glyph
->type
== CHAR_GLYPH
14105 && INTEGERP (glyph
->object
))
14108 /* If last glyph is a space or stretch, and it's trailing
14109 whitespace, set the face of all trailing whitespace glyphs in
14110 IT->glyph_row to `trailing-whitespace'. */
14112 && BUFFERP (glyph
->object
)
14113 && (glyph
->type
== STRETCH_GLYPH
14114 || (glyph
->type
== CHAR_GLYPH
14115 && glyph
->u
.ch
== ' '))
14116 && trailing_whitespace_p (glyph
->charpos
))
14118 int face_id
= lookup_named_face (f
, Qtrailing_whitespace
, 0);
14120 while (glyph
>= start
14121 && BUFFERP (glyph
->object
)
14122 && (glyph
->type
== STRETCH_GLYPH
14123 || (glyph
->type
== CHAR_GLYPH
14124 && glyph
->u
.ch
== ' ')))
14125 (glyph
--)->face_id
= face_id
;
14131 /* Value is non-zero if glyph row ROW in window W should be
14132 used to hold the cursor. */
14135 cursor_row_p (w
, row
)
14137 struct glyph_row
*row
;
14139 int cursor_row_p
= 1;
14141 if (PT
== MATRIX_ROW_END_CHARPOS (row
))
14143 /* If the row ends with a newline from a string, we don't want
14144 the cursor there (if the row is continued it doesn't end in a
14146 if (CHARPOS (row
->end
.string_pos
) >= 0
14147 || MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
))
14148 cursor_row_p
= row
->continued_p
;
14150 /* If the row ends at ZV, display the cursor at the end of that
14151 row instead of at the start of the row below. */
14152 else if (row
->ends_at_zv_p
)
14158 return cursor_row_p
;
14162 /* Construct the glyph row IT->glyph_row in the desired matrix of
14163 IT->w from text at the current position of IT. See dispextern.h
14164 for an overview of struct it. Value is non-zero if
14165 IT->glyph_row displays text, as opposed to a line displaying ZV
14172 struct glyph_row
*row
= it
->glyph_row
;
14174 /* We always start displaying at hpos zero even if hscrolled. */
14175 xassert (it
->hpos
== 0 && it
->current_x
== 0);
14177 /* We must not display in a row that's not a text row. */
14178 xassert (MATRIX_ROW_VPOS (row
, it
->w
->desired_matrix
)
14179 < it
->w
->desired_matrix
->nrows
);
14181 /* Is IT->w showing the region? */
14182 it
->w
->region_showing
= it
->region_beg_charpos
> 0 ? Qt
: Qnil
;
14184 /* Clear the result glyph row and enable it. */
14185 prepare_desired_row (row
);
14187 row
->y
= it
->current_y
;
14188 row
->start
= it
->start
;
14189 row
->continuation_lines_width
= it
->continuation_lines_width
;
14190 row
->displays_text_p
= 1;
14191 row
->starts_in_middle_of_char_p
= it
->starts_in_middle_of_char_p
;
14192 it
->starts_in_middle_of_char_p
= 0;
14194 /* Arrange the overlays nicely for our purposes. Usually, we call
14195 display_line on only one line at a time, in which case this
14196 can't really hurt too much, or we call it on lines which appear
14197 one after another in the buffer, in which case all calls to
14198 recenter_overlay_lists but the first will be pretty cheap. */
14199 recenter_overlay_lists (current_buffer
, IT_CHARPOS (*it
));
14201 /* Move over display elements that are not visible because we are
14202 hscrolled. This may stop at an x-position < IT->first_visible_x
14203 if the first glyph is partially visible or if we hit a line end. */
14204 if (it
->current_x
< it
->first_visible_x
)
14205 move_it_in_display_line_to (it
, ZV
, it
->first_visible_x
,
14206 MOVE_TO_POS
| MOVE_TO_X
);
14208 /* Get the initial row height. This is either the height of the
14209 text hscrolled, if there is any, or zero. */
14210 row
->ascent
= it
->max_ascent
;
14211 row
->height
= it
->max_ascent
+ it
->max_descent
;
14212 row
->phys_ascent
= it
->max_phys_ascent
;
14213 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
14215 /* Loop generating characters. The loop is left with IT on the next
14216 character to display. */
14219 int n_glyphs_before
, hpos_before
, x_before
;
14221 int ascent
= 0, descent
= 0, phys_ascent
= 0, phys_descent
= 0;
14223 /* Retrieve the next thing to display. Value is zero if end of
14225 if (!get_next_display_element (it
))
14227 /* Maybe add a space at the end of this line that is used to
14228 display the cursor there under X. Set the charpos of the
14229 first glyph of blank lines not corresponding to any text
14231 #ifdef HAVE_WINDOW_SYSTEM
14232 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
14233 row
->exact_window_width_line_p
= 1;
14235 #endif /* HAVE_WINDOW_SYSTEM */
14236 if ((append_space (it
, 1) && row
->used
[TEXT_AREA
] == 1)
14237 || row
->used
[TEXT_AREA
] == 0)
14239 row
->glyphs
[TEXT_AREA
]->charpos
= -1;
14240 row
->displays_text_p
= 0;
14242 if (!NILP (XBUFFER (it
->w
->buffer
)->indicate_empty_lines
)
14243 && (!MINI_WINDOW_P (it
->w
)
14244 || (minibuf_level
&& EQ (it
->window
, minibuf_window
))))
14245 row
->indicate_empty_line_p
= 1;
14248 it
->continuation_lines_width
= 0;
14249 row
->ends_at_zv_p
= 1;
14253 /* Now, get the metrics of what we want to display. This also
14254 generates glyphs in `row' (which is IT->glyph_row). */
14255 n_glyphs_before
= row
->used
[TEXT_AREA
];
14258 /* Remember the line height so far in case the next element doesn't
14259 fit on the line. */
14260 if (!it
->truncate_lines_p
)
14262 ascent
= it
->max_ascent
;
14263 descent
= it
->max_descent
;
14264 phys_ascent
= it
->max_phys_ascent
;
14265 phys_descent
= it
->max_phys_descent
;
14268 PRODUCE_GLYPHS (it
);
14270 /* If this display element was in marginal areas, continue with
14272 if (it
->area
!= TEXT_AREA
)
14274 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
14275 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
14276 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
14277 row
->phys_height
= max (row
->phys_height
,
14278 it
->max_phys_ascent
+ it
->max_phys_descent
);
14279 set_iterator_to_next (it
, 1);
14283 /* Does the display element fit on the line? If we truncate
14284 lines, we should draw past the right edge of the window. If
14285 we don't truncate, we want to stop so that we can display the
14286 continuation glyph before the right margin. If lines are
14287 continued, there are two possible strategies for characters
14288 resulting in more than 1 glyph (e.g. tabs): Display as many
14289 glyphs as possible in this line and leave the rest for the
14290 continuation line, or display the whole element in the next
14291 line. Original redisplay did the former, so we do it also. */
14292 nglyphs
= row
->used
[TEXT_AREA
] - n_glyphs_before
;
14293 hpos_before
= it
->hpos
;
14296 if (/* Not a newline. */
14298 /* Glyphs produced fit entirely in the line. */
14299 && it
->current_x
< it
->last_visible_x
)
14301 it
->hpos
+= nglyphs
;
14302 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
14303 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
14304 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
14305 row
->phys_height
= max (row
->phys_height
,
14306 it
->max_phys_ascent
+ it
->max_phys_descent
);
14307 if (it
->current_x
- it
->pixel_width
< it
->first_visible_x
)
14308 row
->x
= x
- it
->first_visible_x
;
14313 struct glyph
*glyph
;
14315 for (i
= 0; i
< nglyphs
; ++i
, x
= new_x
)
14317 glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
14318 new_x
= x
+ glyph
->pixel_width
;
14320 if (/* Lines are continued. */
14321 !it
->truncate_lines_p
14322 && (/* Glyph doesn't fit on the line. */
14323 new_x
> it
->last_visible_x
14324 /* Or it fits exactly on a window system frame. */
14325 || (new_x
== it
->last_visible_x
14326 && FRAME_WINDOW_P (it
->f
))))
14328 /* End of a continued line. */
14331 || (new_x
== it
->last_visible_x
14332 && FRAME_WINDOW_P (it
->f
)))
14334 /* Current glyph is the only one on the line or
14335 fits exactly on the line. We must continue
14336 the line because we can't draw the cursor
14337 after the glyph. */
14338 row
->continued_p
= 1;
14339 it
->current_x
= new_x
;
14340 it
->continuation_lines_width
+= new_x
;
14342 if (i
== nglyphs
- 1)
14344 set_iterator_to_next (it
, 1);
14345 #ifdef HAVE_WINDOW_SYSTEM
14346 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
14348 if (!get_next_display_element (it
))
14350 row
->exact_window_width_line_p
= 1;
14351 it
->continuation_lines_width
= 0;
14352 row
->continued_p
= 0;
14353 row
->ends_at_zv_p
= 1;
14355 else if (ITERATOR_AT_END_OF_LINE_P (it
))
14357 row
->continued_p
= 0;
14358 row
->exact_window_width_line_p
= 1;
14361 #endif /* HAVE_WINDOW_SYSTEM */
14364 else if (CHAR_GLYPH_PADDING_P (*glyph
)
14365 && !FRAME_WINDOW_P (it
->f
))
14367 /* A padding glyph that doesn't fit on this line.
14368 This means the whole character doesn't fit
14370 row
->used
[TEXT_AREA
] = n_glyphs_before
;
14372 /* Fill the rest of the row with continuation
14373 glyphs like in 20.x. */
14374 while (row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
]
14375 < row
->glyphs
[1 + TEXT_AREA
])
14376 produce_special_glyphs (it
, IT_CONTINUATION
);
14378 row
->continued_p
= 1;
14379 it
->current_x
= x_before
;
14380 it
->continuation_lines_width
+= x_before
;
14382 /* Restore the height to what it was before the
14383 element not fitting on the line. */
14384 it
->max_ascent
= ascent
;
14385 it
->max_descent
= descent
;
14386 it
->max_phys_ascent
= phys_ascent
;
14387 it
->max_phys_descent
= phys_descent
;
14389 else if (it
->c
== '\t' && FRAME_WINDOW_P (it
->f
))
14391 /* A TAB that extends past the right edge of the
14392 window. This produces a single glyph on
14393 window system frames. We leave the glyph in
14394 this row and let it fill the row, but don't
14395 consume the TAB. */
14396 it
->continuation_lines_width
+= it
->last_visible_x
;
14397 row
->ends_in_middle_of_char_p
= 1;
14398 row
->continued_p
= 1;
14399 glyph
->pixel_width
= it
->last_visible_x
- x
;
14400 it
->starts_in_middle_of_char_p
= 1;
14404 /* Something other than a TAB that draws past
14405 the right edge of the window. Restore
14406 positions to values before the element. */
14407 row
->used
[TEXT_AREA
] = n_glyphs_before
+ i
;
14409 /* Display continuation glyphs. */
14410 if (!FRAME_WINDOW_P (it
->f
))
14411 produce_special_glyphs (it
, IT_CONTINUATION
);
14412 row
->continued_p
= 1;
14414 it
->continuation_lines_width
+= x
;
14416 if (nglyphs
> 1 && i
> 0)
14418 row
->ends_in_middle_of_char_p
= 1;
14419 it
->starts_in_middle_of_char_p
= 1;
14422 /* Restore the height to what it was before the
14423 element not fitting on the line. */
14424 it
->max_ascent
= ascent
;
14425 it
->max_descent
= descent
;
14426 it
->max_phys_ascent
= phys_ascent
;
14427 it
->max_phys_descent
= phys_descent
;
14432 else if (new_x
> it
->first_visible_x
)
14434 /* Increment number of glyphs actually displayed. */
14437 if (x
< it
->first_visible_x
)
14438 /* Glyph is partially visible, i.e. row starts at
14439 negative X position. */
14440 row
->x
= x
- it
->first_visible_x
;
14444 /* Glyph is completely off the left margin of the
14445 window. This should not happen because of the
14446 move_it_in_display_line at the start of this
14447 function, unless the text display area of the
14448 window is empty. */
14449 xassert (it
->first_visible_x
<= it
->last_visible_x
);
14453 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
14454 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
14455 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
14456 row
->phys_height
= max (row
->phys_height
,
14457 it
->max_phys_ascent
+ it
->max_phys_descent
);
14459 /* End of this display line if row is continued. */
14460 if (row
->continued_p
|| row
->ends_at_zv_p
)
14465 /* Is this a line end? If yes, we're also done, after making
14466 sure that a non-default face is extended up to the right
14467 margin of the window. */
14468 if (ITERATOR_AT_END_OF_LINE_P (it
))
14470 int used_before
= row
->used
[TEXT_AREA
];
14472 row
->ends_in_newline_from_string_p
= STRINGP (it
->object
);
14474 #ifdef HAVE_WINDOW_SYSTEM
14475 /* Add a space at the end of the line that is used to
14476 display the cursor there. */
14477 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
14478 append_space (it
, 0);
14479 #endif /* HAVE_WINDOW_SYSTEM */
14481 /* Extend the face to the end of the line. */
14482 extend_face_to_end_of_line (it
);
14484 /* Make sure we have the position. */
14485 if (used_before
== 0)
14486 row
->glyphs
[TEXT_AREA
]->charpos
= CHARPOS (it
->position
);
14488 /* Consume the line end. This skips over invisible lines. */
14489 set_iterator_to_next (it
, 1);
14490 it
->continuation_lines_width
= 0;
14494 /* Proceed with next display element. Note that this skips
14495 over lines invisible because of selective display. */
14496 set_iterator_to_next (it
, 1);
14498 /* If we truncate lines, we are done when the last displayed
14499 glyphs reach past the right margin of the window. */
14500 if (it
->truncate_lines_p
14501 && (FRAME_WINDOW_P (it
->f
)
14502 ? (it
->current_x
>= it
->last_visible_x
)
14503 : (it
->current_x
> it
->last_visible_x
)))
14505 /* Maybe add truncation glyphs. */
14506 if (!FRAME_WINDOW_P (it
->f
))
14510 for (i
= row
->used
[TEXT_AREA
] - 1; i
> 0; --i
)
14511 if (!CHAR_GLYPH_PADDING_P (row
->glyphs
[TEXT_AREA
][i
]))
14514 for (n
= row
->used
[TEXT_AREA
]; i
< n
; ++i
)
14516 row
->used
[TEXT_AREA
] = i
;
14517 produce_special_glyphs (it
, IT_TRUNCATION
);
14520 #ifdef HAVE_WINDOW_SYSTEM
14523 /* Don't truncate if we can overflow newline into fringe. */
14524 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
14526 if (!get_next_display_element (it
))
14528 #ifdef HAVE_WINDOW_SYSTEM
14529 it
->continuation_lines_width
= 0;
14530 row
->ends_at_zv_p
= 1;
14531 row
->exact_window_width_line_p
= 1;
14533 #endif /* HAVE_WINDOW_SYSTEM */
14535 if (ITERATOR_AT_END_OF_LINE_P (it
))
14537 row
->exact_window_width_line_p
= 1;
14538 goto at_end_of_line
;
14542 #endif /* HAVE_WINDOW_SYSTEM */
14544 row
->truncated_on_right_p
= 1;
14545 it
->continuation_lines_width
= 0;
14546 reseat_at_next_visible_line_start (it
, 0);
14547 row
->ends_at_zv_p
= FETCH_BYTE (IT_BYTEPOS (*it
) - 1) != '\n';
14548 it
->hpos
= hpos_before
;
14549 it
->current_x
= x_before
;
14554 /* If line is not empty and hscrolled, maybe insert truncation glyphs
14555 at the left window margin. */
14556 if (it
->first_visible_x
14557 && IT_CHARPOS (*it
) != MATRIX_ROW_START_CHARPOS (row
))
14559 if (!FRAME_WINDOW_P (it
->f
))
14560 insert_left_trunc_glyphs (it
);
14561 row
->truncated_on_left_p
= 1;
14564 /* If the start of this line is the overlay arrow-position, then
14565 mark this glyph row as the one containing the overlay arrow.
14566 This is clearly a mess with variable size fonts. It would be
14567 better to let it be displayed like cursors under X. */
14568 if (MARKERP (Voverlay_arrow_position
)
14569 && current_buffer
== XMARKER (Voverlay_arrow_position
)->buffer
14570 && (MATRIX_ROW_START_CHARPOS (row
)
14571 == marker_position (Voverlay_arrow_position
))
14572 && STRINGP (Voverlay_arrow_string
)
14573 && ! overlay_arrow_seen
)
14575 /* Overlay arrow in window redisplay is a fringe bitmap. */
14576 if (!FRAME_WINDOW_P (it
->f
))
14578 struct glyph_row
*arrow_row
= get_overlay_arrow_glyph_row (it
->w
);
14579 struct glyph
*glyph
= arrow_row
->glyphs
[TEXT_AREA
];
14580 struct glyph
*arrow_end
= glyph
+ arrow_row
->used
[TEXT_AREA
];
14581 struct glyph
*p
= row
->glyphs
[TEXT_AREA
];
14582 struct glyph
*p2
, *end
;
14584 /* Copy the arrow glyphs. */
14585 while (glyph
< arrow_end
)
14588 /* Throw away padding glyphs. */
14590 end
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
];
14591 while (p2
< end
&& CHAR_GLYPH_PADDING_P (*p2
))
14597 row
->used
[TEXT_AREA
] = p2
- row
->glyphs
[TEXT_AREA
];
14601 overlay_arrow_seen
= 1;
14602 row
->overlay_arrow_p
= 1;
14605 /* Compute pixel dimensions of this line. */
14606 compute_line_metrics (it
);
14608 /* Remember the position at which this line ends. */
14609 row
->end
= it
->current
;
14611 /* Save fringe bitmaps in this row. */
14612 row
->left_user_fringe_bitmap
= it
->left_user_fringe_bitmap
;
14613 row
->left_user_fringe_face_id
= it
->left_user_fringe_face_id
;
14614 row
->right_user_fringe_bitmap
= it
->right_user_fringe_bitmap
;
14615 row
->right_user_fringe_face_id
= it
->right_user_fringe_face_id
;
14617 it
->left_user_fringe_bitmap
= 0;
14618 it
->left_user_fringe_face_id
= 0;
14619 it
->right_user_fringe_bitmap
= 0;
14620 it
->right_user_fringe_face_id
= 0;
14622 /* Maybe set the cursor. */
14623 if (it
->w
->cursor
.vpos
< 0
14624 && PT
>= MATRIX_ROW_START_CHARPOS (row
)
14625 && PT
<= MATRIX_ROW_END_CHARPOS (row
)
14626 && cursor_row_p (it
->w
, row
))
14627 set_cursor_from_row (it
->w
, row
, it
->w
->desired_matrix
, 0, 0, 0, 0);
14629 /* Highlight trailing whitespace. */
14630 if (!NILP (Vshow_trailing_whitespace
))
14631 highlight_trailing_whitespace (it
->f
, it
->glyph_row
);
14633 /* Prepare for the next line. This line starts horizontally at (X
14634 HPOS) = (0 0). Vertical positions are incremented. As a
14635 convenience for the caller, IT->glyph_row is set to the next
14637 it
->current_x
= it
->hpos
= 0;
14638 it
->current_y
+= row
->height
;
14641 it
->start
= it
->current
;
14642 return row
->displays_text_p
;
14647 /***********************************************************************
14649 ***********************************************************************/
14651 /* Redisplay the menu bar in the frame for window W.
14653 The menu bar of X frames that don't have X toolkit support is
14654 displayed in a special window W->frame->menu_bar_window.
14656 The menu bar of terminal frames is treated specially as far as
14657 glyph matrices are concerned. Menu bar lines are not part of
14658 windows, so the update is done directly on the frame matrix rows
14659 for the menu bar. */
14662 display_menu_bar (w
)
14665 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
14670 /* Don't do all this for graphical frames. */
14672 if (!NILP (Vwindow_system
))
14675 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
14680 if (FRAME_MAC_P (f
))
14684 #ifdef USE_X_TOOLKIT
14685 xassert (!FRAME_WINDOW_P (f
));
14686 init_iterator (&it
, w
, -1, -1, f
->desired_matrix
->rows
, MENU_FACE_ID
);
14687 it
.first_visible_x
= 0;
14688 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
14689 #else /* not USE_X_TOOLKIT */
14690 if (FRAME_WINDOW_P (f
))
14692 /* Menu bar lines are displayed in the desired matrix of the
14693 dummy window menu_bar_window. */
14694 struct window
*menu_w
;
14695 xassert (WINDOWP (f
->menu_bar_window
));
14696 menu_w
= XWINDOW (f
->menu_bar_window
);
14697 init_iterator (&it
, menu_w
, -1, -1, menu_w
->desired_matrix
->rows
,
14699 it
.first_visible_x
= 0;
14700 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
14704 /* This is a TTY frame, i.e. character hpos/vpos are used as
14706 init_iterator (&it
, w
, -1, -1, f
->desired_matrix
->rows
,
14708 it
.first_visible_x
= 0;
14709 it
.last_visible_x
= FRAME_COLS (f
);
14711 #endif /* not USE_X_TOOLKIT */
14713 if (! mode_line_inverse_video
)
14714 /* Force the menu-bar to be displayed in the default face. */
14715 it
.base_face_id
= it
.face_id
= DEFAULT_FACE_ID
;
14717 /* Clear all rows of the menu bar. */
14718 for (i
= 0; i
< FRAME_MENU_BAR_LINES (f
); ++i
)
14720 struct glyph_row
*row
= it
.glyph_row
+ i
;
14721 clear_glyph_row (row
);
14722 row
->enabled_p
= 1;
14723 row
->full_width_p
= 1;
14726 /* Display all items of the menu bar. */
14727 items
= FRAME_MENU_BAR_ITEMS (it
.f
);
14728 for (i
= 0; i
< XVECTOR (items
)->size
; i
+= 4)
14730 Lisp_Object string
;
14732 /* Stop at nil string. */
14733 string
= AREF (items
, i
+ 1);
14737 /* Remember where item was displayed. */
14738 AREF (items
, i
+ 3) = make_number (it
.hpos
);
14740 /* Display the item, pad with one space. */
14741 if (it
.current_x
< it
.last_visible_x
)
14742 display_string (NULL
, string
, Qnil
, 0, 0, &it
,
14743 SCHARS (string
) + 1, 0, 0, -1);
14746 /* Fill out the line with spaces. */
14747 if (it
.current_x
< it
.last_visible_x
)
14748 display_string ("", Qnil
, Qnil
, 0, 0, &it
, -1, 0, 0, -1);
14750 /* Compute the total height of the lines. */
14751 compute_line_metrics (&it
);
14756 /***********************************************************************
14758 ***********************************************************************/
14760 /* Redisplay mode lines in the window tree whose root is WINDOW. If
14761 FORCE is non-zero, redisplay mode lines unconditionally.
14762 Otherwise, redisplay only mode lines that are garbaged. Value is
14763 the number of windows whose mode lines were redisplayed. */
14766 redisplay_mode_lines (window
, force
)
14767 Lisp_Object window
;
14772 while (!NILP (window
))
14774 struct window
*w
= XWINDOW (window
);
14776 if (WINDOWP (w
->hchild
))
14777 nwindows
+= redisplay_mode_lines (w
->hchild
, force
);
14778 else if (WINDOWP (w
->vchild
))
14779 nwindows
+= redisplay_mode_lines (w
->vchild
, force
);
14781 || FRAME_GARBAGED_P (XFRAME (w
->frame
))
14782 || !MATRIX_MODE_LINE_ROW (w
->current_matrix
)->enabled_p
)
14784 struct text_pos lpoint
;
14785 struct buffer
*old
= current_buffer
;
14787 /* Set the window's buffer for the mode line display. */
14788 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
14789 set_buffer_internal_1 (XBUFFER (w
->buffer
));
14791 /* Point refers normally to the selected window. For any
14792 other window, set up appropriate value. */
14793 if (!EQ (window
, selected_window
))
14795 struct text_pos pt
;
14797 SET_TEXT_POS_FROM_MARKER (pt
, w
->pointm
);
14798 if (CHARPOS (pt
) < BEGV
)
14799 TEMP_SET_PT_BOTH (BEGV
, BEGV_BYTE
);
14800 else if (CHARPOS (pt
) > (ZV
- 1))
14801 TEMP_SET_PT_BOTH (ZV
, ZV_BYTE
);
14803 TEMP_SET_PT_BOTH (CHARPOS (pt
), BYTEPOS (pt
));
14806 /* Display mode lines. */
14807 clear_glyph_matrix (w
->desired_matrix
);
14808 if (display_mode_lines (w
))
14811 w
->must_be_updated_p
= 1;
14814 /* Restore old settings. */
14815 set_buffer_internal_1 (old
);
14816 TEMP_SET_PT_BOTH (CHARPOS (lpoint
), BYTEPOS (lpoint
));
14826 /* Display the mode and/or top line of window W. Value is the number
14827 of mode lines displayed. */
14830 display_mode_lines (w
)
14833 Lisp_Object old_selected_window
, old_selected_frame
;
14836 old_selected_frame
= selected_frame
;
14837 selected_frame
= w
->frame
;
14838 old_selected_window
= selected_window
;
14839 XSETWINDOW (selected_window
, w
);
14841 /* These will be set while the mode line specs are processed. */
14842 line_number_displayed
= 0;
14843 w
->column_number_displayed
= Qnil
;
14845 if (WINDOW_WANTS_MODELINE_P (w
))
14847 struct window
*sel_w
= XWINDOW (old_selected_window
);
14849 /* Select mode line face based on the real selected window. */
14850 display_mode_line (w
, CURRENT_MODE_LINE_FACE_ID_3 (sel_w
, sel_w
, w
),
14851 current_buffer
->mode_line_format
);
14855 if (WINDOW_WANTS_HEADER_LINE_P (w
))
14857 display_mode_line (w
, HEADER_LINE_FACE_ID
,
14858 current_buffer
->header_line_format
);
14862 selected_frame
= old_selected_frame
;
14863 selected_window
= old_selected_window
;
14868 /* Display mode or top line of window W. FACE_ID specifies which line
14869 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
14870 FORMAT is the mode line format to display. Value is the pixel
14871 height of the mode line displayed. */
14874 display_mode_line (w
, face_id
, format
)
14876 enum face_id face_id
;
14877 Lisp_Object format
;
14882 init_iterator (&it
, w
, -1, -1, NULL
, face_id
);
14883 prepare_desired_row (it
.glyph_row
);
14885 if (! mode_line_inverse_video
)
14886 /* Force the mode-line to be displayed in the default face. */
14887 it
.base_face_id
= it
.face_id
= DEFAULT_FACE_ID
;
14889 /* Temporarily make frame's keyboard the current kboard so that
14890 kboard-local variables in the mode_line_format will get the right
14892 push_frame_kboard (it
.f
);
14893 display_mode_element (&it
, 0, 0, 0, format
, Qnil
, 0);
14894 pop_frame_kboard ();
14896 /* Fill up with spaces. */
14897 display_string (" ", Qnil
, Qnil
, 0, 0, &it
, 10000, -1, -1, 0);
14899 compute_line_metrics (&it
);
14900 it
.glyph_row
->full_width_p
= 1;
14901 it
.glyph_row
->mode_line_p
= 1;
14902 it
.glyph_row
->continued_p
= 0;
14903 it
.glyph_row
->truncated_on_left_p
= 0;
14904 it
.glyph_row
->truncated_on_right_p
= 0;
14906 /* Make a 3D mode-line have a shadow at its right end. */
14907 face
= FACE_FROM_ID (it
.f
, face_id
);
14908 extend_face_to_end_of_line (&it
);
14909 if (face
->box
!= FACE_NO_BOX
)
14911 struct glyph
*last
= (it
.glyph_row
->glyphs
[TEXT_AREA
]
14912 + it
.glyph_row
->used
[TEXT_AREA
] - 1);
14913 last
->right_box_line_p
= 1;
14916 return it
.glyph_row
->height
;
14919 /* Alist that caches the results of :propertize.
14920 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
14921 Lisp_Object mode_line_proptrans_alist
;
14923 /* List of strings making up the mode-line. */
14924 Lisp_Object mode_line_string_list
;
14926 /* Base face property when building propertized mode line string. */
14927 static Lisp_Object mode_line_string_face
;
14928 static Lisp_Object mode_line_string_face_prop
;
14931 /* Contribute ELT to the mode line for window IT->w. How it
14932 translates into text depends on its data type.
14934 IT describes the display environment in which we display, as usual.
14936 DEPTH is the depth in recursion. It is used to prevent
14937 infinite recursion here.
14939 FIELD_WIDTH is the number of characters the display of ELT should
14940 occupy in the mode line, and PRECISION is the maximum number of
14941 characters to display from ELT's representation. See
14942 display_string for details.
14944 Returns the hpos of the end of the text generated by ELT.
14946 PROPS is a property list to add to any string we encounter.
14948 If RISKY is nonzero, remove (disregard) any properties in any string
14949 we encounter, and ignore :eval and :propertize.
14951 If the global variable `frame_title_ptr' is non-NULL, then the output
14952 is passed to `store_frame_title' instead of `display_string'. */
14955 display_mode_element (it
, depth
, field_width
, precision
, elt
, props
, risky
)
14958 int field_width
, precision
;
14959 Lisp_Object elt
, props
;
14962 int n
= 0, field
, prec
;
14967 elt
= build_string ("*too-deep*");
14971 switch (SWITCH_ENUM_CAST (XTYPE (elt
)))
14975 /* A string: output it and check for %-constructs within it. */
14977 const unsigned char *this, *lisp_string
;
14979 if (!NILP (props
) || risky
)
14981 Lisp_Object oprops
, aelt
;
14982 oprops
= Ftext_properties_at (make_number (0), elt
);
14984 if (NILP (Fequal (props
, oprops
)) || risky
)
14986 /* If the starting string has properties,
14987 merge the specified ones onto the existing ones. */
14988 if (! NILP (oprops
) && !risky
)
14992 oprops
= Fcopy_sequence (oprops
);
14994 while (CONSP (tem
))
14996 oprops
= Fplist_put (oprops
, XCAR (tem
),
14997 XCAR (XCDR (tem
)));
14998 tem
= XCDR (XCDR (tem
));
15003 aelt
= Fassoc (elt
, mode_line_proptrans_alist
);
15004 if (! NILP (aelt
) && !NILP (Fequal (props
, XCDR (aelt
))))
15006 mode_line_proptrans_alist
15007 = Fcons (aelt
, Fdelq (aelt
, mode_line_proptrans_alist
));
15014 elt
= Fcopy_sequence (elt
);
15015 Fset_text_properties (make_number (0), Flength (elt
),
15017 /* Add this item to mode_line_proptrans_alist. */
15018 mode_line_proptrans_alist
15019 = Fcons (Fcons (elt
, props
),
15020 mode_line_proptrans_alist
);
15021 /* Truncate mode_line_proptrans_alist
15022 to at most 50 elements. */
15023 tem
= Fnthcdr (make_number (50),
15024 mode_line_proptrans_alist
);
15026 XSETCDR (tem
, Qnil
);
15031 this = SDATA (elt
);
15032 lisp_string
= this;
15036 prec
= precision
- n
;
15037 if (frame_title_ptr
)
15038 n
+= store_frame_title (SDATA (elt
), -1, prec
);
15039 else if (!NILP (mode_line_string_list
))
15040 n
+= store_mode_line_string (NULL
, elt
, 1, 0, prec
, Qnil
);
15042 n
+= display_string (NULL
, elt
, Qnil
, 0, 0, it
,
15043 0, prec
, 0, STRING_MULTIBYTE (elt
));
15048 while ((precision
<= 0 || n
< precision
)
15050 && (frame_title_ptr
15051 || !NILP (mode_line_string_list
)
15052 || it
->current_x
< it
->last_visible_x
))
15054 const unsigned char *last
= this;
15056 /* Advance to end of string or next format specifier. */
15057 while ((c
= *this++) != '\0' && c
!= '%')
15060 if (this - 1 != last
)
15062 /* Output to end of string or up to '%'. Field width
15063 is length of string. Don't output more than
15064 PRECISION allows us. */
15067 prec
= chars_in_text (last
, this - last
);
15068 if (precision
> 0 && prec
> precision
- n
)
15069 prec
= precision
- n
;
15071 if (frame_title_ptr
)
15072 n
+= store_frame_title (last
, 0, prec
);
15073 else if (!NILP (mode_line_string_list
))
15075 int bytepos
= last
- lisp_string
;
15076 int charpos
= string_byte_to_char (elt
, bytepos
);
15077 n
+= store_mode_line_string (NULL
,
15078 Fsubstring (elt
, make_number (charpos
),
15079 make_number (charpos
+ prec
)),
15084 int bytepos
= last
- lisp_string
;
15085 int charpos
= string_byte_to_char (elt
, bytepos
);
15086 n
+= display_string (NULL
, elt
, Qnil
, 0, charpos
,
15088 STRING_MULTIBYTE (elt
));
15091 else /* c == '%' */
15093 const unsigned char *percent_position
= this;
15095 /* Get the specified minimum width. Zero means
15098 while ((c
= *this++) >= '0' && c
<= '9')
15099 field
= field
* 10 + c
- '0';
15101 /* Don't pad beyond the total padding allowed. */
15102 if (field_width
- n
> 0 && field
> field_width
- n
)
15103 field
= field_width
- n
;
15105 /* Note that either PRECISION <= 0 or N < PRECISION. */
15106 prec
= precision
- n
;
15109 n
+= display_mode_element (it
, depth
, field
, prec
,
15110 Vglobal_mode_string
, props
,
15115 int bytepos
, charpos
;
15116 unsigned char *spec
;
15118 bytepos
= percent_position
- lisp_string
;
15119 charpos
= (STRING_MULTIBYTE (elt
)
15120 ? string_byte_to_char (elt
, bytepos
)
15124 = decode_mode_spec (it
->w
, c
, field
, prec
, &multibyte
);
15126 if (frame_title_ptr
)
15127 n
+= store_frame_title (spec
, field
, prec
);
15128 else if (!NILP (mode_line_string_list
))
15130 int len
= strlen (spec
);
15131 Lisp_Object tem
= make_string (spec
, len
);
15132 props
= Ftext_properties_at (make_number (charpos
), elt
);
15133 /* Should only keep face property in props */
15134 n
+= store_mode_line_string (NULL
, tem
, 0, field
, prec
, props
);
15138 int nglyphs_before
, nwritten
;
15140 nglyphs_before
= it
->glyph_row
->used
[TEXT_AREA
];
15141 nwritten
= display_string (spec
, Qnil
, elt
,
15146 /* Assign to the glyphs written above the
15147 string where the `%x' came from, position
15151 struct glyph
*glyph
15152 = (it
->glyph_row
->glyphs
[TEXT_AREA
]
15156 for (i
= 0; i
< nwritten
; ++i
)
15158 glyph
[i
].object
= elt
;
15159 glyph
[i
].charpos
= charpos
;
15174 /* A symbol: process the value of the symbol recursively
15175 as if it appeared here directly. Avoid error if symbol void.
15176 Special case: if value of symbol is a string, output the string
15179 register Lisp_Object tem
;
15181 /* If the variable is not marked as risky to set
15182 then its contents are risky to use. */
15183 if (NILP (Fget (elt
, Qrisky_local_variable
)))
15186 tem
= Fboundp (elt
);
15189 tem
= Fsymbol_value (elt
);
15190 /* If value is a string, output that string literally:
15191 don't check for % within it. */
15195 if (!EQ (tem
, elt
))
15197 /* Give up right away for nil or t. */
15207 register Lisp_Object car
, tem
;
15209 /* A cons cell: five distinct cases.
15210 If first element is :eval or :propertize, do something special.
15211 If first element is a string or a cons, process all the elements
15212 and effectively concatenate them.
15213 If first element is a negative number, truncate displaying cdr to
15214 at most that many characters. If positive, pad (with spaces)
15215 to at least that many characters.
15216 If first element is a symbol, process the cadr or caddr recursively
15217 according to whether the symbol's value is non-nil or nil. */
15219 if (EQ (car
, QCeval
))
15221 /* An element of the form (:eval FORM) means evaluate FORM
15222 and use the result as mode line elements. */
15227 if (CONSP (XCDR (elt
)))
15230 spec
= safe_eval (XCAR (XCDR (elt
)));
15231 n
+= display_mode_element (it
, depth
, field_width
- n
,
15232 precision
- n
, spec
, props
,
15236 else if (EQ (car
, QCpropertize
))
15238 /* An element of the form (:propertize ELT PROPS...)
15239 means display ELT but applying properties PROPS. */
15244 if (CONSP (XCDR (elt
)))
15245 n
+= display_mode_element (it
, depth
, field_width
- n
,
15246 precision
- n
, XCAR (XCDR (elt
)),
15247 XCDR (XCDR (elt
)), risky
);
15249 else if (SYMBOLP (car
))
15251 tem
= Fboundp (car
);
15255 /* elt is now the cdr, and we know it is a cons cell.
15256 Use its car if CAR has a non-nil value. */
15259 tem
= Fsymbol_value (car
);
15266 /* Symbol's value is nil (or symbol is unbound)
15267 Get the cddr of the original list
15268 and if possible find the caddr and use that. */
15272 else if (!CONSP (elt
))
15277 else if (INTEGERP (car
))
15279 register int lim
= XINT (car
);
15283 /* Negative int means reduce maximum width. */
15284 if (precision
<= 0)
15287 precision
= min (precision
, -lim
);
15291 /* Padding specified. Don't let it be more than
15292 current maximum. */
15294 lim
= min (precision
, lim
);
15296 /* If that's more padding than already wanted, queue it.
15297 But don't reduce padding already specified even if
15298 that is beyond the current truncation point. */
15299 field_width
= max (lim
, field_width
);
15303 else if (STRINGP (car
) || CONSP (car
))
15305 register int limit
= 50;
15306 /* Limit is to protect against circular lists. */
15309 && (precision
<= 0 || n
< precision
))
15311 n
+= display_mode_element (it
, depth
, field_width
- n
,
15312 precision
- n
, XCAR (elt
),
15322 elt
= build_string ("*invalid*");
15326 /* Pad to FIELD_WIDTH. */
15327 if (field_width
> 0 && n
< field_width
)
15329 if (frame_title_ptr
)
15330 n
+= store_frame_title ("", field_width
- n
, 0);
15331 else if (!NILP (mode_line_string_list
))
15332 n
+= store_mode_line_string ("", Qnil
, 0, field_width
- n
, 0, Qnil
);
15334 n
+= display_string ("", Qnil
, Qnil
, 0, 0, it
, field_width
- n
,
15341 /* Store a mode-line string element in mode_line_string_list.
15343 If STRING is non-null, display that C string. Otherwise, the Lisp
15344 string LISP_STRING is displayed.
15346 FIELD_WIDTH is the minimum number of output glyphs to produce.
15347 If STRING has fewer characters than FIELD_WIDTH, pad to the right
15348 with spaces. FIELD_WIDTH <= 0 means don't pad.
15350 PRECISION is the maximum number of characters to output from
15351 STRING. PRECISION <= 0 means don't truncate the string.
15353 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
15354 properties to the string.
15356 PROPS are the properties to add to the string.
15357 The mode_line_string_face face property is always added to the string.
15360 static int store_mode_line_string (string
, lisp_string
, copy_string
, field_width
, precision
, props
)
15362 Lisp_Object lisp_string
;
15371 if (string
!= NULL
)
15373 len
= strlen (string
);
15374 if (precision
> 0 && len
> precision
)
15376 lisp_string
= make_string (string
, len
);
15378 props
= mode_line_string_face_prop
;
15379 else if (!NILP (mode_line_string_face
))
15381 Lisp_Object face
= Fplist_get (props
, Qface
);
15382 props
= Fcopy_sequence (props
);
15384 face
= mode_line_string_face
;
15386 face
= Fcons (face
, Fcons (mode_line_string_face
, Qnil
));
15387 props
= Fplist_put (props
, Qface
, face
);
15389 Fadd_text_properties (make_number (0), make_number (len
),
15390 props
, lisp_string
);
15394 len
= XFASTINT (Flength (lisp_string
));
15395 if (precision
> 0 && len
> precision
)
15398 lisp_string
= Fsubstring (lisp_string
, make_number (0), make_number (len
));
15401 if (!NILP (mode_line_string_face
))
15405 props
= Ftext_properties_at (make_number (0), lisp_string
);
15406 face
= Fplist_get (props
, Qface
);
15408 face
= mode_line_string_face
;
15410 face
= Fcons (face
, Fcons (mode_line_string_face
, Qnil
));
15411 props
= Fcons (Qface
, Fcons (face
, Qnil
));
15413 lisp_string
= Fcopy_sequence (lisp_string
);
15416 Fadd_text_properties (make_number (0), make_number (len
),
15417 props
, lisp_string
);
15422 mode_line_string_list
= Fcons (lisp_string
, mode_line_string_list
);
15426 if (field_width
> len
)
15428 field_width
-= len
;
15429 lisp_string
= Fmake_string (make_number (field_width
), make_number (' '));
15431 Fadd_text_properties (make_number (0), make_number (field_width
),
15432 props
, lisp_string
);
15433 mode_line_string_list
= Fcons (lisp_string
, mode_line_string_list
);
15441 DEFUN ("format-mode-line", Fformat_mode_line
, Sformat_mode_line
,
15443 doc
: /* Return the mode-line of selected window as a string.
15444 First optional arg FORMAT specifies a different format string (see
15445 `mode-line-format' for details) to use. If FORMAT is t, return
15446 the buffer's header-line. Second optional arg WINDOW specifies a
15447 different window to use as the context for the formatting.
15448 If third optional arg NO-PROPS is non-nil, string is not propertized. */)
15449 (format
, window
, no_props
)
15450 Lisp_Object format
, window
, no_props
;
15455 struct buffer
*old_buffer
= NULL
;
15456 enum face_id face_id
= DEFAULT_FACE_ID
;
15459 window
= selected_window
;
15460 CHECK_WINDOW (window
);
15461 w
= XWINDOW (window
);
15462 CHECK_BUFFER (w
->buffer
);
15464 if (XBUFFER (w
->buffer
) != current_buffer
)
15466 old_buffer
= current_buffer
;
15467 set_buffer_internal_1 (XBUFFER (w
->buffer
));
15470 if (NILP (format
) || EQ (format
, Qt
))
15472 face_id
= NILP (format
)
15473 ? CURRENT_MODE_LINE_FACE_ID (w
) :
15474 HEADER_LINE_FACE_ID
;
15475 format
= NILP (format
)
15476 ? current_buffer
->mode_line_format
15477 : current_buffer
->header_line_format
;
15480 init_iterator (&it
, w
, -1, -1, NULL
, face_id
);
15482 if (NILP (no_props
))
15484 mode_line_string_face
=
15485 (face_id
== MODE_LINE_FACE_ID
? Qmode_line
:
15486 face_id
== MODE_LINE_INACTIVE_FACE_ID
? Qmode_line_inactive
:
15487 face_id
== HEADER_LINE_FACE_ID
? Qheader_line
: Qnil
);
15489 mode_line_string_face_prop
=
15490 NILP (mode_line_string_face
) ? Qnil
:
15491 Fcons (Qface
, Fcons (mode_line_string_face
, Qnil
));
15493 /* We need a dummy last element in mode_line_string_list to
15494 indicate we are building the propertized mode-line string.
15495 Using mode_line_string_face_prop here GC protects it. */
15496 mode_line_string_list
=
15497 Fcons (mode_line_string_face_prop
, Qnil
);
15498 frame_title_ptr
= NULL
;
15502 mode_line_string_face_prop
= Qnil
;
15503 mode_line_string_list
= Qnil
;
15504 frame_title_ptr
= frame_title_buf
;
15507 push_frame_kboard (it
.f
);
15508 display_mode_element (&it
, 0, 0, 0, format
, Qnil
, 0);
15509 pop_frame_kboard ();
15512 set_buffer_internal_1 (old_buffer
);
15514 if (NILP (no_props
))
15517 mode_line_string_list
= Fnreverse (mode_line_string_list
);
15518 str
= Fmapconcat (intern ("identity"), XCDR (mode_line_string_list
),
15519 make_string ("", 0));
15520 mode_line_string_face_prop
= Qnil
;
15521 mode_line_string_list
= Qnil
;
15525 len
= frame_title_ptr
- frame_title_buf
;
15526 if (len
> 0 && frame_title_ptr
[-1] == '-')
15528 /* Mode lines typically ends with numerous dashes; reduce to two dashes. */
15529 while (frame_title_ptr
> frame_title_buf
&& *--frame_title_ptr
== '-')
15531 frame_title_ptr
+= 3; /* restore last non-dash + two dashes */
15532 if (len
> frame_title_ptr
- frame_title_buf
)
15533 len
= frame_title_ptr
- frame_title_buf
;
15536 frame_title_ptr
= NULL
;
15537 return make_string (frame_title_buf
, len
);
15540 /* Write a null-terminated, right justified decimal representation of
15541 the positive integer D to BUF using a minimal field width WIDTH. */
15544 pint2str (buf
, width
, d
)
15545 register char *buf
;
15546 register int width
;
15549 register char *p
= buf
;
15557 *p
++ = d
% 10 + '0';
15562 for (width
-= (int) (p
- buf
); width
> 0; --width
)
15573 /* Write a null-terminated, right justified decimal and "human
15574 readable" representation of the nonnegative integer D to BUF using
15575 a minimal field width WIDTH. D should be smaller than 999.5e24. */
15577 static const char power_letter
[] =
15591 pint2hrstr (buf
, width
, d
)
15596 /* We aim to represent the nonnegative integer D as
15597 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
15600 /* -1 means: do not use TENTHS. */
15604 /* Length of QUOTIENT.TENTHS as a string. */
15610 if (1000 <= quotient
)
15612 /* Scale to the appropriate EXPONENT. */
15615 remainder
= quotient
% 1000;
15619 while (1000 <= quotient
);
15621 /* Round to nearest and decide whether to use TENTHS or not. */
15624 tenths
= remainder
/ 100;
15625 if (50 <= remainder
% 100)
15631 if (quotient
== 10)
15638 if (500 <= remainder
)
15639 if (quotient
< 999)
15649 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
15650 if (tenths
== -1 && quotient
<= 99)
15657 p
= psuffix
= buf
+ max (width
, length
);
15659 /* Print EXPONENT. */
15661 *psuffix
++ = power_letter
[exponent
];
15664 /* Print TENTHS. */
15667 *--p
= '0' + tenths
;
15671 /* Print QUOTIENT. */
15674 int digit
= quotient
% 10;
15675 *--p
= '0' + digit
;
15677 while ((quotient
/= 10) != 0);
15679 /* Print leading spaces. */
15684 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
15685 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
15686 type of CODING_SYSTEM. Return updated pointer into BUF. */
15688 static unsigned char invalid_eol_type
[] = "(*invalid*)";
15691 decode_mode_spec_coding (coding_system
, buf
, eol_flag
)
15692 Lisp_Object coding_system
;
15693 register char *buf
;
15697 int multibyte
= !NILP (current_buffer
->enable_multibyte_characters
);
15698 const unsigned char *eol_str
;
15700 /* The EOL conversion we are using. */
15701 Lisp_Object eoltype
;
15703 val
= Fget (coding_system
, Qcoding_system
);
15706 if (!VECTORP (val
)) /* Not yet decided. */
15711 eoltype
= eol_mnemonic_undecided
;
15712 /* Don't mention EOL conversion if it isn't decided. */
15716 Lisp_Object eolvalue
;
15718 eolvalue
= Fget (coding_system
, Qeol_type
);
15721 *buf
++ = XFASTINT (AREF (val
, 1));
15725 /* The EOL conversion that is normal on this system. */
15727 if (NILP (eolvalue
)) /* Not yet decided. */
15728 eoltype
= eol_mnemonic_undecided
;
15729 else if (VECTORP (eolvalue
)) /* Not yet decided. */
15730 eoltype
= eol_mnemonic_undecided
;
15731 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
15732 eoltype
= (XFASTINT (eolvalue
) == 0
15733 ? eol_mnemonic_unix
15734 : (XFASTINT (eolvalue
) == 1
15735 ? eol_mnemonic_dos
: eol_mnemonic_mac
));
15741 /* Mention the EOL conversion if it is not the usual one. */
15742 if (STRINGP (eoltype
))
15744 eol_str
= SDATA (eoltype
);
15745 eol_str_len
= SBYTES (eoltype
);
15747 else if (INTEGERP (eoltype
)
15748 && CHAR_VALID_P (XINT (eoltype
), 0))
15750 unsigned char *tmp
= (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH
);
15751 eol_str_len
= CHAR_STRING (XINT (eoltype
), tmp
);
15756 eol_str
= invalid_eol_type
;
15757 eol_str_len
= sizeof (invalid_eol_type
) - 1;
15759 bcopy (eol_str
, buf
, eol_str_len
);
15760 buf
+= eol_str_len
;
15766 /* Return a string for the output of a mode line %-spec for window W,
15767 generated by character C. PRECISION >= 0 means don't return a
15768 string longer than that value. FIELD_WIDTH > 0 means pad the
15769 string returned with spaces to that value. Return 1 in *MULTIBYTE
15770 if the result is multibyte text. */
15772 static char lots_of_dashes
[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
15775 decode_mode_spec (w
, c
, field_width
, precision
, multibyte
)
15778 int field_width
, precision
;
15782 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
15783 char *decode_mode_spec_buf
= f
->decode_mode_spec_buffer
;
15784 struct buffer
*b
= XBUFFER (w
->buffer
);
15792 if (!NILP (b
->read_only
))
15794 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
15799 /* This differs from %* only for a modified read-only buffer. */
15800 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
15802 if (!NILP (b
->read_only
))
15807 /* This differs from %* in ignoring read-only-ness. */
15808 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
15820 if (command_loop_level
> 5)
15822 p
= decode_mode_spec_buf
;
15823 for (i
= 0; i
< command_loop_level
; i
++)
15826 return decode_mode_spec_buf
;
15834 if (command_loop_level
> 5)
15836 p
= decode_mode_spec_buf
;
15837 for (i
= 0; i
< command_loop_level
; i
++)
15840 return decode_mode_spec_buf
;
15847 /* Let lots_of_dashes be a string of infinite length. */
15848 if (!NILP (mode_line_string_list
))
15850 if (field_width
<= 0
15851 || field_width
> sizeof (lots_of_dashes
))
15853 for (i
= 0; i
< FRAME_MESSAGE_BUF_SIZE (f
) - 1; ++i
)
15854 decode_mode_spec_buf
[i
] = '-';
15855 decode_mode_spec_buf
[i
] = '\0';
15856 return decode_mode_spec_buf
;
15859 return lots_of_dashes
;
15868 int col
= (int) current_column (); /* iftc */
15869 w
->column_number_displayed
= make_number (col
);
15870 pint2str (decode_mode_spec_buf
, field_width
, col
);
15871 return decode_mode_spec_buf
;
15875 /* %F displays the frame name. */
15876 if (!NILP (f
->title
))
15877 return (char *) SDATA (f
->title
);
15878 if (f
->explicit_name
|| ! FRAME_WINDOW_P (f
))
15879 return (char *) SDATA (f
->name
);
15888 int size
= ZV
- BEGV
;
15889 pint2str (decode_mode_spec_buf
, field_width
, size
);
15890 return decode_mode_spec_buf
;
15895 int size
= ZV
- BEGV
;
15896 pint2hrstr (decode_mode_spec_buf
, field_width
, size
);
15897 return decode_mode_spec_buf
;
15902 int startpos
= XMARKER (w
->start
)->charpos
;
15903 int startpos_byte
= marker_byte_position (w
->start
);
15904 int line
, linepos
, linepos_byte
, topline
;
15906 int height
= WINDOW_TOTAL_LINES (w
);
15908 /* If we decided that this buffer isn't suitable for line numbers,
15909 don't forget that too fast. */
15910 if (EQ (w
->base_line_pos
, w
->buffer
))
15912 /* But do forget it, if the window shows a different buffer now. */
15913 else if (BUFFERP (w
->base_line_pos
))
15914 w
->base_line_pos
= Qnil
;
15916 /* If the buffer is very big, don't waste time. */
15917 if (INTEGERP (Vline_number_display_limit
)
15918 && BUF_ZV (b
) - BUF_BEGV (b
) > XINT (Vline_number_display_limit
))
15920 w
->base_line_pos
= Qnil
;
15921 w
->base_line_number
= Qnil
;
15925 if (!NILP (w
->base_line_number
)
15926 && !NILP (w
->base_line_pos
)
15927 && XFASTINT (w
->base_line_pos
) <= startpos
)
15929 line
= XFASTINT (w
->base_line_number
);
15930 linepos
= XFASTINT (w
->base_line_pos
);
15931 linepos_byte
= buf_charpos_to_bytepos (b
, linepos
);
15936 linepos
= BUF_BEGV (b
);
15937 linepos_byte
= BUF_BEGV_BYTE (b
);
15940 /* Count lines from base line to window start position. */
15941 nlines
= display_count_lines (linepos
, linepos_byte
,
15945 topline
= nlines
+ line
;
15947 /* Determine a new base line, if the old one is too close
15948 or too far away, or if we did not have one.
15949 "Too close" means it's plausible a scroll-down would
15950 go back past it. */
15951 if (startpos
== BUF_BEGV (b
))
15953 w
->base_line_number
= make_number (topline
);
15954 w
->base_line_pos
= make_number (BUF_BEGV (b
));
15956 else if (nlines
< height
+ 25 || nlines
> height
* 3 + 50
15957 || linepos
== BUF_BEGV (b
))
15959 int limit
= BUF_BEGV (b
);
15960 int limit_byte
= BUF_BEGV_BYTE (b
);
15962 int distance
= (height
* 2 + 30) * line_number_display_limit_width
;
15964 if (startpos
- distance
> limit
)
15966 limit
= startpos
- distance
;
15967 limit_byte
= CHAR_TO_BYTE (limit
);
15970 nlines
= display_count_lines (startpos
, startpos_byte
,
15972 - (height
* 2 + 30),
15974 /* If we couldn't find the lines we wanted within
15975 line_number_display_limit_width chars per line,
15976 give up on line numbers for this window. */
15977 if (position
== limit_byte
&& limit
== startpos
- distance
)
15979 w
->base_line_pos
= w
->buffer
;
15980 w
->base_line_number
= Qnil
;
15984 w
->base_line_number
= make_number (topline
- nlines
);
15985 w
->base_line_pos
= make_number (BYTE_TO_CHAR (position
));
15988 /* Now count lines from the start pos to point. */
15989 nlines
= display_count_lines (startpos
, startpos_byte
,
15990 PT_BYTE
, PT
, &junk
);
15992 /* Record that we did display the line number. */
15993 line_number_displayed
= 1;
15995 /* Make the string to show. */
15996 pint2str (decode_mode_spec_buf
, field_width
, topline
+ nlines
);
15997 return decode_mode_spec_buf
;
16000 char* p
= decode_mode_spec_buf
;
16001 int pad
= field_width
- 2;
16007 return decode_mode_spec_buf
;
16013 obj
= b
->mode_name
;
16017 if (BUF_BEGV (b
) > BUF_BEG (b
) || BUF_ZV (b
) < BUF_Z (b
))
16023 int pos
= marker_position (w
->start
);
16024 int total
= BUF_ZV (b
) - BUF_BEGV (b
);
16026 if (XFASTINT (w
->window_end_pos
) <= BUF_Z (b
) - BUF_ZV (b
))
16028 if (pos
<= BUF_BEGV (b
))
16033 else if (pos
<= BUF_BEGV (b
))
16037 if (total
> 1000000)
16038 /* Do it differently for a large value, to avoid overflow. */
16039 total
= ((pos
- BUF_BEGV (b
)) + (total
/ 100) - 1) / (total
/ 100);
16041 total
= ((pos
- BUF_BEGV (b
)) * 100 + total
- 1) / total
;
16042 /* We can't normally display a 3-digit number,
16043 so get us a 2-digit number that is close. */
16046 sprintf (decode_mode_spec_buf
, "%2d%%", total
);
16047 return decode_mode_spec_buf
;
16051 /* Display percentage of size above the bottom of the screen. */
16054 int toppos
= marker_position (w
->start
);
16055 int botpos
= BUF_Z (b
) - XFASTINT (w
->window_end_pos
);
16056 int total
= BUF_ZV (b
) - BUF_BEGV (b
);
16058 if (botpos
>= BUF_ZV (b
))
16060 if (toppos
<= BUF_BEGV (b
))
16067 if (total
> 1000000)
16068 /* Do it differently for a large value, to avoid overflow. */
16069 total
= ((botpos
- BUF_BEGV (b
)) + (total
/ 100) - 1) / (total
/ 100);
16071 total
= ((botpos
- BUF_BEGV (b
)) * 100 + total
- 1) / total
;
16072 /* We can't normally display a 3-digit number,
16073 so get us a 2-digit number that is close. */
16076 if (toppos
<= BUF_BEGV (b
))
16077 sprintf (decode_mode_spec_buf
, "Top%2d%%", total
);
16079 sprintf (decode_mode_spec_buf
, "%2d%%", total
);
16080 return decode_mode_spec_buf
;
16085 /* status of process */
16086 obj
= Fget_buffer_process (w
->buffer
);
16088 return "no process";
16089 #ifdef subprocesses
16090 obj
= Fsymbol_name (Fprocess_status (obj
));
16094 case 't': /* indicate TEXT or BINARY */
16095 #ifdef MODE_LINE_BINARY_TEXT
16096 return MODE_LINE_BINARY_TEXT (b
);
16102 /* coding-system (not including end-of-line format) */
16104 /* coding-system (including end-of-line type) */
16106 int eol_flag
= (c
== 'Z');
16107 char *p
= decode_mode_spec_buf
;
16109 if (! FRAME_WINDOW_P (f
))
16111 /* No need to mention EOL here--the terminal never needs
16112 to do EOL conversion. */
16113 p
= decode_mode_spec_coding (keyboard_coding
.symbol
, p
, 0);
16114 p
= decode_mode_spec_coding (terminal_coding
.symbol
, p
, 0);
16116 p
= decode_mode_spec_coding (b
->buffer_file_coding_system
,
16119 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
16120 #ifdef subprocesses
16121 obj
= Fget_buffer_process (Fcurrent_buffer ());
16122 if (PROCESSP (obj
))
16124 p
= decode_mode_spec_coding (XPROCESS (obj
)->decode_coding_system
,
16126 p
= decode_mode_spec_coding (XPROCESS (obj
)->encode_coding_system
,
16129 #endif /* subprocesses */
16132 return decode_mode_spec_buf
;
16138 *multibyte
= STRING_MULTIBYTE (obj
);
16139 return (char *) SDATA (obj
);
16146 /* Count up to COUNT lines starting from START / START_BYTE.
16147 But don't go beyond LIMIT_BYTE.
16148 Return the number of lines thus found (always nonnegative).
16150 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
16153 display_count_lines (start
, start_byte
, limit_byte
, count
, byte_pos_ptr
)
16154 int start
, start_byte
, limit_byte
, count
;
16157 register unsigned char *cursor
;
16158 unsigned char *base
;
16160 register int ceiling
;
16161 register unsigned char *ceiling_addr
;
16162 int orig_count
= count
;
16164 /* If we are not in selective display mode,
16165 check only for newlines. */
16166 int selective_display
= (!NILP (current_buffer
->selective_display
)
16167 && !INTEGERP (current_buffer
->selective_display
));
16171 while (start_byte
< limit_byte
)
16173 ceiling
= BUFFER_CEILING_OF (start_byte
);
16174 ceiling
= min (limit_byte
- 1, ceiling
);
16175 ceiling_addr
= BYTE_POS_ADDR (ceiling
) + 1;
16176 base
= (cursor
= BYTE_POS_ADDR (start_byte
));
16179 if (selective_display
)
16180 while (*cursor
!= '\n' && *cursor
!= 015 && ++cursor
!= ceiling_addr
)
16183 while (*cursor
!= '\n' && ++cursor
!= ceiling_addr
)
16186 if (cursor
!= ceiling_addr
)
16190 start_byte
+= cursor
- base
+ 1;
16191 *byte_pos_ptr
= start_byte
;
16195 if (++cursor
== ceiling_addr
)
16201 start_byte
+= cursor
- base
;
16206 while (start_byte
> limit_byte
)
16208 ceiling
= BUFFER_FLOOR_OF (start_byte
- 1);
16209 ceiling
= max (limit_byte
, ceiling
);
16210 ceiling_addr
= BYTE_POS_ADDR (ceiling
) - 1;
16211 base
= (cursor
= BYTE_POS_ADDR (start_byte
- 1) + 1);
16214 if (selective_display
)
16215 while (--cursor
!= ceiling_addr
16216 && *cursor
!= '\n' && *cursor
!= 015)
16219 while (--cursor
!= ceiling_addr
&& *cursor
!= '\n')
16222 if (cursor
!= ceiling_addr
)
16226 start_byte
+= cursor
- base
+ 1;
16227 *byte_pos_ptr
= start_byte
;
16228 /* When scanning backwards, we should
16229 not count the newline posterior to which we stop. */
16230 return - orig_count
- 1;
16236 /* Here we add 1 to compensate for the last decrement
16237 of CURSOR, which took it past the valid range. */
16238 start_byte
+= cursor
- base
+ 1;
16242 *byte_pos_ptr
= limit_byte
;
16245 return - orig_count
+ count
;
16246 return orig_count
- count
;
16252 /***********************************************************************
16254 ***********************************************************************/
16256 /* Display a NUL-terminated string, starting with index START.
16258 If STRING is non-null, display that C string. Otherwise, the Lisp
16259 string LISP_STRING is displayed.
16261 If FACE_STRING is not nil, FACE_STRING_POS is a position in
16262 FACE_STRING. Display STRING or LISP_STRING with the face at
16263 FACE_STRING_POS in FACE_STRING:
16265 Display the string in the environment given by IT, but use the
16266 standard display table, temporarily.
16268 FIELD_WIDTH is the minimum number of output glyphs to produce.
16269 If STRING has fewer characters than FIELD_WIDTH, pad to the right
16270 with spaces. If STRING has more characters, more than FIELD_WIDTH
16271 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
16273 PRECISION is the maximum number of characters to output from
16274 STRING. PRECISION < 0 means don't truncate the string.
16276 This is roughly equivalent to printf format specifiers:
16278 FIELD_WIDTH PRECISION PRINTF
16279 ----------------------------------------
16285 MULTIBYTE zero means do not display multibyte chars, > 0 means do
16286 display them, and < 0 means obey the current buffer's value of
16287 enable_multibyte_characters.
16289 Value is the number of glyphs produced. */
16292 display_string (string
, lisp_string
, face_string
, face_string_pos
,
16293 start
, it
, field_width
, precision
, max_x
, multibyte
)
16294 unsigned char *string
;
16295 Lisp_Object lisp_string
;
16296 Lisp_Object face_string
;
16297 int face_string_pos
;
16300 int field_width
, precision
, max_x
;
16303 int hpos_at_start
= it
->hpos
;
16304 int saved_face_id
= it
->face_id
;
16305 struct glyph_row
*row
= it
->glyph_row
;
16307 /* Initialize the iterator IT for iteration over STRING beginning
16308 with index START. */
16309 reseat_to_string (it
, string
, lisp_string
, start
,
16310 precision
, field_width
, multibyte
);
16312 /* If displaying STRING, set up the face of the iterator
16313 from LISP_STRING, if that's given. */
16314 if (STRINGP (face_string
))
16320 = face_at_string_position (it
->w
, face_string
, face_string_pos
,
16321 0, it
->region_beg_charpos
,
16322 it
->region_end_charpos
,
16323 &endptr
, it
->base_face_id
, 0);
16324 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
16325 it
->face_box_p
= face
->box
!= FACE_NO_BOX
;
16328 /* Set max_x to the maximum allowed X position. Don't let it go
16329 beyond the right edge of the window. */
16331 max_x
= it
->last_visible_x
;
16333 max_x
= min (max_x
, it
->last_visible_x
);
16335 /* Skip over display elements that are not visible. because IT->w is
16337 if (it
->current_x
< it
->first_visible_x
)
16338 move_it_in_display_line_to (it
, 100000, it
->first_visible_x
,
16339 MOVE_TO_POS
| MOVE_TO_X
);
16341 row
->ascent
= it
->max_ascent
;
16342 row
->height
= it
->max_ascent
+ it
->max_descent
;
16343 row
->phys_ascent
= it
->max_phys_ascent
;
16344 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
16346 /* This condition is for the case that we are called with current_x
16347 past last_visible_x. */
16348 while (it
->current_x
< max_x
)
16350 int x_before
, x
, n_glyphs_before
, i
, nglyphs
;
16352 /* Get the next display element. */
16353 if (!get_next_display_element (it
))
16356 /* Produce glyphs. */
16357 x_before
= it
->current_x
;
16358 n_glyphs_before
= it
->glyph_row
->used
[TEXT_AREA
];
16359 PRODUCE_GLYPHS (it
);
16361 nglyphs
= it
->glyph_row
->used
[TEXT_AREA
] - n_glyphs_before
;
16364 while (i
< nglyphs
)
16366 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
16368 if (!it
->truncate_lines_p
16369 && x
+ glyph
->pixel_width
> max_x
)
16371 /* End of continued line or max_x reached. */
16372 if (CHAR_GLYPH_PADDING_P (*glyph
))
16374 /* A wide character is unbreakable. */
16375 it
->glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
;
16376 it
->current_x
= x_before
;
16380 it
->glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
+ i
;
16385 else if (x
+ glyph
->pixel_width
> it
->first_visible_x
)
16387 /* Glyph is at least partially visible. */
16389 if (x
< it
->first_visible_x
)
16390 it
->glyph_row
->x
= x
- it
->first_visible_x
;
16394 /* Glyph is off the left margin of the display area.
16395 Should not happen. */
16399 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
16400 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
16401 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
16402 row
->phys_height
= max (row
->phys_height
,
16403 it
->max_phys_ascent
+ it
->max_phys_descent
);
16404 x
+= glyph
->pixel_width
;
16408 /* Stop if max_x reached. */
16412 /* Stop at line ends. */
16413 if (ITERATOR_AT_END_OF_LINE_P (it
))
16415 it
->continuation_lines_width
= 0;
16419 set_iterator_to_next (it
, 1);
16421 /* Stop if truncating at the right edge. */
16422 if (it
->truncate_lines_p
16423 && it
->current_x
>= it
->last_visible_x
)
16425 /* Add truncation mark, but don't do it if the line is
16426 truncated at a padding space. */
16427 if (IT_CHARPOS (*it
) < it
->string_nchars
)
16429 if (!FRAME_WINDOW_P (it
->f
))
16433 if (it
->current_x
> it
->last_visible_x
)
16435 for (i
= row
->used
[TEXT_AREA
] - 1; i
> 0; --i
)
16436 if (!CHAR_GLYPH_PADDING_P (row
->glyphs
[TEXT_AREA
][i
]))
16438 for (n
= row
->used
[TEXT_AREA
]; i
< n
; ++i
)
16440 row
->used
[TEXT_AREA
] = i
;
16441 produce_special_glyphs (it
, IT_TRUNCATION
);
16444 produce_special_glyphs (it
, IT_TRUNCATION
);
16446 it
->glyph_row
->truncated_on_right_p
= 1;
16452 /* Maybe insert a truncation at the left. */
16453 if (it
->first_visible_x
16454 && IT_CHARPOS (*it
) > 0)
16456 if (!FRAME_WINDOW_P (it
->f
))
16457 insert_left_trunc_glyphs (it
);
16458 it
->glyph_row
->truncated_on_left_p
= 1;
16461 it
->face_id
= saved_face_id
;
16463 /* Value is number of columns displayed. */
16464 return it
->hpos
- hpos_at_start
;
16469 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
16470 appears as an element of LIST or as the car of an element of LIST.
16471 If PROPVAL is a list, compare each element against LIST in that
16472 way, and return 1/2 if any element of PROPVAL is found in LIST.
16473 Otherwise return 0. This function cannot quit.
16474 The return value is 2 if the text is invisible but with an ellipsis
16475 and 1 if it's invisible and without an ellipsis. */
16478 invisible_p (propval
, list
)
16479 register Lisp_Object propval
;
16482 register Lisp_Object tail
, proptail
;
16484 for (tail
= list
; CONSP (tail
); tail
= XCDR (tail
))
16486 register Lisp_Object tem
;
16488 if (EQ (propval
, tem
))
16490 if (CONSP (tem
) && EQ (propval
, XCAR (tem
)))
16491 return NILP (XCDR (tem
)) ? 1 : 2;
16494 if (CONSP (propval
))
16496 for (proptail
= propval
; CONSP (proptail
); proptail
= XCDR (proptail
))
16498 Lisp_Object propelt
;
16499 propelt
= XCAR (proptail
);
16500 for (tail
= list
; CONSP (tail
); tail
= XCDR (tail
))
16502 register Lisp_Object tem
;
16504 if (EQ (propelt
, tem
))
16506 if (CONSP (tem
) && EQ (propelt
, XCAR (tem
)))
16507 return NILP (XCDR (tem
)) ? 1 : 2;
16516 /***********************************************************************
16518 ***********************************************************************/
16520 #ifdef HAVE_WINDOW_SYSTEM
16525 dump_glyph_string (s
)
16526 struct glyph_string
*s
;
16528 fprintf (stderr
, "glyph string\n");
16529 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
16530 s
->x
, s
->y
, s
->width
, s
->height
);
16531 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
16532 fprintf (stderr
, " hl = %d\n", s
->hl
);
16533 fprintf (stderr
, " left overhang = %d, right = %d\n",
16534 s
->left_overhang
, s
->right_overhang
);
16535 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
16536 fprintf (stderr
, " extends to end of line = %d\n",
16537 s
->extends_to_end_of_line_p
);
16538 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
16539 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
16542 #endif /* GLYPH_DEBUG */
16544 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
16545 of XChar2b structures for S; it can't be allocated in
16546 init_glyph_string because it must be allocated via `alloca'. W
16547 is the window on which S is drawn. ROW and AREA are the glyph row
16548 and area within the row from which S is constructed. START is the
16549 index of the first glyph structure covered by S. HL is a
16550 face-override for drawing S. */
16553 #define OPTIONAL_HDC(hdc) hdc,
16554 #define DECLARE_HDC(hdc) HDC hdc;
16555 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
16556 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
16559 #ifndef OPTIONAL_HDC
16560 #define OPTIONAL_HDC(hdc)
16561 #define DECLARE_HDC(hdc)
16562 #define ALLOCATE_HDC(hdc, f)
16563 #define RELEASE_HDC(hdc, f)
16567 init_glyph_string (s
, OPTIONAL_HDC (hdc
) char2b
, w
, row
, area
, start
, hl
)
16568 struct glyph_string
*s
;
16572 struct glyph_row
*row
;
16573 enum glyph_row_area area
;
16575 enum draw_glyphs_face hl
;
16577 bzero (s
, sizeof *s
);
16579 s
->f
= XFRAME (w
->frame
);
16583 s
->display
= FRAME_X_DISPLAY (s
->f
);
16584 s
->window
= FRAME_X_WINDOW (s
->f
);
16585 s
->char2b
= char2b
;
16589 s
->first_glyph
= row
->glyphs
[area
] + start
;
16590 s
->height
= row
->height
;
16591 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
16593 /* Display the internal border below the tool-bar window. */
16594 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
16595 s
->y
-= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
16597 s
->ybase
= s
->y
+ row
->ascent
;
16601 /* Append the list of glyph strings with head H and tail T to the list
16602 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
16605 append_glyph_string_lists (head
, tail
, h
, t
)
16606 struct glyph_string
**head
, **tail
;
16607 struct glyph_string
*h
, *t
;
16621 /* Prepend the list of glyph strings with head H and tail T to the
16622 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
16626 prepend_glyph_string_lists (head
, tail
, h
, t
)
16627 struct glyph_string
**head
, **tail
;
16628 struct glyph_string
*h
, *t
;
16642 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
16643 Set *HEAD and *TAIL to the resulting list. */
16646 append_glyph_string (head
, tail
, s
)
16647 struct glyph_string
**head
, **tail
;
16648 struct glyph_string
*s
;
16650 s
->next
= s
->prev
= NULL
;
16651 append_glyph_string_lists (head
, tail
, s
, s
);
16655 /* Get face and two-byte form of character glyph GLYPH on frame F.
16656 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
16657 a pointer to a realized face that is ready for display. */
16659 static INLINE
struct face
*
16660 get_glyph_face_and_encoding (f
, glyph
, char2b
, two_byte_p
)
16662 struct glyph
*glyph
;
16668 xassert (glyph
->type
== CHAR_GLYPH
);
16669 face
= FACE_FROM_ID (f
, glyph
->face_id
);
16674 if (!glyph
->multibyte_p
)
16676 /* Unibyte case. We don't have to encode, but we have to make
16677 sure to use a face suitable for unibyte. */
16678 STORE_XCHAR2B (char2b
, 0, glyph
->u
.ch
);
16680 else if (glyph
->u
.ch
< 128
16681 && glyph
->face_id
< BASIC_FACE_ID_SENTINEL
)
16683 /* Case of ASCII in a face known to fit ASCII. */
16684 STORE_XCHAR2B (char2b
, 0, glyph
->u
.ch
);
16688 int c1
, c2
, charset
;
16690 /* Split characters into bytes. If c2 is -1 afterwards, C is
16691 really a one-byte character so that byte1 is zero. */
16692 SPLIT_CHAR (glyph
->u
.ch
, charset
, c1
, c2
);
16694 STORE_XCHAR2B (char2b
, c1
, c2
);
16696 STORE_XCHAR2B (char2b
, 0, c1
);
16698 /* Maybe encode the character in *CHAR2B. */
16699 if (charset
!= CHARSET_ASCII
)
16701 struct font_info
*font_info
16702 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
16705 = FRAME_RIF (f
)->encode_char (glyph
->u
.ch
, char2b
, font_info
, two_byte_p
);
16709 /* Make sure X resources of the face are allocated. */
16710 xassert (face
!= NULL
);
16711 PREPARE_FACE_FOR_DISPLAY (f
, face
);
16716 /* Fill glyph string S with composition components specified by S->cmp.
16718 FACES is an array of faces for all components of this composition.
16719 S->gidx is the index of the first component for S.
16720 OVERLAPS_P non-zero means S should draw the foreground only, and
16721 use its physical height for clipping.
16723 Value is the index of a component not in S. */
16726 fill_composite_glyph_string (s
, faces
, overlaps_p
)
16727 struct glyph_string
*s
;
16728 struct face
**faces
;
16735 s
->for_overlaps_p
= overlaps_p
;
16737 s
->face
= faces
[s
->gidx
];
16738 s
->font
= s
->face
->font
;
16739 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
16741 /* For all glyphs of this composition, starting at the offset
16742 S->gidx, until we reach the end of the definition or encounter a
16743 glyph that requires the different face, add it to S. */
16745 for (i
= s
->gidx
+ 1; i
< s
->cmp
->glyph_len
&& faces
[i
] == s
->face
; ++i
)
16748 /* All glyph strings for the same composition has the same width,
16749 i.e. the width set for the first component of the composition. */
16751 s
->width
= s
->first_glyph
->pixel_width
;
16753 /* If the specified font could not be loaded, use the frame's
16754 default font, but record the fact that we couldn't load it in
16755 the glyph string so that we can draw rectangles for the
16756 characters of the glyph string. */
16757 if (s
->font
== NULL
)
16759 s
->font_not_found_p
= 1;
16760 s
->font
= FRAME_FONT (s
->f
);
16763 /* Adjust base line for subscript/superscript text. */
16764 s
->ybase
+= s
->first_glyph
->voffset
;
16766 xassert (s
->face
&& s
->face
->gc
);
16768 /* This glyph string must always be drawn with 16-bit functions. */
16771 return s
->gidx
+ s
->nchars
;
16775 /* Fill glyph string S from a sequence of character glyphs.
16777 FACE_ID is the face id of the string. START is the index of the
16778 first glyph to consider, END is the index of the last + 1.
16779 OVERLAPS_P non-zero means S should draw the foreground only, and
16780 use its physical height for clipping.
16782 Value is the index of the first glyph not in S. */
16785 fill_glyph_string (s
, face_id
, start
, end
, overlaps_p
)
16786 struct glyph_string
*s
;
16788 int start
, end
, overlaps_p
;
16790 struct glyph
*glyph
, *last
;
16792 int glyph_not_available_p
;
16794 xassert (s
->f
== XFRAME (s
->w
->frame
));
16795 xassert (s
->nchars
== 0);
16796 xassert (start
>= 0 && end
> start
);
16798 s
->for_overlaps_p
= overlaps_p
,
16799 glyph
= s
->row
->glyphs
[s
->area
] + start
;
16800 last
= s
->row
->glyphs
[s
->area
] + end
;
16801 voffset
= glyph
->voffset
;
16803 glyph_not_available_p
= glyph
->glyph_not_available_p
;
16805 while (glyph
< last
16806 && glyph
->type
== CHAR_GLYPH
16807 && glyph
->voffset
== voffset
16808 /* Same face id implies same font, nowadays. */
16809 && glyph
->face_id
== face_id
16810 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
16814 s
->face
= get_glyph_face_and_encoding (s
->f
, glyph
,
16815 s
->char2b
+ s
->nchars
,
16817 s
->two_byte_p
= two_byte_p
;
16819 xassert (s
->nchars
<= end
- start
);
16820 s
->width
+= glyph
->pixel_width
;
16824 s
->font
= s
->face
->font
;
16825 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
16827 /* If the specified font could not be loaded, use the frame's font,
16828 but record the fact that we couldn't load it in
16829 S->font_not_found_p so that we can draw rectangles for the
16830 characters of the glyph string. */
16831 if (s
->font
== NULL
|| glyph_not_available_p
)
16833 s
->font_not_found_p
= 1;
16834 s
->font
= FRAME_FONT (s
->f
);
16837 /* Adjust base line for subscript/superscript text. */
16838 s
->ybase
+= voffset
;
16840 xassert (s
->face
&& s
->face
->gc
);
16841 return glyph
- s
->row
->glyphs
[s
->area
];
16845 /* Fill glyph string S from image glyph S->first_glyph. */
16848 fill_image_glyph_string (s
)
16849 struct glyph_string
*s
;
16851 xassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
16852 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
16854 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
16855 s
->font
= s
->face
->font
;
16856 s
->width
= s
->first_glyph
->pixel_width
;
16858 /* Adjust base line for subscript/superscript text. */
16859 s
->ybase
+= s
->first_glyph
->voffset
;
16863 /* Fill glyph string S from a sequence of stretch glyphs.
16865 ROW is the glyph row in which the glyphs are found, AREA is the
16866 area within the row. START is the index of the first glyph to
16867 consider, END is the index of the last + 1.
16869 Value is the index of the first glyph not in S. */
16872 fill_stretch_glyph_string (s
, row
, area
, start
, end
)
16873 struct glyph_string
*s
;
16874 struct glyph_row
*row
;
16875 enum glyph_row_area area
;
16878 struct glyph
*glyph
, *last
;
16879 int voffset
, face_id
;
16881 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
16883 glyph
= s
->row
->glyphs
[s
->area
] + start
;
16884 last
= s
->row
->glyphs
[s
->area
] + end
;
16885 face_id
= glyph
->face_id
;
16886 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
16887 s
->font
= s
->face
->font
;
16888 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
16889 s
->width
= glyph
->pixel_width
;
16890 voffset
= glyph
->voffset
;
16894 && glyph
->type
== STRETCH_GLYPH
16895 && glyph
->voffset
== voffset
16896 && glyph
->face_id
== face_id
);
16898 s
->width
+= glyph
->pixel_width
;
16900 /* Adjust base line for subscript/superscript text. */
16901 s
->ybase
+= voffset
;
16903 /* The case that face->gc == 0 is handled when drawing the glyph
16904 string by calling PREPARE_FACE_FOR_DISPLAY. */
16906 return glyph
- s
->row
->glyphs
[s
->area
];
16911 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
16912 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
16913 assumed to be zero. */
16916 x_get_glyph_overhangs (glyph
, f
, left
, right
)
16917 struct glyph
*glyph
;
16921 *left
= *right
= 0;
16923 if (glyph
->type
== CHAR_GLYPH
)
16927 struct font_info
*font_info
;
16931 face
= get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
16933 font_info
= FONT_INFO_FROM_ID (f
, face
->font_info_id
);
16934 if (font
/* ++KFS: Should this be font_info ? */
16935 && (pcm
= FRAME_RIF (f
)->per_char_metric (font
, &char2b
, glyph
->font_type
)))
16937 if (pcm
->rbearing
> pcm
->width
)
16938 *right
= pcm
->rbearing
- pcm
->width
;
16939 if (pcm
->lbearing
< 0)
16940 *left
= -pcm
->lbearing
;
16946 /* Return the index of the first glyph preceding glyph string S that
16947 is overwritten by S because of S's left overhang. Value is -1
16948 if no glyphs are overwritten. */
16951 left_overwritten (s
)
16952 struct glyph_string
*s
;
16956 if (s
->left_overhang
)
16959 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
16960 int first
= s
->first_glyph
- glyphs
;
16962 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
16963 x
-= glyphs
[i
].pixel_width
;
16974 /* Return the index of the first glyph preceding glyph string S that
16975 is overwriting S because of its right overhang. Value is -1 if no
16976 glyph in front of S overwrites S. */
16979 left_overwriting (s
)
16980 struct glyph_string
*s
;
16983 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
16984 int first
= s
->first_glyph
- glyphs
;
16988 for (i
= first
- 1; i
>= 0; --i
)
16991 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
16994 x
-= glyphs
[i
].pixel_width
;
17001 /* Return the index of the last glyph following glyph string S that is
17002 not overwritten by S because of S's right overhang. Value is -1 if
17003 no such glyph is found. */
17006 right_overwritten (s
)
17007 struct glyph_string
*s
;
17011 if (s
->right_overhang
)
17014 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
17015 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
17016 int end
= s
->row
->used
[s
->area
];
17018 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
17019 x
+= glyphs
[i
].pixel_width
;
17028 /* Return the index of the last glyph following glyph string S that
17029 overwrites S because of its left overhang. Value is negative
17030 if no such glyph is found. */
17033 right_overwriting (s
)
17034 struct glyph_string
*s
;
17037 int end
= s
->row
->used
[s
->area
];
17038 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
17039 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
17043 for (i
= first
; i
< end
; ++i
)
17046 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
17049 x
+= glyphs
[i
].pixel_width
;
17056 /* Get face and two-byte form of character C in face FACE_ID on frame
17057 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
17058 means we want to display multibyte text. DISPLAY_P non-zero means
17059 make sure that X resources for the face returned are allocated.
17060 Value is a pointer to a realized face that is ready for display if
17061 DISPLAY_P is non-zero. */
17063 static INLINE
struct face
*
17064 get_char_face_and_encoding (f
, c
, face_id
, char2b
, multibyte_p
, display_p
)
17068 int multibyte_p
, display_p
;
17070 struct face
*face
= FACE_FROM_ID (f
, face_id
);
17074 /* Unibyte case. We don't have to encode, but we have to make
17075 sure to use a face suitable for unibyte. */
17076 STORE_XCHAR2B (char2b
, 0, c
);
17077 face_id
= FACE_FOR_CHAR (f
, face
, c
);
17078 face
= FACE_FROM_ID (f
, face_id
);
17080 else if (c
< 128 && face_id
< BASIC_FACE_ID_SENTINEL
)
17082 /* Case of ASCII in a face known to fit ASCII. */
17083 STORE_XCHAR2B (char2b
, 0, c
);
17087 int c1
, c2
, charset
;
17089 /* Split characters into bytes. If c2 is -1 afterwards, C is
17090 really a one-byte character so that byte1 is zero. */
17091 SPLIT_CHAR (c
, charset
, c1
, c2
);
17093 STORE_XCHAR2B (char2b
, c1
, c2
);
17095 STORE_XCHAR2B (char2b
, 0, c1
);
17097 /* Maybe encode the character in *CHAR2B. */
17098 if (face
->font
!= NULL
)
17100 struct font_info
*font_info
17101 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
17103 FRAME_RIF (f
)->encode_char (c
, char2b
, font_info
, 0);
17107 /* Make sure X resources of the face are allocated. */
17108 #ifdef HAVE_X_WINDOWS
17112 xassert (face
!= NULL
);
17113 PREPARE_FACE_FOR_DISPLAY (f
, face
);
17120 /* Set background width of glyph string S. START is the index of the
17121 first glyph following S. LAST_X is the right-most x-position + 1
17122 in the drawing area. */
17125 set_glyph_string_background_width (s
, start
, last_x
)
17126 struct glyph_string
*s
;
17130 /* If the face of this glyph string has to be drawn to the end of
17131 the drawing area, set S->extends_to_end_of_line_p. */
17132 struct face
*default_face
= FACE_FROM_ID (s
->f
, DEFAULT_FACE_ID
);
17134 if (start
== s
->row
->used
[s
->area
]
17135 && s
->area
== TEXT_AREA
17136 && ((s
->hl
== DRAW_NORMAL_TEXT
17137 && (s
->row
->fill_line_p
17138 || s
->face
->background
!= default_face
->background
17139 || s
->face
->stipple
!= default_face
->stipple
17140 || s
->row
->mouse_face_p
))
17141 || s
->hl
== DRAW_MOUSE_FACE
17142 || ((s
->hl
== DRAW_IMAGE_RAISED
|| s
->hl
== DRAW_IMAGE_SUNKEN
)
17143 && s
->row
->fill_line_p
)))
17144 s
->extends_to_end_of_line_p
= 1;
17146 /* If S extends its face to the end of the line, set its
17147 background_width to the distance to the right edge of the drawing
17149 if (s
->extends_to_end_of_line_p
)
17150 s
->background_width
= last_x
- s
->x
+ 1;
17152 s
->background_width
= s
->width
;
17156 /* Compute overhangs and x-positions for glyph string S and its
17157 predecessors, or successors. X is the starting x-position for S.
17158 BACKWARD_P non-zero means process predecessors. */
17161 compute_overhangs_and_x (s
, x
, backward_p
)
17162 struct glyph_string
*s
;
17170 if (FRAME_RIF (s
->f
)->compute_glyph_string_overhangs
)
17171 FRAME_RIF (s
->f
)->compute_glyph_string_overhangs (s
);
17181 if (FRAME_RIF (s
->f
)->compute_glyph_string_overhangs
)
17182 FRAME_RIF (s
->f
)->compute_glyph_string_overhangs (s
);
17192 /* The following macros are only called from draw_glyphs below.
17193 They reference the following parameters of that function directly:
17194 `w', `row', `area', and `overlap_p'
17195 as well as the following local variables:
17196 `s', `f', and `hdc' (in W32) */
17199 /* On W32, silently add local `hdc' variable to argument list of
17200 init_glyph_string. */
17201 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17202 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
17204 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17205 init_glyph_string (s, char2b, w, row, area, start, hl)
17208 /* Add a glyph string for a stretch glyph to the list of strings
17209 between HEAD and TAIL. START is the index of the stretch glyph in
17210 row area AREA of glyph row ROW. END is the index of the last glyph
17211 in that glyph row area. X is the current output position assigned
17212 to the new glyph string constructed. HL overrides that face of the
17213 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17214 is the right-most x-position of the drawing area. */
17216 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
17217 and below -- keep them on one line. */
17218 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17221 s = (struct glyph_string *) alloca (sizeof *s); \
17222 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17223 START = fill_stretch_glyph_string (s, row, area, START, END); \
17224 append_glyph_string (&HEAD, &TAIL, s); \
17230 /* Add a glyph string for an image glyph to the list of strings
17231 between HEAD and TAIL. START is the index of the image glyph in
17232 row area AREA of glyph row ROW. END is the index of the last glyph
17233 in that glyph row area. X is the current output position assigned
17234 to the new glyph string constructed. HL overrides that face of the
17235 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17236 is the right-most x-position of the drawing area. */
17238 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17241 s = (struct glyph_string *) alloca (sizeof *s); \
17242 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17243 fill_image_glyph_string (s); \
17244 append_glyph_string (&HEAD, &TAIL, s); \
17251 /* Add a glyph string for a sequence of character glyphs to the list
17252 of strings between HEAD and TAIL. START is the index of the first
17253 glyph in row area AREA of glyph row ROW that is part of the new
17254 glyph string. END is the index of the last glyph in that glyph row
17255 area. X is the current output position assigned to the new glyph
17256 string constructed. HL overrides that face of the glyph; e.g. it
17257 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
17258 right-most x-position of the drawing area. */
17260 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17266 c = (row)->glyphs[area][START].u.ch; \
17267 face_id = (row)->glyphs[area][START].face_id; \
17269 s = (struct glyph_string *) alloca (sizeof *s); \
17270 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
17271 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
17272 append_glyph_string (&HEAD, &TAIL, s); \
17274 START = fill_glyph_string (s, face_id, START, END, overlaps_p); \
17279 /* Add a glyph string for a composite sequence to the list of strings
17280 between HEAD and TAIL. START is the index of the first glyph in
17281 row area AREA of glyph row ROW that is part of the new glyph
17282 string. END is the index of the last glyph in that glyph row area.
17283 X is the current output position assigned to the new glyph string
17284 constructed. HL overrides that face of the glyph; e.g. it is
17285 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
17286 x-position of the drawing area. */
17288 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17290 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
17291 int face_id = (row)->glyphs[area][START].face_id; \
17292 struct face *base_face = FACE_FROM_ID (f, face_id); \
17293 struct composition *cmp = composition_table[cmp_id]; \
17294 int glyph_len = cmp->glyph_len; \
17296 struct face **faces; \
17297 struct glyph_string *first_s = NULL; \
17300 base_face = base_face->ascii_face; \
17301 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
17302 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
17303 /* At first, fill in `char2b' and `faces'. */ \
17304 for (n = 0; n < glyph_len; n++) \
17306 int c = COMPOSITION_GLYPH (cmp, n); \
17307 int this_face_id = FACE_FOR_CHAR (f, base_face, c); \
17308 faces[n] = FACE_FROM_ID (f, this_face_id); \
17309 get_char_face_and_encoding (f, c, this_face_id, \
17310 char2b + n, 1, 1); \
17313 /* Make glyph_strings for each glyph sequence that is drawable by \
17314 the same face, and append them to HEAD/TAIL. */ \
17315 for (n = 0; n < cmp->glyph_len;) \
17317 s = (struct glyph_string *) alloca (sizeof *s); \
17318 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \
17319 append_glyph_string (&(HEAD), &(TAIL), s); \
17327 n = fill_composite_glyph_string (s, faces, overlaps_p); \
17335 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
17336 of AREA of glyph row ROW on window W between indices START and END.
17337 HL overrides the face for drawing glyph strings, e.g. it is
17338 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
17339 x-positions of the drawing area.
17341 This is an ugly monster macro construct because we must use alloca
17342 to allocate glyph strings (because draw_glyphs can be called
17343 asynchronously). */
17345 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17348 HEAD = TAIL = NULL; \
17349 while (START < END) \
17351 struct glyph *first_glyph = (row)->glyphs[area] + START; \
17352 switch (first_glyph->type) \
17355 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
17359 case COMPOSITE_GLYPH: \
17360 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
17364 case STRETCH_GLYPH: \
17365 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
17369 case IMAGE_GLYPH: \
17370 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
17378 set_glyph_string_background_width (s, START, LAST_X); \
17385 /* Draw glyphs between START and END in AREA of ROW on window W,
17386 starting at x-position X. X is relative to AREA in W. HL is a
17387 face-override with the following meaning:
17389 DRAW_NORMAL_TEXT draw normally
17390 DRAW_CURSOR draw in cursor face
17391 DRAW_MOUSE_FACE draw in mouse face.
17392 DRAW_INVERSE_VIDEO draw in mode line face
17393 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
17394 DRAW_IMAGE_RAISED draw an image with a raised relief around it
17396 If OVERLAPS_P is non-zero, draw only the foreground of characters
17397 and clip to the physical height of ROW.
17399 Value is the x-position reached, relative to AREA of W. */
17402 draw_glyphs (w
, x
, row
, area
, start
, end
, hl
, overlaps_p
)
17405 struct glyph_row
*row
;
17406 enum glyph_row_area area
;
17408 enum draw_glyphs_face hl
;
17411 struct glyph_string
*head
, *tail
;
17412 struct glyph_string
*s
;
17413 int last_x
, area_width
;
17416 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
17419 ALLOCATE_HDC (hdc
, f
);
17421 /* Let's rather be paranoid than getting a SEGV. */
17422 end
= min (end
, row
->used
[area
]);
17423 start
= max (0, start
);
17424 start
= min (end
, start
);
17426 /* Translate X to frame coordinates. Set last_x to the right
17427 end of the drawing area. */
17428 if (row
->full_width_p
)
17430 /* X is relative to the left edge of W, without scroll bars
17432 x
+= WINDOW_LEFT_EDGE_X (w
);
17433 last_x
= WINDOW_LEFT_EDGE_X (w
) + WINDOW_TOTAL_WIDTH (w
);
17437 int area_left
= window_box_left (w
, area
);
17439 area_width
= window_box_width (w
, area
);
17440 last_x
= area_left
+ area_width
;
17443 /* Build a doubly-linked list of glyph_string structures between
17444 head and tail from what we have to draw. Note that the macro
17445 BUILD_GLYPH_STRINGS will modify its start parameter. That's
17446 the reason we use a separate variable `i'. */
17448 BUILD_GLYPH_STRINGS (i
, end
, head
, tail
, hl
, x
, last_x
);
17450 x_reached
= tail
->x
+ tail
->background_width
;
17454 /* If there are any glyphs with lbearing < 0 or rbearing > width in
17455 the row, redraw some glyphs in front or following the glyph
17456 strings built above. */
17457 if (head
&& !overlaps_p
&& row
->contains_overlapping_glyphs_p
)
17460 struct glyph_string
*h
, *t
;
17462 /* Compute overhangs for all glyph strings. */
17463 if (FRAME_RIF (f
)->compute_glyph_string_overhangs
)
17464 for (s
= head
; s
; s
= s
->next
)
17465 FRAME_RIF (f
)->compute_glyph_string_overhangs (s
);
17467 /* Prepend glyph strings for glyphs in front of the first glyph
17468 string that are overwritten because of the first glyph
17469 string's left overhang. The background of all strings
17470 prepended must be drawn because the first glyph string
17472 i
= left_overwritten (head
);
17476 BUILD_GLYPH_STRINGS (j
, start
, h
, t
,
17477 DRAW_NORMAL_TEXT
, dummy_x
, last_x
);
17479 compute_overhangs_and_x (t
, head
->x
, 1);
17480 prepend_glyph_string_lists (&head
, &tail
, h
, t
);
17483 /* Prepend glyph strings for glyphs in front of the first glyph
17484 string that overwrite that glyph string because of their
17485 right overhang. For these strings, only the foreground must
17486 be drawn, because it draws over the glyph string at `head'.
17487 The background must not be drawn because this would overwrite
17488 right overhangs of preceding glyphs for which no glyph
17490 i
= left_overwriting (head
);
17493 BUILD_GLYPH_STRINGS (i
, start
, h
, t
,
17494 DRAW_NORMAL_TEXT
, dummy_x
, last_x
);
17495 for (s
= h
; s
; s
= s
->next
)
17496 s
->background_filled_p
= 1;
17497 compute_overhangs_and_x (t
, head
->x
, 1);
17498 prepend_glyph_string_lists (&head
, &tail
, h
, t
);
17501 /* Append glyphs strings for glyphs following the last glyph
17502 string tail that are overwritten by tail. The background of
17503 these strings has to be drawn because tail's foreground draws
17505 i
= right_overwritten (tail
);
17508 BUILD_GLYPH_STRINGS (end
, i
, h
, t
,
17509 DRAW_NORMAL_TEXT
, x
, last_x
);
17510 compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
17511 append_glyph_string_lists (&head
, &tail
, h
, t
);
17514 /* Append glyph strings for glyphs following the last glyph
17515 string tail that overwrite tail. The foreground of such
17516 glyphs has to be drawn because it writes into the background
17517 of tail. The background must not be drawn because it could
17518 paint over the foreground of following glyphs. */
17519 i
= right_overwriting (tail
);
17522 BUILD_GLYPH_STRINGS (end
, i
, h
, t
,
17523 DRAW_NORMAL_TEXT
, x
, last_x
);
17524 for (s
= h
; s
; s
= s
->next
)
17525 s
->background_filled_p
= 1;
17526 compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
17527 append_glyph_string_lists (&head
, &tail
, h
, t
);
17531 /* Draw all strings. */
17532 for (s
= head
; s
; s
= s
->next
)
17533 FRAME_RIF (f
)->draw_glyph_string (s
);
17535 if (area
== TEXT_AREA
17536 && !row
->full_width_p
17537 /* When drawing overlapping rows, only the glyph strings'
17538 foreground is drawn, which doesn't erase a cursor
17542 int x0
= head
? head
->x
: x
;
17543 int x1
= tail
? tail
->x
+ tail
->background_width
: x
;
17545 int text_left
= window_box_left (w
, TEXT_AREA
);
17549 notice_overwritten_cursor (w
, TEXT_AREA
, x0
, x1
,
17550 row
->y
, MATRIX_ROW_BOTTOM_Y (row
));
17553 /* Value is the x-position up to which drawn, relative to AREA of W.
17554 This doesn't include parts drawn because of overhangs. */
17555 if (row
->full_width_p
)
17556 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
17558 x_reached
-= window_box_left (w
, area
);
17560 RELEASE_HDC (hdc
, f
);
17566 /* Store one glyph for IT->char_to_display in IT->glyph_row.
17567 Called from x_produce_glyphs when IT->glyph_row is non-null. */
17573 struct glyph
*glyph
;
17574 enum glyph_row_area area
= it
->area
;
17576 xassert (it
->glyph_row
);
17577 xassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
17579 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
17580 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
17582 glyph
->charpos
= CHARPOS (it
->position
);
17583 glyph
->object
= it
->object
;
17584 glyph
->pixel_width
= it
->pixel_width
;
17585 glyph
->ascent
= it
->ascent
;
17586 glyph
->descent
= it
->descent
;
17587 glyph
->voffset
= it
->voffset
;
17588 glyph
->type
= CHAR_GLYPH
;
17589 glyph
->multibyte_p
= it
->multibyte_p
;
17590 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
17591 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
17592 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
17593 || it
->phys_descent
> it
->descent
);
17594 glyph
->padding_p
= 0;
17595 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
17596 glyph
->face_id
= it
->face_id
;
17597 glyph
->u
.ch
= it
->char_to_display
;
17598 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
17599 ++it
->glyph_row
->used
[area
];
17603 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
17604 Called from x_produce_glyphs when IT->glyph_row is non-null. */
17607 append_composite_glyph (it
)
17610 struct glyph
*glyph
;
17611 enum glyph_row_area area
= it
->area
;
17613 xassert (it
->glyph_row
);
17615 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
17616 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
17618 glyph
->charpos
= CHARPOS (it
->position
);
17619 glyph
->object
= it
->object
;
17620 glyph
->pixel_width
= it
->pixel_width
;
17621 glyph
->ascent
= it
->ascent
;
17622 glyph
->descent
= it
->descent
;
17623 glyph
->voffset
= it
->voffset
;
17624 glyph
->type
= COMPOSITE_GLYPH
;
17625 glyph
->multibyte_p
= it
->multibyte_p
;
17626 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
17627 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
17628 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
17629 || it
->phys_descent
> it
->descent
);
17630 glyph
->padding_p
= 0;
17631 glyph
->glyph_not_available_p
= 0;
17632 glyph
->face_id
= it
->face_id
;
17633 glyph
->u
.cmp_id
= it
->cmp_id
;
17634 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
17635 ++it
->glyph_row
->used
[area
];
17640 /* Change IT->ascent and IT->height according to the setting of
17644 take_vertical_position_into_account (it
)
17649 if (it
->voffset
< 0)
17650 /* Increase the ascent so that we can display the text higher
17652 it
->ascent
+= abs (it
->voffset
);
17654 /* Increase the descent so that we can display the text lower
17656 it
->descent
+= it
->voffset
;
17661 /* Produce glyphs/get display metrics for the image IT is loaded with.
17662 See the description of struct display_iterator in dispextern.h for
17663 an overview of struct display_iterator. */
17666 produce_image_glyph (it
)
17671 int face_ascent
, glyph_ascent
;
17673 xassert (it
->what
== IT_IMAGE
);
17675 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
17676 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
17679 /* Make sure X resources of the face and image are loaded. */
17680 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
17681 prepare_image_for_display (it
->f
, img
);
17683 it
->ascent
= it
->phys_ascent
= glyph_ascent
= image_ascent (img
, face
);
17684 it
->descent
= it
->phys_descent
= img
->height
+ 2 * img
->vmargin
- it
->ascent
;
17685 it
->pixel_width
= img
->width
+ 2 * img
->hmargin
;
17687 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
17688 face_ascent
= face
->font
? FONT_BASE (face
->font
) : FRAME_BASELINE_OFFSET (it
->f
);
17689 if (face_ascent
> it
->ascent
)
17690 it
->ascent
= it
->phys_ascent
= face_ascent
;
17694 if (face
->box
!= FACE_NO_BOX
)
17696 if (face
->box_line_width
> 0)
17698 it
->ascent
+= face
->box_line_width
;
17699 it
->descent
+= face
->box_line_width
;
17702 if (it
->start_of_box_run_p
)
17703 it
->pixel_width
+= abs (face
->box_line_width
);
17704 if (it
->end_of_box_run_p
)
17705 it
->pixel_width
+= abs (face
->box_line_width
);
17708 take_vertical_position_into_account (it
);
17712 struct glyph
*glyph
;
17713 enum glyph_row_area area
= it
->area
;
17715 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
17716 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
17718 glyph
->charpos
= CHARPOS (it
->position
);
17719 glyph
->object
= it
->object
;
17720 glyph
->pixel_width
= it
->pixel_width
;
17721 glyph
->ascent
= glyph_ascent
;
17722 glyph
->descent
= it
->descent
;
17723 glyph
->voffset
= it
->voffset
;
17724 glyph
->type
= IMAGE_GLYPH
;
17725 glyph
->multibyte_p
= it
->multibyte_p
;
17726 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
17727 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
17728 glyph
->overlaps_vertically_p
= 0;
17729 glyph
->padding_p
= 0;
17730 glyph
->glyph_not_available_p
= 0;
17731 glyph
->face_id
= it
->face_id
;
17732 glyph
->u
.img_id
= img
->id
;
17733 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
17734 ++it
->glyph_row
->used
[area
];
17740 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
17741 of the glyph, WIDTH and HEIGHT are the width and height of the
17742 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
17745 append_stretch_glyph (it
, object
, width
, height
, ascent
)
17747 Lisp_Object object
;
17751 struct glyph
*glyph
;
17752 enum glyph_row_area area
= it
->area
;
17754 xassert (ascent
>= 0 && ascent
<= height
);
17756 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
17757 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
17759 glyph
->charpos
= CHARPOS (it
->position
);
17760 glyph
->object
= object
;
17761 glyph
->pixel_width
= width
;
17762 glyph
->ascent
= ascent
;
17763 glyph
->descent
= height
- ascent
;
17764 glyph
->voffset
= it
->voffset
;
17765 glyph
->type
= STRETCH_GLYPH
;
17766 glyph
->multibyte_p
= it
->multibyte_p
;
17767 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
17768 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
17769 glyph
->overlaps_vertically_p
= 0;
17770 glyph
->padding_p
= 0;
17771 glyph
->glyph_not_available_p
= 0;
17772 glyph
->face_id
= it
->face_id
;
17773 glyph
->u
.stretch
.ascent
= ascent
;
17774 glyph
->u
.stretch
.height
= height
;
17775 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
17776 ++it
->glyph_row
->used
[area
];
17781 /* Calculate a width or height in pixels from a specification using
17782 the following elements:
17785 NUM - a (fractional) multiple of the default font width/height
17786 (NUM) - specifies exactly NUM pixels
17787 UNIT - a fixed number of pixels, see below.
17788 ELEMENT - size of a display element in pixels, see below.
17789 (NUM . SPEC) - equals NUM * SPEC
17790 (+ SPEC SPEC ...) - add pixel values
17791 (- SPEC SPEC ...) - subtract pixel values
17792 (- SPEC) - negate pixel value
17795 INT or FLOAT - a number constant
17796 SYMBOL - use symbol's (buffer local) variable binding.
17799 in - pixels per inch *)
17800 mm - pixels per 1/1000 meter *)
17801 cm - pixels per 1/100 meter *)
17802 width - width of current font in pixels.
17803 height - height of current font in pixels.
17805 *) using the ratio(s) defined in display-pixels-per-inch.
17809 left-fringe - left fringe width in pixels
17810 (left-fringe . nil) - left fringe width if inside margins, else 0
17811 (left-fringe . t) - left fringe width if outside margins, else 0
17813 right-fringe - right fringe width in pixels
17814 (right-fringe . nil) - right fringe width if inside margins, else 0
17815 (right-fringe . t) - right fringe width if outside margins, else 0
17817 left-margin - left margin width in pixels
17818 right-margin - right margin width in pixels
17820 scroll-bar - scroll-bar area width in pixels
17821 (scroll-bar . left) - scroll-bar width if on left, else 0
17822 (scroll-bar . right) - scroll-bar width if on right, else 0
17826 Pixels corresponding to 5 inches:
17829 Total width of non-text areas on left side of window:
17830 (+ left-fringe left-margin (scroll-bar . left))
17832 Total width of fringes if inside display margins:
17833 (+ (left-fringe) (right-fringe))
17835 Width of left margin minus width of 1 character in the default font:
17838 Width of left margin minus width of 2 characters in the current font:
17839 (- left-margin (2 . width))
17841 Width of left fringe plus left margin minus one pixel:
17842 (- (+ left-fringe left-margin) (1))
17843 (+ left-fringe left-margin (- (1)))
17844 (+ left-fringe left-margin (-1))
17848 #define NUMVAL(X) \
17849 ((INTEGERP (X) || FLOATP (X)) \
17854 calc_pixel_width_or_height (res
, it
, prop
, font
, width_p
)
17863 #define OK_PIXELS(val) ((*res = (val)), 1)
17865 if (SYMBOLP (prop
))
17867 if (SCHARS (SYMBOL_NAME (prop
)) == 2)
17869 char *unit
= SDATA (SYMBOL_NAME (prop
));
17871 if (unit
[0] == 'i' && unit
[1] == 'n')
17873 else if (unit
[0] == 'm' && unit
[1] == 'm')
17875 else if (unit
[0] == 'c' && unit
[1] == 'm')
17882 if ((ppi
= NUMVAL (Vdisplay_pixels_per_inch
), ppi
> 0)
17883 || (CONSP (Vdisplay_pixels_per_inch
)
17885 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch
))
17886 : NUMVAL (XCDR (Vdisplay_pixels_per_inch
))),
17888 return OK_PIXELS (ppi
/ pixels
);
17894 if (EQ (prop
, Qheight
))
17895 return OK_PIXELS (font
? FONT_HEIGHT (font
) : FRAME_LINE_HEIGHT (it
->f
));
17896 if (EQ (prop
, Qwidth
))
17897 return OK_PIXELS (font
? FONT_WIDTH (font
) : FRAME_COLUMN_WIDTH (it
->f
));
17898 if (EQ (prop
, Qleft_fringe
))
17899 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it
->w
));
17900 if (EQ (prop
, Qright_fringe
))
17901 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it
->w
));
17902 if (EQ (prop
, Qleft_margin
))
17903 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it
->w
));
17904 if (EQ (prop
, Qright_margin
))
17905 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it
->w
));
17906 if (EQ (prop
, Qscroll_bar
))
17907 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it
->w
));
17909 prop
= Fbuffer_local_value (prop
, it
->w
->buffer
);
17912 if (INTEGERP (prop
) || FLOATP (prop
))
17914 int base_unit
= (width_p
17915 ? FRAME_COLUMN_WIDTH (it
->f
)
17916 : FRAME_LINE_HEIGHT (it
->f
));
17917 return OK_PIXELS (XFLOATINT (prop
) * base_unit
);
17922 Lisp_Object car
= XCAR (prop
);
17923 Lisp_Object cdr
= XCDR (prop
);
17927 if (EQ (car
, Qplus
) || EQ (car
, Qminus
))
17933 while (CONSP (cdr
))
17935 if (!calc_pixel_width_or_height (&px
, it
, XCAR (cdr
), font
, width_p
))
17938 pixels
= (EQ (car
, Qplus
) ? px
: -px
), first
= 0;
17943 if (EQ (car
, Qminus
))
17945 return OK_PIXELS (pixels
);
17948 if (EQ (car
, Qleft_fringe
))
17949 return OK_PIXELS ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it
->w
)
17951 ? WINDOW_LEFT_FRINGE_WIDTH (it
->w
)
17953 if (EQ (car
, Qright_fringe
))
17954 return OK_PIXELS ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it
->w
)
17956 ? WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)
17958 if (EQ (car
, Qscroll_bar
))
17959 return OK_PIXELS ((WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it
->w
)
17960 == EQ (cdr
, Qleft
))
17961 ? WINDOW_SCROLL_BAR_AREA_WIDTH (it
->w
)
17964 car
= Fbuffer_local_value (car
, it
->w
->buffer
);
17967 if (INTEGERP (car
) || FLOATP (car
))
17970 pixels
= XFLOATINT (car
);
17972 return OK_PIXELS (pixels
);
17973 if (calc_pixel_width_or_height (&fact
, it
, cdr
, font
, width_p
))
17974 return OK_PIXELS (pixels
* fact
);
17984 /* Produce a stretch glyph for iterator IT. IT->object is the value
17985 of the glyph property displayed. The value must be a list
17986 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
17989 1. `:width WIDTH' specifies that the space should be WIDTH *
17990 canonical char width wide. WIDTH may be an integer or floating
17993 2. `:relative-width FACTOR' specifies that the width of the stretch
17994 should be computed from the width of the first character having the
17995 `glyph' property, and should be FACTOR times that width.
17997 3. `:align-to HPOS' specifies that the space should be wide enough
17998 to reach HPOS, a value in canonical character units.
18000 Exactly one of the above pairs must be present.
18002 4. `:height HEIGHT' specifies that the height of the stretch produced
18003 should be HEIGHT, measured in canonical character units.
18005 5. `:relative-height FACTOR' specifies that the height of the
18006 stretch should be FACTOR times the height of the characters having
18007 the glyph property.
18009 Either none or exactly one of 4 or 5 must be present.
18011 6. `:ascent ASCENT' specifies that ASCENT percent of the height
18012 of the stretch should be used for the ascent of the stretch.
18013 ASCENT must be in the range 0 <= ASCENT <= 100. */
18016 produce_stretch_glyph (it
)
18019 /* (space :width WIDTH :height HEIGHT ...) */
18020 Lisp_Object prop
, plist
;
18021 int width
= 0, height
= 0;
18022 int zero_width_ok_p
= 0, zero_height_ok_p
= 0;
18025 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
18026 XFontStruct
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
18028 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
18030 /* List should start with `space'. */
18031 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
18032 plist
= XCDR (it
->object
);
18034 /* Compute the width of the stretch. */
18035 if ((prop
= Fplist_get (plist
, QCwidth
), !NILP (prop
))
18036 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 1))
18038 /* Absolute width `:width WIDTH' specified and valid. */
18039 zero_width_ok_p
= 1;
18042 else if (prop
= Fplist_get (plist
, QCrelative_width
),
18045 /* Relative width `:relative-width FACTOR' specified and valid.
18046 Compute the width of the characters having the `glyph'
18049 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
18052 if (it
->multibyte_p
)
18054 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT
? ZV
: GPT
)
18055 - IT_BYTEPOS (*it
));
18056 it2
.c
= STRING_CHAR_AND_LENGTH (p
, maxlen
, it2
.len
);
18059 it2
.c
= *p
, it2
.len
= 1;
18061 it2
.glyph_row
= NULL
;
18062 it2
.what
= IT_CHARACTER
;
18063 x_produce_glyphs (&it2
);
18064 width
= NUMVAL (prop
) * it2
.pixel_width
;
18066 else if ((prop
= Fplist_get (plist
, QCalign_to
), !NILP (prop
))
18067 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 1))
18069 width
= max (0, (int)tem
- it
->current_x
);
18070 zero_width_ok_p
= 1;
18073 /* Nothing specified -> width defaults to canonical char width. */
18074 width
= FRAME_COLUMN_WIDTH (it
->f
);
18076 if (width
<= 0 && (width
< 0 || !zero_width_ok_p
))
18079 /* Compute height. */
18080 if ((prop
= Fplist_get (plist
, QCheight
), !NILP (prop
))
18081 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 0))
18084 zero_height_ok_p
= 1;
18086 else if (prop
= Fplist_get (plist
, QCrelative_height
),
18088 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
18090 height
= FONT_HEIGHT (font
);
18092 if (height
<= 0 && (height
< 0 || !zero_height_ok_p
))
18095 /* Compute percentage of height used for ascent. If
18096 `:ascent ASCENT' is present and valid, use that. Otherwise,
18097 derive the ascent from the font in use. */
18098 if (prop
= Fplist_get (plist
, QCascent
),
18099 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
18100 ascent
= height
* NUMVAL (prop
) / 100.0;
18101 else if (!NILP (prop
)
18102 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 0))
18103 ascent
= min (max (0, (int)tem
), height
);
18105 ascent
= (height
* FONT_BASE (font
)) / FONT_HEIGHT (font
);
18107 if (width
> 0 && height
> 0 && it
->glyph_row
)
18109 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
18110 if (!STRINGP (object
))
18111 object
= it
->w
->buffer
;
18112 append_stretch_glyph (it
, object
, width
, height
, ascent
);
18115 it
->pixel_width
= width
;
18116 it
->ascent
= it
->phys_ascent
= ascent
;
18117 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
18118 it
->nglyphs
= width
> 0 && height
> 0 ? 1 : 0;
18120 if (width
> 0 && height
> 0 && face
->box
!= FACE_NO_BOX
)
18122 if (face
->box_line_width
> 0)
18124 it
->ascent
+= face
->box_line_width
;
18125 it
->descent
+= face
->box_line_width
;
18128 if (it
->start_of_box_run_p
)
18129 it
->pixel_width
+= abs (face
->box_line_width
);
18130 if (it
->end_of_box_run_p
)
18131 it
->pixel_width
+= abs (face
->box_line_width
);
18134 take_vertical_position_into_account (it
);
18138 Produce glyphs/get display metrics for the display element IT is
18139 loaded with. See the description of struct display_iterator in
18140 dispextern.h for an overview of struct display_iterator. */
18143 x_produce_glyphs (it
)
18146 it
->glyph_not_available_p
= 0;
18148 if (it
->what
== IT_CHARACTER
)
18152 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
18154 int font_not_found_p
;
18155 struct font_info
*font_info
;
18156 int boff
; /* baseline offset */
18157 /* We may change it->multibyte_p upon unibyte<->multibyte
18158 conversion. So, save the current value now and restore it
18161 Note: It seems that we don't have to record multibyte_p in
18162 struct glyph because the character code itself tells if or
18163 not the character is multibyte. Thus, in the future, we must
18164 consider eliminating the field `multibyte_p' in the struct
18166 int saved_multibyte_p
= it
->multibyte_p
;
18168 /* Maybe translate single-byte characters to multibyte, or the
18170 it
->char_to_display
= it
->c
;
18171 if (!ASCII_BYTE_P (it
->c
))
18173 if (unibyte_display_via_language_environment
18174 && SINGLE_BYTE_CHAR_P (it
->c
)
18176 || !NILP (Vnonascii_translation_table
)))
18178 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
18179 it
->multibyte_p
= 1;
18180 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
18181 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
18183 else if (!SINGLE_BYTE_CHAR_P (it
->c
)
18184 && !it
->multibyte_p
)
18186 it
->multibyte_p
= 1;
18187 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
18188 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
18192 /* Get font to use. Encode IT->char_to_display. */
18193 get_char_face_and_encoding (it
->f
, it
->char_to_display
, it
->face_id
,
18194 &char2b
, it
->multibyte_p
, 0);
18197 /* When no suitable font found, use the default font. */
18198 font_not_found_p
= font
== NULL
;
18199 if (font_not_found_p
)
18201 font
= FRAME_FONT (it
->f
);
18202 boff
= FRAME_BASELINE_OFFSET (it
->f
);
18207 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
18208 boff
= font_info
->baseline_offset
;
18209 if (font_info
->vertical_centering
)
18210 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
18213 if (it
->char_to_display
>= ' '
18214 && (!it
->multibyte_p
|| it
->char_to_display
< 128))
18216 /* Either unibyte or ASCII. */
18221 pcm
= FRAME_RIF (it
->f
)->per_char_metric (font
, &char2b
,
18222 FONT_TYPE_FOR_UNIBYTE (font
, it
->char_to_display
));
18223 it
->ascent
= FONT_BASE (font
) + boff
;
18224 it
->descent
= FONT_DESCENT (font
) - boff
;
18228 it
->phys_ascent
= pcm
->ascent
+ boff
;
18229 it
->phys_descent
= pcm
->descent
- boff
;
18230 it
->pixel_width
= pcm
->width
;
18234 it
->glyph_not_available_p
= 1;
18235 it
->phys_ascent
= FONT_BASE (font
) + boff
;
18236 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
18237 it
->pixel_width
= FONT_WIDTH (font
);
18240 /* If this is a space inside a region of text with
18241 `space-width' property, change its width. */
18242 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
18244 it
->pixel_width
*= XFLOATINT (it
->space_width
);
18246 /* If face has a box, add the box thickness to the character
18247 height. If character has a box line to the left and/or
18248 right, add the box line width to the character's width. */
18249 if (face
->box
!= FACE_NO_BOX
)
18251 int thick
= face
->box_line_width
;
18255 it
->ascent
+= thick
;
18256 it
->descent
+= thick
;
18261 if (it
->start_of_box_run_p
)
18262 it
->pixel_width
+= thick
;
18263 if (it
->end_of_box_run_p
)
18264 it
->pixel_width
+= thick
;
18267 /* If face has an overline, add the height of the overline
18268 (1 pixel) and a 1 pixel margin to the character height. */
18269 if (face
->overline_p
)
18272 take_vertical_position_into_account (it
);
18274 /* If we have to actually produce glyphs, do it. */
18279 /* Translate a space with a `space-width' property
18280 into a stretch glyph. */
18281 int ascent
= (((it
->ascent
+ it
->descent
) * FONT_BASE (font
))
18282 / FONT_HEIGHT (font
));
18283 append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
18284 it
->ascent
+ it
->descent
, ascent
);
18289 /* If characters with lbearing or rbearing are displayed
18290 in this line, record that fact in a flag of the
18291 glyph row. This is used to optimize X output code. */
18292 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
18293 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
18296 else if (it
->char_to_display
== '\n')
18298 /* A newline has no width but we need the height of the line. */
18299 it
->pixel_width
= 0;
18301 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
18302 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
18304 if (face
->box
!= FACE_NO_BOX
18305 && face
->box_line_width
> 0)
18307 it
->ascent
+= face
->box_line_width
;
18308 it
->descent
+= face
->box_line_width
;
18311 else if (it
->char_to_display
== '\t')
18313 int tab_width
= it
->tab_width
* FRAME_COLUMN_WIDTH (it
->f
);
18314 int x
= it
->current_x
+ it
->continuation_lines_width
;
18315 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
18317 /* If the distance from the current position to the next tab
18318 stop is less than a canonical character width, use the
18319 tab stop after that. */
18320 if (next_tab_x
- x
< FRAME_COLUMN_WIDTH (it
->f
))
18321 next_tab_x
+= tab_width
;
18323 it
->pixel_width
= next_tab_x
- x
;
18325 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
18326 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
18330 append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
18331 it
->ascent
+ it
->descent
, it
->ascent
);
18336 /* A multi-byte character. Assume that the display width of the
18337 character is the width of the character multiplied by the
18338 width of the font. */
18340 /* If we found a font, this font should give us the right
18341 metrics. If we didn't find a font, use the frame's
18342 default font and calculate the width of the character
18343 from the charset width; this is what old redisplay code
18346 pcm
= FRAME_RIF (it
->f
)->per_char_metric (font
, &char2b
,
18347 FONT_TYPE_FOR_MULTIBYTE (font
, it
->c
));
18349 if (font_not_found_p
|| !pcm
)
18351 int charset
= CHAR_CHARSET (it
->char_to_display
);
18353 it
->glyph_not_available_p
= 1;
18354 it
->pixel_width
= (FRAME_COLUMN_WIDTH (it
->f
)
18355 * CHARSET_WIDTH (charset
));
18356 it
->phys_ascent
= FONT_BASE (font
) + boff
;
18357 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
18361 it
->pixel_width
= pcm
->width
;
18362 it
->phys_ascent
= pcm
->ascent
+ boff
;
18363 it
->phys_descent
= pcm
->descent
- boff
;
18365 && (pcm
->lbearing
< 0
18366 || pcm
->rbearing
> pcm
->width
))
18367 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
18370 it
->ascent
= FONT_BASE (font
) + boff
;
18371 it
->descent
= FONT_DESCENT (font
) - boff
;
18372 if (face
->box
!= FACE_NO_BOX
)
18374 int thick
= face
->box_line_width
;
18378 it
->ascent
+= thick
;
18379 it
->descent
+= thick
;
18384 if (it
->start_of_box_run_p
)
18385 it
->pixel_width
+= thick
;
18386 if (it
->end_of_box_run_p
)
18387 it
->pixel_width
+= thick
;
18390 /* If face has an overline, add the height of the overline
18391 (1 pixel) and a 1 pixel margin to the character height. */
18392 if (face
->overline_p
)
18395 take_vertical_position_into_account (it
);
18400 it
->multibyte_p
= saved_multibyte_p
;
18402 else if (it
->what
== IT_COMPOSITION
)
18404 /* Note: A composition is represented as one glyph in the
18405 glyph matrix. There are no padding glyphs. */
18408 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
18410 int font_not_found_p
;
18411 struct font_info
*font_info
;
18412 int boff
; /* baseline offset */
18413 struct composition
*cmp
= composition_table
[it
->cmp_id
];
18415 /* Maybe translate single-byte characters to multibyte. */
18416 it
->char_to_display
= it
->c
;
18417 if (unibyte_display_via_language_environment
18418 && SINGLE_BYTE_CHAR_P (it
->c
)
18421 && !NILP (Vnonascii_translation_table
))))
18423 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
18426 /* Get face and font to use. Encode IT->char_to_display. */
18427 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
18428 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
18429 get_char_face_and_encoding (it
->f
, it
->char_to_display
, it
->face_id
,
18430 &char2b
, it
->multibyte_p
, 0);
18433 /* When no suitable font found, use the default font. */
18434 font_not_found_p
= font
== NULL
;
18435 if (font_not_found_p
)
18437 font
= FRAME_FONT (it
->f
);
18438 boff
= FRAME_BASELINE_OFFSET (it
->f
);
18443 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
18444 boff
= font_info
->baseline_offset
;
18445 if (font_info
->vertical_centering
)
18446 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
18449 /* There are no padding glyphs, so there is only one glyph to
18450 produce for the composition. Important is that pixel_width,
18451 ascent and descent are the values of what is drawn by
18452 draw_glyphs (i.e. the values of the overall glyphs composed). */
18455 /* If we have not yet calculated pixel size data of glyphs of
18456 the composition for the current face font, calculate them
18457 now. Theoretically, we have to check all fonts for the
18458 glyphs, but that requires much time and memory space. So,
18459 here we check only the font of the first glyph. This leads
18460 to incorrect display very rarely, and C-l (recenter) can
18461 correct the display anyway. */
18462 if (cmp
->font
!= (void *) font
)
18464 /* Ascent and descent of the font of the first character of
18465 this composition (adjusted by baseline offset). Ascent
18466 and descent of overall glyphs should not be less than
18467 them respectively. */
18468 int font_ascent
= FONT_BASE (font
) + boff
;
18469 int font_descent
= FONT_DESCENT (font
) - boff
;
18470 /* Bounding box of the overall glyphs. */
18471 int leftmost
, rightmost
, lowest
, highest
;
18472 int i
, width
, ascent
, descent
;
18474 cmp
->font
= (void *) font
;
18476 /* Initialize the bounding box. */
18478 && (pcm
= FRAME_RIF (it
->f
)->per_char_metric (font
, &char2b
,
18479 FONT_TYPE_FOR_MULTIBYTE (font
, it
->c
))))
18481 width
= pcm
->width
;
18482 ascent
= pcm
->ascent
;
18483 descent
= pcm
->descent
;
18487 width
= FONT_WIDTH (font
);
18488 ascent
= FONT_BASE (font
);
18489 descent
= FONT_DESCENT (font
);
18493 lowest
= - descent
+ boff
;
18494 highest
= ascent
+ boff
;
18498 && font_info
->default_ascent
18499 && CHAR_TABLE_P (Vuse_default_ascent
)
18500 && !NILP (Faref (Vuse_default_ascent
,
18501 make_number (it
->char_to_display
))))
18502 highest
= font_info
->default_ascent
+ boff
;
18504 /* Draw the first glyph at the normal position. It may be
18505 shifted to right later if some other glyphs are drawn at
18507 cmp
->offsets
[0] = 0;
18508 cmp
->offsets
[1] = boff
;
18510 /* Set cmp->offsets for the remaining glyphs. */
18511 for (i
= 1; i
< cmp
->glyph_len
; i
++)
18513 int left
, right
, btm
, top
;
18514 int ch
= COMPOSITION_GLYPH (cmp
, i
);
18515 int face_id
= FACE_FOR_CHAR (it
->f
, face
, ch
);
18517 face
= FACE_FROM_ID (it
->f
, face_id
);
18518 get_char_face_and_encoding (it
->f
, ch
, face
->id
,
18519 &char2b
, it
->multibyte_p
, 0);
18523 font
= FRAME_FONT (it
->f
);
18524 boff
= FRAME_BASELINE_OFFSET (it
->f
);
18530 = FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
18531 boff
= font_info
->baseline_offset
;
18532 if (font_info
->vertical_centering
)
18533 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
18537 && (pcm
= FRAME_RIF (it
->f
)->per_char_metric (font
, &char2b
,
18538 FONT_TYPE_FOR_MULTIBYTE (font
, ch
))))
18540 width
= pcm
->width
;
18541 ascent
= pcm
->ascent
;
18542 descent
= pcm
->descent
;
18546 width
= FONT_WIDTH (font
);
18551 if (cmp
->method
!= COMPOSITION_WITH_RULE_ALTCHARS
)
18553 /* Relative composition with or without
18554 alternate chars. */
18555 left
= (leftmost
+ rightmost
- width
) / 2;
18556 btm
= - descent
+ boff
;
18557 if (font_info
&& font_info
->relative_compose
18558 && (! CHAR_TABLE_P (Vignore_relative_composition
)
18559 || NILP (Faref (Vignore_relative_composition
,
18560 make_number (ch
)))))
18563 if (- descent
>= font_info
->relative_compose
)
18564 /* One extra pixel between two glyphs. */
18566 else if (ascent
<= 0)
18567 /* One extra pixel between two glyphs. */
18568 btm
= lowest
- 1 - ascent
- descent
;
18573 /* A composition rule is specified by an integer
18574 value that encodes global and new reference
18575 points (GREF and NREF). GREF and NREF are
18576 specified by numbers as below:
18578 0---1---2 -- ascent
18582 9--10--11 -- center
18584 ---3---4---5--- baseline
18586 6---7---8 -- descent
18588 int rule
= COMPOSITION_RULE (cmp
, i
);
18589 int gref
, nref
, grefx
, grefy
, nrefx
, nrefy
;
18591 COMPOSITION_DECODE_RULE (rule
, gref
, nref
);
18592 grefx
= gref
% 3, nrefx
= nref
% 3;
18593 grefy
= gref
/ 3, nrefy
= nref
/ 3;
18596 + grefx
* (rightmost
- leftmost
) / 2
18597 - nrefx
* width
/ 2);
18598 btm
= ((grefy
== 0 ? highest
18600 : grefy
== 2 ? lowest
18601 : (highest
+ lowest
) / 2)
18602 - (nrefy
== 0 ? ascent
+ descent
18603 : nrefy
== 1 ? descent
- boff
18605 : (ascent
+ descent
) / 2));
18608 cmp
->offsets
[i
* 2] = left
;
18609 cmp
->offsets
[i
* 2 + 1] = btm
+ descent
;
18611 /* Update the bounding box of the overall glyphs. */
18612 right
= left
+ width
;
18613 top
= btm
+ descent
+ ascent
;
18614 if (left
< leftmost
)
18616 if (right
> rightmost
)
18624 /* If there are glyphs whose x-offsets are negative,
18625 shift all glyphs to the right and make all x-offsets
18629 for (i
= 0; i
< cmp
->glyph_len
; i
++)
18630 cmp
->offsets
[i
* 2] -= leftmost
;
18631 rightmost
-= leftmost
;
18634 cmp
->pixel_width
= rightmost
;
18635 cmp
->ascent
= highest
;
18636 cmp
->descent
= - lowest
;
18637 if (cmp
->ascent
< font_ascent
)
18638 cmp
->ascent
= font_ascent
;
18639 if (cmp
->descent
< font_descent
)
18640 cmp
->descent
= font_descent
;
18643 it
->pixel_width
= cmp
->pixel_width
;
18644 it
->ascent
= it
->phys_ascent
= cmp
->ascent
;
18645 it
->descent
= it
->phys_descent
= cmp
->descent
;
18647 if (face
->box
!= FACE_NO_BOX
)
18649 int thick
= face
->box_line_width
;
18653 it
->ascent
+= thick
;
18654 it
->descent
+= thick
;
18659 if (it
->start_of_box_run_p
)
18660 it
->pixel_width
+= thick
;
18661 if (it
->end_of_box_run_p
)
18662 it
->pixel_width
+= thick
;
18665 /* If face has an overline, add the height of the overline
18666 (1 pixel) and a 1 pixel margin to the character height. */
18667 if (face
->overline_p
)
18670 take_vertical_position_into_account (it
);
18673 append_composite_glyph (it
);
18675 else if (it
->what
== IT_IMAGE
)
18676 produce_image_glyph (it
);
18677 else if (it
->what
== IT_STRETCH
)
18678 produce_stretch_glyph (it
);
18680 /* Accumulate dimensions. Note: can't assume that it->descent > 0
18681 because this isn't true for images with `:ascent 100'. */
18682 xassert (it
->ascent
>= 0 && it
->descent
>= 0);
18683 if (it
->area
== TEXT_AREA
)
18684 it
->current_x
+= it
->pixel_width
;
18686 it
->descent
+= it
->extra_line_spacing
;
18688 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
18689 it
->max_descent
= max (it
->max_descent
, it
->descent
);
18690 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
18691 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
18695 Output LEN glyphs starting at START at the nominal cursor position.
18696 Advance the nominal cursor over the text. The global variable
18697 updated_window contains the window being updated, updated_row is
18698 the glyph row being updated, and updated_area is the area of that
18699 row being updated. */
18702 x_write_glyphs (start
, len
)
18703 struct glyph
*start
;
18708 xassert (updated_window
&& updated_row
);
18711 /* Write glyphs. */
18713 hpos
= start
- updated_row
->glyphs
[updated_area
];
18714 x
= draw_glyphs (updated_window
, output_cursor
.x
,
18715 updated_row
, updated_area
,
18717 DRAW_NORMAL_TEXT
, 0);
18719 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
18720 if (updated_area
== TEXT_AREA
18721 && updated_window
->phys_cursor_on_p
18722 && updated_window
->phys_cursor
.vpos
== output_cursor
.vpos
18723 && updated_window
->phys_cursor
.hpos
>= hpos
18724 && updated_window
->phys_cursor
.hpos
< hpos
+ len
)
18725 updated_window
->phys_cursor_on_p
= 0;
18729 /* Advance the output cursor. */
18730 output_cursor
.hpos
+= len
;
18731 output_cursor
.x
= x
;
18736 Insert LEN glyphs from START at the nominal cursor position. */
18739 x_insert_glyphs (start
, len
)
18740 struct glyph
*start
;
18745 int line_height
, shift_by_width
, shifted_region_width
;
18746 struct glyph_row
*row
;
18747 struct glyph
*glyph
;
18748 int frame_x
, frame_y
, hpos
;
18750 xassert (updated_window
&& updated_row
);
18752 w
= updated_window
;
18753 f
= XFRAME (WINDOW_FRAME (w
));
18755 /* Get the height of the line we are in. */
18757 line_height
= row
->height
;
18759 /* Get the width of the glyphs to insert. */
18760 shift_by_width
= 0;
18761 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
18762 shift_by_width
+= glyph
->pixel_width
;
18764 /* Get the width of the region to shift right. */
18765 shifted_region_width
= (window_box_width (w
, updated_area
)
18770 frame_x
= window_box_left (w
, updated_area
) + output_cursor
.x
;
18771 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
18773 FRAME_RIF (f
)->shift_glyphs_for_insert (f
, frame_x
, frame_y
, shifted_region_width
,
18774 line_height
, shift_by_width
);
18776 /* Write the glyphs. */
18777 hpos
= start
- row
->glyphs
[updated_area
];
18778 draw_glyphs (w
, output_cursor
.x
, row
, updated_area
,
18780 DRAW_NORMAL_TEXT
, 0);
18782 /* Advance the output cursor. */
18783 output_cursor
.hpos
+= len
;
18784 output_cursor
.x
+= shift_by_width
;
18790 Erase the current text line from the nominal cursor position
18791 (inclusive) to pixel column TO_X (exclusive). The idea is that
18792 everything from TO_X onward is already erased.
18794 TO_X is a pixel position relative to updated_area of
18795 updated_window. TO_X == -1 means clear to the end of this area. */
18798 x_clear_end_of_line (to_x
)
18802 struct window
*w
= updated_window
;
18803 int max_x
, min_y
, max_y
;
18804 int from_x
, from_y
, to_y
;
18806 xassert (updated_window
&& updated_row
);
18807 f
= XFRAME (w
->frame
);
18809 if (updated_row
->full_width_p
)
18810 max_x
= WINDOW_TOTAL_WIDTH (w
);
18812 max_x
= window_box_width (w
, updated_area
);
18813 max_y
= window_text_bottom_y (w
);
18815 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
18816 of window. For TO_X > 0, truncate to end of drawing area. */
18822 to_x
= min (to_x
, max_x
);
18824 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
18826 /* Notice if the cursor will be cleared by this operation. */
18827 if (!updated_row
->full_width_p
)
18828 notice_overwritten_cursor (w
, updated_area
,
18829 output_cursor
.x
, -1,
18831 MATRIX_ROW_BOTTOM_Y (updated_row
));
18833 from_x
= output_cursor
.x
;
18835 /* Translate to frame coordinates. */
18836 if (updated_row
->full_width_p
)
18838 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
18839 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
18843 int area_left
= window_box_left (w
, updated_area
);
18844 from_x
+= area_left
;
18848 min_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
18849 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
18850 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
18852 /* Prevent inadvertently clearing to end of the X window. */
18853 if (to_x
> from_x
&& to_y
> from_y
)
18856 FRAME_RIF (f
)->clear_frame_area (f
, from_x
, from_y
,
18857 to_x
- from_x
, to_y
- from_y
);
18862 #endif /* HAVE_WINDOW_SYSTEM */
18866 /***********************************************************************
18868 ***********************************************************************/
18870 /* Value is the internal representation of the specified cursor type
18871 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
18872 of the bar cursor. */
18874 static enum text_cursor_kinds
18875 get_specified_cursor_type (arg
, width
)
18879 enum text_cursor_kinds type
;
18884 if (EQ (arg
, Qbox
))
18885 return FILLED_BOX_CURSOR
;
18887 if (EQ (arg
, Qhollow
))
18888 return HOLLOW_BOX_CURSOR
;
18890 if (EQ (arg
, Qbar
))
18897 && EQ (XCAR (arg
), Qbar
)
18898 && INTEGERP (XCDR (arg
))
18899 && XINT (XCDR (arg
)) >= 0)
18901 *width
= XINT (XCDR (arg
));
18905 if (EQ (arg
, Qhbar
))
18908 return HBAR_CURSOR
;
18912 && EQ (XCAR (arg
), Qhbar
)
18913 && INTEGERP (XCDR (arg
))
18914 && XINT (XCDR (arg
)) >= 0)
18916 *width
= XINT (XCDR (arg
));
18917 return HBAR_CURSOR
;
18920 /* Treat anything unknown as "hollow box cursor".
18921 It was bad to signal an error; people have trouble fixing
18922 .Xdefaults with Emacs, when it has something bad in it. */
18923 type
= HOLLOW_BOX_CURSOR
;
18928 /* Set the default cursor types for specified frame. */
18930 set_frame_cursor_types (f
, arg
)
18937 FRAME_DESIRED_CURSOR (f
) = get_specified_cursor_type (arg
, &width
);
18938 FRAME_CURSOR_WIDTH (f
) = width
;
18940 /* By default, set up the blink-off state depending on the on-state. */
18942 tem
= Fassoc (arg
, Vblink_cursor_alist
);
18945 FRAME_BLINK_OFF_CURSOR (f
)
18946 = get_specified_cursor_type (XCDR (tem
), &width
);
18947 FRAME_BLINK_OFF_CURSOR_WIDTH (f
) = width
;
18950 FRAME_BLINK_OFF_CURSOR (f
) = DEFAULT_CURSOR
;
18954 /* Return the cursor we want to be displayed in window W. Return
18955 width of bar/hbar cursor through WIDTH arg. Return with
18956 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
18957 (i.e. if the `system caret' should track this cursor).
18959 In a mini-buffer window, we want the cursor only to appear if we
18960 are reading input from this window. For the selected window, we
18961 want the cursor type given by the frame parameter or buffer local
18962 setting of cursor-type. If explicitly marked off, draw no cursor.
18963 In all other cases, we want a hollow box cursor. */
18965 static enum text_cursor_kinds
18966 get_window_cursor_type (w
, glyph
, width
, active_cursor
)
18968 struct glyph
*glyph
;
18970 int *active_cursor
;
18972 struct frame
*f
= XFRAME (w
->frame
);
18973 struct buffer
*b
= XBUFFER (w
->buffer
);
18974 int cursor_type
= DEFAULT_CURSOR
;
18975 Lisp_Object alt_cursor
;
18976 int non_selected
= 0;
18978 *active_cursor
= 1;
18981 if (cursor_in_echo_area
18982 && FRAME_HAS_MINIBUF_P (f
)
18983 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
18985 if (w
== XWINDOW (echo_area_window
))
18987 *width
= FRAME_CURSOR_WIDTH (f
);
18988 return FRAME_DESIRED_CURSOR (f
);
18991 *active_cursor
= 0;
18995 /* Nonselected window or nonselected frame. */
18996 else if (w
!= XWINDOW (f
->selected_window
)
18997 #ifdef HAVE_WINDOW_SYSTEM
18998 || f
!= FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
19002 *active_cursor
= 0;
19004 if (MINI_WINDOW_P (w
) && minibuf_level
== 0)
19010 /* Never display a cursor in a window in which cursor-type is nil. */
19011 if (NILP (b
->cursor_type
))
19014 /* Use cursor-in-non-selected-windows for non-selected window or frame. */
19017 alt_cursor
= Fbuffer_local_value (Qcursor_in_non_selected_windows
, w
->buffer
);
19018 return get_specified_cursor_type (alt_cursor
, width
);
19021 /* Get the normal cursor type for this window. */
19022 if (EQ (b
->cursor_type
, Qt
))
19024 cursor_type
= FRAME_DESIRED_CURSOR (f
);
19025 *width
= FRAME_CURSOR_WIDTH (f
);
19028 cursor_type
= get_specified_cursor_type (b
->cursor_type
, width
);
19030 /* Use normal cursor if not blinked off. */
19031 if (!w
->cursor_off_p
&& glyph
!= NULL
)
19033 if (glyph
->type
== IMAGE_GLYPH
) {
19034 if (cursor_type
== FILLED_BOX_CURSOR
)
19035 cursor_type
= HOLLOW_BOX_CURSOR
;
19037 return cursor_type
;
19040 /* Cursor is blinked off, so determine how to "toggle" it. */
19042 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
19043 if ((alt_cursor
= Fassoc (b
->cursor_type
, Vblink_cursor_alist
), !NILP (alt_cursor
)))
19044 return get_specified_cursor_type (XCDR (alt_cursor
), width
);
19046 /* Then see if frame has specified a specific blink off cursor type. */
19047 if (FRAME_BLINK_OFF_CURSOR (f
) != DEFAULT_CURSOR
)
19049 *width
= FRAME_BLINK_OFF_CURSOR_WIDTH (f
);
19050 return FRAME_BLINK_OFF_CURSOR (f
);
19054 /* Some people liked having a permanently visible blinking cursor,
19055 while others had very strong opinions against it. So it was
19056 decided to remove it. KFS 2003-09-03 */
19058 /* Finally perform built-in cursor blinking:
19059 filled box <-> hollow box
19060 wide [h]bar <-> narrow [h]bar
19061 narrow [h]bar <-> no cursor
19062 other type <-> no cursor */
19064 if (cursor_type
== FILLED_BOX_CURSOR
)
19065 return HOLLOW_BOX_CURSOR
;
19067 if ((cursor_type
== BAR_CURSOR
|| cursor_type
== HBAR_CURSOR
) && *width
> 1)
19070 return cursor_type
;
19078 #ifdef HAVE_WINDOW_SYSTEM
19080 /* Notice when the text cursor of window W has been completely
19081 overwritten by a drawing operation that outputs glyphs in AREA
19082 starting at X0 and ending at X1 in the line starting at Y0 and
19083 ending at Y1. X coordinates are area-relative. X1 < 0 means all
19084 the rest of the line after X0 has been written. Y coordinates
19085 are window-relative. */
19088 notice_overwritten_cursor (w
, area
, x0
, x1
, y0
, y1
)
19090 enum glyph_row_area area
;
19091 int x0
, y0
, x1
, y1
;
19093 int cx0
, cx1
, cy0
, cy1
;
19094 struct glyph_row
*row
;
19096 if (!w
->phys_cursor_on_p
)
19098 if (area
!= TEXT_AREA
)
19101 row
= w
->current_matrix
->rows
+ w
->phys_cursor
.vpos
;
19102 if (!row
->displays_text_p
)
19105 if (row
->cursor_in_fringe_p
)
19107 row
->cursor_in_fringe_p
= 0;
19108 draw_fringe_bitmap (w
, row
, 0);
19109 w
->phys_cursor_on_p
= 0;
19113 cx0
= w
->phys_cursor
.x
;
19114 cx1
= cx0
+ w
->phys_cursor_width
;
19115 if (x0
> cx0
|| (x1
>= 0 && x1
< cx1
))
19118 /* The cursor image will be completely removed from the
19119 screen if the output area intersects the cursor area in
19120 y-direction. When we draw in [y0 y1[, and some part of
19121 the cursor is at y < y0, that part must have been drawn
19122 before. When scrolling, the cursor is erased before
19123 actually scrolling, so we don't come here. When not
19124 scrolling, the rows above the old cursor row must have
19125 changed, and in this case these rows must have written
19126 over the cursor image.
19128 Likewise if part of the cursor is below y1, with the
19129 exception of the cursor being in the first blank row at
19130 the buffer and window end because update_text_area
19131 doesn't draw that row. (Except when it does, but
19132 that's handled in update_text_area.) */
19134 cy0
= w
->phys_cursor
.y
;
19135 cy1
= cy0
+ w
->phys_cursor_height
;
19136 if ((y0
< cy0
|| y0
>= cy1
) && (y1
<= cy0
|| y1
>= cy1
))
19139 w
->phys_cursor_on_p
= 0;
19142 #endif /* HAVE_WINDOW_SYSTEM */
19145 /************************************************************************
19147 ************************************************************************/
19149 #ifdef HAVE_WINDOW_SYSTEM
19152 Fix the display of area AREA of overlapping row ROW in window W. */
19155 x_fix_overlapping_area (w
, row
, area
)
19157 struct glyph_row
*row
;
19158 enum glyph_row_area area
;
19165 for (i
= 0; i
< row
->used
[area
];)
19167 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
19169 int start
= i
, start_x
= x
;
19173 x
+= row
->glyphs
[area
][i
].pixel_width
;
19176 while (i
< row
->used
[area
]
19177 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
19179 draw_glyphs (w
, start_x
, row
, area
,
19181 DRAW_NORMAL_TEXT
, 1);
19185 x
+= row
->glyphs
[area
][i
].pixel_width
;
19195 Draw the cursor glyph of window W in glyph row ROW. See the
19196 comment of draw_glyphs for the meaning of HL. */
19199 draw_phys_cursor_glyph (w
, row
, hl
)
19201 struct glyph_row
*row
;
19202 enum draw_glyphs_face hl
;
19204 /* If cursor hpos is out of bounds, don't draw garbage. This can
19205 happen in mini-buffer windows when switching between echo area
19206 glyphs and mini-buffer. */
19207 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
19209 int on_p
= w
->phys_cursor_on_p
;
19211 x1
= draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
19212 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
19214 w
->phys_cursor_on_p
= on_p
;
19216 if (hl
== DRAW_CURSOR
)
19217 w
->phys_cursor_width
= x1
- w
->phys_cursor
.x
;
19218 /* When we erase the cursor, and ROW is overlapped by other
19219 rows, make sure that these overlapping parts of other rows
19221 else if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
19223 if (row
> w
->current_matrix
->rows
19224 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
19225 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
);
19227 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
19228 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
19229 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
);
19236 Erase the image of a cursor of window W from the screen. */
19239 erase_phys_cursor (w
)
19242 struct frame
*f
= XFRAME (w
->frame
);
19243 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
19244 int hpos
= w
->phys_cursor
.hpos
;
19245 int vpos
= w
->phys_cursor
.vpos
;
19246 int mouse_face_here_p
= 0;
19247 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
19248 struct glyph_row
*cursor_row
;
19249 struct glyph
*cursor_glyph
;
19250 enum draw_glyphs_face hl
;
19252 /* No cursor displayed or row invalidated => nothing to do on the
19254 if (w
->phys_cursor_type
== NO_CURSOR
)
19255 goto mark_cursor_off
;
19257 /* VPOS >= active_glyphs->nrows means that window has been resized.
19258 Don't bother to erase the cursor. */
19259 if (vpos
>= active_glyphs
->nrows
)
19260 goto mark_cursor_off
;
19262 /* If row containing cursor is marked invalid, there is nothing we
19264 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
19265 if (!cursor_row
->enabled_p
)
19266 goto mark_cursor_off
;
19268 /* If row is completely invisible, don't attempt to delete a cursor which
19269 isn't there. This can happen if cursor is at top of a window, and
19270 we switch to a buffer with a header line in that window. */
19271 if (cursor_row
->visible_height
<= 0)
19272 goto mark_cursor_off
;
19274 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
19275 if (cursor_row
->cursor_in_fringe_p
)
19277 cursor_row
->cursor_in_fringe_p
= 0;
19278 draw_fringe_bitmap (w
, cursor_row
, 0);
19279 goto mark_cursor_off
;
19282 /* This can happen when the new row is shorter than the old one.
19283 In this case, either draw_glyphs or clear_end_of_line
19284 should have cleared the cursor. Note that we wouldn't be
19285 able to erase the cursor in this case because we don't have a
19286 cursor glyph at hand. */
19287 if (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])
19288 goto mark_cursor_off
;
19290 /* If the cursor is in the mouse face area, redisplay that when
19291 we clear the cursor. */
19292 if (! NILP (dpyinfo
->mouse_face_window
)
19293 && w
== XWINDOW (dpyinfo
->mouse_face_window
)
19294 && (vpos
> dpyinfo
->mouse_face_beg_row
19295 || (vpos
== dpyinfo
->mouse_face_beg_row
19296 && hpos
>= dpyinfo
->mouse_face_beg_col
))
19297 && (vpos
< dpyinfo
->mouse_face_end_row
19298 || (vpos
== dpyinfo
->mouse_face_end_row
19299 && hpos
< dpyinfo
->mouse_face_end_col
))
19300 /* Don't redraw the cursor's spot in mouse face if it is at the
19301 end of a line (on a newline). The cursor appears there, but
19302 mouse highlighting does not. */
19303 && cursor_row
->used
[TEXT_AREA
] > hpos
)
19304 mouse_face_here_p
= 1;
19306 /* Maybe clear the display under the cursor. */
19307 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
19310 int header_line_height
= WINDOW_HEADER_LINE_HEIGHT (w
);
19312 cursor_glyph
= get_phys_cursor_glyph (w
);
19313 if (cursor_glyph
== NULL
)
19314 goto mark_cursor_off
;
19316 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
19317 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
, cursor_row
->y
));
19319 FRAME_RIF (f
)->clear_frame_area (f
, x
, y
,
19320 cursor_glyph
->pixel_width
, cursor_row
->visible_height
);
19323 /* Erase the cursor by redrawing the character underneath it. */
19324 if (mouse_face_here_p
)
19325 hl
= DRAW_MOUSE_FACE
;
19327 hl
= DRAW_NORMAL_TEXT
;
19328 draw_phys_cursor_glyph (w
, cursor_row
, hl
);
19331 w
->phys_cursor_on_p
= 0;
19332 w
->phys_cursor_type
= NO_CURSOR
;
19337 Display or clear cursor of window W. If ON is zero, clear the
19338 cursor. If it is non-zero, display the cursor. If ON is nonzero,
19339 where to put the cursor is specified by HPOS, VPOS, X and Y. */
19342 display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
)
19344 int on
, hpos
, vpos
, x
, y
;
19346 struct frame
*f
= XFRAME (w
->frame
);
19347 int new_cursor_type
;
19348 int new_cursor_width
;
19350 struct glyph_matrix
*current_glyphs
;
19351 struct glyph_row
*glyph_row
;
19352 struct glyph
*glyph
;
19354 /* This is pointless on invisible frames, and dangerous on garbaged
19355 windows and frames; in the latter case, the frame or window may
19356 be in the midst of changing its size, and x and y may be off the
19358 if (! FRAME_VISIBLE_P (f
)
19359 || FRAME_GARBAGED_P (f
)
19360 || vpos
>= w
->current_matrix
->nrows
19361 || hpos
>= w
->current_matrix
->matrix_w
)
19364 /* If cursor is off and we want it off, return quickly. */
19365 if (!on
&& !w
->phys_cursor_on_p
)
19368 current_glyphs
= w
->current_matrix
;
19369 glyph_row
= MATRIX_ROW (current_glyphs
, vpos
);
19370 glyph
= (glyph_row
->cursor_in_fringe_p
? NULL
19371 : glyph_row
->glyphs
[TEXT_AREA
] + hpos
);
19373 /* If cursor row is not enabled, we don't really know where to
19374 display the cursor. */
19375 if (!glyph_row
->enabled_p
)
19377 w
->phys_cursor_on_p
= 0;
19381 xassert (interrupt_input_blocked
);
19383 /* Set new_cursor_type to the cursor we want to be displayed. */
19384 new_cursor_type
= get_window_cursor_type (w
, glyph
,
19385 &new_cursor_width
, &active_cursor
);
19387 /* If cursor is currently being shown and we don't want it to be or
19388 it is in the wrong place, or the cursor type is not what we want,
19390 if (w
->phys_cursor_on_p
19392 || w
->phys_cursor
.x
!= x
19393 || w
->phys_cursor
.y
!= y
19394 || new_cursor_type
!= w
->phys_cursor_type
19395 || ((new_cursor_type
== BAR_CURSOR
|| new_cursor_type
== HBAR_CURSOR
)
19396 && new_cursor_width
!= w
->phys_cursor_width
)))
19397 erase_phys_cursor (w
);
19399 /* Don't check phys_cursor_on_p here because that flag is only set
19400 to zero in some cases where we know that the cursor has been
19401 completely erased, to avoid the extra work of erasing the cursor
19402 twice. In other words, phys_cursor_on_p can be 1 and the cursor
19403 still not be visible, or it has only been partly erased. */
19406 w
->phys_cursor_ascent
= glyph_row
->ascent
;
19407 w
->phys_cursor_height
= glyph_row
->height
;
19409 /* Set phys_cursor_.* before x_draw_.* is called because some
19410 of them may need the information. */
19411 w
->phys_cursor
.x
= x
;
19412 w
->phys_cursor
.y
= glyph_row
->y
;
19413 w
->phys_cursor
.hpos
= hpos
;
19414 w
->phys_cursor
.vpos
= vpos
;
19417 FRAME_RIF (f
)->draw_window_cursor (w
, glyph_row
, x
, y
,
19418 new_cursor_type
, new_cursor_width
,
19419 on
, active_cursor
);
19423 /* Switch the display of W's cursor on or off, according to the value
19427 update_window_cursor (w
, on
)
19431 /* Don't update cursor in windows whose frame is in the process
19432 of being deleted. */
19433 if (w
->current_matrix
)
19436 display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
19437 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
19443 /* Call update_window_cursor with parameter ON_P on all leaf windows
19444 in the window tree rooted at W. */
19447 update_cursor_in_window_tree (w
, on_p
)
19453 if (!NILP (w
->hchild
))
19454 update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
19455 else if (!NILP (w
->vchild
))
19456 update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
19458 update_window_cursor (w
, on_p
);
19460 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
19466 Display the cursor on window W, or clear it, according to ON_P.
19467 Don't change the cursor's position. */
19470 x_update_cursor (f
, on_p
)
19474 update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
19479 Clear the cursor of window W to background color, and mark the
19480 cursor as not shown. This is used when the text where the cursor
19481 is is about to be rewritten. */
19487 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
19488 update_window_cursor (w
, 0);
19493 Display the active region described by mouse_face_* according to DRAW. */
19496 show_mouse_face (dpyinfo
, draw
)
19497 Display_Info
*dpyinfo
;
19498 enum draw_glyphs_face draw
;
19500 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
19501 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
19503 if (/* If window is in the process of being destroyed, don't bother
19505 w
->current_matrix
!= NULL
19506 /* Don't update mouse highlight if hidden */
19507 && (draw
!= DRAW_MOUSE_FACE
|| !dpyinfo
->mouse_face_hidden
)
19508 /* Recognize when we are called to operate on rows that don't exist
19509 anymore. This can happen when a window is split. */
19510 && dpyinfo
->mouse_face_end_row
< w
->current_matrix
->nrows
)
19512 int phys_cursor_on_p
= w
->phys_cursor_on_p
;
19513 struct glyph_row
*row
, *first
, *last
;
19515 first
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_beg_row
);
19516 last
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_end_row
);
19518 for (row
= first
; row
<= last
&& row
->enabled_p
; ++row
)
19520 int start_hpos
, end_hpos
, start_x
;
19522 /* For all but the first row, the highlight starts at column 0. */
19525 start_hpos
= dpyinfo
->mouse_face_beg_col
;
19526 start_x
= dpyinfo
->mouse_face_beg_x
;
19535 end_hpos
= dpyinfo
->mouse_face_end_col
;
19537 end_hpos
= row
->used
[TEXT_AREA
];
19539 if (end_hpos
> start_hpos
)
19541 draw_glyphs (w
, start_x
, row
, TEXT_AREA
,
19542 start_hpos
, end_hpos
,
19546 = draw
== DRAW_MOUSE_FACE
|| draw
== DRAW_IMAGE_RAISED
;
19550 /* When we've written over the cursor, arrange for it to
19551 be displayed again. */
19552 if (phys_cursor_on_p
&& !w
->phys_cursor_on_p
)
19555 display_and_set_cursor (w
, 1,
19556 w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
19557 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
19562 /* Change the mouse cursor. */
19563 if (draw
== DRAW_NORMAL_TEXT
)
19564 FRAME_RIF (f
)->define_frame_cursor (f
, FRAME_X_OUTPUT (f
)->text_cursor
);
19565 else if (draw
== DRAW_MOUSE_FACE
)
19566 FRAME_RIF (f
)->define_frame_cursor (f
, FRAME_X_OUTPUT (f
)->hand_cursor
);
19568 FRAME_RIF (f
)->define_frame_cursor (f
, FRAME_X_OUTPUT (f
)->nontext_cursor
);
19572 Clear out the mouse-highlighted active region.
19573 Redraw it un-highlighted first. Value is non-zero if mouse
19574 face was actually drawn unhighlighted. */
19577 clear_mouse_face (dpyinfo
)
19578 Display_Info
*dpyinfo
;
19582 if (!NILP (dpyinfo
->mouse_face_window
))
19584 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
19588 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
19589 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
19590 dpyinfo
->mouse_face_window
= Qnil
;
19591 dpyinfo
->mouse_face_overlay
= Qnil
;
19597 Non-zero if physical cursor of window W is within mouse face. */
19600 cursor_in_mouse_face_p (w
)
19603 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (XFRAME (w
->frame
));
19604 int in_mouse_face
= 0;
19606 if (WINDOWP (dpyinfo
->mouse_face_window
)
19607 && XWINDOW (dpyinfo
->mouse_face_window
) == w
)
19609 int hpos
= w
->phys_cursor
.hpos
;
19610 int vpos
= w
->phys_cursor
.vpos
;
19612 if (vpos
>= dpyinfo
->mouse_face_beg_row
19613 && vpos
<= dpyinfo
->mouse_face_end_row
19614 && (vpos
> dpyinfo
->mouse_face_beg_row
19615 || hpos
>= dpyinfo
->mouse_face_beg_col
)
19616 && (vpos
< dpyinfo
->mouse_face_end_row
19617 || hpos
< dpyinfo
->mouse_face_end_col
19618 || dpyinfo
->mouse_face_past_end
))
19622 return in_mouse_face
;
19628 /* Find the glyph matrix position of buffer position CHARPOS in window
19629 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
19630 current glyphs must be up to date. If CHARPOS is above window
19631 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
19632 of last line in W. In the row containing CHARPOS, stop before glyphs
19633 having STOP as object. */
19635 #if 1 /* This is a version of fast_find_position that's more correct
19636 in the presence of hscrolling, for example. I didn't install
19637 it right away because the problem fixed is minor, it failed
19638 in 20.x as well, and I think it's too risky to install
19639 so near the release of 21.1. 2001-09-25 gerd. */
19642 fast_find_position (w
, charpos
, hpos
, vpos
, x
, y
, stop
)
19645 int *hpos
, *vpos
, *x
, *y
;
19648 struct glyph_row
*row
, *first
;
19649 struct glyph
*glyph
, *end
;
19652 first
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
19653 row
= row_containing_pos (w
, charpos
, first
, NULL
, 0);
19656 if (charpos
< MATRIX_ROW_START_CHARPOS (first
))
19658 *x
= *y
= *hpos
= *vpos
= 0;
19663 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
19670 *vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
19672 glyph
= row
->glyphs
[TEXT_AREA
];
19673 end
= glyph
+ row
->used
[TEXT_AREA
];
19675 /* Skip over glyphs not having an object at the start of the row.
19676 These are special glyphs like truncation marks on terminal
19678 if (row
->displays_text_p
)
19680 && INTEGERP (glyph
->object
)
19681 && !EQ (stop
, glyph
->object
)
19682 && glyph
->charpos
< 0)
19684 *x
+= glyph
->pixel_width
;
19689 && !INTEGERP (glyph
->object
)
19690 && !EQ (stop
, glyph
->object
)
19691 && (!BUFFERP (glyph
->object
)
19692 || glyph
->charpos
< charpos
))
19694 *x
+= glyph
->pixel_width
;
19698 *hpos
= glyph
- row
->glyphs
[TEXT_AREA
];
19705 fast_find_position (w
, pos
, hpos
, vpos
, x
, y
, stop
)
19708 int *hpos
, *vpos
, *x
, *y
;
19713 int maybe_next_line_p
= 0;
19714 int line_start_position
;
19715 int yb
= window_text_bottom_y (w
);
19716 struct glyph_row
*row
, *best_row
;
19717 int row_vpos
, best_row_vpos
;
19720 row
= best_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
19721 row_vpos
= best_row_vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
19723 while (row
->y
< yb
)
19725 if (row
->used
[TEXT_AREA
])
19726 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
19728 line_start_position
= 0;
19730 if (line_start_position
> pos
)
19732 /* If the position sought is the end of the buffer,
19733 don't include the blank lines at the bottom of the window. */
19734 else if (line_start_position
== pos
19735 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
19737 maybe_next_line_p
= 1;
19740 else if (line_start_position
> 0)
19743 best_row_vpos
= row_vpos
;
19746 if (row
->y
+ row
->height
>= yb
)
19753 /* Find the right column within BEST_ROW. */
19755 current_x
= best_row
->x
;
19756 for (i
= 0; i
< best_row
->used
[TEXT_AREA
]; i
++)
19758 struct glyph
*glyph
= best_row
->glyphs
[TEXT_AREA
] + i
;
19759 int charpos
= glyph
->charpos
;
19761 if (BUFFERP (glyph
->object
))
19763 if (charpos
== pos
)
19766 *vpos
= best_row_vpos
;
19771 else if (charpos
> pos
)
19774 else if (EQ (glyph
->object
, stop
))
19779 current_x
+= glyph
->pixel_width
;
19782 /* If we're looking for the end of the buffer,
19783 and we didn't find it in the line we scanned,
19784 use the start of the following line. */
19785 if (maybe_next_line_p
)
19790 current_x
= best_row
->x
;
19793 *vpos
= best_row_vpos
;
19794 *hpos
= lastcol
+ 1;
19803 /* Find the position of the glyph for position POS in OBJECT in
19804 window W's current matrix, and return in *X, *Y the pixel
19805 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
19807 RIGHT_P non-zero means return the position of the right edge of the
19808 glyph, RIGHT_P zero means return the left edge position.
19810 If no glyph for POS exists in the matrix, return the position of
19811 the glyph with the next smaller position that is in the matrix, if
19812 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
19813 exists in the matrix, return the position of the glyph with the
19814 next larger position in OBJECT.
19816 Value is non-zero if a glyph was found. */
19819 fast_find_string_pos (w
, pos
, object
, hpos
, vpos
, x
, y
, right_p
)
19822 Lisp_Object object
;
19823 int *hpos
, *vpos
, *x
, *y
;
19826 int yb
= window_text_bottom_y (w
);
19827 struct glyph_row
*r
;
19828 struct glyph
*best_glyph
= NULL
;
19829 struct glyph_row
*best_row
= NULL
;
19832 for (r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
19833 r
->enabled_p
&& r
->y
< yb
;
19836 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
19837 struct glyph
*e
= g
+ r
->used
[TEXT_AREA
];
19840 for (gx
= r
->x
; g
< e
; gx
+= g
->pixel_width
, ++g
)
19841 if (EQ (g
->object
, object
))
19843 if (g
->charpos
== pos
)
19850 else if (best_glyph
== NULL
19851 || ((abs (g
->charpos
- pos
)
19852 < abs (best_glyph
->charpos
- pos
))
19855 : g
->charpos
> pos
)))
19869 *hpos
= best_glyph
- best_row
->glyphs
[TEXT_AREA
];
19873 *x
+= best_glyph
->pixel_width
;
19878 *vpos
= best_row
- w
->current_matrix
->rows
;
19881 return best_glyph
!= NULL
;
19885 /* See if position X, Y is within a hot-spot of an image. */
19888 on_hot_spot_p (hot_spot
, x
, y
)
19889 Lisp_Object hot_spot
;
19892 if (!CONSP (hot_spot
))
19895 if (EQ (XCAR (hot_spot
), Qrect
))
19897 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
19898 Lisp_Object rect
= XCDR (hot_spot
);
19902 if (!CONSP (XCAR (rect
)))
19904 if (!CONSP (XCDR (rect
)))
19906 if (!(tem
= XCAR (XCAR (rect
)), INTEGERP (tem
) && x
>= XINT (tem
)))
19908 if (!(tem
= XCDR (XCAR (rect
)), INTEGERP (tem
) && y
>= XINT (tem
)))
19910 if (!(tem
= XCAR (XCDR (rect
)), INTEGERP (tem
) && x
<= XINT (tem
)))
19912 if (!(tem
= XCDR (XCDR (rect
)), INTEGERP (tem
) && y
<= XINT (tem
)))
19916 else if (EQ (XCAR (hot_spot
), Qcircle
))
19918 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
19919 Lisp_Object circ
= XCDR (hot_spot
);
19920 Lisp_Object lr
, lx0
, ly0
;
19922 && CONSP (XCAR (circ
))
19923 && (lr
= XCDR (circ
), INTEGERP (lr
) || FLOATP (lr
))
19924 && (lx0
= XCAR (XCAR (circ
)), INTEGERP (lx0
))
19925 && (ly0
= XCDR (XCAR (circ
)), INTEGERP (ly0
)))
19927 double r
= XFLOATINT (lr
);
19928 double dx
= XINT (lx0
) - x
;
19929 double dy
= XINT (ly0
) - y
;
19930 return (dx
* dx
+ dy
* dy
<= r
* r
);
19933 else if (EQ (XCAR (hot_spot
), Qpoly
))
19935 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
19936 if (VECTORP (XCDR (hot_spot
)))
19938 struct Lisp_Vector
*v
= XVECTOR (XCDR (hot_spot
));
19939 Lisp_Object
*poly
= v
->contents
;
19943 Lisp_Object lx
, ly
;
19946 /* Need an even number of coordinates, and at least 3 edges. */
19947 if (n
< 6 || n
& 1)
19950 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
19951 If count is odd, we are inside polygon. Pixels on edges
19952 may or may not be included depending on actual geometry of the
19954 if ((lx
= poly
[n
-2], !INTEGERP (lx
))
19955 || (ly
= poly
[n
-1], !INTEGERP (lx
)))
19957 x0
= XINT (lx
), y0
= XINT (ly
);
19958 for (i
= 0; i
< n
; i
+= 2)
19960 int x1
= x0
, y1
= y0
;
19961 if ((lx
= poly
[i
], !INTEGERP (lx
))
19962 || (ly
= poly
[i
+1], !INTEGERP (ly
)))
19964 x0
= XINT (lx
), y0
= XINT (ly
);
19966 /* Does this segment cross the X line? */
19974 if (y
> y0
&& y
> y1
)
19976 if (y
< y0
+ ((y1
- y0
) * (x
- x0
)) / (x1
- x0
))
19986 find_hot_spot (map
, x
, y
)
19990 while (CONSP (map
))
19992 if (CONSP (XCAR (map
))
19993 && on_hot_spot_p (XCAR (XCAR (map
)), x
, y
))
20001 DEFUN ("lookup-image-map", Flookup_image_map
, Slookup_image_map
,
20003 doc
: /* Lookup in image map MAP coordinates X and Y.
20004 An image map is an alist where each element has the format (AREA ID PLIST).
20005 An AREA is specified as either a rectangle, a circle, or a polygon:
20006 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
20007 pixel coordinates of the upper left and bottom right corners.
20008 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
20009 and the radius of the circle; r may be a float or integer.
20010 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
20011 vector describes one corner in the polygon.
20012 Returns the alist element for the first matching AREA in MAP. */)
20024 return find_hot_spot (map
, XINT (x
), XINT (y
));
20028 /* Display frame CURSOR, optionally using shape defined by POINTER. */
20030 define_frame_cursor1 (f
, cursor
, pointer
)
20033 Lisp_Object pointer
;
20035 if (!NILP (pointer
))
20037 if (EQ (pointer
, Qarrow
))
20038 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
20039 else if (EQ (pointer
, Qhand
))
20040 cursor
= FRAME_X_OUTPUT (f
)->hand_cursor
;
20041 else if (EQ (pointer
, Qtext
))
20042 cursor
= FRAME_X_OUTPUT (f
)->text_cursor
;
20043 else if (EQ (pointer
, intern ("hdrag")))
20044 cursor
= FRAME_X_OUTPUT (f
)->horizontal_drag_cursor
;
20045 #ifdef HAVE_X_WINDOWS
20046 else if (EQ (pointer
, intern ("vdrag")))
20047 cursor
= FRAME_X_DISPLAY_INFO (f
)->vertical_scroll_bar_cursor
;
20049 else if (EQ (pointer
, intern ("hourglass")))
20050 cursor
= FRAME_X_OUTPUT (f
)->hourglass_cursor
;
20051 else if (EQ (pointer
, Qmodeline
))
20052 cursor
= FRAME_X_OUTPUT (f
)->modeline_cursor
;
20054 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
20057 #ifndef HAVE_CARBON
20058 if (cursor
!= No_Cursor
)
20060 if (bcmp (&cursor
, &No_Cursor
, sizeof (Cursor
)))
20062 FRAME_RIF (f
)->define_frame_cursor (f
, cursor
);
20065 /* Take proper action when mouse has moved to the mode or header line
20066 or marginal area AREA of window W, x-position X and y-position Y.
20067 X is relative to the start of the text display area of W, so the
20068 width of bitmap areas and scroll bars must be subtracted to get a
20069 position relative to the start of the mode line. */
20072 note_mode_line_or_margin_highlight (w
, x
, y
, area
)
20075 enum window_part area
;
20077 struct frame
*f
= XFRAME (w
->frame
);
20078 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
20079 Cursor cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
20080 Lisp_Object pointer
= Qnil
;
20081 int charpos
, dx
, dy
, width
, height
;
20082 Lisp_Object string
, object
= Qnil
;
20083 Lisp_Object pos
, help
, image
;
20085 if (area
== ON_MODE_LINE
|| area
== ON_HEADER_LINE
)
20086 string
= mode_line_string (w
, area
, &x
, &y
, &charpos
,
20087 &object
, &dx
, &dy
, &width
, &height
);
20090 x
-= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w
);
20091 string
= marginal_area_string (w
, area
, &x
, &y
, &charpos
,
20092 &object
, &dx
, &dy
, &width
, &height
);
20097 if (IMAGEP (object
))
20099 Lisp_Object image_map
, hotspot
;
20100 if ((image_map
= Fplist_get (XCDR (object
), QCmap
),
20102 && (hotspot
= find_hot_spot (image_map
, dx
, dy
),
20104 && (hotspot
= XCDR (hotspot
), CONSP (hotspot
)))
20106 Lisp_Object area_id
, plist
;
20108 area_id
= XCAR (hotspot
);
20109 /* Could check AREA_ID to see if we enter/leave this hot-spot.
20110 If so, we could look for mouse-enter, mouse-leave
20111 properties in PLIST (and do something...). */
20112 if ((plist
= XCDR (hotspot
), CONSP (plist
)))
20114 pointer
= Fplist_get (plist
, Qpointer
);
20115 if (NILP (pointer
))
20117 help
= Fplist_get (plist
, Qhelp_echo
);
20120 help_echo_string
= help
;
20121 /* Is this correct? ++kfs */
20122 XSETWINDOW (help_echo_window
, w
);
20123 help_echo_object
= w
->buffer
;
20124 help_echo_pos
= charpos
;
20127 if (NILP (pointer
))
20128 pointer
= Fplist_get (XCDR (object
), QCpointer
);
20132 if (STRINGP (string
))
20134 pos
= make_number (charpos
);
20135 /* If we're on a string with `help-echo' text property, arrange
20136 for the help to be displayed. This is done by setting the
20137 global variable help_echo_string to the help string. */
20138 help
= Fget_text_property (pos
, Qhelp_echo
, string
);
20141 help_echo_string
= help
;
20142 XSETWINDOW (help_echo_window
, w
);
20143 help_echo_object
= string
;
20144 help_echo_pos
= charpos
;
20147 if (NILP (pointer
))
20148 pointer
= Fget_text_property (pos
, Qpointer
, string
);
20150 /* Change the mouse pointer according to what is under X/Y. */
20151 if (NILP (pointer
) && area
== ON_MODE_LINE
)
20154 map
= Fget_text_property (pos
, Qlocal_map
, string
);
20155 if (!KEYMAPP (map
))
20156 map
= Fget_text_property (pos
, Qkeymap
, string
);
20157 if (!KEYMAPP (map
))
20158 cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
20162 define_frame_cursor1 (f
, cursor
, pointer
);
20167 Take proper action when the mouse has moved to position X, Y on
20168 frame F as regards highlighting characters that have mouse-face
20169 properties. Also de-highlighting chars where the mouse was before.
20170 X and Y can be negative or out of range. */
20173 note_mouse_highlight (f
, x
, y
)
20177 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
20178 enum window_part part
;
20179 Lisp_Object window
;
20181 Cursor cursor
= No_Cursor
;
20182 Lisp_Object pointer
= Qnil
; /* Takes precedence over cursor! */
20185 /* When a menu is active, don't highlight because this looks odd. */
20186 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
20187 if (popup_activated ())
20191 if (NILP (Vmouse_highlight
)
20192 || !f
->glyphs_initialized_p
)
20195 dpyinfo
->mouse_face_mouse_x
= x
;
20196 dpyinfo
->mouse_face_mouse_y
= y
;
20197 dpyinfo
->mouse_face_mouse_frame
= f
;
20199 if (dpyinfo
->mouse_face_defer
)
20202 if (gc_in_progress
)
20204 dpyinfo
->mouse_face_deferred_gc
= 1;
20208 /* Which window is that in? */
20209 window
= window_from_coordinates (f
, x
, y
, &part
, 0, 0, 1);
20211 /* If we were displaying active text in another window, clear that. */
20212 if (! EQ (window
, dpyinfo
->mouse_face_window
))
20213 clear_mouse_face (dpyinfo
);
20215 /* Not on a window -> return. */
20216 if (!WINDOWP (window
))
20219 /* Reset help_echo_string. It will get recomputed below. */
20220 help_echo_string
= Qnil
;
20222 /* Convert to window-relative pixel coordinates. */
20223 w
= XWINDOW (window
);
20224 frame_to_window_pixel_xy (w
, &x
, &y
);
20226 /* Handle tool-bar window differently since it doesn't display a
20228 if (EQ (window
, f
->tool_bar_window
))
20230 note_tool_bar_highlight (f
, x
, y
);
20234 /* Mouse is on the mode, header line or margin? */
20235 if (part
== ON_MODE_LINE
|| part
== ON_HEADER_LINE
20236 || part
== ON_LEFT_MARGIN
|| part
== ON_RIGHT_MARGIN
)
20238 note_mode_line_or_margin_highlight (w
, x
, y
, part
);
20242 if (part
== ON_VERTICAL_BORDER
)
20243 cursor
= FRAME_X_OUTPUT (f
)->horizontal_drag_cursor
;
20244 else if (part
== ON_LEFT_FRINGE
|| part
== ON_RIGHT_FRINGE
)
20245 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
20247 cursor
= FRAME_X_OUTPUT (f
)->text_cursor
;
20249 /* Are we in a window whose display is up to date?
20250 And verify the buffer's text has not changed. */
20251 b
= XBUFFER (w
->buffer
);
20252 if (part
== ON_TEXT
20253 && EQ (w
->window_end_valid
, w
->buffer
)
20254 && XFASTINT (w
->last_modified
) == BUF_MODIFF (b
)
20255 && XFASTINT (w
->last_overlay_modified
) == BUF_OVERLAY_MODIFF (b
))
20257 int hpos
, vpos
, pos
, i
, dx
, dy
, area
;
20258 struct glyph
*glyph
;
20259 Lisp_Object object
;
20260 Lisp_Object mouse_face
= Qnil
, overlay
= Qnil
, position
;
20261 Lisp_Object
*overlay_vec
= NULL
;
20262 int len
, noverlays
;
20263 struct buffer
*obuf
;
20264 int obegv
, ozv
, same_region
;
20266 /* Find the glyph under X/Y. */
20267 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &dx
, &dy
, &area
);
20269 /* Look for :pointer property on image. */
20270 if (glyph
!= NULL
&& glyph
->type
== IMAGE_GLYPH
)
20272 struct image
*img
= IMAGE_FROM_ID (f
, glyph
->u
.img_id
);
20273 if (img
!= NULL
&& IMAGEP (img
->spec
))
20275 Lisp_Object image_map
, hotspot
;
20276 if ((image_map
= Fplist_get (XCDR (img
->spec
), QCmap
),
20278 && (hotspot
= find_hot_spot (image_map
, dx
, dy
),
20280 && (hotspot
= XCDR (hotspot
), CONSP (hotspot
)))
20282 Lisp_Object area_id
, plist
;
20284 area_id
= XCAR (hotspot
);
20285 /* Could check AREA_ID to see if we enter/leave this hot-spot.
20286 If so, we could look for mouse-enter, mouse-leave
20287 properties in PLIST (and do something...). */
20288 if ((plist
= XCDR (hotspot
), CONSP (plist
)))
20290 pointer
= Fplist_get (plist
, Qpointer
);
20291 if (NILP (pointer
))
20293 help_echo_string
= Fplist_get (plist
, Qhelp_echo
);
20294 if (!NILP (help_echo_string
))
20296 help_echo_window
= window
;
20297 help_echo_object
= glyph
->object
;
20298 help_echo_pos
= glyph
->charpos
;
20302 if (NILP (pointer
))
20303 pointer
= Fplist_get (XCDR (img
->spec
), QCpointer
);
20307 /* Clear mouse face if X/Y not over text. */
20309 || area
!= TEXT_AREA
20310 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
)
20312 if (clear_mouse_face (dpyinfo
))
20313 cursor
= No_Cursor
;
20314 if (NILP (pointer
))
20316 if (area
!= TEXT_AREA
)
20317 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
20319 pointer
= Vvoid_text_area_pointer
;
20324 pos
= glyph
->charpos
;
20325 object
= glyph
->object
;
20326 if (!STRINGP (object
) && !BUFFERP (object
))
20329 /* If we get an out-of-range value, return now; avoid an error. */
20330 if (BUFFERP (object
) && pos
> BUF_Z (b
))
20333 /* Make the window's buffer temporarily current for
20334 overlays_at and compute_char_face. */
20335 obuf
= current_buffer
;
20336 current_buffer
= b
;
20342 /* Is this char mouse-active or does it have help-echo? */
20343 position
= make_number (pos
);
20345 if (BUFFERP (object
))
20347 /* Put all the overlays we want in a vector in overlay_vec.
20348 Store the length in len. If there are more than 10, make
20349 enough space for all, and try again. */
20351 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
20352 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
, 0);
20353 if (noverlays
> len
)
20356 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
20357 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
,0);
20360 /* Sort overlays into increasing priority order. */
20361 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
20366 same_region
= (EQ (window
, dpyinfo
->mouse_face_window
)
20367 && vpos
>= dpyinfo
->mouse_face_beg_row
20368 && vpos
<= dpyinfo
->mouse_face_end_row
20369 && (vpos
> dpyinfo
->mouse_face_beg_row
20370 || hpos
>= dpyinfo
->mouse_face_beg_col
)
20371 && (vpos
< dpyinfo
->mouse_face_end_row
20372 || hpos
< dpyinfo
->mouse_face_end_col
20373 || dpyinfo
->mouse_face_past_end
));
20376 cursor
= No_Cursor
;
20378 /* Check mouse-face highlighting. */
20380 /* If there exists an overlay with mouse-face overlapping
20381 the one we are currently highlighting, we have to
20382 check if we enter the overlapping overlay, and then
20383 highlight only that. */
20384 || (OVERLAYP (dpyinfo
->mouse_face_overlay
)
20385 && mouse_face_overlay_overlaps (dpyinfo
->mouse_face_overlay
)))
20387 /* Find the highest priority overlay that has a mouse-face
20390 for (i
= noverlays
- 1; i
>= 0 && NILP (overlay
); --i
)
20392 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
20393 if (!NILP (mouse_face
))
20394 overlay
= overlay_vec
[i
];
20397 /* If we're actually highlighting the same overlay as
20398 before, there's no need to do that again. */
20399 if (!NILP (overlay
)
20400 && EQ (overlay
, dpyinfo
->mouse_face_overlay
))
20401 goto check_help_echo
;
20403 dpyinfo
->mouse_face_overlay
= overlay
;
20405 /* Clear the display of the old active region, if any. */
20406 if (clear_mouse_face (dpyinfo
))
20407 cursor
= No_Cursor
;
20409 /* If no overlay applies, get a text property. */
20410 if (NILP (overlay
))
20411 mouse_face
= Fget_text_property (position
, Qmouse_face
, object
);
20413 /* Handle the overlay case. */
20414 if (!NILP (overlay
))
20416 /* Find the range of text around this char that
20417 should be active. */
20418 Lisp_Object before
, after
;
20421 before
= Foverlay_start (overlay
);
20422 after
= Foverlay_end (overlay
);
20423 /* Record this as the current active region. */
20424 fast_find_position (w
, XFASTINT (before
),
20425 &dpyinfo
->mouse_face_beg_col
,
20426 &dpyinfo
->mouse_face_beg_row
,
20427 &dpyinfo
->mouse_face_beg_x
,
20428 &dpyinfo
->mouse_face_beg_y
, Qnil
);
20430 dpyinfo
->mouse_face_past_end
20431 = !fast_find_position (w
, XFASTINT (after
),
20432 &dpyinfo
->mouse_face_end_col
,
20433 &dpyinfo
->mouse_face_end_row
,
20434 &dpyinfo
->mouse_face_end_x
,
20435 &dpyinfo
->mouse_face_end_y
, Qnil
);
20436 dpyinfo
->mouse_face_window
= window
;
20438 dpyinfo
->mouse_face_face_id
20439 = face_at_buffer_position (w
, pos
, 0, 0,
20441 !dpyinfo
->mouse_face_hidden
);
20443 /* Display it as active. */
20444 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
20445 cursor
= No_Cursor
;
20447 /* Handle the text property case. */
20448 else if (!NILP (mouse_face
) && BUFFERP (object
))
20450 /* Find the range of text around this char that
20451 should be active. */
20452 Lisp_Object before
, after
, beginning
, end
;
20455 beginning
= Fmarker_position (w
->start
);
20456 end
= make_number (BUF_Z (XBUFFER (object
))
20457 - XFASTINT (w
->window_end_pos
));
20459 = Fprevious_single_property_change (make_number (pos
+ 1),
20461 object
, beginning
);
20463 = Fnext_single_property_change (position
, Qmouse_face
,
20466 /* Record this as the current active region. */
20467 fast_find_position (w
, XFASTINT (before
),
20468 &dpyinfo
->mouse_face_beg_col
,
20469 &dpyinfo
->mouse_face_beg_row
,
20470 &dpyinfo
->mouse_face_beg_x
,
20471 &dpyinfo
->mouse_face_beg_y
, Qnil
);
20472 dpyinfo
->mouse_face_past_end
20473 = !fast_find_position (w
, XFASTINT (after
),
20474 &dpyinfo
->mouse_face_end_col
,
20475 &dpyinfo
->mouse_face_end_row
,
20476 &dpyinfo
->mouse_face_end_x
,
20477 &dpyinfo
->mouse_face_end_y
, Qnil
);
20478 dpyinfo
->mouse_face_window
= window
;
20480 if (BUFFERP (object
))
20481 dpyinfo
->mouse_face_face_id
20482 = face_at_buffer_position (w
, pos
, 0, 0,
20484 !dpyinfo
->mouse_face_hidden
);
20486 /* Display it as active. */
20487 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
20488 cursor
= No_Cursor
;
20490 else if (!NILP (mouse_face
) && STRINGP (object
))
20495 b
= Fprevious_single_property_change (make_number (pos
+ 1),
20498 e
= Fnext_single_property_change (position
, Qmouse_face
,
20501 b
= make_number (0);
20503 e
= make_number (SCHARS (object
) - 1);
20504 fast_find_string_pos (w
, XINT (b
), object
,
20505 &dpyinfo
->mouse_face_beg_col
,
20506 &dpyinfo
->mouse_face_beg_row
,
20507 &dpyinfo
->mouse_face_beg_x
,
20508 &dpyinfo
->mouse_face_beg_y
, 0);
20509 fast_find_string_pos (w
, XINT (e
), object
,
20510 &dpyinfo
->mouse_face_end_col
,
20511 &dpyinfo
->mouse_face_end_row
,
20512 &dpyinfo
->mouse_face_end_x
,
20513 &dpyinfo
->mouse_face_end_y
, 1);
20514 dpyinfo
->mouse_face_past_end
= 0;
20515 dpyinfo
->mouse_face_window
= window
;
20516 dpyinfo
->mouse_face_face_id
20517 = face_at_string_position (w
, object
, pos
, 0, 0, 0, &ignore
,
20518 glyph
->face_id
, 1);
20519 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
20520 cursor
= No_Cursor
;
20522 else if (STRINGP (object
) && NILP (mouse_face
))
20524 /* A string which doesn't have mouse-face, but
20525 the text ``under'' it might have. */
20526 struct glyph_row
*r
= MATRIX_ROW (w
->current_matrix
, vpos
);
20527 int start
= MATRIX_ROW_START_CHARPOS (r
);
20529 pos
= string_buffer_position (w
, object
, start
);
20531 mouse_face
= get_char_property_and_overlay (make_number (pos
),
20535 if (!NILP (mouse_face
) && !NILP (overlay
))
20537 Lisp_Object before
= Foverlay_start (overlay
);
20538 Lisp_Object after
= Foverlay_end (overlay
);
20541 /* Note that we might not be able to find position
20542 BEFORE in the glyph matrix if the overlay is
20543 entirely covered by a `display' property. In
20544 this case, we overshoot. So let's stop in
20545 the glyph matrix before glyphs for OBJECT. */
20546 fast_find_position (w
, XFASTINT (before
),
20547 &dpyinfo
->mouse_face_beg_col
,
20548 &dpyinfo
->mouse_face_beg_row
,
20549 &dpyinfo
->mouse_face_beg_x
,
20550 &dpyinfo
->mouse_face_beg_y
,
20553 dpyinfo
->mouse_face_past_end
20554 = !fast_find_position (w
, XFASTINT (after
),
20555 &dpyinfo
->mouse_face_end_col
,
20556 &dpyinfo
->mouse_face_end_row
,
20557 &dpyinfo
->mouse_face_end_x
,
20558 &dpyinfo
->mouse_face_end_y
,
20560 dpyinfo
->mouse_face_window
= window
;
20561 dpyinfo
->mouse_face_face_id
20562 = face_at_buffer_position (w
, pos
, 0, 0,
20564 !dpyinfo
->mouse_face_hidden
);
20566 /* Display it as active. */
20567 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
20568 cursor
= No_Cursor
;
20575 /* Look for a `help-echo' property. */
20576 if (NILP (help_echo_string
)) {
20577 Lisp_Object help
, overlay
;
20579 /* Check overlays first. */
20580 help
= overlay
= Qnil
;
20581 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
20583 overlay
= overlay_vec
[i
];
20584 help
= Foverlay_get (overlay
, Qhelp_echo
);
20589 help_echo_string
= help
;
20590 help_echo_window
= window
;
20591 help_echo_object
= overlay
;
20592 help_echo_pos
= pos
;
20596 Lisp_Object object
= glyph
->object
;
20597 int charpos
= glyph
->charpos
;
20599 /* Try text properties. */
20600 if (STRINGP (object
)
20602 && charpos
< SCHARS (object
))
20604 help
= Fget_text_property (make_number (charpos
),
20605 Qhelp_echo
, object
);
20608 /* If the string itself doesn't specify a help-echo,
20609 see if the buffer text ``under'' it does. */
20610 struct glyph_row
*r
20611 = MATRIX_ROW (w
->current_matrix
, vpos
);
20612 int start
= MATRIX_ROW_START_CHARPOS (r
);
20613 int pos
= string_buffer_position (w
, object
, start
);
20616 help
= Fget_char_property (make_number (pos
),
20617 Qhelp_echo
, w
->buffer
);
20621 object
= w
->buffer
;
20626 else if (BUFFERP (object
)
20629 help
= Fget_text_property (make_number (charpos
), Qhelp_echo
,
20634 help_echo_string
= help
;
20635 help_echo_window
= window
;
20636 help_echo_object
= object
;
20637 help_echo_pos
= charpos
;
20642 /* Look for a `pointer' property. */
20643 if (NILP (pointer
))
20645 /* Check overlays first. */
20646 for (i
= noverlays
- 1; i
>= 0 && NILP (pointer
); --i
)
20647 pointer
= Foverlay_get (overlay_vec
[i
], Qpointer
);
20649 if (NILP (pointer
))
20651 Lisp_Object object
= glyph
->object
;
20652 int charpos
= glyph
->charpos
;
20654 /* Try text properties. */
20655 if (STRINGP (object
)
20657 && charpos
< SCHARS (object
))
20659 pointer
= Fget_text_property (make_number (charpos
),
20661 if (NILP (pointer
))
20663 /* If the string itself doesn't specify a pointer,
20664 see if the buffer text ``under'' it does. */
20665 struct glyph_row
*r
20666 = MATRIX_ROW (w
->current_matrix
, vpos
);
20667 int start
= MATRIX_ROW_START_CHARPOS (r
);
20668 int pos
= string_buffer_position (w
, object
, start
);
20670 pointer
= Fget_char_property (make_number (pos
),
20671 Qpointer
, w
->buffer
);
20674 else if (BUFFERP (object
)
20677 pointer
= Fget_text_property (make_number (charpos
),
20684 current_buffer
= obuf
;
20689 define_frame_cursor1 (f
, cursor
, pointer
);
20694 Clear any mouse-face on window W. This function is part of the
20695 redisplay interface, and is called from try_window_id and similar
20696 functions to ensure the mouse-highlight is off. */
20699 x_clear_window_mouse_face (w
)
20702 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (XFRAME (w
->frame
));
20703 Lisp_Object window
;
20706 XSETWINDOW (window
, w
);
20707 if (EQ (window
, dpyinfo
->mouse_face_window
))
20708 clear_mouse_face (dpyinfo
);
20714 Just discard the mouse face information for frame F, if any.
20715 This is used when the size of F is changed. */
20718 cancel_mouse_face (f
)
20721 Lisp_Object window
;
20722 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
20724 window
= dpyinfo
->mouse_face_window
;
20725 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
20727 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
20728 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
20729 dpyinfo
->mouse_face_window
= Qnil
;
20734 #endif /* HAVE_WINDOW_SYSTEM */
20737 /***********************************************************************
20739 ***********************************************************************/
20741 #ifdef HAVE_WINDOW_SYSTEM
20743 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
20744 which intersects rectangle R. R is in window-relative coordinates. */
20747 expose_area (w
, row
, r
, area
)
20749 struct glyph_row
*row
;
20751 enum glyph_row_area area
;
20753 struct glyph
*first
= row
->glyphs
[area
];
20754 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
20755 struct glyph
*last
;
20756 int first_x
, start_x
, x
;
20758 if (area
== TEXT_AREA
&& row
->fill_line_p
)
20759 /* If row extends face to end of line write the whole line. */
20760 draw_glyphs (w
, 0, row
, area
,
20761 0, row
->used
[area
],
20762 DRAW_NORMAL_TEXT
, 0);
20765 /* Set START_X to the window-relative start position for drawing glyphs of
20766 AREA. The first glyph of the text area can be partially visible.
20767 The first glyphs of other areas cannot. */
20768 start_x
= window_box_left_offset (w
, area
);
20770 if (area
== TEXT_AREA
)
20773 /* Find the first glyph that must be redrawn. */
20775 && x
+ first
->pixel_width
< r
->x
)
20777 x
+= first
->pixel_width
;
20781 /* Find the last one. */
20785 && x
< r
->x
+ r
->width
)
20787 x
+= last
->pixel_width
;
20793 draw_glyphs (w
, first_x
- start_x
, row
, area
,
20794 first
- row
->glyphs
[area
], last
- row
->glyphs
[area
],
20795 DRAW_NORMAL_TEXT
, 0);
20800 /* Redraw the parts of the glyph row ROW on window W intersecting
20801 rectangle R. R is in window-relative coordinates. Value is
20802 non-zero if mouse-face was overwritten. */
20805 expose_line (w
, row
, r
)
20807 struct glyph_row
*row
;
20810 xassert (row
->enabled_p
);
20812 if (row
->mode_line_p
|| w
->pseudo_window_p
)
20813 draw_glyphs (w
, 0, row
, TEXT_AREA
,
20814 0, row
->used
[TEXT_AREA
],
20815 DRAW_NORMAL_TEXT
, 0);
20818 if (row
->used
[LEFT_MARGIN_AREA
])
20819 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
20820 if (row
->used
[TEXT_AREA
])
20821 expose_area (w
, row
, r
, TEXT_AREA
);
20822 if (row
->used
[RIGHT_MARGIN_AREA
])
20823 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
20824 draw_row_fringe_bitmaps (w
, row
);
20827 return row
->mouse_face_p
;
20831 /* Redraw those parts of glyphs rows during expose event handling that
20832 overlap other rows. Redrawing of an exposed line writes over parts
20833 of lines overlapping that exposed line; this function fixes that.
20835 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
20836 row in W's current matrix that is exposed and overlaps other rows.
20837 LAST_OVERLAPPING_ROW is the last such row. */
20840 expose_overlaps (w
, first_overlapping_row
, last_overlapping_row
)
20842 struct glyph_row
*first_overlapping_row
;
20843 struct glyph_row
*last_overlapping_row
;
20845 struct glyph_row
*row
;
20847 for (row
= first_overlapping_row
; row
<= last_overlapping_row
; ++row
)
20848 if (row
->overlapping_p
)
20850 xassert (row
->enabled_p
&& !row
->mode_line_p
);
20852 if (row
->used
[LEFT_MARGIN_AREA
])
20853 x_fix_overlapping_area (w
, row
, LEFT_MARGIN_AREA
);
20855 if (row
->used
[TEXT_AREA
])
20856 x_fix_overlapping_area (w
, row
, TEXT_AREA
);
20858 if (row
->used
[RIGHT_MARGIN_AREA
])
20859 x_fix_overlapping_area (w
, row
, RIGHT_MARGIN_AREA
);
20864 /* Return non-zero if W's cursor intersects rectangle R. */
20867 phys_cursor_in_rect_p (w
, r
)
20871 XRectangle cr
, result
;
20872 struct glyph
*cursor_glyph
;
20874 cursor_glyph
= get_phys_cursor_glyph (w
);
20877 /* r is relative to W's box, but w->phys_cursor.x is relative
20878 to left edge of W's TEXT area. Adjust it. */
20879 cr
.x
= window_box_left_offset (w
, TEXT_AREA
) + w
->phys_cursor
.x
;
20880 cr
.y
= w
->phys_cursor
.y
;
20881 cr
.width
= cursor_glyph
->pixel_width
;
20882 cr
.height
= w
->phys_cursor_height
;
20883 /* ++KFS: W32 version used W32-specific IntersectRect here, but
20884 I assume the effect is the same -- and this is portable. */
20885 return x_intersect_rectangles (&cr
, r
, &result
);
20893 Draw a vertical window border to the right of window W if W doesn't
20894 have vertical scroll bars. */
20897 x_draw_vertical_border (w
)
20900 struct frame
*f
= XFRAME (WINDOW_FRAME (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 FRAME_RIF (f
)->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 FRAME_RIF (f
)->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) */