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
;
305 Lisp_Object Qmargin
, Qpointer
;
306 extern Lisp_Object Qheight
;
307 extern Lisp_Object QCwidth
, QCheight
, QCascent
;
308 extern Lisp_Object Qscroll_bar
;
310 /* Non-nil means highlight trailing whitespace. */
312 Lisp_Object Vshow_trailing_whitespace
;
314 #ifdef HAVE_WINDOW_SYSTEM
315 extern Lisp_Object Voverflow_newline_into_fringe
;
317 /* Test if overflow newline into fringe. Called with iterator IT
318 at or past right window margin, and with IT->current_x set. */
320 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) \
321 (!NILP (Voverflow_newline_into_fringe) \
322 && FRAME_WINDOW_P (it->f) \
323 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
324 && it->current_x == it->last_visible_x)
326 #endif /* HAVE_WINDOW_SYSTEM */
328 /* Non-nil means show the text cursor in void text areas
329 i.e. in blank areas after eol and eob. This used to be
330 the default in 21.3. */
332 Lisp_Object Vvoid_text_area_pointer
;
334 /* Name of the face used to highlight trailing whitespace. */
336 Lisp_Object Qtrailing_whitespace
;
338 /* The symbol `image' which is the car of the lists used to represent
343 /* The image map types. */
344 Lisp_Object QCmap
, QCpointer
;
345 Lisp_Object Qrect
, Qcircle
, Qpoly
;
347 /* Non-zero means print newline to stdout before next mini-buffer
350 int noninteractive_need_newline
;
352 /* Non-zero means print newline to message log before next message. */
354 static int message_log_need_newline
;
356 /* Three markers that message_dolog uses.
357 It could allocate them itself, but that causes trouble
358 in handling memory-full errors. */
359 static Lisp_Object message_dolog_marker1
;
360 static Lisp_Object message_dolog_marker2
;
361 static Lisp_Object message_dolog_marker3
;
363 /* The buffer position of the first character appearing entirely or
364 partially on the line of the selected window which contains the
365 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
366 redisplay optimization in redisplay_internal. */
368 static struct text_pos this_line_start_pos
;
370 /* Number of characters past the end of the line above, including the
371 terminating newline. */
373 static struct text_pos this_line_end_pos
;
375 /* The vertical positions and the height of this line. */
377 static int this_line_vpos
;
378 static int this_line_y
;
379 static int this_line_pixel_height
;
381 /* X position at which this display line starts. Usually zero;
382 negative if first character is partially visible. */
384 static int this_line_start_x
;
386 /* Buffer that this_line_.* variables are referring to. */
388 static struct buffer
*this_line_buffer
;
390 /* Nonzero means truncate lines in all windows less wide than the
393 int truncate_partial_width_windows
;
395 /* A flag to control how to display unibyte 8-bit character. */
397 int unibyte_display_via_language_environment
;
399 /* Nonzero means we have more than one non-mini-buffer-only frame.
400 Not guaranteed to be accurate except while parsing
401 frame-title-format. */
405 Lisp_Object Vglobal_mode_string
;
408 /* List of variables (symbols) which hold markers for overlay arrows.
409 The symbols on this list are examined during redisplay to determine
410 where to display overlay arrows. */
412 Lisp_Object Voverlay_arrow_variable_list
;
414 /* Marker for where to display an arrow on top of the buffer text. */
416 Lisp_Object Voverlay_arrow_position
;
418 /* String to display for the arrow. Only used on terminal frames. */
420 Lisp_Object Voverlay_arrow_string
;
422 /* Values of those variables at last redisplay are stored as
423 properties on `overlay-arrow-position' symbol. However, if
424 Voverlay_arrow_position is a marker, last-arrow-position is its
425 numerical position. */
427 Lisp_Object Qlast_arrow_position
, Qlast_arrow_string
;
429 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
430 properties on a symbol in overlay-arrow-variable-list. */
432 Lisp_Object Qoverlay_arrow_string
, Qoverlay_arrow_bitmap
;
434 /* Like mode-line-format, but for the title bar on a visible frame. */
436 Lisp_Object Vframe_title_format
;
438 /* Like mode-line-format, but for the title bar on an iconified frame. */
440 Lisp_Object Vicon_title_format
;
442 /* List of functions to call when a window's size changes. These
443 functions get one arg, a frame on which one or more windows' sizes
446 static Lisp_Object Vwindow_size_change_functions
;
448 Lisp_Object Qmenu_bar_update_hook
, Vmenu_bar_update_hook
;
450 /* Nonzero if overlay arrow has been displayed once in this window. */
452 static int overlay_arrow_seen
;
454 /* Nonzero means highlight the region even in nonselected windows. */
456 int highlight_nonselected_windows
;
458 /* If cursor motion alone moves point off frame, try scrolling this
459 many lines up or down if that will bring it back. */
461 static EMACS_INT scroll_step
;
463 /* Nonzero means scroll just far enough to bring point back on the
464 screen, when appropriate. */
466 static EMACS_INT scroll_conservatively
;
468 /* Recenter the window whenever point gets within this many lines of
469 the top or bottom of the window. This value is translated into a
470 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
471 that there is really a fixed pixel height scroll margin. */
473 EMACS_INT scroll_margin
;
475 /* Number of windows showing the buffer of the selected window (or
476 another buffer with the same base buffer). keyboard.c refers to
481 /* Vector containing glyphs for an ellipsis `...'. */
483 static Lisp_Object default_invis_vector
[3];
485 /* Zero means display the mode-line/header-line/menu-bar in the default face
486 (this slightly odd definition is for compatibility with previous versions
487 of emacs), non-zero means display them using their respective faces.
489 This variable is deprecated. */
491 int mode_line_inverse_video
;
493 /* Prompt to display in front of the mini-buffer contents. */
495 Lisp_Object minibuf_prompt
;
497 /* Width of current mini-buffer prompt. Only set after display_line
498 of the line that contains the prompt. */
500 int minibuf_prompt_width
;
502 /* This is the window where the echo area message was displayed. It
503 is always a mini-buffer window, but it may not be the same window
504 currently active as a mini-buffer. */
506 Lisp_Object echo_area_window
;
508 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
509 pushes the current message and the value of
510 message_enable_multibyte on the stack, the function restore_message
511 pops the stack and displays MESSAGE again. */
513 Lisp_Object Vmessage_stack
;
515 /* Nonzero means multibyte characters were enabled when the echo area
516 message was specified. */
518 int message_enable_multibyte
;
520 /* Nonzero if we should redraw the mode lines on the next redisplay. */
522 int update_mode_lines
;
524 /* Nonzero if window sizes or contents have changed since last
525 redisplay that finished. */
527 int windows_or_buffers_changed
;
529 /* Nonzero means a frame's cursor type has been changed. */
531 int cursor_type_changed
;
533 /* Nonzero after display_mode_line if %l was used and it displayed a
536 int line_number_displayed
;
538 /* Maximum buffer size for which to display line numbers. */
540 Lisp_Object Vline_number_display_limit
;
542 /* Line width to consider when repositioning for line number display. */
544 static EMACS_INT line_number_display_limit_width
;
546 /* Number of lines to keep in the message log buffer. t means
547 infinite. nil means don't log at all. */
549 Lisp_Object Vmessage_log_max
;
551 /* The name of the *Messages* buffer, a string. */
553 static Lisp_Object Vmessages_buffer_name
;
555 /* Current, index 0, and last displayed echo area message. Either
556 buffers from echo_buffers, or nil to indicate no message. */
558 Lisp_Object echo_area_buffer
[2];
560 /* The buffers referenced from echo_area_buffer. */
562 static Lisp_Object echo_buffer
[2];
564 /* A vector saved used in with_area_buffer to reduce consing. */
566 static Lisp_Object Vwith_echo_area_save_vector
;
568 /* Non-zero means display_echo_area should display the last echo area
569 message again. Set by redisplay_preserve_echo_area. */
571 static int display_last_displayed_message_p
;
573 /* Nonzero if echo area is being used by print; zero if being used by
576 int message_buf_print
;
578 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
580 Lisp_Object Qinhibit_menubar_update
;
581 int inhibit_menubar_update
;
583 /* Maximum height for resizing mini-windows. Either a float
584 specifying a fraction of the available height, or an integer
585 specifying a number of lines. */
587 Lisp_Object Vmax_mini_window_height
;
589 /* Non-zero means messages should be displayed with truncated
590 lines instead of being continued. */
592 int message_truncate_lines
;
593 Lisp_Object Qmessage_truncate_lines
;
595 /* Set to 1 in clear_message to make redisplay_internal aware
596 of an emptied echo area. */
598 static int message_cleared_p
;
600 /* Non-zero means we want a hollow cursor in windows that are not
601 selected. Zero means there's no cursor in such windows. */
603 Lisp_Object Vcursor_in_non_selected_windows
;
604 Lisp_Object Qcursor_in_non_selected_windows
;
606 /* How to blink the default frame cursor off. */
607 Lisp_Object Vblink_cursor_alist
;
609 /* A scratch glyph row with contents used for generating truncation
610 glyphs. Also used in direct_output_for_insert. */
612 #define MAX_SCRATCH_GLYPHS 100
613 struct glyph_row scratch_glyph_row
;
614 static struct glyph scratch_glyphs
[MAX_SCRATCH_GLYPHS
];
616 /* Ascent and height of the last line processed by move_it_to. */
618 static int last_max_ascent
, last_height
;
620 /* Non-zero if there's a help-echo in the echo area. */
622 int help_echo_showing_p
;
624 /* If >= 0, computed, exact values of mode-line and header-line height
625 to use in the macros CURRENT_MODE_LINE_HEIGHT and
626 CURRENT_HEADER_LINE_HEIGHT. */
628 int current_mode_line_height
, current_header_line_height
;
630 /* The maximum distance to look ahead for text properties. Values
631 that are too small let us call compute_char_face and similar
632 functions too often which is expensive. Values that are too large
633 let us call compute_char_face and alike too often because we
634 might not be interested in text properties that far away. */
636 #define TEXT_PROP_DISTANCE_LIMIT 100
640 /* Variables to turn off display optimizations from Lisp. */
642 int inhibit_try_window_id
, inhibit_try_window_reusing
;
643 int inhibit_try_cursor_movement
;
645 /* Non-zero means print traces of redisplay if compiled with
648 int trace_redisplay_p
;
650 #endif /* GLYPH_DEBUG */
652 #ifdef DEBUG_TRACE_MOVE
653 /* Non-zero means trace with TRACE_MOVE to stderr. */
656 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
658 #define TRACE_MOVE(x) (void) 0
661 /* Non-zero means automatically scroll windows horizontally to make
664 int automatic_hscrolling_p
;
666 /* How close to the margin can point get before the window is scrolled
668 EMACS_INT hscroll_margin
;
670 /* How much to scroll horizontally when point is inside the above margin. */
671 Lisp_Object Vhscroll_step
;
673 /* A list of symbols, one for each supported image type. */
675 Lisp_Object Vimage_types
;
677 /* The variable `resize-mini-windows'. If nil, don't resize
678 mini-windows. If t, always resize them to fit the text they
679 display. If `grow-only', let mini-windows grow only until they
682 Lisp_Object Vresize_mini_windows
;
684 /* Buffer being redisplayed -- for redisplay_window_error. */
686 struct buffer
*displayed_buffer
;
688 /* Value returned from text property handlers (see below). */
693 HANDLED_RECOMPUTE_PROPS
,
694 HANDLED_OVERLAY_STRING_CONSUMED
,
698 /* A description of text properties that redisplay is interested
703 /* The name of the property. */
706 /* A unique index for the property. */
709 /* A handler function called to set up iterator IT from the property
710 at IT's current position. Value is used to steer handle_stop. */
711 enum prop_handled (*handler
) P_ ((struct it
*it
));
714 static enum prop_handled handle_face_prop
P_ ((struct it
*));
715 static enum prop_handled handle_invisible_prop
P_ ((struct it
*));
716 static enum prop_handled handle_display_prop
P_ ((struct it
*));
717 static enum prop_handled handle_composition_prop
P_ ((struct it
*));
718 static enum prop_handled handle_overlay_change
P_ ((struct it
*));
719 static enum prop_handled handle_fontified_prop
P_ ((struct it
*));
721 /* Properties handled by iterators. */
723 static struct props it_props
[] =
725 {&Qfontified
, FONTIFIED_PROP_IDX
, handle_fontified_prop
},
726 /* Handle `face' before `display' because some sub-properties of
727 `display' need to know the face. */
728 {&Qface
, FACE_PROP_IDX
, handle_face_prop
},
729 {&Qdisplay
, DISPLAY_PROP_IDX
, handle_display_prop
},
730 {&Qinvisible
, INVISIBLE_PROP_IDX
, handle_invisible_prop
},
731 {&Qcomposition
, COMPOSITION_PROP_IDX
, handle_composition_prop
},
735 /* Value is the position described by X. If X is a marker, value is
736 the marker_position of X. Otherwise, value is X. */
738 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
740 /* Enumeration returned by some move_it_.* functions internally. */
744 /* Not used. Undefined value. */
747 /* Move ended at the requested buffer position or ZV. */
748 MOVE_POS_MATCH_OR_ZV
,
750 /* Move ended at the requested X pixel position. */
753 /* Move within a line ended at the end of a line that must be
757 /* Move within a line ended at the end of a line that would
758 be displayed truncated. */
761 /* Move within a line ended at a line end. */
765 /* This counter is used to clear the face cache every once in a while
766 in redisplay_internal. It is incremented for each redisplay.
767 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
770 #define CLEAR_FACE_CACHE_COUNT 500
771 static int clear_face_cache_count
;
773 /* Non-zero while redisplay_internal is in progress. */
777 /* Non-zero means don't free realized faces. Bound while freeing
778 realized faces is dangerous because glyph matrices might still
781 int inhibit_free_realized_faces
;
782 Lisp_Object Qinhibit_free_realized_faces
;
784 /* If a string, XTread_socket generates an event to display that string.
785 (The display is done in read_char.) */
787 Lisp_Object help_echo_string
;
788 Lisp_Object help_echo_window
;
789 Lisp_Object help_echo_object
;
792 /* Temporary variable for XTread_socket. */
794 Lisp_Object previous_help_echo_string
;
798 /* Function prototypes. */
800 static void setup_for_ellipsis
P_ ((struct it
*));
801 static void mark_window_display_accurate_1
P_ ((struct window
*, int));
802 static int single_display_prop_string_p
P_ ((Lisp_Object
, Lisp_Object
));
803 static int display_prop_string_p
P_ ((Lisp_Object
, Lisp_Object
));
804 static int cursor_row_p
P_ ((struct window
*, struct glyph_row
*));
805 static int redisplay_mode_lines
P_ ((Lisp_Object
, int));
806 static char *decode_mode_spec_coding
P_ ((Lisp_Object
, char *, int));
809 static int invisible_text_between_p
P_ ((struct it
*, int, int));
812 static int next_element_from_ellipsis
P_ ((struct it
*));
813 static void pint2str
P_ ((char *, int, int));
814 static void pint2hrstr
P_ ((char *, int, int));
815 static struct text_pos run_window_scroll_functions
P_ ((Lisp_Object
,
817 static void reconsider_clip_changes
P_ ((struct window
*, struct buffer
*));
818 static int text_outside_line_unchanged_p
P_ ((struct window
*, int, int));
819 static void store_frame_title_char
P_ ((char));
820 static int store_frame_title
P_ ((const unsigned char *, int, int));
821 static void x_consider_frame_title
P_ ((Lisp_Object
));
822 static void handle_stop
P_ ((struct it
*));
823 static int tool_bar_lines_needed
P_ ((struct frame
*));
824 static int single_display_prop_intangible_p
P_ ((Lisp_Object
));
825 static void ensure_echo_area_buffers
P_ ((void));
826 static Lisp_Object unwind_with_echo_area_buffer
P_ ((Lisp_Object
));
827 static Lisp_Object with_echo_area_buffer_unwind_data
P_ ((struct window
*));
828 static int with_echo_area_buffer
P_ ((struct window
*, int,
829 int (*) (EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
),
830 EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
831 static void clear_garbaged_frames
P_ ((void));
832 static int current_message_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
833 static int truncate_message_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
834 static int set_message_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
835 static int display_echo_area
P_ ((struct window
*));
836 static int display_echo_area_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
837 static int resize_mini_window_1
P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
838 static Lisp_Object unwind_redisplay
P_ ((Lisp_Object
));
839 static int string_char_and_length
P_ ((const unsigned char *, int, int *));
840 static struct text_pos display_prop_end
P_ ((struct it
*, Lisp_Object
,
842 static int compute_window_start_on_continuation_line
P_ ((struct window
*));
843 static Lisp_Object safe_eval_handler
P_ ((Lisp_Object
));
844 static void insert_left_trunc_glyphs
P_ ((struct it
*));
845 static struct glyph_row
*get_overlay_arrow_glyph_row
P_ ((struct window
*,
847 static void extend_face_to_end_of_line
P_ ((struct it
*));
848 static int append_space
P_ ((struct it
*, int));
849 static int make_cursor_line_fully_visible
P_ ((struct window
*, int));
850 static int try_scrolling
P_ ((Lisp_Object
, int, EMACS_INT
, EMACS_INT
, int, int));
851 static int try_cursor_movement
P_ ((Lisp_Object
, struct text_pos
, int *));
852 static int trailing_whitespace_p
P_ ((int));
853 static int message_log_check_duplicate
P_ ((int, int, int, int));
854 static void push_it
P_ ((struct it
*));
855 static void pop_it
P_ ((struct it
*));
856 static void sync_frame_with_window_matrix_rows
P_ ((struct window
*));
857 static void select_frame_for_redisplay
P_ ((Lisp_Object
));
858 static void redisplay_internal
P_ ((int));
859 static int echo_area_display
P_ ((int));
860 static void redisplay_windows
P_ ((Lisp_Object
));
861 static void redisplay_window
P_ ((Lisp_Object
, int));
862 static Lisp_Object
redisplay_window_error ();
863 static Lisp_Object redisplay_window_0
P_ ((Lisp_Object
));
864 static Lisp_Object redisplay_window_1
P_ ((Lisp_Object
));
865 static void update_menu_bar
P_ ((struct frame
*, int));
866 static int try_window_reusing_current_matrix
P_ ((struct window
*));
867 static int try_window_id
P_ ((struct window
*));
868 static int display_line
P_ ((struct it
*));
869 static int display_mode_lines
P_ ((struct window
*));
870 static int display_mode_line
P_ ((struct window
*, enum face_id
, Lisp_Object
));
871 static int display_mode_element
P_ ((struct it
*, int, int, int, Lisp_Object
, Lisp_Object
, int));
872 static int store_mode_line_string
P_ ((char *, Lisp_Object
, int, int, int, Lisp_Object
));
873 static char *decode_mode_spec
P_ ((struct window
*, int, int, int, int *));
874 static void display_menu_bar
P_ ((struct window
*));
875 static int display_count_lines
P_ ((int, int, int, int, int *));
876 static int display_string
P_ ((unsigned char *, Lisp_Object
, Lisp_Object
,
877 int, int, struct it
*, int, int, int, int));
878 static void compute_line_metrics
P_ ((struct it
*));
879 static void run_redisplay_end_trigger_hook
P_ ((struct it
*));
880 static int get_overlay_strings
P_ ((struct it
*, int));
881 static void next_overlay_string
P_ ((struct it
*));
882 static void reseat
P_ ((struct it
*, struct text_pos
, int));
883 static void reseat_1
P_ ((struct it
*, struct text_pos
, int));
884 static void back_to_previous_visible_line_start
P_ ((struct it
*));
885 static void reseat_at_previous_visible_line_start
P_ ((struct it
*));
886 static void reseat_at_next_visible_line_start
P_ ((struct it
*, int));
887 static int next_element_from_display_vector
P_ ((struct it
*));
888 static int next_element_from_string
P_ ((struct it
*));
889 static int next_element_from_c_string
P_ ((struct it
*));
890 static int next_element_from_buffer
P_ ((struct it
*));
891 static int next_element_from_composition
P_ ((struct it
*));
892 static int next_element_from_image
P_ ((struct it
*));
893 static int next_element_from_stretch
P_ ((struct it
*));
894 static void load_overlay_strings
P_ ((struct it
*, int));
895 static int init_from_display_pos
P_ ((struct it
*, struct window
*,
896 struct display_pos
*));
897 static void reseat_to_string
P_ ((struct it
*, unsigned char *,
898 Lisp_Object
, int, int, int, int));
899 static enum move_it_result move_it_in_display_line_to
P_ ((struct it
*,
901 void move_it_vertically_backward
P_ ((struct it
*, int));
902 static void init_to_row_start
P_ ((struct it
*, struct window
*,
903 struct glyph_row
*));
904 static int init_to_row_end
P_ ((struct it
*, struct window
*,
905 struct glyph_row
*));
906 static void back_to_previous_line_start
P_ ((struct it
*));
907 static int forward_to_next_line_start
P_ ((struct it
*, int *));
908 static struct text_pos string_pos_nchars_ahead
P_ ((struct text_pos
,
910 static struct text_pos string_pos
P_ ((int, Lisp_Object
));
911 static struct text_pos c_string_pos
P_ ((int, unsigned char *, int));
912 static int number_of_chars
P_ ((unsigned char *, int));
913 static void compute_stop_pos
P_ ((struct it
*));
914 static void compute_string_pos
P_ ((struct text_pos
*, struct text_pos
,
916 static int face_before_or_after_it_pos
P_ ((struct it
*, int));
917 static int next_overlay_change
P_ ((int));
918 static int handle_single_display_prop
P_ ((struct it
*, Lisp_Object
,
919 Lisp_Object
, struct text_pos
*,
921 static int underlying_face_id
P_ ((struct it
*));
922 static int in_ellipses_for_invisible_text_p
P_ ((struct display_pos
*,
925 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
926 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
928 #ifdef HAVE_WINDOW_SYSTEM
930 static void update_tool_bar
P_ ((struct frame
*, int));
931 static void build_desired_tool_bar_string
P_ ((struct frame
*f
));
932 static int redisplay_tool_bar
P_ ((struct frame
*));
933 static void display_tool_bar_line
P_ ((struct it
*));
934 static void notice_overwritten_cursor
P_ ((struct window
*,
936 int, int, int, int));
940 #endif /* HAVE_WINDOW_SYSTEM */
943 /***********************************************************************
944 Window display dimensions
945 ***********************************************************************/
947 /* Return the bottom boundary y-position for text lines in window W.
948 This is the first y position at which a line cannot start.
949 It is relative to the top of the window.
951 This is the height of W minus the height of a mode line, if any. */
954 window_text_bottom_y (w
)
957 int height
= WINDOW_TOTAL_HEIGHT (w
);
959 if (WINDOW_WANTS_MODELINE_P (w
))
960 height
-= CURRENT_MODE_LINE_HEIGHT (w
);
964 /* Return the pixel width of display area AREA of window W. AREA < 0
965 means return the total width of W, not including fringes to
966 the left and right of the window. */
969 window_box_width (w
, area
)
973 int cols
= XFASTINT (w
->total_cols
);
976 if (!w
->pseudo_window_p
)
978 cols
-= WINDOW_SCROLL_BAR_COLS (w
);
980 if (area
== TEXT_AREA
)
982 if (INTEGERP (w
->left_margin_cols
))
983 cols
-= XFASTINT (w
->left_margin_cols
);
984 if (INTEGERP (w
->right_margin_cols
))
985 cols
-= XFASTINT (w
->right_margin_cols
);
986 pixels
= -WINDOW_TOTAL_FRINGE_WIDTH (w
);
988 else if (area
== LEFT_MARGIN_AREA
)
990 cols
= (INTEGERP (w
->left_margin_cols
)
991 ? XFASTINT (w
->left_margin_cols
) : 0);
994 else if (area
== RIGHT_MARGIN_AREA
)
996 cols
= (INTEGERP (w
->right_margin_cols
)
997 ? XFASTINT (w
->right_margin_cols
) : 0);
1002 return cols
* WINDOW_FRAME_COLUMN_WIDTH (w
) + pixels
;
1006 /* Return the pixel height of the display area of window W, not
1007 including mode lines of W, if any. */
1010 window_box_height (w
)
1013 struct frame
*f
= XFRAME (w
->frame
);
1014 int height
= WINDOW_TOTAL_HEIGHT (w
);
1016 xassert (height
>= 0);
1018 /* Note: the code below that determines the mode-line/header-line
1019 height is essentially the same as that contained in the macro
1020 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1021 the appropriate glyph row has its `mode_line_p' flag set,
1022 and if it doesn't, uses estimate_mode_line_height instead. */
1024 if (WINDOW_WANTS_MODELINE_P (w
))
1026 struct glyph_row
*ml_row
1027 = (w
->current_matrix
&& w
->current_matrix
->rows
1028 ? MATRIX_MODE_LINE_ROW (w
->current_matrix
)
1030 if (ml_row
&& ml_row
->mode_line_p
)
1031 height
-= ml_row
->height
;
1033 height
-= estimate_mode_line_height (f
, CURRENT_MODE_LINE_FACE_ID (w
));
1036 if (WINDOW_WANTS_HEADER_LINE_P (w
))
1038 struct glyph_row
*hl_row
1039 = (w
->current_matrix
&& w
->current_matrix
->rows
1040 ? MATRIX_HEADER_LINE_ROW (w
->current_matrix
)
1042 if (hl_row
&& hl_row
->mode_line_p
)
1043 height
-= hl_row
->height
;
1045 height
-= estimate_mode_line_height (f
, HEADER_LINE_FACE_ID
);
1048 /* With a very small font and a mode-line that's taller than
1049 default, we might end up with a negative height. */
1050 return max (0, height
);
1053 /* Return the window-relative coordinate of the left edge of display
1054 area AREA of window W. AREA < 0 means return the left edge of the
1055 whole window, to the right of the left fringe of W. */
1058 window_box_left_offset (w
, area
)
1064 if (w
->pseudo_window_p
)
1067 x
= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w
);
1069 if (area
== TEXT_AREA
)
1070 x
+= (WINDOW_LEFT_FRINGE_WIDTH (w
)
1071 + window_box_width (w
, LEFT_MARGIN_AREA
));
1072 else if (area
== RIGHT_MARGIN_AREA
)
1073 x
+= (WINDOW_LEFT_FRINGE_WIDTH (w
)
1074 + window_box_width (w
, LEFT_MARGIN_AREA
)
1075 + window_box_width (w
, TEXT_AREA
)
1076 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
1078 : WINDOW_RIGHT_FRINGE_WIDTH (w
)));
1079 else if (area
== LEFT_MARGIN_AREA
1080 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
))
1081 x
+= WINDOW_LEFT_FRINGE_WIDTH (w
);
1087 /* Return the window-relative coordinate of the right edge of display
1088 area AREA of window W. AREA < 0 means return the left edge of the
1089 whole window, to the left of the right fringe of W. */
1092 window_box_right_offset (w
, area
)
1096 return window_box_left_offset (w
, area
) + window_box_width (w
, area
);
1099 /* Return the frame-relative coordinate of the left edge of display
1100 area AREA of window W. AREA < 0 means return the left edge of the
1101 whole window, to the right of the left fringe of W. */
1104 window_box_left (w
, area
)
1108 struct frame
*f
= XFRAME (w
->frame
);
1111 if (w
->pseudo_window_p
)
1112 return FRAME_INTERNAL_BORDER_WIDTH (f
);
1114 x
= (WINDOW_LEFT_EDGE_X (w
)
1115 + window_box_left_offset (w
, area
));
1121 /* Return the frame-relative coordinate of the right edge of display
1122 area AREA of window W. AREA < 0 means return the left edge of the
1123 whole window, to the left of the right fringe of W. */
1126 window_box_right (w
, area
)
1130 return window_box_left (w
, area
) + window_box_width (w
, area
);
1133 /* Get the bounding box of the display area AREA of window W, without
1134 mode lines, in frame-relative coordinates. AREA < 0 means the
1135 whole window, not including the left and right fringes of
1136 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1137 coordinates of the upper-left corner of the box. Return in
1138 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1141 window_box (w
, area
, box_x
, box_y
, box_width
, box_height
)
1144 int *box_x
, *box_y
, *box_width
, *box_height
;
1147 *box_width
= window_box_width (w
, area
);
1149 *box_height
= window_box_height (w
);
1151 *box_x
= window_box_left (w
, area
);
1154 *box_y
= WINDOW_TOP_EDGE_Y (w
);
1155 if (WINDOW_WANTS_HEADER_LINE_P (w
))
1156 *box_y
+= CURRENT_HEADER_LINE_HEIGHT (w
);
1161 /* Get the bounding box of the display area AREA of window W, without
1162 mode lines. AREA < 0 means the whole window, not including the
1163 left and right fringe of the window. Return in *TOP_LEFT_X
1164 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1165 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1166 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1170 window_box_edges (w
, area
, top_left_x
, top_left_y
,
1171 bottom_right_x
, bottom_right_y
)
1174 int *top_left_x
, *top_left_y
, *bottom_right_x
, *bottom_right_y
;
1176 window_box (w
, area
, top_left_x
, top_left_y
, bottom_right_x
,
1178 *bottom_right_x
+= *top_left_x
;
1179 *bottom_right_y
+= *top_left_y
;
1184 /***********************************************************************
1186 ***********************************************************************/
1188 /* Return the bottom y-position of the line the iterator IT is in.
1189 This can modify IT's settings. */
1195 int line_height
= it
->max_ascent
+ it
->max_descent
;
1196 int line_top_y
= it
->current_y
;
1198 if (line_height
== 0)
1201 line_height
= last_height
;
1202 else if (IT_CHARPOS (*it
) < ZV
)
1204 move_it_by_lines (it
, 1, 1);
1205 line_height
= (it
->max_ascent
|| it
->max_descent
1206 ? it
->max_ascent
+ it
->max_descent
1211 struct glyph_row
*row
= it
->glyph_row
;
1213 /* Use the default character height. */
1214 it
->glyph_row
= NULL
;
1215 it
->what
= IT_CHARACTER
;
1218 PRODUCE_GLYPHS (it
);
1219 line_height
= it
->ascent
+ it
->descent
;
1220 it
->glyph_row
= row
;
1224 return line_top_y
+ line_height
;
1228 /* Return 1 if position CHARPOS is visible in window W. Set *FULLY to
1229 1 if POS is visible and the line containing POS is fully visible.
1230 EXACT_MODE_LINE_HEIGHTS_P non-zero means compute exact mode-line
1231 and header-lines heights. */
1234 pos_visible_p (w
, charpos
, fully
, exact_mode_line_heights_p
)
1236 int charpos
, *fully
, exact_mode_line_heights_p
;
1239 struct text_pos top
;
1241 struct buffer
*old_buffer
= NULL
;
1243 if (XBUFFER (w
->buffer
) != current_buffer
)
1245 old_buffer
= current_buffer
;
1246 set_buffer_internal_1 (XBUFFER (w
->buffer
));
1249 *fully
= visible_p
= 0;
1250 SET_TEXT_POS_FROM_MARKER (top
, w
->start
);
1252 /* Compute exact mode line heights, if requested. */
1253 if (exact_mode_line_heights_p
)
1255 if (WINDOW_WANTS_MODELINE_P (w
))
1256 current_mode_line_height
1257 = display_mode_line (w
, CURRENT_MODE_LINE_FACE_ID (w
),
1258 current_buffer
->mode_line_format
);
1260 if (WINDOW_WANTS_HEADER_LINE_P (w
))
1261 current_header_line_height
1262 = display_mode_line (w
, HEADER_LINE_FACE_ID
,
1263 current_buffer
->header_line_format
);
1266 start_display (&it
, w
, top
);
1267 move_it_to (&it
, charpos
, 0, it
.last_visible_y
, -1,
1268 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
1270 /* Note that we may overshoot because of invisible text. */
1271 if (IT_CHARPOS (it
) >= charpos
)
1273 int top_y
= it
.current_y
;
1274 int bottom_y
= line_bottom_y (&it
);
1275 int window_top_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
1277 if (top_y
< window_top_y
)
1278 visible_p
= bottom_y
> window_top_y
;
1279 else if (top_y
< it
.last_visible_y
)
1282 *fully
= bottom_y
<= it
.last_visible_y
;
1285 else if (it
.current_y
+ it
.max_ascent
+ it
.max_descent
> it
.last_visible_y
)
1287 move_it_by_lines (&it
, 1, 0);
1288 if (charpos
< IT_CHARPOS (it
))
1296 set_buffer_internal_1 (old_buffer
);
1298 current_header_line_height
= current_mode_line_height
= -1;
1303 /* Return the next character from STR which is MAXLEN bytes long.
1304 Return in *LEN the length of the character. This is like
1305 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1306 we find one, we return a `?', but with the length of the invalid
1310 string_char_and_length (str
, maxlen
, len
)
1311 const unsigned char *str
;
1316 c
= STRING_CHAR_AND_LENGTH (str
, maxlen
, *len
);
1317 if (!CHAR_VALID_P (c
, 1))
1318 /* We may not change the length here because other places in Emacs
1319 don't use this function, i.e. they silently accept invalid
1328 /* Given a position POS containing a valid character and byte position
1329 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1331 static struct text_pos
1332 string_pos_nchars_ahead (pos
, string
, nchars
)
1333 struct text_pos pos
;
1337 xassert (STRINGP (string
) && nchars
>= 0);
1339 if (STRING_MULTIBYTE (string
))
1341 int rest
= SBYTES (string
) - BYTEPOS (pos
);
1342 const unsigned char *p
= SDATA (string
) + BYTEPOS (pos
);
1347 string_char_and_length (p
, rest
, &len
);
1348 p
+= len
, rest
-= len
;
1349 xassert (rest
>= 0);
1351 BYTEPOS (pos
) += len
;
1355 SET_TEXT_POS (pos
, CHARPOS (pos
) + nchars
, BYTEPOS (pos
) + nchars
);
1361 /* Value is the text position, i.e. character and byte position,
1362 for character position CHARPOS in STRING. */
1364 static INLINE
struct text_pos
1365 string_pos (charpos
, string
)
1369 struct text_pos pos
;
1370 xassert (STRINGP (string
));
1371 xassert (charpos
>= 0);
1372 SET_TEXT_POS (pos
, charpos
, string_char_to_byte (string
, charpos
));
1377 /* Value is a text position, i.e. character and byte position, for
1378 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1379 means recognize multibyte characters. */
1381 static struct text_pos
1382 c_string_pos (charpos
, s
, multibyte_p
)
1387 struct text_pos pos
;
1389 xassert (s
!= NULL
);
1390 xassert (charpos
>= 0);
1394 int rest
= strlen (s
), len
;
1396 SET_TEXT_POS (pos
, 0, 0);
1399 string_char_and_length (s
, rest
, &len
);
1400 s
+= len
, rest
-= len
;
1401 xassert (rest
>= 0);
1403 BYTEPOS (pos
) += len
;
1407 SET_TEXT_POS (pos
, charpos
, charpos
);
1413 /* Value is the number of characters in C string S. MULTIBYTE_P
1414 non-zero means recognize multibyte characters. */
1417 number_of_chars (s
, multibyte_p
)
1425 int rest
= strlen (s
), len
;
1426 unsigned char *p
= (unsigned char *) s
;
1428 for (nchars
= 0; rest
> 0; ++nchars
)
1430 string_char_and_length (p
, rest
, &len
);
1431 rest
-= len
, p
+= len
;
1435 nchars
= strlen (s
);
1441 /* Compute byte position NEWPOS->bytepos corresponding to
1442 NEWPOS->charpos. POS is a known position in string STRING.
1443 NEWPOS->charpos must be >= POS.charpos. */
1446 compute_string_pos (newpos
, pos
, string
)
1447 struct text_pos
*newpos
, pos
;
1450 xassert (STRINGP (string
));
1451 xassert (CHARPOS (*newpos
) >= CHARPOS (pos
));
1453 if (STRING_MULTIBYTE (string
))
1454 *newpos
= string_pos_nchars_ahead (pos
, string
,
1455 CHARPOS (*newpos
) - CHARPOS (pos
));
1457 BYTEPOS (*newpos
) = CHARPOS (*newpos
);
1461 Return an estimation of the pixel height of mode or top lines on
1462 frame F. FACE_ID specifies what line's height to estimate. */
1465 estimate_mode_line_height (f
, face_id
)
1467 enum face_id face_id
;
1469 #ifdef HAVE_WINDOW_SYSTEM
1470 if (FRAME_WINDOW_P (f
))
1472 int height
= FONT_HEIGHT (FRAME_FONT (f
));
1474 /* This function is called so early when Emacs starts that the face
1475 cache and mode line face are not yet initialized. */
1476 if (FRAME_FACE_CACHE (f
))
1478 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1482 height
= FONT_HEIGHT (face
->font
);
1483 if (face
->box_line_width
> 0)
1484 height
+= 2 * face
->box_line_width
;
1495 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1496 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1497 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1498 not force the value into range. */
1501 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
, noclip
)
1503 register int pix_x
, pix_y
;
1505 NativeRectangle
*bounds
;
1509 #ifdef HAVE_WINDOW_SYSTEM
1510 if (FRAME_WINDOW_P (f
))
1512 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1513 even for negative values. */
1515 pix_x
-= FRAME_COLUMN_WIDTH (f
) - 1;
1517 pix_y
-= FRAME_LINE_HEIGHT (f
) - 1;
1519 pix_x
= FRAME_PIXEL_X_TO_COL (f
, pix_x
);
1520 pix_y
= FRAME_PIXEL_Y_TO_LINE (f
, pix_y
);
1523 STORE_NATIVE_RECT (*bounds
,
1524 FRAME_COL_TO_PIXEL_X (f
, pix_x
),
1525 FRAME_LINE_TO_PIXEL_Y (f
, pix_y
),
1526 FRAME_COLUMN_WIDTH (f
) - 1,
1527 FRAME_LINE_HEIGHT (f
) - 1);
1533 else if (pix_x
> FRAME_TOTAL_COLS (f
))
1534 pix_x
= FRAME_TOTAL_COLS (f
);
1538 else if (pix_y
> FRAME_LINES (f
))
1539 pix_y
= FRAME_LINES (f
);
1549 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1550 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1551 can't tell the positions because W's display is not up to date,
1555 glyph_to_pixel_coords (w
, hpos
, vpos
, frame_x
, frame_y
)
1558 int *frame_x
, *frame_y
;
1560 #ifdef HAVE_WINDOW_SYSTEM
1561 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w
))))
1565 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
1566 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
1568 if (display_completed
)
1570 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
1571 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
1572 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
1578 hpos
+= glyph
->pixel_width
;
1582 /* If first glyph is partially visible, its first visible position is still 0. */
1594 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, hpos
);
1595 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, vpos
);
1606 #ifdef HAVE_WINDOW_SYSTEM
1608 /* Find the glyph under window-relative coordinates X/Y in window W.
1609 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1610 strings. Return in *HPOS and *VPOS the row and column number of
1611 the glyph found. Return in *AREA the glyph area containing X.
1612 Value is a pointer to the glyph found or null if X/Y is not on
1613 text, or we can't tell because W's current matrix is not up to
1616 static struct glyph
*
1617 x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, dx
, dy
, area
)
1620 int *hpos
, *vpos
, *dx
, *dy
, *area
;
1622 struct glyph
*glyph
, *end
;
1623 struct glyph_row
*row
= NULL
;
1626 /* Find row containing Y. Give up if some row is not enabled. */
1627 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
1629 row
= MATRIX_ROW (w
->current_matrix
, i
);
1630 if (!row
->enabled_p
)
1632 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
1639 /* Give up if Y is not in the window. */
1640 if (i
== w
->current_matrix
->nrows
)
1643 /* Get the glyph area containing X. */
1644 if (w
->pseudo_window_p
)
1651 if (x
< window_box_left_offset (w
, TEXT_AREA
))
1653 *area
= LEFT_MARGIN_AREA
;
1654 x0
= window_box_left_offset (w
, LEFT_MARGIN_AREA
);
1656 else if (x
< window_box_right_offset (w
, TEXT_AREA
))
1659 x0
= window_box_left_offset (w
, TEXT_AREA
) + min (row
->x
, 0);
1663 *area
= RIGHT_MARGIN_AREA
;
1664 x0
= window_box_left_offset (w
, RIGHT_MARGIN_AREA
);
1668 /* Find glyph containing X. */
1669 glyph
= row
->glyphs
[*area
];
1670 end
= glyph
+ row
->used
[*area
];
1672 while (glyph
< end
&& x
>= glyph
->pixel_width
)
1674 x
-= glyph
->pixel_width
;
1684 *dy
= y
- (row
->y
+ row
->ascent
- glyph
->ascent
);
1687 *hpos
= glyph
- row
->glyphs
[*area
];
1693 Convert frame-relative x/y to coordinates relative to window W.
1694 Takes pseudo-windows into account. */
1697 frame_to_window_pixel_xy (w
, x
, y
)
1701 if (w
->pseudo_window_p
)
1703 /* A pseudo-window is always full-width, and starts at the
1704 left edge of the frame, plus a frame border. */
1705 struct frame
*f
= XFRAME (w
->frame
);
1706 *x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
1707 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
1711 *x
-= WINDOW_LEFT_EDGE_X (w
);
1712 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
1717 Return in *R the clipping rectangle for glyph string S. */
1720 get_glyph_string_clip_rect (s
, nr
)
1721 struct glyph_string
*s
;
1722 NativeRectangle
*nr
;
1726 if (s
->row
->full_width_p
)
1728 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1729 r
.x
= WINDOW_LEFT_EDGE_X (s
->w
);
1730 r
.width
= WINDOW_TOTAL_WIDTH (s
->w
);
1732 /* Unless displaying a mode or menu bar line, which are always
1733 fully visible, clip to the visible part of the row. */
1734 if (s
->w
->pseudo_window_p
)
1735 r
.height
= s
->row
->visible_height
;
1737 r
.height
= s
->height
;
1741 /* This is a text line that may be partially visible. */
1742 r
.x
= window_box_left (s
->w
, s
->area
);
1743 r
.width
= window_box_width (s
->w
, s
->area
);
1744 r
.height
= s
->row
->visible_height
;
1747 /* If S draws overlapping rows, it's sufficient to use the top and
1748 bottom of the window for clipping because this glyph string
1749 intentionally draws over other lines. */
1750 if (s
->for_overlaps_p
)
1752 r
.y
= WINDOW_HEADER_LINE_HEIGHT (s
->w
);
1753 r
.height
= window_text_bottom_y (s
->w
) - r
.y
;
1757 /* Don't use S->y for clipping because it doesn't take partially
1758 visible lines into account. For example, it can be negative for
1759 partially visible lines at the top of a window. */
1760 if (!s
->row
->full_width_p
1761 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
1762 r
.y
= WINDOW_HEADER_LINE_HEIGHT (s
->w
);
1764 r
.y
= max (0, s
->row
->y
);
1766 /* If drawing a tool-bar window, draw it over the internal border
1767 at the top of the window. */
1768 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
1769 r
.y
-= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
1772 r
.y
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
.y
);
1774 /* If drawing the cursor, don't let glyph draw outside its
1775 advertised boundaries. Cleartype does this under some circumstances. */
1776 if (s
->hl
== DRAW_CURSOR
)
1778 struct glyph
*glyph
= s
->first_glyph
;
1783 r
.width
-= s
->x
- r
.x
;
1786 r
.width
= min (r
.width
, glyph
->pixel_width
);
1788 /* Don't draw cursor glyph taller than our actual glyph. */
1789 height
= max (FRAME_LINE_HEIGHT (s
->f
), glyph
->ascent
+ glyph
->descent
);
1790 if (height
< r
.height
)
1792 int max_y
= r
.y
+ r
.height
;
1793 r
.y
= min (max_y
, s
->ybase
+ glyph
->descent
- height
);
1794 r
.height
= min (max_y
- r
.y
, height
);
1798 #ifdef CONVERT_FROM_XRECT
1799 CONVERT_FROM_XRECT (r
, *nr
);
1805 #endif /* HAVE_WINDOW_SYSTEM */
1808 /***********************************************************************
1809 Lisp form evaluation
1810 ***********************************************************************/
1812 /* Error handler for safe_eval and safe_call. */
1815 safe_eval_handler (arg
)
1818 add_to_log ("Error during redisplay: %s", arg
, Qnil
);
1823 /* Evaluate SEXPR and return the result, or nil if something went
1824 wrong. Prevent redisplay during the evaluation. */
1832 if (inhibit_eval_during_redisplay
)
1836 int count
= SPECPDL_INDEX ();
1837 struct gcpro gcpro1
;
1840 specbind (Qinhibit_redisplay
, Qt
);
1841 /* Use Qt to ensure debugger does not run,
1842 so there is no possibility of wanting to redisplay. */
1843 val
= internal_condition_case_1 (Feval
, sexpr
, Qt
,
1846 val
= unbind_to (count
, val
);
1853 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
1854 Return the result, or nil if something went wrong. Prevent
1855 redisplay during the evaluation. */
1858 safe_call (nargs
, args
)
1864 if (inhibit_eval_during_redisplay
)
1868 int count
= SPECPDL_INDEX ();
1869 struct gcpro gcpro1
;
1872 gcpro1
.nvars
= nargs
;
1873 specbind (Qinhibit_redisplay
, Qt
);
1874 /* Use Qt to ensure debugger does not run,
1875 so there is no possibility of wanting to redisplay. */
1876 val
= internal_condition_case_2 (Ffuncall
, nargs
, args
, Qt
,
1879 val
= unbind_to (count
, val
);
1886 /* Call function FN with one argument ARG.
1887 Return the result, or nil if something went wrong. */
1890 safe_call1 (fn
, arg
)
1891 Lisp_Object fn
, arg
;
1893 Lisp_Object args
[2];
1896 return safe_call (2, args
);
1901 /***********************************************************************
1903 ***********************************************************************/
1907 /* Define CHECK_IT to perform sanity checks on iterators.
1908 This is for debugging. It is too slow to do unconditionally. */
1914 if (it
->method
== next_element_from_string
)
1916 xassert (STRINGP (it
->string
));
1917 xassert (IT_STRING_CHARPOS (*it
) >= 0);
1921 xassert (IT_STRING_CHARPOS (*it
) < 0);
1922 if (it
->method
== next_element_from_buffer
)
1924 /* Check that character and byte positions agree. */
1925 xassert (IT_CHARPOS (*it
) == BYTE_TO_CHAR (IT_BYTEPOS (*it
)));
1930 xassert (it
->current
.dpvec_index
>= 0);
1932 xassert (it
->current
.dpvec_index
< 0);
1935 #define CHECK_IT(IT) check_it ((IT))
1939 #define CHECK_IT(IT) (void) 0
1946 /* Check that the window end of window W is what we expect it
1947 to be---the last row in the current matrix displaying text. */
1950 check_window_end (w
)
1953 if (!MINI_WINDOW_P (w
)
1954 && !NILP (w
->window_end_valid
))
1956 struct glyph_row
*row
;
1957 xassert ((row
= MATRIX_ROW (w
->current_matrix
,
1958 XFASTINT (w
->window_end_vpos
)),
1960 || MATRIX_ROW_DISPLAYS_TEXT_P (row
)
1961 || MATRIX_ROW_VPOS (row
, w
->current_matrix
) == 0));
1965 #define CHECK_WINDOW_END(W) check_window_end ((W))
1967 #else /* not GLYPH_DEBUG */
1969 #define CHECK_WINDOW_END(W) (void) 0
1971 #endif /* not GLYPH_DEBUG */
1975 /***********************************************************************
1976 Iterator initialization
1977 ***********************************************************************/
1979 /* Initialize IT for displaying current_buffer in window W, starting
1980 at character position CHARPOS. CHARPOS < 0 means that no buffer
1981 position is specified which is useful when the iterator is assigned
1982 a position later. BYTEPOS is the byte position corresponding to
1983 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
1985 If ROW is not null, calls to produce_glyphs with IT as parameter
1986 will produce glyphs in that row.
1988 BASE_FACE_ID is the id of a base face to use. It must be one of
1989 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
1990 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
1991 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
1993 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
1994 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
1995 will be initialized to use the corresponding mode line glyph row of
1996 the desired matrix of W. */
1999 init_iterator (it
, w
, charpos
, bytepos
, row
, base_face_id
)
2002 int charpos
, bytepos
;
2003 struct glyph_row
*row
;
2004 enum face_id base_face_id
;
2006 int highlight_region_p
;
2008 /* Some precondition checks. */
2009 xassert (w
!= NULL
&& it
!= NULL
);
2010 xassert (charpos
< 0 || (charpos
>= BUF_BEG (current_buffer
)
2013 /* If face attributes have been changed since the last redisplay,
2014 free realized faces now because they depend on face definitions
2015 that might have changed. Don't free faces while there might be
2016 desired matrices pending which reference these faces. */
2017 if (face_change_count
&& !inhibit_free_realized_faces
)
2019 face_change_count
= 0;
2020 free_all_realized_faces (Qnil
);
2023 /* Use one of the mode line rows of W's desired matrix if
2027 if (base_face_id
== MODE_LINE_FACE_ID
2028 || base_face_id
== MODE_LINE_INACTIVE_FACE_ID
)
2029 row
= MATRIX_MODE_LINE_ROW (w
->desired_matrix
);
2030 else if (base_face_id
== HEADER_LINE_FACE_ID
)
2031 row
= MATRIX_HEADER_LINE_ROW (w
->desired_matrix
);
2035 bzero (it
, sizeof *it
);
2036 it
->current
.overlay_string_index
= -1;
2037 it
->current
.dpvec_index
= -1;
2038 it
->base_face_id
= base_face_id
;
2040 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = -1;
2042 /* The window in which we iterate over current_buffer: */
2043 XSETWINDOW (it
->window
, w
);
2045 it
->f
= XFRAME (w
->frame
);
2047 /* Extra space between lines (on window systems only). */
2048 if (base_face_id
== DEFAULT_FACE_ID
2049 && FRAME_WINDOW_P (it
->f
))
2051 if (NATNUMP (current_buffer
->extra_line_spacing
))
2052 it
->extra_line_spacing
= XFASTINT (current_buffer
->extra_line_spacing
);
2053 else if (it
->f
->extra_line_spacing
> 0)
2054 it
->extra_line_spacing
= it
->f
->extra_line_spacing
;
2057 /* If realized faces have been removed, e.g. because of face
2058 attribute changes of named faces, recompute them. When running
2059 in batch mode, the face cache of the initial frame is null. If
2060 we happen to get called, make a dummy face cache. */
2061 if (FRAME_FACE_CACHE (it
->f
) == NULL
)
2062 init_frame_faces (it
->f
);
2063 if (FRAME_FACE_CACHE (it
->f
)->used
== 0)
2064 recompute_basic_faces (it
->f
);
2066 /* Current value of the `space-width', and 'height' properties. */
2067 it
->space_width
= Qnil
;
2068 it
->font_height
= Qnil
;
2070 /* Are control characters displayed as `^C'? */
2071 it
->ctl_arrow_p
= !NILP (current_buffer
->ctl_arrow
);
2073 /* -1 means everything between a CR and the following line end
2074 is invisible. >0 means lines indented more than this value are
2076 it
->selective
= (INTEGERP (current_buffer
->selective_display
)
2077 ? XFASTINT (current_buffer
->selective_display
)
2078 : (!NILP (current_buffer
->selective_display
)
2080 it
->selective_display_ellipsis_p
2081 = !NILP (current_buffer
->selective_display_ellipses
);
2083 /* Display table to use. */
2084 it
->dp
= window_display_table (w
);
2086 /* Are multibyte characters enabled in current_buffer? */
2087 it
->multibyte_p
= !NILP (current_buffer
->enable_multibyte_characters
);
2089 /* Non-zero if we should highlight the region. */
2091 = (!NILP (Vtransient_mark_mode
)
2092 && !NILP (current_buffer
->mark_active
)
2093 && XMARKER (current_buffer
->mark
)->buffer
!= 0);
2095 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2096 start and end of a visible region in window IT->w. Set both to
2097 -1 to indicate no region. */
2098 if (highlight_region_p
2099 /* Maybe highlight only in selected window. */
2100 && (/* Either show region everywhere. */
2101 highlight_nonselected_windows
2102 /* Or show region in the selected window. */
2103 || w
== XWINDOW (selected_window
)
2104 /* Or show the region if we are in the mini-buffer and W is
2105 the window the mini-buffer refers to. */
2106 || (MINI_WINDOW_P (XWINDOW (selected_window
))
2107 && WINDOWP (minibuf_selected_window
)
2108 && w
== XWINDOW (minibuf_selected_window
))))
2110 int charpos
= marker_position (current_buffer
->mark
);
2111 it
->region_beg_charpos
= min (PT
, charpos
);
2112 it
->region_end_charpos
= max (PT
, charpos
);
2115 it
->region_beg_charpos
= it
->region_end_charpos
= -1;
2117 /* Get the position at which the redisplay_end_trigger hook should
2118 be run, if it is to be run at all. */
2119 if (MARKERP (w
->redisplay_end_trigger
)
2120 && XMARKER (w
->redisplay_end_trigger
)->buffer
!= 0)
2121 it
->redisplay_end_trigger_charpos
2122 = marker_position (w
->redisplay_end_trigger
);
2123 else if (INTEGERP (w
->redisplay_end_trigger
))
2124 it
->redisplay_end_trigger_charpos
= XINT (w
->redisplay_end_trigger
);
2126 /* Correct bogus values of tab_width. */
2127 it
->tab_width
= XINT (current_buffer
->tab_width
);
2128 if (it
->tab_width
<= 0 || it
->tab_width
> 1000)
2131 /* Are lines in the display truncated? */
2132 it
->truncate_lines_p
2133 = (base_face_id
!= DEFAULT_FACE_ID
2134 || XINT (it
->w
->hscroll
)
2135 || (truncate_partial_width_windows
2136 && !WINDOW_FULL_WIDTH_P (it
->w
))
2137 || !NILP (current_buffer
->truncate_lines
));
2139 /* Get dimensions of truncation and continuation glyphs. These are
2140 displayed as fringe bitmaps under X, so we don't need them for such
2142 if (!FRAME_WINDOW_P (it
->f
))
2144 if (it
->truncate_lines_p
)
2146 /* We will need the truncation glyph. */
2147 xassert (it
->glyph_row
== NULL
);
2148 produce_special_glyphs (it
, IT_TRUNCATION
);
2149 it
->truncation_pixel_width
= it
->pixel_width
;
2153 /* We will need the continuation glyph. */
2154 xassert (it
->glyph_row
== NULL
);
2155 produce_special_glyphs (it
, IT_CONTINUATION
);
2156 it
->continuation_pixel_width
= it
->pixel_width
;
2159 /* Reset these values to zero because the produce_special_glyphs
2160 above has changed them. */
2161 it
->pixel_width
= it
->ascent
= it
->descent
= 0;
2162 it
->phys_ascent
= it
->phys_descent
= 0;
2165 /* Set this after getting the dimensions of truncation and
2166 continuation glyphs, so that we don't produce glyphs when calling
2167 produce_special_glyphs, above. */
2168 it
->glyph_row
= row
;
2169 it
->area
= TEXT_AREA
;
2171 /* Get the dimensions of the display area. The display area
2172 consists of the visible window area plus a horizontally scrolled
2173 part to the left of the window. All x-values are relative to the
2174 start of this total display area. */
2175 if (base_face_id
!= DEFAULT_FACE_ID
)
2177 /* Mode lines, menu bar in terminal frames. */
2178 it
->first_visible_x
= 0;
2179 it
->last_visible_x
= WINDOW_TOTAL_WIDTH (w
);
2184 = XFASTINT (it
->w
->hscroll
) * FRAME_COLUMN_WIDTH (it
->f
);
2185 it
->last_visible_x
= (it
->first_visible_x
2186 + window_box_width (w
, TEXT_AREA
));
2188 /* If we truncate lines, leave room for the truncator glyph(s) at
2189 the right margin. Otherwise, leave room for the continuation
2190 glyph(s). Truncation and continuation glyphs are not inserted
2191 for window-based redisplay. */
2192 if (!FRAME_WINDOW_P (it
->f
))
2194 if (it
->truncate_lines_p
)
2195 it
->last_visible_x
-= it
->truncation_pixel_width
;
2197 it
->last_visible_x
-= it
->continuation_pixel_width
;
2200 it
->header_line_p
= WINDOW_WANTS_HEADER_LINE_P (w
);
2201 it
->current_y
= WINDOW_HEADER_LINE_HEIGHT (w
) + w
->vscroll
;
2204 /* Leave room for a border glyph. */
2205 if (!FRAME_WINDOW_P (it
->f
)
2206 && !WINDOW_RIGHTMOST_P (it
->w
))
2207 it
->last_visible_x
-= 1;
2209 it
->last_visible_y
= window_text_bottom_y (w
);
2211 /* For mode lines and alike, arrange for the first glyph having a
2212 left box line if the face specifies a box. */
2213 if (base_face_id
!= DEFAULT_FACE_ID
)
2217 it
->face_id
= base_face_id
;
2219 /* If we have a boxed mode line, make the first character appear
2220 with a left box line. */
2221 face
= FACE_FROM_ID (it
->f
, base_face_id
);
2222 if (face
->box
!= FACE_NO_BOX
)
2223 it
->start_of_box_run_p
= 1;
2226 /* If a buffer position was specified, set the iterator there,
2227 getting overlays and face properties from that position. */
2228 if (charpos
>= BUF_BEG (current_buffer
))
2230 it
->end_charpos
= ZV
;
2232 IT_CHARPOS (*it
) = charpos
;
2234 /* Compute byte position if not specified. */
2235 if (bytepos
< charpos
)
2236 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (charpos
);
2238 IT_BYTEPOS (*it
) = bytepos
;
2240 it
->start
= it
->current
;
2242 /* Compute faces etc. */
2243 reseat (it
, it
->current
.pos
, 1);
2250 /* Initialize IT for the display of window W with window start POS. */
2253 start_display (it
, w
, pos
)
2256 struct text_pos pos
;
2258 struct glyph_row
*row
;
2259 int first_vpos
= WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0;
2261 row
= w
->desired_matrix
->rows
+ first_vpos
;
2262 init_iterator (it
, w
, CHARPOS (pos
), BYTEPOS (pos
), row
, DEFAULT_FACE_ID
);
2263 it
->first_vpos
= first_vpos
;
2265 if (!it
->truncate_lines_p
)
2267 int start_at_line_beg_p
;
2268 int first_y
= it
->current_y
;
2270 /* If window start is not at a line start, skip forward to POS to
2271 get the correct continuation lines width. */
2272 start_at_line_beg_p
= (CHARPOS (pos
) == BEGV
2273 || FETCH_BYTE (BYTEPOS (pos
) - 1) == '\n');
2274 if (!start_at_line_beg_p
)
2278 reseat_at_previous_visible_line_start (it
);
2279 move_it_to (it
, CHARPOS (pos
), -1, -1, -1, MOVE_TO_POS
);
2281 new_x
= it
->current_x
+ it
->pixel_width
;
2283 /* If lines are continued, this line may end in the middle
2284 of a multi-glyph character (e.g. a control character
2285 displayed as \003, or in the middle of an overlay
2286 string). In this case move_it_to above will not have
2287 taken us to the start of the continuation line but to the
2288 end of the continued line. */
2289 if (it
->current_x
> 0
2290 && !it
->truncate_lines_p
/* Lines are continued. */
2291 && (/* And glyph doesn't fit on the line. */
2292 new_x
> it
->last_visible_x
2293 /* Or it fits exactly and we're on a window
2295 || (new_x
== it
->last_visible_x
2296 && FRAME_WINDOW_P (it
->f
))))
2298 if (it
->current
.dpvec_index
>= 0
2299 || it
->current
.overlay_string_index
>= 0)
2301 set_iterator_to_next (it
, 1);
2302 move_it_in_display_line_to (it
, -1, -1, 0);
2305 it
->continuation_lines_width
+= it
->current_x
;
2308 /* We're starting a new display line, not affected by the
2309 height of the continued line, so clear the appropriate
2310 fields in the iterator structure. */
2311 it
->max_ascent
= it
->max_descent
= 0;
2312 it
->max_phys_ascent
= it
->max_phys_descent
= 0;
2314 it
->current_y
= first_y
;
2316 it
->current_x
= it
->hpos
= 0;
2320 #if 0 /* Don't assert the following because start_display is sometimes
2321 called intentionally with a window start that is not at a
2322 line start. Please leave this code in as a comment. */
2324 /* Window start should be on a line start, now. */
2325 xassert (it
->continuation_lines_width
2326 || IT_CHARPOS (it
) == BEGV
2327 || FETCH_BYTE (IT_BYTEPOS (it
) - 1) == '\n');
2332 /* Return 1 if POS is a position in ellipses displayed for invisible
2333 text. W is the window we display, for text property lookup. */
2336 in_ellipses_for_invisible_text_p (pos
, w
)
2337 struct display_pos
*pos
;
2340 Lisp_Object prop
, window
;
2342 int charpos
= CHARPOS (pos
->pos
);
2344 /* If POS specifies a position in a display vector, this might
2345 be for an ellipsis displayed for invisible text. We won't
2346 get the iterator set up for delivering that ellipsis unless
2347 we make sure that it gets aware of the invisible text. */
2348 if (pos
->dpvec_index
>= 0
2349 && pos
->overlay_string_index
< 0
2350 && CHARPOS (pos
->string_pos
) < 0
2352 && (XSETWINDOW (window
, w
),
2353 prop
= Fget_char_property (make_number (charpos
),
2354 Qinvisible
, window
),
2355 !TEXT_PROP_MEANS_INVISIBLE (prop
)))
2357 prop
= Fget_char_property (make_number (charpos
- 1), Qinvisible
,
2359 ellipses_p
= 2 == TEXT_PROP_MEANS_INVISIBLE (prop
);
2366 /* Initialize IT for stepping through current_buffer in window W,
2367 starting at position POS that includes overlay string and display
2368 vector/ control character translation position information. Value
2369 is zero if there are overlay strings with newlines at POS. */
2372 init_from_display_pos (it
, w
, pos
)
2375 struct display_pos
*pos
;
2377 int charpos
= CHARPOS (pos
->pos
), bytepos
= BYTEPOS (pos
->pos
);
2378 int i
, overlay_strings_with_newlines
= 0;
2380 /* If POS specifies a position in a display vector, this might
2381 be for an ellipsis displayed for invisible text. We won't
2382 get the iterator set up for delivering that ellipsis unless
2383 we make sure that it gets aware of the invisible text. */
2384 if (in_ellipses_for_invisible_text_p (pos
, w
))
2390 /* Keep in mind: the call to reseat in init_iterator skips invisible
2391 text, so we might end up at a position different from POS. This
2392 is only a problem when POS is a row start after a newline and an
2393 overlay starts there with an after-string, and the overlay has an
2394 invisible property. Since we don't skip invisible text in
2395 display_line and elsewhere immediately after consuming the
2396 newline before the row start, such a POS will not be in a string,
2397 but the call to init_iterator below will move us to the
2399 init_iterator (it
, w
, charpos
, bytepos
, NULL
, DEFAULT_FACE_ID
);
2401 for (i
= 0; i
< it
->n_overlay_strings
; ++i
)
2403 const char *s
= SDATA (it
->overlay_strings
[i
]);
2404 const char *e
= s
+ SBYTES (it
->overlay_strings
[i
]);
2406 while (s
< e
&& *s
!= '\n')
2411 overlay_strings_with_newlines
= 1;
2416 /* If position is within an overlay string, set up IT to the right
2418 if (pos
->overlay_string_index
>= 0)
2422 /* If the first overlay string happens to have a `display'
2423 property for an image, the iterator will be set up for that
2424 image, and we have to undo that setup first before we can
2425 correct the overlay string index. */
2426 if (it
->method
== next_element_from_image
)
2429 /* We already have the first chunk of overlay strings in
2430 IT->overlay_strings. Load more until the one for
2431 pos->overlay_string_index is in IT->overlay_strings. */
2432 if (pos
->overlay_string_index
>= OVERLAY_STRING_CHUNK_SIZE
)
2434 int n
= pos
->overlay_string_index
/ OVERLAY_STRING_CHUNK_SIZE
;
2435 it
->current
.overlay_string_index
= 0;
2438 load_overlay_strings (it
, 0);
2439 it
->current
.overlay_string_index
+= OVERLAY_STRING_CHUNK_SIZE
;
2443 it
->current
.overlay_string_index
= pos
->overlay_string_index
;
2444 relative_index
= (it
->current
.overlay_string_index
2445 % OVERLAY_STRING_CHUNK_SIZE
);
2446 it
->string
= it
->overlay_strings
[relative_index
];
2447 xassert (STRINGP (it
->string
));
2448 it
->current
.string_pos
= pos
->string_pos
;
2449 it
->method
= next_element_from_string
;
2452 #if 0 /* This is bogus because POS not having an overlay string
2453 position does not mean it's after the string. Example: A
2454 line starting with a before-string and initialization of IT
2455 to the previous row's end position. */
2456 else if (it
->current
.overlay_string_index
>= 0)
2458 /* If POS says we're already after an overlay string ending at
2459 POS, make sure to pop the iterator because it will be in
2460 front of that overlay string. When POS is ZV, we've thereby
2461 also ``processed'' overlay strings at ZV. */
2464 it
->current
.overlay_string_index
= -1;
2465 it
->method
= next_element_from_buffer
;
2466 if (CHARPOS (pos
->pos
) == ZV
)
2467 it
->overlay_strings_at_end_processed_p
= 1;
2471 if (CHARPOS (pos
->string_pos
) >= 0)
2473 /* Recorded position is not in an overlay string, but in another
2474 string. This can only be a string from a `display' property.
2475 IT should already be filled with that string. */
2476 it
->current
.string_pos
= pos
->string_pos
;
2477 xassert (STRINGP (it
->string
));
2480 /* Restore position in display vector translations, control
2481 character translations or ellipses. */
2482 if (pos
->dpvec_index
>= 0)
2484 if (it
->dpvec
== NULL
)
2485 get_next_display_element (it
);
2486 xassert (it
->dpvec
&& it
->current
.dpvec_index
== 0);
2487 it
->current
.dpvec_index
= pos
->dpvec_index
;
2491 return !overlay_strings_with_newlines
;
2495 /* Initialize IT for stepping through current_buffer in window W
2496 starting at ROW->start. */
2499 init_to_row_start (it
, w
, row
)
2502 struct glyph_row
*row
;
2504 init_from_display_pos (it
, w
, &row
->start
);
2505 it
->start
= row
->start
;
2506 it
->continuation_lines_width
= row
->continuation_lines_width
;
2511 /* Initialize IT for stepping through current_buffer in window W
2512 starting in the line following ROW, i.e. starting at ROW->end.
2513 Value is zero if there are overlay strings with newlines at ROW's
2517 init_to_row_end (it
, w
, row
)
2520 struct glyph_row
*row
;
2524 if (init_from_display_pos (it
, w
, &row
->end
))
2526 if (row
->continued_p
)
2527 it
->continuation_lines_width
2528 = row
->continuation_lines_width
+ row
->pixel_width
;
2539 /***********************************************************************
2541 ***********************************************************************/
2543 /* Called when IT reaches IT->stop_charpos. Handle text property and
2544 overlay changes. Set IT->stop_charpos to the next position where
2551 enum prop_handled handled
;
2552 int handle_overlay_change_p
= 1;
2556 it
->current
.dpvec_index
= -1;
2560 handled
= HANDLED_NORMALLY
;
2562 /* Call text property handlers. */
2563 for (p
= it_props
; p
->handler
; ++p
)
2565 handled
= p
->handler (it
);
2567 if (handled
== HANDLED_RECOMPUTE_PROPS
)
2569 else if (handled
== HANDLED_RETURN
)
2571 else if (handled
== HANDLED_OVERLAY_STRING_CONSUMED
)
2572 handle_overlay_change_p
= 0;
2575 if (handled
!= HANDLED_RECOMPUTE_PROPS
)
2577 /* Don't check for overlay strings below when set to deliver
2578 characters from a display vector. */
2579 if (it
->method
== next_element_from_display_vector
)
2580 handle_overlay_change_p
= 0;
2582 /* Handle overlay changes. */
2583 if (handle_overlay_change_p
)
2584 handled
= handle_overlay_change (it
);
2586 /* Determine where to stop next. */
2587 if (handled
== HANDLED_NORMALLY
)
2588 compute_stop_pos (it
);
2591 while (handled
== HANDLED_RECOMPUTE_PROPS
);
2595 /* Compute IT->stop_charpos from text property and overlay change
2596 information for IT's current position. */
2599 compute_stop_pos (it
)
2602 register INTERVAL iv
, next_iv
;
2603 Lisp_Object object
, limit
, position
;
2605 /* If nowhere else, stop at the end. */
2606 it
->stop_charpos
= it
->end_charpos
;
2608 if (STRINGP (it
->string
))
2610 /* Strings are usually short, so don't limit the search for
2612 object
= it
->string
;
2614 position
= make_number (IT_STRING_CHARPOS (*it
));
2620 /* If next overlay change is in front of the current stop pos
2621 (which is IT->end_charpos), stop there. Note: value of
2622 next_overlay_change is point-max if no overlay change
2624 charpos
= next_overlay_change (IT_CHARPOS (*it
));
2625 if (charpos
< it
->stop_charpos
)
2626 it
->stop_charpos
= charpos
;
2628 /* If showing the region, we have to stop at the region
2629 start or end because the face might change there. */
2630 if (it
->region_beg_charpos
> 0)
2632 if (IT_CHARPOS (*it
) < it
->region_beg_charpos
)
2633 it
->stop_charpos
= min (it
->stop_charpos
, it
->region_beg_charpos
);
2634 else if (IT_CHARPOS (*it
) < it
->region_end_charpos
)
2635 it
->stop_charpos
= min (it
->stop_charpos
, it
->region_end_charpos
);
2638 /* Set up variables for computing the stop position from text
2639 property changes. */
2640 XSETBUFFER (object
, current_buffer
);
2641 limit
= make_number (IT_CHARPOS (*it
) + TEXT_PROP_DISTANCE_LIMIT
);
2642 position
= make_number (IT_CHARPOS (*it
));
2646 /* Get the interval containing IT's position. Value is a null
2647 interval if there isn't such an interval. */
2648 iv
= validate_interval_range (object
, &position
, &position
, 0);
2649 if (!NULL_INTERVAL_P (iv
))
2651 Lisp_Object values_here
[LAST_PROP_IDX
];
2654 /* Get properties here. */
2655 for (p
= it_props
; p
->handler
; ++p
)
2656 values_here
[p
->idx
] = textget (iv
->plist
, *p
->name
);
2658 /* Look for an interval following iv that has different
2660 for (next_iv
= next_interval (iv
);
2661 (!NULL_INTERVAL_P (next_iv
)
2663 || XFASTINT (limit
) > next_iv
->position
));
2664 next_iv
= next_interval (next_iv
))
2666 for (p
= it_props
; p
->handler
; ++p
)
2668 Lisp_Object new_value
;
2670 new_value
= textget (next_iv
->plist
, *p
->name
);
2671 if (!EQ (values_here
[p
->idx
], new_value
))
2679 if (!NULL_INTERVAL_P (next_iv
))
2681 if (INTEGERP (limit
)
2682 && next_iv
->position
>= XFASTINT (limit
))
2683 /* No text property change up to limit. */
2684 it
->stop_charpos
= min (XFASTINT (limit
), it
->stop_charpos
);
2686 /* Text properties change in next_iv. */
2687 it
->stop_charpos
= min (it
->stop_charpos
, next_iv
->position
);
2691 xassert (STRINGP (it
->string
)
2692 || (it
->stop_charpos
>= BEGV
2693 && it
->stop_charpos
>= IT_CHARPOS (*it
)));
2697 /* Return the position of the next overlay change after POS in
2698 current_buffer. Value is point-max if no overlay change
2699 follows. This is like `next-overlay-change' but doesn't use
2703 next_overlay_change (pos
)
2708 Lisp_Object
*overlays
;
2712 /* Get all overlays at the given position. */
2714 overlays
= (Lisp_Object
*) alloca (len
* sizeof *overlays
);
2715 noverlays
= overlays_at (pos
, 0, &overlays
, &len
, &endpos
, NULL
, 1);
2716 if (noverlays
> len
)
2719 overlays
= (Lisp_Object
*) alloca (len
* sizeof *overlays
);
2720 noverlays
= overlays_at (pos
, 0, &overlays
, &len
, &endpos
, NULL
, 1);
2723 /* If any of these overlays ends before endpos,
2724 use its ending point instead. */
2725 for (i
= 0; i
< noverlays
; ++i
)
2730 oend
= OVERLAY_END (overlays
[i
]);
2731 oendpos
= OVERLAY_POSITION (oend
);
2732 endpos
= min (endpos
, oendpos
);
2740 /***********************************************************************
2742 ***********************************************************************/
2744 /* Handle changes in the `fontified' property of the current buffer by
2745 calling hook functions from Qfontification_functions to fontify
2748 static enum prop_handled
2749 handle_fontified_prop (it
)
2752 Lisp_Object prop
, pos
;
2753 enum prop_handled handled
= HANDLED_NORMALLY
;
2755 /* Get the value of the `fontified' property at IT's current buffer
2756 position. (The `fontified' property doesn't have a special
2757 meaning in strings.) If the value is nil, call functions from
2758 Qfontification_functions. */
2759 if (!STRINGP (it
->string
)
2761 && !NILP (Vfontification_functions
)
2762 && !NILP (Vrun_hooks
)
2763 && (pos
= make_number (IT_CHARPOS (*it
)),
2764 prop
= Fget_char_property (pos
, Qfontified
, Qnil
),
2767 int count
= SPECPDL_INDEX ();
2770 val
= Vfontification_functions
;
2771 specbind (Qfontification_functions
, Qnil
);
2773 if (!CONSP (val
) || EQ (XCAR (val
), Qlambda
))
2774 safe_call1 (val
, pos
);
2777 Lisp_Object globals
, fn
;
2778 struct gcpro gcpro1
, gcpro2
;
2781 GCPRO2 (val
, globals
);
2783 for (; CONSP (val
); val
= XCDR (val
))
2789 /* A value of t indicates this hook has a local
2790 binding; it means to run the global binding too.
2791 In a global value, t should not occur. If it
2792 does, we must ignore it to avoid an endless
2794 for (globals
= Fdefault_value (Qfontification_functions
);
2796 globals
= XCDR (globals
))
2798 fn
= XCAR (globals
);
2800 safe_call1 (fn
, pos
);
2804 safe_call1 (fn
, pos
);
2810 unbind_to (count
, Qnil
);
2812 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
2813 something. This avoids an endless loop if they failed to
2814 fontify the text for which reason ever. */
2815 if (!NILP (Fget_char_property (pos
, Qfontified
, Qnil
)))
2816 handled
= HANDLED_RECOMPUTE_PROPS
;
2824 /***********************************************************************
2826 ***********************************************************************/
2828 /* Set up iterator IT from face properties at its current position.
2829 Called from handle_stop. */
2831 static enum prop_handled
2832 handle_face_prop (it
)
2835 int new_face_id
, next_stop
;
2837 if (!STRINGP (it
->string
))
2840 = face_at_buffer_position (it
->w
,
2842 it
->region_beg_charpos
,
2843 it
->region_end_charpos
,
2846 + TEXT_PROP_DISTANCE_LIMIT
),
2849 /* Is this a start of a run of characters with box face?
2850 Caveat: this can be called for a freshly initialized
2851 iterator; face_id is -1 in this case. We know that the new
2852 face will not change until limit, i.e. if the new face has a
2853 box, all characters up to limit will have one. But, as
2854 usual, we don't know whether limit is really the end. */
2855 if (new_face_id
!= it
->face_id
)
2857 struct face
*new_face
= FACE_FROM_ID (it
->f
, new_face_id
);
2859 /* If new face has a box but old face has not, this is
2860 the start of a run of characters with box, i.e. it has
2861 a shadow on the left side. The value of face_id of the
2862 iterator will be -1 if this is the initial call that gets
2863 the face. In this case, we have to look in front of IT's
2864 position and see whether there is a face != new_face_id. */
2865 it
->start_of_box_run_p
2866 = (new_face
->box
!= FACE_NO_BOX
2867 && (it
->face_id
>= 0
2868 || IT_CHARPOS (*it
) == BEG
2869 || new_face_id
!= face_before_it_pos (it
)));
2870 it
->face_box_p
= new_face
->box
!= FACE_NO_BOX
;
2875 int base_face_id
, bufpos
;
2877 if (it
->current
.overlay_string_index
>= 0)
2878 bufpos
= IT_CHARPOS (*it
);
2882 /* For strings from a buffer, i.e. overlay strings or strings
2883 from a `display' property, use the face at IT's current
2884 buffer position as the base face to merge with, so that
2885 overlay strings appear in the same face as surrounding
2886 text, unless they specify their own faces. */
2887 base_face_id
= underlying_face_id (it
);
2889 new_face_id
= face_at_string_position (it
->w
,
2891 IT_STRING_CHARPOS (*it
),
2893 it
->region_beg_charpos
,
2894 it
->region_end_charpos
,
2898 #if 0 /* This shouldn't be neccessary. Let's check it. */
2899 /* If IT is used to display a mode line we would really like to
2900 use the mode line face instead of the frame's default face. */
2901 if (it
->glyph_row
== MATRIX_MODE_LINE_ROW (it
->w
->desired_matrix
)
2902 && new_face_id
== DEFAULT_FACE_ID
)
2903 new_face_id
= CURRENT_MODE_LINE_FACE_ID (it
->w
);
2906 /* Is this a start of a run of characters with box? Caveat:
2907 this can be called for a freshly allocated iterator; face_id
2908 is -1 is this case. We know that the new face will not
2909 change until the next check pos, i.e. if the new face has a
2910 box, all characters up to that position will have a
2911 box. But, as usual, we don't know whether that position
2912 is really the end. */
2913 if (new_face_id
!= it
->face_id
)
2915 struct face
*new_face
= FACE_FROM_ID (it
->f
, new_face_id
);
2916 struct face
*old_face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2918 /* If new face has a box but old face hasn't, this is the
2919 start of a run of characters with box, i.e. it has a
2920 shadow on the left side. */
2921 it
->start_of_box_run_p
2922 = new_face
->box
&& (old_face
== NULL
|| !old_face
->box
);
2923 it
->face_box_p
= new_face
->box
!= FACE_NO_BOX
;
2927 it
->face_id
= new_face_id
;
2928 return HANDLED_NORMALLY
;
2932 /* Return the ID of the face ``underlying'' IT's current position,
2933 which is in a string. If the iterator is associated with a
2934 buffer, return the face at IT's current buffer position.
2935 Otherwise, use the iterator's base_face_id. */
2938 underlying_face_id (it
)
2941 int face_id
= it
->base_face_id
, i
;
2943 xassert (STRINGP (it
->string
));
2945 for (i
= it
->sp
- 1; i
>= 0; --i
)
2946 if (NILP (it
->stack
[i
].string
))
2947 face_id
= it
->stack
[i
].face_id
;
2953 /* Compute the face one character before or after the current position
2954 of IT. BEFORE_P non-zero means get the face in front of IT's
2955 position. Value is the id of the face. */
2958 face_before_or_after_it_pos (it
, before_p
)
2963 int next_check_charpos
;
2964 struct text_pos pos
;
2966 xassert (it
->s
== NULL
);
2968 if (STRINGP (it
->string
))
2970 int bufpos
, base_face_id
;
2972 /* No face change past the end of the string (for the case
2973 we are padding with spaces). No face change before the
2975 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
)
2976 || (IT_STRING_CHARPOS (*it
) == 0 && before_p
))
2979 /* Set pos to the position before or after IT's current position. */
2981 pos
= string_pos (IT_STRING_CHARPOS (*it
) - 1, it
->string
);
2983 /* For composition, we must check the character after the
2985 pos
= (it
->what
== IT_COMPOSITION
2986 ? string_pos (IT_STRING_CHARPOS (*it
) + it
->cmp_len
, it
->string
)
2987 : string_pos (IT_STRING_CHARPOS (*it
) + 1, it
->string
));
2989 if (it
->current
.overlay_string_index
>= 0)
2990 bufpos
= IT_CHARPOS (*it
);
2994 base_face_id
= underlying_face_id (it
);
2996 /* Get the face for ASCII, or unibyte. */
2997 face_id
= face_at_string_position (it
->w
,
3001 it
->region_beg_charpos
,
3002 it
->region_end_charpos
,
3003 &next_check_charpos
,
3006 /* Correct the face for charsets different from ASCII. Do it
3007 for the multibyte case only. The face returned above is
3008 suitable for unibyte text if IT->string is unibyte. */
3009 if (STRING_MULTIBYTE (it
->string
))
3011 const unsigned char *p
= SDATA (it
->string
) + BYTEPOS (pos
);
3012 int rest
= SBYTES (it
->string
) - BYTEPOS (pos
);
3014 struct face
*face
= FACE_FROM_ID (it
->f
, face_id
);
3016 c
= string_char_and_length (p
, rest
, &len
);
3017 face_id
= FACE_FOR_CHAR (it
->f
, face
, c
);
3022 if ((IT_CHARPOS (*it
) >= ZV
&& !before_p
)
3023 || (IT_CHARPOS (*it
) <= BEGV
&& before_p
))
3026 limit
= IT_CHARPOS (*it
) + TEXT_PROP_DISTANCE_LIMIT
;
3027 pos
= it
->current
.pos
;
3030 DEC_TEXT_POS (pos
, it
->multibyte_p
);
3033 if (it
->what
== IT_COMPOSITION
)
3034 /* For composition, we must check the position after the
3036 pos
.charpos
+= it
->cmp_len
, pos
.bytepos
+= it
->len
;
3038 INC_TEXT_POS (pos
, it
->multibyte_p
);
3041 /* Determine face for CHARSET_ASCII, or unibyte. */
3042 face_id
= face_at_buffer_position (it
->w
,
3044 it
->region_beg_charpos
,
3045 it
->region_end_charpos
,
3046 &next_check_charpos
,
3049 /* Correct the face for charsets different from ASCII. Do it
3050 for the multibyte case only. The face returned above is
3051 suitable for unibyte text if current_buffer is unibyte. */
3052 if (it
->multibyte_p
)
3054 int c
= FETCH_MULTIBYTE_CHAR (BYTEPOS (pos
));
3055 struct face
*face
= FACE_FROM_ID (it
->f
, face_id
);
3056 face_id
= FACE_FOR_CHAR (it
->f
, face
, c
);
3065 /***********************************************************************
3067 ***********************************************************************/
3069 /* Set up iterator IT from invisible properties at its current
3070 position. Called from handle_stop. */
3072 static enum prop_handled
3073 handle_invisible_prop (it
)
3076 enum prop_handled handled
= HANDLED_NORMALLY
;
3078 if (STRINGP (it
->string
))
3080 extern Lisp_Object Qinvisible
;
3081 Lisp_Object prop
, end_charpos
, limit
, charpos
;
3083 /* Get the value of the invisible text property at the
3084 current position. Value will be nil if there is no such
3086 charpos
= make_number (IT_STRING_CHARPOS (*it
));
3087 prop
= Fget_text_property (charpos
, Qinvisible
, it
->string
);
3090 && IT_STRING_CHARPOS (*it
) < it
->end_charpos
)
3092 handled
= HANDLED_RECOMPUTE_PROPS
;
3094 /* Get the position at which the next change of the
3095 invisible text property can be found in IT->string.
3096 Value will be nil if the property value is the same for
3097 all the rest of IT->string. */
3098 XSETINT (limit
, SCHARS (it
->string
));
3099 end_charpos
= Fnext_single_property_change (charpos
, Qinvisible
,
3102 /* Text at current position is invisible. The next
3103 change in the property is at position end_charpos.
3104 Move IT's current position to that position. */
3105 if (INTEGERP (end_charpos
)
3106 && XFASTINT (end_charpos
) < XFASTINT (limit
))
3108 struct text_pos old
;
3109 old
= it
->current
.string_pos
;
3110 IT_STRING_CHARPOS (*it
) = XFASTINT (end_charpos
);
3111 compute_string_pos (&it
->current
.string_pos
, old
, it
->string
);
3115 /* The rest of the string is invisible. If this is an
3116 overlay string, proceed with the next overlay string
3117 or whatever comes and return a character from there. */
3118 if (it
->current
.overlay_string_index
>= 0)
3120 next_overlay_string (it
);
3121 /* Don't check for overlay strings when we just
3122 finished processing them. */
3123 handled
= HANDLED_OVERLAY_STRING_CONSUMED
;
3127 IT_STRING_CHARPOS (*it
) = SCHARS (it
->string
);
3128 IT_STRING_BYTEPOS (*it
) = SBYTES (it
->string
);
3135 int invis_p
, newpos
, next_stop
, start_charpos
;
3136 Lisp_Object pos
, prop
, overlay
;
3138 /* First of all, is there invisible text at this position? */
3139 start_charpos
= IT_CHARPOS (*it
);
3140 pos
= make_number (IT_CHARPOS (*it
));
3141 prop
= get_char_property_and_overlay (pos
, Qinvisible
, it
->window
,
3143 invis_p
= TEXT_PROP_MEANS_INVISIBLE (prop
);
3145 /* If we are on invisible text, skip over it. */
3146 if (invis_p
&& IT_CHARPOS (*it
) < it
->end_charpos
)
3148 /* Record whether we have to display an ellipsis for the
3150 int display_ellipsis_p
= invis_p
== 2;
3152 handled
= HANDLED_RECOMPUTE_PROPS
;
3154 /* Loop skipping over invisible text. The loop is left at
3155 ZV or with IT on the first char being visible again. */
3158 /* Try to skip some invisible text. Return value is the
3159 position reached which can be equal to IT's position
3160 if there is nothing invisible here. This skips both
3161 over invisible text properties and overlays with
3162 invisible property. */
3163 newpos
= skip_invisible (IT_CHARPOS (*it
),
3164 &next_stop
, ZV
, it
->window
);
3166 /* If we skipped nothing at all we weren't at invisible
3167 text in the first place. If everything to the end of
3168 the buffer was skipped, end the loop. */
3169 if (newpos
== IT_CHARPOS (*it
) || newpos
>= ZV
)
3173 /* We skipped some characters but not necessarily
3174 all there are. Check if we ended up on visible
3175 text. Fget_char_property returns the property of
3176 the char before the given position, i.e. if we
3177 get invis_p = 0, this means that the char at
3178 newpos is visible. */
3179 pos
= make_number (newpos
);
3180 prop
= Fget_char_property (pos
, Qinvisible
, it
->window
);
3181 invis_p
= TEXT_PROP_MEANS_INVISIBLE (prop
);
3184 /* If we ended up on invisible text, proceed to
3185 skip starting with next_stop. */
3187 IT_CHARPOS (*it
) = next_stop
;
3191 /* The position newpos is now either ZV or on visible text. */
3192 IT_CHARPOS (*it
) = newpos
;
3193 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (newpos
);
3195 /* If there are before-strings at the start of invisible
3196 text, and the text is invisible because of a text
3197 property, arrange to show before-strings because 20.x did
3198 it that way. (If the text is invisible because of an
3199 overlay property instead of a text property, this is
3200 already handled in the overlay code.) */
3202 && get_overlay_strings (it
, start_charpos
))
3204 handled
= HANDLED_RECOMPUTE_PROPS
;
3205 it
->stack
[it
->sp
- 1].display_ellipsis_p
= display_ellipsis_p
;
3207 else if (display_ellipsis_p
)
3208 setup_for_ellipsis (it
);
3216 /* Make iterator IT return `...' next. */
3219 setup_for_ellipsis (it
)
3223 && VECTORP (DISP_INVIS_VECTOR (it
->dp
)))
3225 struct Lisp_Vector
*v
= XVECTOR (DISP_INVIS_VECTOR (it
->dp
));
3226 it
->dpvec
= v
->contents
;
3227 it
->dpend
= v
->contents
+ v
->size
;
3231 /* Default `...'. */
3232 it
->dpvec
= default_invis_vector
;
3233 it
->dpend
= default_invis_vector
+ 3;
3236 /* The ellipsis display does not replace the display of the
3237 character at the new position. Indicate this by setting
3238 IT->dpvec_char_len to zero. */
3239 it
->dpvec_char_len
= 0;
3241 it
->current
.dpvec_index
= 0;
3242 it
->method
= next_element_from_display_vector
;
3247 /***********************************************************************
3249 ***********************************************************************/
3251 /* Set up iterator IT from `display' property at its current position.
3252 Called from handle_stop. */
3254 static enum prop_handled
3255 handle_display_prop (it
)
3258 Lisp_Object prop
, object
;
3259 struct text_pos
*position
;
3260 int display_replaced_p
= 0;
3262 if (STRINGP (it
->string
))
3264 object
= it
->string
;
3265 position
= &it
->current
.string_pos
;
3269 object
= it
->w
->buffer
;
3270 position
= &it
->current
.pos
;
3273 /* Reset those iterator values set from display property values. */
3274 it
->font_height
= Qnil
;
3275 it
->space_width
= Qnil
;
3278 /* We don't support recursive `display' properties, i.e. string
3279 values that have a string `display' property, that have a string
3280 `display' property etc. */
3281 if (!it
->string_from_display_prop_p
)
3282 it
->area
= TEXT_AREA
;
3284 prop
= Fget_char_property (make_number (position
->charpos
),
3287 return HANDLED_NORMALLY
;
3290 /* Simple properties. */
3291 && !EQ (XCAR (prop
), Qimage
)
3292 && !EQ (XCAR (prop
), Qspace
)
3293 && !EQ (XCAR (prop
), Qwhen
)
3294 && !EQ (XCAR (prop
), Qspace_width
)
3295 && !EQ (XCAR (prop
), Qheight
)
3296 && !EQ (XCAR (prop
), Qraise
)
3297 /* Marginal area specifications. */
3298 && !(CONSP (XCAR (prop
)) && EQ (XCAR (XCAR (prop
)), Qmargin
))
3299 && !EQ (XCAR (prop
), Qleft_fringe
)
3300 && !EQ (XCAR (prop
), Qright_fringe
)
3301 && !NILP (XCAR (prop
)))
3303 for (; CONSP (prop
); prop
= XCDR (prop
))
3305 if (handle_single_display_prop (it
, XCAR (prop
), object
,
3306 position
, display_replaced_p
))
3307 display_replaced_p
= 1;
3310 else if (VECTORP (prop
))
3313 for (i
= 0; i
< ASIZE (prop
); ++i
)
3314 if (handle_single_display_prop (it
, AREF (prop
, i
), object
,
3315 position
, display_replaced_p
))
3316 display_replaced_p
= 1;
3320 if (handle_single_display_prop (it
, prop
, object
, position
, 0))
3321 display_replaced_p
= 1;
3324 return display_replaced_p
? HANDLED_RETURN
: HANDLED_NORMALLY
;
3328 /* Value is the position of the end of the `display' property starting
3329 at START_POS in OBJECT. */
3331 static struct text_pos
3332 display_prop_end (it
, object
, start_pos
)
3335 struct text_pos start_pos
;
3338 struct text_pos end_pos
;
3340 end
= Fnext_single_char_property_change (make_number (CHARPOS (start_pos
)),
3341 Qdisplay
, object
, Qnil
);
3342 CHARPOS (end_pos
) = XFASTINT (end
);
3343 if (STRINGP (object
))
3344 compute_string_pos (&end_pos
, start_pos
, it
->string
);
3346 BYTEPOS (end_pos
) = CHAR_TO_BYTE (XFASTINT (end
));
3352 /* Set up IT from a single `display' sub-property value PROP. OBJECT
3353 is the object in which the `display' property was found. *POSITION
3354 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3355 means that we previously saw a display sub-property which already
3356 replaced text display with something else, for example an image;
3357 ignore such properties after the first one has been processed.
3359 If PROP is a `space' or `image' sub-property, set *POSITION to the
3360 end position of the `display' property.
3362 Value is non-zero if something was found which replaces the display
3363 of buffer or string text. */
3366 handle_single_display_prop (it
, prop
, object
, position
,
3367 display_replaced_before_p
)
3371 struct text_pos
*position
;
3372 int display_replaced_before_p
;
3375 int replaces_text_display_p
= 0;
3378 /* If PROP is a list of the form `(when FORM . VALUE)', FORM is
3379 evaluated. If the result is nil, VALUE is ignored. */
3381 if (CONSP (prop
) && EQ (XCAR (prop
), Qwhen
))
3390 if (!NILP (form
) && !EQ (form
, Qt
))
3392 int count
= SPECPDL_INDEX ();
3393 struct gcpro gcpro1
;
3395 /* Bind `object' to the object having the `display' property, a
3396 buffer or string. Bind `position' to the position in the
3397 object where the property was found, and `buffer-position'
3398 to the current position in the buffer. */
3399 specbind (Qobject
, object
);
3400 specbind (Qposition
, make_number (CHARPOS (*position
)));
3401 specbind (Qbuffer_position
,
3402 make_number (STRINGP (object
)
3403 ? IT_CHARPOS (*it
) : CHARPOS (*position
)));
3405 form
= safe_eval (form
);
3407 unbind_to (count
, Qnil
);
3414 && EQ (XCAR (prop
), Qheight
)
3415 && CONSP (XCDR (prop
)))
3417 if (FRAME_TERMCAP_P (it
->f
) || FRAME_MSDOS_P (it
->f
))
3420 /* `(height HEIGHT)'. */
3421 it
->font_height
= XCAR (XCDR (prop
));
3422 if (!NILP (it
->font_height
))
3424 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
3425 int new_height
= -1;
3427 if (CONSP (it
->font_height
)
3428 && (EQ (XCAR (it
->font_height
), Qplus
)
3429 || EQ (XCAR (it
->font_height
), Qminus
))
3430 && CONSP (XCDR (it
->font_height
))
3431 && INTEGERP (XCAR (XCDR (it
->font_height
))))
3433 /* `(+ N)' or `(- N)' where N is an integer. */
3434 int steps
= XINT (XCAR (XCDR (it
->font_height
)));
3435 if (EQ (XCAR (it
->font_height
), Qplus
))
3437 it
->face_id
= smaller_face (it
->f
, it
->face_id
, steps
);
3439 else if (FUNCTIONP (it
->font_height
))
3441 /* Call function with current height as argument.
3442 Value is the new height. */
3444 height
= safe_call1 (it
->font_height
,
3445 face
->lface
[LFACE_HEIGHT_INDEX
]);
3446 if (NUMBERP (height
))
3447 new_height
= XFLOATINT (height
);
3449 else if (NUMBERP (it
->font_height
))
3451 /* Value is a multiple of the canonical char height. */
3454 face
= FACE_FROM_ID (it
->f
, DEFAULT_FACE_ID
);
3455 new_height
= (XFLOATINT (it
->font_height
)
3456 * XINT (face
->lface
[LFACE_HEIGHT_INDEX
]));
3460 /* Evaluate IT->font_height with `height' bound to the
3461 current specified height to get the new height. */
3463 int count
= SPECPDL_INDEX ();
3465 specbind (Qheight
, face
->lface
[LFACE_HEIGHT_INDEX
]);
3466 value
= safe_eval (it
->font_height
);
3467 unbind_to (count
, Qnil
);
3469 if (NUMBERP (value
))
3470 new_height
= XFLOATINT (value
);
3474 it
->face_id
= face_with_height (it
->f
, it
->face_id
, new_height
);
3477 else if (CONSP (prop
)
3478 && EQ (XCAR (prop
), Qspace_width
)
3479 && CONSP (XCDR (prop
)))
3481 /* `(space_width WIDTH)'. */
3482 if (FRAME_TERMCAP_P (it
->f
) || FRAME_MSDOS_P (it
->f
))
3485 value
= XCAR (XCDR (prop
));
3486 if (NUMBERP (value
) && XFLOATINT (value
) > 0)
3487 it
->space_width
= value
;
3489 else if (CONSP (prop
)
3490 && EQ (XCAR (prop
), Qraise
)
3491 && CONSP (XCDR (prop
)))
3493 /* `(raise FACTOR)'. */
3494 if (FRAME_TERMCAP_P (it
->f
) || FRAME_MSDOS_P (it
->f
))
3497 #ifdef HAVE_WINDOW_SYSTEM
3498 value
= XCAR (XCDR (prop
));
3499 if (NUMBERP (value
))
3501 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
3502 it
->voffset
= - (XFLOATINT (value
)
3503 * (FONT_HEIGHT (face
->font
)));
3505 #endif /* HAVE_WINDOW_SYSTEM */
3507 else if (!it
->string_from_display_prop_p
)
3509 /* `((margin left-margin) VALUE)' or `((margin right-margin)
3510 VALUE) or `((margin nil) VALUE)' or VALUE. */
3511 Lisp_Object location
, value
;
3512 struct text_pos start_pos
;
3515 /* Characters having this form of property are not displayed, so
3516 we have to find the end of the property. */
3517 start_pos
= *position
;
3518 *position
= display_prop_end (it
, object
, start_pos
);
3521 /* Let's stop at the new position and assume that all
3522 text properties change there. */
3523 it
->stop_charpos
= position
->charpos
;
3526 && (EQ (XCAR (prop
), Qleft_fringe
)
3527 || EQ (XCAR (prop
), Qright_fringe
))
3528 && CONSP (XCDR (prop
)))
3530 unsigned face_id
= DEFAULT_FACE_ID
;
3532 /* Save current settings of IT so that we can restore them
3533 when we are finished with the glyph property value. */
3535 /* `(left-fringe BITMAP FACE)'. */
3536 if (FRAME_TERMCAP_P (it
->f
) || FRAME_MSDOS_P (it
->f
))
3539 #ifdef HAVE_WINDOW_SYSTEM
3540 value
= XCAR (XCDR (prop
));
3541 if (!NUMBERP (value
)
3542 || !valid_fringe_bitmap_id_p (XINT (value
)))
3545 if (CONSP (XCDR (XCDR (prop
))))
3547 Lisp_Object face_name
= XCAR (XCDR (XCDR (prop
)));
3549 face_id
= lookup_named_face (it
->f
, face_name
, 'A');
3556 it
->area
= TEXT_AREA
;
3557 it
->what
= IT_IMAGE
;
3558 it
->image_id
= -1; /* no image */
3559 it
->position
= start_pos
;
3560 it
->object
= NILP (object
) ? it
->w
->buffer
: object
;
3561 it
->method
= next_element_from_image
;
3562 it
->face_id
= face_id
;
3564 /* Say that we haven't consumed the characters with
3565 `display' property yet. The call to pop_it in
3566 set_iterator_to_next will clean this up. */
3567 *position
= start_pos
;
3569 if (EQ (XCAR (prop
), Qleft_fringe
))
3571 it
->left_user_fringe_bitmap
= XINT (value
);
3572 it
->left_user_fringe_face_id
= face_id
;
3576 it
->right_user_fringe_bitmap
= XINT (value
);
3577 it
->right_user_fringe_face_id
= face_id
;
3579 #endif /* HAVE_WINDOW_SYSTEM */
3583 location
= Qunbound
;
3584 if (CONSP (prop
) && CONSP (XCAR (prop
)))
3588 value
= XCDR (prop
);
3590 value
= XCAR (value
);
3593 if (EQ (XCAR (tem
), Qmargin
)
3594 && (tem
= XCDR (tem
),
3595 tem
= CONSP (tem
) ? XCAR (tem
) : Qnil
,
3597 || EQ (tem
, Qleft_margin
)
3598 || EQ (tem
, Qright_margin
))))
3602 if (EQ (location
, Qunbound
))
3608 valid_p
= (STRINGP (value
)
3609 #ifdef HAVE_WINDOW_SYSTEM
3610 || (!FRAME_TERMCAP_P (it
->f
) && valid_image_p (value
))
3611 #endif /* not HAVE_WINDOW_SYSTEM */
3612 || (CONSP (value
) && EQ (XCAR (value
), Qspace
)));
3614 if ((EQ (location
, Qleft_margin
)
3615 || EQ (location
, Qright_margin
)
3618 && !display_replaced_before_p
)
3620 replaces_text_display_p
= 1;
3622 /* Save current settings of IT so that we can restore them
3623 when we are finished with the glyph property value. */
3626 if (NILP (location
))
3627 it
->area
= TEXT_AREA
;
3628 else if (EQ (location
, Qleft_margin
))
3629 it
->area
= LEFT_MARGIN_AREA
;
3631 it
->area
= RIGHT_MARGIN_AREA
;
3633 if (STRINGP (value
))
3636 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
3637 it
->current
.overlay_string_index
= -1;
3638 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = 0;
3639 it
->end_charpos
= it
->string_nchars
= SCHARS (it
->string
);
3640 it
->method
= next_element_from_string
;
3641 it
->stop_charpos
= 0;
3642 it
->string_from_display_prop_p
= 1;
3643 /* Say that we haven't consumed the characters with
3644 `display' property yet. The call to pop_it in
3645 set_iterator_to_next will clean this up. */
3646 *position
= start_pos
;
3648 else if (CONSP (value
) && EQ (XCAR (value
), Qspace
))
3650 it
->method
= next_element_from_stretch
;
3652 it
->current
.pos
= it
->position
= start_pos
;
3654 #ifdef HAVE_WINDOW_SYSTEM
3657 it
->what
= IT_IMAGE
;
3658 it
->image_id
= lookup_image (it
->f
, value
);
3659 it
->position
= start_pos
;
3660 it
->object
= NILP (object
) ? it
->w
->buffer
: object
;
3661 it
->method
= next_element_from_image
;
3663 /* Say that we haven't consumed the characters with
3664 `display' property yet. The call to pop_it in
3665 set_iterator_to_next will clean this up. */
3666 *position
= start_pos
;
3668 #endif /* HAVE_WINDOW_SYSTEM */
3671 /* Invalid property or property not supported. Restore
3672 the position to what it was before. */
3673 *position
= start_pos
;
3676 return replaces_text_display_p
;
3680 /* Check if PROP is a display sub-property value whose text should be
3681 treated as intangible. */
3684 single_display_prop_intangible_p (prop
)
3687 /* Skip over `when FORM'. */
3688 if (CONSP (prop
) && EQ (XCAR (prop
), Qwhen
))
3702 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
3703 we don't need to treat text as intangible. */
3704 if (EQ (XCAR (prop
), Qmargin
))
3712 || EQ (XCAR (prop
), Qleft_margin
)
3713 || EQ (XCAR (prop
), Qright_margin
))
3717 return (CONSP (prop
)
3718 && (EQ (XCAR (prop
), Qimage
)
3719 || EQ (XCAR (prop
), Qspace
)));
3723 /* Check if PROP is a display property value whose text should be
3724 treated as intangible. */
3727 display_prop_intangible_p (prop
)
3731 && CONSP (XCAR (prop
))
3732 && !EQ (Qmargin
, XCAR (XCAR (prop
))))
3734 /* A list of sub-properties. */
3735 while (CONSP (prop
))
3737 if (single_display_prop_intangible_p (XCAR (prop
)))
3742 else if (VECTORP (prop
))
3744 /* A vector of sub-properties. */
3746 for (i
= 0; i
< ASIZE (prop
); ++i
)
3747 if (single_display_prop_intangible_p (AREF (prop
, i
)))
3751 return single_display_prop_intangible_p (prop
);
3757 /* Return 1 if PROP is a display sub-property value containing STRING. */
3760 single_display_prop_string_p (prop
, string
)
3761 Lisp_Object prop
, string
;
3763 if (EQ (string
, prop
))
3766 /* Skip over `when FORM'. */
3767 if (CONSP (prop
) && EQ (XCAR (prop
), Qwhen
))
3776 /* Skip over `margin LOCATION'. */
3777 if (EQ (XCAR (prop
), Qmargin
))
3788 return CONSP (prop
) && EQ (XCAR (prop
), string
);
3792 /* Return 1 if STRING appears in the `display' property PROP. */
3795 display_prop_string_p (prop
, string
)
3796 Lisp_Object prop
, string
;
3799 && CONSP (XCAR (prop
))
3800 && !EQ (Qmargin
, XCAR (XCAR (prop
))))
3802 /* A list of sub-properties. */
3803 while (CONSP (prop
))
3805 if (single_display_prop_string_p (XCAR (prop
), string
))
3810 else if (VECTORP (prop
))
3812 /* A vector of sub-properties. */
3814 for (i
= 0; i
< ASIZE (prop
); ++i
)
3815 if (single_display_prop_string_p (AREF (prop
, i
), string
))
3819 return single_display_prop_string_p (prop
, string
);
3825 /* Determine from which buffer position in W's buffer STRING comes
3826 from. AROUND_CHARPOS is an approximate position where it could
3827 be from. Value is the buffer position or 0 if it couldn't be
3830 W's buffer must be current.
3832 This function is necessary because we don't record buffer positions
3833 in glyphs generated from strings (to keep struct glyph small).
3834 This function may only use code that doesn't eval because it is
3835 called asynchronously from note_mouse_highlight. */
3838 string_buffer_position (w
, string
, around_charpos
)
3843 Lisp_Object limit
, prop
, pos
;
3844 const int MAX_DISTANCE
= 1000;
3847 pos
= make_number (around_charpos
);
3848 limit
= make_number (min (XINT (pos
) + MAX_DISTANCE
, ZV
));
3849 while (!found
&& !EQ (pos
, limit
))
3851 prop
= Fget_char_property (pos
, Qdisplay
, Qnil
);
3852 if (!NILP (prop
) && display_prop_string_p (prop
, string
))
3855 pos
= Fnext_single_char_property_change (pos
, Qdisplay
, Qnil
, limit
);
3860 pos
= make_number (around_charpos
);
3861 limit
= make_number (max (XINT (pos
) - MAX_DISTANCE
, BEGV
));
3862 while (!found
&& !EQ (pos
, limit
))
3864 prop
= Fget_char_property (pos
, Qdisplay
, Qnil
);
3865 if (!NILP (prop
) && display_prop_string_p (prop
, string
))
3868 pos
= Fprevious_single_char_property_change (pos
, Qdisplay
, Qnil
,
3873 return found
? XINT (pos
) : 0;
3878 /***********************************************************************
3879 `composition' property
3880 ***********************************************************************/
3882 /* Set up iterator IT from `composition' property at its current
3883 position. Called from handle_stop. */
3885 static enum prop_handled
3886 handle_composition_prop (it
)
3889 Lisp_Object prop
, string
;
3890 int pos
, pos_byte
, end
;
3891 enum prop_handled handled
= HANDLED_NORMALLY
;
3893 if (STRINGP (it
->string
))
3895 pos
= IT_STRING_CHARPOS (*it
);
3896 pos_byte
= IT_STRING_BYTEPOS (*it
);
3897 string
= it
->string
;
3901 pos
= IT_CHARPOS (*it
);
3902 pos_byte
= IT_BYTEPOS (*it
);
3906 /* If there's a valid composition and point is not inside of the
3907 composition (in the case that the composition is from the current
3908 buffer), draw a glyph composed from the composition components. */
3909 if (find_composition (pos
, -1, &pos
, &end
, &prop
, string
)
3910 && COMPOSITION_VALID_P (pos
, end
, prop
)
3911 && (STRINGP (it
->string
) || (PT
<= pos
|| PT
>= end
)))
3913 int id
= get_composition_id (pos
, pos_byte
, end
- pos
, prop
, string
);
3917 it
->method
= next_element_from_composition
;
3919 it
->cmp_len
= COMPOSITION_LENGTH (prop
);
3920 /* For a terminal, draw only the first character of the
3922 it
->c
= COMPOSITION_GLYPH (composition_table
[id
], 0);
3923 it
->len
= (STRINGP (it
->string
)
3924 ? string_char_to_byte (it
->string
, end
)
3925 : CHAR_TO_BYTE (end
)) - pos_byte
;
3926 it
->stop_charpos
= end
;
3927 handled
= HANDLED_RETURN
;
3936 /***********************************************************************
3938 ***********************************************************************/
3940 /* The following structure is used to record overlay strings for
3941 later sorting in load_overlay_strings. */
3943 struct overlay_entry
3945 Lisp_Object overlay
;
3952 /* Set up iterator IT from overlay strings at its current position.
3953 Called from handle_stop. */
3955 static enum prop_handled
3956 handle_overlay_change (it
)
3959 if (!STRINGP (it
->string
) && get_overlay_strings (it
, 0))
3960 return HANDLED_RECOMPUTE_PROPS
;
3962 return HANDLED_NORMALLY
;
3966 /* Set up the next overlay string for delivery by IT, if there is an
3967 overlay string to deliver. Called by set_iterator_to_next when the
3968 end of the current overlay string is reached. If there are more
3969 overlay strings to display, IT->string and
3970 IT->current.overlay_string_index are set appropriately here.
3971 Otherwise IT->string is set to nil. */
3974 next_overlay_string (it
)
3977 ++it
->current
.overlay_string_index
;
3978 if (it
->current
.overlay_string_index
== it
->n_overlay_strings
)
3980 /* No more overlay strings. Restore IT's settings to what
3981 they were before overlay strings were processed, and
3982 continue to deliver from current_buffer. */
3983 int display_ellipsis_p
= it
->stack
[it
->sp
- 1].display_ellipsis_p
;
3986 xassert (it
->stop_charpos
>= BEGV
3987 && it
->stop_charpos
<= it
->end_charpos
);
3989 it
->current
.overlay_string_index
= -1;
3990 SET_TEXT_POS (it
->current
.string_pos
, -1, -1);
3991 it
->n_overlay_strings
= 0;
3992 it
->method
= next_element_from_buffer
;
3994 /* If we're at the end of the buffer, record that we have
3995 processed the overlay strings there already, so that
3996 next_element_from_buffer doesn't try it again. */
3997 if (IT_CHARPOS (*it
) >= it
->end_charpos
)
3998 it
->overlay_strings_at_end_processed_p
= 1;
4000 /* If we have to display `...' for invisible text, set
4001 the iterator up for that. */
4002 if (display_ellipsis_p
)
4003 setup_for_ellipsis (it
);
4007 /* There are more overlay strings to process. If
4008 IT->current.overlay_string_index has advanced to a position
4009 where we must load IT->overlay_strings with more strings, do
4011 int i
= it
->current
.overlay_string_index
% OVERLAY_STRING_CHUNK_SIZE
;
4013 if (it
->current
.overlay_string_index
&& i
== 0)
4014 load_overlay_strings (it
, 0);
4016 /* Initialize IT to deliver display elements from the overlay
4018 it
->string
= it
->overlay_strings
[i
];
4019 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
4020 SET_TEXT_POS (it
->current
.string_pos
, 0, 0);
4021 it
->method
= next_element_from_string
;
4022 it
->stop_charpos
= 0;
4029 /* Compare two overlay_entry structures E1 and E2. Used as a
4030 comparison function for qsort in load_overlay_strings. Overlay
4031 strings for the same position are sorted so that
4033 1. All after-strings come in front of before-strings, except
4034 when they come from the same overlay.
4036 2. Within after-strings, strings are sorted so that overlay strings
4037 from overlays with higher priorities come first.
4039 2. Within before-strings, strings are sorted so that overlay
4040 strings from overlays with higher priorities come last.
4042 Value is analogous to strcmp. */
4046 compare_overlay_entries (e1
, e2
)
4049 struct overlay_entry
*entry1
= (struct overlay_entry
*) e1
;
4050 struct overlay_entry
*entry2
= (struct overlay_entry
*) e2
;
4053 if (entry1
->after_string_p
!= entry2
->after_string_p
)
4055 /* Let after-strings appear in front of before-strings if
4056 they come from different overlays. */
4057 if (EQ (entry1
->overlay
, entry2
->overlay
))
4058 result
= entry1
->after_string_p
? 1 : -1;
4060 result
= entry1
->after_string_p
? -1 : 1;
4062 else if (entry1
->after_string_p
)
4063 /* After-strings sorted in order of decreasing priority. */
4064 result
= entry2
->priority
- entry1
->priority
;
4066 /* Before-strings sorted in order of increasing priority. */
4067 result
= entry1
->priority
- entry2
->priority
;
4073 /* Load the vector IT->overlay_strings with overlay strings from IT's
4074 current buffer position, or from CHARPOS if that is > 0. Set
4075 IT->n_overlays to the total number of overlay strings found.
4077 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4078 a time. On entry into load_overlay_strings,
4079 IT->current.overlay_string_index gives the number of overlay
4080 strings that have already been loaded by previous calls to this
4083 IT->add_overlay_start contains an additional overlay start
4084 position to consider for taking overlay strings from, if non-zero.
4085 This position comes into play when the overlay has an `invisible'
4086 property, and both before and after-strings. When we've skipped to
4087 the end of the overlay, because of its `invisible' property, we
4088 nevertheless want its before-string to appear.
4089 IT->add_overlay_start will contain the overlay start position
4092 Overlay strings are sorted so that after-string strings come in
4093 front of before-string strings. Within before and after-strings,
4094 strings are sorted by overlay priority. See also function
4095 compare_overlay_entries. */
4098 load_overlay_strings (it
, charpos
)
4102 extern Lisp_Object Qafter_string
, Qbefore_string
, Qwindow
, Qpriority
;
4103 Lisp_Object overlay
, window
, str
, invisible
;
4104 struct Lisp_Overlay
*ov
;
4107 int n
= 0, i
, j
, invis_p
;
4108 struct overlay_entry
*entries
4109 = (struct overlay_entry
*) alloca (size
* sizeof *entries
);
4112 charpos
= IT_CHARPOS (*it
);
4114 /* Append the overlay string STRING of overlay OVERLAY to vector
4115 `entries' which has size `size' and currently contains `n'
4116 elements. AFTER_P non-zero means STRING is an after-string of
4118 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4121 Lisp_Object priority; \
4125 int new_size = 2 * size; \
4126 struct overlay_entry *old = entries; \
4128 (struct overlay_entry *) alloca (new_size \
4129 * sizeof *entries); \
4130 bcopy (old, entries, size * sizeof *entries); \
4134 entries[n].string = (STRING); \
4135 entries[n].overlay = (OVERLAY); \
4136 priority = Foverlay_get ((OVERLAY), Qpriority); \
4137 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4138 entries[n].after_string_p = (AFTER_P); \
4143 /* Process overlay before the overlay center. */
4144 for (ov
= current_buffer
->overlays_before
; ov
; ov
= ov
->next
)
4146 XSETMISC (overlay
, ov
);
4147 xassert (OVERLAYP (overlay
));
4148 start
= OVERLAY_POSITION (OVERLAY_START (overlay
));
4149 end
= OVERLAY_POSITION (OVERLAY_END (overlay
));
4154 /* Skip this overlay if it doesn't start or end at IT's current
4156 if (end
!= charpos
&& start
!= charpos
)
4159 /* Skip this overlay if it doesn't apply to IT->w. */
4160 window
= Foverlay_get (overlay
, Qwindow
);
4161 if (WINDOWP (window
) && XWINDOW (window
) != it
->w
)
4164 /* If the text ``under'' the overlay is invisible, both before-
4165 and after-strings from this overlay are visible; start and
4166 end position are indistinguishable. */
4167 invisible
= Foverlay_get (overlay
, Qinvisible
);
4168 invis_p
= TEXT_PROP_MEANS_INVISIBLE (invisible
);
4170 /* If overlay has a non-empty before-string, record it. */
4171 if ((start
== charpos
|| (end
== charpos
&& invis_p
))
4172 && (str
= Foverlay_get (overlay
, Qbefore_string
), STRINGP (str
))
4174 RECORD_OVERLAY_STRING (overlay
, str
, 0);
4176 /* If overlay has a non-empty after-string, record it. */
4177 if ((end
== charpos
|| (start
== charpos
&& invis_p
))
4178 && (str
= Foverlay_get (overlay
, Qafter_string
), STRINGP (str
))
4180 RECORD_OVERLAY_STRING (overlay
, str
, 1);
4183 /* Process overlays after the overlay center. */
4184 for (ov
= current_buffer
->overlays_after
; ov
; ov
= ov
->next
)
4186 XSETMISC (overlay
, ov
);
4187 xassert (OVERLAYP (overlay
));
4188 start
= OVERLAY_POSITION (OVERLAY_START (overlay
));
4189 end
= OVERLAY_POSITION (OVERLAY_END (overlay
));
4191 if (start
> charpos
)
4194 /* Skip this overlay if it doesn't start or end at IT's current
4196 if (end
!= charpos
&& start
!= charpos
)
4199 /* Skip this overlay if it doesn't apply to IT->w. */
4200 window
= Foverlay_get (overlay
, Qwindow
);
4201 if (WINDOWP (window
) && XWINDOW (window
) != it
->w
)
4204 /* If the text ``under'' the overlay is invisible, it has a zero
4205 dimension, and both before- and after-strings apply. */
4206 invisible
= Foverlay_get (overlay
, Qinvisible
);
4207 invis_p
= TEXT_PROP_MEANS_INVISIBLE (invisible
);
4209 /* If overlay has a non-empty before-string, record it. */
4210 if ((start
== charpos
|| (end
== charpos
&& invis_p
))
4211 && (str
= Foverlay_get (overlay
, Qbefore_string
), STRINGP (str
))
4213 RECORD_OVERLAY_STRING (overlay
, str
, 0);
4215 /* If overlay has a non-empty after-string, record it. */
4216 if ((end
== charpos
|| (start
== charpos
&& invis_p
))
4217 && (str
= Foverlay_get (overlay
, Qafter_string
), STRINGP (str
))
4219 RECORD_OVERLAY_STRING (overlay
, str
, 1);
4222 #undef RECORD_OVERLAY_STRING
4226 qsort (entries
, n
, sizeof *entries
, compare_overlay_entries
);
4228 /* Record the total number of strings to process. */
4229 it
->n_overlay_strings
= n
;
4231 /* IT->current.overlay_string_index is the number of overlay strings
4232 that have already been consumed by IT. Copy some of the
4233 remaining overlay strings to IT->overlay_strings. */
4235 j
= it
->current
.overlay_string_index
;
4236 while (i
< OVERLAY_STRING_CHUNK_SIZE
&& j
< n
)
4237 it
->overlay_strings
[i
++] = entries
[j
++].string
;
4243 /* Get the first chunk of overlay strings at IT's current buffer
4244 position, or at CHARPOS if that is > 0. Value is non-zero if at
4245 least one overlay string was found. */
4248 get_overlay_strings (it
, charpos
)
4252 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4253 process. This fills IT->overlay_strings with strings, and sets
4254 IT->n_overlay_strings to the total number of strings to process.
4255 IT->pos.overlay_string_index has to be set temporarily to zero
4256 because load_overlay_strings needs this; it must be set to -1
4257 when no overlay strings are found because a zero value would
4258 indicate a position in the first overlay string. */
4259 it
->current
.overlay_string_index
= 0;
4260 load_overlay_strings (it
, charpos
);
4262 /* If we found overlay strings, set up IT to deliver display
4263 elements from the first one. Otherwise set up IT to deliver
4264 from current_buffer. */
4265 if (it
->n_overlay_strings
)
4267 /* Make sure we know settings in current_buffer, so that we can
4268 restore meaningful values when we're done with the overlay
4270 compute_stop_pos (it
);
4271 xassert (it
->face_id
>= 0);
4273 /* Save IT's settings. They are restored after all overlay
4274 strings have been processed. */
4275 xassert (it
->sp
== 0);
4278 /* Set up IT to deliver display elements from the first overlay
4280 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = 0;
4281 it
->string
= it
->overlay_strings
[0];
4282 it
->stop_charpos
= 0;
4283 xassert (STRINGP (it
->string
));
4284 it
->end_charpos
= SCHARS (it
->string
);
4285 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
4286 it
->method
= next_element_from_string
;
4291 it
->current
.overlay_string_index
= -1;
4292 it
->method
= next_element_from_buffer
;
4297 /* Value is non-zero if we found at least one overlay string. */
4298 return STRINGP (it
->string
);
4303 /***********************************************************************
4304 Saving and restoring state
4305 ***********************************************************************/
4307 /* Save current settings of IT on IT->stack. Called, for example,
4308 before setting up IT for an overlay string, to be able to restore
4309 IT's settings to what they were after the overlay string has been
4316 struct iterator_stack_entry
*p
;
4318 xassert (it
->sp
< 2);
4319 p
= it
->stack
+ it
->sp
;
4321 p
->stop_charpos
= it
->stop_charpos
;
4322 xassert (it
->face_id
>= 0);
4323 p
->face_id
= it
->face_id
;
4324 p
->string
= it
->string
;
4325 p
->pos
= it
->current
;
4326 p
->end_charpos
= it
->end_charpos
;
4327 p
->string_nchars
= it
->string_nchars
;
4329 p
->multibyte_p
= it
->multibyte_p
;
4330 p
->space_width
= it
->space_width
;
4331 p
->font_height
= it
->font_height
;
4332 p
->voffset
= it
->voffset
;
4333 p
->string_from_display_prop_p
= it
->string_from_display_prop_p
;
4334 p
->display_ellipsis_p
= 0;
4339 /* Restore IT's settings from IT->stack. Called, for example, when no
4340 more overlay strings must be processed, and we return to delivering
4341 display elements from a buffer, or when the end of a string from a
4342 `display' property is reached and we return to delivering display
4343 elements from an overlay string, or from a buffer. */
4349 struct iterator_stack_entry
*p
;
4351 xassert (it
->sp
> 0);
4353 p
= it
->stack
+ it
->sp
;
4354 it
->stop_charpos
= p
->stop_charpos
;
4355 it
->face_id
= p
->face_id
;
4356 it
->string
= p
->string
;
4357 it
->current
= p
->pos
;
4358 it
->end_charpos
= p
->end_charpos
;
4359 it
->string_nchars
= p
->string_nchars
;
4361 it
->multibyte_p
= p
->multibyte_p
;
4362 it
->space_width
= p
->space_width
;
4363 it
->font_height
= p
->font_height
;
4364 it
->voffset
= p
->voffset
;
4365 it
->string_from_display_prop_p
= p
->string_from_display_prop_p
;
4370 /***********************************************************************
4372 ***********************************************************************/
4374 /* Set IT's current position to the previous line start. */
4377 back_to_previous_line_start (it
)
4380 IT_CHARPOS (*it
) = find_next_newline_no_quit (IT_CHARPOS (*it
) - 1, -1);
4381 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (IT_CHARPOS (*it
));
4385 /* Move IT to the next line start.
4387 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
4388 we skipped over part of the text (as opposed to moving the iterator
4389 continuously over the text). Otherwise, don't change the value
4392 Newlines may come from buffer text, overlay strings, or strings
4393 displayed via the `display' property. That's the reason we can't
4394 simply use find_next_newline_no_quit.
4396 Note that this function may not skip over invisible text that is so
4397 because of text properties and immediately follows a newline. If
4398 it would, function reseat_at_next_visible_line_start, when called
4399 from set_iterator_to_next, would effectively make invisible
4400 characters following a newline part of the wrong glyph row, which
4401 leads to wrong cursor motion. */
4404 forward_to_next_line_start (it
, skipped_p
)
4408 int old_selective
, newline_found_p
, n
;
4409 const int MAX_NEWLINE_DISTANCE
= 500;
4411 /* If already on a newline, just consume it to avoid unintended
4412 skipping over invisible text below. */
4413 if (it
->what
== IT_CHARACTER
4415 && CHARPOS (it
->position
) == IT_CHARPOS (*it
))
4417 set_iterator_to_next (it
, 0);
4422 /* Don't handle selective display in the following. It's (a)
4423 unnecessary because it's done by the caller, and (b) leads to an
4424 infinite recursion because next_element_from_ellipsis indirectly
4425 calls this function. */
4426 old_selective
= it
->selective
;
4429 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
4430 from buffer text. */
4431 for (n
= newline_found_p
= 0;
4432 !newline_found_p
&& n
< MAX_NEWLINE_DISTANCE
;
4433 n
+= STRINGP (it
->string
) ? 0 : 1)
4435 if (!get_next_display_element (it
))
4437 newline_found_p
= it
->what
== IT_CHARACTER
&& it
->c
== '\n';
4438 set_iterator_to_next (it
, 0);
4441 /* If we didn't find a newline near enough, see if we can use a
4443 if (!newline_found_p
)
4445 int start
= IT_CHARPOS (*it
);
4446 int limit
= find_next_newline_no_quit (start
, 1);
4449 xassert (!STRINGP (it
->string
));
4451 /* If there isn't any `display' property in sight, and no
4452 overlays, we can just use the position of the newline in
4454 if (it
->stop_charpos
>= limit
4455 || ((pos
= Fnext_single_property_change (make_number (start
),
4457 Qnil
, make_number (limit
)),
4459 && next_overlay_change (start
) == ZV
))
4461 IT_CHARPOS (*it
) = limit
;
4462 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (limit
);
4463 *skipped_p
= newline_found_p
= 1;
4467 while (get_next_display_element (it
)
4468 && !newline_found_p
)
4470 newline_found_p
= ITERATOR_AT_END_OF_LINE_P (it
);
4471 set_iterator_to_next (it
, 0);
4476 it
->selective
= old_selective
;
4477 return newline_found_p
;
4481 /* Set IT's current position to the previous visible line start. Skip
4482 invisible text that is so either due to text properties or due to
4483 selective display. Caution: this does not change IT->current_x and
4487 back_to_previous_visible_line_start (it
)
4492 /* Go back one newline if not on BEGV already. */
4493 if (IT_CHARPOS (*it
) > BEGV
)
4494 back_to_previous_line_start (it
);
4496 /* Move over lines that are invisible because of selective display
4497 or text properties. */
4498 while (IT_CHARPOS (*it
) > BEGV
4503 /* If selective > 0, then lines indented more than that values
4505 if (it
->selective
> 0
4506 && indented_beyond_p (IT_CHARPOS (*it
), IT_BYTEPOS (*it
),
4507 (double) it
->selective
)) /* iftc */
4513 prop
= Fget_char_property (make_number (IT_CHARPOS (*it
)),
4514 Qinvisible
, it
->window
);
4515 if (TEXT_PROP_MEANS_INVISIBLE (prop
))
4519 /* Back one more newline if the current one is invisible. */
4521 back_to_previous_line_start (it
);
4524 xassert (IT_CHARPOS (*it
) >= BEGV
);
4525 xassert (IT_CHARPOS (*it
) == BEGV
4526 || FETCH_BYTE (IT_BYTEPOS (*it
) - 1) == '\n');
4531 /* Reseat iterator IT at the previous visible line start. Skip
4532 invisible text that is so either due to text properties or due to
4533 selective display. At the end, update IT's overlay information,
4534 face information etc. */
4537 reseat_at_previous_visible_line_start (it
)
4540 back_to_previous_visible_line_start (it
);
4541 reseat (it
, it
->current
.pos
, 1);
4546 /* Reseat iterator IT on the next visible line start in the current
4547 buffer. ON_NEWLINE_P non-zero means position IT on the newline
4548 preceding the line start. Skip over invisible text that is so
4549 because of selective display. Compute faces, overlays etc at the
4550 new position. Note that this function does not skip over text that
4551 is invisible because of text properties. */
4554 reseat_at_next_visible_line_start (it
, on_newline_p
)
4558 int newline_found_p
, skipped_p
= 0;
4560 newline_found_p
= forward_to_next_line_start (it
, &skipped_p
);
4562 /* Skip over lines that are invisible because they are indented
4563 more than the value of IT->selective. */
4564 if (it
->selective
> 0)
4565 while (IT_CHARPOS (*it
) < ZV
4566 && indented_beyond_p (IT_CHARPOS (*it
), IT_BYTEPOS (*it
),
4567 (double) it
->selective
)) /* iftc */
4569 xassert (FETCH_BYTE (IT_BYTEPOS (*it
) - 1) == '\n');
4570 newline_found_p
= forward_to_next_line_start (it
, &skipped_p
);
4573 /* Position on the newline if that's what's requested. */
4574 if (on_newline_p
&& newline_found_p
)
4576 if (STRINGP (it
->string
))
4578 if (IT_STRING_CHARPOS (*it
) > 0)
4580 --IT_STRING_CHARPOS (*it
);
4581 --IT_STRING_BYTEPOS (*it
);
4584 else if (IT_CHARPOS (*it
) > BEGV
)
4588 reseat (it
, it
->current
.pos
, 0);
4592 reseat (it
, it
->current
.pos
, 0);
4599 /***********************************************************************
4600 Changing an iterator's position
4601 ***********************************************************************/
4603 /* Change IT's current position to POS in current_buffer. If FORCE_P
4604 is non-zero, always check for text properties at the new position.
4605 Otherwise, text properties are only looked up if POS >=
4606 IT->check_charpos of a property. */
4609 reseat (it
, pos
, force_p
)
4611 struct text_pos pos
;
4614 int original_pos
= IT_CHARPOS (*it
);
4616 reseat_1 (it
, pos
, 0);
4618 /* Determine where to check text properties. Avoid doing it
4619 where possible because text property lookup is very expensive. */
4621 || CHARPOS (pos
) > it
->stop_charpos
4622 || CHARPOS (pos
) < original_pos
)
4629 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
4630 IT->stop_pos to POS, also. */
4633 reseat_1 (it
, pos
, set_stop_p
)
4635 struct text_pos pos
;
4638 /* Don't call this function when scanning a C string. */
4639 xassert (it
->s
== NULL
);
4641 /* POS must be a reasonable value. */
4642 xassert (CHARPOS (pos
) >= BEGV
&& CHARPOS (pos
) <= ZV
);
4644 it
->current
.pos
= it
->position
= pos
;
4645 XSETBUFFER (it
->object
, current_buffer
);
4646 it
->end_charpos
= ZV
;
4648 it
->current
.dpvec_index
= -1;
4649 it
->current
.overlay_string_index
= -1;
4650 IT_STRING_CHARPOS (*it
) = -1;
4651 IT_STRING_BYTEPOS (*it
) = -1;
4653 it
->method
= next_element_from_buffer
;
4654 /* RMS: I added this to fix a bug in move_it_vertically_backward
4655 where it->area continued to relate to the starting point
4656 for the backward motion. Bug report from
4657 Nick Roberts <nick@nick.uklinux.net> on 19 May 2003.
4658 However, I am not sure whether reseat still does the right thing
4659 in general after this change. */
4660 it
->area
= TEXT_AREA
;
4661 it
->multibyte_p
= !NILP (current_buffer
->enable_multibyte_characters
);
4663 it
->face_before_selective_p
= 0;
4666 it
->stop_charpos
= CHARPOS (pos
);
4670 /* Set up IT for displaying a string, starting at CHARPOS in window W.
4671 If S is non-null, it is a C string to iterate over. Otherwise,
4672 STRING gives a Lisp string to iterate over.
4674 If PRECISION > 0, don't return more then PRECISION number of
4675 characters from the string.
4677 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
4678 characters have been returned. FIELD_WIDTH < 0 means an infinite
4681 MULTIBYTE = 0 means disable processing of multibyte characters,
4682 MULTIBYTE > 0 means enable it,
4683 MULTIBYTE < 0 means use IT->multibyte_p.
4685 IT must be initialized via a prior call to init_iterator before
4686 calling this function. */
4689 reseat_to_string (it
, s
, string
, charpos
, precision
, field_width
, multibyte
)
4694 int precision
, field_width
, multibyte
;
4696 /* No region in strings. */
4697 it
->region_beg_charpos
= it
->region_end_charpos
= -1;
4699 /* No text property checks performed by default, but see below. */
4700 it
->stop_charpos
= -1;
4702 /* Set iterator position and end position. */
4703 bzero (&it
->current
, sizeof it
->current
);
4704 it
->current
.overlay_string_index
= -1;
4705 it
->current
.dpvec_index
= -1;
4706 xassert (charpos
>= 0);
4708 /* If STRING is specified, use its multibyteness, otherwise use the
4709 setting of MULTIBYTE, if specified. */
4711 it
->multibyte_p
= multibyte
> 0;
4715 xassert (STRINGP (string
));
4716 it
->string
= string
;
4718 it
->end_charpos
= it
->string_nchars
= SCHARS (string
);
4719 it
->method
= next_element_from_string
;
4720 it
->current
.string_pos
= string_pos (charpos
, string
);
4727 /* Note that we use IT->current.pos, not it->current.string_pos,
4728 for displaying C strings. */
4729 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = -1;
4730 if (it
->multibyte_p
)
4732 it
->current
.pos
= c_string_pos (charpos
, s
, 1);
4733 it
->end_charpos
= it
->string_nchars
= number_of_chars (s
, 1);
4737 IT_CHARPOS (*it
) = IT_BYTEPOS (*it
) = charpos
;
4738 it
->end_charpos
= it
->string_nchars
= strlen (s
);
4741 it
->method
= next_element_from_c_string
;
4744 /* PRECISION > 0 means don't return more than PRECISION characters
4746 if (precision
> 0 && it
->end_charpos
- charpos
> precision
)
4747 it
->end_charpos
= it
->string_nchars
= charpos
+ precision
;
4749 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
4750 characters have been returned. FIELD_WIDTH == 0 means don't pad,
4751 FIELD_WIDTH < 0 means infinite field width. This is useful for
4752 padding with `-' at the end of a mode line. */
4753 if (field_width
< 0)
4754 field_width
= INFINITY
;
4755 if (field_width
> it
->end_charpos
- charpos
)
4756 it
->end_charpos
= charpos
+ field_width
;
4758 /* Use the standard display table for displaying strings. */
4759 if (DISP_TABLE_P (Vstandard_display_table
))
4760 it
->dp
= XCHAR_TABLE (Vstandard_display_table
);
4762 it
->stop_charpos
= charpos
;
4768 /***********************************************************************
4770 ***********************************************************************/
4772 /* Load IT's display element fields with information about the next
4773 display element from the current position of IT. Value is zero if
4774 end of buffer (or C string) is reached. */
4777 get_next_display_element (it
)
4780 /* Non-zero means that we found a display element. Zero means that
4781 we hit the end of what we iterate over. Performance note: the
4782 function pointer `method' used here turns out to be faster than
4783 using a sequence of if-statements. */
4784 int success_p
= (*it
->method
) (it
);
4786 if (it
->what
== IT_CHARACTER
)
4788 /* Map via display table or translate control characters.
4789 IT->c, IT->len etc. have been set to the next character by
4790 the function call above. If we have a display table, and it
4791 contains an entry for IT->c, translate it. Don't do this if
4792 IT->c itself comes from a display table, otherwise we could
4793 end up in an infinite recursion. (An alternative could be to
4794 count the recursion depth of this function and signal an
4795 error when a certain maximum depth is reached.) Is it worth
4797 if (success_p
&& it
->dpvec
== NULL
)
4802 && (dv
= DISP_CHAR_VECTOR (it
->dp
, it
->c
),
4805 struct Lisp_Vector
*v
= XVECTOR (dv
);
4807 /* Return the first character from the display table
4808 entry, if not empty. If empty, don't display the
4809 current character. */
4812 it
->dpvec_char_len
= it
->len
;
4813 it
->dpvec
= v
->contents
;
4814 it
->dpend
= v
->contents
+ v
->size
;
4815 it
->current
.dpvec_index
= 0;
4816 it
->method
= next_element_from_display_vector
;
4817 success_p
= get_next_display_element (it
);
4821 set_iterator_to_next (it
, 0);
4822 success_p
= get_next_display_element (it
);
4826 /* Translate control characters into `\003' or `^C' form.
4827 Control characters coming from a display table entry are
4828 currently not translated because we use IT->dpvec to hold
4829 the translation. This could easily be changed but I
4830 don't believe that it is worth doing.
4832 If it->multibyte_p is nonzero, eight-bit characters and
4833 non-printable multibyte characters are also translated to
4836 If it->multibyte_p is zero, eight-bit characters that
4837 don't have corresponding multibyte char code are also
4838 translated to octal form. */
4839 else if ((it
->c
< ' '
4840 && (it
->area
!= TEXT_AREA
4841 || (it
->c
!= '\n' && it
->c
!= '\t')))
4845 || !CHAR_PRINTABLE_P (it
->c
))
4847 && it
->c
== unibyte_char_to_multibyte (it
->c
))))
4849 /* IT->c is a control character which must be displayed
4850 either as '\003' or as `^C' where the '\\' and '^'
4851 can be defined in the display table. Fill
4852 IT->ctl_chars with glyphs for what we have to
4853 display. Then, set IT->dpvec to these glyphs. */
4856 if (it
->c
< 128 && it
->ctl_arrow_p
)
4858 /* Set IT->ctl_chars[0] to the glyph for `^'. */
4860 && INTEGERP (DISP_CTRL_GLYPH (it
->dp
))
4861 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it
->dp
))))
4862 g
= XINT (DISP_CTRL_GLYPH (it
->dp
));
4864 g
= FAST_MAKE_GLYPH ('^', 0);
4865 XSETINT (it
->ctl_chars
[0], g
);
4867 g
= FAST_MAKE_GLYPH (it
->c
^ 0100, 0);
4868 XSETINT (it
->ctl_chars
[1], g
);
4870 /* Set up IT->dpvec and return first character from it. */
4871 it
->dpvec_char_len
= it
->len
;
4872 it
->dpvec
= it
->ctl_chars
;
4873 it
->dpend
= it
->dpvec
+ 2;
4874 it
->current
.dpvec_index
= 0;
4875 it
->method
= next_element_from_display_vector
;
4876 get_next_display_element (it
);
4880 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
4885 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
4887 && INTEGERP (DISP_ESCAPE_GLYPH (it
->dp
))
4888 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it
->dp
))))
4889 escape_glyph
= XFASTINT (DISP_ESCAPE_GLYPH (it
->dp
));
4891 escape_glyph
= FAST_MAKE_GLYPH ('\\', 0);
4893 if (SINGLE_BYTE_CHAR_P (it
->c
))
4894 str
[0] = it
->c
, len
= 1;
4897 len
= CHAR_STRING_NO_SIGNAL (it
->c
, str
);
4900 /* It's an invalid character, which
4901 shouldn't happen actually, but due to
4902 bugs it may happen. Let's print the char
4903 as is, there's not much meaningful we can
4906 str
[1] = it
->c
>> 8;
4907 str
[2] = it
->c
>> 16;
4908 str
[3] = it
->c
>> 24;
4913 for (i
= 0; i
< len
; i
++)
4915 XSETINT (it
->ctl_chars
[i
* 4], escape_glyph
);
4916 /* Insert three more glyphs into IT->ctl_chars for
4917 the octal display of the character. */
4918 g
= FAST_MAKE_GLYPH (((str
[i
] >> 6) & 7) + '0', 0);
4919 XSETINT (it
->ctl_chars
[i
* 4 + 1], g
);
4920 g
= FAST_MAKE_GLYPH (((str
[i
] >> 3) & 7) + '0', 0);
4921 XSETINT (it
->ctl_chars
[i
* 4 + 2], g
);
4922 g
= FAST_MAKE_GLYPH ((str
[i
] & 7) + '0', 0);
4923 XSETINT (it
->ctl_chars
[i
* 4 + 3], g
);
4926 /* Set up IT->dpvec and return the first character
4928 it
->dpvec_char_len
= it
->len
;
4929 it
->dpvec
= it
->ctl_chars
;
4930 it
->dpend
= it
->dpvec
+ len
* 4;
4931 it
->current
.dpvec_index
= 0;
4932 it
->method
= next_element_from_display_vector
;
4933 get_next_display_element (it
);
4938 /* Adjust face id for a multibyte character. There are no
4939 multibyte character in unibyte text. */
4942 && FRAME_WINDOW_P (it
->f
))
4944 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
4945 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->c
);
4949 /* Is this character the last one of a run of characters with
4950 box? If yes, set IT->end_of_box_run_p to 1. */
4957 it
->end_of_box_run_p
4958 = ((face_id
= face_after_it_pos (it
),
4959 face_id
!= it
->face_id
)
4960 && (face
= FACE_FROM_ID (it
->f
, face_id
),
4961 face
->box
== FACE_NO_BOX
));
4964 /* Value is 0 if end of buffer or string reached. */
4969 /* Move IT to the next display element.
4971 RESEAT_P non-zero means if called on a newline in buffer text,
4972 skip to the next visible line start.
4974 Functions get_next_display_element and set_iterator_to_next are
4975 separate because I find this arrangement easier to handle than a
4976 get_next_display_element function that also increments IT's
4977 position. The way it is we can first look at an iterator's current
4978 display element, decide whether it fits on a line, and if it does,
4979 increment the iterator position. The other way around we probably
4980 would either need a flag indicating whether the iterator has to be
4981 incremented the next time, or we would have to implement a
4982 decrement position function which would not be easy to write. */
4985 set_iterator_to_next (it
, reseat_p
)
4989 /* Reset flags indicating start and end of a sequence of characters
4990 with box. Reset them at the start of this function because
4991 moving the iterator to a new position might set them. */
4992 it
->start_of_box_run_p
= it
->end_of_box_run_p
= 0;
4994 if (it
->method
== next_element_from_buffer
)
4996 /* The current display element of IT is a character from
4997 current_buffer. Advance in the buffer, and maybe skip over
4998 invisible lines that are so because of selective display. */
4999 if (ITERATOR_AT_END_OF_LINE_P (it
) && reseat_p
)
5000 reseat_at_next_visible_line_start (it
, 0);
5003 xassert (it
->len
!= 0);
5004 IT_BYTEPOS (*it
) += it
->len
;
5005 IT_CHARPOS (*it
) += 1;
5006 xassert (IT_BYTEPOS (*it
) == CHAR_TO_BYTE (IT_CHARPOS (*it
)));
5009 else if (it
->method
== next_element_from_composition
)
5011 xassert (it
->cmp_id
>= 0 && it
->cmp_id
< n_compositions
);
5012 if (STRINGP (it
->string
))
5014 IT_STRING_BYTEPOS (*it
) += it
->len
;
5015 IT_STRING_CHARPOS (*it
) += it
->cmp_len
;
5016 it
->method
= next_element_from_string
;
5017 goto consider_string_end
;
5021 IT_BYTEPOS (*it
) += it
->len
;
5022 IT_CHARPOS (*it
) += it
->cmp_len
;
5023 it
->method
= next_element_from_buffer
;
5026 else if (it
->method
== next_element_from_c_string
)
5028 /* Current display element of IT is from a C string. */
5029 IT_BYTEPOS (*it
) += it
->len
;
5030 IT_CHARPOS (*it
) += 1;
5032 else if (it
->method
== next_element_from_display_vector
)
5034 /* Current display element of IT is from a display table entry.
5035 Advance in the display table definition. Reset it to null if
5036 end reached, and continue with characters from buffers/
5038 ++it
->current
.dpvec_index
;
5040 /* Restore face of the iterator to what they were before the
5041 display vector entry (these entries may contain faces). */
5042 it
->face_id
= it
->saved_face_id
;
5044 if (it
->dpvec
+ it
->current
.dpvec_index
== it
->dpend
)
5047 it
->method
= next_element_from_c_string
;
5048 else if (STRINGP (it
->string
))
5049 it
->method
= next_element_from_string
;
5051 it
->method
= next_element_from_buffer
;
5054 it
->current
.dpvec_index
= -1;
5056 /* Skip over characters which were displayed via IT->dpvec. */
5057 if (it
->dpvec_char_len
< 0)
5058 reseat_at_next_visible_line_start (it
, 1);
5059 else if (it
->dpvec_char_len
> 0)
5061 it
->len
= it
->dpvec_char_len
;
5062 set_iterator_to_next (it
, reseat_p
);
5066 else if (it
->method
== next_element_from_string
)
5068 /* Current display element is a character from a Lisp string. */
5069 xassert (it
->s
== NULL
&& STRINGP (it
->string
));
5070 IT_STRING_BYTEPOS (*it
) += it
->len
;
5071 IT_STRING_CHARPOS (*it
) += 1;
5073 consider_string_end
:
5075 if (it
->current
.overlay_string_index
>= 0)
5077 /* IT->string is an overlay string. Advance to the
5078 next, if there is one. */
5079 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
))
5080 next_overlay_string (it
);
5084 /* IT->string is not an overlay string. If we reached
5085 its end, and there is something on IT->stack, proceed
5086 with what is on the stack. This can be either another
5087 string, this time an overlay string, or a buffer. */
5088 if (IT_STRING_CHARPOS (*it
) == SCHARS (it
->string
)
5092 if (!STRINGP (it
->string
))
5093 it
->method
= next_element_from_buffer
;
5095 goto consider_string_end
;
5099 else if (it
->method
== next_element_from_image
5100 || it
->method
== next_element_from_stretch
)
5102 /* The position etc with which we have to proceed are on
5103 the stack. The position may be at the end of a string,
5104 if the `display' property takes up the whole string. */
5107 if (STRINGP (it
->string
))
5109 it
->method
= next_element_from_string
;
5110 goto consider_string_end
;
5113 it
->method
= next_element_from_buffer
;
5116 /* There are no other methods defined, so this should be a bug. */
5119 xassert (it
->method
!= next_element_from_string
5120 || (STRINGP (it
->string
)
5121 && IT_STRING_CHARPOS (*it
) >= 0));
5125 /* Load IT's display element fields with information about the next
5126 display element which comes from a display table entry or from the
5127 result of translating a control character to one of the forms `^C'
5128 or `\003'. IT->dpvec holds the glyphs to return as characters. */
5131 next_element_from_display_vector (it
)
5135 xassert (it
->dpvec
&& it
->current
.dpvec_index
>= 0);
5137 /* Remember the current face id in case glyphs specify faces.
5138 IT's face is restored in set_iterator_to_next. */
5139 it
->saved_face_id
= it
->face_id
;
5141 if (INTEGERP (*it
->dpvec
)
5142 && GLYPH_CHAR_VALID_P (XFASTINT (*it
->dpvec
)))
5147 g
= XFASTINT (it
->dpvec
[it
->current
.dpvec_index
]);
5148 it
->c
= FAST_GLYPH_CHAR (g
);
5149 it
->len
= CHAR_BYTES (it
->c
);
5151 /* The entry may contain a face id to use. Such a face id is
5152 the id of a Lisp face, not a realized face. A face id of
5153 zero means no face is specified. */
5154 lface_id
= FAST_GLYPH_FACE (g
);
5157 /* The function returns -1 if lface_id is invalid. */
5158 int face_id
= ascii_face_of_lisp_face (it
->f
, lface_id
);
5160 it
->face_id
= face_id
;
5164 /* Display table entry is invalid. Return a space. */
5165 it
->c
= ' ', it
->len
= 1;
5167 /* Don't change position and object of the iterator here. They are
5168 still the values of the character that had this display table
5169 entry or was translated, and that's what we want. */
5170 it
->what
= IT_CHARACTER
;
5175 /* Load IT with the next display element from Lisp string IT->string.
5176 IT->current.string_pos is the current position within the string.
5177 If IT->current.overlay_string_index >= 0, the Lisp string is an
5181 next_element_from_string (it
)
5184 struct text_pos position
;
5186 xassert (STRINGP (it
->string
));
5187 xassert (IT_STRING_CHARPOS (*it
) >= 0);
5188 position
= it
->current
.string_pos
;
5190 /* Time to check for invisible text? */
5191 if (IT_STRING_CHARPOS (*it
) < it
->end_charpos
5192 && IT_STRING_CHARPOS (*it
) == it
->stop_charpos
)
5196 /* Since a handler may have changed IT->method, we must
5198 return get_next_display_element (it
);
5201 if (it
->current
.overlay_string_index
>= 0)
5203 /* Get the next character from an overlay string. In overlay
5204 strings, There is no field width or padding with spaces to
5206 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
))
5211 else if (STRING_MULTIBYTE (it
->string
))
5213 int remaining
= SBYTES (it
->string
) - IT_STRING_BYTEPOS (*it
);
5214 const unsigned char *s
= (SDATA (it
->string
)
5215 + IT_STRING_BYTEPOS (*it
));
5216 it
->c
= string_char_and_length (s
, remaining
, &it
->len
);
5220 it
->c
= SREF (it
->string
, IT_STRING_BYTEPOS (*it
));
5226 /* Get the next character from a Lisp string that is not an
5227 overlay string. Such strings come from the mode line, for
5228 example. We may have to pad with spaces, or truncate the
5229 string. See also next_element_from_c_string. */
5230 if (IT_STRING_CHARPOS (*it
) >= it
->end_charpos
)
5235 else if (IT_STRING_CHARPOS (*it
) >= it
->string_nchars
)
5237 /* Pad with spaces. */
5238 it
->c
= ' ', it
->len
= 1;
5239 CHARPOS (position
) = BYTEPOS (position
) = -1;
5241 else if (STRING_MULTIBYTE (it
->string
))
5243 int maxlen
= SBYTES (it
->string
) - IT_STRING_BYTEPOS (*it
);
5244 const unsigned char *s
= (SDATA (it
->string
)
5245 + IT_STRING_BYTEPOS (*it
));
5246 it
->c
= string_char_and_length (s
, maxlen
, &it
->len
);
5250 it
->c
= SREF (it
->string
, IT_STRING_BYTEPOS (*it
));
5255 /* Record what we have and where it came from. Note that we store a
5256 buffer position in IT->position although it could arguably be a
5258 it
->what
= IT_CHARACTER
;
5259 it
->object
= it
->string
;
5260 it
->position
= position
;
5265 /* Load IT with next display element from C string IT->s.
5266 IT->string_nchars is the maximum number of characters to return
5267 from the string. IT->end_charpos may be greater than
5268 IT->string_nchars when this function is called, in which case we
5269 may have to return padding spaces. Value is zero if end of string
5270 reached, including padding spaces. */
5273 next_element_from_c_string (it
)
5279 it
->what
= IT_CHARACTER
;
5280 BYTEPOS (it
->position
) = CHARPOS (it
->position
) = 0;
5283 /* IT's position can be greater IT->string_nchars in case a field
5284 width or precision has been specified when the iterator was
5286 if (IT_CHARPOS (*it
) >= it
->end_charpos
)
5288 /* End of the game. */
5292 else if (IT_CHARPOS (*it
) >= it
->string_nchars
)
5294 /* Pad with spaces. */
5295 it
->c
= ' ', it
->len
= 1;
5296 BYTEPOS (it
->position
) = CHARPOS (it
->position
) = -1;
5298 else if (it
->multibyte_p
)
5300 /* Implementation note: The calls to strlen apparently aren't a
5301 performance problem because there is no noticeable performance
5302 difference between Emacs running in unibyte or multibyte mode. */
5303 int maxlen
= strlen (it
->s
) - IT_BYTEPOS (*it
);
5304 it
->c
= string_char_and_length (it
->s
+ IT_BYTEPOS (*it
),
5308 it
->c
= it
->s
[IT_BYTEPOS (*it
)], it
->len
= 1;
5314 /* Set up IT to return characters from an ellipsis, if appropriate.
5315 The definition of the ellipsis glyphs may come from a display table
5316 entry. This function Fills IT with the first glyph from the
5317 ellipsis if an ellipsis is to be displayed. */
5320 next_element_from_ellipsis (it
)
5323 if (it
->selective_display_ellipsis_p
)
5325 if (it
->dp
&& VECTORP (DISP_INVIS_VECTOR (it
->dp
)))
5327 /* Use the display table definition for `...'. Invalid glyphs
5328 will be handled by the method returning elements from dpvec. */
5329 struct Lisp_Vector
*v
= XVECTOR (DISP_INVIS_VECTOR (it
->dp
));
5330 it
->dpvec_char_len
= it
->len
;
5331 it
->dpvec
= v
->contents
;
5332 it
->dpend
= v
->contents
+ v
->size
;
5333 it
->current
.dpvec_index
= 0;
5334 it
->method
= next_element_from_display_vector
;
5338 /* Use default `...' which is stored in default_invis_vector. */
5339 it
->dpvec_char_len
= it
->len
;
5340 it
->dpvec
= default_invis_vector
;
5341 it
->dpend
= default_invis_vector
+ 3;
5342 it
->current
.dpvec_index
= 0;
5343 it
->method
= next_element_from_display_vector
;
5348 /* The face at the current position may be different from the
5349 face we find after the invisible text. Remember what it
5350 was in IT->saved_face_id, and signal that it's there by
5351 setting face_before_selective_p. */
5352 it
->saved_face_id
= it
->face_id
;
5353 it
->method
= next_element_from_buffer
;
5354 reseat_at_next_visible_line_start (it
, 1);
5355 it
->face_before_selective_p
= 1;
5358 return get_next_display_element (it
);
5362 /* Deliver an image display element. The iterator IT is already
5363 filled with image information (done in handle_display_prop). Value
5368 next_element_from_image (it
)
5371 it
->what
= IT_IMAGE
;
5376 /* Fill iterator IT with next display element from a stretch glyph
5377 property. IT->object is the value of the text property. Value is
5381 next_element_from_stretch (it
)
5384 it
->what
= IT_STRETCH
;
5389 /* Load IT with the next display element from current_buffer. Value
5390 is zero if end of buffer reached. IT->stop_charpos is the next
5391 position at which to stop and check for text properties or buffer
5395 next_element_from_buffer (it
)
5400 /* Check this assumption, otherwise, we would never enter the
5401 if-statement, below. */
5402 xassert (IT_CHARPOS (*it
) >= BEGV
5403 && IT_CHARPOS (*it
) <= it
->stop_charpos
);
5405 if (IT_CHARPOS (*it
) >= it
->stop_charpos
)
5407 if (IT_CHARPOS (*it
) >= it
->end_charpos
)
5409 int overlay_strings_follow_p
;
5411 /* End of the game, except when overlay strings follow that
5412 haven't been returned yet. */
5413 if (it
->overlay_strings_at_end_processed_p
)
5414 overlay_strings_follow_p
= 0;
5417 it
->overlay_strings_at_end_processed_p
= 1;
5418 overlay_strings_follow_p
= get_overlay_strings (it
, 0);
5421 if (overlay_strings_follow_p
)
5422 success_p
= get_next_display_element (it
);
5426 it
->position
= it
->current
.pos
;
5433 return get_next_display_element (it
);
5438 /* No face changes, overlays etc. in sight, so just return a
5439 character from current_buffer. */
5442 /* Maybe run the redisplay end trigger hook. Performance note:
5443 This doesn't seem to cost measurable time. */
5444 if (it
->redisplay_end_trigger_charpos
5446 && IT_CHARPOS (*it
) >= it
->redisplay_end_trigger_charpos
)
5447 run_redisplay_end_trigger_hook (it
);
5449 /* Get the next character, maybe multibyte. */
5450 p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
5451 if (it
->multibyte_p
&& !ASCII_BYTE_P (*p
))
5453 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT_BYTE
? ZV_BYTE
: GPT_BYTE
)
5454 - IT_BYTEPOS (*it
));
5455 it
->c
= string_char_and_length (p
, maxlen
, &it
->len
);
5458 it
->c
= *p
, it
->len
= 1;
5460 /* Record what we have and where it came from. */
5461 it
->what
= IT_CHARACTER
;;
5462 it
->object
= it
->w
->buffer
;
5463 it
->position
= it
->current
.pos
;
5465 /* Normally we return the character found above, except when we
5466 really want to return an ellipsis for selective display. */
5471 /* A value of selective > 0 means hide lines indented more
5472 than that number of columns. */
5473 if (it
->selective
> 0
5474 && IT_CHARPOS (*it
) + 1 < ZV
5475 && indented_beyond_p (IT_CHARPOS (*it
) + 1,
5476 IT_BYTEPOS (*it
) + 1,
5477 (double) it
->selective
)) /* iftc */
5479 success_p
= next_element_from_ellipsis (it
);
5480 it
->dpvec_char_len
= -1;
5483 else if (it
->c
== '\r' && it
->selective
== -1)
5485 /* A value of selective == -1 means that everything from the
5486 CR to the end of the line is invisible, with maybe an
5487 ellipsis displayed for it. */
5488 success_p
= next_element_from_ellipsis (it
);
5489 it
->dpvec_char_len
= -1;
5494 /* Value is zero if end of buffer reached. */
5495 xassert (!success_p
|| it
->what
!= IT_CHARACTER
|| it
->len
> 0);
5500 /* Run the redisplay end trigger hook for IT. */
5503 run_redisplay_end_trigger_hook (it
)
5506 Lisp_Object args
[3];
5508 /* IT->glyph_row should be non-null, i.e. we should be actually
5509 displaying something, or otherwise we should not run the hook. */
5510 xassert (it
->glyph_row
);
5512 /* Set up hook arguments. */
5513 args
[0] = Qredisplay_end_trigger_functions
;
5514 args
[1] = it
->window
;
5515 XSETINT (args
[2], it
->redisplay_end_trigger_charpos
);
5516 it
->redisplay_end_trigger_charpos
= 0;
5518 /* Since we are *trying* to run these functions, don't try to run
5519 them again, even if they get an error. */
5520 it
->w
->redisplay_end_trigger
= Qnil
;
5521 Frun_hook_with_args (3, args
);
5523 /* Notice if it changed the face of the character we are on. */
5524 handle_face_prop (it
);
5528 /* Deliver a composition display element. The iterator IT is already
5529 filled with composition information (done in
5530 handle_composition_prop). Value is always 1. */
5533 next_element_from_composition (it
)
5536 it
->what
= IT_COMPOSITION
;
5537 it
->position
= (STRINGP (it
->string
)
5538 ? it
->current
.string_pos
5545 /***********************************************************************
5546 Moving an iterator without producing glyphs
5547 ***********************************************************************/
5549 /* Move iterator IT to a specified buffer or X position within one
5550 line on the display without producing glyphs.
5552 OP should be a bit mask including some or all of these bits:
5553 MOVE_TO_X: Stop on reaching x-position TO_X.
5554 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
5555 Regardless of OP's value, stop in reaching the end of the display line.
5557 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
5558 This means, in particular, that TO_X includes window's horizontal
5561 The return value has several possible values that
5562 say what condition caused the scan to stop:
5564 MOVE_POS_MATCH_OR_ZV
5565 - when TO_POS or ZV was reached.
5568 -when TO_X was reached before TO_POS or ZV were reached.
5571 - when we reached the end of the display area and the line must
5575 - when we reached the end of the display area and the line is
5579 - when we stopped at a line end, i.e. a newline or a CR and selective
5582 static enum move_it_result
5583 move_it_in_display_line_to (it
, to_charpos
, to_x
, op
)
5585 int to_charpos
, to_x
, op
;
5587 enum move_it_result result
= MOVE_UNDEFINED
;
5588 struct glyph_row
*saved_glyph_row
;
5590 /* Don't produce glyphs in produce_glyphs. */
5591 saved_glyph_row
= it
->glyph_row
;
5592 it
->glyph_row
= NULL
;
5594 #define BUFFER_POS_REACHED_P() \
5595 ((op & MOVE_TO_POS) != 0 \
5596 && BUFFERP (it->object) \
5597 && IT_CHARPOS (*it) >= to_charpos)
5601 int x
, i
, ascent
= 0, descent
= 0;
5603 /* Stop when ZV or TO_CHARPOS reached. */
5604 if (!get_next_display_element (it
)
5605 || BUFFER_POS_REACHED_P ())
5607 result
= MOVE_POS_MATCH_OR_ZV
;
5611 /* The call to produce_glyphs will get the metrics of the
5612 display element IT is loaded with. We record in x the
5613 x-position before this display element in case it does not
5617 /* Remember the line height so far in case the next element doesn't
5619 if (!it
->truncate_lines_p
)
5621 ascent
= it
->max_ascent
;
5622 descent
= it
->max_descent
;
5625 PRODUCE_GLYPHS (it
);
5627 if (it
->area
!= TEXT_AREA
)
5629 set_iterator_to_next (it
, 1);
5633 /* The number of glyphs we get back in IT->nglyphs will normally
5634 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
5635 character on a terminal frame, or (iii) a line end. For the
5636 second case, IT->nglyphs - 1 padding glyphs will be present
5637 (on X frames, there is only one glyph produced for a
5638 composite character.
5640 The behavior implemented below means, for continuation lines,
5641 that as many spaces of a TAB as fit on the current line are
5642 displayed there. For terminal frames, as many glyphs of a
5643 multi-glyph character are displayed in the current line, too.
5644 This is what the old redisplay code did, and we keep it that
5645 way. Under X, the whole shape of a complex character must
5646 fit on the line or it will be completely displayed in the
5649 Note that both for tabs and padding glyphs, all glyphs have
5653 /* More than one glyph or glyph doesn't fit on line. All
5654 glyphs have the same width. */
5655 int single_glyph_width
= it
->pixel_width
/ it
->nglyphs
;
5658 for (i
= 0; i
< it
->nglyphs
; ++i
, x
= new_x
)
5660 new_x
= x
+ single_glyph_width
;
5662 /* We want to leave anything reaching TO_X to the caller. */
5663 if ((op
& MOVE_TO_X
) && new_x
> to_x
)
5666 result
= MOVE_X_REACHED
;
5669 else if (/* Lines are continued. */
5670 !it
->truncate_lines_p
5671 && (/* And glyph doesn't fit on the line. */
5672 new_x
> it
->last_visible_x
5673 /* Or it fits exactly and we're on a window
5675 || (new_x
== it
->last_visible_x
5676 && FRAME_WINDOW_P (it
->f
))))
5678 if (/* IT->hpos == 0 means the very first glyph
5679 doesn't fit on the line, e.g. a wide image. */
5681 || (new_x
== it
->last_visible_x
5682 && FRAME_WINDOW_P (it
->f
)))
5685 it
->current_x
= new_x
;
5686 if (i
== it
->nglyphs
- 1)
5688 set_iterator_to_next (it
, 1);
5689 #ifdef HAVE_WINDOW_SYSTEM
5690 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
5692 if (!get_next_display_element (it
)
5693 || BUFFER_POS_REACHED_P ())
5695 result
= MOVE_POS_MATCH_OR_ZV
;
5698 if (ITERATOR_AT_END_OF_LINE_P (it
))
5700 result
= MOVE_NEWLINE_OR_CR
;
5704 #endif /* HAVE_WINDOW_SYSTEM */
5710 it
->max_ascent
= ascent
;
5711 it
->max_descent
= descent
;
5714 TRACE_MOVE ((stderr
, "move_it_in: continued at %d\n",
5716 result
= MOVE_LINE_CONTINUED
;
5719 else if (new_x
> it
->first_visible_x
)
5721 /* Glyph is visible. Increment number of glyphs that
5722 would be displayed. */
5727 /* Glyph is completely off the left margin of the display
5728 area. Nothing to do. */
5732 if (result
!= MOVE_UNDEFINED
)
5735 else if ((op
& MOVE_TO_X
) && it
->current_x
>= to_x
)
5737 /* Stop when TO_X specified and reached. This check is
5738 necessary here because of lines consisting of a line end,
5739 only. The line end will not produce any glyphs and we
5740 would never get MOVE_X_REACHED. */
5741 xassert (it
->nglyphs
== 0);
5742 result
= MOVE_X_REACHED
;
5746 /* Is this a line end? If yes, we're done. */
5747 if (ITERATOR_AT_END_OF_LINE_P (it
))
5749 result
= MOVE_NEWLINE_OR_CR
;
5753 /* The current display element has been consumed. Advance
5755 set_iterator_to_next (it
, 1);
5757 /* Stop if lines are truncated and IT's current x-position is
5758 past the right edge of the window now. */
5759 if (it
->truncate_lines_p
5760 && it
->current_x
>= it
->last_visible_x
)
5762 #ifdef HAVE_WINDOW_SYSTEM
5763 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
5765 if (!get_next_display_element (it
)
5766 || BUFFER_POS_REACHED_P ())
5768 result
= MOVE_POS_MATCH_OR_ZV
;
5771 if (ITERATOR_AT_END_OF_LINE_P (it
))
5773 result
= MOVE_NEWLINE_OR_CR
;
5777 #endif /* HAVE_WINDOW_SYSTEM */
5778 result
= MOVE_LINE_TRUNCATED
;
5783 #undef BUFFER_POS_REACHED_P
5785 /* Restore the iterator settings altered at the beginning of this
5787 it
->glyph_row
= saved_glyph_row
;
5792 /* Move IT forward until it satisfies one or more of the criteria in
5793 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
5795 OP is a bit-mask that specifies where to stop, and in particular,
5796 which of those four position arguments makes a difference. See the
5797 description of enum move_operation_enum.
5799 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
5800 screen line, this function will set IT to the next position >
5804 move_it_to (it
, to_charpos
, to_x
, to_y
, to_vpos
, op
)
5806 int to_charpos
, to_x
, to_y
, to_vpos
;
5809 enum move_it_result skip
, skip2
= MOVE_X_REACHED
;
5815 if (op
& MOVE_TO_VPOS
)
5817 /* If no TO_CHARPOS and no TO_X specified, stop at the
5818 start of the line TO_VPOS. */
5819 if ((op
& (MOVE_TO_X
| MOVE_TO_POS
)) == 0)
5821 if (it
->vpos
== to_vpos
)
5827 skip
= move_it_in_display_line_to (it
, -1, -1, 0);
5831 /* TO_VPOS >= 0 means stop at TO_X in the line at
5832 TO_VPOS, or at TO_POS, whichever comes first. */
5833 if (it
->vpos
== to_vpos
)
5839 skip
= move_it_in_display_line_to (it
, to_charpos
, to_x
, op
);
5841 if (skip
== MOVE_POS_MATCH_OR_ZV
|| it
->vpos
== to_vpos
)
5846 else if (skip
== MOVE_X_REACHED
&& it
->vpos
!= to_vpos
)
5848 /* We have reached TO_X but not in the line we want. */
5849 skip
= move_it_in_display_line_to (it
, to_charpos
,
5851 if (skip
== MOVE_POS_MATCH_OR_ZV
)
5859 else if (op
& MOVE_TO_Y
)
5861 struct it it_backup
;
5863 /* TO_Y specified means stop at TO_X in the line containing
5864 TO_Y---or at TO_CHARPOS if this is reached first. The
5865 problem is that we can't really tell whether the line
5866 contains TO_Y before we have completely scanned it, and
5867 this may skip past TO_X. What we do is to first scan to
5870 If TO_X is not specified, use a TO_X of zero. The reason
5871 is to make the outcome of this function more predictable.
5872 If we didn't use TO_X == 0, we would stop at the end of
5873 the line which is probably not what a caller would expect
5875 skip
= move_it_in_display_line_to (it
, to_charpos
,
5879 | (op
& MOVE_TO_POS
)));
5881 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
5882 if (skip
== MOVE_POS_MATCH_OR_ZV
)
5888 /* If TO_X was reached, we would like to know whether TO_Y
5889 is in the line. This can only be said if we know the
5890 total line height which requires us to scan the rest of
5892 if (skip
== MOVE_X_REACHED
)
5895 TRACE_MOVE ((stderr
, "move_it: from %d\n", IT_CHARPOS (*it
)));
5896 skip2
= move_it_in_display_line_to (it
, to_charpos
, -1,
5898 TRACE_MOVE ((stderr
, "move_it: to %d\n", IT_CHARPOS (*it
)));
5901 /* Now, decide whether TO_Y is in this line. */
5902 line_height
= it
->max_ascent
+ it
->max_descent
;
5903 TRACE_MOVE ((stderr
, "move_it: line_height = %d\n", line_height
));
5905 if (to_y
>= it
->current_y
5906 && to_y
< it
->current_y
+ line_height
)
5908 if (skip
== MOVE_X_REACHED
)
5909 /* If TO_Y is in this line and TO_X was reached above,
5910 we scanned too far. We have to restore IT's settings
5911 to the ones before skipping. */
5915 else if (skip
== MOVE_X_REACHED
)
5918 if (skip
== MOVE_POS_MATCH_OR_ZV
)
5926 skip
= move_it_in_display_line_to (it
, to_charpos
, -1, MOVE_TO_POS
);
5930 case MOVE_POS_MATCH_OR_ZV
:
5934 case MOVE_NEWLINE_OR_CR
:
5935 set_iterator_to_next (it
, 1);
5936 it
->continuation_lines_width
= 0;
5939 case MOVE_LINE_TRUNCATED
:
5940 it
->continuation_lines_width
= 0;
5941 reseat_at_next_visible_line_start (it
, 0);
5942 if ((op
& MOVE_TO_POS
) != 0
5943 && IT_CHARPOS (*it
) > to_charpos
)
5950 case MOVE_LINE_CONTINUED
:
5951 it
->continuation_lines_width
+= it
->current_x
;
5958 /* Reset/increment for the next run. */
5959 recenter_overlay_lists (current_buffer
, IT_CHARPOS (*it
));
5960 it
->current_x
= it
->hpos
= 0;
5961 it
->current_y
+= it
->max_ascent
+ it
->max_descent
;
5963 last_height
= it
->max_ascent
+ it
->max_descent
;
5964 last_max_ascent
= it
->max_ascent
;
5965 it
->max_ascent
= it
->max_descent
= 0;
5970 TRACE_MOVE ((stderr
, "move_it_to: reached %d\n", reached
));
5974 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
5976 If DY > 0, move IT backward at least that many pixels. DY = 0
5977 means move IT backward to the preceding line start or BEGV. This
5978 function may move over more than DY pixels if IT->current_y - DY
5979 ends up in the middle of a line; in this case IT->current_y will be
5980 set to the top of the line moved to. */
5983 move_it_vertically_backward (it
, dy
)
5989 int start_pos
= IT_CHARPOS (*it
);
5993 /* Estimate how many newlines we must move back. */
5994 nlines
= max (1, dy
/ FRAME_LINE_HEIGHT (it
->f
));
5996 /* Set the iterator's position that many lines back. */
5997 while (nlines
-- && IT_CHARPOS (*it
) > BEGV
)
5998 back_to_previous_visible_line_start (it
);
6000 /* Reseat the iterator here. When moving backward, we don't want
6001 reseat to skip forward over invisible text, set up the iterator
6002 to deliver from overlay strings at the new position etc. So,
6003 use reseat_1 here. */
6004 reseat_1 (it
, it
->current
.pos
, 1);
6006 /* We are now surely at a line start. */
6007 it
->current_x
= it
->hpos
= 0;
6008 it
->continuation_lines_width
= 0;
6010 /* Move forward and see what y-distance we moved. First move to the
6011 start of the next line so that we get its height. We need this
6012 height to be able to tell whether we reached the specified
6015 it2
.max_ascent
= it2
.max_descent
= 0;
6016 move_it_to (&it2
, start_pos
, -1, -1, it2
.vpos
+ 1,
6017 MOVE_TO_POS
| MOVE_TO_VPOS
);
6018 xassert (IT_CHARPOS (*it
) >= BEGV
);
6021 move_it_to (&it2
, start_pos
, -1, -1, -1, MOVE_TO_POS
);
6022 xassert (IT_CHARPOS (*it
) >= BEGV
);
6023 /* H is the actual vertical distance from the position in *IT
6024 and the starting position. */
6025 h
= it2
.current_y
- it
->current_y
;
6026 /* NLINES is the distance in number of lines. */
6027 nlines
= it2
.vpos
- it
->vpos
;
6029 /* Correct IT's y and vpos position
6030 so that they are relative to the starting point. */
6036 /* DY == 0 means move to the start of the screen line. The
6037 value of nlines is > 0 if continuation lines were involved. */
6039 move_it_by_lines (it
, nlines
, 1);
6040 xassert (IT_CHARPOS (*it
) <= start_pos
);
6044 /* The y-position we try to reach, relative to *IT.
6045 Note that H has been subtracted in front of the if-statement. */
6046 int target_y
= it
->current_y
+ h
- dy
;
6047 int y0
= it3
.current_y
;
6048 int y1
= line_bottom_y (&it3
);
6049 int line_height
= y1
- y0
;
6051 /* If we did not reach target_y, try to move further backward if
6052 we can. If we moved too far backward, try to move forward. */
6053 if (target_y
< it
->current_y
6054 /* This is heuristic. In a window that's 3 lines high, with
6055 a line height of 13 pixels each, recentering with point
6056 on the bottom line will try to move -39/2 = 19 pixels
6057 backward. Try to avoid moving into the first line. */
6058 && it
->current_y
- target_y
> line_height
/ 3 * 2
6059 && IT_CHARPOS (*it
) > BEGV
)
6061 TRACE_MOVE ((stderr
, " not far enough -> move_vert %d\n",
6062 target_y
- it
->current_y
));
6063 move_it_vertically (it
, target_y
- it
->current_y
);
6064 xassert (IT_CHARPOS (*it
) >= BEGV
);
6066 else if (target_y
>= it
->current_y
+ line_height
6067 && IT_CHARPOS (*it
) < ZV
)
6069 /* Should move forward by at least one line, maybe more.
6071 Note: Calling move_it_by_lines can be expensive on
6072 terminal frames, where compute_motion is used (via
6073 vmotion) to do the job, when there are very long lines
6074 and truncate-lines is nil. That's the reason for
6075 treating terminal frames specially here. */
6077 if (!FRAME_WINDOW_P (it
->f
))
6078 move_it_vertically (it
, target_y
- (it
->current_y
+ line_height
));
6083 move_it_by_lines (it
, 1, 1);
6085 while (target_y
>= line_bottom_y (it
) && IT_CHARPOS (*it
) < ZV
);
6088 xassert (IT_CHARPOS (*it
) >= BEGV
);
6094 /* Move IT by a specified amount of pixel lines DY. DY negative means
6095 move backwards. DY = 0 means move to start of screen line. At the
6096 end, IT will be on the start of a screen line. */
6099 move_it_vertically (it
, dy
)
6104 move_it_vertically_backward (it
, -dy
);
6107 TRACE_MOVE ((stderr
, "move_it_v: from %d, %d\n", IT_CHARPOS (*it
), dy
));
6108 move_it_to (it
, ZV
, -1, it
->current_y
+ dy
, -1,
6109 MOVE_TO_POS
| MOVE_TO_Y
);
6110 TRACE_MOVE ((stderr
, "move_it_v: to %d\n", IT_CHARPOS (*it
)));
6112 /* If buffer ends in ZV without a newline, move to the start of
6113 the line to satisfy the post-condition. */
6114 if (IT_CHARPOS (*it
) == ZV
6115 && FETCH_BYTE (IT_BYTEPOS (*it
) - 1) != '\n')
6116 move_it_by_lines (it
, 0, 0);
6121 /* Move iterator IT past the end of the text line it is in. */
6124 move_it_past_eol (it
)
6127 enum move_it_result rc
;
6129 rc
= move_it_in_display_line_to (it
, Z
, 0, MOVE_TO_POS
);
6130 if (rc
== MOVE_NEWLINE_OR_CR
)
6131 set_iterator_to_next (it
, 0);
6135 #if 0 /* Currently not used. */
6137 /* Return non-zero if some text between buffer positions START_CHARPOS
6138 and END_CHARPOS is invisible. IT->window is the window for text
6142 invisible_text_between_p (it
, start_charpos
, end_charpos
)
6144 int start_charpos
, end_charpos
;
6146 Lisp_Object prop
, limit
;
6147 int invisible_found_p
;
6149 xassert (it
!= NULL
&& start_charpos
<= end_charpos
);
6151 /* Is text at START invisible? */
6152 prop
= Fget_char_property (make_number (start_charpos
), Qinvisible
,
6154 if (TEXT_PROP_MEANS_INVISIBLE (prop
))
6155 invisible_found_p
= 1;
6158 limit
= Fnext_single_char_property_change (make_number (start_charpos
),
6160 make_number (end_charpos
));
6161 invisible_found_p
= XFASTINT (limit
) < end_charpos
;
6164 return invisible_found_p
;
6170 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
6171 negative means move up. DVPOS == 0 means move to the start of the
6172 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
6173 NEED_Y_P is zero, IT->current_y will be left unchanged.
6175 Further optimization ideas: If we would know that IT->f doesn't use
6176 a face with proportional font, we could be faster for
6177 truncate-lines nil. */
6180 move_it_by_lines (it
, dvpos
, need_y_p
)
6182 int dvpos
, need_y_p
;
6184 struct position pos
;
6186 if (!FRAME_WINDOW_P (it
->f
))
6188 struct text_pos textpos
;
6190 /* We can use vmotion on frames without proportional fonts. */
6191 pos
= *vmotion (IT_CHARPOS (*it
), dvpos
, it
->w
);
6192 SET_TEXT_POS (textpos
, pos
.bufpos
, pos
.bytepos
);
6193 reseat (it
, textpos
, 1);
6194 it
->vpos
+= pos
.vpos
;
6195 it
->current_y
+= pos
.vpos
;
6197 else if (dvpos
== 0)
6199 /* DVPOS == 0 means move to the start of the screen line. */
6200 move_it_vertically_backward (it
, 0);
6201 xassert (it
->current_x
== 0 && it
->hpos
== 0);
6204 move_it_to (it
, -1, -1, -1, it
->vpos
+ dvpos
, MOVE_TO_VPOS
);
6208 int start_charpos
, i
;
6210 /* Start at the beginning of the screen line containing IT's
6212 move_it_vertically_backward (it
, 0);
6214 /* Go back -DVPOS visible lines and reseat the iterator there. */
6215 start_charpos
= IT_CHARPOS (*it
);
6216 for (i
= -dvpos
; i
&& IT_CHARPOS (*it
) > BEGV
; --i
)
6217 back_to_previous_visible_line_start (it
);
6218 reseat (it
, it
->current
.pos
, 1);
6219 it
->current_x
= it
->hpos
= 0;
6221 /* Above call may have moved too far if continuation lines
6222 are involved. Scan forward and see if it did. */
6224 it2
.vpos
= it2
.current_y
= 0;
6225 move_it_to (&it2
, start_charpos
, -1, -1, -1, MOVE_TO_POS
);
6226 it
->vpos
-= it2
.vpos
;
6227 it
->current_y
-= it2
.current_y
;
6228 it
->current_x
= it
->hpos
= 0;
6230 /* If we moved too far, move IT some lines forward. */
6231 if (it2
.vpos
> -dvpos
)
6233 int delta
= it2
.vpos
+ dvpos
;
6234 move_it_to (it
, -1, -1, -1, it
->vpos
+ delta
, MOVE_TO_VPOS
);
6239 /* Return 1 if IT points into the middle of a display vector. */
6242 in_display_vector_p (it
)
6245 return (it
->method
== next_element_from_display_vector
6246 && it
->current
.dpvec_index
> 0
6247 && it
->dpvec
+ it
->current
.dpvec_index
!= it
->dpend
);
6251 /***********************************************************************
6253 ***********************************************************************/
6256 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
6260 add_to_log (format
, arg1
, arg2
)
6262 Lisp_Object arg1
, arg2
;
6264 Lisp_Object args
[3];
6265 Lisp_Object msg
, fmt
;
6268 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
6270 /* Do nothing if called asynchronously. Inserting text into
6271 a buffer may call after-change-functions and alike and
6272 that would means running Lisp asynchronously. */
6273 if (handling_signal
)
6277 GCPRO4 (fmt
, msg
, arg1
, arg2
);
6279 args
[0] = fmt
= build_string (format
);
6282 msg
= Fformat (3, args
);
6284 len
= SBYTES (msg
) + 1;
6285 buffer
= (char *) alloca (len
);
6286 bcopy (SDATA (msg
), buffer
, len
);
6288 message_dolog (buffer
, len
- 1, 1, 0);
6293 /* Output a newline in the *Messages* buffer if "needs" one. */
6296 message_log_maybe_newline ()
6298 if (message_log_need_newline
)
6299 message_dolog ("", 0, 1, 0);
6303 /* Add a string M of length NBYTES to the message log, optionally
6304 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
6305 nonzero, means interpret the contents of M as multibyte. This
6306 function calls low-level routines in order to bypass text property
6307 hooks, etc. which might not be safe to run. */
6310 message_dolog (m
, nbytes
, nlflag
, multibyte
)
6312 int nbytes
, nlflag
, multibyte
;
6314 if (!NILP (Vmemory_full
))
6317 if (!NILP (Vmessage_log_max
))
6319 struct buffer
*oldbuf
;
6320 Lisp_Object oldpoint
, oldbegv
, oldzv
;
6321 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
6322 int point_at_end
= 0;
6324 Lisp_Object old_deactivate_mark
, tem
;
6325 struct gcpro gcpro1
;
6327 old_deactivate_mark
= Vdeactivate_mark
;
6328 oldbuf
= current_buffer
;
6329 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name
));
6330 current_buffer
->undo_list
= Qt
;
6332 oldpoint
= message_dolog_marker1
;
6333 set_marker_restricted (oldpoint
, make_number (PT
), Qnil
);
6334 oldbegv
= message_dolog_marker2
;
6335 set_marker_restricted (oldbegv
, make_number (BEGV
), Qnil
);
6336 oldzv
= message_dolog_marker3
;
6337 set_marker_restricted (oldzv
, make_number (ZV
), Qnil
);
6338 GCPRO1 (old_deactivate_mark
);
6346 BEGV_BYTE
= BEG_BYTE
;
6349 TEMP_SET_PT_BOTH (Z
, Z_BYTE
);
6351 /* Insert the string--maybe converting multibyte to single byte
6352 or vice versa, so that all the text fits the buffer. */
6354 && NILP (current_buffer
->enable_multibyte_characters
))
6356 int i
, c
, char_bytes
;
6357 unsigned char work
[1];
6359 /* Convert a multibyte string to single-byte
6360 for the *Message* buffer. */
6361 for (i
= 0; i
< nbytes
; i
+= char_bytes
)
6363 c
= string_char_and_length (m
+ i
, nbytes
- i
, &char_bytes
);
6364 work
[0] = (SINGLE_BYTE_CHAR_P (c
)
6366 : multibyte_char_to_unibyte (c
, Qnil
));
6367 insert_1_both (work
, 1, 1, 1, 0, 0);
6370 else if (! multibyte
6371 && ! NILP (current_buffer
->enable_multibyte_characters
))
6373 int i
, c
, char_bytes
;
6374 unsigned char *msg
= (unsigned char *) m
;
6375 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
6376 /* Convert a single-byte string to multibyte
6377 for the *Message* buffer. */
6378 for (i
= 0; i
< nbytes
; i
++)
6380 c
= unibyte_char_to_multibyte (msg
[i
]);
6381 char_bytes
= CHAR_STRING (c
, str
);
6382 insert_1_both (str
, 1, char_bytes
, 1, 0, 0);
6386 insert_1 (m
, nbytes
, 1, 0, 0);
6390 int this_bol
, this_bol_byte
, prev_bol
, prev_bol_byte
, dup
;
6391 insert_1 ("\n", 1, 1, 0, 0);
6393 scan_newline (Z
, Z_BYTE
, BEG
, BEG_BYTE
, -2, 0);
6395 this_bol_byte
= PT_BYTE
;
6397 /* See if this line duplicates the previous one.
6398 If so, combine duplicates. */
6401 scan_newline (PT
, PT_BYTE
, BEG
, BEG_BYTE
, -2, 0);
6403 prev_bol_byte
= PT_BYTE
;
6405 dup
= message_log_check_duplicate (prev_bol
, prev_bol_byte
,
6406 this_bol
, this_bol_byte
);
6409 del_range_both (prev_bol
, prev_bol_byte
,
6410 this_bol
, this_bol_byte
, 0);
6416 /* If you change this format, don't forget to also
6417 change message_log_check_duplicate. */
6418 sprintf (dupstr
, " [%d times]", dup
);
6419 duplen
= strlen (dupstr
);
6420 TEMP_SET_PT_BOTH (Z
- 1, Z_BYTE
- 1);
6421 insert_1 (dupstr
, duplen
, 1, 0, 1);
6426 /* If we have more than the desired maximum number of lines
6427 in the *Messages* buffer now, delete the oldest ones.
6428 This is safe because we don't have undo in this buffer. */
6430 if (NATNUMP (Vmessage_log_max
))
6432 scan_newline (Z
, Z_BYTE
, BEG
, BEG_BYTE
,
6433 -XFASTINT (Vmessage_log_max
) - 1, 0);
6434 del_range_both (BEG
, BEG_BYTE
, PT
, PT_BYTE
, 0);
6437 BEGV
= XMARKER (oldbegv
)->charpos
;
6438 BEGV_BYTE
= marker_byte_position (oldbegv
);
6447 ZV
= XMARKER (oldzv
)->charpos
;
6448 ZV_BYTE
= marker_byte_position (oldzv
);
6452 TEMP_SET_PT_BOTH (Z
, Z_BYTE
);
6454 /* We can't do Fgoto_char (oldpoint) because it will run some
6456 TEMP_SET_PT_BOTH (XMARKER (oldpoint
)->charpos
,
6457 XMARKER (oldpoint
)->bytepos
);
6460 unchain_marker (XMARKER (oldpoint
));
6461 unchain_marker (XMARKER (oldbegv
));
6462 unchain_marker (XMARKER (oldzv
));
6464 tem
= Fget_buffer_window (Fcurrent_buffer (), Qt
);
6465 set_buffer_internal (oldbuf
);
6467 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
6468 message_log_need_newline
= !nlflag
;
6469 Vdeactivate_mark
= old_deactivate_mark
;
6474 /* We are at the end of the buffer after just having inserted a newline.
6475 (Note: We depend on the fact we won't be crossing the gap.)
6476 Check to see if the most recent message looks a lot like the previous one.
6477 Return 0 if different, 1 if the new one should just replace it, or a
6478 value N > 1 if we should also append " [N times]". */
6481 message_log_check_duplicate (prev_bol
, prev_bol_byte
, this_bol
, this_bol_byte
)
6482 int prev_bol
, this_bol
;
6483 int prev_bol_byte
, this_bol_byte
;
6486 int len
= Z_BYTE
- 1 - this_bol_byte
;
6488 unsigned char *p1
= BUF_BYTE_ADDRESS (current_buffer
, prev_bol_byte
);
6489 unsigned char *p2
= BUF_BYTE_ADDRESS (current_buffer
, this_bol_byte
);
6491 for (i
= 0; i
< len
; i
++)
6493 if (i
>= 3 && p1
[i
-3] == '.' && p1
[i
-2] == '.' && p1
[i
-1] == '.')
6501 if (*p1
++ == ' ' && *p1
++ == '[')
6504 while (*p1
>= '0' && *p1
<= '9')
6505 n
= n
* 10 + *p1
++ - '0';
6506 if (strncmp (p1
, " times]\n", 8) == 0)
6513 /* Display an echo area message M with a specified length of NBYTES
6514 bytes. The string may include null characters. If M is 0, clear
6515 out any existing message, and let the mini-buffer text show
6518 The buffer M must continue to exist until after the echo area gets
6519 cleared or some other message gets displayed there. This means do
6520 not pass text that is stored in a Lisp string; do not pass text in
6521 a buffer that was alloca'd. */
6524 message2 (m
, nbytes
, multibyte
)
6529 /* First flush out any partial line written with print. */
6530 message_log_maybe_newline ();
6532 message_dolog (m
, nbytes
, 1, multibyte
);
6533 message2_nolog (m
, nbytes
, multibyte
);
6537 /* The non-logging counterpart of message2. */
6540 message2_nolog (m
, nbytes
, multibyte
)
6542 int nbytes
, multibyte
;
6544 struct frame
*sf
= SELECTED_FRAME ();
6545 message_enable_multibyte
= multibyte
;
6549 if (noninteractive_need_newline
)
6550 putc ('\n', stderr
);
6551 noninteractive_need_newline
= 0;
6553 fwrite (m
, nbytes
, 1, stderr
);
6554 if (cursor_in_echo_area
== 0)
6555 fprintf (stderr
, "\n");
6558 /* A null message buffer means that the frame hasn't really been
6559 initialized yet. Error messages get reported properly by
6560 cmd_error, so this must be just an informative message; toss it. */
6561 else if (INTERACTIVE
6562 && sf
->glyphs_initialized_p
6563 && FRAME_MESSAGE_BUF (sf
))
6565 Lisp_Object mini_window
;
6568 /* Get the frame containing the mini-buffer
6569 that the selected frame is using. */
6570 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
6571 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
6573 FRAME_SAMPLE_VISIBILITY (f
);
6574 if (FRAME_VISIBLE_P (sf
)
6575 && ! FRAME_VISIBLE_P (f
))
6576 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window
)));
6580 set_message (m
, Qnil
, nbytes
, multibyte
);
6581 if (minibuffer_auto_raise
)
6582 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window
)));
6585 clear_message (1, 1);
6587 do_pending_window_change (0);
6588 echo_area_display (1);
6589 do_pending_window_change (0);
6590 if (FRAME_DISPLAY (f
)->frame_up_to_date_hook
!= 0 && ! gc_in_progress
)
6591 (*FRAME_DISPLAY (f
)->frame_up_to_date_hook
) (f
);
6596 /* Display an echo area message M with a specified length of NBYTES
6597 bytes. The string may include null characters. If M is not a
6598 string, clear out any existing message, and let the mini-buffer
6599 text show through. */
6602 message3 (m
, nbytes
, multibyte
)
6607 struct gcpro gcpro1
;
6611 /* First flush out any partial line written with print. */
6612 message_log_maybe_newline ();
6614 message_dolog (SDATA (m
), nbytes
, 1, multibyte
);
6615 message3_nolog (m
, nbytes
, multibyte
);
6621 /* The non-logging version of message3. */
6624 message3_nolog (m
, nbytes
, multibyte
)
6626 int nbytes
, multibyte
;
6628 struct frame
*sf
= SELECTED_FRAME ();
6629 message_enable_multibyte
= multibyte
;
6633 if (noninteractive_need_newline
)
6634 putc ('\n', stderr
);
6635 noninteractive_need_newline
= 0;
6637 fwrite (SDATA (m
), nbytes
, 1, stderr
);
6638 if (cursor_in_echo_area
== 0)
6639 fprintf (stderr
, "\n");
6642 /* A null message buffer means that the frame hasn't really been
6643 initialized yet. Error messages get reported properly by
6644 cmd_error, so this must be just an informative message; toss it. */
6645 else if (INTERACTIVE
6646 && sf
->glyphs_initialized_p
6647 && FRAME_MESSAGE_BUF (sf
))
6649 Lisp_Object mini_window
;
6653 /* Get the frame containing the mini-buffer
6654 that the selected frame is using. */
6655 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
6656 frame
= XWINDOW (mini_window
)->frame
;
6659 FRAME_SAMPLE_VISIBILITY (f
);
6660 if (FRAME_VISIBLE_P (sf
)
6661 && !FRAME_VISIBLE_P (f
))
6662 Fmake_frame_visible (frame
);
6664 if (STRINGP (m
) && SCHARS (m
) > 0)
6666 set_message (NULL
, m
, nbytes
, multibyte
);
6667 if (minibuffer_auto_raise
)
6668 Fraise_frame (frame
);
6671 clear_message (1, 1);
6673 do_pending_window_change (0);
6674 echo_area_display (1);
6675 do_pending_window_change (0);
6676 if (FRAME_DISPLAY (f
)->frame_up_to_date_hook
!= 0 && ! gc_in_progress
)
6677 (*FRAME_DISPLAY (f
)->frame_up_to_date_hook
) (f
);
6682 /* Display a null-terminated echo area message M. If M is 0, clear
6683 out any existing message, and let the mini-buffer text show through.
6685 The buffer M must continue to exist until after the echo area gets
6686 cleared or some other message gets displayed there. Do not pass
6687 text that is stored in a Lisp string. Do not pass text in a buffer
6688 that was alloca'd. */
6694 message2 (m
, (m
? strlen (m
) : 0), 0);
6698 /* The non-logging counterpart of message1. */
6704 message2_nolog (m
, (m
? strlen (m
) : 0), 0);
6707 /* Display a message M which contains a single %s
6708 which gets replaced with STRING. */
6711 message_with_string (m
, string
, log
)
6716 CHECK_STRING (string
);
6722 if (noninteractive_need_newline
)
6723 putc ('\n', stderr
);
6724 noninteractive_need_newline
= 0;
6725 fprintf (stderr
, m
, SDATA (string
));
6726 if (cursor_in_echo_area
== 0)
6727 fprintf (stderr
, "\n");
6731 else if (INTERACTIVE
)
6733 /* The frame whose minibuffer we're going to display the message on.
6734 It may be larger than the selected frame, so we need
6735 to use its buffer, not the selected frame's buffer. */
6736 Lisp_Object mini_window
;
6737 struct frame
*f
, *sf
= SELECTED_FRAME ();
6739 /* Get the frame containing the minibuffer
6740 that the selected frame is using. */
6741 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
6742 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
6744 /* A null message buffer means that the frame hasn't really been
6745 initialized yet. Error messages get reported properly by
6746 cmd_error, so this must be just an informative message; toss it. */
6747 if (FRAME_MESSAGE_BUF (f
))
6749 Lisp_Object args
[2], message
;
6750 struct gcpro gcpro1
, gcpro2
;
6752 args
[0] = build_string (m
);
6753 args
[1] = message
= string
;
6754 GCPRO2 (args
[0], message
);
6757 message
= Fformat (2, args
);
6760 message3 (message
, SBYTES (message
), STRING_MULTIBYTE (message
));
6762 message3_nolog (message
, SBYTES (message
), STRING_MULTIBYTE (message
));
6766 /* Print should start at the beginning of the message
6767 buffer next time. */
6768 message_buf_print
= 0;
6774 /* Dump an informative message to the minibuf. If M is 0, clear out
6775 any existing message, and let the mini-buffer text show through. */
6779 message (m
, a1
, a2
, a3
)
6781 EMACS_INT a1
, a2
, a3
;
6787 if (noninteractive_need_newline
)
6788 putc ('\n', stderr
);
6789 noninteractive_need_newline
= 0;
6790 fprintf (stderr
, m
, a1
, a2
, a3
);
6791 if (cursor_in_echo_area
== 0)
6792 fprintf (stderr
, "\n");
6796 else if (INTERACTIVE
)
6798 /* The frame whose mini-buffer we're going to display the message
6799 on. It may be larger than the selected frame, so we need to
6800 use its buffer, not the selected frame's buffer. */
6801 Lisp_Object mini_window
;
6802 struct frame
*f
, *sf
= SELECTED_FRAME ();
6804 /* Get the frame containing the mini-buffer
6805 that the selected frame is using. */
6806 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
6807 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
6809 /* A null message buffer means that the frame hasn't really been
6810 initialized yet. Error messages get reported properly by
6811 cmd_error, so this must be just an informative message; toss
6813 if (FRAME_MESSAGE_BUF (f
))
6824 len
= doprnt (FRAME_MESSAGE_BUF (f
),
6825 FRAME_MESSAGE_BUF_SIZE (f
), m
, (char *)0, 3, a
);
6827 len
= doprnt (FRAME_MESSAGE_BUF (f
),
6828 FRAME_MESSAGE_BUF_SIZE (f
), m
, (char *)0, 3,
6830 #endif /* NO_ARG_ARRAY */
6832 message2 (FRAME_MESSAGE_BUF (f
), len
, 0);
6837 /* Print should start at the beginning of the message
6838 buffer next time. */
6839 message_buf_print
= 0;
6845 /* The non-logging version of message. */
6848 message_nolog (m
, a1
, a2
, a3
)
6850 EMACS_INT a1
, a2
, a3
;
6852 Lisp_Object old_log_max
;
6853 old_log_max
= Vmessage_log_max
;
6854 Vmessage_log_max
= Qnil
;
6855 message (m
, a1
, a2
, a3
);
6856 Vmessage_log_max
= old_log_max
;
6860 /* Display the current message in the current mini-buffer. This is
6861 only called from error handlers in process.c, and is not time
6867 if (!NILP (echo_area_buffer
[0]))
6870 string
= Fcurrent_message ();
6871 message3 (string
, SBYTES (string
),
6872 !NILP (current_buffer
->enable_multibyte_characters
));
6877 /* Make sure echo area buffers in `echo_buffers' are live.
6878 If they aren't, make new ones. */
6881 ensure_echo_area_buffers ()
6885 for (i
= 0; i
< 2; ++i
)
6886 if (!BUFFERP (echo_buffer
[i
])
6887 || NILP (XBUFFER (echo_buffer
[i
])->name
))
6890 Lisp_Object old_buffer
;
6893 old_buffer
= echo_buffer
[i
];
6894 sprintf (name
, " *Echo Area %d*", i
);
6895 echo_buffer
[i
] = Fget_buffer_create (build_string (name
));
6896 XBUFFER (echo_buffer
[i
])->truncate_lines
= Qnil
;
6898 for (j
= 0; j
< 2; ++j
)
6899 if (EQ (old_buffer
, echo_area_buffer
[j
]))
6900 echo_area_buffer
[j
] = echo_buffer
[i
];
6905 /* Call FN with args A1..A4 with either the current or last displayed
6906 echo_area_buffer as current buffer.
6908 WHICH zero means use the current message buffer
6909 echo_area_buffer[0]. If that is nil, choose a suitable buffer
6910 from echo_buffer[] and clear it.
6912 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
6913 suitable buffer from echo_buffer[] and clear it.
6915 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
6916 that the current message becomes the last displayed one, make
6917 choose a suitable buffer for echo_area_buffer[0], and clear it.
6919 Value is what FN returns. */
6922 with_echo_area_buffer (w
, which
, fn
, a1
, a2
, a3
, a4
)
6925 int (*fn
) P_ ((EMACS_INT
, Lisp_Object
, EMACS_INT
, EMACS_INT
));
6931 int this_one
, the_other
, clear_buffer_p
, rc
;
6932 int count
= SPECPDL_INDEX ();
6934 /* If buffers aren't live, make new ones. */
6935 ensure_echo_area_buffers ();
6940 this_one
= 0, the_other
= 1;
6942 this_one
= 1, the_other
= 0;
6945 this_one
= 0, the_other
= 1;
6948 /* We need a fresh one in case the current echo buffer equals
6949 the one containing the last displayed echo area message. */
6950 if (!NILP (echo_area_buffer
[this_one
])
6951 && EQ (echo_area_buffer
[this_one
], echo_area_buffer
[the_other
]))
6952 echo_area_buffer
[this_one
] = Qnil
;
6955 /* Choose a suitable buffer from echo_buffer[] is we don't
6957 if (NILP (echo_area_buffer
[this_one
]))
6959 echo_area_buffer
[this_one
]
6960 = (EQ (echo_area_buffer
[the_other
], echo_buffer
[this_one
])
6961 ? echo_buffer
[the_other
]
6962 : echo_buffer
[this_one
]);
6966 buffer
= echo_area_buffer
[this_one
];
6968 /* Don't get confused by reusing the buffer used for echoing
6969 for a different purpose. */
6970 if (echo_kboard
== NULL
&& EQ (buffer
, echo_message_buffer
))
6973 record_unwind_protect (unwind_with_echo_area_buffer
,
6974 with_echo_area_buffer_unwind_data (w
));
6976 /* Make the echo area buffer current. Note that for display
6977 purposes, it is not necessary that the displayed window's buffer
6978 == current_buffer, except for text property lookup. So, let's
6979 only set that buffer temporarily here without doing a full
6980 Fset_window_buffer. We must also change w->pointm, though,
6981 because otherwise an assertions in unshow_buffer fails, and Emacs
6983 set_buffer_internal_1 (XBUFFER (buffer
));
6987 set_marker_both (w
->pointm
, buffer
, BEG
, BEG_BYTE
);
6990 current_buffer
->undo_list
= Qt
;
6991 current_buffer
->read_only
= Qnil
;
6992 specbind (Qinhibit_read_only
, Qt
);
6993 specbind (Qinhibit_modification_hooks
, Qt
);
6995 if (clear_buffer_p
&& Z
> BEG
)
6998 xassert (BEGV
>= BEG
);
6999 xassert (ZV
<= Z
&& ZV
>= BEGV
);
7001 rc
= fn (a1
, a2
, a3
, a4
);
7003 xassert (BEGV
>= BEG
);
7004 xassert (ZV
<= Z
&& ZV
>= BEGV
);
7006 unbind_to (count
, Qnil
);
7011 /* Save state that should be preserved around the call to the function
7012 FN called in with_echo_area_buffer. */
7015 with_echo_area_buffer_unwind_data (w
)
7021 /* Reduce consing by keeping one vector in
7022 Vwith_echo_area_save_vector. */
7023 vector
= Vwith_echo_area_save_vector
;
7024 Vwith_echo_area_save_vector
= Qnil
;
7027 vector
= Fmake_vector (make_number (7), Qnil
);
7029 XSETBUFFER (AREF (vector
, i
), current_buffer
); ++i
;
7030 AREF (vector
, i
) = Vdeactivate_mark
, ++i
;
7031 AREF (vector
, i
) = make_number (windows_or_buffers_changed
), ++i
;
7035 XSETWINDOW (AREF (vector
, i
), w
); ++i
;
7036 AREF (vector
, i
) = w
->buffer
; ++i
;
7037 AREF (vector
, i
) = make_number (XMARKER (w
->pointm
)->charpos
); ++i
;
7038 AREF (vector
, i
) = make_number (XMARKER (w
->pointm
)->bytepos
); ++i
;
7043 for (; i
< end
; ++i
)
7044 AREF (vector
, i
) = Qnil
;
7047 xassert (i
== ASIZE (vector
));
7052 /* Restore global state from VECTOR which was created by
7053 with_echo_area_buffer_unwind_data. */
7056 unwind_with_echo_area_buffer (vector
)
7059 set_buffer_internal_1 (XBUFFER (AREF (vector
, 0)));
7060 Vdeactivate_mark
= AREF (vector
, 1);
7061 windows_or_buffers_changed
= XFASTINT (AREF (vector
, 2));
7063 if (WINDOWP (AREF (vector
, 3)))
7066 Lisp_Object buffer
, charpos
, bytepos
;
7068 w
= XWINDOW (AREF (vector
, 3));
7069 buffer
= AREF (vector
, 4);
7070 charpos
= AREF (vector
, 5);
7071 bytepos
= AREF (vector
, 6);
7074 set_marker_both (w
->pointm
, buffer
,
7075 XFASTINT (charpos
), XFASTINT (bytepos
));
7078 Vwith_echo_area_save_vector
= vector
;
7083 /* Set up the echo area for use by print functions. MULTIBYTE_P
7084 non-zero means we will print multibyte. */
7087 setup_echo_area_for_printing (multibyte_p
)
7090 /* If we can't find an echo area any more, exit. */
7091 if (! FRAME_LIVE_P (XFRAME (selected_frame
)))
7094 ensure_echo_area_buffers ();
7096 if (!message_buf_print
)
7098 /* A message has been output since the last time we printed.
7099 Choose a fresh echo area buffer. */
7100 if (EQ (echo_area_buffer
[1], echo_buffer
[0]))
7101 echo_area_buffer
[0] = echo_buffer
[1];
7103 echo_area_buffer
[0] = echo_buffer
[0];
7105 /* Switch to that buffer and clear it. */
7106 set_buffer_internal (XBUFFER (echo_area_buffer
[0]));
7107 current_buffer
->truncate_lines
= Qnil
;
7111 int count
= SPECPDL_INDEX ();
7112 specbind (Qinhibit_read_only
, Qt
);
7113 /* Note that undo recording is always disabled. */
7115 unbind_to (count
, Qnil
);
7117 TEMP_SET_PT_BOTH (BEG
, BEG_BYTE
);
7119 /* Set up the buffer for the multibyteness we need. */
7121 != !NILP (current_buffer
->enable_multibyte_characters
))
7122 Fset_buffer_multibyte (multibyte_p
? Qt
: Qnil
);
7124 /* Raise the frame containing the echo area. */
7125 if (minibuffer_auto_raise
)
7127 struct frame
*sf
= SELECTED_FRAME ();
7128 Lisp_Object mini_window
;
7129 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
7130 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window
)));
7133 message_log_maybe_newline ();
7134 message_buf_print
= 1;
7138 if (NILP (echo_area_buffer
[0]))
7140 if (EQ (echo_area_buffer
[1], echo_buffer
[0]))
7141 echo_area_buffer
[0] = echo_buffer
[1];
7143 echo_area_buffer
[0] = echo_buffer
[0];
7146 if (current_buffer
!= XBUFFER (echo_area_buffer
[0]))
7148 /* Someone switched buffers between print requests. */
7149 set_buffer_internal (XBUFFER (echo_area_buffer
[0]));
7150 current_buffer
->truncate_lines
= Qnil
;
7156 /* Display an echo area message in window W. Value is non-zero if W's
7157 height is changed. If display_last_displayed_message_p is
7158 non-zero, display the message that was last displayed, otherwise
7159 display the current message. */
7162 display_echo_area (w
)
7165 int i
, no_message_p
, window_height_changed_p
, count
;
7167 /* Temporarily disable garbage collections while displaying the echo
7168 area. This is done because a GC can print a message itself.
7169 That message would modify the echo area buffer's contents while a
7170 redisplay of the buffer is going on, and seriously confuse
7172 count
= inhibit_garbage_collection ();
7174 /* If there is no message, we must call display_echo_area_1
7175 nevertheless because it resizes the window. But we will have to
7176 reset the echo_area_buffer in question to nil at the end because
7177 with_echo_area_buffer will sets it to an empty buffer. */
7178 i
= display_last_displayed_message_p
? 1 : 0;
7179 no_message_p
= NILP (echo_area_buffer
[i
]);
7181 window_height_changed_p
7182 = with_echo_area_buffer (w
, display_last_displayed_message_p
,
7183 display_echo_area_1
,
7184 (EMACS_INT
) w
, Qnil
, 0, 0);
7187 echo_area_buffer
[i
] = Qnil
;
7189 unbind_to (count
, Qnil
);
7190 return window_height_changed_p
;
7194 /* Helper for display_echo_area. Display the current buffer which
7195 contains the current echo area message in window W, a mini-window,
7196 a pointer to which is passed in A1. A2..A4 are currently not used.
7197 Change the height of W so that all of the message is displayed.
7198 Value is non-zero if height of W was changed. */
7201 display_echo_area_1 (a1
, a2
, a3
, a4
)
7206 struct window
*w
= (struct window
*) a1
;
7208 struct text_pos start
;
7209 int window_height_changed_p
= 0;
7211 /* Do this before displaying, so that we have a large enough glyph
7212 matrix for the display. */
7213 window_height_changed_p
= resize_mini_window (w
, 0);
7216 clear_glyph_matrix (w
->desired_matrix
);
7217 XSETWINDOW (window
, w
);
7218 SET_TEXT_POS (start
, BEG
, BEG_BYTE
);
7219 try_window (window
, start
);
7221 return window_height_changed_p
;
7225 /* Resize the echo area window to exactly the size needed for the
7226 currently displayed message, if there is one. If a mini-buffer
7227 is active, don't shrink it. */
7230 resize_echo_area_exactly ()
7232 if (BUFFERP (echo_area_buffer
[0])
7233 && WINDOWP (echo_area_window
))
7235 struct window
*w
= XWINDOW (echo_area_window
);
7237 Lisp_Object resize_exactly
;
7239 if (minibuf_level
== 0)
7240 resize_exactly
= Qt
;
7242 resize_exactly
= Qnil
;
7244 resized_p
= with_echo_area_buffer (w
, 0, resize_mini_window_1
,
7245 (EMACS_INT
) w
, resize_exactly
, 0, 0);
7248 ++windows_or_buffers_changed
;
7249 ++update_mode_lines
;
7250 redisplay_internal (0);
7256 /* Callback function for with_echo_area_buffer, when used from
7257 resize_echo_area_exactly. A1 contains a pointer to the window to
7258 resize, EXACTLY non-nil means resize the mini-window exactly to the
7259 size of the text displayed. A3 and A4 are not used. Value is what
7260 resize_mini_window returns. */
7263 resize_mini_window_1 (a1
, exactly
, a3
, a4
)
7265 Lisp_Object exactly
;
7268 return resize_mini_window ((struct window
*) a1
, !NILP (exactly
));
7272 /* Resize mini-window W to fit the size of its contents. EXACT:P
7273 means size the window exactly to the size needed. Otherwise, it's
7274 only enlarged until W's buffer is empty. Value is non-zero if
7275 the window height has been changed. */
7278 resize_mini_window (w
, exact_p
)
7282 struct frame
*f
= XFRAME (w
->frame
);
7283 int window_height_changed_p
= 0;
7285 xassert (MINI_WINDOW_P (w
));
7287 /* Don't resize windows while redisplaying a window; it would
7288 confuse redisplay functions when the size of the window they are
7289 displaying changes from under them. Such a resizing can happen,
7290 for instance, when which-func prints a long message while
7291 we are running fontification-functions. We're running these
7292 functions with safe_call which binds inhibit-redisplay to t. */
7293 if (!NILP (Vinhibit_redisplay
))
7296 /* Nil means don't try to resize. */
7297 if (NILP (Vresize_mini_windows
)
7298 || (FRAME_X_P (f
) && FRAME_X_OUTPUT (f
) == NULL
))
7301 if (!FRAME_MINIBUF_ONLY_P (f
))
7304 struct window
*root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
7305 int total_height
= WINDOW_TOTAL_LINES (root
) + WINDOW_TOTAL_LINES (w
);
7306 int height
, max_height
;
7307 int unit
= FRAME_LINE_HEIGHT (f
);
7308 struct text_pos start
;
7309 struct buffer
*old_current_buffer
= NULL
;
7311 if (current_buffer
!= XBUFFER (w
->buffer
))
7313 old_current_buffer
= current_buffer
;
7314 set_buffer_internal (XBUFFER (w
->buffer
));
7317 init_iterator (&it
, w
, BEGV
, BEGV_BYTE
, NULL
, DEFAULT_FACE_ID
);
7319 /* Compute the max. number of lines specified by the user. */
7320 if (FLOATP (Vmax_mini_window_height
))
7321 max_height
= XFLOATINT (Vmax_mini_window_height
) * FRAME_LINES (f
);
7322 else if (INTEGERP (Vmax_mini_window_height
))
7323 max_height
= XINT (Vmax_mini_window_height
);
7325 max_height
= total_height
/ 4;
7327 /* Correct that max. height if it's bogus. */
7328 max_height
= max (1, max_height
);
7329 max_height
= min (total_height
, max_height
);
7331 /* Find out the height of the text in the window. */
7332 if (it
.truncate_lines_p
)
7337 move_it_to (&it
, ZV
, -1, -1, -1, MOVE_TO_POS
);
7338 if (it
.max_ascent
== 0 && it
.max_descent
== 0)
7339 height
= it
.current_y
+ last_height
;
7341 height
= it
.current_y
+ it
.max_ascent
+ it
.max_descent
;
7342 height
-= it
.extra_line_spacing
;
7343 height
= (height
+ unit
- 1) / unit
;
7346 /* Compute a suitable window start. */
7347 if (height
> max_height
)
7349 height
= max_height
;
7350 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
7351 move_it_vertically_backward (&it
, (height
- 1) * unit
);
7352 start
= it
.current
.pos
;
7355 SET_TEXT_POS (start
, BEGV
, BEGV_BYTE
);
7356 SET_MARKER_FROM_TEXT_POS (w
->start
, start
);
7358 if (EQ (Vresize_mini_windows
, Qgrow_only
))
7360 /* Let it grow only, until we display an empty message, in which
7361 case the window shrinks again. */
7362 if (height
> WINDOW_TOTAL_LINES (w
))
7364 int old_height
= WINDOW_TOTAL_LINES (w
);
7365 freeze_window_starts (f
, 1);
7366 grow_mini_window (w
, height
- WINDOW_TOTAL_LINES (w
));
7367 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
7369 else if (height
< WINDOW_TOTAL_LINES (w
)
7370 && (exact_p
|| BEGV
== ZV
))
7372 int old_height
= WINDOW_TOTAL_LINES (w
);
7373 freeze_window_starts (f
, 0);
7374 shrink_mini_window (w
);
7375 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
7380 /* Always resize to exact size needed. */
7381 if (height
> WINDOW_TOTAL_LINES (w
))
7383 int old_height
= WINDOW_TOTAL_LINES (w
);
7384 freeze_window_starts (f
, 1);
7385 grow_mini_window (w
, height
- WINDOW_TOTAL_LINES (w
));
7386 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
7388 else if (height
< WINDOW_TOTAL_LINES (w
))
7390 int old_height
= WINDOW_TOTAL_LINES (w
);
7391 freeze_window_starts (f
, 0);
7392 shrink_mini_window (w
);
7396 freeze_window_starts (f
, 1);
7397 grow_mini_window (w
, height
- WINDOW_TOTAL_LINES (w
));
7400 window_height_changed_p
= WINDOW_TOTAL_LINES (w
) != old_height
;
7404 if (old_current_buffer
)
7405 set_buffer_internal (old_current_buffer
);
7408 return window_height_changed_p
;
7412 /* Value is the current message, a string, or nil if there is no
7420 if (NILP (echo_area_buffer
[0]))
7424 with_echo_area_buffer (0, 0, current_message_1
,
7425 (EMACS_INT
) &msg
, Qnil
, 0, 0);
7427 echo_area_buffer
[0] = Qnil
;
7435 current_message_1 (a1
, a2
, a3
, a4
)
7440 Lisp_Object
*msg
= (Lisp_Object
*) a1
;
7443 *msg
= make_buffer_string (BEG
, Z
, 1);
7450 /* Push the current message on Vmessage_stack for later restauration
7451 by restore_message. Value is non-zero if the current message isn't
7452 empty. This is a relatively infrequent operation, so it's not
7453 worth optimizing. */
7459 msg
= current_message ();
7460 Vmessage_stack
= Fcons (msg
, Vmessage_stack
);
7461 return STRINGP (msg
);
7465 /* Restore message display from the top of Vmessage_stack. */
7472 xassert (CONSP (Vmessage_stack
));
7473 msg
= XCAR (Vmessage_stack
);
7475 message3_nolog (msg
, SBYTES (msg
), STRING_MULTIBYTE (msg
));
7477 message3_nolog (msg
, 0, 0);
7481 /* Handler for record_unwind_protect calling pop_message. */
7484 pop_message_unwind (dummy
)
7491 /* Pop the top-most entry off Vmessage_stack. */
7496 xassert (CONSP (Vmessage_stack
));
7497 Vmessage_stack
= XCDR (Vmessage_stack
);
7501 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
7502 exits. If the stack is not empty, we have a missing pop_message
7506 check_message_stack ()
7508 if (!NILP (Vmessage_stack
))
7513 /* Truncate to NCHARS what will be displayed in the echo area the next
7514 time we display it---but don't redisplay it now. */
7517 truncate_echo_area (nchars
)
7521 echo_area_buffer
[0] = Qnil
;
7522 /* A null message buffer means that the frame hasn't really been
7523 initialized yet. Error messages get reported properly by
7524 cmd_error, so this must be just an informative message; toss it. */
7525 else if (!noninteractive
7527 && !NILP (echo_area_buffer
[0]))
7529 struct frame
*sf
= SELECTED_FRAME ();
7530 if (FRAME_MESSAGE_BUF (sf
))
7531 with_echo_area_buffer (0, 0, truncate_message_1
, nchars
, Qnil
, 0, 0);
7536 /* Helper function for truncate_echo_area. Truncate the current
7537 message to at most NCHARS characters. */
7540 truncate_message_1 (nchars
, a2
, a3
, a4
)
7545 if (BEG
+ nchars
< Z
)
7546 del_range (BEG
+ nchars
, Z
);
7548 echo_area_buffer
[0] = Qnil
;
7553 /* Set the current message to a substring of S or STRING.
7555 If STRING is a Lisp string, set the message to the first NBYTES
7556 bytes from STRING. NBYTES zero means use the whole string. If
7557 STRING is multibyte, the message will be displayed multibyte.
7559 If S is not null, set the message to the first LEN bytes of S. LEN
7560 zero means use the whole string. MULTIBYTE_P non-zero means S is
7561 multibyte. Display the message multibyte in that case. */
7564 set_message (s
, string
, nbytes
, multibyte_p
)
7567 int nbytes
, multibyte_p
;
7569 message_enable_multibyte
7570 = ((s
&& multibyte_p
)
7571 || (STRINGP (string
) && STRING_MULTIBYTE (string
)));
7573 with_echo_area_buffer (0, -1, set_message_1
,
7574 (EMACS_INT
) s
, string
, nbytes
, multibyte_p
);
7575 message_buf_print
= 0;
7576 help_echo_showing_p
= 0;
7580 /* Helper function for set_message. Arguments have the same meaning
7581 as there, with A1 corresponding to S and A2 corresponding to STRING
7582 This function is called with the echo area buffer being
7586 set_message_1 (a1
, a2
, nbytes
, multibyte_p
)
7589 EMACS_INT nbytes
, multibyte_p
;
7591 const char *s
= (const char *) a1
;
7592 Lisp_Object string
= a2
;
7596 /* Change multibyteness of the echo buffer appropriately. */
7597 if (message_enable_multibyte
7598 != !NILP (current_buffer
->enable_multibyte_characters
))
7599 Fset_buffer_multibyte (message_enable_multibyte
? Qt
: Qnil
);
7601 current_buffer
->truncate_lines
= message_truncate_lines
? Qt
: Qnil
;
7603 /* Insert new message at BEG. */
7604 TEMP_SET_PT_BOTH (BEG
, BEG_BYTE
);
7606 if (STRINGP (string
))
7611 nbytes
= SBYTES (string
);
7612 nchars
= string_byte_to_char (string
, nbytes
);
7614 /* This function takes care of single/multibyte conversion. We
7615 just have to ensure that the echo area buffer has the right
7616 setting of enable_multibyte_characters. */
7617 insert_from_string (string
, 0, 0, nchars
, nbytes
, 1);
7622 nbytes
= strlen (s
);
7624 if (multibyte_p
&& NILP (current_buffer
->enable_multibyte_characters
))
7626 /* Convert from multi-byte to single-byte. */
7628 unsigned char work
[1];
7630 /* Convert a multibyte string to single-byte. */
7631 for (i
= 0; i
< nbytes
; i
+= n
)
7633 c
= string_char_and_length (s
+ i
, nbytes
- i
, &n
);
7634 work
[0] = (SINGLE_BYTE_CHAR_P (c
)
7636 : multibyte_char_to_unibyte (c
, Qnil
));
7637 insert_1_both (work
, 1, 1, 1, 0, 0);
7640 else if (!multibyte_p
7641 && !NILP (current_buffer
->enable_multibyte_characters
))
7643 /* Convert from single-byte to multi-byte. */
7645 const unsigned char *msg
= (const unsigned char *) s
;
7646 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
7648 /* Convert a single-byte string to multibyte. */
7649 for (i
= 0; i
< nbytes
; i
++)
7651 c
= unibyte_char_to_multibyte (msg
[i
]);
7652 n
= CHAR_STRING (c
, str
);
7653 insert_1_both (str
, 1, n
, 1, 0, 0);
7657 insert_1 (s
, nbytes
, 1, 0, 0);
7664 /* Clear messages. CURRENT_P non-zero means clear the current
7665 message. LAST_DISPLAYED_P non-zero means clear the message
7669 clear_message (current_p
, last_displayed_p
)
7670 int current_p
, last_displayed_p
;
7674 echo_area_buffer
[0] = Qnil
;
7675 message_cleared_p
= 1;
7678 if (last_displayed_p
)
7679 echo_area_buffer
[1] = Qnil
;
7681 message_buf_print
= 0;
7684 /* Clear garbaged frames.
7686 This function is used where the old redisplay called
7687 redraw_garbaged_frames which in turn called redraw_frame which in
7688 turn called clear_frame. The call to clear_frame was a source of
7689 flickering. I believe a clear_frame is not necessary. It should
7690 suffice in the new redisplay to invalidate all current matrices,
7691 and ensure a complete redisplay of all windows. */
7694 clear_garbaged_frames ()
7698 Lisp_Object tail
, frame
;
7699 int changed_count
= 0;
7701 FOR_EACH_FRAME (tail
, frame
)
7703 struct frame
*f
= XFRAME (frame
);
7705 if (FRAME_VISIBLE_P (f
) && FRAME_GARBAGED_P (f
))
7709 Fredraw_frame (frame
);
7710 f
->force_flush_display_p
= 1;
7712 clear_current_matrices (f
);
7721 ++windows_or_buffers_changed
;
7726 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
7727 is non-zero update selected_frame. Value is non-zero if the
7728 mini-windows height has been changed. */
7731 echo_area_display (update_frame_p
)
7734 Lisp_Object mini_window
;
7737 int window_height_changed_p
= 0;
7738 struct frame
*sf
= SELECTED_FRAME ();
7740 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
7741 w
= XWINDOW (mini_window
);
7742 f
= XFRAME (WINDOW_FRAME (w
));
7744 /* Don't display if frame is invisible or not yet initialized. */
7745 if (!FRAME_VISIBLE_P (f
) || !f
->glyphs_initialized_p
)
7748 /* The terminal frame is used as the first Emacs frame on the Mac OS. */
7750 #ifdef HAVE_WINDOW_SYSTEM
7751 /* When Emacs starts, selected_frame may be the initial terminal
7752 frame. If we let this through, a message would be displayed on
7754 if (FRAME_TERMCAP_P (XFRAME (selected_frame
))
7755 && FRAME_TTY (XFRAME (selected_frame
))->type
== NULL
)
7757 #endif /* HAVE_WINDOW_SYSTEM */
7760 /* Redraw garbaged frames. */
7762 clear_garbaged_frames ();
7764 if (!NILP (echo_area_buffer
[0]) || minibuf_level
== 0)
7766 echo_area_window
= mini_window
;
7767 window_height_changed_p
= display_echo_area (w
);
7768 w
->must_be_updated_p
= 1;
7770 /* Update the display, unless called from redisplay_internal.
7771 Also don't update the screen during redisplay itself. The
7772 update will happen at the end of redisplay, and an update
7773 here could cause confusion. */
7774 if (update_frame_p
&& !redisplaying_p
)
7778 /* If the display update has been interrupted by pending
7779 input, update mode lines in the frame. Due to the
7780 pending input, it might have been that redisplay hasn't
7781 been called, so that mode lines above the echo area are
7782 garbaged. This looks odd, so we prevent it here. */
7783 if (!display_completed
)
7784 n
= redisplay_mode_lines (FRAME_ROOT_WINDOW (f
), 0);
7786 if (window_height_changed_p
7787 /* Don't do this if Emacs is shutting down. Redisplay
7788 needs to run hooks. */
7789 && !NILP (Vrun_hooks
))
7791 /* Must update other windows. Likewise as in other
7792 cases, don't let this update be interrupted by
7794 int count
= SPECPDL_INDEX ();
7795 specbind (Qredisplay_dont_pause
, Qt
);
7796 windows_or_buffers_changed
= 1;
7797 redisplay_internal (0);
7798 unbind_to (count
, Qnil
);
7800 else if (FRAME_WINDOW_P (f
) && n
== 0)
7802 /* Window configuration is the same as before.
7803 Can do with a display update of the echo area,
7804 unless we displayed some mode lines. */
7805 update_single_window (w
, 1);
7806 FRAME_RIF (f
)->flush_display (f
);
7809 update_frame (f
, 1, 1);
7811 /* If cursor is in the echo area, make sure that the next
7812 redisplay displays the minibuffer, so that the cursor will
7813 be replaced with what the minibuffer wants. */
7814 if (cursor_in_echo_area
)
7815 ++windows_or_buffers_changed
;
7818 else if (!EQ (mini_window
, selected_window
))
7819 windows_or_buffers_changed
++;
7821 /* Last displayed message is now the current message. */
7822 echo_area_buffer
[1] = echo_area_buffer
[0];
7824 /* Prevent redisplay optimization in redisplay_internal by resetting
7825 this_line_start_pos. This is done because the mini-buffer now
7826 displays the message instead of its buffer text. */
7827 if (EQ (mini_window
, selected_window
))
7828 CHARPOS (this_line_start_pos
) = 0;
7830 return window_height_changed_p
;
7835 /***********************************************************************
7837 ***********************************************************************/
7840 /* The frame title buffering code is also used by Fformat_mode_line.
7841 So it is not conditioned by HAVE_WINDOW_SYSTEM. */
7843 /* A buffer for constructing frame titles in it; allocated from the
7844 heap in init_xdisp and resized as needed in store_frame_title_char. */
7846 static char *frame_title_buf
;
7848 /* The buffer's end, and a current output position in it. */
7850 static char *frame_title_buf_end
;
7851 static char *frame_title_ptr
;
7854 /* Store a single character C for the frame title in frame_title_buf.
7855 Re-allocate frame_title_buf if necessary. */
7859 store_frame_title_char (char c
)
7861 store_frame_title_char (c
)
7865 /* If output position has reached the end of the allocated buffer,
7866 double the buffer's size. */
7867 if (frame_title_ptr
== frame_title_buf_end
)
7869 int len
= frame_title_ptr
- frame_title_buf
;
7870 int new_size
= 2 * len
* sizeof *frame_title_buf
;
7871 frame_title_buf
= (char *) xrealloc (frame_title_buf
, new_size
);
7872 frame_title_buf_end
= frame_title_buf
+ new_size
;
7873 frame_title_ptr
= frame_title_buf
+ len
;
7876 *frame_title_ptr
++ = c
;
7880 /* Store part of a frame title in frame_title_buf, beginning at
7881 frame_title_ptr. STR is the string to store. Do not copy
7882 characters that yield more columns than PRECISION; PRECISION <= 0
7883 means copy the whole string. Pad with spaces until FIELD_WIDTH
7884 number of characters have been copied; FIELD_WIDTH <= 0 means don't
7885 pad. Called from display_mode_element when it is used to build a
7889 store_frame_title (str
, field_width
, precision
)
7890 const unsigned char *str
;
7891 int field_width
, precision
;
7896 /* Copy at most PRECISION chars from STR. */
7897 nbytes
= strlen (str
);
7898 n
+= c_string_width (str
, nbytes
, precision
, &dummy
, &nbytes
);
7900 store_frame_title_char (*str
++);
7902 /* Fill up with spaces until FIELD_WIDTH reached. */
7903 while (field_width
> 0
7906 store_frame_title_char (' ');
7913 #ifdef HAVE_WINDOW_SYSTEM
7915 /* Set the title of FRAME, if it has changed. The title format is
7916 Vicon_title_format if FRAME is iconified, otherwise it is
7917 frame_title_format. */
7920 x_consider_frame_title (frame
)
7923 struct frame
*f
= XFRAME (frame
);
7925 if (FRAME_WINDOW_P (f
)
7926 || FRAME_MINIBUF_ONLY_P (f
)
7927 || f
->explicit_name
)
7929 /* Do we have more than one visible frame on this X display? */
7932 struct buffer
*obuf
;
7936 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCDR (tail
))
7938 Lisp_Object other_frame
= XCAR (tail
);
7939 struct frame
*tf
= XFRAME (other_frame
);
7942 && FRAME_KBOARD (tf
) == FRAME_KBOARD (f
)
7943 && !FRAME_MINIBUF_ONLY_P (tf
)
7944 && !EQ (other_frame
, tip_frame
)
7945 && (FRAME_VISIBLE_P (tf
) || FRAME_ICONIFIED_P (tf
)))
7949 /* Set global variable indicating that multiple frames exist. */
7950 multiple_frames
= CONSP (tail
);
7952 /* Switch to the buffer of selected window of the frame. Set up
7953 frame_title_ptr so that display_mode_element will output into it;
7954 then display the title. */
7955 obuf
= current_buffer
;
7956 set_buffer_internal_1 (XBUFFER (XWINDOW (f
->selected_window
)->buffer
));
7957 fmt
= FRAME_ICONIFIED_P (f
) ? Vicon_title_format
: Vframe_title_format
;
7958 frame_title_ptr
= frame_title_buf
;
7959 init_iterator (&it
, XWINDOW (f
->selected_window
), -1, -1,
7960 NULL
, DEFAULT_FACE_ID
);
7961 display_mode_element (&it
, 0, -1, -1, fmt
, Qnil
, 0);
7962 len
= frame_title_ptr
- frame_title_buf
;
7963 frame_title_ptr
= NULL
;
7964 set_buffer_internal_1 (obuf
);
7966 /* Set the title only if it's changed. This avoids consing in
7967 the common case where it hasn't. (If it turns out that we've
7968 already wasted too much time by walking through the list with
7969 display_mode_element, then we might need to optimize at a
7970 higher level than this.) */
7971 if (! STRINGP (f
->name
)
7972 || SBYTES (f
->name
) != len
7973 || bcmp (frame_title_buf
, SDATA (f
->name
), len
) != 0)
7974 x_implicitly_set_name (f
, make_string (frame_title_buf
, len
), Qnil
);
7978 #endif /* not HAVE_WINDOW_SYSTEM */
7983 /***********************************************************************
7985 ***********************************************************************/
7988 /* Prepare for redisplay by updating menu-bar item lists when
7989 appropriate. This can call eval. */
7992 prepare_menu_bars ()
7995 struct gcpro gcpro1
, gcpro2
;
7997 Lisp_Object tooltip_frame
;
7999 #ifdef HAVE_WINDOW_SYSTEM
8000 tooltip_frame
= tip_frame
;
8002 tooltip_frame
= Qnil
;
8005 /* Update all frame titles based on their buffer names, etc. We do
8006 this before the menu bars so that the buffer-menu will show the
8007 up-to-date frame titles. */
8008 #ifdef HAVE_WINDOW_SYSTEM
8009 if (windows_or_buffers_changed
|| update_mode_lines
)
8011 Lisp_Object tail
, frame
;
8013 FOR_EACH_FRAME (tail
, frame
)
8016 if (!EQ (frame
, tooltip_frame
)
8017 && (FRAME_VISIBLE_P (f
) || FRAME_ICONIFIED_P (f
)))
8018 x_consider_frame_title (frame
);
8021 #endif /* HAVE_WINDOW_SYSTEM */
8023 /* Update the menu bar item lists, if appropriate. This has to be
8024 done before any actual redisplay or generation of display lines. */
8025 all_windows
= (update_mode_lines
8026 || buffer_shared
> 1
8027 || windows_or_buffers_changed
);
8030 Lisp_Object tail
, frame
;
8031 int count
= SPECPDL_INDEX ();
8033 record_unwind_protect (Fset_match_data
, Fmatch_data (Qnil
, Qnil
));
8035 FOR_EACH_FRAME (tail
, frame
)
8039 /* Ignore tooltip frame. */
8040 if (EQ (frame
, tooltip_frame
))
8043 /* If a window on this frame changed size, report that to
8044 the user and clear the size-change flag. */
8045 if (FRAME_WINDOW_SIZES_CHANGED (f
))
8047 Lisp_Object functions
;
8049 /* Clear flag first in case we get an error below. */
8050 FRAME_WINDOW_SIZES_CHANGED (f
) = 0;
8051 functions
= Vwindow_size_change_functions
;
8052 GCPRO2 (tail
, functions
);
8054 while (CONSP (functions
))
8056 call1 (XCAR (functions
), frame
);
8057 functions
= XCDR (functions
);
8063 update_menu_bar (f
, 0);
8064 #ifdef HAVE_WINDOW_SYSTEM
8065 update_tool_bar (f
, 0);
8070 unbind_to (count
, Qnil
);
8074 struct frame
*sf
= SELECTED_FRAME ();
8075 update_menu_bar (sf
, 1);
8076 #ifdef HAVE_WINDOW_SYSTEM
8077 update_tool_bar (sf
, 1);
8081 /* Motif needs this. See comment in xmenu.c. Turn it off when
8082 pending_menu_activation is not defined. */
8083 #ifdef USE_X_TOOLKIT
8084 pending_menu_activation
= 0;
8089 /* Update the menu bar item list for frame F. This has to be done
8090 before we start to fill in any display lines, because it can call
8093 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
8096 update_menu_bar (f
, save_match_data
)
8098 int save_match_data
;
8101 register struct window
*w
;
8103 /* If called recursively during a menu update, do nothing. This can
8104 happen when, for instance, an activate-menubar-hook causes a
8106 if (inhibit_menubar_update
)
8109 window
= FRAME_SELECTED_WINDOW (f
);
8110 w
= XWINDOW (window
);
8112 #if 0 /* The if statement below this if statement used to include the
8113 condition !NILP (w->update_mode_line), rather than using
8114 update_mode_lines directly, and this if statement may have
8115 been added to make that condition work. Now the if
8116 statement below matches its comment, this isn't needed. */
8117 if (update_mode_lines
)
8118 w
->update_mode_line
= Qt
;
8121 if (FRAME_WINDOW_P (f
)
8123 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8124 || defined (USE_GTK)
8125 FRAME_EXTERNAL_MENU_BAR (f
)
8127 FRAME_MENU_BAR_LINES (f
) > 0
8129 : FRAME_MENU_BAR_LINES (f
) > 0)
8131 /* If the user has switched buffers or windows, we need to
8132 recompute to reflect the new bindings. But we'll
8133 recompute when update_mode_lines is set too; that means
8134 that people can use force-mode-line-update to request
8135 that the menu bar be recomputed. The adverse effect on
8136 the rest of the redisplay algorithm is about the same as
8137 windows_or_buffers_changed anyway. */
8138 if (windows_or_buffers_changed
8139 /* This used to test w->update_mode_line, but we believe
8140 there is no need to recompute the menu in that case. */
8141 || update_mode_lines
8142 || ((BUF_SAVE_MODIFF (XBUFFER (w
->buffer
))
8143 < BUF_MODIFF (XBUFFER (w
->buffer
)))
8144 != !NILP (w
->last_had_star
))
8145 || ((!NILP (Vtransient_mark_mode
)
8146 && !NILP (XBUFFER (w
->buffer
)->mark_active
))
8147 != !NILP (w
->region_showing
)))
8149 struct buffer
*prev
= current_buffer
;
8150 int count
= SPECPDL_INDEX ();
8152 specbind (Qinhibit_menubar_update
, Qt
);
8154 set_buffer_internal_1 (XBUFFER (w
->buffer
));
8155 if (save_match_data
)
8156 record_unwind_protect (Fset_match_data
, Fmatch_data (Qnil
, Qnil
));
8157 if (NILP (Voverriding_local_map_menu_flag
))
8159 specbind (Qoverriding_terminal_local_map
, Qnil
);
8160 specbind (Qoverriding_local_map
, Qnil
);
8163 /* Run the Lucid hook. */
8164 safe_run_hooks (Qactivate_menubar_hook
);
8166 /* If it has changed current-menubar from previous value,
8167 really recompute the menu-bar from the value. */
8168 if (! NILP (Vlucid_menu_bar_dirty_flag
))
8169 call0 (Qrecompute_lucid_menubar
);
8171 safe_run_hooks (Qmenu_bar_update_hook
);
8172 FRAME_MENU_BAR_ITEMS (f
) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f
));
8174 /* Redisplay the menu bar in case we changed it. */
8175 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8176 || defined (USE_GTK)
8177 if (FRAME_WINDOW_P (f
)
8178 #if defined (MAC_OS)
8179 /* All frames on Mac OS share the same menubar. So only the
8180 selected frame should be allowed to set it. */
8181 && f
== SELECTED_FRAME ()
8184 set_frame_menubar (f
, 0, 0);
8186 /* On a terminal screen, the menu bar is an ordinary screen
8187 line, and this makes it get updated. */
8188 w
->update_mode_line
= Qt
;
8189 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8190 /* In the non-toolkit version, the menu bar is an ordinary screen
8191 line, and this makes it get updated. */
8192 w
->update_mode_line
= Qt
;
8193 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8195 unbind_to (count
, Qnil
);
8196 set_buffer_internal_1 (prev
);
8203 /***********************************************************************
8205 ***********************************************************************/
8207 #ifdef HAVE_WINDOW_SYSTEM
8210 Nominal cursor position -- where to draw output.
8211 HPOS and VPOS are window relative glyph matrix coordinates.
8212 X and Y are window relative pixel coordinates. */
8214 struct cursor_pos output_cursor
;
8218 Set the global variable output_cursor to CURSOR. All cursor
8219 positions are relative to updated_window. */
8222 set_output_cursor (cursor
)
8223 struct cursor_pos
*cursor
;
8225 output_cursor
.hpos
= cursor
->hpos
;
8226 output_cursor
.vpos
= cursor
->vpos
;
8227 output_cursor
.x
= cursor
->x
;
8228 output_cursor
.y
= cursor
->y
;
8233 Set a nominal cursor position.
8235 HPOS and VPOS are column/row positions in a window glyph matrix. X
8236 and Y are window text area relative pixel positions.
8238 If this is done during an update, updated_window will contain the
8239 window that is being updated and the position is the future output
8240 cursor position for that window. If updated_window is null, use
8241 selected_window and display the cursor at the given position. */
8244 x_cursor_to (vpos
, hpos
, y
, x
)
8245 int vpos
, hpos
, y
, x
;
8249 /* If updated_window is not set, work on selected_window. */
8253 w
= XWINDOW (selected_window
);
8255 /* Set the output cursor. */
8256 output_cursor
.hpos
= hpos
;
8257 output_cursor
.vpos
= vpos
;
8258 output_cursor
.x
= x
;
8259 output_cursor
.y
= y
;
8261 /* If not called as part of an update, really display the cursor.
8262 This will also set the cursor position of W. */
8263 if (updated_window
== NULL
)
8266 display_and_set_cursor (w
, 1, hpos
, vpos
, x
, y
);
8267 if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional
)
8268 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
8273 #endif /* HAVE_WINDOW_SYSTEM */
8276 /***********************************************************************
8278 ***********************************************************************/
8280 #ifdef HAVE_WINDOW_SYSTEM
8282 /* Where the mouse was last time we reported a mouse event. */
8284 FRAME_PTR last_mouse_frame
;
8286 /* Tool-bar item index of the item on which a mouse button was pressed
8289 int last_tool_bar_item
;
8292 /* Update the tool-bar item list for frame F. This has to be done
8293 before we start to fill in any display lines. Called from
8294 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
8295 and restore it here. */
8298 update_tool_bar (f
, save_match_data
)
8300 int save_match_data
;
8303 int do_update
= FRAME_EXTERNAL_TOOL_BAR (f
);
8305 int do_update
= WINDOWP (f
->tool_bar_window
)
8306 && WINDOW_TOTAL_LINES (XWINDOW (f
->tool_bar_window
)) > 0;
8314 window
= FRAME_SELECTED_WINDOW (f
);
8315 w
= XWINDOW (window
);
8317 /* If the user has switched buffers or windows, we need to
8318 recompute to reflect the new bindings. But we'll
8319 recompute when update_mode_lines is set too; that means
8320 that people can use force-mode-line-update to request
8321 that the menu bar be recomputed. The adverse effect on
8322 the rest of the redisplay algorithm is about the same as
8323 windows_or_buffers_changed anyway. */
8324 if (windows_or_buffers_changed
8325 || !NILP (w
->update_mode_line
)
8326 || update_mode_lines
8327 || ((BUF_SAVE_MODIFF (XBUFFER (w
->buffer
))
8328 < BUF_MODIFF (XBUFFER (w
->buffer
)))
8329 != !NILP (w
->last_had_star
))
8330 || ((!NILP (Vtransient_mark_mode
)
8331 && !NILP (XBUFFER (w
->buffer
)->mark_active
))
8332 != !NILP (w
->region_showing
)))
8334 struct buffer
*prev
= current_buffer
;
8335 int count
= SPECPDL_INDEX ();
8336 Lisp_Object old_tool_bar
;
8337 struct gcpro gcpro1
;
8339 /* Set current_buffer to the buffer of the selected
8340 window of the frame, so that we get the right local
8342 set_buffer_internal_1 (XBUFFER (w
->buffer
));
8344 /* Save match data, if we must. */
8345 if (save_match_data
)
8346 record_unwind_protect (Fset_match_data
, Fmatch_data (Qnil
, Qnil
));
8348 /* Make sure that we don't accidentally use bogus keymaps. */
8349 if (NILP (Voverriding_local_map_menu_flag
))
8351 specbind (Qoverriding_terminal_local_map
, Qnil
);
8352 specbind (Qoverriding_local_map
, Qnil
);
8355 old_tool_bar
= f
->tool_bar_items
;
8356 GCPRO1 (old_tool_bar
);
8358 /* Build desired tool-bar items from keymaps. */
8361 = tool_bar_items (f
->tool_bar_items
, &f
->n_tool_bar_items
);
8364 /* Redisplay the tool-bar if we changed it. */
8365 if (! NILP (Fequal (old_tool_bar
, f
->tool_bar_items
)))
8366 w
->update_mode_line
= Qt
;
8370 unbind_to (count
, Qnil
);
8371 set_buffer_internal_1 (prev
);
8377 /* Set F->desired_tool_bar_string to a Lisp string representing frame
8378 F's desired tool-bar contents. F->tool_bar_items must have
8379 been set up previously by calling prepare_menu_bars. */
8382 build_desired_tool_bar_string (f
)
8385 int i
, size
, size_needed
;
8386 struct gcpro gcpro1
, gcpro2
, gcpro3
;
8387 Lisp_Object image
, plist
, props
;
8389 image
= plist
= props
= Qnil
;
8390 GCPRO3 (image
, plist
, props
);
8392 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
8393 Otherwise, make a new string. */
8395 /* The size of the string we might be able to reuse. */
8396 size
= (STRINGP (f
->desired_tool_bar_string
)
8397 ? SCHARS (f
->desired_tool_bar_string
)
8400 /* We need one space in the string for each image. */
8401 size_needed
= f
->n_tool_bar_items
;
8403 /* Reuse f->desired_tool_bar_string, if possible. */
8404 if (size
< size_needed
|| NILP (f
->desired_tool_bar_string
))
8405 f
->desired_tool_bar_string
= Fmake_string (make_number (size_needed
),
8409 props
= list4 (Qdisplay
, Qnil
, Qmenu_item
, Qnil
);
8410 Fremove_text_properties (make_number (0), make_number (size
),
8411 props
, f
->desired_tool_bar_string
);
8414 /* Put a `display' property on the string for the images to display,
8415 put a `menu_item' property on tool-bar items with a value that
8416 is the index of the item in F's tool-bar item vector. */
8417 for (i
= 0; i
< f
->n_tool_bar_items
; ++i
)
8419 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
8421 int enabled_p
= !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P
));
8422 int selected_p
= !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P
));
8423 int hmargin
, vmargin
, relief
, idx
, end
;
8424 extern Lisp_Object QCrelief
, QCmargin
, QCconversion
;
8426 /* If image is a vector, choose the image according to the
8428 image
= PROP (TOOL_BAR_ITEM_IMAGES
);
8429 if (VECTORP (image
))
8433 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
8434 : TOOL_BAR_IMAGE_ENABLED_DESELECTED
);
8437 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
8438 : TOOL_BAR_IMAGE_DISABLED_DESELECTED
);
8440 xassert (ASIZE (image
) >= idx
);
8441 image
= AREF (image
, idx
);
8446 /* Ignore invalid image specifications. */
8447 if (!valid_image_p (image
))
8450 /* Display the tool-bar button pressed, or depressed. */
8451 plist
= Fcopy_sequence (XCDR (image
));
8453 /* Compute margin and relief to draw. */
8454 relief
= (tool_bar_button_relief
>= 0
8455 ? tool_bar_button_relief
8456 : DEFAULT_TOOL_BAR_BUTTON_RELIEF
);
8457 hmargin
= vmargin
= relief
;
8459 if (INTEGERP (Vtool_bar_button_margin
)
8460 && XINT (Vtool_bar_button_margin
) > 0)
8462 hmargin
+= XFASTINT (Vtool_bar_button_margin
);
8463 vmargin
+= XFASTINT (Vtool_bar_button_margin
);
8465 else if (CONSP (Vtool_bar_button_margin
))
8467 if (INTEGERP (XCAR (Vtool_bar_button_margin
))
8468 && XINT (XCAR (Vtool_bar_button_margin
)) > 0)
8469 hmargin
+= XFASTINT (XCAR (Vtool_bar_button_margin
));
8471 if (INTEGERP (XCDR (Vtool_bar_button_margin
))
8472 && XINT (XCDR (Vtool_bar_button_margin
)) > 0)
8473 vmargin
+= XFASTINT (XCDR (Vtool_bar_button_margin
));
8476 if (auto_raise_tool_bar_buttons_p
)
8478 /* Add a `:relief' property to the image spec if the item is
8482 plist
= Fplist_put (plist
, QCrelief
, make_number (-relief
));
8489 /* If image is selected, display it pressed, i.e. with a
8490 negative relief. If it's not selected, display it with a
8492 plist
= Fplist_put (plist
, QCrelief
,
8494 ? make_number (-relief
)
8495 : make_number (relief
)));
8500 /* Put a margin around the image. */
8501 if (hmargin
|| vmargin
)
8503 if (hmargin
== vmargin
)
8504 plist
= Fplist_put (plist
, QCmargin
, make_number (hmargin
));
8506 plist
= Fplist_put (plist
, QCmargin
,
8507 Fcons (make_number (hmargin
),
8508 make_number (vmargin
)));
8511 /* If button is not enabled, and we don't have special images
8512 for the disabled state, make the image appear disabled by
8513 applying an appropriate algorithm to it. */
8514 if (!enabled_p
&& idx
< 0)
8515 plist
= Fplist_put (plist
, QCconversion
, Qdisabled
);
8517 /* Put a `display' text property on the string for the image to
8518 display. Put a `menu-item' property on the string that gives
8519 the start of this item's properties in the tool-bar items
8521 image
= Fcons (Qimage
, plist
);
8522 props
= list4 (Qdisplay
, image
,
8523 Qmenu_item
, make_number (i
* TOOL_BAR_ITEM_NSLOTS
));
8525 /* Let the last image hide all remaining spaces in the tool bar
8526 string. The string can be longer than needed when we reuse a
8528 if (i
+ 1 == f
->n_tool_bar_items
)
8529 end
= SCHARS (f
->desired_tool_bar_string
);
8532 Fadd_text_properties (make_number (i
), make_number (end
),
8533 props
, f
->desired_tool_bar_string
);
8541 /* Display one line of the tool-bar of frame IT->f. */
8544 display_tool_bar_line (it
)
8547 struct glyph_row
*row
= it
->glyph_row
;
8548 int max_x
= it
->last_visible_x
;
8551 prepare_desired_row (row
);
8552 row
->y
= it
->current_y
;
8554 /* Note that this isn't made use of if the face hasn't a box,
8555 so there's no need to check the face here. */
8556 it
->start_of_box_run_p
= 1;
8558 while (it
->current_x
< max_x
)
8560 int x_before
, x
, n_glyphs_before
, i
, nglyphs
;
8562 /* Get the next display element. */
8563 if (!get_next_display_element (it
))
8566 /* Produce glyphs. */
8567 x_before
= it
->current_x
;
8568 n_glyphs_before
= it
->glyph_row
->used
[TEXT_AREA
];
8569 PRODUCE_GLYPHS (it
);
8571 nglyphs
= it
->glyph_row
->used
[TEXT_AREA
] - n_glyphs_before
;
8576 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
8578 if (x
+ glyph
->pixel_width
> max_x
)
8580 /* Glyph doesn't fit on line. */
8581 it
->glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
+ i
;
8587 x
+= glyph
->pixel_width
;
8591 /* Stop at line ends. */
8592 if (ITERATOR_AT_END_OF_LINE_P (it
))
8595 set_iterator_to_next (it
, 1);
8600 row
->displays_text_p
= row
->used
[TEXT_AREA
] != 0;
8601 extend_face_to_end_of_line (it
);
8602 last
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
] - 1;
8603 last
->right_box_line_p
= 1;
8604 if (last
== row
->glyphs
[TEXT_AREA
])
8605 last
->left_box_line_p
= 1;
8606 compute_line_metrics (it
);
8608 /* If line is empty, make it occupy the rest of the tool-bar. */
8609 if (!row
->displays_text_p
)
8611 row
->height
= row
->phys_height
= it
->last_visible_y
- row
->y
;
8612 row
->ascent
= row
->phys_ascent
= 0;
8615 row
->full_width_p
= 1;
8616 row
->continued_p
= 0;
8617 row
->truncated_on_left_p
= 0;
8618 row
->truncated_on_right_p
= 0;
8620 it
->current_x
= it
->hpos
= 0;
8621 it
->current_y
+= row
->height
;
8627 /* Value is the number of screen lines needed to make all tool-bar
8628 items of frame F visible. */
8631 tool_bar_lines_needed (f
)
8634 struct window
*w
= XWINDOW (f
->tool_bar_window
);
8637 /* Initialize an iterator for iteration over
8638 F->desired_tool_bar_string in the tool-bar window of frame F. */
8639 init_iterator (&it
, w
, -1, -1, w
->desired_matrix
->rows
, TOOL_BAR_FACE_ID
);
8640 it
.first_visible_x
= 0;
8641 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
8642 reseat_to_string (&it
, NULL
, f
->desired_tool_bar_string
, 0, 0, 0, -1);
8644 while (!ITERATOR_AT_END_P (&it
))
8646 it
.glyph_row
= w
->desired_matrix
->rows
;
8647 clear_glyph_row (it
.glyph_row
);
8648 display_tool_bar_line (&it
);
8651 return (it
.current_y
+ FRAME_LINE_HEIGHT (f
) - 1) / FRAME_LINE_HEIGHT (f
);
8655 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed
, Stool_bar_lines_needed
,
8657 doc
: /* Return the number of lines occupied by the tool bar of FRAME. */)
8666 frame
= selected_frame
;
8668 CHECK_FRAME (frame
);
8671 if (WINDOWP (f
->tool_bar_window
)
8672 || (w
= XWINDOW (f
->tool_bar_window
),
8673 WINDOW_TOTAL_LINES (w
) > 0))
8675 update_tool_bar (f
, 1);
8676 if (f
->n_tool_bar_items
)
8678 build_desired_tool_bar_string (f
);
8679 nlines
= tool_bar_lines_needed (f
);
8683 return make_number (nlines
);
8687 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
8688 height should be changed. */
8691 redisplay_tool_bar (f
)
8696 struct glyph_row
*row
;
8697 int change_height_p
= 0;
8700 if (FRAME_EXTERNAL_TOOL_BAR (f
))
8701 update_frame_tool_bar (f
);
8705 /* If frame hasn't a tool-bar window or if it is zero-height, don't
8706 do anything. This means you must start with tool-bar-lines
8707 non-zero to get the auto-sizing effect. Or in other words, you
8708 can turn off tool-bars by specifying tool-bar-lines zero. */
8709 if (!WINDOWP (f
->tool_bar_window
)
8710 || (w
= XWINDOW (f
->tool_bar_window
),
8711 WINDOW_TOTAL_LINES (w
) == 0))
8714 /* Set up an iterator for the tool-bar window. */
8715 init_iterator (&it
, w
, -1, -1, w
->desired_matrix
->rows
, TOOL_BAR_FACE_ID
);
8716 it
.first_visible_x
= 0;
8717 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
8720 /* Build a string that represents the contents of the tool-bar. */
8721 build_desired_tool_bar_string (f
);
8722 reseat_to_string (&it
, NULL
, f
->desired_tool_bar_string
, 0, 0, 0, -1);
8724 /* Display as many lines as needed to display all tool-bar items. */
8725 while (it
.current_y
< it
.last_visible_y
)
8726 display_tool_bar_line (&it
);
8728 /* It doesn't make much sense to try scrolling in the tool-bar
8729 window, so don't do it. */
8730 w
->desired_matrix
->no_scrolling_p
= 1;
8731 w
->must_be_updated_p
= 1;
8733 if (auto_resize_tool_bars_p
)
8737 /* If we couldn't display everything, change the tool-bar's
8739 if (IT_STRING_CHARPOS (it
) < it
.end_charpos
)
8740 change_height_p
= 1;
8742 /* If there are blank lines at the end, except for a partially
8743 visible blank line at the end that is smaller than
8744 FRAME_LINE_HEIGHT, change the tool-bar's height. */
8745 row
= it
.glyph_row
- 1;
8746 if (!row
->displays_text_p
8747 && row
->height
>= FRAME_LINE_HEIGHT (f
))
8748 change_height_p
= 1;
8750 /* If row displays tool-bar items, but is partially visible,
8751 change the tool-bar's height. */
8752 if (row
->displays_text_p
8753 && MATRIX_ROW_BOTTOM_Y (row
) > it
.last_visible_y
)
8754 change_height_p
= 1;
8756 /* Resize windows as needed by changing the `tool-bar-lines'
8759 && (nlines
= tool_bar_lines_needed (f
),
8760 nlines
!= WINDOW_TOTAL_LINES (w
)))
8762 extern Lisp_Object Qtool_bar_lines
;
8764 int old_height
= WINDOW_TOTAL_LINES (w
);
8766 XSETFRAME (frame
, f
);
8767 clear_glyph_matrix (w
->desired_matrix
);
8768 Fmodify_frame_parameters (frame
,
8769 Fcons (Fcons (Qtool_bar_lines
,
8770 make_number (nlines
)),
8772 if (WINDOW_TOTAL_LINES (w
) != old_height
)
8773 fonts_changed_p
= 1;
8777 return change_height_p
;
8781 /* Get information about the tool-bar item which is displayed in GLYPH
8782 on frame F. Return in *PROP_IDX the index where tool-bar item
8783 properties start in F->tool_bar_items. Value is zero if
8784 GLYPH doesn't display a tool-bar item. */
8787 tool_bar_item_info (f
, glyph
, prop_idx
)
8789 struct glyph
*glyph
;
8796 /* This function can be called asynchronously, which means we must
8797 exclude any possibility that Fget_text_property signals an
8799 charpos
= min (SCHARS (f
->current_tool_bar_string
), glyph
->charpos
);
8800 charpos
= max (0, charpos
);
8802 /* Get the text property `menu-item' at pos. The value of that
8803 property is the start index of this item's properties in
8804 F->tool_bar_items. */
8805 prop
= Fget_text_property (make_number (charpos
),
8806 Qmenu_item
, f
->current_tool_bar_string
);
8807 if (INTEGERP (prop
))
8809 *prop_idx
= XINT (prop
);
8819 /* Get information about the tool-bar item at position X/Y on frame F.
8820 Return in *GLYPH a pointer to the glyph of the tool-bar item in
8821 the current matrix of the tool-bar window of F, or NULL if not
8822 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
8823 item in F->tool_bar_items. Value is
8825 -1 if X/Y is not on a tool-bar item
8826 0 if X/Y is on the same item that was highlighted before.
8830 get_tool_bar_item (f
, x
, y
, glyph
, hpos
, vpos
, prop_idx
)
8833 struct glyph
**glyph
;
8834 int *hpos
, *vpos
, *prop_idx
;
8836 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
8837 struct window
*w
= XWINDOW (f
->tool_bar_window
);
8840 /* Find the glyph under X/Y. */
8841 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, 0, 0, &area
);
8845 /* Get the start of this tool-bar item's properties in
8846 f->tool_bar_items. */
8847 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
8850 /* Is mouse on the highlighted item? */
8851 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
8852 && *vpos
>= dpyinfo
->mouse_face_beg_row
8853 && *vpos
<= dpyinfo
->mouse_face_end_row
8854 && (*vpos
> dpyinfo
->mouse_face_beg_row
8855 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
8856 && (*vpos
< dpyinfo
->mouse_face_end_row
8857 || *hpos
< dpyinfo
->mouse_face_end_col
8858 || dpyinfo
->mouse_face_past_end
))
8866 Handle mouse button event on the tool-bar of frame F, at
8867 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
8868 0 for button release. MODIFIERS is event modifiers for button
8872 handle_tool_bar_click (f
, x
, y
, down_p
, modifiers
)
8875 unsigned int modifiers
;
8877 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
8878 struct window
*w
= XWINDOW (f
->tool_bar_window
);
8879 int hpos
, vpos
, prop_idx
;
8880 struct glyph
*glyph
;
8881 Lisp_Object enabled_p
;
8883 /* If not on the highlighted tool-bar item, return. */
8884 frame_to_window_pixel_xy (w
, &x
, &y
);
8885 if (get_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
8888 /* If item is disabled, do nothing. */
8889 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
8890 if (NILP (enabled_p
))
8895 /* Show item in pressed state. */
8896 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
8897 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
8898 last_tool_bar_item
= prop_idx
;
8902 Lisp_Object key
, frame
;
8903 struct input_event event
;
8906 /* Show item in released state. */
8907 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
8908 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
8910 key
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_KEY
);
8912 XSETFRAME (frame
, f
);
8913 event
.kind
= TOOL_BAR_EVENT
;
8914 event
.frame_or_window
= frame
;
8916 kbd_buffer_store_event (&event
);
8918 event
.kind
= TOOL_BAR_EVENT
;
8919 event
.frame_or_window
= frame
;
8921 event
.modifiers
= modifiers
;
8922 kbd_buffer_store_event (&event
);
8923 last_tool_bar_item
= -1;
8928 /* Possibly highlight a tool-bar item on frame F when mouse moves to
8929 tool-bar window-relative coordinates X/Y. Called from
8930 note_mouse_highlight. */
8933 note_tool_bar_highlight (f
, x
, y
)
8937 Lisp_Object window
= f
->tool_bar_window
;
8938 struct window
*w
= XWINDOW (window
);
8939 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
8941 struct glyph
*glyph
;
8942 struct glyph_row
*row
;
8944 Lisp_Object enabled_p
;
8946 enum draw_glyphs_face draw
= DRAW_IMAGE_RAISED
;
8947 int mouse_down_p
, rc
;
8949 /* Function note_mouse_highlight is called with negative x(y
8950 values when mouse moves outside of the frame. */
8951 if (x
<= 0 || y
<= 0)
8953 clear_mouse_face (dpyinfo
);
8957 rc
= get_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
8960 /* Not on tool-bar item. */
8961 clear_mouse_face (dpyinfo
);
8965 /* On same tool-bar item as before. */
8968 clear_mouse_face (dpyinfo
);
8970 /* Mouse is down, but on different tool-bar item? */
8971 mouse_down_p
= (dpyinfo
->grabbed
8972 && f
== last_mouse_frame
8973 && FRAME_LIVE_P (f
));
8975 && last_tool_bar_item
!= prop_idx
)
8978 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
8979 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
8981 /* If tool-bar item is not enabled, don't highlight it. */
8982 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
8983 if (!NILP (enabled_p
))
8985 /* Compute the x-position of the glyph. In front and past the
8986 image is a space. We include this in the highlighted area. */
8987 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
8988 for (i
= x
= 0; i
< hpos
; ++i
)
8989 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
8991 /* Record this as the current active region. */
8992 dpyinfo
->mouse_face_beg_col
= hpos
;
8993 dpyinfo
->mouse_face_beg_row
= vpos
;
8994 dpyinfo
->mouse_face_beg_x
= x
;
8995 dpyinfo
->mouse_face_beg_y
= row
->y
;
8996 dpyinfo
->mouse_face_past_end
= 0;
8998 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
8999 dpyinfo
->mouse_face_end_row
= vpos
;
9000 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
9001 dpyinfo
->mouse_face_end_y
= row
->y
;
9002 dpyinfo
->mouse_face_window
= window
;
9003 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
9005 /* Display it as active. */
9006 show_mouse_face (dpyinfo
, draw
);
9007 dpyinfo
->mouse_face_image_state
= draw
;
9012 /* Set help_echo_string to a help string to display for this tool-bar item.
9013 XTread_socket does the rest. */
9014 help_echo_object
= help_echo_window
= Qnil
;
9016 help_echo_string
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_HELP
);
9017 if (NILP (help_echo_string
))
9018 help_echo_string
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_CAPTION
);
9021 #endif /* HAVE_WINDOW_SYSTEM */
9025 /************************************************************************
9026 Horizontal scrolling
9027 ************************************************************************/
9029 static int hscroll_window_tree
P_ ((Lisp_Object
));
9030 static int hscroll_windows
P_ ((Lisp_Object
));
9032 /* For all leaf windows in the window tree rooted at WINDOW, set their
9033 hscroll value so that PT is (i) visible in the window, and (ii) so
9034 that it is not within a certain margin at the window's left and
9035 right border. Value is non-zero if any window's hscroll has been
9039 hscroll_window_tree (window
)
9042 int hscrolled_p
= 0;
9043 int hscroll_relative_p
= FLOATP (Vhscroll_step
);
9044 int hscroll_step_abs
= 0;
9045 double hscroll_step_rel
= 0;
9047 if (hscroll_relative_p
)
9049 hscroll_step_rel
= XFLOAT_DATA (Vhscroll_step
);
9050 if (hscroll_step_rel
< 0)
9052 hscroll_relative_p
= 0;
9053 hscroll_step_abs
= 0;
9056 else if (INTEGERP (Vhscroll_step
))
9058 hscroll_step_abs
= XINT (Vhscroll_step
);
9059 if (hscroll_step_abs
< 0)
9060 hscroll_step_abs
= 0;
9063 hscroll_step_abs
= 0;
9065 while (WINDOWP (window
))
9067 struct window
*w
= XWINDOW (window
);
9069 if (WINDOWP (w
->hchild
))
9070 hscrolled_p
|= hscroll_window_tree (w
->hchild
);
9071 else if (WINDOWP (w
->vchild
))
9072 hscrolled_p
|= hscroll_window_tree (w
->vchild
);
9073 else if (w
->cursor
.vpos
>= 0)
9076 int text_area_width
;
9077 struct glyph_row
*current_cursor_row
9078 = MATRIX_ROW (w
->current_matrix
, w
->cursor
.vpos
);
9079 struct glyph_row
*desired_cursor_row
9080 = MATRIX_ROW (w
->desired_matrix
, w
->cursor
.vpos
);
9081 struct glyph_row
*cursor_row
9082 = (desired_cursor_row
->enabled_p
9083 ? desired_cursor_row
9084 : current_cursor_row
);
9086 text_area_width
= window_box_width (w
, TEXT_AREA
);
9088 /* Scroll when cursor is inside this scroll margin. */
9089 h_margin
= hscroll_margin
* WINDOW_FRAME_COLUMN_WIDTH (w
);
9091 if ((XFASTINT (w
->hscroll
)
9092 && w
->cursor
.x
<= h_margin
)
9093 || (cursor_row
->enabled_p
9094 && cursor_row
->truncated_on_right_p
9095 && (w
->cursor
.x
>= text_area_width
- h_margin
)))
9099 struct buffer
*saved_current_buffer
;
9103 /* Find point in a display of infinite width. */
9104 saved_current_buffer
= current_buffer
;
9105 current_buffer
= XBUFFER (w
->buffer
);
9107 if (w
== XWINDOW (selected_window
))
9108 pt
= BUF_PT (current_buffer
);
9111 pt
= marker_position (w
->pointm
);
9112 pt
= max (BEGV
, pt
);
9116 /* Move iterator to pt starting at cursor_row->start in
9117 a line with infinite width. */
9118 init_to_row_start (&it
, w
, cursor_row
);
9119 it
.last_visible_x
= INFINITY
;
9120 move_it_in_display_line_to (&it
, pt
, -1, MOVE_TO_POS
);
9121 current_buffer
= saved_current_buffer
;
9123 /* Position cursor in window. */
9124 if (!hscroll_relative_p
&& hscroll_step_abs
== 0)
9125 hscroll
= max (0, (it
.current_x
9126 - (ITERATOR_AT_END_OF_LINE_P (&it
)
9127 ? (text_area_width
- 4 * FRAME_COLUMN_WIDTH (it
.f
))
9128 : (text_area_width
/ 2))))
9129 / FRAME_COLUMN_WIDTH (it
.f
);
9130 else if (w
->cursor
.x
>= text_area_width
- h_margin
)
9132 if (hscroll_relative_p
)
9133 wanted_x
= text_area_width
* (1 - hscroll_step_rel
)
9136 wanted_x
= text_area_width
9137 - hscroll_step_abs
* FRAME_COLUMN_WIDTH (it
.f
)
9140 = max (0, it
.current_x
- wanted_x
) / FRAME_COLUMN_WIDTH (it
.f
);
9144 if (hscroll_relative_p
)
9145 wanted_x
= text_area_width
* hscroll_step_rel
9148 wanted_x
= hscroll_step_abs
* FRAME_COLUMN_WIDTH (it
.f
)
9151 = max (0, it
.current_x
- wanted_x
) / FRAME_COLUMN_WIDTH (it
.f
);
9153 hscroll
= max (hscroll
, XFASTINT (w
->min_hscroll
));
9155 /* Don't call Fset_window_hscroll if value hasn't
9156 changed because it will prevent redisplay
9158 if (XFASTINT (w
->hscroll
) != hscroll
)
9160 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
9161 w
->hscroll
= make_number (hscroll
);
9170 /* Value is non-zero if hscroll of any leaf window has been changed. */
9175 /* Set hscroll so that cursor is visible and not inside horizontal
9176 scroll margins for all windows in the tree rooted at WINDOW. See
9177 also hscroll_window_tree above. Value is non-zero if any window's
9178 hscroll has been changed. If it has, desired matrices on the frame
9179 of WINDOW are cleared. */
9182 hscroll_windows (window
)
9187 if (automatic_hscrolling_p
)
9189 hscrolled_p
= hscroll_window_tree (window
);
9191 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window
))));
9200 /************************************************************************
9202 ************************************************************************/
9204 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
9205 to a non-zero value. This is sometimes handy to have in a debugger
9210 /* First and last unchanged row for try_window_id. */
9212 int debug_first_unchanged_at_end_vpos
;
9213 int debug_last_unchanged_at_beg_vpos
;
9215 /* Delta vpos and y. */
9217 int debug_dvpos
, debug_dy
;
9219 /* Delta in characters and bytes for try_window_id. */
9221 int debug_delta
, debug_delta_bytes
;
9223 /* Values of window_end_pos and window_end_vpos at the end of
9226 EMACS_INT debug_end_pos
, debug_end_vpos
;
9228 /* Append a string to W->desired_matrix->method. FMT is a printf
9229 format string. A1...A9 are a supplement for a variable-length
9230 argument list. If trace_redisplay_p is non-zero also printf the
9231 resulting string to stderr. */
9234 debug_method_add (w
, fmt
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
)
9237 int a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
;
9240 char *method
= w
->desired_matrix
->method
;
9241 int len
= strlen (method
);
9242 int size
= sizeof w
->desired_matrix
->method
;
9243 int remaining
= size
- len
- 1;
9245 sprintf (buffer
, fmt
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
);
9246 if (len
&& remaining
)
9252 strncpy (method
+ len
, buffer
, remaining
);
9254 if (trace_redisplay_p
)
9255 fprintf (stderr
, "%p (%s): %s\n",
9257 ((BUFFERP (w
->buffer
)
9258 && STRINGP (XBUFFER (w
->buffer
)->name
))
9259 ? (char *) SDATA (XBUFFER (w
->buffer
)->name
)
9264 #endif /* GLYPH_DEBUG */
9267 /* Value is non-zero if all changes in window W, which displays
9268 current_buffer, are in the text between START and END. START is a
9269 buffer position, END is given as a distance from Z. Used in
9270 redisplay_internal for display optimization. */
9273 text_outside_line_unchanged_p (w
, start
, end
)
9277 int unchanged_p
= 1;
9279 /* If text or overlays have changed, see where. */
9280 if (XFASTINT (w
->last_modified
) < MODIFF
9281 || XFASTINT (w
->last_overlay_modified
) < OVERLAY_MODIFF
)
9283 /* Gap in the line? */
9284 if (GPT
< start
|| Z
- GPT
< end
)
9287 /* Changes start in front of the line, or end after it? */
9289 && (BEG_UNCHANGED
< start
- 1
9290 || END_UNCHANGED
< end
))
9293 /* If selective display, can't optimize if changes start at the
9294 beginning of the line. */
9296 && INTEGERP (current_buffer
->selective_display
)
9297 && XINT (current_buffer
->selective_display
) > 0
9298 && (BEG_UNCHANGED
< start
|| GPT
<= start
))
9301 /* If there are overlays at the start or end of the line, these
9302 may have overlay strings with newlines in them. A change at
9303 START, for instance, may actually concern the display of such
9304 overlay strings as well, and they are displayed on different
9305 lines. So, quickly rule out this case. (For the future, it
9306 might be desirable to implement something more telling than
9307 just BEG/END_UNCHANGED.) */
9310 if (BEG
+ BEG_UNCHANGED
== start
9311 && overlay_touches_p (start
))
9313 if (END_UNCHANGED
== end
9314 && overlay_touches_p (Z
- end
))
9323 /* Do a frame update, taking possible shortcuts into account. This is
9324 the main external entry point for redisplay.
9326 If the last redisplay displayed an echo area message and that message
9327 is no longer requested, we clear the echo area or bring back the
9328 mini-buffer if that is in use. */
9333 redisplay_internal (0);
9338 overlay_arrow_string_or_property (var
, pbitmap
)
9342 Lisp_Object pstr
= Fget (var
, Qoverlay_arrow_string
);
9348 if (bitmap
= Fget (var
, Qoverlay_arrow_bitmap
), INTEGERP (bitmap
))
9349 *pbitmap
= XINT (bitmap
);
9354 return Voverlay_arrow_string
;
9357 /* Return 1 if there are any overlay-arrows in current_buffer. */
9359 overlay_arrow_in_current_buffer_p ()
9363 for (vlist
= Voverlay_arrow_variable_list
;
9365 vlist
= XCDR (vlist
))
9367 Lisp_Object var
= XCAR (vlist
);
9372 val
= find_symbol_value (var
);
9374 && current_buffer
== XMARKER (val
)->buffer
)
9381 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
9385 overlay_arrows_changed_p ()
9389 for (vlist
= Voverlay_arrow_variable_list
;
9391 vlist
= XCDR (vlist
))
9393 Lisp_Object var
= XCAR (vlist
);
9394 Lisp_Object val
, pstr
;
9398 val
= find_symbol_value (var
);
9401 if (! EQ (COERCE_MARKER (val
),
9402 Fget (var
, Qlast_arrow_position
))
9403 || ! (pstr
= overlay_arrow_string_or_property (var
, 0),
9404 EQ (pstr
, Fget (var
, Qlast_arrow_string
))))
9410 /* Mark overlay arrows to be updated on next redisplay. */
9413 update_overlay_arrows (up_to_date
)
9418 for (vlist
= Voverlay_arrow_variable_list
;
9420 vlist
= XCDR (vlist
))
9422 Lisp_Object var
= XCAR (vlist
);
9429 Lisp_Object val
= find_symbol_value (var
);
9430 Fput (var
, Qlast_arrow_position
,
9431 COERCE_MARKER (val
));
9432 Fput (var
, Qlast_arrow_string
,
9433 overlay_arrow_string_or_property (var
, 0));
9435 else if (up_to_date
< 0
9436 || !NILP (Fget (var
, Qlast_arrow_position
)))
9438 Fput (var
, Qlast_arrow_position
, Qt
);
9439 Fput (var
, Qlast_arrow_string
, Qt
);
9445 /* Return overlay arrow string at row, or nil. */
9448 overlay_arrow_at_row (f
, row
, pbitmap
)
9450 struct glyph_row
*row
;
9455 for (vlist
= Voverlay_arrow_variable_list
;
9457 vlist
= XCDR (vlist
))
9459 Lisp_Object var
= XCAR (vlist
);
9465 val
= find_symbol_value (var
);
9468 && current_buffer
== XMARKER (val
)->buffer
9469 && (MATRIX_ROW_START_CHARPOS (row
) == marker_position (val
)))
9471 val
= overlay_arrow_string_or_property (var
, pbitmap
);
9472 if (FRAME_WINDOW_P (f
))
9474 else if (STRINGP (val
))
9484 /* Return 1 if point moved out of or into a composition. Otherwise
9485 return 0. PREV_BUF and PREV_PT are the last point buffer and
9486 position. BUF and PT are the current point buffer and position. */
9489 check_point_in_composition (prev_buf
, prev_pt
, buf
, pt
)
9490 struct buffer
*prev_buf
, *buf
;
9497 XSETBUFFER (buffer
, buf
);
9498 /* Check a composition at the last point if point moved within the
9500 if (prev_buf
== buf
)
9503 /* Point didn't move. */
9506 if (prev_pt
> BUF_BEGV (buf
) && prev_pt
< BUF_ZV (buf
)
9507 && find_composition (prev_pt
, -1, &start
, &end
, &prop
, buffer
)
9508 && COMPOSITION_VALID_P (start
, end
, prop
)
9509 && start
< prev_pt
&& end
> prev_pt
)
9510 /* The last point was within the composition. Return 1 iff
9511 point moved out of the composition. */
9512 return (pt
<= start
|| pt
>= end
);
9515 /* Check a composition at the current point. */
9516 return (pt
> BUF_BEGV (buf
) && pt
< BUF_ZV (buf
)
9517 && find_composition (pt
, -1, &start
, &end
, &prop
, buffer
)
9518 && COMPOSITION_VALID_P (start
, end
, prop
)
9519 && start
< pt
&& end
> pt
);
9523 /* Reconsider the setting of B->clip_changed which is displayed
9527 reconsider_clip_changes (w
, b
)
9532 && !NILP (w
->window_end_valid
)
9533 && w
->current_matrix
->buffer
== b
9534 && w
->current_matrix
->zv
== BUF_ZV (b
)
9535 && w
->current_matrix
->begv
== BUF_BEGV (b
))
9536 b
->clip_changed
= 0;
9538 /* If display wasn't paused, and W is not a tool bar window, see if
9539 point has been moved into or out of a composition. In that case,
9540 we set b->clip_changed to 1 to force updating the screen. If
9541 b->clip_changed has already been set to 1, we can skip this
9543 if (!b
->clip_changed
9544 && BUFFERP (w
->buffer
) && !NILP (w
->window_end_valid
))
9548 if (w
== XWINDOW (selected_window
))
9549 pt
= BUF_PT (current_buffer
);
9551 pt
= marker_position (w
->pointm
);
9553 if ((w
->current_matrix
->buffer
!= XBUFFER (w
->buffer
)
9554 || pt
!= XINT (w
->last_point
))
9555 && check_point_in_composition (w
->current_matrix
->buffer
,
9556 XINT (w
->last_point
),
9557 XBUFFER (w
->buffer
), pt
))
9558 b
->clip_changed
= 1;
9563 /* Select FRAME to forward the values of frame-local variables into C
9564 variables so that the redisplay routines can access those values
9568 select_frame_for_redisplay (frame
)
9571 Lisp_Object tail
, sym
, val
;
9572 Lisp_Object old
= selected_frame
;
9574 selected_frame
= frame
;
9576 for (tail
= XFRAME (frame
)->param_alist
; CONSP (tail
); tail
= XCDR (tail
))
9577 if (CONSP (XCAR (tail
))
9578 && (sym
= XCAR (XCAR (tail
)),
9580 && (sym
= indirect_variable (sym
),
9581 val
= SYMBOL_VALUE (sym
),
9582 (BUFFER_LOCAL_VALUEP (val
)
9583 || SOME_BUFFER_LOCAL_VALUEP (val
)))
9584 && XBUFFER_LOCAL_VALUE (val
)->check_frame
)
9585 Fsymbol_value (sym
);
9587 for (tail
= XFRAME (old
)->param_alist
; CONSP (tail
); tail
= XCDR (tail
))
9588 if (CONSP (XCAR (tail
))
9589 && (sym
= XCAR (XCAR (tail
)),
9591 && (sym
= indirect_variable (sym
),
9592 val
= SYMBOL_VALUE (sym
),
9593 (BUFFER_LOCAL_VALUEP (val
)
9594 || SOME_BUFFER_LOCAL_VALUEP (val
)))
9595 && XBUFFER_LOCAL_VALUE (val
)->check_frame
)
9596 Fsymbol_value (sym
);
9600 #define STOP_POLLING \
9601 do { if (! polling_stopped_here) stop_polling (); \
9602 polling_stopped_here = 1; } while (0)
9604 #define RESUME_POLLING \
9605 do { if (polling_stopped_here) start_polling (); \
9606 polling_stopped_here = 0; } while (0)
9609 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
9610 response to any user action; therefore, we should preserve the echo
9611 area. (Actually, our caller does that job.) Perhaps in the future
9612 avoid recentering windows if it is not necessary; currently that
9613 causes some problems. */
9616 redisplay_internal (preserve_echo_area
)
9617 int preserve_echo_area
;
9619 struct window
*w
= XWINDOW (selected_window
);
9620 struct frame
*f
= XFRAME (w
->frame
);
9622 int must_finish
= 0;
9623 struct text_pos tlbufpos
, tlendpos
;
9624 int number_of_visible_frames
;
9626 struct frame
*sf
= SELECTED_FRAME ();
9627 int polling_stopped_here
= 0;
9629 /* Non-zero means redisplay has to consider all windows on all
9630 frames. Zero means, only selected_window is considered. */
9631 int consider_all_windows_p
;
9633 TRACE ((stderr
, "redisplay_internal %d\n", redisplaying_p
));
9635 /* No redisplay if running in batch mode or frame is not yet fully
9636 initialized, or redisplay is explicitly turned off by setting
9637 Vinhibit_redisplay. */
9639 || !NILP (Vinhibit_redisplay
)
9640 || !f
->glyphs_initialized_p
)
9643 /* The flag redisplay_performed_directly_p is set by
9644 direct_output_for_insert when it already did the whole screen
9645 update necessary. */
9646 if (redisplay_performed_directly_p
)
9648 redisplay_performed_directly_p
= 0;
9649 if (!hscroll_windows (selected_window
))
9653 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
9654 if (popup_activated ())
9658 /* I don't think this happens but let's be paranoid. */
9662 /* Record a function that resets redisplaying_p to its old value
9663 when we leave this function. */
9664 count
= SPECPDL_INDEX ();
9665 record_unwind_protect (unwind_redisplay
,
9666 Fcons (make_number (redisplaying_p
), selected_frame
));
9668 specbind (Qinhibit_free_realized_faces
, Qnil
);
9672 reconsider_clip_changes (w
, current_buffer
);
9674 /* If new fonts have been loaded that make a glyph matrix adjustment
9675 necessary, do it. */
9676 if (fonts_changed_p
)
9678 adjust_glyphs (NULL
);
9679 ++windows_or_buffers_changed
;
9680 fonts_changed_p
= 0;
9683 /* If face_change_count is non-zero, init_iterator will free all
9684 realized faces, which includes the faces referenced from current
9685 matrices. So, we can't reuse current matrices in this case. */
9686 if (face_change_count
)
9687 ++windows_or_buffers_changed
;
9689 if (FRAME_TERMCAP_P (sf
)
9690 && FRAME_TTY (sf
)->previous_terminal_frame
!= sf
)
9692 /* Since frames on a single ASCII terminal share the same
9693 display area, displaying a different frame means redisplay
9695 windows_or_buffers_changed
++;
9696 SET_FRAME_GARBAGED (sf
);
9697 FRAME_TTY (sf
)->previous_terminal_frame
= sf
;
9700 /* Set the visible flags for all frames. Do this before checking
9701 for resized or garbaged frames; they want to know if their frames
9702 are visible. See the comment in frame.h for
9703 FRAME_SAMPLE_VISIBILITY. */
9705 Lisp_Object tail
, frame
;
9707 number_of_visible_frames
= 0;
9709 FOR_EACH_FRAME (tail
, frame
)
9711 struct frame
*f
= XFRAME (frame
);
9713 FRAME_SAMPLE_VISIBILITY (f
);
9714 if (FRAME_VISIBLE_P (f
))
9715 ++number_of_visible_frames
;
9716 clear_desired_matrices (f
);
9721 /* Notice any pending interrupt request to change frame size. */
9722 do_pending_window_change (1);
9724 /* Clear frames marked as garbaged. */
9726 clear_garbaged_frames ();
9728 /* Build menubar and tool-bar items. */
9729 prepare_menu_bars ();
9731 if (windows_or_buffers_changed
)
9732 update_mode_lines
++;
9734 /* Detect case that we need to write or remove a star in the mode line. */
9735 if ((SAVE_MODIFF
< MODIFF
) != !NILP (w
->last_had_star
))
9737 w
->update_mode_line
= Qt
;
9738 if (buffer_shared
> 1)
9739 update_mode_lines
++;
9742 /* If %c is in the mode line, update it if needed. */
9743 if (!NILP (w
->column_number_displayed
)
9744 /* This alternative quickly identifies a common case
9745 where no change is needed. */
9746 && !(PT
== XFASTINT (w
->last_point
)
9747 && XFASTINT (w
->last_modified
) >= MODIFF
9748 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
)
9749 && (XFASTINT (w
->column_number_displayed
)
9750 != (int) current_column ())) /* iftc */
9751 w
->update_mode_line
= Qt
;
9753 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w
->frame
)) = -1;
9755 /* The variable buffer_shared is set in redisplay_window and
9756 indicates that we redisplay a buffer in different windows. See
9758 consider_all_windows_p
= (update_mode_lines
|| buffer_shared
> 1
9759 || cursor_type_changed
);
9761 /* If specs for an arrow have changed, do thorough redisplay
9762 to ensure we remove any arrow that should no longer exist. */
9763 if (overlay_arrows_changed_p ())
9764 consider_all_windows_p
= windows_or_buffers_changed
= 1;
9766 /* Normally the message* functions will have already displayed and
9767 updated the echo area, but the frame may have been trashed, or
9768 the update may have been preempted, so display the echo area
9769 again here. Checking message_cleared_p captures the case that
9770 the echo area should be cleared. */
9771 if ((!NILP (echo_area_buffer
[0]) && !display_last_displayed_message_p
)
9772 || (!NILP (echo_area_buffer
[1]) && display_last_displayed_message_p
)
9773 || (message_cleared_p
9774 && minibuf_level
== 0
9775 /* If the mini-window is currently selected, this means the
9776 echo-area doesn't show through. */
9777 && !MINI_WINDOW_P (XWINDOW (selected_window
))))
9779 int window_height_changed_p
= echo_area_display (0);
9782 /* If we don't display the current message, don't clear the
9783 message_cleared_p flag, because, if we did, we wouldn't clear
9784 the echo area in the next redisplay which doesn't preserve
9786 if (!display_last_displayed_message_p
)
9787 message_cleared_p
= 0;
9789 if (fonts_changed_p
)
9791 else if (window_height_changed_p
)
9793 consider_all_windows_p
= 1;
9794 ++update_mode_lines
;
9795 ++windows_or_buffers_changed
;
9797 /* If window configuration was changed, frames may have been
9798 marked garbaged. Clear them or we will experience
9799 surprises wrt scrolling. */
9801 clear_garbaged_frames ();
9804 else if (EQ (selected_window
, minibuf_window
)
9805 && (current_buffer
->clip_changed
9806 || XFASTINT (w
->last_modified
) < MODIFF
9807 || XFASTINT (w
->last_overlay_modified
) < OVERLAY_MODIFF
)
9808 && resize_mini_window (w
, 0))
9810 /* Resized active mini-window to fit the size of what it is
9811 showing if its contents might have changed. */
9813 consider_all_windows_p
= 1;
9814 ++windows_or_buffers_changed
;
9815 ++update_mode_lines
;
9817 /* If window configuration was changed, frames may have been
9818 marked garbaged. Clear them or we will experience
9819 surprises wrt scrolling. */
9821 clear_garbaged_frames ();
9825 /* If showing the region, and mark has changed, we must redisplay
9826 the whole window. The assignment to this_line_start_pos prevents
9827 the optimization directly below this if-statement. */
9828 if (((!NILP (Vtransient_mark_mode
)
9829 && !NILP (XBUFFER (w
->buffer
)->mark_active
))
9830 != !NILP (w
->region_showing
))
9831 || (!NILP (w
->region_showing
)
9832 && !EQ (w
->region_showing
,
9833 Fmarker_position (XBUFFER (w
->buffer
)->mark
))))
9834 CHARPOS (this_line_start_pos
) = 0;
9836 /* Optimize the case that only the line containing the cursor in the
9837 selected window has changed. Variables starting with this_ are
9838 set in display_line and record information about the line
9839 containing the cursor. */
9840 tlbufpos
= this_line_start_pos
;
9841 tlendpos
= this_line_end_pos
;
9842 if (!consider_all_windows_p
9843 && CHARPOS (tlbufpos
) > 0
9844 && NILP (w
->update_mode_line
)
9845 && !current_buffer
->clip_changed
9846 && !current_buffer
->prevent_redisplay_optimizations_p
9847 && FRAME_VISIBLE_P (XFRAME (w
->frame
))
9848 && !FRAME_OBSCURED_P (XFRAME (w
->frame
))
9849 /* Make sure recorded data applies to current buffer, etc. */
9850 && this_line_buffer
== current_buffer
9851 && current_buffer
== XBUFFER (w
->buffer
)
9852 && NILP (w
->force_start
)
9853 && NILP (w
->optional_new_start
)
9854 /* Point must be on the line that we have info recorded about. */
9855 && PT
>= CHARPOS (tlbufpos
)
9856 && PT
<= Z
- CHARPOS (tlendpos
)
9857 /* All text outside that line, including its final newline,
9858 must be unchanged */
9859 && text_outside_line_unchanged_p (w
, CHARPOS (tlbufpos
),
9860 CHARPOS (tlendpos
)))
9862 if (CHARPOS (tlbufpos
) > BEGV
9863 && FETCH_BYTE (BYTEPOS (tlbufpos
) - 1) != '\n'
9864 && (CHARPOS (tlbufpos
) == ZV
9865 || FETCH_BYTE (BYTEPOS (tlbufpos
)) == '\n'))
9866 /* Former continuation line has disappeared by becoming empty */
9868 else if (XFASTINT (w
->last_modified
) < MODIFF
9869 || XFASTINT (w
->last_overlay_modified
) < OVERLAY_MODIFF
9870 || MINI_WINDOW_P (w
))
9872 /* We have to handle the case of continuation around a
9873 wide-column character (See the comment in indent.c around
9876 For instance, in the following case:
9878 -------- Insert --------
9879 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
9880 J_I_ ==> J_I_ `^^' are cursors.
9884 As we have to redraw the line above, we should goto cancel. */
9887 int line_height_before
= this_line_pixel_height
;
9889 /* Note that start_display will handle the case that the
9890 line starting at tlbufpos is a continuation lines. */
9891 start_display (&it
, w
, tlbufpos
);
9893 /* Implementation note: It this still necessary? */
9894 if (it
.current_x
!= this_line_start_x
)
9897 TRACE ((stderr
, "trying display optimization 1\n"));
9898 w
->cursor
.vpos
= -1;
9899 overlay_arrow_seen
= 0;
9900 it
.vpos
= this_line_vpos
;
9901 it
.current_y
= this_line_y
;
9902 it
.glyph_row
= MATRIX_ROW (w
->desired_matrix
, this_line_vpos
);
9905 /* If line contains point, is not continued,
9906 and ends at same distance from eob as before, we win */
9907 if (w
->cursor
.vpos
>= 0
9908 /* Line is not continued, otherwise this_line_start_pos
9909 would have been set to 0 in display_line. */
9910 && CHARPOS (this_line_start_pos
)
9911 /* Line ends as before. */
9912 && CHARPOS (this_line_end_pos
) == CHARPOS (tlendpos
)
9913 /* Line has same height as before. Otherwise other lines
9914 would have to be shifted up or down. */
9915 && this_line_pixel_height
== line_height_before
)
9917 /* If this is not the window's last line, we must adjust
9918 the charstarts of the lines below. */
9919 if (it
.current_y
< it
.last_visible_y
)
9921 struct glyph_row
*row
9922 = MATRIX_ROW (w
->current_matrix
, this_line_vpos
+ 1);
9923 int delta
, delta_bytes
;
9925 if (Z
- CHARPOS (tlendpos
) == ZV
)
9927 /* This line ends at end of (accessible part of)
9928 buffer. There is no newline to count. */
9930 - CHARPOS (tlendpos
)
9931 - MATRIX_ROW_START_CHARPOS (row
));
9932 delta_bytes
= (Z_BYTE
9933 - BYTEPOS (tlendpos
)
9934 - MATRIX_ROW_START_BYTEPOS (row
));
9938 /* This line ends in a newline. Must take
9939 account of the newline and the rest of the
9940 text that follows. */
9942 - CHARPOS (tlendpos
)
9943 - MATRIX_ROW_START_CHARPOS (row
));
9944 delta_bytes
= (Z_BYTE
9945 - BYTEPOS (tlendpos
)
9946 - MATRIX_ROW_START_BYTEPOS (row
));
9949 increment_matrix_positions (w
->current_matrix
,
9951 w
->current_matrix
->nrows
,
9952 delta
, delta_bytes
);
9955 /* If this row displays text now but previously didn't,
9956 or vice versa, w->window_end_vpos may have to be
9958 if ((it
.glyph_row
- 1)->displays_text_p
)
9960 if (XFASTINT (w
->window_end_vpos
) < this_line_vpos
)
9961 XSETINT (w
->window_end_vpos
, this_line_vpos
);
9963 else if (XFASTINT (w
->window_end_vpos
) == this_line_vpos
9964 && this_line_vpos
> 0)
9965 XSETINT (w
->window_end_vpos
, this_line_vpos
- 1);
9966 w
->window_end_valid
= Qnil
;
9968 /* Update hint: No need to try to scroll in update_window. */
9969 w
->desired_matrix
->no_scrolling_p
= 1;
9972 *w
->desired_matrix
->method
= 0;
9973 debug_method_add (w
, "optimization 1");
9975 #ifdef HAVE_WINDOW_SYSTEM
9976 update_window_fringes (w
, 0);
9983 else if (/* Cursor position hasn't changed. */
9984 PT
== XFASTINT (w
->last_point
)
9985 /* Make sure the cursor was last displayed
9986 in this window. Otherwise we have to reposition it. */
9987 && 0 <= w
->cursor
.vpos
9988 && WINDOW_TOTAL_LINES (w
) > w
->cursor
.vpos
)
9992 do_pending_window_change (1);
9994 /* We used to always goto end_of_redisplay here, but this
9995 isn't enough if we have a blinking cursor. */
9996 if (w
->cursor_off_p
== w
->last_cursor_off_p
)
9997 goto end_of_redisplay
;
10001 /* If highlighting the region, or if the cursor is in the echo area,
10002 then we can't just move the cursor. */
10003 else if (! (!NILP (Vtransient_mark_mode
)
10004 && !NILP (current_buffer
->mark_active
))
10005 && (EQ (selected_window
, current_buffer
->last_selected_window
)
10006 || highlight_nonselected_windows
)
10007 && NILP (w
->region_showing
)
10008 && NILP (Vshow_trailing_whitespace
)
10009 && !cursor_in_echo_area
)
10012 struct glyph_row
*row
;
10014 /* Skip from tlbufpos to PT and see where it is. Note that
10015 PT may be in invisible text. If so, we will end at the
10016 next visible position. */
10017 init_iterator (&it
, w
, CHARPOS (tlbufpos
), BYTEPOS (tlbufpos
),
10018 NULL
, DEFAULT_FACE_ID
);
10019 it
.current_x
= this_line_start_x
;
10020 it
.current_y
= this_line_y
;
10021 it
.vpos
= this_line_vpos
;
10023 /* The call to move_it_to stops in front of PT, but
10024 moves over before-strings. */
10025 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
10027 if (it
.vpos
== this_line_vpos
10028 && (row
= MATRIX_ROW (w
->current_matrix
, this_line_vpos
),
10031 xassert (this_line_vpos
== it
.vpos
);
10032 xassert (this_line_y
== it
.current_y
);
10033 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
10035 *w
->desired_matrix
->method
= 0;
10036 debug_method_add (w
, "optimization 3");
10045 /* Text changed drastically or point moved off of line. */
10046 SET_MATRIX_ROW_ENABLED_P (w
->desired_matrix
, this_line_vpos
, 0);
10049 CHARPOS (this_line_start_pos
) = 0;
10050 consider_all_windows_p
|= buffer_shared
> 1;
10051 ++clear_face_cache_count
;
10054 /* Build desired matrices, and update the display. If
10055 consider_all_windows_p is non-zero, do it for all windows on all
10056 frames. Otherwise do it for selected_window, only. */
10058 if (consider_all_windows_p
)
10060 Lisp_Object tail
, frame
;
10061 int i
, n
= 0, size
= 50;
10062 struct frame
**updated
10063 = (struct frame
**) alloca (size
* sizeof *updated
);
10065 /* Clear the face cache eventually. */
10066 if (clear_face_cache_count
> CLEAR_FACE_CACHE_COUNT
)
10068 clear_face_cache (0);
10069 clear_face_cache_count
= 0;
10072 /* Recompute # windows showing selected buffer. This will be
10073 incremented each time such a window is displayed. */
10076 FOR_EACH_FRAME (tail
, frame
)
10078 struct frame
*f
= XFRAME (frame
);
10080 if (FRAME_WINDOW_P (f
) || FRAME_TERMCAP_P (f
) || f
== sf
)
10082 if (! EQ (frame
, selected_frame
))
10083 /* Select the frame, for the sake of frame-local
10085 select_frame_for_redisplay (frame
);
10087 #ifdef HAVE_WINDOW_SYSTEM
10088 if (clear_face_cache_count
% 50 == 0
10089 && FRAME_WINDOW_P (f
))
10090 clear_image_cache (f
, 0);
10091 #endif /* HAVE_WINDOW_SYSTEM */
10093 /* Mark all the scroll bars to be removed; we'll redeem
10094 the ones we want when we redisplay their windows. */
10095 if (FRAME_DISPLAY (f
)->condemn_scroll_bars_hook
)
10096 FRAME_DISPLAY (f
)->condemn_scroll_bars_hook (f
);
10098 if (FRAME_VISIBLE_P (f
) && !FRAME_OBSCURED_P (f
))
10099 redisplay_windows (FRAME_ROOT_WINDOW (f
));
10101 /* Any scroll bars which redisplay_windows should have
10102 nuked should now go away. */
10103 if (FRAME_DISPLAY (f
)->judge_scroll_bars_hook
)
10104 FRAME_DISPLAY (f
)->judge_scroll_bars_hook (f
);
10106 /* If fonts changed, display again. */
10107 /* ??? rms: I suspect it is a mistake to jump all the way
10108 back to retry here. It should just retry this frame. */
10109 if (fonts_changed_p
)
10112 if (FRAME_VISIBLE_P (f
) && !FRAME_OBSCURED_P (f
))
10114 /* See if we have to hscroll. */
10115 if (hscroll_windows (f
->root_window
))
10118 /* Prevent various kinds of signals during display
10119 update. stdio is not robust about handling
10120 signals, which can cause an apparent I/O
10122 if (interrupt_input
)
10123 unrequest_sigio ();
10126 /* Update the display. */
10127 set_window_update_flags (XWINDOW (f
->root_window
), 1);
10128 pause
|= update_frame (f
, 0, 0);
10129 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
10136 int nbytes
= size
* sizeof *updated
;
10137 struct frame
**p
= (struct frame
**) alloca (2 * nbytes
);
10138 bcopy (updated
, p
, nbytes
);
10149 /* Do the mark_window_display_accurate after all windows have
10150 been redisplayed because this call resets flags in buffers
10151 which are needed for proper redisplay. */
10152 for (i
= 0; i
< n
; ++i
)
10154 struct frame
*f
= updated
[i
];
10155 mark_window_display_accurate (f
->root_window
, 1);
10156 if (FRAME_DISPLAY (f
)->frame_up_to_date_hook
)
10157 FRAME_DISPLAY (f
)->frame_up_to_date_hook (f
);
10161 else if (FRAME_VISIBLE_P (sf
) && !FRAME_OBSCURED_P (sf
))
10163 Lisp_Object mini_window
;
10164 struct frame
*mini_frame
;
10166 displayed_buffer
= XBUFFER (XWINDOW (selected_window
)->buffer
);
10167 /* Use list_of_error, not Qerror, so that
10168 we catch only errors and don't run the debugger. */
10169 internal_condition_case_1 (redisplay_window_1
, selected_window
,
10171 redisplay_window_error
);
10173 /* Compare desired and current matrices, perform output. */
10176 /* If fonts changed, display again. */
10177 if (fonts_changed_p
)
10180 /* Prevent various kinds of signals during display update.
10181 stdio is not robust about handling signals,
10182 which can cause an apparent I/O error. */
10183 if (interrupt_input
)
10184 unrequest_sigio ();
10187 if (FRAME_VISIBLE_P (sf
) && !FRAME_OBSCURED_P (sf
))
10189 if (hscroll_windows (selected_window
))
10192 XWINDOW (selected_window
)->must_be_updated_p
= 1;
10193 pause
= update_frame (sf
, 0, 0);
10196 /* We may have called echo_area_display at the top of this
10197 function. If the echo area is on another frame, that may
10198 have put text on a frame other than the selected one, so the
10199 above call to update_frame would not have caught it. Catch
10201 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
10202 mini_frame
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
10204 if (mini_frame
!= sf
&& FRAME_WINDOW_P (mini_frame
))
10206 XWINDOW (mini_window
)->must_be_updated_p
= 1;
10207 pause
|= update_frame (mini_frame
, 0, 0);
10208 if (!pause
&& hscroll_windows (mini_window
))
10213 /* If display was paused because of pending input, make sure we do a
10214 thorough update the next time. */
10217 /* Prevent the optimization at the beginning of
10218 redisplay_internal that tries a single-line update of the
10219 line containing the cursor in the selected window. */
10220 CHARPOS (this_line_start_pos
) = 0;
10222 /* Let the overlay arrow be updated the next time. */
10223 update_overlay_arrows (0);
10225 /* If we pause after scrolling, some rows in the current
10226 matrices of some windows are not valid. */
10227 if (!WINDOW_FULL_WIDTH_P (w
)
10228 && !FRAME_WINDOW_P (XFRAME (w
->frame
)))
10229 update_mode_lines
= 1;
10233 if (!consider_all_windows_p
)
10235 /* This has already been done above if
10236 consider_all_windows_p is set. */
10237 mark_window_display_accurate_1 (w
, 1);
10239 /* Say overlay arrows are up to date. */
10240 update_overlay_arrows (1);
10242 if (FRAME_DISPLAY (sf
)->frame_up_to_date_hook
!= 0)
10243 FRAME_DISPLAY (sf
)->frame_up_to_date_hook (sf
);
10246 update_mode_lines
= 0;
10247 windows_or_buffers_changed
= 0;
10248 cursor_type_changed
= 0;
10251 /* Start SIGIO interrupts coming again. Having them off during the
10252 code above makes it less likely one will discard output, but not
10253 impossible, since there might be stuff in the system buffer here.
10254 But it is much hairier to try to do anything about that. */
10255 if (interrupt_input
)
10259 /* If a frame has become visible which was not before, redisplay
10260 again, so that we display it. Expose events for such a frame
10261 (which it gets when becoming visible) don't call the parts of
10262 redisplay constructing glyphs, so simply exposing a frame won't
10263 display anything in this case. So, we have to display these
10264 frames here explicitly. */
10267 Lisp_Object tail
, frame
;
10270 FOR_EACH_FRAME (tail
, frame
)
10272 int this_is_visible
= 0;
10274 if (XFRAME (frame
)->visible
)
10275 this_is_visible
= 1;
10276 FRAME_SAMPLE_VISIBILITY (XFRAME (frame
));
10277 if (XFRAME (frame
)->visible
)
10278 this_is_visible
= 1;
10280 if (this_is_visible
)
10284 if (new_count
!= number_of_visible_frames
)
10285 windows_or_buffers_changed
++;
10288 /* Change frame size now if a change is pending. */
10289 do_pending_window_change (1);
10291 /* If we just did a pending size change, or have additional
10292 visible frames, redisplay again. */
10293 if (windows_or_buffers_changed
&& !pause
)
10297 unbind_to (count
, Qnil
);
10302 /* Redisplay, but leave alone any recent echo area message unless
10303 another message has been requested in its place.
10305 This is useful in situations where you need to redisplay but no
10306 user action has occurred, making it inappropriate for the message
10307 area to be cleared. See tracking_off and
10308 wait_reading_process_input for examples of these situations.
10310 FROM_WHERE is an integer saying from where this function was
10311 called. This is useful for debugging. */
10314 redisplay_preserve_echo_area (from_where
)
10317 TRACE ((stderr
, "redisplay_preserve_echo_area (%d)\n", from_where
));
10319 if (!NILP (echo_area_buffer
[1]))
10321 /* We have a previously displayed message, but no current
10322 message. Redisplay the previous message. */
10323 display_last_displayed_message_p
= 1;
10324 redisplay_internal (1);
10325 display_last_displayed_message_p
= 0;
10328 redisplay_internal (1);
10332 /* Function registered with record_unwind_protect in
10333 redisplay_internal. Reset redisplaying_p to the value it had
10334 before redisplay_internal was called, and clear
10335 prevent_freeing_realized_faces_p. It also selects the previously
10339 unwind_redisplay (val
)
10342 Lisp_Object old_redisplaying_p
, old_frame
;
10344 old_redisplaying_p
= XCAR (val
);
10345 redisplaying_p
= XFASTINT (old_redisplaying_p
);
10346 old_frame
= XCDR (val
);
10347 if (! EQ (old_frame
, selected_frame
))
10348 select_frame_for_redisplay (old_frame
);
10353 /* Mark the display of window W as accurate or inaccurate. If
10354 ACCURATE_P is non-zero mark display of W as accurate. If
10355 ACCURATE_P is zero, arrange for W to be redisplayed the next time
10356 redisplay_internal is called. */
10359 mark_window_display_accurate_1 (w
, accurate_p
)
10363 if (BUFFERP (w
->buffer
))
10365 struct buffer
*b
= XBUFFER (w
->buffer
);
10368 = make_number (accurate_p
? BUF_MODIFF (b
) : 0);
10369 w
->last_overlay_modified
10370 = make_number (accurate_p
? BUF_OVERLAY_MODIFF (b
) : 0);
10372 = BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
) ? Qt
: Qnil
;
10376 b
->clip_changed
= 0;
10377 b
->prevent_redisplay_optimizations_p
= 0;
10379 BUF_UNCHANGED_MODIFIED (b
) = BUF_MODIFF (b
);
10380 BUF_OVERLAY_UNCHANGED_MODIFIED (b
) = BUF_OVERLAY_MODIFF (b
);
10381 BUF_BEG_UNCHANGED (b
) = BUF_GPT (b
) - BUF_BEG (b
);
10382 BUF_END_UNCHANGED (b
) = BUF_Z (b
) - BUF_GPT (b
);
10384 w
->current_matrix
->buffer
= b
;
10385 w
->current_matrix
->begv
= BUF_BEGV (b
);
10386 w
->current_matrix
->zv
= BUF_ZV (b
);
10388 w
->last_cursor
= w
->cursor
;
10389 w
->last_cursor_off_p
= w
->cursor_off_p
;
10391 if (w
== XWINDOW (selected_window
))
10392 w
->last_point
= make_number (BUF_PT (b
));
10394 w
->last_point
= make_number (XMARKER (w
->pointm
)->charpos
);
10400 w
->window_end_valid
= w
->buffer
;
10401 #if 0 /* This is incorrect with variable-height lines. */
10402 xassert (XINT (w
->window_end_vpos
)
10403 < (WINDOW_TOTAL_LINES (w
)
10404 - (WINDOW_WANTS_MODELINE_P (w
) ? 1 : 0)));
10406 w
->update_mode_line
= Qnil
;
10411 /* Mark the display of windows in the window tree rooted at WINDOW as
10412 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
10413 windows as accurate. If ACCURATE_P is zero, arrange for windows to
10414 be redisplayed the next time redisplay_internal is called. */
10417 mark_window_display_accurate (window
, accurate_p
)
10418 Lisp_Object window
;
10423 for (; !NILP (window
); window
= w
->next
)
10425 w
= XWINDOW (window
);
10426 mark_window_display_accurate_1 (w
, accurate_p
);
10428 if (!NILP (w
->vchild
))
10429 mark_window_display_accurate (w
->vchild
, accurate_p
);
10430 if (!NILP (w
->hchild
))
10431 mark_window_display_accurate (w
->hchild
, accurate_p
);
10436 update_overlay_arrows (1);
10440 /* Force a thorough redisplay the next time by setting
10441 last_arrow_position and last_arrow_string to t, which is
10442 unequal to any useful value of Voverlay_arrow_... */
10443 update_overlay_arrows (-1);
10448 /* Return value in display table DP (Lisp_Char_Table *) for character
10449 C. Since a display table doesn't have any parent, we don't have to
10450 follow parent. Do not call this function directly but use the
10451 macro DISP_CHAR_VECTOR. */
10454 disp_char_vector (dp
, c
)
10455 struct Lisp_Char_Table
*dp
;
10461 if (SINGLE_BYTE_CHAR_P (c
))
10462 return (dp
->contents
[c
]);
10464 SPLIT_CHAR (c
, code
[0], code
[1], code
[2]);
10467 else if (code
[2] < 32)
10470 /* Here, the possible range of code[0] (== charset ID) is
10471 128..max_charset. Since the top level char table contains data
10472 for multibyte characters after 256th element, we must increment
10473 code[0] by 128 to get a correct index. */
10475 code
[3] = -1; /* anchor */
10477 for (i
= 0; code
[i
] >= 0; i
++, dp
= XCHAR_TABLE (val
))
10479 val
= dp
->contents
[code
[i
]];
10480 if (!SUB_CHAR_TABLE_P (val
))
10481 return (NILP (val
) ? dp
->defalt
: val
);
10484 /* Here, val is a sub char table. We return the default value of
10486 return (dp
->defalt
);
10491 /***********************************************************************
10493 ***********************************************************************/
10495 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
10498 redisplay_windows (window
)
10499 Lisp_Object window
;
10501 while (!NILP (window
))
10503 struct window
*w
= XWINDOW (window
);
10505 if (!NILP (w
->hchild
))
10506 redisplay_windows (w
->hchild
);
10507 else if (!NILP (w
->vchild
))
10508 redisplay_windows (w
->vchild
);
10511 displayed_buffer
= XBUFFER (w
->buffer
);
10512 /* Use list_of_error, not Qerror, so that
10513 we catch only errors and don't run the debugger. */
10514 internal_condition_case_1 (redisplay_window_0
, window
,
10516 redisplay_window_error
);
10524 redisplay_window_error ()
10526 displayed_buffer
->display_error_modiff
= BUF_MODIFF (displayed_buffer
);
10531 redisplay_window_0 (window
)
10532 Lisp_Object window
;
10534 if (displayed_buffer
->display_error_modiff
< BUF_MODIFF (displayed_buffer
))
10535 redisplay_window (window
, 0);
10540 redisplay_window_1 (window
)
10541 Lisp_Object window
;
10543 if (displayed_buffer
->display_error_modiff
< BUF_MODIFF (displayed_buffer
))
10544 redisplay_window (window
, 1);
10549 /* Increment GLYPH until it reaches END or CONDITION fails while
10550 adding (GLYPH)->pixel_width to X. */
10552 #define SKIP_GLYPHS(glyph, end, x, condition) \
10555 (x) += (glyph)->pixel_width; \
10558 while ((glyph) < (end) && (condition))
10561 /* Set cursor position of W. PT is assumed to be displayed in ROW.
10562 DELTA is the number of bytes by which positions recorded in ROW
10563 differ from current buffer positions. */
10566 set_cursor_from_row (w
, row
, matrix
, delta
, delta_bytes
, dy
, dvpos
)
10568 struct glyph_row
*row
;
10569 struct glyph_matrix
*matrix
;
10570 int delta
, delta_bytes
, dy
, dvpos
;
10572 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
10573 struct glyph
*end
= glyph
+ row
->used
[TEXT_AREA
];
10574 /* The first glyph that starts a sequence of glyphs from string. */
10575 struct glyph
*string_start
;
10576 /* The X coordinate of string_start. */
10577 int string_start_x
;
10578 /* The last known character position. */
10579 int last_pos
= MATRIX_ROW_START_CHARPOS (row
) + delta
;
10580 /* The last known character position before string_start. */
10581 int string_before_pos
;
10583 int pt_old
= PT
- delta
;
10585 /* Skip over glyphs not having an object at the start of the row.
10586 These are special glyphs like truncation marks on terminal
10588 if (row
->displays_text_p
)
10590 && INTEGERP (glyph
->object
)
10591 && glyph
->charpos
< 0)
10593 x
+= glyph
->pixel_width
;
10597 string_start
= NULL
;
10599 && !INTEGERP (glyph
->object
)
10600 && (!BUFFERP (glyph
->object
)
10601 || (last_pos
= glyph
->charpos
) < pt_old
))
10603 if (! STRINGP (glyph
->object
))
10605 string_start
= NULL
;
10606 x
+= glyph
->pixel_width
;
10611 string_before_pos
= last_pos
;
10612 string_start
= glyph
;
10613 string_start_x
= x
;
10614 /* Skip all glyphs from string. */
10615 SKIP_GLYPHS (glyph
, end
, x
, STRINGP (glyph
->object
));
10620 && (glyph
== end
|| !BUFFERP (glyph
->object
) || last_pos
> pt_old
))
10622 /* We may have skipped over point because the previous glyphs
10623 are from string. As there's no easy way to know the
10624 character position of the current glyph, find the correct
10625 glyph on point by scanning from string_start again. */
10627 Lisp_Object string
;
10630 limit
= make_number (pt_old
+ 1);
10632 glyph
= string_start
;
10633 x
= string_start_x
;
10634 string
= glyph
->object
;
10635 pos
= string_buffer_position (w
, string
, string_before_pos
);
10636 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
10637 because we always put cursor after overlay strings. */
10638 while (pos
== 0 && glyph
< end
)
10640 string
= glyph
->object
;
10641 SKIP_GLYPHS (glyph
, end
, x
, EQ (glyph
->object
, string
));
10643 pos
= string_buffer_position (w
, glyph
->object
, string_before_pos
);
10646 while (glyph
< end
)
10648 pos
= XINT (Fnext_single_char_property_change
10649 (make_number (pos
), Qdisplay
, Qnil
, limit
));
10652 /* Skip glyphs from the same string. */
10653 string
= glyph
->object
;
10654 SKIP_GLYPHS (glyph
, end
, x
, EQ (glyph
->object
, string
));
10655 /* Skip glyphs from an overlay. */
10657 && ! string_buffer_position (w
, glyph
->object
, pos
))
10659 string
= glyph
->object
;
10660 SKIP_GLYPHS (glyph
, end
, x
, EQ (glyph
->object
, string
));
10665 w
->cursor
.hpos
= glyph
- row
->glyphs
[TEXT_AREA
];
10667 w
->cursor
.vpos
= MATRIX_ROW_VPOS (row
, matrix
) + dvpos
;
10668 w
->cursor
.y
= row
->y
+ dy
;
10670 if (w
== XWINDOW (selected_window
))
10672 if (!row
->continued_p
10673 && !MATRIX_ROW_CONTINUATION_LINE_P (row
)
10676 this_line_buffer
= XBUFFER (w
->buffer
);
10678 CHARPOS (this_line_start_pos
)
10679 = MATRIX_ROW_START_CHARPOS (row
) + delta
;
10680 BYTEPOS (this_line_start_pos
)
10681 = MATRIX_ROW_START_BYTEPOS (row
) + delta_bytes
;
10683 CHARPOS (this_line_end_pos
)
10684 = Z
- (MATRIX_ROW_END_CHARPOS (row
) + delta
);
10685 BYTEPOS (this_line_end_pos
)
10686 = Z_BYTE
- (MATRIX_ROW_END_BYTEPOS (row
) + delta_bytes
);
10688 this_line_y
= w
->cursor
.y
;
10689 this_line_pixel_height
= row
->height
;
10690 this_line_vpos
= w
->cursor
.vpos
;
10691 this_line_start_x
= row
->x
;
10694 CHARPOS (this_line_start_pos
) = 0;
10699 /* Run window scroll functions, if any, for WINDOW with new window
10700 start STARTP. Sets the window start of WINDOW to that position.
10702 We assume that the window's buffer is really current. */
10704 static INLINE
struct text_pos
10705 run_window_scroll_functions (window
, startp
)
10706 Lisp_Object window
;
10707 struct text_pos startp
;
10709 struct window
*w
= XWINDOW (window
);
10710 SET_MARKER_FROM_TEXT_POS (w
->start
, startp
);
10712 if (current_buffer
!= XBUFFER (w
->buffer
))
10715 if (!NILP (Vwindow_scroll_functions
))
10717 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
10718 make_number (CHARPOS (startp
)));
10719 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
10720 /* In case the hook functions switch buffers. */
10721 if (current_buffer
!= XBUFFER (w
->buffer
))
10722 set_buffer_internal_1 (XBUFFER (w
->buffer
));
10729 /* Make sure the line containing the cursor is fully visible.
10730 A value of 1 means there is nothing to be done.
10731 (Either the line is fully visible, or it cannot be made so,
10732 or we cannot tell.)
10734 If FORCE_P is non-zero, return 0 even if partial visible cursor row
10735 is higher than window.
10737 A value of 0 means the caller should do scrolling
10738 as if point had gone off the screen. */
10741 make_cursor_line_fully_visible (w
, force_p
)
10745 struct glyph_matrix
*matrix
;
10746 struct glyph_row
*row
;
10749 /* It's not always possible to find the cursor, e.g, when a window
10750 is full of overlay strings. Don't do anything in that case. */
10751 if (w
->cursor
.vpos
< 0)
10754 matrix
= w
->desired_matrix
;
10755 row
= MATRIX_ROW (matrix
, w
->cursor
.vpos
);
10757 /* If the cursor row is not partially visible, there's nothing to do. */
10758 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (row
))
10764 /* If the row the cursor is in is taller than the window's height,
10765 it's not clear what to do, so do nothing. */
10766 window_height
= window_box_height (w
);
10767 if (row
->height
>= window_height
)
10773 /* This code used to try to scroll the window just enough to make
10774 the line visible. It returned 0 to say that the caller should
10775 allocate larger glyph matrices. */
10777 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w
, row
))
10779 int dy
= row
->height
- row
->visible_height
;
10782 shift_glyph_matrix (w
, matrix
, 0, matrix
->nrows
, dy
);
10784 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
10786 int dy
= - (row
->height
- row
->visible_height
);
10789 shift_glyph_matrix (w
, matrix
, 0, matrix
->nrows
, dy
);
10792 /* When we change the cursor y-position of the selected window,
10793 change this_line_y as well so that the display optimization for
10794 the cursor line of the selected window in redisplay_internal uses
10795 the correct y-position. */
10796 if (w
== XWINDOW (selected_window
))
10797 this_line_y
= w
->cursor
.y
;
10799 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
10800 redisplay with larger matrices. */
10801 if (matrix
->nrows
< required_matrix_height (w
))
10803 fonts_changed_p
= 1;
10812 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
10813 non-zero means only WINDOW is redisplayed in redisplay_internal.
10814 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
10815 in redisplay_window to bring a partially visible line into view in
10816 the case that only the cursor has moved.
10818 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
10819 last screen line's vertical height extends past the end of the screen.
10823 1 if scrolling succeeded
10825 0 if scrolling didn't find point.
10827 -1 if new fonts have been loaded so that we must interrupt
10828 redisplay, adjust glyph matrices, and try again. */
10834 SCROLLING_NEED_LARGER_MATRICES
10838 try_scrolling (window
, just_this_one_p
, scroll_conservatively
,
10839 scroll_step
, temp_scroll_step
, last_line_misfit
)
10840 Lisp_Object window
;
10841 int just_this_one_p
;
10842 EMACS_INT scroll_conservatively
, scroll_step
;
10843 int temp_scroll_step
;
10844 int last_line_misfit
;
10846 struct window
*w
= XWINDOW (window
);
10847 struct frame
*f
= XFRAME (w
->frame
);
10848 struct text_pos scroll_margin_pos
;
10849 struct text_pos pos
;
10850 struct text_pos startp
;
10852 Lisp_Object window_end
;
10853 int this_scroll_margin
;
10857 int amount_to_scroll
= 0;
10858 Lisp_Object aggressive
;
10860 int extra_scroll_margin_lines
= last_line_misfit
? 1 : 0;
10863 debug_method_add (w
, "try_scrolling");
10866 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
10868 /* Compute scroll margin height in pixels. We scroll when point is
10869 within this distance from the top or bottom of the window. */
10870 if (scroll_margin
> 0)
10872 this_scroll_margin
= min (scroll_margin
, WINDOW_TOTAL_LINES (w
) / 4);
10873 this_scroll_margin
*= FRAME_LINE_HEIGHT (f
);
10876 this_scroll_margin
= 0;
10878 /* Force scroll_conservatively to have a reasonable value so it doesn't
10879 cause an overflow while computing how much to scroll. */
10880 if (scroll_conservatively
)
10881 scroll_conservatively
= min (scroll_conservatively
,
10882 MOST_POSITIVE_FIXNUM
/ FRAME_LINE_HEIGHT (f
));
10884 /* Compute how much we should try to scroll maximally to bring point
10886 if (scroll_step
|| scroll_conservatively
|| temp_scroll_step
)
10887 scroll_max
= max (scroll_step
,
10888 max (scroll_conservatively
, temp_scroll_step
));
10889 else if (NUMBERP (current_buffer
->scroll_down_aggressively
)
10890 || NUMBERP (current_buffer
->scroll_up_aggressively
))
10891 /* We're trying to scroll because of aggressive scrolling
10892 but no scroll_step is set. Choose an arbitrary one. Maybe
10893 there should be a variable for this. */
10897 scroll_max
*= FRAME_LINE_HEIGHT (f
);
10899 /* Decide whether we have to scroll down. Start at the window end
10900 and move this_scroll_margin up to find the position of the scroll
10902 window_end
= Fwindow_end (window
, Qt
);
10906 CHARPOS (scroll_margin_pos
) = XINT (window_end
);
10907 BYTEPOS (scroll_margin_pos
) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos
));
10909 if (this_scroll_margin
|| extra_scroll_margin_lines
)
10911 start_display (&it
, w
, scroll_margin_pos
);
10912 if (this_scroll_margin
)
10913 move_it_vertically (&it
, - this_scroll_margin
);
10914 if (extra_scroll_margin_lines
)
10915 move_it_by_lines (&it
, - extra_scroll_margin_lines
, 0);
10916 scroll_margin_pos
= it
.current
.pos
;
10919 if (PT
>= CHARPOS (scroll_margin_pos
))
10923 /* Point is in the scroll margin at the bottom of the window, or
10924 below. Compute a new window start that makes point visible. */
10926 /* Compute the distance from the scroll margin to PT.
10927 Give up if the distance is greater than scroll_max. */
10928 start_display (&it
, w
, scroll_margin_pos
);
10930 move_it_to (&it
, PT
, 0, it
.last_visible_y
, -1,
10931 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
10933 /* To make point visible, we have to move the window start
10934 down so that the line the cursor is in is visible, which
10935 means we have to add in the height of the cursor line. */
10936 dy
= line_bottom_y (&it
) - y0
;
10938 if (dy
> scroll_max
)
10939 return SCROLLING_FAILED
;
10941 /* Move the window start down. If scrolling conservatively,
10942 move it just enough down to make point visible. If
10943 scroll_step is set, move it down by scroll_step. */
10944 start_display (&it
, w
, startp
);
10946 if (scroll_conservatively
)
10947 /* Set AMOUNT_TO_SCROLL to at least one line,
10948 and at most scroll_conservatively lines. */
10950 = min (max (dy
, FRAME_LINE_HEIGHT (f
)),
10951 FRAME_LINE_HEIGHT (f
) * scroll_conservatively
);
10952 else if (scroll_step
|| temp_scroll_step
)
10953 amount_to_scroll
= scroll_max
;
10956 aggressive
= current_buffer
->scroll_up_aggressively
;
10957 height
= WINDOW_BOX_TEXT_HEIGHT (w
);
10958 if (NUMBERP (aggressive
))
10959 amount_to_scroll
= XFLOATINT (aggressive
) * height
;
10962 if (amount_to_scroll
<= 0)
10963 return SCROLLING_FAILED
;
10965 /* If moving by amount_to_scroll leaves STARTP unchanged,
10966 move it down one screen line. */
10968 move_it_vertically (&it
, amount_to_scroll
);
10969 if (CHARPOS (it
.current
.pos
) == CHARPOS (startp
))
10970 move_it_by_lines (&it
, 1, 1);
10971 startp
= it
.current
.pos
;
10975 /* See if point is inside the scroll margin at the top of the
10977 scroll_margin_pos
= startp
;
10978 if (this_scroll_margin
)
10980 start_display (&it
, w
, startp
);
10981 move_it_vertically (&it
, this_scroll_margin
);
10982 scroll_margin_pos
= it
.current
.pos
;
10985 if (PT
< CHARPOS (scroll_margin_pos
))
10987 /* Point is in the scroll margin at the top of the window or
10988 above what is displayed in the window. */
10991 /* Compute the vertical distance from PT to the scroll
10992 margin position. Give up if distance is greater than
10994 SET_TEXT_POS (pos
, PT
, PT_BYTE
);
10995 start_display (&it
, w
, pos
);
10997 move_it_to (&it
, CHARPOS (scroll_margin_pos
), 0,
10998 it
.last_visible_y
, -1,
10999 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
11000 dy
= it
.current_y
- y0
;
11001 if (dy
> scroll_max
)
11002 return SCROLLING_FAILED
;
11004 /* Compute new window start. */
11005 start_display (&it
, w
, startp
);
11007 if (scroll_conservatively
)
11009 max (dy
, FRAME_LINE_HEIGHT (f
) * max (scroll_step
, temp_scroll_step
));
11010 else if (scroll_step
|| temp_scroll_step
)
11011 amount_to_scroll
= scroll_max
;
11014 aggressive
= current_buffer
->scroll_down_aggressively
;
11015 height
= WINDOW_BOX_TEXT_HEIGHT (w
);
11016 if (NUMBERP (aggressive
))
11017 amount_to_scroll
= XFLOATINT (aggressive
) * height
;
11020 if (amount_to_scroll
<= 0)
11021 return SCROLLING_FAILED
;
11023 move_it_vertically (&it
, - amount_to_scroll
);
11024 startp
= it
.current
.pos
;
11028 /* Run window scroll functions. */
11029 startp
= run_window_scroll_functions (window
, startp
);
11031 /* Display the window. Give up if new fonts are loaded, or if point
11033 if (!try_window (window
, startp
))
11034 rc
= SCROLLING_NEED_LARGER_MATRICES
;
11035 else if (w
->cursor
.vpos
< 0)
11037 clear_glyph_matrix (w
->desired_matrix
);
11038 rc
= SCROLLING_FAILED
;
11042 /* Maybe forget recorded base line for line number display. */
11043 if (!just_this_one_p
11044 || current_buffer
->clip_changed
11045 || BEG_UNCHANGED
< CHARPOS (startp
))
11046 w
->base_line_number
= Qnil
;
11048 /* If cursor ends up on a partially visible line,
11049 treat that as being off the bottom of the screen. */
11050 if (! make_cursor_line_fully_visible (w
, extra_scroll_margin_lines
<= 1))
11052 clear_glyph_matrix (w
->desired_matrix
);
11053 ++extra_scroll_margin_lines
;
11056 rc
= SCROLLING_SUCCESS
;
11063 /* Compute a suitable window start for window W if display of W starts
11064 on a continuation line. Value is non-zero if a new window start
11067 The new window start will be computed, based on W's width, starting
11068 from the start of the continued line. It is the start of the
11069 screen line with the minimum distance from the old start W->start. */
11072 compute_window_start_on_continuation_line (w
)
11075 struct text_pos pos
, start_pos
;
11076 int window_start_changed_p
= 0;
11078 SET_TEXT_POS_FROM_MARKER (start_pos
, w
->start
);
11080 /* If window start is on a continuation line... Window start may be
11081 < BEGV in case there's invisible text at the start of the
11082 buffer (M-x rmail, for example). */
11083 if (CHARPOS (start_pos
) > BEGV
11084 && FETCH_BYTE (BYTEPOS (start_pos
) - 1) != '\n')
11087 struct glyph_row
*row
;
11089 /* Handle the case that the window start is out of range. */
11090 if (CHARPOS (start_pos
) < BEGV
)
11091 SET_TEXT_POS (start_pos
, BEGV
, BEGV_BYTE
);
11092 else if (CHARPOS (start_pos
) > ZV
)
11093 SET_TEXT_POS (start_pos
, ZV
, ZV_BYTE
);
11095 /* Find the start of the continued line. This should be fast
11096 because scan_buffer is fast (newline cache). */
11097 row
= w
->desired_matrix
->rows
+ (WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0);
11098 init_iterator (&it
, w
, CHARPOS (start_pos
), BYTEPOS (start_pos
),
11099 row
, DEFAULT_FACE_ID
);
11100 reseat_at_previous_visible_line_start (&it
);
11102 /* If the line start is "too far" away from the window start,
11103 say it takes too much time to compute a new window start. */
11104 if (CHARPOS (start_pos
) - IT_CHARPOS (it
)
11105 < WINDOW_TOTAL_LINES (w
) * WINDOW_TOTAL_COLS (w
))
11107 int min_distance
, distance
;
11109 /* Move forward by display lines to find the new window
11110 start. If window width was enlarged, the new start can
11111 be expected to be > the old start. If window width was
11112 decreased, the new window start will be < the old start.
11113 So, we're looking for the display line start with the
11114 minimum distance from the old window start. */
11115 pos
= it
.current
.pos
;
11116 min_distance
= INFINITY
;
11117 while ((distance
= abs (CHARPOS (start_pos
) - IT_CHARPOS (it
))),
11118 distance
< min_distance
)
11120 min_distance
= distance
;
11121 pos
= it
.current
.pos
;
11122 move_it_by_lines (&it
, 1, 0);
11125 /* Set the window start there. */
11126 SET_MARKER_FROM_TEXT_POS (w
->start
, pos
);
11127 window_start_changed_p
= 1;
11131 return window_start_changed_p
;
11135 /* Try cursor movement in case text has not changed in window WINDOW,
11136 with window start STARTP. Value is
11138 CURSOR_MOVEMENT_SUCCESS if successful
11140 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
11142 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
11143 display. *SCROLL_STEP is set to 1, under certain circumstances, if
11144 we want to scroll as if scroll-step were set to 1. See the code.
11146 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
11147 which case we have to abort this redisplay, and adjust matrices
11152 CURSOR_MOVEMENT_SUCCESS
,
11153 CURSOR_MOVEMENT_CANNOT_BE_USED
,
11154 CURSOR_MOVEMENT_MUST_SCROLL
,
11155 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
11159 try_cursor_movement (window
, startp
, scroll_step
)
11160 Lisp_Object window
;
11161 struct text_pos startp
;
11164 struct window
*w
= XWINDOW (window
);
11165 struct frame
*f
= XFRAME (w
->frame
);
11166 int rc
= CURSOR_MOVEMENT_CANNOT_BE_USED
;
11169 if (inhibit_try_cursor_movement
)
11173 /* Handle case where text has not changed, only point, and it has
11174 not moved off the frame. */
11175 if (/* Point may be in this window. */
11176 PT
>= CHARPOS (startp
)
11177 /* Selective display hasn't changed. */
11178 && !current_buffer
->clip_changed
11179 /* Function force-mode-line-update is used to force a thorough
11180 redisplay. It sets either windows_or_buffers_changed or
11181 update_mode_lines. So don't take a shortcut here for these
11183 && !update_mode_lines
11184 && !windows_or_buffers_changed
11185 && !cursor_type_changed
11186 /* Can't use this case if highlighting a region. When a
11187 region exists, cursor movement has to do more than just
11189 && !(!NILP (Vtransient_mark_mode
)
11190 && !NILP (current_buffer
->mark_active
))
11191 && NILP (w
->region_showing
)
11192 && NILP (Vshow_trailing_whitespace
)
11193 /* Right after splitting windows, last_point may be nil. */
11194 && INTEGERP (w
->last_point
)
11195 /* This code is not used for mini-buffer for the sake of the case
11196 of redisplaying to replace an echo area message; since in
11197 that case the mini-buffer contents per se are usually
11198 unchanged. This code is of no real use in the mini-buffer
11199 since the handling of this_line_start_pos, etc., in redisplay
11200 handles the same cases. */
11201 && !EQ (window
, minibuf_window
)
11202 /* When splitting windows or for new windows, it happens that
11203 redisplay is called with a nil window_end_vpos or one being
11204 larger than the window. This should really be fixed in
11205 window.c. I don't have this on my list, now, so we do
11206 approximately the same as the old redisplay code. --gerd. */
11207 && INTEGERP (w
->window_end_vpos
)
11208 && XFASTINT (w
->window_end_vpos
) < w
->current_matrix
->nrows
11209 && (FRAME_WINDOW_P (f
)
11210 || !overlay_arrow_in_current_buffer_p ()))
11212 int this_scroll_margin
;
11213 struct glyph_row
*row
= NULL
;
11216 debug_method_add (w
, "cursor movement");
11219 /* Scroll if point within this distance from the top or bottom
11220 of the window. This is a pixel value. */
11221 this_scroll_margin
= max (0, scroll_margin
);
11222 this_scroll_margin
= min (this_scroll_margin
, WINDOW_TOTAL_LINES (w
) / 4);
11223 this_scroll_margin
*= FRAME_LINE_HEIGHT (f
);
11225 /* Start with the row the cursor was displayed during the last
11226 not paused redisplay. Give up if that row is not valid. */
11227 if (w
->last_cursor
.vpos
< 0
11228 || w
->last_cursor
.vpos
>= w
->current_matrix
->nrows
)
11229 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11232 row
= MATRIX_ROW (w
->current_matrix
, w
->last_cursor
.vpos
);
11233 if (row
->mode_line_p
)
11235 if (!row
->enabled_p
)
11236 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11239 if (rc
== CURSOR_MOVEMENT_CANNOT_BE_USED
)
11242 int last_y
= window_text_bottom_y (w
) - this_scroll_margin
;
11244 if (PT
> XFASTINT (w
->last_point
))
11246 /* Point has moved forward. */
11247 while (MATRIX_ROW_END_CHARPOS (row
) < PT
11248 && MATRIX_ROW_BOTTOM_Y (row
) < last_y
)
11250 xassert (row
->enabled_p
);
11254 /* The end position of a row equals the start position
11255 of the next row. If PT is there, we would rather
11256 display it in the next line. */
11257 while (MATRIX_ROW_BOTTOM_Y (row
) < last_y
11258 && MATRIX_ROW_END_CHARPOS (row
) == PT
11259 && !cursor_row_p (w
, row
))
11262 /* If within the scroll margin, scroll. Note that
11263 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
11264 the next line would be drawn, and that
11265 this_scroll_margin can be zero. */
11266 if (MATRIX_ROW_BOTTOM_Y (row
) > last_y
11267 || PT
> MATRIX_ROW_END_CHARPOS (row
)
11268 /* Line is completely visible last line in window
11269 and PT is to be set in the next line. */
11270 || (MATRIX_ROW_BOTTOM_Y (row
) == last_y
11271 && PT
== MATRIX_ROW_END_CHARPOS (row
)
11272 && !row
->ends_at_zv_p
11273 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
)))
11276 else if (PT
< XFASTINT (w
->last_point
))
11278 /* Cursor has to be moved backward. Note that PT >=
11279 CHARPOS (startp) because of the outer
11281 while (!row
->mode_line_p
11282 && (MATRIX_ROW_START_CHARPOS (row
) > PT
11283 || (MATRIX_ROW_START_CHARPOS (row
) == PT
11284 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row
)))
11285 && (row
->y
> this_scroll_margin
11286 || CHARPOS (startp
) == BEGV
))
11288 xassert (row
->enabled_p
);
11292 /* Consider the following case: Window starts at BEGV,
11293 there is invisible, intangible text at BEGV, so that
11294 display starts at some point START > BEGV. It can
11295 happen that we are called with PT somewhere between
11296 BEGV and START. Try to handle that case. */
11297 if (row
< w
->current_matrix
->rows
11298 || row
->mode_line_p
)
11300 row
= w
->current_matrix
->rows
;
11301 if (row
->mode_line_p
)
11305 /* Due to newlines in overlay strings, we may have to
11306 skip forward over overlay strings. */
11307 while (MATRIX_ROW_BOTTOM_Y (row
) < last_y
11308 && MATRIX_ROW_END_CHARPOS (row
) == PT
11309 && !cursor_row_p (w
, row
))
11312 /* If within the scroll margin, scroll. */
11313 if (row
->y
< this_scroll_margin
11314 && CHARPOS (startp
) != BEGV
)
11318 if (PT
< MATRIX_ROW_START_CHARPOS (row
)
11319 || PT
> MATRIX_ROW_END_CHARPOS (row
))
11321 /* if PT is not in the glyph row, give up. */
11322 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11324 else if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row
))
11326 if (PT
== MATRIX_ROW_END_CHARPOS (row
)
11327 && !row
->ends_at_zv_p
11328 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
))
11329 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11330 else if (row
->height
> window_box_height (w
))
11332 /* If we end up in a partially visible line, let's
11333 make it fully visible, except when it's taller
11334 than the window, in which case we can't do much
11337 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11341 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
11342 if (!make_cursor_line_fully_visible (w
, 0))
11343 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11345 rc
= CURSOR_MOVEMENT_SUCCESS
;
11349 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
11352 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
11353 rc
= CURSOR_MOVEMENT_SUCCESS
;
11362 set_vertical_scroll_bar (w
)
11365 int start
, end
, whole
;
11367 /* Calculate the start and end positions for the current window.
11368 At some point, it would be nice to choose between scrollbars
11369 which reflect the whole buffer size, with special markers
11370 indicating narrowing, and scrollbars which reflect only the
11373 Note that mini-buffers sometimes aren't displaying any text. */
11374 if (!MINI_WINDOW_P (w
)
11375 || (w
== XWINDOW (minibuf_window
)
11376 && NILP (echo_area_buffer
[0])))
11378 struct buffer
*buf
= XBUFFER (w
->buffer
);
11379 whole
= BUF_ZV (buf
) - BUF_BEGV (buf
);
11380 start
= marker_position (w
->start
) - BUF_BEGV (buf
);
11381 /* I don't think this is guaranteed to be right. For the
11382 moment, we'll pretend it is. */
11383 end
= BUF_Z (buf
) - XFASTINT (w
->window_end_pos
) - BUF_BEGV (buf
);
11387 if (whole
< (end
- start
))
11388 whole
= end
- start
;
11391 start
= end
= whole
= 0;
11393 /* Indicate what this scroll bar ought to be displaying now. */
11394 if (FRAME_DISPLAY (XFRAME (w
->frame
))->set_vertical_scroll_bar_hook
)
11395 (*FRAME_DISPLAY (XFRAME (w
->frame
))->set_vertical_scroll_bar_hook
)
11396 (w
, end
- start
, whole
, start
);
11400 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
11401 selected_window is redisplayed.
11403 We can return without actually redisplaying the window if
11404 fonts_changed_p is nonzero. In that case, redisplay_internal will
11408 redisplay_window (window
, just_this_one_p
)
11409 Lisp_Object window
;
11410 int just_this_one_p
;
11412 struct window
*w
= XWINDOW (window
);
11413 struct frame
*f
= XFRAME (w
->frame
);
11414 struct buffer
*buffer
= XBUFFER (w
->buffer
);
11415 struct buffer
*old
= current_buffer
;
11416 struct text_pos lpoint
, opoint
, startp
;
11417 int update_mode_line
;
11420 /* Record it now because it's overwritten. */
11421 int current_matrix_up_to_date_p
= 0;
11422 int used_current_matrix_p
= 0;
11423 /* This is less strict than current_matrix_up_to_date_p.
11424 It indictes that the buffer contents and narrowing are unchanged. */
11425 int buffer_unchanged_p
= 0;
11426 int temp_scroll_step
= 0;
11427 int count
= SPECPDL_INDEX ();
11429 int centering_position
;
11430 int last_line_misfit
= 0;
11432 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
11435 /* W must be a leaf window here. */
11436 xassert (!NILP (w
->buffer
));
11438 *w
->desired_matrix
->method
= 0;
11441 specbind (Qinhibit_point_motion_hooks
, Qt
);
11443 reconsider_clip_changes (w
, buffer
);
11445 /* Has the mode line to be updated? */
11446 update_mode_line
= (!NILP (w
->update_mode_line
)
11447 || update_mode_lines
11448 || buffer
->clip_changed
11449 || buffer
->prevent_redisplay_optimizations_p
);
11451 if (MINI_WINDOW_P (w
))
11453 if (w
== XWINDOW (echo_area_window
)
11454 && !NILP (echo_area_buffer
[0]))
11456 if (update_mode_line
)
11457 /* We may have to update a tty frame's menu bar or a
11458 tool-bar. Example `M-x C-h C-h C-g'. */
11459 goto finish_menu_bars
;
11461 /* We've already displayed the echo area glyphs in this window. */
11462 goto finish_scroll_bars
;
11464 else if ((w
!= XWINDOW (minibuf_window
)
11465 || minibuf_level
== 0)
11466 /* When buffer is nonempty, redisplay window normally. */
11467 && BUF_Z (XBUFFER (w
->buffer
)) == BUF_BEG (XBUFFER (w
->buffer
))
11468 /* Quail displays non-mini buffers in minibuffer window.
11469 In that case, redisplay the window normally. */
11470 && !NILP (Fmemq (w
->buffer
, Vminibuffer_list
)))
11472 /* W is a mini-buffer window, but it's not active, so clear
11474 int yb
= window_text_bottom_y (w
);
11475 struct glyph_row
*row
;
11478 for (y
= 0, row
= w
->desired_matrix
->rows
;
11480 y
+= row
->height
, ++row
)
11481 blank_row (w
, row
, y
);
11482 goto finish_scroll_bars
;
11485 clear_glyph_matrix (w
->desired_matrix
);
11488 /* Otherwise set up data on this window; select its buffer and point
11490 /* Really select the buffer, for the sake of buffer-local
11492 set_buffer_internal_1 (XBUFFER (w
->buffer
));
11493 SET_TEXT_POS (opoint
, PT
, PT_BYTE
);
11495 current_matrix_up_to_date_p
11496 = (!NILP (w
->window_end_valid
)
11497 && !current_buffer
->clip_changed
11498 && !current_buffer
->prevent_redisplay_optimizations_p
11499 && XFASTINT (w
->last_modified
) >= MODIFF
11500 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
);
11503 = (!NILP (w
->window_end_valid
)
11504 && !current_buffer
->clip_changed
11505 && XFASTINT (w
->last_modified
) >= MODIFF
11506 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
);
11508 /* When windows_or_buffers_changed is non-zero, we can't rely on
11509 the window end being valid, so set it to nil there. */
11510 if (windows_or_buffers_changed
)
11512 /* If window starts on a continuation line, maybe adjust the
11513 window start in case the window's width changed. */
11514 if (XMARKER (w
->start
)->buffer
== current_buffer
)
11515 compute_window_start_on_continuation_line (w
);
11517 w
->window_end_valid
= Qnil
;
11520 /* Some sanity checks. */
11521 CHECK_WINDOW_END (w
);
11522 if (Z
== Z_BYTE
&& CHARPOS (opoint
) != BYTEPOS (opoint
))
11524 if (BYTEPOS (opoint
) < CHARPOS (opoint
))
11527 /* If %c is in mode line, update it if needed. */
11528 if (!NILP (w
->column_number_displayed
)
11529 /* This alternative quickly identifies a common case
11530 where no change is needed. */
11531 && !(PT
== XFASTINT (w
->last_point
)
11532 && XFASTINT (w
->last_modified
) >= MODIFF
11533 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
)
11534 && (XFASTINT (w
->column_number_displayed
)
11535 != (int) current_column ())) /* iftc */
11536 update_mode_line
= 1;
11538 /* Count number of windows showing the selected buffer. An indirect
11539 buffer counts as its base buffer. */
11540 if (!just_this_one_p
)
11542 struct buffer
*current_base
, *window_base
;
11543 current_base
= current_buffer
;
11544 window_base
= XBUFFER (XWINDOW (selected_window
)->buffer
);
11545 if (current_base
->base_buffer
)
11546 current_base
= current_base
->base_buffer
;
11547 if (window_base
->base_buffer
)
11548 window_base
= window_base
->base_buffer
;
11549 if (current_base
== window_base
)
11553 /* Point refers normally to the selected window. For any other
11554 window, set up appropriate value. */
11555 if (!EQ (window
, selected_window
))
11557 int new_pt
= XMARKER (w
->pointm
)->charpos
;
11558 int new_pt_byte
= marker_byte_position (w
->pointm
);
11562 new_pt_byte
= BEGV_BYTE
;
11563 set_marker_both (w
->pointm
, Qnil
, BEGV
, BEGV_BYTE
);
11565 else if (new_pt
> (ZV
- 1))
11568 new_pt_byte
= ZV_BYTE
;
11569 set_marker_both (w
->pointm
, Qnil
, ZV
, ZV_BYTE
);
11572 /* We don't use SET_PT so that the point-motion hooks don't run. */
11573 TEMP_SET_PT_BOTH (new_pt
, new_pt_byte
);
11576 /* If any of the character widths specified in the display table
11577 have changed, invalidate the width run cache. It's true that
11578 this may be a bit late to catch such changes, but the rest of
11579 redisplay goes (non-fatally) haywire when the display table is
11580 changed, so why should we worry about doing any better? */
11581 if (current_buffer
->width_run_cache
)
11583 struct Lisp_Char_Table
*disptab
= buffer_display_table ();
11585 if (! disptab_matches_widthtab (disptab
,
11586 XVECTOR (current_buffer
->width_table
)))
11588 invalidate_region_cache (current_buffer
,
11589 current_buffer
->width_run_cache
,
11591 recompute_width_table (current_buffer
, disptab
);
11595 /* If window-start is screwed up, choose a new one. */
11596 if (XMARKER (w
->start
)->buffer
!= current_buffer
)
11599 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
11601 /* If someone specified a new starting point but did not insist,
11602 check whether it can be used. */
11603 if (!NILP (w
->optional_new_start
)
11604 && CHARPOS (startp
) >= BEGV
11605 && CHARPOS (startp
) <= ZV
)
11607 w
->optional_new_start
= Qnil
;
11608 start_display (&it
, w
, startp
);
11609 move_it_to (&it
, PT
, 0, it
.last_visible_y
, -1,
11610 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
11611 if (IT_CHARPOS (it
) == PT
)
11612 w
->force_start
= Qt
;
11613 /* IT may overshoot PT if text at PT is invisible. */
11614 else if (IT_CHARPOS (it
) > PT
&& CHARPOS (startp
) <= PT
)
11615 w
->force_start
= Qt
;
11620 /* Handle case where place to start displaying has been specified,
11621 unless the specified location is outside the accessible range. */
11622 if (!NILP (w
->force_start
)
11623 || w
->frozen_window_start_p
)
11625 /* We set this later on if we have to adjust point. */
11628 w
->force_start
= Qnil
;
11630 w
->window_end_valid
= Qnil
;
11632 /* Forget any recorded base line for line number display. */
11633 if (!buffer_unchanged_p
)
11634 w
->base_line_number
= Qnil
;
11636 /* Redisplay the mode line. Select the buffer properly for that.
11637 Also, run the hook window-scroll-functions
11638 because we have scrolled. */
11639 /* Note, we do this after clearing force_start because
11640 if there's an error, it is better to forget about force_start
11641 than to get into an infinite loop calling the hook functions
11642 and having them get more errors. */
11643 if (!update_mode_line
11644 || ! NILP (Vwindow_scroll_functions
))
11646 update_mode_line
= 1;
11647 w
->update_mode_line
= Qt
;
11648 startp
= run_window_scroll_functions (window
, startp
);
11651 w
->last_modified
= make_number (0);
11652 w
->last_overlay_modified
= make_number (0);
11653 if (CHARPOS (startp
) < BEGV
)
11654 SET_TEXT_POS (startp
, BEGV
, BEGV_BYTE
);
11655 else if (CHARPOS (startp
) > ZV
)
11656 SET_TEXT_POS (startp
, ZV
, ZV_BYTE
);
11658 /* Redisplay, then check if cursor has been set during the
11659 redisplay. Give up if new fonts were loaded. */
11660 if (!try_window (window
, startp
))
11662 w
->force_start
= Qt
;
11663 clear_glyph_matrix (w
->desired_matrix
);
11664 goto need_larger_matrices
;
11667 if (w
->cursor
.vpos
< 0 && !w
->frozen_window_start_p
)
11669 /* If point does not appear, try to move point so it does
11670 appear. The desired matrix has been built above, so we
11671 can use it here. */
11672 new_vpos
= window_box_height (w
) / 2;
11675 if (!make_cursor_line_fully_visible (w
, 0))
11677 /* Point does appear, but on a line partly visible at end of window.
11678 Move it back to a fully-visible line. */
11679 new_vpos
= window_box_height (w
);
11682 /* If we need to move point for either of the above reasons,
11683 now actually do it. */
11686 struct glyph_row
*row
;
11688 row
= MATRIX_FIRST_TEXT_ROW (w
->desired_matrix
);
11689 while (MATRIX_ROW_BOTTOM_Y (row
) < new_vpos
)
11692 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row
),
11693 MATRIX_ROW_START_BYTEPOS (row
));
11695 if (w
!= XWINDOW (selected_window
))
11696 set_marker_both (w
->pointm
, Qnil
, PT
, PT_BYTE
);
11697 else if (current_buffer
== old
)
11698 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
11700 set_cursor_from_row (w
, row
, w
->desired_matrix
, 0, 0, 0, 0);
11702 /* If we are highlighting the region, then we just changed
11703 the region, so redisplay to show it. */
11704 if (!NILP (Vtransient_mark_mode
)
11705 && !NILP (current_buffer
->mark_active
))
11707 clear_glyph_matrix (w
->desired_matrix
);
11708 if (!try_window (window
, startp
))
11709 goto need_larger_matrices
;
11714 debug_method_add (w
, "forced window start");
11719 /* Handle case where text has not changed, only point, and it has
11720 not moved off the frame, and we are not retrying after hscroll.
11721 (current_matrix_up_to_date_p is nonzero when retrying.) */
11722 if (current_matrix_up_to_date_p
11723 && (rc
= try_cursor_movement (window
, startp
, &temp_scroll_step
),
11724 rc
!= CURSOR_MOVEMENT_CANNOT_BE_USED
))
11728 case CURSOR_MOVEMENT_SUCCESS
:
11729 used_current_matrix_p
= 1;
11732 #if 0 /* try_cursor_movement never returns this value. */
11733 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES
:
11734 goto need_larger_matrices
;
11737 case CURSOR_MOVEMENT_MUST_SCROLL
:
11738 goto try_to_scroll
;
11744 /* If current starting point was originally the beginning of a line
11745 but no longer is, find a new starting point. */
11746 else if (!NILP (w
->start_at_line_beg
)
11747 && !(CHARPOS (startp
) <= BEGV
11748 || FETCH_BYTE (BYTEPOS (startp
) - 1) == '\n'))
11751 debug_method_add (w
, "recenter 1");
11756 /* Try scrolling with try_window_id. Value is > 0 if update has
11757 been done, it is -1 if we know that the same window start will
11758 not work. It is 0 if unsuccessful for some other reason. */
11759 else if ((tem
= try_window_id (w
)) != 0)
11762 debug_method_add (w
, "try_window_id %d", tem
);
11765 if (fonts_changed_p
)
11766 goto need_larger_matrices
;
11770 /* Otherwise try_window_id has returned -1 which means that we
11771 don't want the alternative below this comment to execute. */
11773 else if (CHARPOS (startp
) >= BEGV
11774 && CHARPOS (startp
) <= ZV
11775 && PT
>= CHARPOS (startp
)
11776 && (CHARPOS (startp
) < ZV
11777 /* Avoid starting at end of buffer. */
11778 || CHARPOS (startp
) == BEGV
11779 || (XFASTINT (w
->last_modified
) >= MODIFF
11780 && XFASTINT (w
->last_overlay_modified
) >= OVERLAY_MODIFF
)))
11783 debug_method_add (w
, "same window start");
11786 /* Try to redisplay starting at same place as before.
11787 If point has not moved off frame, accept the results. */
11788 if (!current_matrix_up_to_date_p
11789 /* Don't use try_window_reusing_current_matrix in this case
11790 because a window scroll function can have changed the
11792 || !NILP (Vwindow_scroll_functions
)
11793 || MINI_WINDOW_P (w
)
11794 || !(used_current_matrix_p
=
11795 try_window_reusing_current_matrix (w
)))
11797 IF_DEBUG (debug_method_add (w
, "1"));
11798 try_window (window
, startp
);
11801 if (fonts_changed_p
)
11802 goto need_larger_matrices
;
11804 if (w
->cursor
.vpos
>= 0)
11806 if (!just_this_one_p
11807 || current_buffer
->clip_changed
11808 || BEG_UNCHANGED
< CHARPOS (startp
))
11809 /* Forget any recorded base line for line number display. */
11810 w
->base_line_number
= Qnil
;
11812 if (!make_cursor_line_fully_visible (w
, 1))
11814 clear_glyph_matrix (w
->desired_matrix
);
11815 last_line_misfit
= 1;
11817 /* Drop through and scroll. */
11822 clear_glyph_matrix (w
->desired_matrix
);
11827 w
->last_modified
= make_number (0);
11828 w
->last_overlay_modified
= make_number (0);
11830 /* Redisplay the mode line. Select the buffer properly for that. */
11831 if (!update_mode_line
)
11833 update_mode_line
= 1;
11834 w
->update_mode_line
= Qt
;
11837 /* Try to scroll by specified few lines. */
11838 if ((scroll_conservatively
11840 || temp_scroll_step
11841 || NUMBERP (current_buffer
->scroll_up_aggressively
)
11842 || NUMBERP (current_buffer
->scroll_down_aggressively
))
11843 && !current_buffer
->clip_changed
11844 && CHARPOS (startp
) >= BEGV
11845 && CHARPOS (startp
) <= ZV
)
11847 /* The function returns -1 if new fonts were loaded, 1 if
11848 successful, 0 if not successful. */
11849 int rc
= try_scrolling (window
, just_this_one_p
,
11850 scroll_conservatively
,
11852 temp_scroll_step
, last_line_misfit
);
11855 case SCROLLING_SUCCESS
:
11858 case SCROLLING_NEED_LARGER_MATRICES
:
11859 goto need_larger_matrices
;
11861 case SCROLLING_FAILED
:
11869 /* Finally, just choose place to start which centers point */
11872 centering_position
= window_box_height (w
) / 2;
11875 /* Jump here with centering_position already set to 0. */
11878 debug_method_add (w
, "recenter");
11881 /* w->vscroll = 0; */
11883 /* Forget any previously recorded base line for line number display. */
11884 if (!buffer_unchanged_p
)
11885 w
->base_line_number
= Qnil
;
11887 /* Move backward half the height of the window. */
11888 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
11889 it
.current_y
= it
.last_visible_y
;
11890 move_it_vertically_backward (&it
, centering_position
);
11891 xassert (IT_CHARPOS (it
) >= BEGV
);
11893 /* The function move_it_vertically_backward may move over more
11894 than the specified y-distance. If it->w is small, e.g. a
11895 mini-buffer window, we may end up in front of the window's
11896 display area. Start displaying at the start of the line
11897 containing PT in this case. */
11898 if (it
.current_y
<= 0)
11900 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
11901 move_it_vertically (&it
, 0);
11902 xassert (IT_CHARPOS (it
) <= PT
);
11906 it
.current_x
= it
.hpos
= 0;
11908 /* Set startp here explicitly in case that helps avoid an infinite loop
11909 in case the window-scroll-functions functions get errors. */
11910 set_marker_both (w
->start
, Qnil
, IT_CHARPOS (it
), IT_BYTEPOS (it
));
11912 /* Run scroll hooks. */
11913 startp
= run_window_scroll_functions (window
, it
.current
.pos
);
11915 /* Redisplay the window. */
11916 if (!current_matrix_up_to_date_p
11917 || windows_or_buffers_changed
11918 || cursor_type_changed
11919 /* Don't use try_window_reusing_current_matrix in this case
11920 because it can have changed the buffer. */
11921 || !NILP (Vwindow_scroll_functions
)
11922 || !just_this_one_p
11923 || MINI_WINDOW_P (w
)
11924 || !(used_current_matrix_p
=
11925 try_window_reusing_current_matrix (w
)))
11926 try_window (window
, startp
);
11928 /* If new fonts have been loaded (due to fontsets), give up. We
11929 have to start a new redisplay since we need to re-adjust glyph
11931 if (fonts_changed_p
)
11932 goto need_larger_matrices
;
11934 /* If cursor did not appear assume that the middle of the window is
11935 in the first line of the window. Do it again with the next line.
11936 (Imagine a window of height 100, displaying two lines of height
11937 60. Moving back 50 from it->last_visible_y will end in the first
11939 if (w
->cursor
.vpos
< 0)
11941 if (!NILP (w
->window_end_valid
)
11942 && PT
>= Z
- XFASTINT (w
->window_end_pos
))
11944 clear_glyph_matrix (w
->desired_matrix
);
11945 move_it_by_lines (&it
, 1, 0);
11946 try_window (window
, it
.current
.pos
);
11948 else if (PT
< IT_CHARPOS (it
))
11950 clear_glyph_matrix (w
->desired_matrix
);
11951 move_it_by_lines (&it
, -1, 0);
11952 try_window (window
, it
.current
.pos
);
11956 /* Not much we can do about it. */
11960 /* Consider the following case: Window starts at BEGV, there is
11961 invisible, intangible text at BEGV, so that display starts at
11962 some point START > BEGV. It can happen that we are called with
11963 PT somewhere between BEGV and START. Try to handle that case. */
11964 if (w
->cursor
.vpos
< 0)
11966 struct glyph_row
*row
= w
->current_matrix
->rows
;
11967 if (row
->mode_line_p
)
11969 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
11972 if (!make_cursor_line_fully_visible (w
, centering_position
> 0))
11974 /* If vscroll is enabled, disable it and try again. */
11978 clear_glyph_matrix (w
->desired_matrix
);
11982 /* If centering point failed to make the whole line visible,
11983 put point at the top instead. That has to make the whole line
11984 visible, if it can be done. */
11985 clear_glyph_matrix (w
->desired_matrix
);
11986 centering_position
= 0;
11992 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
11993 w
->start_at_line_beg
= ((CHARPOS (startp
) == BEGV
11994 || FETCH_BYTE (BYTEPOS (startp
) - 1) == '\n')
11997 /* Display the mode line, if we must. */
11998 if ((update_mode_line
11999 /* If window not full width, must redo its mode line
12000 if (a) the window to its side is being redone and
12001 (b) we do a frame-based redisplay. This is a consequence
12002 of how inverted lines are drawn in frame-based redisplay. */
12003 || (!just_this_one_p
12004 && !FRAME_WINDOW_P (f
)
12005 && !WINDOW_FULL_WIDTH_P (w
))
12006 /* Line number to display. */
12007 || INTEGERP (w
->base_line_pos
)
12008 /* Column number is displayed and different from the one displayed. */
12009 || (!NILP (w
->column_number_displayed
)
12010 && (XFASTINT (w
->column_number_displayed
)
12011 != (int) current_column ()))) /* iftc */
12012 /* This means that the window has a mode line. */
12013 && (WINDOW_WANTS_MODELINE_P (w
)
12014 || WINDOW_WANTS_HEADER_LINE_P (w
)))
12016 display_mode_lines (w
);
12018 /* If mode line height has changed, arrange for a thorough
12019 immediate redisplay using the correct mode line height. */
12020 if (WINDOW_WANTS_MODELINE_P (w
)
12021 && CURRENT_MODE_LINE_HEIGHT (w
) != DESIRED_MODE_LINE_HEIGHT (w
))
12023 fonts_changed_p
= 1;
12024 MATRIX_MODE_LINE_ROW (w
->current_matrix
)->height
12025 = DESIRED_MODE_LINE_HEIGHT (w
);
12028 /* If top line height has changed, arrange for a thorough
12029 immediate redisplay using the correct mode line height. */
12030 if (WINDOW_WANTS_HEADER_LINE_P (w
)
12031 && CURRENT_HEADER_LINE_HEIGHT (w
) != DESIRED_HEADER_LINE_HEIGHT (w
))
12033 fonts_changed_p
= 1;
12034 MATRIX_HEADER_LINE_ROW (w
->current_matrix
)->height
12035 = DESIRED_HEADER_LINE_HEIGHT (w
);
12038 if (fonts_changed_p
)
12039 goto need_larger_matrices
;
12042 if (!line_number_displayed
12043 && !BUFFERP (w
->base_line_pos
))
12045 w
->base_line_pos
= Qnil
;
12046 w
->base_line_number
= Qnil
;
12051 /* When we reach a frame's selected window, redo the frame's menu bar. */
12052 if (update_mode_line
12053 && EQ (FRAME_SELECTED_WINDOW (f
), window
))
12055 int redisplay_menu_p
= 0;
12056 int redisplay_tool_bar_p
= 0;
12058 if (FRAME_WINDOW_P (f
))
12060 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
12061 || defined (USE_GTK)
12062 redisplay_menu_p
= FRAME_EXTERNAL_MENU_BAR (f
);
12064 redisplay_menu_p
= FRAME_MENU_BAR_LINES (f
) > 0;
12068 redisplay_menu_p
= FRAME_MENU_BAR_LINES (f
) > 0;
12070 if (redisplay_menu_p
)
12071 display_menu_bar (w
);
12073 #ifdef HAVE_WINDOW_SYSTEM
12075 redisplay_tool_bar_p
= FRAME_EXTERNAL_TOOL_BAR (f
);
12077 redisplay_tool_bar_p
= WINDOWP (f
->tool_bar_window
)
12078 && (FRAME_TOOL_BAR_LINES (f
) > 0
12079 || auto_resize_tool_bars_p
);
12083 if (redisplay_tool_bar_p
)
12084 redisplay_tool_bar (f
);
12088 #ifdef HAVE_WINDOW_SYSTEM
12089 if (update_window_fringes (w
, 0)
12090 && !just_this_one_p
12091 && (used_current_matrix_p
|| overlay_arrow_seen
)
12092 && !w
->pseudo_window_p
)
12096 draw_window_fringes (w
);
12100 #endif /* HAVE_WINDOW_SYSTEM */
12102 /* We go to this label, with fonts_changed_p nonzero,
12103 if it is necessary to try again using larger glyph matrices.
12104 We have to redeem the scroll bar even in this case,
12105 because the loop in redisplay_internal expects that. */
12106 need_larger_matrices
:
12108 finish_scroll_bars
:
12110 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w
))
12112 /* Set the thumb's position and size. */
12113 set_vertical_scroll_bar (w
);
12115 /* Note that we actually used the scroll bar attached to this
12116 window, so it shouldn't be deleted at the end of redisplay. */
12117 if (FRAME_DISPLAY (f
)->redeem_scroll_bar_hook
)
12118 (*FRAME_DISPLAY (f
)->redeem_scroll_bar_hook
) (w
);
12121 /* Restore current_buffer and value of point in it. */
12122 TEMP_SET_PT_BOTH (CHARPOS (opoint
), BYTEPOS (opoint
));
12123 set_buffer_internal_1 (old
);
12124 TEMP_SET_PT_BOTH (CHARPOS (lpoint
), BYTEPOS (lpoint
));
12126 unbind_to (count
, Qnil
);
12130 /* Build the complete desired matrix of WINDOW with a window start
12131 buffer position POS. Value is non-zero if successful. It is zero
12132 if fonts were loaded during redisplay which makes re-adjusting
12133 glyph matrices necessary. */
12136 try_window (window
, pos
)
12137 Lisp_Object window
;
12138 struct text_pos pos
;
12140 struct window
*w
= XWINDOW (window
);
12142 struct glyph_row
*last_text_row
= NULL
;
12144 /* Make POS the new window start. */
12145 set_marker_both (w
->start
, Qnil
, CHARPOS (pos
), BYTEPOS (pos
));
12147 /* Mark cursor position as unknown. No overlay arrow seen. */
12148 w
->cursor
.vpos
= -1;
12149 overlay_arrow_seen
= 0;
12151 /* Initialize iterator and info to start at POS. */
12152 start_display (&it
, w
, pos
);
12154 /* Display all lines of W. */
12155 while (it
.current_y
< it
.last_visible_y
)
12157 if (display_line (&it
))
12158 last_text_row
= it
.glyph_row
- 1;
12159 if (fonts_changed_p
)
12163 /* If bottom moved off end of frame, change mode line percentage. */
12164 if (XFASTINT (w
->window_end_pos
) <= 0
12165 && Z
!= IT_CHARPOS (it
))
12166 w
->update_mode_line
= Qt
;
12168 /* Set window_end_pos to the offset of the last character displayed
12169 on the window from the end of current_buffer. Set
12170 window_end_vpos to its row number. */
12173 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row
));
12174 w
->window_end_bytepos
12175 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
12177 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
12179 = make_number (MATRIX_ROW_VPOS (last_text_row
, w
->desired_matrix
));
12180 xassert (MATRIX_ROW (w
->desired_matrix
, XFASTINT (w
->window_end_vpos
))
12181 ->displays_text_p
);
12185 w
->window_end_bytepos
= Z_BYTE
- ZV_BYTE
;
12186 w
->window_end_pos
= make_number (Z
- ZV
);
12187 w
->window_end_vpos
= make_number (0);
12190 /* But that is not valid info until redisplay finishes. */
12191 w
->window_end_valid
= Qnil
;
12197 /************************************************************************
12198 Window redisplay reusing current matrix when buffer has not changed
12199 ************************************************************************/
12201 /* Try redisplay of window W showing an unchanged buffer with a
12202 different window start than the last time it was displayed by
12203 reusing its current matrix. Value is non-zero if successful.
12204 W->start is the new window start. */
12207 try_window_reusing_current_matrix (w
)
12210 struct frame
*f
= XFRAME (w
->frame
);
12211 struct glyph_row
*row
, *bottom_row
;
12214 struct text_pos start
, new_start
;
12215 int nrows_scrolled
, i
;
12216 struct glyph_row
*last_text_row
;
12217 struct glyph_row
*last_reused_text_row
;
12218 struct glyph_row
*start_row
;
12219 int start_vpos
, min_y
, max_y
;
12222 if (inhibit_try_window_reusing
)
12226 if (/* This function doesn't handle terminal frames. */
12227 !FRAME_WINDOW_P (f
)
12228 /* Don't try to reuse the display if windows have been split
12230 || windows_or_buffers_changed
12231 || cursor_type_changed
)
12234 /* Can't do this if region may have changed. */
12235 if ((!NILP (Vtransient_mark_mode
)
12236 && !NILP (current_buffer
->mark_active
))
12237 || !NILP (w
->region_showing
)
12238 || !NILP (Vshow_trailing_whitespace
))
12241 /* If top-line visibility has changed, give up. */
12242 if (WINDOW_WANTS_HEADER_LINE_P (w
)
12243 != MATRIX_HEADER_LINE_ROW (w
->current_matrix
)->mode_line_p
)
12246 /* Give up if old or new display is scrolled vertically. We could
12247 make this function handle this, but right now it doesn't. */
12248 start_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
12249 if (w
->vscroll
|| MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row
))
12252 /* The variable new_start now holds the new window start. The old
12253 start `start' can be determined from the current matrix. */
12254 SET_TEXT_POS_FROM_MARKER (new_start
, w
->start
);
12255 start
= start_row
->start
.pos
;
12256 start_vpos
= MATRIX_ROW_VPOS (start_row
, w
->current_matrix
);
12258 /* Clear the desired matrix for the display below. */
12259 clear_glyph_matrix (w
->desired_matrix
);
12261 if (CHARPOS (new_start
) <= CHARPOS (start
))
12265 /* Don't use this method if the display starts with an ellipsis
12266 displayed for invisible text. It's not easy to handle that case
12267 below, and it's certainly not worth the effort since this is
12268 not a frequent case. */
12269 if (in_ellipses_for_invisible_text_p (&start_row
->start
, w
))
12272 IF_DEBUG (debug_method_add (w
, "twu1"));
12274 /* Display up to a row that can be reused. The variable
12275 last_text_row is set to the last row displayed that displays
12276 text. Note that it.vpos == 0 if or if not there is a
12277 header-line; it's not the same as the MATRIX_ROW_VPOS! */
12278 start_display (&it
, w
, new_start
);
12279 first_row_y
= it
.current_y
;
12280 w
->cursor
.vpos
= -1;
12281 last_text_row
= last_reused_text_row
= NULL
;
12283 while (it
.current_y
< it
.last_visible_y
12284 && IT_CHARPOS (it
) < CHARPOS (start
)
12285 && !fonts_changed_p
)
12286 if (display_line (&it
))
12287 last_text_row
= it
.glyph_row
- 1;
12289 /* A value of current_y < last_visible_y means that we stopped
12290 at the previous window start, which in turn means that we
12291 have at least one reusable row. */
12292 if (it
.current_y
< it
.last_visible_y
)
12294 /* IT.vpos always starts from 0; it counts text lines. */
12295 nrows_scrolled
= it
.vpos
;
12297 /* Find PT if not already found in the lines displayed. */
12298 if (w
->cursor
.vpos
< 0)
12300 int dy
= it
.current_y
- first_row_y
;
12302 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
12303 row
= row_containing_pos (w
, PT
, row
, NULL
, dy
);
12305 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0,
12306 dy
, nrows_scrolled
);
12309 clear_glyph_matrix (w
->desired_matrix
);
12314 /* Scroll the display. Do it before the current matrix is
12315 changed. The problem here is that update has not yet
12316 run, i.e. part of the current matrix is not up to date.
12317 scroll_run_hook will clear the cursor, and use the
12318 current matrix to get the height of the row the cursor is
12320 run
.current_y
= first_row_y
;
12321 run
.desired_y
= it
.current_y
;
12322 run
.height
= it
.last_visible_y
- it
.current_y
;
12324 if (run
.height
> 0 && run
.current_y
!= run
.desired_y
)
12327 FRAME_RIF (f
)->update_window_begin_hook (w
);
12328 FRAME_RIF (f
)->clear_window_mouse_face (w
);
12329 FRAME_RIF (f
)->scroll_run_hook (w
, &run
);
12330 FRAME_RIF (f
)->update_window_end_hook (w
, 0, 0);
12334 /* Shift current matrix down by nrows_scrolled lines. */
12335 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
12336 rotate_matrix (w
->current_matrix
,
12338 MATRIX_ROW_VPOS (bottom_row
, w
->current_matrix
),
12341 /* Disable lines that must be updated. */
12342 for (i
= 0; i
< it
.vpos
; ++i
)
12343 (start_row
+ i
)->enabled_p
= 0;
12345 /* Re-compute Y positions. */
12346 min_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
12347 max_y
= it
.last_visible_y
;
12348 for (row
= start_row
+ nrows_scrolled
;
12352 row
->y
= it
.current_y
;
12353 row
->visible_height
= row
->height
;
12355 if (row
->y
< min_y
)
12356 row
->visible_height
-= min_y
- row
->y
;
12357 if (row
->y
+ row
->height
> max_y
)
12358 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
12359 row
->redraw_fringe_bitmaps_p
= 1;
12361 it
.current_y
+= row
->height
;
12363 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
12364 last_reused_text_row
= row
;
12365 if (MATRIX_ROW_BOTTOM_Y (row
) >= it
.last_visible_y
)
12369 /* Disable lines in the current matrix which are now
12370 below the window. */
12371 for (++row
; row
< bottom_row
; ++row
)
12372 row
->enabled_p
= 0;
12375 /* Update window_end_pos etc.; last_reused_text_row is the last
12376 reused row from the current matrix containing text, if any.
12377 The value of last_text_row is the last displayed line
12378 containing text. */
12379 if (last_reused_text_row
)
12381 w
->window_end_bytepos
12382 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_reused_text_row
);
12384 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_reused_text_row
));
12386 = make_number (MATRIX_ROW_VPOS (last_reused_text_row
,
12387 w
->current_matrix
));
12389 else if (last_text_row
)
12391 w
->window_end_bytepos
12392 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
12394 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
12396 = make_number (MATRIX_ROW_VPOS (last_text_row
, w
->desired_matrix
));
12400 /* This window must be completely empty. */
12401 w
->window_end_bytepos
= Z_BYTE
- ZV_BYTE
;
12402 w
->window_end_pos
= make_number (Z
- ZV
);
12403 w
->window_end_vpos
= make_number (0);
12405 w
->window_end_valid
= Qnil
;
12407 /* Update hint: don't try scrolling again in update_window. */
12408 w
->desired_matrix
->no_scrolling_p
= 1;
12411 debug_method_add (w
, "try_window_reusing_current_matrix 1");
12415 else if (CHARPOS (new_start
) > CHARPOS (start
))
12417 struct glyph_row
*pt_row
, *row
;
12418 struct glyph_row
*first_reusable_row
;
12419 struct glyph_row
*first_row_to_display
;
12421 int yb
= window_text_bottom_y (w
);
12423 /* Find the row starting at new_start, if there is one. Don't
12424 reuse a partially visible line at the end. */
12425 first_reusable_row
= start_row
;
12426 while (first_reusable_row
->enabled_p
12427 && MATRIX_ROW_BOTTOM_Y (first_reusable_row
) < yb
12428 && (MATRIX_ROW_START_CHARPOS (first_reusable_row
)
12429 < CHARPOS (new_start
)))
12430 ++first_reusable_row
;
12432 /* Give up if there is no row to reuse. */
12433 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row
) >= yb
12434 || !first_reusable_row
->enabled_p
12435 || (MATRIX_ROW_START_CHARPOS (first_reusable_row
)
12436 != CHARPOS (new_start
)))
12439 /* We can reuse fully visible rows beginning with
12440 first_reusable_row to the end of the window. Set
12441 first_row_to_display to the first row that cannot be reused.
12442 Set pt_row to the row containing point, if there is any. */
12444 for (first_row_to_display
= first_reusable_row
;
12445 MATRIX_ROW_BOTTOM_Y (first_row_to_display
) < yb
;
12446 ++first_row_to_display
)
12448 if (PT
>= MATRIX_ROW_START_CHARPOS (first_row_to_display
)
12449 && PT
< MATRIX_ROW_END_CHARPOS (first_row_to_display
))
12450 pt_row
= first_row_to_display
;
12453 /* Start displaying at the start of first_row_to_display. */
12454 xassert (first_row_to_display
->y
< yb
);
12455 init_to_row_start (&it
, w
, first_row_to_display
);
12457 nrows_scrolled
= (MATRIX_ROW_VPOS (first_reusable_row
, w
->current_matrix
)
12459 it
.vpos
= (MATRIX_ROW_VPOS (first_row_to_display
, w
->current_matrix
)
12461 it
.current_y
= (first_row_to_display
->y
- first_reusable_row
->y
12462 + WINDOW_HEADER_LINE_HEIGHT (w
));
12464 /* Display lines beginning with first_row_to_display in the
12465 desired matrix. Set last_text_row to the last row displayed
12466 that displays text. */
12467 it
.glyph_row
= MATRIX_ROW (w
->desired_matrix
, it
.vpos
);
12468 if (pt_row
== NULL
)
12469 w
->cursor
.vpos
= -1;
12470 last_text_row
= NULL
;
12471 while (it
.current_y
< it
.last_visible_y
&& !fonts_changed_p
)
12472 if (display_line (&it
))
12473 last_text_row
= it
.glyph_row
- 1;
12475 /* Give up If point isn't in a row displayed or reused. */
12476 if (w
->cursor
.vpos
< 0)
12478 clear_glyph_matrix (w
->desired_matrix
);
12482 /* If point is in a reused row, adjust y and vpos of the cursor
12486 w
->cursor
.vpos
-= MATRIX_ROW_VPOS (first_reusable_row
,
12487 w
->current_matrix
);
12488 w
->cursor
.y
-= first_reusable_row
->y
;
12491 /* Scroll the display. */
12492 run
.current_y
= first_reusable_row
->y
;
12493 run
.desired_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
12494 run
.height
= it
.last_visible_y
- run
.current_y
;
12495 dy
= run
.current_y
- run
.desired_y
;
12500 FRAME_RIF (f
)->update_window_begin_hook (w
);
12501 FRAME_RIF (f
)->clear_window_mouse_face (w
);
12502 FRAME_RIF (f
)->scroll_run_hook (w
, &run
);
12503 FRAME_RIF (f
)->update_window_end_hook (w
, 0, 0);
12507 /* Adjust Y positions of reused rows. */
12508 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
12509 min_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
12510 max_y
= it
.last_visible_y
;
12511 for (row
= first_reusable_row
; row
< first_row_to_display
; ++row
)
12514 row
->visible_height
= row
->height
;
12515 if (row
->y
< min_y
)
12516 row
->visible_height
-= min_y
- row
->y
;
12517 if (row
->y
+ row
->height
> max_y
)
12518 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
12519 row
->redraw_fringe_bitmaps_p
= 1;
12522 /* Scroll the current matrix. */
12523 xassert (nrows_scrolled
> 0);
12524 rotate_matrix (w
->current_matrix
,
12526 MATRIX_ROW_VPOS (bottom_row
, w
->current_matrix
),
12529 /* Disable rows not reused. */
12530 for (row
-= nrows_scrolled
; row
< bottom_row
; ++row
)
12531 row
->enabled_p
= 0;
12533 /* Adjust window end. A null value of last_text_row means that
12534 the window end is in reused rows which in turn means that
12535 only its vpos can have changed. */
12538 w
->window_end_bytepos
12539 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
12541 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
12543 = make_number (MATRIX_ROW_VPOS (last_text_row
, w
->desired_matrix
));
12548 = make_number (XFASTINT (w
->window_end_vpos
) - nrows_scrolled
);
12551 w
->window_end_valid
= Qnil
;
12552 w
->desired_matrix
->no_scrolling_p
= 1;
12555 debug_method_add (w
, "try_window_reusing_current_matrix 2");
12565 /************************************************************************
12566 Window redisplay reusing current matrix when buffer has changed
12567 ************************************************************************/
12569 static struct glyph_row
*find_last_unchanged_at_beg_row
P_ ((struct window
*));
12570 static struct glyph_row
*find_first_unchanged_at_end_row
P_ ((struct window
*,
12572 static struct glyph_row
*
12573 find_last_row_displaying_text
P_ ((struct glyph_matrix
*, struct it
*,
12574 struct glyph_row
*));
12577 /* Return the last row in MATRIX displaying text. If row START is
12578 non-null, start searching with that row. IT gives the dimensions
12579 of the display. Value is null if matrix is empty; otherwise it is
12580 a pointer to the row found. */
12582 static struct glyph_row
*
12583 find_last_row_displaying_text (matrix
, it
, start
)
12584 struct glyph_matrix
*matrix
;
12586 struct glyph_row
*start
;
12588 struct glyph_row
*row
, *row_found
;
12590 /* Set row_found to the last row in IT->w's current matrix
12591 displaying text. The loop looks funny but think of partially
12594 row
= start
? start
: MATRIX_FIRST_TEXT_ROW (matrix
);
12595 while (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
12597 xassert (row
->enabled_p
);
12599 if (MATRIX_ROW_BOTTOM_Y (row
) >= it
->last_visible_y
)
12608 /* Return the last row in the current matrix of W that is not affected
12609 by changes at the start of current_buffer that occurred since W's
12610 current matrix was built. Value is null if no such row exists.
12612 BEG_UNCHANGED us the number of characters unchanged at the start of
12613 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
12614 first changed character in current_buffer. Characters at positions <
12615 BEG + BEG_UNCHANGED are at the same buffer positions as they were
12616 when the current matrix was built. */
12618 static struct glyph_row
*
12619 find_last_unchanged_at_beg_row (w
)
12622 int first_changed_pos
= BEG
+ BEG_UNCHANGED
;
12623 struct glyph_row
*row
;
12624 struct glyph_row
*row_found
= NULL
;
12625 int yb
= window_text_bottom_y (w
);
12627 /* Find the last row displaying unchanged text. */
12628 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
12629 while (MATRIX_ROW_DISPLAYS_TEXT_P (row
)
12630 && MATRIX_ROW_START_CHARPOS (row
) < first_changed_pos
)
12632 if (/* If row ends before first_changed_pos, it is unchanged,
12633 except in some case. */
12634 MATRIX_ROW_END_CHARPOS (row
) <= first_changed_pos
12635 /* When row ends in ZV and we write at ZV it is not
12637 && !row
->ends_at_zv_p
12638 /* When first_changed_pos is the end of a continued line,
12639 row is not unchanged because it may be no longer
12641 && !(MATRIX_ROW_END_CHARPOS (row
) == first_changed_pos
12642 && (row
->continued_p
12643 || row
->exact_window_width_line_p
)))
12646 /* Stop if last visible row. */
12647 if (MATRIX_ROW_BOTTOM_Y (row
) >= yb
)
12657 /* Find the first glyph row in the current matrix of W that is not
12658 affected by changes at the end of current_buffer since the
12659 time W's current matrix was built.
12661 Return in *DELTA the number of chars by which buffer positions in
12662 unchanged text at the end of current_buffer must be adjusted.
12664 Return in *DELTA_BYTES the corresponding number of bytes.
12666 Value is null if no such row exists, i.e. all rows are affected by
12669 static struct glyph_row
*
12670 find_first_unchanged_at_end_row (w
, delta
, delta_bytes
)
12672 int *delta
, *delta_bytes
;
12674 struct glyph_row
*row
;
12675 struct glyph_row
*row_found
= NULL
;
12677 *delta
= *delta_bytes
= 0;
12679 /* Display must not have been paused, otherwise the current matrix
12680 is not up to date. */
12681 if (NILP (w
->window_end_valid
))
12684 /* A value of window_end_pos >= END_UNCHANGED means that the window
12685 end is in the range of changed text. If so, there is no
12686 unchanged row at the end of W's current matrix. */
12687 if (XFASTINT (w
->window_end_pos
) >= END_UNCHANGED
)
12690 /* Set row to the last row in W's current matrix displaying text. */
12691 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
12693 /* If matrix is entirely empty, no unchanged row exists. */
12694 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
12696 /* The value of row is the last glyph row in the matrix having a
12697 meaningful buffer position in it. The end position of row
12698 corresponds to window_end_pos. This allows us to translate
12699 buffer positions in the current matrix to current buffer
12700 positions for characters not in changed text. */
12701 int Z_old
= MATRIX_ROW_END_CHARPOS (row
) + XFASTINT (w
->window_end_pos
);
12702 int Z_BYTE_old
= MATRIX_ROW_END_BYTEPOS (row
) + w
->window_end_bytepos
;
12703 int last_unchanged_pos
, last_unchanged_pos_old
;
12704 struct glyph_row
*first_text_row
12705 = MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
12707 *delta
= Z
- Z_old
;
12708 *delta_bytes
= Z_BYTE
- Z_BYTE_old
;
12710 /* Set last_unchanged_pos to the buffer position of the last
12711 character in the buffer that has not been changed. Z is the
12712 index + 1 of the last character in current_buffer, i.e. by
12713 subtracting END_UNCHANGED we get the index of the last
12714 unchanged character, and we have to add BEG to get its buffer
12716 last_unchanged_pos
= Z
- END_UNCHANGED
+ BEG
;
12717 last_unchanged_pos_old
= last_unchanged_pos
- *delta
;
12719 /* Search backward from ROW for a row displaying a line that
12720 starts at a minimum position >= last_unchanged_pos_old. */
12721 for (; row
> first_text_row
; --row
)
12723 if (!row
->enabled_p
|| !MATRIX_ROW_DISPLAYS_TEXT_P (row
))
12726 if (MATRIX_ROW_START_CHARPOS (row
) >= last_unchanged_pos_old
)
12731 if (row_found
&& !MATRIX_ROW_DISPLAYS_TEXT_P (row_found
))
12738 /* Make sure that glyph rows in the current matrix of window W
12739 reference the same glyph memory as corresponding rows in the
12740 frame's frame matrix. This function is called after scrolling W's
12741 current matrix on a terminal frame in try_window_id and
12742 try_window_reusing_current_matrix. */
12745 sync_frame_with_window_matrix_rows (w
)
12748 struct frame
*f
= XFRAME (w
->frame
);
12749 struct glyph_row
*window_row
, *window_row_end
, *frame_row
;
12751 /* Preconditions: W must be a leaf window and full-width. Its frame
12752 must have a frame matrix. */
12753 xassert (NILP (w
->hchild
) && NILP (w
->vchild
));
12754 xassert (WINDOW_FULL_WIDTH_P (w
));
12755 xassert (!FRAME_WINDOW_P (f
));
12757 /* If W is a full-width window, glyph pointers in W's current matrix
12758 have, by definition, to be the same as glyph pointers in the
12759 corresponding frame matrix. Note that frame matrices have no
12760 marginal areas (see build_frame_matrix). */
12761 window_row
= w
->current_matrix
->rows
;
12762 window_row_end
= window_row
+ w
->current_matrix
->nrows
;
12763 frame_row
= f
->current_matrix
->rows
+ WINDOW_TOP_EDGE_LINE (w
);
12764 while (window_row
< window_row_end
)
12766 struct glyph
*start
= window_row
->glyphs
[LEFT_MARGIN_AREA
];
12767 struct glyph
*end
= window_row
->glyphs
[LAST_AREA
];
12769 frame_row
->glyphs
[LEFT_MARGIN_AREA
] = start
;
12770 frame_row
->glyphs
[TEXT_AREA
] = start
;
12771 frame_row
->glyphs
[RIGHT_MARGIN_AREA
] = end
;
12772 frame_row
->glyphs
[LAST_AREA
] = end
;
12774 /* Disable frame rows whose corresponding window rows have
12775 been disabled in try_window_id. */
12776 if (!window_row
->enabled_p
)
12777 frame_row
->enabled_p
= 0;
12779 ++window_row
, ++frame_row
;
12784 /* Find the glyph row in window W containing CHARPOS. Consider all
12785 rows between START and END (not inclusive). END null means search
12786 all rows to the end of the display area of W. Value is the row
12787 containing CHARPOS or null. */
12790 row_containing_pos (w
, charpos
, start
, end
, dy
)
12793 struct glyph_row
*start
, *end
;
12796 struct glyph_row
*row
= start
;
12799 /* If we happen to start on a header-line, skip that. */
12800 if (row
->mode_line_p
)
12803 if ((end
&& row
>= end
) || !row
->enabled_p
)
12806 last_y
= window_text_bottom_y (w
) - dy
;
12810 /* Give up if we have gone too far. */
12811 if (end
&& row
>= end
)
12813 /* This formerly returned if they were equal.
12814 I think that both quantities are of a "last plus one" type;
12815 if so, when they are equal, the row is within the screen. -- rms. */
12816 if (MATRIX_ROW_BOTTOM_Y (row
) > last_y
)
12819 /* If it is in this row, return this row. */
12820 if (! (MATRIX_ROW_END_CHARPOS (row
) < charpos
12821 || (MATRIX_ROW_END_CHARPOS (row
) == charpos
12822 /* The end position of a row equals the start
12823 position of the next row. If CHARPOS is there, we
12824 would rather display it in the next line, except
12825 when this line ends in ZV. */
12826 && !row
->ends_at_zv_p
12827 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
)))
12828 && charpos
>= MATRIX_ROW_START_CHARPOS (row
))
12835 /* Try to redisplay window W by reusing its existing display. W's
12836 current matrix must be up to date when this function is called,
12837 i.e. window_end_valid must not be nil.
12841 1 if display has been updated
12842 0 if otherwise unsuccessful
12843 -1 if redisplay with same window start is known not to succeed
12845 The following steps are performed:
12847 1. Find the last row in the current matrix of W that is not
12848 affected by changes at the start of current_buffer. If no such row
12851 2. Find the first row in W's current matrix that is not affected by
12852 changes at the end of current_buffer. Maybe there is no such row.
12854 3. Display lines beginning with the row + 1 found in step 1 to the
12855 row found in step 2 or, if step 2 didn't find a row, to the end of
12858 4. If cursor is not known to appear on the window, give up.
12860 5. If display stopped at the row found in step 2, scroll the
12861 display and current matrix as needed.
12863 6. Maybe display some lines at the end of W, if we must. This can
12864 happen under various circumstances, like a partially visible line
12865 becoming fully visible, or because newly displayed lines are displayed
12866 in smaller font sizes.
12868 7. Update W's window end information. */
12874 struct frame
*f
= XFRAME (w
->frame
);
12875 struct glyph_matrix
*current_matrix
= w
->current_matrix
;
12876 struct glyph_matrix
*desired_matrix
= w
->desired_matrix
;
12877 struct glyph_row
*last_unchanged_at_beg_row
;
12878 struct glyph_row
*first_unchanged_at_end_row
;
12879 struct glyph_row
*row
;
12880 struct glyph_row
*bottom_row
;
12883 int delta
= 0, delta_bytes
= 0, stop_pos
, dvpos
, dy
;
12884 struct text_pos start_pos
;
12886 int first_unchanged_at_end_vpos
= 0;
12887 struct glyph_row
*last_text_row
, *last_text_row_at_end
;
12888 struct text_pos start
;
12889 int first_changed_charpos
, last_changed_charpos
;
12892 if (inhibit_try_window_id
)
12896 /* This is handy for debugging. */
12898 #define GIVE_UP(X) \
12900 fprintf (stderr, "try_window_id give up %d\n", (X)); \
12904 #define GIVE_UP(X) return 0
12907 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
12909 /* Don't use this for mini-windows because these can show
12910 messages and mini-buffers, and we don't handle that here. */
12911 if (MINI_WINDOW_P (w
))
12914 /* This flag is used to prevent redisplay optimizations. */
12915 if (windows_or_buffers_changed
|| cursor_type_changed
)
12918 /* Verify that narrowing has not changed.
12919 Also verify that we were not told to prevent redisplay optimizations.
12920 It would be nice to further
12921 reduce the number of cases where this prevents try_window_id. */
12922 if (current_buffer
->clip_changed
12923 || current_buffer
->prevent_redisplay_optimizations_p
)
12926 /* Window must either use window-based redisplay or be full width. */
12927 if (!FRAME_WINDOW_P (f
)
12928 && (!FRAME_LINE_INS_DEL_OK (f
)
12929 || !WINDOW_FULL_WIDTH_P (w
)))
12932 /* Give up if point is not known NOT to appear in W. */
12933 if (PT
< CHARPOS (start
))
12936 /* Another way to prevent redisplay optimizations. */
12937 if (XFASTINT (w
->last_modified
) == 0)
12940 /* Verify that window is not hscrolled. */
12941 if (XFASTINT (w
->hscroll
) != 0)
12944 /* Verify that display wasn't paused. */
12945 if (NILP (w
->window_end_valid
))
12948 /* Can't use this if highlighting a region because a cursor movement
12949 will do more than just set the cursor. */
12950 if (!NILP (Vtransient_mark_mode
)
12951 && !NILP (current_buffer
->mark_active
))
12954 /* Likewise if highlighting trailing whitespace. */
12955 if (!NILP (Vshow_trailing_whitespace
))
12958 /* Likewise if showing a region. */
12959 if (!NILP (w
->region_showing
))
12962 /* Can use this if overlay arrow position and or string have changed. */
12963 if (overlay_arrows_changed_p ())
12967 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
12968 only if buffer has really changed. The reason is that the gap is
12969 initially at Z for freshly visited files. The code below would
12970 set end_unchanged to 0 in that case. */
12971 if (MODIFF
> SAVE_MODIFF
12972 /* This seems to happen sometimes after saving a buffer. */
12973 || BEG_UNCHANGED
+ END_UNCHANGED
> Z_BYTE
)
12975 if (GPT
- BEG
< BEG_UNCHANGED
)
12976 BEG_UNCHANGED
= GPT
- BEG
;
12977 if (Z
- GPT
< END_UNCHANGED
)
12978 END_UNCHANGED
= Z
- GPT
;
12981 /* The position of the first and last character that has been changed. */
12982 first_changed_charpos
= BEG
+ BEG_UNCHANGED
;
12983 last_changed_charpos
= Z
- END_UNCHANGED
;
12985 /* If window starts after a line end, and the last change is in
12986 front of that newline, then changes don't affect the display.
12987 This case happens with stealth-fontification. Note that although
12988 the display is unchanged, glyph positions in the matrix have to
12989 be adjusted, of course. */
12990 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
12991 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
)
12992 && ((last_changed_charpos
< CHARPOS (start
)
12993 && CHARPOS (start
) == BEGV
)
12994 || (last_changed_charpos
< CHARPOS (start
) - 1
12995 && FETCH_BYTE (BYTEPOS (start
) - 1) == '\n')))
12997 int Z_old
, delta
, Z_BYTE_old
, delta_bytes
;
12998 struct glyph_row
*r0
;
13000 /* Compute how many chars/bytes have been added to or removed
13001 from the buffer. */
13002 Z_old
= MATRIX_ROW_END_CHARPOS (row
) + XFASTINT (w
->window_end_pos
);
13003 Z_BYTE_old
= MATRIX_ROW_END_BYTEPOS (row
) + w
->window_end_bytepos
;
13005 delta_bytes
= Z_BYTE
- Z_BYTE_old
;
13007 /* Give up if PT is not in the window. Note that it already has
13008 been checked at the start of try_window_id that PT is not in
13009 front of the window start. */
13010 if (PT
>= MATRIX_ROW_END_CHARPOS (row
) + delta
)
13013 /* If window start is unchanged, we can reuse the whole matrix
13014 as is, after adjusting glyph positions. No need to compute
13015 the window end again, since its offset from Z hasn't changed. */
13016 r0
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
13017 if (CHARPOS (start
) == MATRIX_ROW_START_CHARPOS (r0
) + delta
13018 && BYTEPOS (start
) == MATRIX_ROW_START_BYTEPOS (r0
) + delta_bytes
13019 /* PT must not be in a partially visible line. */
13020 && !(PT
>= MATRIX_ROW_START_CHARPOS (row
) + delta
13021 && MATRIX_ROW_BOTTOM_Y (row
) > window_text_bottom_y (w
)))
13023 /* Adjust positions in the glyph matrix. */
13024 if (delta
|| delta_bytes
)
13026 struct glyph_row
*r1
13027 = MATRIX_BOTTOM_TEXT_ROW (current_matrix
, w
);
13028 increment_matrix_positions (w
->current_matrix
,
13029 MATRIX_ROW_VPOS (r0
, current_matrix
),
13030 MATRIX_ROW_VPOS (r1
, current_matrix
),
13031 delta
, delta_bytes
);
13034 /* Set the cursor. */
13035 row
= row_containing_pos (w
, PT
, r0
, NULL
, 0);
13037 set_cursor_from_row (w
, row
, current_matrix
, 0, 0, 0, 0);
13044 /* Handle the case that changes are all below what is displayed in
13045 the window, and that PT is in the window. This shortcut cannot
13046 be taken if ZV is visible in the window, and text has been added
13047 there that is visible in the window. */
13048 if (first_changed_charpos
>= MATRIX_ROW_END_CHARPOS (row
)
13049 /* ZV is not visible in the window, or there are no
13050 changes at ZV, actually. */
13051 && (current_matrix
->zv
> MATRIX_ROW_END_CHARPOS (row
)
13052 || first_changed_charpos
== last_changed_charpos
))
13054 struct glyph_row
*r0
;
13056 /* Give up if PT is not in the window. Note that it already has
13057 been checked at the start of try_window_id that PT is not in
13058 front of the window start. */
13059 if (PT
>= MATRIX_ROW_END_CHARPOS (row
))
13062 /* If window start is unchanged, we can reuse the whole matrix
13063 as is, without changing glyph positions since no text has
13064 been added/removed in front of the window end. */
13065 r0
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
13066 if (TEXT_POS_EQUAL_P (start
, r0
->start
.pos
)
13067 /* PT must not be in a partially visible line. */
13068 && !(PT
>= MATRIX_ROW_START_CHARPOS (row
)
13069 && MATRIX_ROW_BOTTOM_Y (row
) > window_text_bottom_y (w
)))
13071 /* We have to compute the window end anew since text
13072 can have been added/removed after it. */
13074 = make_number (Z
- MATRIX_ROW_END_CHARPOS (row
));
13075 w
->window_end_bytepos
13076 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
13078 /* Set the cursor. */
13079 row
= row_containing_pos (w
, PT
, r0
, NULL
, 0);
13081 set_cursor_from_row (w
, row
, current_matrix
, 0, 0, 0, 0);
13088 /* Give up if window start is in the changed area.
13090 The condition used to read
13092 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
13094 but why that was tested escapes me at the moment. */
13095 if (CHARPOS (start
) >= first_changed_charpos
13096 && CHARPOS (start
) <= last_changed_charpos
)
13099 /* Check that window start agrees with the start of the first glyph
13100 row in its current matrix. Check this after we know the window
13101 start is not in changed text, otherwise positions would not be
13103 row
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
13104 if (!TEXT_POS_EQUAL_P (start
, row
->start
.pos
))
13107 /* Give up if the window ends in strings. Overlay strings
13108 at the end are difficult to handle, so don't try. */
13109 row
= MATRIX_ROW (current_matrix
, XFASTINT (w
->window_end_vpos
));
13110 if (MATRIX_ROW_START_CHARPOS (row
) == MATRIX_ROW_END_CHARPOS (row
))
13113 /* Compute the position at which we have to start displaying new
13114 lines. Some of the lines at the top of the window might be
13115 reusable because they are not displaying changed text. Find the
13116 last row in W's current matrix not affected by changes at the
13117 start of current_buffer. Value is null if changes start in the
13118 first line of window. */
13119 last_unchanged_at_beg_row
= find_last_unchanged_at_beg_row (w
);
13120 if (last_unchanged_at_beg_row
)
13122 /* Avoid starting to display in the moddle of a character, a TAB
13123 for instance. This is easier than to set up the iterator
13124 exactly, and it's not a frequent case, so the additional
13125 effort wouldn't really pay off. */
13126 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row
)
13127 || last_unchanged_at_beg_row
->ends_in_newline_from_string_p
)
13128 && last_unchanged_at_beg_row
> w
->current_matrix
->rows
)
13129 --last_unchanged_at_beg_row
;
13131 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row
))
13134 if (init_to_row_end (&it
, w
, last_unchanged_at_beg_row
) == 0)
13136 start_pos
= it
.current
.pos
;
13138 /* Start displaying new lines in the desired matrix at the same
13139 vpos we would use in the current matrix, i.e. below
13140 last_unchanged_at_beg_row. */
13141 it
.vpos
= 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row
,
13143 it
.glyph_row
= MATRIX_ROW (desired_matrix
, it
.vpos
);
13144 it
.current_y
= MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row
);
13146 xassert (it
.hpos
== 0 && it
.current_x
== 0);
13150 /* There are no reusable lines at the start of the window.
13151 Start displaying in the first text line. */
13152 start_display (&it
, w
, start
);
13153 it
.vpos
= it
.first_vpos
;
13154 start_pos
= it
.current
.pos
;
13157 /* Find the first row that is not affected by changes at the end of
13158 the buffer. Value will be null if there is no unchanged row, in
13159 which case we must redisplay to the end of the window. delta
13160 will be set to the value by which buffer positions beginning with
13161 first_unchanged_at_end_row have to be adjusted due to text
13163 first_unchanged_at_end_row
13164 = find_first_unchanged_at_end_row (w
, &delta
, &delta_bytes
);
13165 IF_DEBUG (debug_delta
= delta
);
13166 IF_DEBUG (debug_delta_bytes
= delta_bytes
);
13168 /* Set stop_pos to the buffer position up to which we will have to
13169 display new lines. If first_unchanged_at_end_row != NULL, this
13170 is the buffer position of the start of the line displayed in that
13171 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
13172 that we don't stop at a buffer position. */
13174 if (first_unchanged_at_end_row
)
13176 xassert (last_unchanged_at_beg_row
== NULL
13177 || first_unchanged_at_end_row
>= last_unchanged_at_beg_row
);
13179 /* If this is a continuation line, move forward to the next one
13180 that isn't. Changes in lines above affect this line.
13181 Caution: this may move first_unchanged_at_end_row to a row
13182 not displaying text. */
13183 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row
)
13184 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
)
13185 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row
)
13186 < it
.last_visible_y
))
13187 ++first_unchanged_at_end_row
;
13189 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
)
13190 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row
)
13191 >= it
.last_visible_y
))
13192 first_unchanged_at_end_row
= NULL
;
13195 stop_pos
= (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row
)
13197 first_unchanged_at_end_vpos
13198 = MATRIX_ROW_VPOS (first_unchanged_at_end_row
, current_matrix
);
13199 xassert (stop_pos
>= Z
- END_UNCHANGED
);
13202 else if (last_unchanged_at_beg_row
== NULL
)
13208 /* Either there is no unchanged row at the end, or the one we have
13209 now displays text. This is a necessary condition for the window
13210 end pos calculation at the end of this function. */
13211 xassert (first_unchanged_at_end_row
== NULL
13212 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
));
13214 debug_last_unchanged_at_beg_vpos
13215 = (last_unchanged_at_beg_row
13216 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row
, current_matrix
)
13218 debug_first_unchanged_at_end_vpos
= first_unchanged_at_end_vpos
;
13220 #endif /* GLYPH_DEBUG != 0 */
13223 /* Display new lines. Set last_text_row to the last new line
13224 displayed which has text on it, i.e. might end up as being the
13225 line where the window_end_vpos is. */
13226 w
->cursor
.vpos
= -1;
13227 last_text_row
= NULL
;
13228 overlay_arrow_seen
= 0;
13229 while (it
.current_y
< it
.last_visible_y
13230 && !fonts_changed_p
13231 && (first_unchanged_at_end_row
== NULL
13232 || IT_CHARPOS (it
) < stop_pos
))
13234 if (display_line (&it
))
13235 last_text_row
= it
.glyph_row
- 1;
13238 if (fonts_changed_p
)
13242 /* Compute differences in buffer positions, y-positions etc. for
13243 lines reused at the bottom of the window. Compute what we can
13245 if (first_unchanged_at_end_row
13246 /* No lines reused because we displayed everything up to the
13247 bottom of the window. */
13248 && it
.current_y
< it
.last_visible_y
)
13251 - MATRIX_ROW_VPOS (first_unchanged_at_end_row
,
13253 dy
= it
.current_y
- first_unchanged_at_end_row
->y
;
13254 run
.current_y
= first_unchanged_at_end_row
->y
;
13255 run
.desired_y
= run
.current_y
+ dy
;
13256 run
.height
= it
.last_visible_y
- max (run
.current_y
, run
.desired_y
);
13260 delta
= dvpos
= dy
= run
.current_y
= run
.desired_y
= run
.height
= 0;
13261 first_unchanged_at_end_row
= NULL
;
13263 IF_DEBUG (debug_dvpos
= dvpos
; debug_dy
= dy
);
13266 /* Find the cursor if not already found. We have to decide whether
13267 PT will appear on this window (it sometimes doesn't, but this is
13268 not a very frequent case.) This decision has to be made before
13269 the current matrix is altered. A value of cursor.vpos < 0 means
13270 that PT is either in one of the lines beginning at
13271 first_unchanged_at_end_row or below the window. Don't care for
13272 lines that might be displayed later at the window end; as
13273 mentioned, this is not a frequent case. */
13274 if (w
->cursor
.vpos
< 0)
13276 /* Cursor in unchanged rows at the top? */
13277 if (PT
< CHARPOS (start_pos
)
13278 && last_unchanged_at_beg_row
)
13280 row
= row_containing_pos (w
, PT
,
13281 MATRIX_FIRST_TEXT_ROW (w
->current_matrix
),
13282 last_unchanged_at_beg_row
+ 1, 0);
13284 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
13287 /* Start from first_unchanged_at_end_row looking for PT. */
13288 else if (first_unchanged_at_end_row
)
13290 row
= row_containing_pos (w
, PT
- delta
,
13291 first_unchanged_at_end_row
, NULL
, 0);
13293 set_cursor_from_row (w
, row
, w
->current_matrix
, delta
,
13294 delta_bytes
, dy
, dvpos
);
13297 /* Give up if cursor was not found. */
13298 if (w
->cursor
.vpos
< 0)
13300 clear_glyph_matrix (w
->desired_matrix
);
13305 /* Don't let the cursor end in the scroll margins. */
13307 int this_scroll_margin
, cursor_height
;
13309 this_scroll_margin
= max (0, scroll_margin
);
13310 this_scroll_margin
= min (this_scroll_margin
, WINDOW_TOTAL_LINES (w
) / 4);
13311 this_scroll_margin
*= FRAME_LINE_HEIGHT (it
.f
);
13312 cursor_height
= MATRIX_ROW (w
->desired_matrix
, w
->cursor
.vpos
)->height
;
13314 if ((w
->cursor
.y
< this_scroll_margin
13315 && CHARPOS (start
) > BEGV
)
13316 /* Don't take scroll margin into account at the bottom because
13317 old redisplay didn't do it either. */
13318 || w
->cursor
.y
+ cursor_height
> it
.last_visible_y
)
13320 w
->cursor
.vpos
= -1;
13321 clear_glyph_matrix (w
->desired_matrix
);
13326 /* Scroll the display. Do it before changing the current matrix so
13327 that xterm.c doesn't get confused about where the cursor glyph is
13329 if (dy
&& run
.height
)
13333 if (FRAME_WINDOW_P (f
))
13335 FRAME_RIF (f
)->update_window_begin_hook (w
);
13336 FRAME_RIF (f
)->clear_window_mouse_face (w
);
13337 FRAME_RIF (f
)->scroll_run_hook (w
, &run
);
13338 FRAME_RIF (f
)->update_window_end_hook (w
, 0, 0);
13342 /* Terminal frame. In this case, dvpos gives the number of
13343 lines to scroll by; dvpos < 0 means scroll up. */
13344 int first_unchanged_at_end_vpos
13345 = MATRIX_ROW_VPOS (first_unchanged_at_end_row
, w
->current_matrix
);
13346 int from
= WINDOW_TOP_EDGE_LINE (w
) + first_unchanged_at_end_vpos
;
13347 int end
= (WINDOW_TOP_EDGE_LINE (w
)
13348 + (WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0)
13349 + window_internal_height (w
));
13351 /* Perform the operation on the screen. */
13354 /* Scroll last_unchanged_at_beg_row to the end of the
13355 window down dvpos lines. */
13356 set_terminal_window (f
, end
);
13358 /* On dumb terminals delete dvpos lines at the end
13359 before inserting dvpos empty lines. */
13360 if (!FRAME_SCROLL_REGION_OK (f
))
13361 ins_del_lines (f
, end
- dvpos
, -dvpos
);
13363 /* Insert dvpos empty lines in front of
13364 last_unchanged_at_beg_row. */
13365 ins_del_lines (f
, from
, dvpos
);
13367 else if (dvpos
< 0)
13369 /* Scroll up last_unchanged_at_beg_vpos to the end of
13370 the window to last_unchanged_at_beg_vpos - |dvpos|. */
13371 set_terminal_window (f
, end
);
13373 /* Delete dvpos lines in front of
13374 last_unchanged_at_beg_vpos. ins_del_lines will set
13375 the cursor to the given vpos and emit |dvpos| delete
13377 ins_del_lines (f
, from
+ dvpos
, dvpos
);
13379 /* On a dumb terminal insert dvpos empty lines at the
13381 if (!FRAME_SCROLL_REGION_OK (f
))
13382 ins_del_lines (f
, end
+ dvpos
, -dvpos
);
13385 set_terminal_window (f
, 0);
13391 /* Shift reused rows of the current matrix to the right position.
13392 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
13394 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (current_matrix
, w
);
13395 bottom_vpos
= MATRIX_ROW_VPOS (bottom_row
, current_matrix
);
13398 rotate_matrix (current_matrix
, first_unchanged_at_end_vpos
+ dvpos
,
13399 bottom_vpos
, dvpos
);
13400 enable_glyph_matrix_rows (current_matrix
, bottom_vpos
+ dvpos
,
13403 else if (dvpos
> 0)
13405 rotate_matrix (current_matrix
, first_unchanged_at_end_vpos
,
13406 bottom_vpos
, dvpos
);
13407 enable_glyph_matrix_rows (current_matrix
, first_unchanged_at_end_vpos
,
13408 first_unchanged_at_end_vpos
+ dvpos
, 0);
13411 /* For frame-based redisplay, make sure that current frame and window
13412 matrix are in sync with respect to glyph memory. */
13413 if (!FRAME_WINDOW_P (f
))
13414 sync_frame_with_window_matrix_rows (w
);
13416 /* Adjust buffer positions in reused rows. */
13418 increment_matrix_positions (current_matrix
,
13419 first_unchanged_at_end_vpos
+ dvpos
,
13420 bottom_vpos
, delta
, delta_bytes
);
13422 /* Adjust Y positions. */
13424 shift_glyph_matrix (w
, current_matrix
,
13425 first_unchanged_at_end_vpos
+ dvpos
,
13428 if (first_unchanged_at_end_row
)
13429 first_unchanged_at_end_row
+= dvpos
;
13431 /* If scrolling up, there may be some lines to display at the end of
13433 last_text_row_at_end
= NULL
;
13436 /* Scrolling up can leave for example a partially visible line
13437 at the end of the window to be redisplayed. */
13438 /* Set last_row to the glyph row in the current matrix where the
13439 window end line is found. It has been moved up or down in
13440 the matrix by dvpos. */
13441 int last_vpos
= XFASTINT (w
->window_end_vpos
) + dvpos
;
13442 struct glyph_row
*last_row
= MATRIX_ROW (current_matrix
, last_vpos
);
13444 /* If last_row is the window end line, it should display text. */
13445 xassert (last_row
->displays_text_p
);
13447 /* If window end line was partially visible before, begin
13448 displaying at that line. Otherwise begin displaying with the
13449 line following it. */
13450 if (MATRIX_ROW_BOTTOM_Y (last_row
) - dy
>= it
.last_visible_y
)
13452 init_to_row_start (&it
, w
, last_row
);
13453 it
.vpos
= last_vpos
;
13454 it
.current_y
= last_row
->y
;
13458 init_to_row_end (&it
, w
, last_row
);
13459 it
.vpos
= 1 + last_vpos
;
13460 it
.current_y
= MATRIX_ROW_BOTTOM_Y (last_row
);
13464 /* We may start in a continuation line. If so, we have to
13465 get the right continuation_lines_width and current_x. */
13466 it
.continuation_lines_width
= last_row
->continuation_lines_width
;
13467 it
.hpos
= it
.current_x
= 0;
13469 /* Display the rest of the lines at the window end. */
13470 it
.glyph_row
= MATRIX_ROW (desired_matrix
, it
.vpos
);
13471 while (it
.current_y
< it
.last_visible_y
13472 && !fonts_changed_p
)
13474 /* Is it always sure that the display agrees with lines in
13475 the current matrix? I don't think so, so we mark rows
13476 displayed invalid in the current matrix by setting their
13477 enabled_p flag to zero. */
13478 MATRIX_ROW (w
->current_matrix
, it
.vpos
)->enabled_p
= 0;
13479 if (display_line (&it
))
13480 last_text_row_at_end
= it
.glyph_row
- 1;
13484 /* Update window_end_pos and window_end_vpos. */
13485 if (first_unchanged_at_end_row
13486 && first_unchanged_at_end_row
->y
< it
.last_visible_y
13487 && !last_text_row_at_end
)
13489 /* Window end line if one of the preserved rows from the current
13490 matrix. Set row to the last row displaying text in current
13491 matrix starting at first_unchanged_at_end_row, after
13493 xassert (first_unchanged_at_end_row
->displays_text_p
);
13494 row
= find_last_row_displaying_text (w
->current_matrix
, &it
,
13495 first_unchanged_at_end_row
);
13496 xassert (row
&& MATRIX_ROW_DISPLAYS_TEXT_P (row
));
13498 w
->window_end_pos
= make_number (Z
- MATRIX_ROW_END_CHARPOS (row
));
13499 w
->window_end_bytepos
= Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
13501 = make_number (MATRIX_ROW_VPOS (row
, w
->current_matrix
));
13502 xassert (w
->window_end_bytepos
>= 0);
13503 IF_DEBUG (debug_method_add (w
, "A"));
13505 else if (last_text_row_at_end
)
13508 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row_at_end
));
13509 w
->window_end_bytepos
13510 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row_at_end
);
13512 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end
, desired_matrix
));
13513 xassert (w
->window_end_bytepos
>= 0);
13514 IF_DEBUG (debug_method_add (w
, "B"));
13516 else if (last_text_row
)
13518 /* We have displayed either to the end of the window or at the
13519 end of the window, i.e. the last row with text is to be found
13520 in the desired matrix. */
13522 = make_number (Z
- MATRIX_ROW_END_CHARPOS (last_text_row
));
13523 w
->window_end_bytepos
13524 = Z_BYTE
- MATRIX_ROW_END_BYTEPOS (last_text_row
);
13526 = make_number (MATRIX_ROW_VPOS (last_text_row
, desired_matrix
));
13527 xassert (w
->window_end_bytepos
>= 0);
13529 else if (first_unchanged_at_end_row
== NULL
13530 && last_text_row
== NULL
13531 && last_text_row_at_end
== NULL
)
13533 /* Displayed to end of window, but no line containing text was
13534 displayed. Lines were deleted at the end of the window. */
13535 int first_vpos
= WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0;
13536 int vpos
= XFASTINT (w
->window_end_vpos
);
13537 struct glyph_row
*current_row
= current_matrix
->rows
+ vpos
;
13538 struct glyph_row
*desired_row
= desired_matrix
->rows
+ vpos
;
13541 row
== NULL
&& vpos
>= first_vpos
;
13542 --vpos
, --current_row
, --desired_row
)
13544 if (desired_row
->enabled_p
)
13546 if (desired_row
->displays_text_p
)
13549 else if (current_row
->displays_text_p
)
13553 xassert (row
!= NULL
);
13554 w
->window_end_vpos
= make_number (vpos
+ 1);
13555 w
->window_end_pos
= make_number (Z
- MATRIX_ROW_END_CHARPOS (row
));
13556 w
->window_end_bytepos
= Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
13557 xassert (w
->window_end_bytepos
>= 0);
13558 IF_DEBUG (debug_method_add (w
, "C"));
13563 #if 0 /* This leads to problems, for instance when the cursor is
13564 at ZV, and the cursor line displays no text. */
13565 /* Disable rows below what's displayed in the window. This makes
13566 debugging easier. */
13567 enable_glyph_matrix_rows (current_matrix
,
13568 XFASTINT (w
->window_end_vpos
) + 1,
13572 IF_DEBUG (debug_end_pos
= XFASTINT (w
->window_end_pos
);
13573 debug_end_vpos
= XFASTINT (w
->window_end_vpos
));
13575 /* Record that display has not been completed. */
13576 w
->window_end_valid
= Qnil
;
13577 w
->desired_matrix
->no_scrolling_p
= 1;
13585 /***********************************************************************
13586 More debugging support
13587 ***********************************************************************/
13591 void dump_glyph_row
P_ ((struct glyph_row
*, int, int));
13592 void dump_glyph_matrix
P_ ((struct glyph_matrix
*, int));
13593 void dump_glyph
P_ ((struct glyph_row
*, struct glyph
*, int));
13596 /* Dump the contents of glyph matrix MATRIX on stderr.
13598 GLYPHS 0 means don't show glyph contents.
13599 GLYPHS 1 means show glyphs in short form
13600 GLYPHS > 1 means show glyphs in long form. */
13603 dump_glyph_matrix (matrix
, glyphs
)
13604 struct glyph_matrix
*matrix
;
13608 for (i
= 0; i
< matrix
->nrows
; ++i
)
13609 dump_glyph_row (MATRIX_ROW (matrix
, i
), i
, glyphs
);
13613 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
13614 the glyph row and area where the glyph comes from. */
13617 dump_glyph (row
, glyph
, area
)
13618 struct glyph_row
*row
;
13619 struct glyph
*glyph
;
13622 if (glyph
->type
== CHAR_GLYPH
)
13625 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13626 glyph
- row
->glyphs
[TEXT_AREA
],
13629 (BUFFERP (glyph
->object
)
13631 : (STRINGP (glyph
->object
)
13634 glyph
->pixel_width
,
13636 (glyph
->u
.ch
< 0x80 && glyph
->u
.ch
>= ' '
13640 glyph
->left_box_line_p
,
13641 glyph
->right_box_line_p
);
13643 else if (glyph
->type
== STRETCH_GLYPH
)
13646 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13647 glyph
- row
->glyphs
[TEXT_AREA
],
13650 (BUFFERP (glyph
->object
)
13652 : (STRINGP (glyph
->object
)
13655 glyph
->pixel_width
,
13659 glyph
->left_box_line_p
,
13660 glyph
->right_box_line_p
);
13662 else if (glyph
->type
== IMAGE_GLYPH
)
13665 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13666 glyph
- row
->glyphs
[TEXT_AREA
],
13669 (BUFFERP (glyph
->object
)
13671 : (STRINGP (glyph
->object
)
13674 glyph
->pixel_width
,
13678 glyph
->left_box_line_p
,
13679 glyph
->right_box_line_p
);
13684 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
13685 GLYPHS 0 means don't show glyph contents.
13686 GLYPHS 1 means show glyphs in short form
13687 GLYPHS > 1 means show glyphs in long form. */
13690 dump_glyph_row (row
, vpos
, glyphs
)
13691 struct glyph_row
*row
;
13696 fprintf (stderr
, "Row Start End Used oEI><O\\CTZFesm X Y W H V A P\n");
13697 fprintf (stderr
, "=======================================================================\n");
13699 fprintf (stderr
, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d%1.1d\
13700 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
13702 MATRIX_ROW_START_CHARPOS (row
),
13703 MATRIX_ROW_END_CHARPOS (row
),
13704 row
->used
[TEXT_AREA
],
13705 row
->contains_overlapping_glyphs_p
,
13707 row
->truncated_on_left_p
,
13708 row
->truncated_on_right_p
,
13709 row
->overlay_arrow_p
,
13711 MATRIX_ROW_CONTINUATION_LINE_P (row
),
13712 row
->displays_text_p
,
13715 row
->ends_in_middle_of_char_p
,
13716 row
->starts_in_middle_of_char_p
,
13722 row
->visible_height
,
13725 fprintf (stderr
, "%9d %5d\t%5d\n", row
->start
.overlay_string_index
,
13726 row
->end
.overlay_string_index
,
13727 row
->continuation_lines_width
);
13728 fprintf (stderr
, "%9d %5d\n",
13729 CHARPOS (row
->start
.string_pos
),
13730 CHARPOS (row
->end
.string_pos
));
13731 fprintf (stderr
, "%9d %5d\n", row
->start
.dpvec_index
,
13732 row
->end
.dpvec_index
);
13739 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
13741 struct glyph
*glyph
= row
->glyphs
[area
];
13742 struct glyph
*glyph_end
= glyph
+ row
->used
[area
];
13744 /* Glyph for a line end in text. */
13745 if (area
== TEXT_AREA
&& glyph
== glyph_end
&& glyph
->charpos
> 0)
13748 if (glyph
< glyph_end
)
13749 fprintf (stderr
, " Glyph Type Pos O W Code C Face LR\n");
13751 for (; glyph
< glyph_end
; ++glyph
)
13752 dump_glyph (row
, glyph
, area
);
13755 else if (glyphs
== 1)
13759 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
13761 char *s
= (char *) alloca (row
->used
[area
] + 1);
13764 for (i
= 0; i
< row
->used
[area
]; ++i
)
13766 struct glyph
*glyph
= row
->glyphs
[area
] + i
;
13767 if (glyph
->type
== CHAR_GLYPH
13768 && glyph
->u
.ch
< 0x80
13769 && glyph
->u
.ch
>= ' ')
13770 s
[i
] = glyph
->u
.ch
;
13776 fprintf (stderr
, "%3d: (%d) '%s'\n", vpos
, row
->enabled_p
, s
);
13782 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix
,
13783 Sdump_glyph_matrix
, 0, 1, "p",
13784 doc
: /* Dump the current matrix of the selected window to stderr.
13785 Shows contents of glyph row structures. With non-nil
13786 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
13787 glyphs in short form, otherwise show glyphs in long form. */)
13789 Lisp_Object glyphs
;
13791 struct window
*w
= XWINDOW (selected_window
);
13792 struct buffer
*buffer
= XBUFFER (w
->buffer
);
13794 fprintf (stderr
, "PT = %d, BEGV = %d. ZV = %d\n",
13795 BUF_PT (buffer
), BUF_BEGV (buffer
), BUF_ZV (buffer
));
13796 fprintf (stderr
, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
13797 w
->cursor
.x
, w
->cursor
.y
, w
->cursor
.hpos
, w
->cursor
.vpos
);
13798 fprintf (stderr
, "=============================================\n");
13799 dump_glyph_matrix (w
->current_matrix
,
13800 NILP (glyphs
) ? 0 : XINT (glyphs
));
13805 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix
,
13806 Sdump_frame_glyph_matrix
, 0, 0, "", doc
: /* */)
13809 struct frame
*f
= XFRAME (selected_frame
);
13810 dump_glyph_matrix (f
->current_matrix
, 1);
13815 DEFUN ("dump-glyph-row", Fdump_glyph_row
, Sdump_glyph_row
, 1, 2, "",
13816 doc
: /* Dump glyph row ROW to stderr.
13817 GLYPH 0 means don't dump glyphs.
13818 GLYPH 1 means dump glyphs in short form.
13819 GLYPH > 1 or omitted means dump glyphs in long form. */)
13821 Lisp_Object row
, glyphs
;
13823 struct glyph_matrix
*matrix
;
13826 CHECK_NUMBER (row
);
13827 matrix
= XWINDOW (selected_window
)->current_matrix
;
13829 if (vpos
>= 0 && vpos
< matrix
->nrows
)
13830 dump_glyph_row (MATRIX_ROW (matrix
, vpos
),
13832 INTEGERP (glyphs
) ? XINT (glyphs
) : 2);
13837 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row
, Sdump_tool_bar_row
, 1, 2, "",
13838 doc
: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
13839 GLYPH 0 means don't dump glyphs.
13840 GLYPH 1 means dump glyphs in short form.
13841 GLYPH > 1 or omitted means dump glyphs in long form. */)
13843 Lisp_Object row
, glyphs
;
13845 struct frame
*sf
= SELECTED_FRAME ();
13846 struct glyph_matrix
*m
= XWINDOW (sf
->tool_bar_window
)->current_matrix
;
13849 CHECK_NUMBER (row
);
13851 if (vpos
>= 0 && vpos
< m
->nrows
)
13852 dump_glyph_row (MATRIX_ROW (m
, vpos
), vpos
,
13853 INTEGERP (glyphs
) ? XINT (glyphs
) : 2);
13858 DEFUN ("trace-redisplay", Ftrace_redisplay
, Strace_redisplay
, 0, 1, "P",
13859 doc
: /* Toggle tracing of redisplay.
13860 With ARG, turn tracing on if and only if ARG is positive. */)
13865 trace_redisplay_p
= !trace_redisplay_p
;
13868 arg
= Fprefix_numeric_value (arg
);
13869 trace_redisplay_p
= XINT (arg
) > 0;
13876 DEFUN ("trace-to-stderr", Ftrace_to_stderr
, Strace_to_stderr
, 1, MANY
, "",
13877 doc
: /* Like `format', but print result to stderr.
13878 usage: (trace-to-stderr STRING &rest OBJECTS) */)
13883 Lisp_Object s
= Fformat (nargs
, args
);
13884 fprintf (stderr
, "%s", SDATA (s
));
13888 #endif /* GLYPH_DEBUG */
13892 /***********************************************************************
13893 Building Desired Matrix Rows
13894 ***********************************************************************/
13896 /* Return a temporary glyph row holding the glyphs of an overlay
13897 arrow. Only used for non-window-redisplay windows. */
13899 static struct glyph_row
*
13900 get_overlay_arrow_glyph_row (w
, overlay_arrow_string
)
13902 Lisp_Object overlay_arrow_string
;
13904 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
13905 struct buffer
*buffer
= XBUFFER (w
->buffer
);
13906 struct buffer
*old
= current_buffer
;
13907 const unsigned char *arrow_string
= SDATA (overlay_arrow_string
);
13908 int arrow_len
= SCHARS (overlay_arrow_string
);
13909 const unsigned char *arrow_end
= arrow_string
+ arrow_len
;
13910 const unsigned char *p
;
13913 int n_glyphs_before
;
13915 set_buffer_temp (buffer
);
13916 init_iterator (&it
, w
, -1, -1, &scratch_glyph_row
, DEFAULT_FACE_ID
);
13917 it
.glyph_row
->used
[TEXT_AREA
] = 0;
13918 SET_TEXT_POS (it
.position
, 0, 0);
13920 multibyte_p
= !NILP (buffer
->enable_multibyte_characters
);
13922 while (p
< arrow_end
)
13924 Lisp_Object face
, ilisp
;
13926 /* Get the next character. */
13928 it
.c
= string_char_and_length (p
, arrow_len
, &it
.len
);
13930 it
.c
= *p
, it
.len
= 1;
13933 /* Get its face. */
13934 ilisp
= make_number (p
- arrow_string
);
13935 face
= Fget_text_property (ilisp
, Qface
, overlay_arrow_string
);
13936 it
.face_id
= compute_char_face (f
, it
.c
, face
);
13938 /* Compute its width, get its glyphs. */
13939 n_glyphs_before
= it
.glyph_row
->used
[TEXT_AREA
];
13940 SET_TEXT_POS (it
.position
, -1, -1);
13941 PRODUCE_GLYPHS (&it
);
13943 /* If this character doesn't fit any more in the line, we have
13944 to remove some glyphs. */
13945 if (it
.current_x
> it
.last_visible_x
)
13947 it
.glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
;
13952 set_buffer_temp (old
);
13953 return it
.glyph_row
;
13957 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
13958 glyphs are only inserted for terminal frames since we can't really
13959 win with truncation glyphs when partially visible glyphs are
13960 involved. Which glyphs to insert is determined by
13961 produce_special_glyphs. */
13964 insert_left_trunc_glyphs (it
)
13967 struct it truncate_it
;
13968 struct glyph
*from
, *end
, *to
, *toend
;
13970 xassert (!FRAME_WINDOW_P (it
->f
));
13972 /* Get the truncation glyphs. */
13974 truncate_it
.current_x
= 0;
13975 truncate_it
.face_id
= DEFAULT_FACE_ID
;
13976 truncate_it
.glyph_row
= &scratch_glyph_row
;
13977 truncate_it
.glyph_row
->used
[TEXT_AREA
] = 0;
13978 CHARPOS (truncate_it
.position
) = BYTEPOS (truncate_it
.position
) = -1;
13979 truncate_it
.object
= make_number (0);
13980 produce_special_glyphs (&truncate_it
, IT_TRUNCATION
);
13982 /* Overwrite glyphs from IT with truncation glyphs. */
13983 from
= truncate_it
.glyph_row
->glyphs
[TEXT_AREA
];
13984 end
= from
+ truncate_it
.glyph_row
->used
[TEXT_AREA
];
13985 to
= it
->glyph_row
->glyphs
[TEXT_AREA
];
13986 toend
= to
+ it
->glyph_row
->used
[TEXT_AREA
];
13991 /* There may be padding glyphs left over. Overwrite them too. */
13992 while (to
< toend
&& CHAR_GLYPH_PADDING_P (*to
))
13994 from
= truncate_it
.glyph_row
->glyphs
[TEXT_AREA
];
14000 it
->glyph_row
->used
[TEXT_AREA
] = to
- it
->glyph_row
->glyphs
[TEXT_AREA
];
14004 /* Compute the pixel height and width of IT->glyph_row.
14006 Most of the time, ascent and height of a display line will be equal
14007 to the max_ascent and max_height values of the display iterator
14008 structure. This is not the case if
14010 1. We hit ZV without displaying anything. In this case, max_ascent
14011 and max_height will be zero.
14013 2. We have some glyphs that don't contribute to the line height.
14014 (The glyph row flag contributes_to_line_height_p is for future
14015 pixmap extensions).
14017 The first case is easily covered by using default values because in
14018 these cases, the line height does not really matter, except that it
14019 must not be zero. */
14022 compute_line_metrics (it
)
14025 struct glyph_row
*row
= it
->glyph_row
;
14028 if (FRAME_WINDOW_P (it
->f
))
14030 int i
, min_y
, max_y
;
14032 /* The line may consist of one space only, that was added to
14033 place the cursor on it. If so, the row's height hasn't been
14035 if (row
->height
== 0)
14037 if (it
->max_ascent
+ it
->max_descent
== 0)
14038 it
->max_descent
= it
->max_phys_descent
= FRAME_LINE_HEIGHT (it
->f
);
14039 row
->ascent
= it
->max_ascent
;
14040 row
->height
= it
->max_ascent
+ it
->max_descent
;
14041 row
->phys_ascent
= it
->max_phys_ascent
;
14042 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
14045 /* Compute the width of this line. */
14046 row
->pixel_width
= row
->x
;
14047 for (i
= 0; i
< row
->used
[TEXT_AREA
]; ++i
)
14048 row
->pixel_width
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
14050 xassert (row
->pixel_width
>= 0);
14051 xassert (row
->ascent
>= 0 && row
->height
> 0);
14053 row
->overlapping_p
= (MATRIX_ROW_OVERLAPS_SUCC_P (row
)
14054 || MATRIX_ROW_OVERLAPS_PRED_P (row
));
14056 /* If first line's physical ascent is larger than its logical
14057 ascent, use the physical ascent, and make the row taller.
14058 This makes accented characters fully visible. */
14059 if (row
== MATRIX_FIRST_TEXT_ROW (it
->w
->desired_matrix
)
14060 && row
->phys_ascent
> row
->ascent
)
14062 row
->height
+= row
->phys_ascent
- row
->ascent
;
14063 row
->ascent
= row
->phys_ascent
;
14066 /* Compute how much of the line is visible. */
14067 row
->visible_height
= row
->height
;
14069 min_y
= WINDOW_HEADER_LINE_HEIGHT (it
->w
);
14070 max_y
= WINDOW_BOX_HEIGHT_NO_MODE_LINE (it
->w
);
14072 if (row
->y
< min_y
)
14073 row
->visible_height
-= min_y
- row
->y
;
14074 if (row
->y
+ row
->height
> max_y
)
14075 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
14079 row
->pixel_width
= row
->used
[TEXT_AREA
];
14080 if (row
->continued_p
)
14081 row
->pixel_width
-= it
->continuation_pixel_width
;
14082 else if (row
->truncated_on_right_p
)
14083 row
->pixel_width
-= it
->truncation_pixel_width
;
14084 row
->ascent
= row
->phys_ascent
= 0;
14085 row
->height
= row
->phys_height
= row
->visible_height
= 1;
14088 /* Compute a hash code for this row. */
14090 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
14091 for (i
= 0; i
< row
->used
[area
]; ++i
)
14092 row
->hash
= ((((row
->hash
<< 4) + (row
->hash
>> 24)) & 0x0fffffff)
14093 + row
->glyphs
[area
][i
].u
.val
14094 + row
->glyphs
[area
][i
].face_id
14095 + row
->glyphs
[area
][i
].padding_p
14096 + (row
->glyphs
[area
][i
].type
<< 2));
14098 it
->max_ascent
= it
->max_descent
= 0;
14099 it
->max_phys_ascent
= it
->max_phys_descent
= 0;
14103 /* Append one space to the glyph row of iterator IT if doing a
14104 window-based redisplay. DEFAULT_FACE_P non-zero means let the
14105 space have the default face, otherwise let it have the same face as
14106 IT->face_id. Value is non-zero if a space was added.
14108 This function is called to make sure that there is always one glyph
14109 at the end of a glyph row that the cursor can be set on under
14110 window-systems. (If there weren't such a glyph we would not know
14111 how wide and tall a box cursor should be displayed).
14113 At the same time this space let's a nicely handle clearing to the
14114 end of the line if the row ends in italic text. */
14117 append_space (it
, default_face_p
)
14119 int default_face_p
;
14121 if (FRAME_WINDOW_P (it
->f
))
14123 int n
= it
->glyph_row
->used
[TEXT_AREA
];
14125 if (it
->glyph_row
->glyphs
[TEXT_AREA
] + n
14126 < it
->glyph_row
->glyphs
[1 + TEXT_AREA
])
14128 /* Save some values that must not be changed.
14129 Must save IT->c and IT->len because otherwise
14130 ITERATOR_AT_END_P wouldn't work anymore after
14131 append_space has been called. */
14132 enum display_element_type saved_what
= it
->what
;
14133 int saved_c
= it
->c
, saved_len
= it
->len
;
14134 int saved_x
= it
->current_x
;
14135 int saved_face_id
= it
->face_id
;
14136 struct text_pos saved_pos
;
14137 Lisp_Object saved_object
;
14140 saved_object
= it
->object
;
14141 saved_pos
= it
->position
;
14143 it
->what
= IT_CHARACTER
;
14144 bzero (&it
->position
, sizeof it
->position
);
14145 it
->object
= make_number (0);
14149 if (default_face_p
)
14150 it
->face_id
= DEFAULT_FACE_ID
;
14151 else if (it
->face_before_selective_p
)
14152 it
->face_id
= it
->saved_face_id
;
14153 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
14154 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, 0);
14156 PRODUCE_GLYPHS (it
);
14158 it
->current_x
= saved_x
;
14159 it
->object
= saved_object
;
14160 it
->position
= saved_pos
;
14161 it
->what
= saved_what
;
14162 it
->face_id
= saved_face_id
;
14163 it
->len
= saved_len
;
14173 /* Extend the face of the last glyph in the text area of IT->glyph_row
14174 to the end of the display line. Called from display_line.
14175 If the glyph row is empty, add a space glyph to it so that we
14176 know the face to draw. Set the glyph row flag fill_line_p. */
14179 extend_face_to_end_of_line (it
)
14183 struct frame
*f
= it
->f
;
14185 /* If line is already filled, do nothing. */
14186 if (it
->current_x
>= it
->last_visible_x
)
14189 /* Face extension extends the background and box of IT->face_id
14190 to the end of the line. If the background equals the background
14191 of the frame, we don't have to do anything. */
14192 if (it
->face_before_selective_p
)
14193 face
= FACE_FROM_ID (it
->f
, it
->saved_face_id
);
14195 face
= FACE_FROM_ID (f
, it
->face_id
);
14197 if (FRAME_WINDOW_P (f
)
14198 && face
->box
== FACE_NO_BOX
14199 && face
->background
== FRAME_BACKGROUND_PIXEL (f
)
14203 /* Set the glyph row flag indicating that the face of the last glyph
14204 in the text area has to be drawn to the end of the text area. */
14205 it
->glyph_row
->fill_line_p
= 1;
14207 /* If current character of IT is not ASCII, make sure we have the
14208 ASCII face. This will be automatically undone the next time
14209 get_next_display_element returns a multibyte character. Note
14210 that the character will always be single byte in unibyte text. */
14211 if (!SINGLE_BYTE_CHAR_P (it
->c
))
14213 it
->face_id
= FACE_FOR_CHAR (f
, face
, 0);
14216 if (FRAME_WINDOW_P (f
))
14218 /* If the row is empty, add a space with the current face of IT,
14219 so that we know which face to draw. */
14220 if (it
->glyph_row
->used
[TEXT_AREA
] == 0)
14222 it
->glyph_row
->glyphs
[TEXT_AREA
][0] = space_glyph
;
14223 it
->glyph_row
->glyphs
[TEXT_AREA
][0].face_id
= it
->face_id
;
14224 it
->glyph_row
->used
[TEXT_AREA
] = 1;
14229 /* Save some values that must not be changed. */
14230 int saved_x
= it
->current_x
;
14231 struct text_pos saved_pos
;
14232 Lisp_Object saved_object
;
14233 enum display_element_type saved_what
= it
->what
;
14234 int saved_face_id
= it
->face_id
;
14236 saved_object
= it
->object
;
14237 saved_pos
= it
->position
;
14239 it
->what
= IT_CHARACTER
;
14240 bzero (&it
->position
, sizeof it
->position
);
14241 it
->object
= make_number (0);
14244 it
->face_id
= face
->id
;
14246 PRODUCE_GLYPHS (it
);
14248 while (it
->current_x
<= it
->last_visible_x
)
14249 PRODUCE_GLYPHS (it
);
14251 /* Don't count these blanks really. It would let us insert a left
14252 truncation glyph below and make us set the cursor on them, maybe. */
14253 it
->current_x
= saved_x
;
14254 it
->object
= saved_object
;
14255 it
->position
= saved_pos
;
14256 it
->what
= saved_what
;
14257 it
->face_id
= saved_face_id
;
14262 /* Value is non-zero if text starting at CHARPOS in current_buffer is
14263 trailing whitespace. */
14266 trailing_whitespace_p (charpos
)
14269 int bytepos
= CHAR_TO_BYTE (charpos
);
14272 while (bytepos
< ZV_BYTE
14273 && (c
= FETCH_CHAR (bytepos
),
14274 c
== ' ' || c
== '\t'))
14277 if (bytepos
>= ZV_BYTE
|| c
== '\n' || c
== '\r')
14279 if (bytepos
!= PT_BYTE
)
14286 /* Highlight trailing whitespace, if any, in ROW. */
14289 highlight_trailing_whitespace (f
, row
)
14291 struct glyph_row
*row
;
14293 int used
= row
->used
[TEXT_AREA
];
14297 struct glyph
*start
= row
->glyphs
[TEXT_AREA
];
14298 struct glyph
*glyph
= start
+ used
- 1;
14300 /* Skip over glyphs inserted to display the cursor at the
14301 end of a line, for extending the face of the last glyph
14302 to the end of the line on terminals, and for truncation
14303 and continuation glyphs. */
14304 while (glyph
>= start
14305 && glyph
->type
== CHAR_GLYPH
14306 && INTEGERP (glyph
->object
))
14309 /* If last glyph is a space or stretch, and it's trailing
14310 whitespace, set the face of all trailing whitespace glyphs in
14311 IT->glyph_row to `trailing-whitespace'. */
14313 && BUFFERP (glyph
->object
)
14314 && (glyph
->type
== STRETCH_GLYPH
14315 || (glyph
->type
== CHAR_GLYPH
14316 && glyph
->u
.ch
== ' '))
14317 && trailing_whitespace_p (glyph
->charpos
))
14319 int face_id
= lookup_named_face (f
, Qtrailing_whitespace
, 0);
14321 while (glyph
>= start
14322 && BUFFERP (glyph
->object
)
14323 && (glyph
->type
== STRETCH_GLYPH
14324 || (glyph
->type
== CHAR_GLYPH
14325 && glyph
->u
.ch
== ' ')))
14326 (glyph
--)->face_id
= face_id
;
14332 /* Value is non-zero if glyph row ROW in window W should be
14333 used to hold the cursor. */
14336 cursor_row_p (w
, row
)
14338 struct glyph_row
*row
;
14340 int cursor_row_p
= 1;
14342 if (PT
== MATRIX_ROW_END_CHARPOS (row
))
14344 /* If the row ends with a newline from a string, we don't want
14345 the cursor there (if the row is continued it doesn't end in a
14347 if (CHARPOS (row
->end
.string_pos
) >= 0
14348 || MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
))
14349 cursor_row_p
= row
->continued_p
;
14351 /* If the row ends at ZV, display the cursor at the end of that
14352 row instead of at the start of the row below. */
14353 else if (row
->ends_at_zv_p
)
14359 return cursor_row_p
;
14363 /* Construct the glyph row IT->glyph_row in the desired matrix of
14364 IT->w from text at the current position of IT. See dispextern.h
14365 for an overview of struct it. Value is non-zero if
14366 IT->glyph_row displays text, as opposed to a line displaying ZV
14373 struct glyph_row
*row
= it
->glyph_row
;
14374 int overlay_arrow_bitmap
;
14375 Lisp_Object overlay_arrow_string
;
14377 /* We always start displaying at hpos zero even if hscrolled. */
14378 xassert (it
->hpos
== 0 && it
->current_x
== 0);
14380 /* We must not display in a row that's not a text row. */
14381 xassert (MATRIX_ROW_VPOS (row
, it
->w
->desired_matrix
)
14382 < it
->w
->desired_matrix
->nrows
);
14384 /* Is IT->w showing the region? */
14385 it
->w
->region_showing
= it
->region_beg_charpos
> 0 ? Qt
: Qnil
;
14387 /* Clear the result glyph row and enable it. */
14388 prepare_desired_row (row
);
14390 row
->y
= it
->current_y
;
14391 row
->start
= it
->start
;
14392 row
->continuation_lines_width
= it
->continuation_lines_width
;
14393 row
->displays_text_p
= 1;
14394 row
->starts_in_middle_of_char_p
= it
->starts_in_middle_of_char_p
;
14395 it
->starts_in_middle_of_char_p
= 0;
14397 /* Arrange the overlays nicely for our purposes. Usually, we call
14398 display_line on only one line at a time, in which case this
14399 can't really hurt too much, or we call it on lines which appear
14400 one after another in the buffer, in which case all calls to
14401 recenter_overlay_lists but the first will be pretty cheap. */
14402 recenter_overlay_lists (current_buffer
, IT_CHARPOS (*it
));
14404 /* Move over display elements that are not visible because we are
14405 hscrolled. This may stop at an x-position < IT->first_visible_x
14406 if the first glyph is partially visible or if we hit a line end. */
14407 if (it
->current_x
< it
->first_visible_x
)
14408 move_it_in_display_line_to (it
, ZV
, it
->first_visible_x
,
14409 MOVE_TO_POS
| MOVE_TO_X
);
14411 /* Get the initial row height. This is either the height of the
14412 text hscrolled, if there is any, or zero. */
14413 row
->ascent
= it
->max_ascent
;
14414 row
->height
= it
->max_ascent
+ it
->max_descent
;
14415 row
->phys_ascent
= it
->max_phys_ascent
;
14416 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
14418 /* Loop generating characters. The loop is left with IT on the next
14419 character to display. */
14422 int n_glyphs_before
, hpos_before
, x_before
;
14424 int ascent
= 0, descent
= 0, phys_ascent
= 0, phys_descent
= 0;
14426 /* Retrieve the next thing to display. Value is zero if end of
14428 if (!get_next_display_element (it
))
14430 /* Maybe add a space at the end of this line that is used to
14431 display the cursor there under X. Set the charpos of the
14432 first glyph of blank lines not corresponding to any text
14434 #ifdef HAVE_WINDOW_SYSTEM
14435 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
14436 row
->exact_window_width_line_p
= 1;
14438 #endif /* HAVE_WINDOW_SYSTEM */
14439 if ((append_space (it
, 1) && row
->used
[TEXT_AREA
] == 1)
14440 || row
->used
[TEXT_AREA
] == 0)
14442 row
->glyphs
[TEXT_AREA
]->charpos
= -1;
14443 row
->displays_text_p
= 0;
14445 if (!NILP (XBUFFER (it
->w
->buffer
)->indicate_empty_lines
)
14446 && (!MINI_WINDOW_P (it
->w
)
14447 || (minibuf_level
&& EQ (it
->window
, minibuf_window
))))
14448 row
->indicate_empty_line_p
= 1;
14451 it
->continuation_lines_width
= 0;
14452 row
->ends_at_zv_p
= 1;
14456 /* Now, get the metrics of what we want to display. This also
14457 generates glyphs in `row' (which is IT->glyph_row). */
14458 n_glyphs_before
= row
->used
[TEXT_AREA
];
14461 /* Remember the line height so far in case the next element doesn't
14462 fit on the line. */
14463 if (!it
->truncate_lines_p
)
14465 ascent
= it
->max_ascent
;
14466 descent
= it
->max_descent
;
14467 phys_ascent
= it
->max_phys_ascent
;
14468 phys_descent
= it
->max_phys_descent
;
14471 PRODUCE_GLYPHS (it
);
14473 /* If this display element was in marginal areas, continue with
14475 if (it
->area
!= TEXT_AREA
)
14477 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
14478 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
14479 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
14480 row
->phys_height
= max (row
->phys_height
,
14481 it
->max_phys_ascent
+ it
->max_phys_descent
);
14482 set_iterator_to_next (it
, 1);
14486 /* Does the display element fit on the line? If we truncate
14487 lines, we should draw past the right edge of the window. If
14488 we don't truncate, we want to stop so that we can display the
14489 continuation glyph before the right margin. If lines are
14490 continued, there are two possible strategies for characters
14491 resulting in more than 1 glyph (e.g. tabs): Display as many
14492 glyphs as possible in this line and leave the rest for the
14493 continuation line, or display the whole element in the next
14494 line. Original redisplay did the former, so we do it also. */
14495 nglyphs
= row
->used
[TEXT_AREA
] - n_glyphs_before
;
14496 hpos_before
= it
->hpos
;
14499 if (/* Not a newline. */
14501 /* Glyphs produced fit entirely in the line. */
14502 && it
->current_x
< it
->last_visible_x
)
14504 it
->hpos
+= nglyphs
;
14505 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
14506 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
14507 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
14508 row
->phys_height
= max (row
->phys_height
,
14509 it
->max_phys_ascent
+ it
->max_phys_descent
);
14510 if (it
->current_x
- it
->pixel_width
< it
->first_visible_x
)
14511 row
->x
= x
- it
->first_visible_x
;
14516 struct glyph
*glyph
;
14518 for (i
= 0; i
< nglyphs
; ++i
, x
= new_x
)
14520 glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
14521 new_x
= x
+ glyph
->pixel_width
;
14523 if (/* Lines are continued. */
14524 !it
->truncate_lines_p
14525 && (/* Glyph doesn't fit on the line. */
14526 new_x
> it
->last_visible_x
14527 /* Or it fits exactly on a window system frame. */
14528 || (new_x
== it
->last_visible_x
14529 && FRAME_WINDOW_P (it
->f
))))
14531 /* End of a continued line. */
14534 || (new_x
== it
->last_visible_x
14535 && FRAME_WINDOW_P (it
->f
)))
14537 /* Current glyph is the only one on the line or
14538 fits exactly on the line. We must continue
14539 the line because we can't draw the cursor
14540 after the glyph. */
14541 row
->continued_p
= 1;
14542 it
->current_x
= new_x
;
14543 it
->continuation_lines_width
+= new_x
;
14545 if (i
== nglyphs
- 1)
14547 set_iterator_to_next (it
, 1);
14548 #ifdef HAVE_WINDOW_SYSTEM
14549 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
14551 if (!get_next_display_element (it
))
14553 row
->exact_window_width_line_p
= 1;
14554 it
->continuation_lines_width
= 0;
14555 row
->continued_p
= 0;
14556 row
->ends_at_zv_p
= 1;
14558 else if (ITERATOR_AT_END_OF_LINE_P (it
))
14560 row
->continued_p
= 0;
14561 row
->exact_window_width_line_p
= 1;
14564 #endif /* HAVE_WINDOW_SYSTEM */
14567 else if (CHAR_GLYPH_PADDING_P (*glyph
)
14568 && !FRAME_WINDOW_P (it
->f
))
14570 /* A padding glyph that doesn't fit on this line.
14571 This means the whole character doesn't fit
14573 row
->used
[TEXT_AREA
] = n_glyphs_before
;
14575 /* Fill the rest of the row with continuation
14576 glyphs like in 20.x. */
14577 while (row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
]
14578 < row
->glyphs
[1 + TEXT_AREA
])
14579 produce_special_glyphs (it
, IT_CONTINUATION
);
14581 row
->continued_p
= 1;
14582 it
->current_x
= x_before
;
14583 it
->continuation_lines_width
+= x_before
;
14585 /* Restore the height to what it was before the
14586 element not fitting on the line. */
14587 it
->max_ascent
= ascent
;
14588 it
->max_descent
= descent
;
14589 it
->max_phys_ascent
= phys_ascent
;
14590 it
->max_phys_descent
= phys_descent
;
14592 else if (it
->c
== '\t' && FRAME_WINDOW_P (it
->f
))
14594 /* A TAB that extends past the right edge of the
14595 window. This produces a single glyph on
14596 window system frames. We leave the glyph in
14597 this row and let it fill the row, but don't
14598 consume the TAB. */
14599 it
->continuation_lines_width
+= it
->last_visible_x
;
14600 row
->ends_in_middle_of_char_p
= 1;
14601 row
->continued_p
= 1;
14602 glyph
->pixel_width
= it
->last_visible_x
- x
;
14603 it
->starts_in_middle_of_char_p
= 1;
14607 /* Something other than a TAB that draws past
14608 the right edge of the window. Restore
14609 positions to values before the element. */
14610 row
->used
[TEXT_AREA
] = n_glyphs_before
+ i
;
14612 /* Display continuation glyphs. */
14613 if (!FRAME_WINDOW_P (it
->f
))
14614 produce_special_glyphs (it
, IT_CONTINUATION
);
14615 row
->continued_p
= 1;
14617 it
->continuation_lines_width
+= x
;
14619 if (nglyphs
> 1 && i
> 0)
14621 row
->ends_in_middle_of_char_p
= 1;
14622 it
->starts_in_middle_of_char_p
= 1;
14625 /* Restore the height to what it was before the
14626 element not fitting on the line. */
14627 it
->max_ascent
= ascent
;
14628 it
->max_descent
= descent
;
14629 it
->max_phys_ascent
= phys_ascent
;
14630 it
->max_phys_descent
= phys_descent
;
14635 else if (new_x
> it
->first_visible_x
)
14637 /* Increment number of glyphs actually displayed. */
14640 if (x
< it
->first_visible_x
)
14641 /* Glyph is partially visible, i.e. row starts at
14642 negative X position. */
14643 row
->x
= x
- it
->first_visible_x
;
14647 /* Glyph is completely off the left margin of the
14648 window. This should not happen because of the
14649 move_it_in_display_line at the start of this
14650 function, unless the text display area of the
14651 window is empty. */
14652 xassert (it
->first_visible_x
<= it
->last_visible_x
);
14656 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
14657 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
14658 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
14659 row
->phys_height
= max (row
->phys_height
,
14660 it
->max_phys_ascent
+ it
->max_phys_descent
);
14662 /* End of this display line if row is continued. */
14663 if (row
->continued_p
|| row
->ends_at_zv_p
)
14668 /* Is this a line end? If yes, we're also done, after making
14669 sure that a non-default face is extended up to the right
14670 margin of the window. */
14671 if (ITERATOR_AT_END_OF_LINE_P (it
))
14673 int used_before
= row
->used
[TEXT_AREA
];
14675 row
->ends_in_newline_from_string_p
= STRINGP (it
->object
);
14677 #ifdef HAVE_WINDOW_SYSTEM
14678 /* Add a space at the end of the line that is used to
14679 display the cursor there. */
14680 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
14681 append_space (it
, 0);
14682 #endif /* HAVE_WINDOW_SYSTEM */
14684 /* Extend the face to the end of the line. */
14685 extend_face_to_end_of_line (it
);
14687 /* Make sure we have the position. */
14688 if (used_before
== 0)
14689 row
->glyphs
[TEXT_AREA
]->charpos
= CHARPOS (it
->position
);
14691 /* Consume the line end. This skips over invisible lines. */
14692 set_iterator_to_next (it
, 1);
14693 it
->continuation_lines_width
= 0;
14697 /* Proceed with next display element. Note that this skips
14698 over lines invisible because of selective display. */
14699 set_iterator_to_next (it
, 1);
14701 /* If we truncate lines, we are done when the last displayed
14702 glyphs reach past the right margin of the window. */
14703 if (it
->truncate_lines_p
14704 && (FRAME_WINDOW_P (it
->f
)
14705 ? (it
->current_x
>= it
->last_visible_x
)
14706 : (it
->current_x
> it
->last_visible_x
)))
14708 /* Maybe add truncation glyphs. */
14709 if (!FRAME_WINDOW_P (it
->f
))
14713 for (i
= row
->used
[TEXT_AREA
] - 1; i
> 0; --i
)
14714 if (!CHAR_GLYPH_PADDING_P (row
->glyphs
[TEXT_AREA
][i
]))
14717 for (n
= row
->used
[TEXT_AREA
]; i
< n
; ++i
)
14719 row
->used
[TEXT_AREA
] = i
;
14720 produce_special_glyphs (it
, IT_TRUNCATION
);
14723 #ifdef HAVE_WINDOW_SYSTEM
14726 /* Don't truncate if we can overflow newline into fringe. */
14727 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
14729 if (!get_next_display_element (it
))
14731 #ifdef HAVE_WINDOW_SYSTEM
14732 it
->continuation_lines_width
= 0;
14733 row
->ends_at_zv_p
= 1;
14734 row
->exact_window_width_line_p
= 1;
14736 #endif /* HAVE_WINDOW_SYSTEM */
14738 if (ITERATOR_AT_END_OF_LINE_P (it
))
14740 row
->exact_window_width_line_p
= 1;
14741 goto at_end_of_line
;
14745 #endif /* HAVE_WINDOW_SYSTEM */
14747 row
->truncated_on_right_p
= 1;
14748 it
->continuation_lines_width
= 0;
14749 reseat_at_next_visible_line_start (it
, 0);
14750 row
->ends_at_zv_p
= FETCH_BYTE (IT_BYTEPOS (*it
) - 1) != '\n';
14751 it
->hpos
= hpos_before
;
14752 it
->current_x
= x_before
;
14757 /* If line is not empty and hscrolled, maybe insert truncation glyphs
14758 at the left window margin. */
14759 if (it
->first_visible_x
14760 && IT_CHARPOS (*it
) != MATRIX_ROW_START_CHARPOS (row
))
14762 if (!FRAME_WINDOW_P (it
->f
))
14763 insert_left_trunc_glyphs (it
);
14764 row
->truncated_on_left_p
= 1;
14767 /* If the start of this line is the overlay arrow-position, then
14768 mark this glyph row as the one containing the overlay arrow.
14769 This is clearly a mess with variable size fonts. It would be
14770 better to let it be displayed like cursors under X. */
14771 if (! overlay_arrow_seen
14772 && (overlay_arrow_string
14773 = overlay_arrow_at_row (it
->f
, row
, &overlay_arrow_bitmap
),
14774 !NILP (overlay_arrow_string
)))
14776 /* Overlay arrow in window redisplay is a fringe bitmap. */
14777 if (!FRAME_WINDOW_P (it
->f
))
14779 struct glyph_row
*arrow_row
14780 = get_overlay_arrow_glyph_row (it
->w
, overlay_arrow_string
);
14781 struct glyph
*glyph
= arrow_row
->glyphs
[TEXT_AREA
];
14782 struct glyph
*arrow_end
= glyph
+ arrow_row
->used
[TEXT_AREA
];
14783 struct glyph
*p
= row
->glyphs
[TEXT_AREA
];
14784 struct glyph
*p2
, *end
;
14786 /* Copy the arrow glyphs. */
14787 while (glyph
< arrow_end
)
14790 /* Throw away padding glyphs. */
14792 end
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
];
14793 while (p2
< end
&& CHAR_GLYPH_PADDING_P (*p2
))
14799 row
->used
[TEXT_AREA
] = p2
- row
->glyphs
[TEXT_AREA
];
14803 overlay_arrow_seen
= 1;
14804 it
->w
->overlay_arrow_bitmap
= overlay_arrow_bitmap
;
14805 row
->overlay_arrow_p
= 1;
14808 /* Compute pixel dimensions of this line. */
14809 compute_line_metrics (it
);
14811 /* Remember the position at which this line ends. */
14812 row
->end
= it
->current
;
14814 /* Save fringe bitmaps in this row. */
14815 row
->left_user_fringe_bitmap
= it
->left_user_fringe_bitmap
;
14816 row
->left_user_fringe_face_id
= it
->left_user_fringe_face_id
;
14817 row
->right_user_fringe_bitmap
= it
->right_user_fringe_bitmap
;
14818 row
->right_user_fringe_face_id
= it
->right_user_fringe_face_id
;
14820 it
->left_user_fringe_bitmap
= 0;
14821 it
->left_user_fringe_face_id
= 0;
14822 it
->right_user_fringe_bitmap
= 0;
14823 it
->right_user_fringe_face_id
= 0;
14825 /* Maybe set the cursor. */
14826 if (it
->w
->cursor
.vpos
< 0
14827 && PT
>= MATRIX_ROW_START_CHARPOS (row
)
14828 && PT
<= MATRIX_ROW_END_CHARPOS (row
)
14829 && cursor_row_p (it
->w
, row
))
14830 set_cursor_from_row (it
->w
, row
, it
->w
->desired_matrix
, 0, 0, 0, 0);
14832 /* Highlight trailing whitespace. */
14833 if (!NILP (Vshow_trailing_whitespace
))
14834 highlight_trailing_whitespace (it
->f
, it
->glyph_row
);
14836 /* Prepare for the next line. This line starts horizontally at (X
14837 HPOS) = (0 0). Vertical positions are incremented. As a
14838 convenience for the caller, IT->glyph_row is set to the next
14840 it
->current_x
= it
->hpos
= 0;
14841 it
->current_y
+= row
->height
;
14844 it
->start
= it
->current
;
14845 return row
->displays_text_p
;
14850 /***********************************************************************
14852 ***********************************************************************/
14854 /* Redisplay the menu bar in the frame for window W.
14856 The menu bar of X frames that don't have X toolkit support is
14857 displayed in a special window W->frame->menu_bar_window.
14859 The menu bar of terminal frames is treated specially as far as
14860 glyph matrices are concerned. Menu bar lines are not part of
14861 windows, so the update is done directly on the frame matrix rows
14862 for the menu bar. */
14865 display_menu_bar (w
)
14868 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
14873 /* Don't do all this for graphical frames. */
14875 if (!NILP (Vwindow_system
))
14878 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
14883 if (FRAME_MAC_P (f
))
14887 #ifdef USE_X_TOOLKIT
14888 xassert (!FRAME_WINDOW_P (f
));
14889 init_iterator (&it
, w
, -1, -1, f
->desired_matrix
->rows
, MENU_FACE_ID
);
14890 it
.first_visible_x
= 0;
14891 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
14892 #else /* not USE_X_TOOLKIT */
14893 if (FRAME_WINDOW_P (f
))
14895 /* Menu bar lines are displayed in the desired matrix of the
14896 dummy window menu_bar_window. */
14897 struct window
*menu_w
;
14898 xassert (WINDOWP (f
->menu_bar_window
));
14899 menu_w
= XWINDOW (f
->menu_bar_window
);
14900 init_iterator (&it
, menu_w
, -1, -1, menu_w
->desired_matrix
->rows
,
14902 it
.first_visible_x
= 0;
14903 it
.last_visible_x
= FRAME_TOTAL_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
14907 /* This is a TTY frame, i.e. character hpos/vpos are used as
14909 init_iterator (&it
, w
, -1, -1, f
->desired_matrix
->rows
,
14911 it
.first_visible_x
= 0;
14912 it
.last_visible_x
= FRAME_COLS (f
);
14914 #endif /* not USE_X_TOOLKIT */
14916 if (! mode_line_inverse_video
)
14917 /* Force the menu-bar to be displayed in the default face. */
14918 it
.base_face_id
= it
.face_id
= DEFAULT_FACE_ID
;
14920 /* Clear all rows of the menu bar. */
14921 for (i
= 0; i
< FRAME_MENU_BAR_LINES (f
); ++i
)
14923 struct glyph_row
*row
= it
.glyph_row
+ i
;
14924 clear_glyph_row (row
);
14925 row
->enabled_p
= 1;
14926 row
->full_width_p
= 1;
14929 /* Display all items of the menu bar. */
14930 items
= FRAME_MENU_BAR_ITEMS (it
.f
);
14931 for (i
= 0; i
< XVECTOR (items
)->size
; i
+= 4)
14933 Lisp_Object string
;
14935 /* Stop at nil string. */
14936 string
= AREF (items
, i
+ 1);
14940 /* Remember where item was displayed. */
14941 AREF (items
, i
+ 3) = make_number (it
.hpos
);
14943 /* Display the item, pad with one space. */
14944 if (it
.current_x
< it
.last_visible_x
)
14945 display_string (NULL
, string
, Qnil
, 0, 0, &it
,
14946 SCHARS (string
) + 1, 0, 0, -1);
14949 /* Fill out the line with spaces. */
14950 if (it
.current_x
< it
.last_visible_x
)
14951 display_string ("", Qnil
, Qnil
, 0, 0, &it
, -1, 0, 0, -1);
14953 /* Compute the total height of the lines. */
14954 compute_line_metrics (&it
);
14959 /***********************************************************************
14961 ***********************************************************************/
14963 /* Redisplay mode lines in the window tree whose root is WINDOW. If
14964 FORCE is non-zero, redisplay mode lines unconditionally.
14965 Otherwise, redisplay only mode lines that are garbaged. Value is
14966 the number of windows whose mode lines were redisplayed. */
14969 redisplay_mode_lines (window
, force
)
14970 Lisp_Object window
;
14975 while (!NILP (window
))
14977 struct window
*w
= XWINDOW (window
);
14979 if (WINDOWP (w
->hchild
))
14980 nwindows
+= redisplay_mode_lines (w
->hchild
, force
);
14981 else if (WINDOWP (w
->vchild
))
14982 nwindows
+= redisplay_mode_lines (w
->vchild
, force
);
14984 || FRAME_GARBAGED_P (XFRAME (w
->frame
))
14985 || !MATRIX_MODE_LINE_ROW (w
->current_matrix
)->enabled_p
)
14987 struct text_pos lpoint
;
14988 struct buffer
*old
= current_buffer
;
14990 /* Set the window's buffer for the mode line display. */
14991 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
14992 set_buffer_internal_1 (XBUFFER (w
->buffer
));
14994 /* Point refers normally to the selected window. For any
14995 other window, set up appropriate value. */
14996 if (!EQ (window
, selected_window
))
14998 struct text_pos pt
;
15000 SET_TEXT_POS_FROM_MARKER (pt
, w
->pointm
);
15001 if (CHARPOS (pt
) < BEGV
)
15002 TEMP_SET_PT_BOTH (BEGV
, BEGV_BYTE
);
15003 else if (CHARPOS (pt
) > (ZV
- 1))
15004 TEMP_SET_PT_BOTH (ZV
, ZV_BYTE
);
15006 TEMP_SET_PT_BOTH (CHARPOS (pt
), BYTEPOS (pt
));
15009 /* Display mode lines. */
15010 clear_glyph_matrix (w
->desired_matrix
);
15011 if (display_mode_lines (w
))
15014 w
->must_be_updated_p
= 1;
15017 /* Restore old settings. */
15018 set_buffer_internal_1 (old
);
15019 TEMP_SET_PT_BOTH (CHARPOS (lpoint
), BYTEPOS (lpoint
));
15029 /* Display the mode and/or top line of window W. Value is the number
15030 of mode lines displayed. */
15033 display_mode_lines (w
)
15036 Lisp_Object old_selected_window
, old_selected_frame
;
15039 old_selected_frame
= selected_frame
;
15040 selected_frame
= w
->frame
;
15041 old_selected_window
= selected_window
;
15042 XSETWINDOW (selected_window
, w
);
15044 /* These will be set while the mode line specs are processed. */
15045 line_number_displayed
= 0;
15046 w
->column_number_displayed
= Qnil
;
15048 if (WINDOW_WANTS_MODELINE_P (w
))
15050 struct window
*sel_w
= XWINDOW (old_selected_window
);
15052 /* Select mode line face based on the real selected window. */
15053 display_mode_line (w
, CURRENT_MODE_LINE_FACE_ID_3 (sel_w
, sel_w
, w
),
15054 current_buffer
->mode_line_format
);
15058 if (WINDOW_WANTS_HEADER_LINE_P (w
))
15060 display_mode_line (w
, HEADER_LINE_FACE_ID
,
15061 current_buffer
->header_line_format
);
15065 selected_frame
= old_selected_frame
;
15066 selected_window
= old_selected_window
;
15071 /* Display mode or top line of window W. FACE_ID specifies which line
15072 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
15073 FORMAT is the mode line format to display. Value is the pixel
15074 height of the mode line displayed. */
15077 display_mode_line (w
, face_id
, format
)
15079 enum face_id face_id
;
15080 Lisp_Object format
;
15085 init_iterator (&it
, w
, -1, -1, NULL
, face_id
);
15086 prepare_desired_row (it
.glyph_row
);
15088 it
.glyph_row
->mode_line_p
= 1;
15090 if (! mode_line_inverse_video
)
15091 /* Force the mode-line to be displayed in the default face. */
15092 it
.base_face_id
= it
.face_id
= DEFAULT_FACE_ID
;
15094 /* Temporarily make frame's keyboard the current kboard so that
15095 kboard-local variables in the mode_line_format will get the right
15097 push_frame_kboard (it
.f
);
15098 display_mode_element (&it
, 0, 0, 0, format
, Qnil
, 0);
15099 pop_frame_kboard ();
15101 /* Fill up with spaces. */
15102 display_string (" ", Qnil
, Qnil
, 0, 0, &it
, 10000, -1, -1, 0);
15104 compute_line_metrics (&it
);
15105 it
.glyph_row
->full_width_p
= 1;
15106 it
.glyph_row
->continued_p
= 0;
15107 it
.glyph_row
->truncated_on_left_p
= 0;
15108 it
.glyph_row
->truncated_on_right_p
= 0;
15110 /* Make a 3D mode-line have a shadow at its right end. */
15111 face
= FACE_FROM_ID (it
.f
, face_id
);
15112 extend_face_to_end_of_line (&it
);
15113 if (face
->box
!= FACE_NO_BOX
)
15115 struct glyph
*last
= (it
.glyph_row
->glyphs
[TEXT_AREA
]
15116 + it
.glyph_row
->used
[TEXT_AREA
] - 1);
15117 last
->right_box_line_p
= 1;
15120 return it
.glyph_row
->height
;
15123 /* Alist that caches the results of :propertize.
15124 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
15125 Lisp_Object mode_line_proptrans_alist
;
15127 /* List of strings making up the mode-line. */
15128 Lisp_Object mode_line_string_list
;
15130 /* Base face property when building propertized mode line string. */
15131 static Lisp_Object mode_line_string_face
;
15132 static Lisp_Object mode_line_string_face_prop
;
15135 /* Contribute ELT to the mode line for window IT->w. How it
15136 translates into text depends on its data type.
15138 IT describes the display environment in which we display, as usual.
15140 DEPTH is the depth in recursion. It is used to prevent
15141 infinite recursion here.
15143 FIELD_WIDTH is the number of characters the display of ELT should
15144 occupy in the mode line, and PRECISION is the maximum number of
15145 characters to display from ELT's representation. See
15146 display_string for details.
15148 Returns the hpos of the end of the text generated by ELT.
15150 PROPS is a property list to add to any string we encounter.
15152 If RISKY is nonzero, remove (disregard) any properties in any string
15153 we encounter, and ignore :eval and :propertize.
15155 If the global variable `frame_title_ptr' is non-NULL, then the output
15156 is passed to `store_frame_title' instead of `display_string'. */
15159 display_mode_element (it
, depth
, field_width
, precision
, elt
, props
, risky
)
15162 int field_width
, precision
;
15163 Lisp_Object elt
, props
;
15166 int n
= 0, field
, prec
;
15171 elt
= build_string ("*too-deep*");
15175 switch (SWITCH_ENUM_CAST (XTYPE (elt
)))
15179 /* A string: output it and check for %-constructs within it. */
15181 const unsigned char *this, *lisp_string
;
15183 if (!NILP (props
) || risky
)
15185 Lisp_Object oprops
, aelt
;
15186 oprops
= Ftext_properties_at (make_number (0), elt
);
15188 if (NILP (Fequal (props
, oprops
)) || risky
)
15190 /* If the starting string has properties,
15191 merge the specified ones onto the existing ones. */
15192 if (! NILP (oprops
) && !risky
)
15196 oprops
= Fcopy_sequence (oprops
);
15198 while (CONSP (tem
))
15200 oprops
= Fplist_put (oprops
, XCAR (tem
),
15201 XCAR (XCDR (tem
)));
15202 tem
= XCDR (XCDR (tem
));
15207 aelt
= Fassoc (elt
, mode_line_proptrans_alist
);
15208 if (! NILP (aelt
) && !NILP (Fequal (props
, XCDR (aelt
))))
15210 mode_line_proptrans_alist
15211 = Fcons (aelt
, Fdelq (aelt
, mode_line_proptrans_alist
));
15218 elt
= Fcopy_sequence (elt
);
15219 Fset_text_properties (make_number (0), Flength (elt
),
15221 /* Add this item to mode_line_proptrans_alist. */
15222 mode_line_proptrans_alist
15223 = Fcons (Fcons (elt
, props
),
15224 mode_line_proptrans_alist
);
15225 /* Truncate mode_line_proptrans_alist
15226 to at most 50 elements. */
15227 tem
= Fnthcdr (make_number (50),
15228 mode_line_proptrans_alist
);
15230 XSETCDR (tem
, Qnil
);
15235 this = SDATA (elt
);
15236 lisp_string
= this;
15240 prec
= precision
- n
;
15241 if (frame_title_ptr
)
15242 n
+= store_frame_title (SDATA (elt
), -1, prec
);
15243 else if (!NILP (mode_line_string_list
))
15244 n
+= store_mode_line_string (NULL
, elt
, 1, 0, prec
, Qnil
);
15246 n
+= display_string (NULL
, elt
, Qnil
, 0, 0, it
,
15247 0, prec
, 0, STRING_MULTIBYTE (elt
));
15252 while ((precision
<= 0 || n
< precision
)
15254 && (frame_title_ptr
15255 || !NILP (mode_line_string_list
)
15256 || it
->current_x
< it
->last_visible_x
))
15258 const unsigned char *last
= this;
15260 /* Advance to end of string or next format specifier. */
15261 while ((c
= *this++) != '\0' && c
!= '%')
15264 if (this - 1 != last
)
15266 /* Output to end of string or up to '%'. Field width
15267 is length of string. Don't output more than
15268 PRECISION allows us. */
15271 prec
= chars_in_text (last
, this - last
);
15272 if (precision
> 0 && prec
> precision
- n
)
15273 prec
= precision
- n
;
15275 if (frame_title_ptr
)
15276 n
+= store_frame_title (last
, 0, prec
);
15277 else if (!NILP (mode_line_string_list
))
15279 int bytepos
= last
- lisp_string
;
15280 int charpos
= string_byte_to_char (elt
, bytepos
);
15281 n
+= store_mode_line_string (NULL
,
15282 Fsubstring (elt
, make_number (charpos
),
15283 make_number (charpos
+ prec
)),
15288 int bytepos
= last
- lisp_string
;
15289 int charpos
= string_byte_to_char (elt
, bytepos
);
15290 n
+= display_string (NULL
, elt
, Qnil
, 0, charpos
,
15292 STRING_MULTIBYTE (elt
));
15295 else /* c == '%' */
15297 const unsigned char *percent_position
= this;
15299 /* Get the specified minimum width. Zero means
15302 while ((c
= *this++) >= '0' && c
<= '9')
15303 field
= field
* 10 + c
- '0';
15305 /* Don't pad beyond the total padding allowed. */
15306 if (field_width
- n
> 0 && field
> field_width
- n
)
15307 field
= field_width
- n
;
15309 /* Note that either PRECISION <= 0 or N < PRECISION. */
15310 prec
= precision
- n
;
15313 n
+= display_mode_element (it
, depth
, field
, prec
,
15314 Vglobal_mode_string
, props
,
15319 int bytepos
, charpos
;
15320 unsigned char *spec
;
15322 bytepos
= percent_position
- lisp_string
;
15323 charpos
= (STRING_MULTIBYTE (elt
)
15324 ? string_byte_to_char (elt
, bytepos
)
15328 = decode_mode_spec (it
->w
, c
, field
, prec
, &multibyte
);
15330 if (frame_title_ptr
)
15331 n
+= store_frame_title (spec
, field
, prec
);
15332 else if (!NILP (mode_line_string_list
))
15334 int len
= strlen (spec
);
15335 Lisp_Object tem
= make_string (spec
, len
);
15336 props
= Ftext_properties_at (make_number (charpos
), elt
);
15337 /* Should only keep face property in props */
15338 n
+= store_mode_line_string (NULL
, tem
, 0, field
, prec
, props
);
15342 int nglyphs_before
, nwritten
;
15344 nglyphs_before
= it
->glyph_row
->used
[TEXT_AREA
];
15345 nwritten
= display_string (spec
, Qnil
, elt
,
15350 /* Assign to the glyphs written above the
15351 string where the `%x' came from, position
15355 struct glyph
*glyph
15356 = (it
->glyph_row
->glyphs
[TEXT_AREA
]
15360 for (i
= 0; i
< nwritten
; ++i
)
15362 glyph
[i
].object
= elt
;
15363 glyph
[i
].charpos
= charpos
;
15378 /* A symbol: process the value of the symbol recursively
15379 as if it appeared here directly. Avoid error if symbol void.
15380 Special case: if value of symbol is a string, output the string
15383 register Lisp_Object tem
;
15385 /* If the variable is not marked as risky to set
15386 then its contents are risky to use. */
15387 if (NILP (Fget (elt
, Qrisky_local_variable
)))
15390 tem
= Fboundp (elt
);
15393 tem
= Fsymbol_value (elt
);
15394 /* If value is a string, output that string literally:
15395 don't check for % within it. */
15399 if (!EQ (tem
, elt
))
15401 /* Give up right away for nil or t. */
15411 register Lisp_Object car
, tem
;
15413 /* A cons cell: five distinct cases.
15414 If first element is :eval or :propertize, do something special.
15415 If first element is a string or a cons, process all the elements
15416 and effectively concatenate them.
15417 If first element is a negative number, truncate displaying cdr to
15418 at most that many characters. If positive, pad (with spaces)
15419 to at least that many characters.
15420 If first element is a symbol, process the cadr or caddr recursively
15421 according to whether the symbol's value is non-nil or nil. */
15423 if (EQ (car
, QCeval
))
15425 /* An element of the form (:eval FORM) means evaluate FORM
15426 and use the result as mode line elements. */
15431 if (CONSP (XCDR (elt
)))
15434 spec
= safe_eval (XCAR (XCDR (elt
)));
15435 n
+= display_mode_element (it
, depth
, field_width
- n
,
15436 precision
- n
, spec
, props
,
15440 else if (EQ (car
, QCpropertize
))
15442 /* An element of the form (:propertize ELT PROPS...)
15443 means display ELT but applying properties PROPS. */
15448 if (CONSP (XCDR (elt
)))
15449 n
+= display_mode_element (it
, depth
, field_width
- n
,
15450 precision
- n
, XCAR (XCDR (elt
)),
15451 XCDR (XCDR (elt
)), risky
);
15453 else if (SYMBOLP (car
))
15455 tem
= Fboundp (car
);
15459 /* elt is now the cdr, and we know it is a cons cell.
15460 Use its car if CAR has a non-nil value. */
15463 tem
= Fsymbol_value (car
);
15470 /* Symbol's value is nil (or symbol is unbound)
15471 Get the cddr of the original list
15472 and if possible find the caddr and use that. */
15476 else if (!CONSP (elt
))
15481 else if (INTEGERP (car
))
15483 register int lim
= XINT (car
);
15487 /* Negative int means reduce maximum width. */
15488 if (precision
<= 0)
15491 precision
= min (precision
, -lim
);
15495 /* Padding specified. Don't let it be more than
15496 current maximum. */
15498 lim
= min (precision
, lim
);
15500 /* If that's more padding than already wanted, queue it.
15501 But don't reduce padding already specified even if
15502 that is beyond the current truncation point. */
15503 field_width
= max (lim
, field_width
);
15507 else if (STRINGP (car
) || CONSP (car
))
15509 register int limit
= 50;
15510 /* Limit is to protect against circular lists. */
15513 && (precision
<= 0 || n
< precision
))
15515 n
+= display_mode_element (it
, depth
, field_width
- n
,
15516 precision
- n
, XCAR (elt
),
15526 elt
= build_string ("*invalid*");
15530 /* Pad to FIELD_WIDTH. */
15531 if (field_width
> 0 && n
< field_width
)
15533 if (frame_title_ptr
)
15534 n
+= store_frame_title ("", field_width
- n
, 0);
15535 else if (!NILP (mode_line_string_list
))
15536 n
+= store_mode_line_string ("", Qnil
, 0, field_width
- n
, 0, Qnil
);
15538 n
+= display_string ("", Qnil
, Qnil
, 0, 0, it
, field_width
- n
,
15545 /* Store a mode-line string element in mode_line_string_list.
15547 If STRING is non-null, display that C string. Otherwise, the Lisp
15548 string LISP_STRING is displayed.
15550 FIELD_WIDTH is the minimum number of output glyphs to produce.
15551 If STRING has fewer characters than FIELD_WIDTH, pad to the right
15552 with spaces. FIELD_WIDTH <= 0 means don't pad.
15554 PRECISION is the maximum number of characters to output from
15555 STRING. PRECISION <= 0 means don't truncate the string.
15557 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
15558 properties to the string.
15560 PROPS are the properties to add to the string.
15561 The mode_line_string_face face property is always added to the string.
15564 static int store_mode_line_string (string
, lisp_string
, copy_string
, field_width
, precision
, props
)
15566 Lisp_Object lisp_string
;
15575 if (string
!= NULL
)
15577 len
= strlen (string
);
15578 if (precision
> 0 && len
> precision
)
15580 lisp_string
= make_string (string
, len
);
15582 props
= mode_line_string_face_prop
;
15583 else if (!NILP (mode_line_string_face
))
15585 Lisp_Object face
= Fplist_get (props
, Qface
);
15586 props
= Fcopy_sequence (props
);
15588 face
= mode_line_string_face
;
15590 face
= Fcons (face
, Fcons (mode_line_string_face
, Qnil
));
15591 props
= Fplist_put (props
, Qface
, face
);
15593 Fadd_text_properties (make_number (0), make_number (len
),
15594 props
, lisp_string
);
15598 len
= XFASTINT (Flength (lisp_string
));
15599 if (precision
> 0 && len
> precision
)
15602 lisp_string
= Fsubstring (lisp_string
, make_number (0), make_number (len
));
15605 if (!NILP (mode_line_string_face
))
15609 props
= Ftext_properties_at (make_number (0), lisp_string
);
15610 face
= Fplist_get (props
, Qface
);
15612 face
= mode_line_string_face
;
15614 face
= Fcons (face
, Fcons (mode_line_string_face
, Qnil
));
15615 props
= Fcons (Qface
, Fcons (face
, Qnil
));
15617 lisp_string
= Fcopy_sequence (lisp_string
);
15620 Fadd_text_properties (make_number (0), make_number (len
),
15621 props
, lisp_string
);
15626 mode_line_string_list
= Fcons (lisp_string
, mode_line_string_list
);
15630 if (field_width
> len
)
15632 field_width
-= len
;
15633 lisp_string
= Fmake_string (make_number (field_width
), make_number (' '));
15635 Fadd_text_properties (make_number (0), make_number (field_width
),
15636 props
, lisp_string
);
15637 mode_line_string_list
= Fcons (lisp_string
, mode_line_string_list
);
15645 DEFUN ("format-mode-line", Fformat_mode_line
, Sformat_mode_line
,
15647 doc
: /* Return the mode-line of selected window as a string.
15648 First optional arg FORMAT specifies a different format string (see
15649 `mode-line-format' for details) to use. If FORMAT is t, return
15650 the buffer's header-line. Second optional arg WINDOW specifies a
15651 different window to use as the context for the formatting.
15652 If third optional arg NO-PROPS is non-nil, string is not propertized. */)
15653 (format
, window
, no_props
)
15654 Lisp_Object format
, window
, no_props
;
15659 struct buffer
*old_buffer
= NULL
;
15660 enum face_id face_id
= DEFAULT_FACE_ID
;
15663 window
= selected_window
;
15664 CHECK_WINDOW (window
);
15665 w
= XWINDOW (window
);
15666 CHECK_BUFFER (w
->buffer
);
15668 if (XBUFFER (w
->buffer
) != current_buffer
)
15670 old_buffer
= current_buffer
;
15671 set_buffer_internal_1 (XBUFFER (w
->buffer
));
15674 if (NILP (format
) || EQ (format
, Qt
))
15676 face_id
= NILP (format
)
15677 ? CURRENT_MODE_LINE_FACE_ID (w
) :
15678 HEADER_LINE_FACE_ID
;
15679 format
= NILP (format
)
15680 ? current_buffer
->mode_line_format
15681 : current_buffer
->header_line_format
;
15684 init_iterator (&it
, w
, -1, -1, NULL
, face_id
);
15686 if (NILP (no_props
))
15688 mode_line_string_face
=
15689 (face_id
== MODE_LINE_FACE_ID
? Qmode_line
:
15690 face_id
== MODE_LINE_INACTIVE_FACE_ID
? Qmode_line_inactive
:
15691 face_id
== HEADER_LINE_FACE_ID
? Qheader_line
: Qnil
);
15693 mode_line_string_face_prop
=
15694 NILP (mode_line_string_face
) ? Qnil
:
15695 Fcons (Qface
, Fcons (mode_line_string_face
, Qnil
));
15697 /* We need a dummy last element in mode_line_string_list to
15698 indicate we are building the propertized mode-line string.
15699 Using mode_line_string_face_prop here GC protects it. */
15700 mode_line_string_list
=
15701 Fcons (mode_line_string_face_prop
, Qnil
);
15702 frame_title_ptr
= NULL
;
15706 mode_line_string_face_prop
= Qnil
;
15707 mode_line_string_list
= Qnil
;
15708 frame_title_ptr
= frame_title_buf
;
15711 push_frame_kboard (it
.f
);
15712 display_mode_element (&it
, 0, 0, 0, format
, Qnil
, 0);
15713 pop_frame_kboard ();
15716 set_buffer_internal_1 (old_buffer
);
15718 if (NILP (no_props
))
15721 mode_line_string_list
= Fnreverse (mode_line_string_list
);
15722 str
= Fmapconcat (intern ("identity"), XCDR (mode_line_string_list
),
15723 make_string ("", 0));
15724 mode_line_string_face_prop
= Qnil
;
15725 mode_line_string_list
= Qnil
;
15729 len
= frame_title_ptr
- frame_title_buf
;
15730 if (len
> 0 && frame_title_ptr
[-1] == '-')
15732 /* Mode lines typically ends with numerous dashes; reduce to two dashes. */
15733 while (frame_title_ptr
> frame_title_buf
&& *--frame_title_ptr
== '-')
15735 frame_title_ptr
+= 3; /* restore last non-dash + two dashes */
15736 if (len
> frame_title_ptr
- frame_title_buf
)
15737 len
= frame_title_ptr
- frame_title_buf
;
15740 frame_title_ptr
= NULL
;
15741 return make_string (frame_title_buf
, len
);
15744 /* Write a null-terminated, right justified decimal representation of
15745 the positive integer D to BUF using a minimal field width WIDTH. */
15748 pint2str (buf
, width
, d
)
15749 register char *buf
;
15750 register int width
;
15753 register char *p
= buf
;
15761 *p
++ = d
% 10 + '0';
15766 for (width
-= (int) (p
- buf
); width
> 0; --width
)
15777 /* Write a null-terminated, right justified decimal and "human
15778 readable" representation of the nonnegative integer D to BUF using
15779 a minimal field width WIDTH. D should be smaller than 999.5e24. */
15781 static const char power_letter
[] =
15795 pint2hrstr (buf
, width
, d
)
15800 /* We aim to represent the nonnegative integer D as
15801 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
15804 /* -1 means: do not use TENTHS. */
15808 /* Length of QUOTIENT.TENTHS as a string. */
15814 if (1000 <= quotient
)
15816 /* Scale to the appropriate EXPONENT. */
15819 remainder
= quotient
% 1000;
15823 while (1000 <= quotient
);
15825 /* Round to nearest and decide whether to use TENTHS or not. */
15828 tenths
= remainder
/ 100;
15829 if (50 <= remainder
% 100)
15835 if (quotient
== 10)
15842 if (500 <= remainder
)
15843 if (quotient
< 999)
15853 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
15854 if (tenths
== -1 && quotient
<= 99)
15861 p
= psuffix
= buf
+ max (width
, length
);
15863 /* Print EXPONENT. */
15865 *psuffix
++ = power_letter
[exponent
];
15868 /* Print TENTHS. */
15871 *--p
= '0' + tenths
;
15875 /* Print QUOTIENT. */
15878 int digit
= quotient
% 10;
15879 *--p
= '0' + digit
;
15881 while ((quotient
/= 10) != 0);
15883 /* Print leading spaces. */
15888 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
15889 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
15890 type of CODING_SYSTEM. Return updated pointer into BUF. */
15892 static unsigned char invalid_eol_type
[] = "(*invalid*)";
15895 decode_mode_spec_coding (coding_system
, buf
, eol_flag
)
15896 Lisp_Object coding_system
;
15897 register char *buf
;
15901 int multibyte
= !NILP (current_buffer
->enable_multibyte_characters
);
15902 const unsigned char *eol_str
;
15904 /* The EOL conversion we are using. */
15905 Lisp_Object eoltype
;
15907 val
= Fget (coding_system
, Qcoding_system
);
15910 if (!VECTORP (val
)) /* Not yet decided. */
15915 eoltype
= eol_mnemonic_undecided
;
15916 /* Don't mention EOL conversion if it isn't decided. */
15920 Lisp_Object eolvalue
;
15922 eolvalue
= Fget (coding_system
, Qeol_type
);
15925 *buf
++ = XFASTINT (AREF (val
, 1));
15929 /* The EOL conversion that is normal on this system. */
15931 if (NILP (eolvalue
)) /* Not yet decided. */
15932 eoltype
= eol_mnemonic_undecided
;
15933 else if (VECTORP (eolvalue
)) /* Not yet decided. */
15934 eoltype
= eol_mnemonic_undecided
;
15935 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
15936 eoltype
= (XFASTINT (eolvalue
) == 0
15937 ? eol_mnemonic_unix
15938 : (XFASTINT (eolvalue
) == 1
15939 ? eol_mnemonic_dos
: eol_mnemonic_mac
));
15945 /* Mention the EOL conversion if it is not the usual one. */
15946 if (STRINGP (eoltype
))
15948 eol_str
= SDATA (eoltype
);
15949 eol_str_len
= SBYTES (eoltype
);
15951 else if (INTEGERP (eoltype
)
15952 && CHAR_VALID_P (XINT (eoltype
), 0))
15954 unsigned char *tmp
= (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH
);
15955 eol_str_len
= CHAR_STRING (XINT (eoltype
), tmp
);
15960 eol_str
= invalid_eol_type
;
15961 eol_str_len
= sizeof (invalid_eol_type
) - 1;
15963 bcopy (eol_str
, buf
, eol_str_len
);
15964 buf
+= eol_str_len
;
15970 /* Return a string for the output of a mode line %-spec for window W,
15971 generated by character C. PRECISION >= 0 means don't return a
15972 string longer than that value. FIELD_WIDTH > 0 means pad the
15973 string returned with spaces to that value. Return 1 in *MULTIBYTE
15974 if the result is multibyte text. */
15976 static char lots_of_dashes
[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
15979 decode_mode_spec (w
, c
, field_width
, precision
, multibyte
)
15982 int field_width
, precision
;
15986 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
15987 char *decode_mode_spec_buf
= f
->decode_mode_spec_buffer
;
15988 struct buffer
*b
= XBUFFER (w
->buffer
);
15996 if (!NILP (b
->read_only
))
15998 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
16003 /* This differs from %* only for a modified read-only buffer. */
16004 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
16006 if (!NILP (b
->read_only
))
16011 /* This differs from %* in ignoring read-only-ness. */
16012 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
16024 if (command_loop_level
> 5)
16026 p
= decode_mode_spec_buf
;
16027 for (i
= 0; i
< command_loop_level
; i
++)
16030 return decode_mode_spec_buf
;
16038 if (command_loop_level
> 5)
16040 p
= decode_mode_spec_buf
;
16041 for (i
= 0; i
< command_loop_level
; i
++)
16044 return decode_mode_spec_buf
;
16051 /* Let lots_of_dashes be a string of infinite length. */
16052 if (!NILP (mode_line_string_list
))
16054 if (field_width
<= 0
16055 || field_width
> sizeof (lots_of_dashes
))
16057 for (i
= 0; i
< FRAME_MESSAGE_BUF_SIZE (f
) - 1; ++i
)
16058 decode_mode_spec_buf
[i
] = '-';
16059 decode_mode_spec_buf
[i
] = '\0';
16060 return decode_mode_spec_buf
;
16063 return lots_of_dashes
;
16072 int col
= (int) current_column (); /* iftc */
16073 w
->column_number_displayed
= make_number (col
);
16074 pint2str (decode_mode_spec_buf
, field_width
, col
);
16075 return decode_mode_spec_buf
;
16079 /* %F displays the frame name. */
16080 if (!NILP (f
->title
))
16081 return (char *) SDATA (f
->title
);
16082 if (f
->explicit_name
|| ! FRAME_WINDOW_P (f
))
16083 return (char *) SDATA (f
->name
);
16092 int size
= ZV
- BEGV
;
16093 pint2str (decode_mode_spec_buf
, field_width
, size
);
16094 return decode_mode_spec_buf
;
16099 int size
= ZV
- BEGV
;
16100 pint2hrstr (decode_mode_spec_buf
, field_width
, size
);
16101 return decode_mode_spec_buf
;
16106 int startpos
= XMARKER (w
->start
)->charpos
;
16107 int startpos_byte
= marker_byte_position (w
->start
);
16108 int line
, linepos
, linepos_byte
, topline
;
16110 int height
= WINDOW_TOTAL_LINES (w
);
16112 /* If we decided that this buffer isn't suitable for line numbers,
16113 don't forget that too fast. */
16114 if (EQ (w
->base_line_pos
, w
->buffer
))
16116 /* But do forget it, if the window shows a different buffer now. */
16117 else if (BUFFERP (w
->base_line_pos
))
16118 w
->base_line_pos
= Qnil
;
16120 /* If the buffer is very big, don't waste time. */
16121 if (INTEGERP (Vline_number_display_limit
)
16122 && BUF_ZV (b
) - BUF_BEGV (b
) > XINT (Vline_number_display_limit
))
16124 w
->base_line_pos
= Qnil
;
16125 w
->base_line_number
= Qnil
;
16129 if (!NILP (w
->base_line_number
)
16130 && !NILP (w
->base_line_pos
)
16131 && XFASTINT (w
->base_line_pos
) <= startpos
)
16133 line
= XFASTINT (w
->base_line_number
);
16134 linepos
= XFASTINT (w
->base_line_pos
);
16135 linepos_byte
= buf_charpos_to_bytepos (b
, linepos
);
16140 linepos
= BUF_BEGV (b
);
16141 linepos_byte
= BUF_BEGV_BYTE (b
);
16144 /* Count lines from base line to window start position. */
16145 nlines
= display_count_lines (linepos
, linepos_byte
,
16149 topline
= nlines
+ line
;
16151 /* Determine a new base line, if the old one is too close
16152 or too far away, or if we did not have one.
16153 "Too close" means it's plausible a scroll-down would
16154 go back past it. */
16155 if (startpos
== BUF_BEGV (b
))
16157 w
->base_line_number
= make_number (topline
);
16158 w
->base_line_pos
= make_number (BUF_BEGV (b
));
16160 else if (nlines
< height
+ 25 || nlines
> height
* 3 + 50
16161 || linepos
== BUF_BEGV (b
))
16163 int limit
= BUF_BEGV (b
);
16164 int limit_byte
= BUF_BEGV_BYTE (b
);
16166 int distance
= (height
* 2 + 30) * line_number_display_limit_width
;
16168 if (startpos
- distance
> limit
)
16170 limit
= startpos
- distance
;
16171 limit_byte
= CHAR_TO_BYTE (limit
);
16174 nlines
= display_count_lines (startpos
, startpos_byte
,
16176 - (height
* 2 + 30),
16178 /* If we couldn't find the lines we wanted within
16179 line_number_display_limit_width chars per line,
16180 give up on line numbers for this window. */
16181 if (position
== limit_byte
&& limit
== startpos
- distance
)
16183 w
->base_line_pos
= w
->buffer
;
16184 w
->base_line_number
= Qnil
;
16188 w
->base_line_number
= make_number (topline
- nlines
);
16189 w
->base_line_pos
= make_number (BYTE_TO_CHAR (position
));
16192 /* Now count lines from the start pos to point. */
16193 nlines
= display_count_lines (startpos
, startpos_byte
,
16194 PT_BYTE
, PT
, &junk
);
16196 /* Record that we did display the line number. */
16197 line_number_displayed
= 1;
16199 /* Make the string to show. */
16200 pint2str (decode_mode_spec_buf
, field_width
, topline
+ nlines
);
16201 return decode_mode_spec_buf
;
16204 char* p
= decode_mode_spec_buf
;
16205 int pad
= field_width
- 2;
16211 return decode_mode_spec_buf
;
16217 obj
= b
->mode_name
;
16221 if (BUF_BEGV (b
) > BUF_BEG (b
) || BUF_ZV (b
) < BUF_Z (b
))
16227 int pos
= marker_position (w
->start
);
16228 int total
= BUF_ZV (b
) - BUF_BEGV (b
);
16230 if (XFASTINT (w
->window_end_pos
) <= BUF_Z (b
) - BUF_ZV (b
))
16232 if (pos
<= BUF_BEGV (b
))
16237 else if (pos
<= BUF_BEGV (b
))
16241 if (total
> 1000000)
16242 /* Do it differently for a large value, to avoid overflow. */
16243 total
= ((pos
- BUF_BEGV (b
)) + (total
/ 100) - 1) / (total
/ 100);
16245 total
= ((pos
- BUF_BEGV (b
)) * 100 + total
- 1) / total
;
16246 /* We can't normally display a 3-digit number,
16247 so get us a 2-digit number that is close. */
16250 sprintf (decode_mode_spec_buf
, "%2d%%", total
);
16251 return decode_mode_spec_buf
;
16255 /* Display percentage of size above the bottom of the screen. */
16258 int toppos
= marker_position (w
->start
);
16259 int botpos
= BUF_Z (b
) - XFASTINT (w
->window_end_pos
);
16260 int total
= BUF_ZV (b
) - BUF_BEGV (b
);
16262 if (botpos
>= BUF_ZV (b
))
16264 if (toppos
<= BUF_BEGV (b
))
16271 if (total
> 1000000)
16272 /* Do it differently for a large value, to avoid overflow. */
16273 total
= ((botpos
- BUF_BEGV (b
)) + (total
/ 100) - 1) / (total
/ 100);
16275 total
= ((botpos
- BUF_BEGV (b
)) * 100 + total
- 1) / total
;
16276 /* We can't normally display a 3-digit number,
16277 so get us a 2-digit number that is close. */
16280 if (toppos
<= BUF_BEGV (b
))
16281 sprintf (decode_mode_spec_buf
, "Top%2d%%", total
);
16283 sprintf (decode_mode_spec_buf
, "%2d%%", total
);
16284 return decode_mode_spec_buf
;
16289 /* status of process */
16290 obj
= Fget_buffer_process (w
->buffer
);
16292 return "no process";
16293 #ifdef subprocesses
16294 obj
= Fsymbol_name (Fprocess_status (obj
));
16298 case 't': /* indicate TEXT or BINARY */
16299 #ifdef MODE_LINE_BINARY_TEXT
16300 return MODE_LINE_BINARY_TEXT (b
);
16306 /* coding-system (not including end-of-line format) */
16308 /* coding-system (including end-of-line type) */
16310 int eol_flag
= (c
== 'Z');
16311 char *p
= decode_mode_spec_buf
;
16313 if (! FRAME_WINDOW_P (f
))
16315 /* No need to mention EOL here--the terminal never needs
16316 to do EOL conversion. */
16317 p
= decode_mode_spec_coding (keyboard_coding
.symbol
, p
, 0);
16318 p
= decode_mode_spec_coding (terminal_coding
.symbol
, p
, 0);
16320 p
= decode_mode_spec_coding (b
->buffer_file_coding_system
,
16323 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
16324 #ifdef subprocesses
16325 obj
= Fget_buffer_process (Fcurrent_buffer ());
16326 if (PROCESSP (obj
))
16328 p
= decode_mode_spec_coding (XPROCESS (obj
)->decode_coding_system
,
16330 p
= decode_mode_spec_coding (XPROCESS (obj
)->encode_coding_system
,
16333 #endif /* subprocesses */
16336 return decode_mode_spec_buf
;
16342 *multibyte
= STRING_MULTIBYTE (obj
);
16343 return (char *) SDATA (obj
);
16350 /* Count up to COUNT lines starting from START / START_BYTE.
16351 But don't go beyond LIMIT_BYTE.
16352 Return the number of lines thus found (always nonnegative).
16354 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
16357 display_count_lines (start
, start_byte
, limit_byte
, count
, byte_pos_ptr
)
16358 int start
, start_byte
, limit_byte
, count
;
16361 register unsigned char *cursor
;
16362 unsigned char *base
;
16364 register int ceiling
;
16365 register unsigned char *ceiling_addr
;
16366 int orig_count
= count
;
16368 /* If we are not in selective display mode,
16369 check only for newlines. */
16370 int selective_display
= (!NILP (current_buffer
->selective_display
)
16371 && !INTEGERP (current_buffer
->selective_display
));
16375 while (start_byte
< limit_byte
)
16377 ceiling
= BUFFER_CEILING_OF (start_byte
);
16378 ceiling
= min (limit_byte
- 1, ceiling
);
16379 ceiling_addr
= BYTE_POS_ADDR (ceiling
) + 1;
16380 base
= (cursor
= BYTE_POS_ADDR (start_byte
));
16383 if (selective_display
)
16384 while (*cursor
!= '\n' && *cursor
!= 015 && ++cursor
!= ceiling_addr
)
16387 while (*cursor
!= '\n' && ++cursor
!= ceiling_addr
)
16390 if (cursor
!= ceiling_addr
)
16394 start_byte
+= cursor
- base
+ 1;
16395 *byte_pos_ptr
= start_byte
;
16399 if (++cursor
== ceiling_addr
)
16405 start_byte
+= cursor
- base
;
16410 while (start_byte
> limit_byte
)
16412 ceiling
= BUFFER_FLOOR_OF (start_byte
- 1);
16413 ceiling
= max (limit_byte
, ceiling
);
16414 ceiling_addr
= BYTE_POS_ADDR (ceiling
) - 1;
16415 base
= (cursor
= BYTE_POS_ADDR (start_byte
- 1) + 1);
16418 if (selective_display
)
16419 while (--cursor
!= ceiling_addr
16420 && *cursor
!= '\n' && *cursor
!= 015)
16423 while (--cursor
!= ceiling_addr
&& *cursor
!= '\n')
16426 if (cursor
!= ceiling_addr
)
16430 start_byte
+= cursor
- base
+ 1;
16431 *byte_pos_ptr
= start_byte
;
16432 /* When scanning backwards, we should
16433 not count the newline posterior to which we stop. */
16434 return - orig_count
- 1;
16440 /* Here we add 1 to compensate for the last decrement
16441 of CURSOR, which took it past the valid range. */
16442 start_byte
+= cursor
- base
+ 1;
16446 *byte_pos_ptr
= limit_byte
;
16449 return - orig_count
+ count
;
16450 return orig_count
- count
;
16456 /***********************************************************************
16458 ***********************************************************************/
16460 /* Display a NUL-terminated string, starting with index START.
16462 If STRING is non-null, display that C string. Otherwise, the Lisp
16463 string LISP_STRING is displayed.
16465 If FACE_STRING is not nil, FACE_STRING_POS is a position in
16466 FACE_STRING. Display STRING or LISP_STRING with the face at
16467 FACE_STRING_POS in FACE_STRING:
16469 Display the string in the environment given by IT, but use the
16470 standard display table, temporarily.
16472 FIELD_WIDTH is the minimum number of output glyphs to produce.
16473 If STRING has fewer characters than FIELD_WIDTH, pad to the right
16474 with spaces. If STRING has more characters, more than FIELD_WIDTH
16475 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
16477 PRECISION is the maximum number of characters to output from
16478 STRING. PRECISION < 0 means don't truncate the string.
16480 This is roughly equivalent to printf format specifiers:
16482 FIELD_WIDTH PRECISION PRINTF
16483 ----------------------------------------
16489 MULTIBYTE zero means do not display multibyte chars, > 0 means do
16490 display them, and < 0 means obey the current buffer's value of
16491 enable_multibyte_characters.
16493 Value is the number of glyphs produced. */
16496 display_string (string
, lisp_string
, face_string
, face_string_pos
,
16497 start
, it
, field_width
, precision
, max_x
, multibyte
)
16498 unsigned char *string
;
16499 Lisp_Object lisp_string
;
16500 Lisp_Object face_string
;
16501 int face_string_pos
;
16504 int field_width
, precision
, max_x
;
16507 int hpos_at_start
= it
->hpos
;
16508 int saved_face_id
= it
->face_id
;
16509 struct glyph_row
*row
= it
->glyph_row
;
16511 /* Initialize the iterator IT for iteration over STRING beginning
16512 with index START. */
16513 reseat_to_string (it
, string
, lisp_string
, start
,
16514 precision
, field_width
, multibyte
);
16516 /* If displaying STRING, set up the face of the iterator
16517 from LISP_STRING, if that's given. */
16518 if (STRINGP (face_string
))
16524 = face_at_string_position (it
->w
, face_string
, face_string_pos
,
16525 0, it
->region_beg_charpos
,
16526 it
->region_end_charpos
,
16527 &endptr
, it
->base_face_id
, 0);
16528 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
16529 it
->face_box_p
= face
->box
!= FACE_NO_BOX
;
16532 /* Set max_x to the maximum allowed X position. Don't let it go
16533 beyond the right edge of the window. */
16535 max_x
= it
->last_visible_x
;
16537 max_x
= min (max_x
, it
->last_visible_x
);
16539 /* Skip over display elements that are not visible. because IT->w is
16541 if (it
->current_x
< it
->first_visible_x
)
16542 move_it_in_display_line_to (it
, 100000, it
->first_visible_x
,
16543 MOVE_TO_POS
| MOVE_TO_X
);
16545 row
->ascent
= it
->max_ascent
;
16546 row
->height
= it
->max_ascent
+ it
->max_descent
;
16547 row
->phys_ascent
= it
->max_phys_ascent
;
16548 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
16550 /* This condition is for the case that we are called with current_x
16551 past last_visible_x. */
16552 while (it
->current_x
< max_x
)
16554 int x_before
, x
, n_glyphs_before
, i
, nglyphs
;
16556 /* Get the next display element. */
16557 if (!get_next_display_element (it
))
16560 /* Produce glyphs. */
16561 x_before
= it
->current_x
;
16562 n_glyphs_before
= it
->glyph_row
->used
[TEXT_AREA
];
16563 PRODUCE_GLYPHS (it
);
16565 nglyphs
= it
->glyph_row
->used
[TEXT_AREA
] - n_glyphs_before
;
16568 while (i
< nglyphs
)
16570 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
16572 if (!it
->truncate_lines_p
16573 && x
+ glyph
->pixel_width
> max_x
)
16575 /* End of continued line or max_x reached. */
16576 if (CHAR_GLYPH_PADDING_P (*glyph
))
16578 /* A wide character is unbreakable. */
16579 it
->glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
;
16580 it
->current_x
= x_before
;
16584 it
->glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
+ i
;
16589 else if (x
+ glyph
->pixel_width
> it
->first_visible_x
)
16591 /* Glyph is at least partially visible. */
16593 if (x
< it
->first_visible_x
)
16594 it
->glyph_row
->x
= x
- it
->first_visible_x
;
16598 /* Glyph is off the left margin of the display area.
16599 Should not happen. */
16603 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
16604 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
16605 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
16606 row
->phys_height
= max (row
->phys_height
,
16607 it
->max_phys_ascent
+ it
->max_phys_descent
);
16608 x
+= glyph
->pixel_width
;
16612 /* Stop if max_x reached. */
16616 /* Stop at line ends. */
16617 if (ITERATOR_AT_END_OF_LINE_P (it
))
16619 it
->continuation_lines_width
= 0;
16623 set_iterator_to_next (it
, 1);
16625 /* Stop if truncating at the right edge. */
16626 if (it
->truncate_lines_p
16627 && it
->current_x
>= it
->last_visible_x
)
16629 /* Add truncation mark, but don't do it if the line is
16630 truncated at a padding space. */
16631 if (IT_CHARPOS (*it
) < it
->string_nchars
)
16633 if (!FRAME_WINDOW_P (it
->f
))
16637 if (it
->current_x
> it
->last_visible_x
)
16639 for (i
= row
->used
[TEXT_AREA
] - 1; i
> 0; --i
)
16640 if (!CHAR_GLYPH_PADDING_P (row
->glyphs
[TEXT_AREA
][i
]))
16642 for (n
= row
->used
[TEXT_AREA
]; i
< n
; ++i
)
16644 row
->used
[TEXT_AREA
] = i
;
16645 produce_special_glyphs (it
, IT_TRUNCATION
);
16648 produce_special_glyphs (it
, IT_TRUNCATION
);
16650 it
->glyph_row
->truncated_on_right_p
= 1;
16656 /* Maybe insert a truncation at the left. */
16657 if (it
->first_visible_x
16658 && IT_CHARPOS (*it
) > 0)
16660 if (!FRAME_WINDOW_P (it
->f
))
16661 insert_left_trunc_glyphs (it
);
16662 it
->glyph_row
->truncated_on_left_p
= 1;
16665 it
->face_id
= saved_face_id
;
16667 /* Value is number of columns displayed. */
16668 return it
->hpos
- hpos_at_start
;
16673 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
16674 appears as an element of LIST or as the car of an element of LIST.
16675 If PROPVAL is a list, compare each element against LIST in that
16676 way, and return 1/2 if any element of PROPVAL is found in LIST.
16677 Otherwise return 0. This function cannot quit.
16678 The return value is 2 if the text is invisible but with an ellipsis
16679 and 1 if it's invisible and without an ellipsis. */
16682 invisible_p (propval
, list
)
16683 register Lisp_Object propval
;
16686 register Lisp_Object tail
, proptail
;
16688 for (tail
= list
; CONSP (tail
); tail
= XCDR (tail
))
16690 register Lisp_Object tem
;
16692 if (EQ (propval
, tem
))
16694 if (CONSP (tem
) && EQ (propval
, XCAR (tem
)))
16695 return NILP (XCDR (tem
)) ? 1 : 2;
16698 if (CONSP (propval
))
16700 for (proptail
= propval
; CONSP (proptail
); proptail
= XCDR (proptail
))
16702 Lisp_Object propelt
;
16703 propelt
= XCAR (proptail
);
16704 for (tail
= list
; CONSP (tail
); tail
= XCDR (tail
))
16706 register Lisp_Object tem
;
16708 if (EQ (propelt
, tem
))
16710 if (CONSP (tem
) && EQ (propelt
, XCAR (tem
)))
16711 return NILP (XCDR (tem
)) ? 1 : 2;
16719 /* Calculate a width or height in pixels from a specification using
16720 the following elements:
16723 NUM - a (fractional) multiple of the default font width/height
16724 (NUM) - specifies exactly NUM pixels
16725 UNIT - a fixed number of pixels, see below.
16726 ELEMENT - size of a display element in pixels, see below.
16727 (NUM . SPEC) - equals NUM * SPEC
16728 (+ SPEC SPEC ...) - add pixel values
16729 (- SPEC SPEC ...) - subtract pixel values
16730 (- SPEC) - negate pixel value
16733 INT or FLOAT - a number constant
16734 SYMBOL - use symbol's (buffer local) variable binding.
16737 in - pixels per inch *)
16738 mm - pixels per 1/1000 meter *)
16739 cm - pixels per 1/100 meter *)
16740 width - width of current font in pixels.
16741 height - height of current font in pixels.
16743 *) using the ratio(s) defined in display-pixels-per-inch.
16747 left-fringe - left fringe width in pixels
16748 right-fringe - right fringe width in pixels
16750 left-margin - left margin width in pixels
16751 right-margin - right margin width in pixels
16753 scroll-bar - scroll-bar area width in pixels
16757 Pixels corresponding to 5 inches:
16760 Total width of non-text areas on left side of window (if scroll-bar is on left):
16761 '(space :width (+ left-fringe left-margin scroll-bar))
16763 Align to first text column (in header line):
16764 '(space :align-to 0)
16766 Align to middle of text area minus half the width of variable `my-image'
16767 containing a loaded image:
16768 '(space :align-to (0.5 . (- text my-image)))
16770 Width of left margin minus width of 1 character in the default font:
16771 '(space :width (- left-margin 1))
16773 Width of left margin minus width of 2 characters in the current font:
16774 '(space :width (- left-margin (2 . width)))
16776 Center 1 character over left-margin (in header line):
16777 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
16779 Different ways to express width of left fringe plus left margin minus one pixel:
16780 '(space :width (- (+ left-fringe left-margin) (1)))
16781 '(space :width (+ left-fringe left-margin (- (1))))
16782 '(space :width (+ left-fringe left-margin (-1)))
16786 #define NUMVAL(X) \
16787 ((INTEGERP (X) || FLOATP (X)) \
16792 calc_pixel_width_or_height (res
, it
, prop
, font
, width_p
, align_to
)
16797 int width_p
, *align_to
;
16801 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
16802 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
16805 return OK_PIXELS (0);
16807 if (SYMBOLP (prop
))
16809 if (SCHARS (SYMBOL_NAME (prop
)) == 2)
16811 char *unit
= SDATA (SYMBOL_NAME (prop
));
16813 if (unit
[0] == 'i' && unit
[1] == 'n')
16815 else if (unit
[0] == 'm' && unit
[1] == 'm')
16817 else if (unit
[0] == 'c' && unit
[1] == 'm')
16824 if ((ppi
= NUMVAL (Vdisplay_pixels_per_inch
), ppi
> 0)
16825 || (CONSP (Vdisplay_pixels_per_inch
)
16827 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch
))
16828 : NUMVAL (XCDR (Vdisplay_pixels_per_inch
))),
16830 return OK_PIXELS (ppi
/ pixels
);
16836 #ifdef HAVE_WINDOW_SYSTEM
16837 if (EQ (prop
, Qheight
))
16838 return OK_PIXELS (font
? FONT_HEIGHT ((XFontStruct
*)font
) : FRAME_LINE_HEIGHT (it
->f
));
16839 if (EQ (prop
, Qwidth
))
16840 return OK_PIXELS (font
? FONT_WIDTH ((XFontStruct
*)font
) : FRAME_COLUMN_WIDTH (it
->f
));
16842 if (EQ (prop
, Qheight
) || EQ (prop
, Qwidth
))
16843 return OK_PIXELS (1);
16846 if (EQ (prop
, Qtext
))
16847 return OK_PIXELS (width_p
16848 ? window_box_width (it
->w
, TEXT_AREA
)
16849 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it
->w
));
16851 if (align_to
&& *align_to
< 0)
16854 if (EQ (prop
, Qleft
))
16855 return OK_ALIGN_TO (window_box_left_offset (it
->w
, TEXT_AREA
));
16856 if (EQ (prop
, Qright
))
16857 return OK_ALIGN_TO (window_box_right_offset (it
->w
, TEXT_AREA
));
16858 if (EQ (prop
, Qcenter
))
16859 return OK_ALIGN_TO (window_box_left_offset (it
->w
, TEXT_AREA
)
16860 + window_box_width (it
->w
, TEXT_AREA
) / 2);
16861 if (EQ (prop
, Qleft_fringe
))
16862 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it
->w
)
16863 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it
->w
)
16864 : window_box_right_offset (it
->w
, LEFT_MARGIN_AREA
));
16865 if (EQ (prop
, Qright_fringe
))
16866 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it
->w
)
16867 ? window_box_right_offset (it
->w
, RIGHT_MARGIN_AREA
)
16868 : window_box_right_offset (it
->w
, TEXT_AREA
));
16869 if (EQ (prop
, Qleft_margin
))
16870 return OK_ALIGN_TO (window_box_left_offset (it
->w
, LEFT_MARGIN_AREA
));
16871 if (EQ (prop
, Qright_margin
))
16872 return OK_ALIGN_TO (window_box_left_offset (it
->w
, RIGHT_MARGIN_AREA
));
16873 if (EQ (prop
, Qscroll_bar
))
16874 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it
->w
)
16876 : (window_box_right_offset (it
->w
, RIGHT_MARGIN_AREA
)
16877 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it
->w
)
16878 ? WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)
16883 if (EQ (prop
, Qleft_fringe
))
16884 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it
->w
));
16885 if (EQ (prop
, Qright_fringe
))
16886 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it
->w
));
16887 if (EQ (prop
, Qleft_margin
))
16888 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it
->w
));
16889 if (EQ (prop
, Qright_margin
))
16890 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it
->w
));
16891 if (EQ (prop
, Qscroll_bar
))
16892 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it
->w
));
16895 prop
= Fbuffer_local_value (prop
, it
->w
->buffer
);
16898 if (INTEGERP (prop
) || FLOATP (prop
))
16900 int base_unit
= (width_p
16901 ? FRAME_COLUMN_WIDTH (it
->f
)
16902 : FRAME_LINE_HEIGHT (it
->f
));
16903 return OK_PIXELS (XFLOATINT (prop
) * base_unit
);
16908 Lisp_Object car
= XCAR (prop
);
16909 Lisp_Object cdr
= XCDR (prop
);
16913 #ifdef HAVE_WINDOW_SYSTEM
16914 if (valid_image_p (prop
))
16916 int id
= lookup_image (it
->f
, prop
);
16917 struct image
*img
= IMAGE_FROM_ID (it
->f
, id
);
16919 return OK_PIXELS (width_p
? img
->width
: img
->height
);
16922 if (EQ (car
, Qplus
) || EQ (car
, Qminus
))
16928 while (CONSP (cdr
))
16930 if (!calc_pixel_width_or_height (&px
, it
, XCAR (cdr
),
16931 font
, width_p
, align_to
))
16934 pixels
= (EQ (car
, Qplus
) ? px
: -px
), first
= 0;
16939 if (EQ (car
, Qminus
))
16941 return OK_PIXELS (pixels
);
16944 car
= Fbuffer_local_value (car
, it
->w
->buffer
);
16947 if (INTEGERP (car
) || FLOATP (car
))
16950 pixels
= XFLOATINT (car
);
16952 return OK_PIXELS (pixels
);
16953 if (calc_pixel_width_or_height (&fact
, it
, cdr
,
16954 font
, width_p
, align_to
))
16955 return OK_PIXELS (pixels
* fact
);
16966 /***********************************************************************
16968 ***********************************************************************/
16970 #ifdef HAVE_WINDOW_SYSTEM
16975 dump_glyph_string (s
)
16976 struct glyph_string
*s
;
16978 fprintf (stderr
, "glyph string\n");
16979 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
16980 s
->x
, s
->y
, s
->width
, s
->height
);
16981 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
16982 fprintf (stderr
, " hl = %d\n", s
->hl
);
16983 fprintf (stderr
, " left overhang = %d, right = %d\n",
16984 s
->left_overhang
, s
->right_overhang
);
16985 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
16986 fprintf (stderr
, " extends to end of line = %d\n",
16987 s
->extends_to_end_of_line_p
);
16988 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
16989 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
16992 #endif /* GLYPH_DEBUG */
16994 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
16995 of XChar2b structures for S; it can't be allocated in
16996 init_glyph_string because it must be allocated via `alloca'. W
16997 is the window on which S is drawn. ROW and AREA are the glyph row
16998 and area within the row from which S is constructed. START is the
16999 index of the first glyph structure covered by S. HL is a
17000 face-override for drawing S. */
17003 #define OPTIONAL_HDC(hdc) hdc,
17004 #define DECLARE_HDC(hdc) HDC hdc;
17005 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
17006 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
17009 #ifndef OPTIONAL_HDC
17010 #define OPTIONAL_HDC(hdc)
17011 #define DECLARE_HDC(hdc)
17012 #define ALLOCATE_HDC(hdc, f)
17013 #define RELEASE_HDC(hdc, f)
17017 init_glyph_string (s
, OPTIONAL_HDC (hdc
) char2b
, w
, row
, area
, start
, hl
)
17018 struct glyph_string
*s
;
17022 struct glyph_row
*row
;
17023 enum glyph_row_area area
;
17025 enum draw_glyphs_face hl
;
17027 bzero (s
, sizeof *s
);
17029 s
->f
= XFRAME (w
->frame
);
17033 s
->display
= FRAME_X_DISPLAY (s
->f
);
17034 s
->window
= FRAME_X_WINDOW (s
->f
);
17035 s
->char2b
= char2b
;
17039 s
->first_glyph
= row
->glyphs
[area
] + start
;
17040 s
->height
= row
->height
;
17041 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
17043 /* Display the internal border below the tool-bar window. */
17044 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
17045 s
->y
-= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
17047 s
->ybase
= s
->y
+ row
->ascent
;
17051 /* Append the list of glyph strings with head H and tail T to the list
17052 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
17055 append_glyph_string_lists (head
, tail
, h
, t
)
17056 struct glyph_string
**head
, **tail
;
17057 struct glyph_string
*h
, *t
;
17071 /* Prepend the list of glyph strings with head H and tail T to the
17072 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
17076 prepend_glyph_string_lists (head
, tail
, h
, t
)
17077 struct glyph_string
**head
, **tail
;
17078 struct glyph_string
*h
, *t
;
17092 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
17093 Set *HEAD and *TAIL to the resulting list. */
17096 append_glyph_string (head
, tail
, s
)
17097 struct glyph_string
**head
, **tail
;
17098 struct glyph_string
*s
;
17100 s
->next
= s
->prev
= NULL
;
17101 append_glyph_string_lists (head
, tail
, s
, s
);
17105 /* Get face and two-byte form of character glyph GLYPH on frame F.
17106 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
17107 a pointer to a realized face that is ready for display. */
17109 static INLINE
struct face
*
17110 get_glyph_face_and_encoding (f
, glyph
, char2b
, two_byte_p
)
17112 struct glyph
*glyph
;
17118 xassert (glyph
->type
== CHAR_GLYPH
);
17119 face
= FACE_FROM_ID (f
, glyph
->face_id
);
17124 if (!glyph
->multibyte_p
)
17126 /* Unibyte case. We don't have to encode, but we have to make
17127 sure to use a face suitable for unibyte. */
17128 STORE_XCHAR2B (char2b
, 0, glyph
->u
.ch
);
17130 else if (glyph
->u
.ch
< 128
17131 && glyph
->face_id
< BASIC_FACE_ID_SENTINEL
)
17133 /* Case of ASCII in a face known to fit ASCII. */
17134 STORE_XCHAR2B (char2b
, 0, glyph
->u
.ch
);
17138 int c1
, c2
, charset
;
17140 /* Split characters into bytes. If c2 is -1 afterwards, C is
17141 really a one-byte character so that byte1 is zero. */
17142 SPLIT_CHAR (glyph
->u
.ch
, charset
, c1
, c2
);
17144 STORE_XCHAR2B (char2b
, c1
, c2
);
17146 STORE_XCHAR2B (char2b
, 0, c1
);
17148 /* Maybe encode the character in *CHAR2B. */
17149 if (charset
!= CHARSET_ASCII
)
17151 struct font_info
*font_info
17152 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
17155 = FRAME_RIF (f
)->encode_char (glyph
->u
.ch
, char2b
, font_info
, two_byte_p
);
17159 /* Make sure X resources of the face are allocated. */
17160 xassert (face
!= NULL
);
17161 PREPARE_FACE_FOR_DISPLAY (f
, face
);
17166 /* Fill glyph string S with composition components specified by S->cmp.
17168 FACES is an array of faces for all components of this composition.
17169 S->gidx is the index of the first component for S.
17170 OVERLAPS_P non-zero means S should draw the foreground only, and
17171 use its physical height for clipping.
17173 Value is the index of a component not in S. */
17176 fill_composite_glyph_string (s
, faces
, overlaps_p
)
17177 struct glyph_string
*s
;
17178 struct face
**faces
;
17185 s
->for_overlaps_p
= overlaps_p
;
17187 s
->face
= faces
[s
->gidx
];
17188 s
->font
= s
->face
->font
;
17189 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
17191 /* For all glyphs of this composition, starting at the offset
17192 S->gidx, until we reach the end of the definition or encounter a
17193 glyph that requires the different face, add it to S. */
17195 for (i
= s
->gidx
+ 1; i
< s
->cmp
->glyph_len
&& faces
[i
] == s
->face
; ++i
)
17198 /* All glyph strings for the same composition has the same width,
17199 i.e. the width set for the first component of the composition. */
17201 s
->width
= s
->first_glyph
->pixel_width
;
17203 /* If the specified font could not be loaded, use the frame's
17204 default font, but record the fact that we couldn't load it in
17205 the glyph string so that we can draw rectangles for the
17206 characters of the glyph string. */
17207 if (s
->font
== NULL
)
17209 s
->font_not_found_p
= 1;
17210 s
->font
= FRAME_FONT (s
->f
);
17213 /* Adjust base line for subscript/superscript text. */
17214 s
->ybase
+= s
->first_glyph
->voffset
;
17216 xassert (s
->face
&& s
->face
->gc
);
17218 /* This glyph string must always be drawn with 16-bit functions. */
17221 return s
->gidx
+ s
->nchars
;
17225 /* Fill glyph string S from a sequence of character glyphs.
17227 FACE_ID is the face id of the string. START is the index of the
17228 first glyph to consider, END is the index of the last + 1.
17229 OVERLAPS_P non-zero means S should draw the foreground only, and
17230 use its physical height for clipping.
17232 Value is the index of the first glyph not in S. */
17235 fill_glyph_string (s
, face_id
, start
, end
, overlaps_p
)
17236 struct glyph_string
*s
;
17238 int start
, end
, overlaps_p
;
17240 struct glyph
*glyph
, *last
;
17242 int glyph_not_available_p
;
17244 xassert (s
->f
== XFRAME (s
->w
->frame
));
17245 xassert (s
->nchars
== 0);
17246 xassert (start
>= 0 && end
> start
);
17248 s
->for_overlaps_p
= overlaps_p
,
17249 glyph
= s
->row
->glyphs
[s
->area
] + start
;
17250 last
= s
->row
->glyphs
[s
->area
] + end
;
17251 voffset
= glyph
->voffset
;
17253 glyph_not_available_p
= glyph
->glyph_not_available_p
;
17255 while (glyph
< last
17256 && glyph
->type
== CHAR_GLYPH
17257 && glyph
->voffset
== voffset
17258 /* Same face id implies same font, nowadays. */
17259 && glyph
->face_id
== face_id
17260 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
17264 s
->face
= get_glyph_face_and_encoding (s
->f
, glyph
,
17265 s
->char2b
+ s
->nchars
,
17267 s
->two_byte_p
= two_byte_p
;
17269 xassert (s
->nchars
<= end
- start
);
17270 s
->width
+= glyph
->pixel_width
;
17274 s
->font
= s
->face
->font
;
17275 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
17277 /* If the specified font could not be loaded, use the frame's font,
17278 but record the fact that we couldn't load it in
17279 S->font_not_found_p so that we can draw rectangles for the
17280 characters of the glyph string. */
17281 if (s
->font
== NULL
|| glyph_not_available_p
)
17283 s
->font_not_found_p
= 1;
17284 s
->font
= FRAME_FONT (s
->f
);
17287 /* Adjust base line for subscript/superscript text. */
17288 s
->ybase
+= voffset
;
17290 xassert (s
->face
&& s
->face
->gc
);
17291 return glyph
- s
->row
->glyphs
[s
->area
];
17295 /* Fill glyph string S from image glyph S->first_glyph. */
17298 fill_image_glyph_string (s
)
17299 struct glyph_string
*s
;
17301 xassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
17302 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
17304 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
17305 s
->font
= s
->face
->font
;
17306 s
->width
= s
->first_glyph
->pixel_width
;
17308 /* Adjust base line for subscript/superscript text. */
17309 s
->ybase
+= s
->first_glyph
->voffset
;
17313 /* Fill glyph string S from a sequence of stretch glyphs.
17315 ROW is the glyph row in which the glyphs are found, AREA is the
17316 area within the row. START is the index of the first glyph to
17317 consider, END is the index of the last + 1.
17319 Value is the index of the first glyph not in S. */
17322 fill_stretch_glyph_string (s
, row
, area
, start
, end
)
17323 struct glyph_string
*s
;
17324 struct glyph_row
*row
;
17325 enum glyph_row_area area
;
17328 struct glyph
*glyph
, *last
;
17329 int voffset
, face_id
;
17331 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
17333 glyph
= s
->row
->glyphs
[s
->area
] + start
;
17334 last
= s
->row
->glyphs
[s
->area
] + end
;
17335 face_id
= glyph
->face_id
;
17336 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
17337 s
->font
= s
->face
->font
;
17338 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
17339 s
->width
= glyph
->pixel_width
;
17340 voffset
= glyph
->voffset
;
17344 && glyph
->type
== STRETCH_GLYPH
17345 && glyph
->voffset
== voffset
17346 && glyph
->face_id
== face_id
);
17348 s
->width
+= glyph
->pixel_width
;
17350 /* Adjust base line for subscript/superscript text. */
17351 s
->ybase
+= voffset
;
17353 /* The case that face->gc == 0 is handled when drawing the glyph
17354 string by calling PREPARE_FACE_FOR_DISPLAY. */
17356 return glyph
- s
->row
->glyphs
[s
->area
];
17361 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
17362 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
17363 assumed to be zero. */
17366 x_get_glyph_overhangs (glyph
, f
, left
, right
)
17367 struct glyph
*glyph
;
17371 *left
= *right
= 0;
17373 if (glyph
->type
== CHAR_GLYPH
)
17377 struct font_info
*font_info
;
17381 face
= get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
17383 font_info
= FONT_INFO_FROM_ID (f
, face
->font_info_id
);
17384 if (font
/* ++KFS: Should this be font_info ? */
17385 && (pcm
= FRAME_RIF (f
)->per_char_metric (font
, &char2b
, glyph
->font_type
)))
17387 if (pcm
->rbearing
> pcm
->width
)
17388 *right
= pcm
->rbearing
- pcm
->width
;
17389 if (pcm
->lbearing
< 0)
17390 *left
= -pcm
->lbearing
;
17396 /* Return the index of the first glyph preceding glyph string S that
17397 is overwritten by S because of S's left overhang. Value is -1
17398 if no glyphs are overwritten. */
17401 left_overwritten (s
)
17402 struct glyph_string
*s
;
17406 if (s
->left_overhang
)
17409 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
17410 int first
= s
->first_glyph
- glyphs
;
17412 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
17413 x
-= glyphs
[i
].pixel_width
;
17424 /* Return the index of the first glyph preceding glyph string S that
17425 is overwriting S because of its right overhang. Value is -1 if no
17426 glyph in front of S overwrites S. */
17429 left_overwriting (s
)
17430 struct glyph_string
*s
;
17433 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
17434 int first
= s
->first_glyph
- glyphs
;
17438 for (i
= first
- 1; i
>= 0; --i
)
17441 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
17444 x
-= glyphs
[i
].pixel_width
;
17451 /* Return the index of the last glyph following glyph string S that is
17452 not overwritten by S because of S's right overhang. Value is -1 if
17453 no such glyph is found. */
17456 right_overwritten (s
)
17457 struct glyph_string
*s
;
17461 if (s
->right_overhang
)
17464 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
17465 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
17466 int end
= s
->row
->used
[s
->area
];
17468 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
17469 x
+= glyphs
[i
].pixel_width
;
17478 /* Return the index of the last glyph following glyph string S that
17479 overwrites S because of its left overhang. Value is negative
17480 if no such glyph is found. */
17483 right_overwriting (s
)
17484 struct glyph_string
*s
;
17487 int end
= s
->row
->used
[s
->area
];
17488 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
17489 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
17493 for (i
= first
; i
< end
; ++i
)
17496 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
17499 x
+= glyphs
[i
].pixel_width
;
17506 /* Get face and two-byte form of character C in face FACE_ID on frame
17507 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
17508 means we want to display multibyte text. DISPLAY_P non-zero means
17509 make sure that X resources for the face returned are allocated.
17510 Value is a pointer to a realized face that is ready for display if
17511 DISPLAY_P is non-zero. */
17513 static INLINE
struct face
*
17514 get_char_face_and_encoding (f
, c
, face_id
, char2b
, multibyte_p
, display_p
)
17518 int multibyte_p
, display_p
;
17520 struct face
*face
= FACE_FROM_ID (f
, face_id
);
17524 /* Unibyte case. We don't have to encode, but we have to make
17525 sure to use a face suitable for unibyte. */
17526 STORE_XCHAR2B (char2b
, 0, c
);
17527 face_id
= FACE_FOR_CHAR (f
, face
, c
);
17528 face
= FACE_FROM_ID (f
, face_id
);
17530 else if (c
< 128 && face_id
< BASIC_FACE_ID_SENTINEL
)
17532 /* Case of ASCII in a face known to fit ASCII. */
17533 STORE_XCHAR2B (char2b
, 0, c
);
17537 int c1
, c2
, charset
;
17539 /* Split characters into bytes. If c2 is -1 afterwards, C is
17540 really a one-byte character so that byte1 is zero. */
17541 SPLIT_CHAR (c
, charset
, c1
, c2
);
17543 STORE_XCHAR2B (char2b
, c1
, c2
);
17545 STORE_XCHAR2B (char2b
, 0, c1
);
17547 /* Maybe encode the character in *CHAR2B. */
17548 if (face
->font
!= NULL
)
17550 struct font_info
*font_info
17551 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
17553 FRAME_RIF (f
)->encode_char (c
, char2b
, font_info
, 0);
17557 /* Make sure X resources of the face are allocated. */
17558 #ifdef HAVE_X_WINDOWS
17562 xassert (face
!= NULL
);
17563 PREPARE_FACE_FOR_DISPLAY (f
, face
);
17570 /* Set background width of glyph string S. START is the index of the
17571 first glyph following S. LAST_X is the right-most x-position + 1
17572 in the drawing area. */
17575 set_glyph_string_background_width (s
, start
, last_x
)
17576 struct glyph_string
*s
;
17580 /* If the face of this glyph string has to be drawn to the end of
17581 the drawing area, set S->extends_to_end_of_line_p. */
17582 struct face
*default_face
= FACE_FROM_ID (s
->f
, DEFAULT_FACE_ID
);
17584 if (start
== s
->row
->used
[s
->area
]
17585 && s
->area
== TEXT_AREA
17586 && ((s
->hl
== DRAW_NORMAL_TEXT
17587 && (s
->row
->fill_line_p
17588 || s
->face
->background
!= default_face
->background
17589 || s
->face
->stipple
!= default_face
->stipple
17590 || s
->row
->mouse_face_p
))
17591 || s
->hl
== DRAW_MOUSE_FACE
17592 || ((s
->hl
== DRAW_IMAGE_RAISED
|| s
->hl
== DRAW_IMAGE_SUNKEN
)
17593 && s
->row
->fill_line_p
)))
17594 s
->extends_to_end_of_line_p
= 1;
17596 /* If S extends its face to the end of the line, set its
17597 background_width to the distance to the right edge of the drawing
17599 if (s
->extends_to_end_of_line_p
)
17600 s
->background_width
= last_x
- s
->x
+ 1;
17602 s
->background_width
= s
->width
;
17606 /* Compute overhangs and x-positions for glyph string S and its
17607 predecessors, or successors. X is the starting x-position for S.
17608 BACKWARD_P non-zero means process predecessors. */
17611 compute_overhangs_and_x (s
, x
, backward_p
)
17612 struct glyph_string
*s
;
17620 if (FRAME_RIF (s
->f
)->compute_glyph_string_overhangs
)
17621 FRAME_RIF (s
->f
)->compute_glyph_string_overhangs (s
);
17631 if (FRAME_RIF (s
->f
)->compute_glyph_string_overhangs
)
17632 FRAME_RIF (s
->f
)->compute_glyph_string_overhangs (s
);
17642 /* The following macros are only called from draw_glyphs below.
17643 They reference the following parameters of that function directly:
17644 `w', `row', `area', and `overlap_p'
17645 as well as the following local variables:
17646 `s', `f', and `hdc' (in W32) */
17649 /* On W32, silently add local `hdc' variable to argument list of
17650 init_glyph_string. */
17651 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17652 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
17654 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17655 init_glyph_string (s, char2b, w, row, area, start, hl)
17658 /* Add a glyph string for a stretch glyph to the list of strings
17659 between HEAD and TAIL. START is the index of the stretch glyph in
17660 row area AREA of glyph row ROW. END is the index of the last glyph
17661 in that glyph row area. X is the current output position assigned
17662 to the new glyph string constructed. HL overrides that face of the
17663 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17664 is the right-most x-position of the drawing area. */
17666 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
17667 and below -- keep them on one line. */
17668 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17671 s = (struct glyph_string *) alloca (sizeof *s); \
17672 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17673 START = fill_stretch_glyph_string (s, row, area, START, END); \
17674 append_glyph_string (&HEAD, &TAIL, s); \
17680 /* Add a glyph string for an image glyph to the list of strings
17681 between HEAD and TAIL. START is the index of the image glyph in
17682 row area AREA of glyph row ROW. END is the index of the last glyph
17683 in that glyph row area. X is the current output position assigned
17684 to the new glyph string constructed. HL overrides that face of the
17685 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17686 is the right-most x-position of the drawing area. */
17688 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17691 s = (struct glyph_string *) alloca (sizeof *s); \
17692 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17693 fill_image_glyph_string (s); \
17694 append_glyph_string (&HEAD, &TAIL, s); \
17701 /* Add a glyph string for a sequence of character glyphs to the list
17702 of strings between HEAD and TAIL. START is the index of the first
17703 glyph in row area AREA of glyph row ROW that is part of the new
17704 glyph string. END is the index of the last glyph in that glyph row
17705 area. X is the current output position assigned to the new glyph
17706 string constructed. HL overrides that face of the glyph; e.g. it
17707 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
17708 right-most x-position of the drawing area. */
17710 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17716 c = (row)->glyphs[area][START].u.ch; \
17717 face_id = (row)->glyphs[area][START].face_id; \
17719 s = (struct glyph_string *) alloca (sizeof *s); \
17720 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
17721 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
17722 append_glyph_string (&HEAD, &TAIL, s); \
17724 START = fill_glyph_string (s, face_id, START, END, overlaps_p); \
17729 /* Add a glyph string for a composite sequence to the list of strings
17730 between HEAD and TAIL. START is the index of the first glyph in
17731 row area AREA of glyph row ROW that is part of the new glyph
17732 string. END is the index of the last glyph in that glyph row area.
17733 X is the current output position assigned to the new glyph string
17734 constructed. HL overrides that face of the glyph; e.g. it is
17735 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
17736 x-position of the drawing area. */
17738 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17740 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
17741 int face_id = (row)->glyphs[area][START].face_id; \
17742 struct face *base_face = FACE_FROM_ID (f, face_id); \
17743 struct composition *cmp = composition_table[cmp_id]; \
17744 int glyph_len = cmp->glyph_len; \
17746 struct face **faces; \
17747 struct glyph_string *first_s = NULL; \
17750 base_face = base_face->ascii_face; \
17751 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
17752 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
17753 /* At first, fill in `char2b' and `faces'. */ \
17754 for (n = 0; n < glyph_len; n++) \
17756 int c = COMPOSITION_GLYPH (cmp, n); \
17757 int this_face_id = FACE_FOR_CHAR (f, base_face, c); \
17758 faces[n] = FACE_FROM_ID (f, this_face_id); \
17759 get_char_face_and_encoding (f, c, this_face_id, \
17760 char2b + n, 1, 1); \
17763 /* Make glyph_strings for each glyph sequence that is drawable by \
17764 the same face, and append them to HEAD/TAIL. */ \
17765 for (n = 0; n < cmp->glyph_len;) \
17767 s = (struct glyph_string *) alloca (sizeof *s); \
17768 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \
17769 append_glyph_string (&(HEAD), &(TAIL), s); \
17777 n = fill_composite_glyph_string (s, faces, overlaps_p); \
17785 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
17786 of AREA of glyph row ROW on window W between indices START and END.
17787 HL overrides the face for drawing glyph strings, e.g. it is
17788 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
17789 x-positions of the drawing area.
17791 This is an ugly monster macro construct because we must use alloca
17792 to allocate glyph strings (because draw_glyphs can be called
17793 asynchronously). */
17795 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17798 HEAD = TAIL = NULL; \
17799 while (START < END) \
17801 struct glyph *first_glyph = (row)->glyphs[area] + START; \
17802 switch (first_glyph->type) \
17805 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
17809 case COMPOSITE_GLYPH: \
17810 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
17814 case STRETCH_GLYPH: \
17815 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
17819 case IMAGE_GLYPH: \
17820 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
17828 set_glyph_string_background_width (s, START, LAST_X); \
17835 /* Draw glyphs between START and END in AREA of ROW on window W,
17836 starting at x-position X. X is relative to AREA in W. HL is a
17837 face-override with the following meaning:
17839 DRAW_NORMAL_TEXT draw normally
17840 DRAW_CURSOR draw in cursor face
17841 DRAW_MOUSE_FACE draw in mouse face.
17842 DRAW_INVERSE_VIDEO draw in mode line face
17843 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
17844 DRAW_IMAGE_RAISED draw an image with a raised relief around it
17846 If OVERLAPS_P is non-zero, draw only the foreground of characters
17847 and clip to the physical height of ROW.
17849 Value is the x-position reached, relative to AREA of W. */
17852 draw_glyphs (w
, x
, row
, area
, start
, end
, hl
, overlaps_p
)
17855 struct glyph_row
*row
;
17856 enum glyph_row_area area
;
17858 enum draw_glyphs_face hl
;
17861 struct glyph_string
*head
, *tail
;
17862 struct glyph_string
*s
;
17863 int last_x
, area_width
;
17866 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
17869 ALLOCATE_HDC (hdc
, f
);
17871 /* Let's rather be paranoid than getting a SEGV. */
17872 end
= min (end
, row
->used
[area
]);
17873 start
= max (0, start
);
17874 start
= min (end
, start
);
17876 /* Translate X to frame coordinates. Set last_x to the right
17877 end of the drawing area. */
17878 if (row
->full_width_p
)
17880 /* X is relative to the left edge of W, without scroll bars
17882 x
+= WINDOW_LEFT_EDGE_X (w
);
17883 last_x
= WINDOW_LEFT_EDGE_X (w
) + WINDOW_TOTAL_WIDTH (w
);
17887 int area_left
= window_box_left (w
, area
);
17889 area_width
= window_box_width (w
, area
);
17890 last_x
= area_left
+ area_width
;
17893 /* Build a doubly-linked list of glyph_string structures between
17894 head and tail from what we have to draw. Note that the macro
17895 BUILD_GLYPH_STRINGS will modify its start parameter. That's
17896 the reason we use a separate variable `i'. */
17898 BUILD_GLYPH_STRINGS (i
, end
, head
, tail
, hl
, x
, last_x
);
17900 x_reached
= tail
->x
+ tail
->background_width
;
17904 /* If there are any glyphs with lbearing < 0 or rbearing > width in
17905 the row, redraw some glyphs in front or following the glyph
17906 strings built above. */
17907 if (head
&& !overlaps_p
&& row
->contains_overlapping_glyphs_p
)
17910 struct glyph_string
*h
, *t
;
17912 /* Compute overhangs for all glyph strings. */
17913 if (FRAME_RIF (f
)->compute_glyph_string_overhangs
)
17914 for (s
= head
; s
; s
= s
->next
)
17915 FRAME_RIF (f
)->compute_glyph_string_overhangs (s
);
17917 /* Prepend glyph strings for glyphs in front of the first glyph
17918 string that are overwritten because of the first glyph
17919 string's left overhang. The background of all strings
17920 prepended must be drawn because the first glyph string
17922 i
= left_overwritten (head
);
17926 BUILD_GLYPH_STRINGS (j
, start
, h
, t
,
17927 DRAW_NORMAL_TEXT
, dummy_x
, last_x
);
17929 compute_overhangs_and_x (t
, head
->x
, 1);
17930 prepend_glyph_string_lists (&head
, &tail
, h
, t
);
17933 /* Prepend glyph strings for glyphs in front of the first glyph
17934 string that overwrite that glyph string because of their
17935 right overhang. For these strings, only the foreground must
17936 be drawn, because it draws over the glyph string at `head'.
17937 The background must not be drawn because this would overwrite
17938 right overhangs of preceding glyphs for which no glyph
17940 i
= left_overwriting (head
);
17943 BUILD_GLYPH_STRINGS (i
, start
, h
, t
,
17944 DRAW_NORMAL_TEXT
, dummy_x
, last_x
);
17945 for (s
= h
; s
; s
= s
->next
)
17946 s
->background_filled_p
= 1;
17947 compute_overhangs_and_x (t
, head
->x
, 1);
17948 prepend_glyph_string_lists (&head
, &tail
, h
, t
);
17951 /* Append glyphs strings for glyphs following the last glyph
17952 string tail that are overwritten by tail. The background of
17953 these strings has to be drawn because tail's foreground draws
17955 i
= right_overwritten (tail
);
17958 BUILD_GLYPH_STRINGS (end
, i
, h
, t
,
17959 DRAW_NORMAL_TEXT
, x
, last_x
);
17960 compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
17961 append_glyph_string_lists (&head
, &tail
, h
, t
);
17964 /* Append glyph strings for glyphs following the last glyph
17965 string tail that overwrite tail. The foreground of such
17966 glyphs has to be drawn because it writes into the background
17967 of tail. The background must not be drawn because it could
17968 paint over the foreground of following glyphs. */
17969 i
= right_overwriting (tail
);
17972 BUILD_GLYPH_STRINGS (end
, i
, h
, t
,
17973 DRAW_NORMAL_TEXT
, x
, last_x
);
17974 for (s
= h
; s
; s
= s
->next
)
17975 s
->background_filled_p
= 1;
17976 compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
17977 append_glyph_string_lists (&head
, &tail
, h
, t
);
17981 /* Draw all strings. */
17982 for (s
= head
; s
; s
= s
->next
)
17983 FRAME_RIF (f
)->draw_glyph_string (s
);
17985 if (area
== TEXT_AREA
17986 && !row
->full_width_p
17987 /* When drawing overlapping rows, only the glyph strings'
17988 foreground is drawn, which doesn't erase a cursor
17992 int x0
= head
? head
->x
: x
;
17993 int x1
= tail
? tail
->x
+ tail
->background_width
: x
;
17995 int text_left
= window_box_left (w
, TEXT_AREA
);
17999 notice_overwritten_cursor (w
, TEXT_AREA
, x0
, x1
,
18000 row
->y
, MATRIX_ROW_BOTTOM_Y (row
));
18003 /* Value is the x-position up to which drawn, relative to AREA of W.
18004 This doesn't include parts drawn because of overhangs. */
18005 if (row
->full_width_p
)
18006 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
18008 x_reached
-= window_box_left (w
, area
);
18010 RELEASE_HDC (hdc
, f
);
18016 /* Store one glyph for IT->char_to_display in IT->glyph_row.
18017 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18023 struct glyph
*glyph
;
18024 enum glyph_row_area area
= it
->area
;
18026 xassert (it
->glyph_row
);
18027 xassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
18029 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
18030 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
18032 glyph
->charpos
= CHARPOS (it
->position
);
18033 glyph
->object
= it
->object
;
18034 glyph
->pixel_width
= it
->pixel_width
;
18035 glyph
->ascent
= it
->ascent
;
18036 glyph
->descent
= it
->descent
;
18037 glyph
->voffset
= it
->voffset
;
18038 glyph
->type
= CHAR_GLYPH
;
18039 glyph
->multibyte_p
= it
->multibyte_p
;
18040 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
18041 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
18042 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
18043 || it
->phys_descent
> it
->descent
);
18044 glyph
->padding_p
= 0;
18045 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
18046 glyph
->face_id
= it
->face_id
;
18047 glyph
->u
.ch
= it
->char_to_display
;
18048 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
18049 ++it
->glyph_row
->used
[area
];
18053 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
18054 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18057 append_composite_glyph (it
)
18060 struct glyph
*glyph
;
18061 enum glyph_row_area area
= it
->area
;
18063 xassert (it
->glyph_row
);
18065 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
18066 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
18068 glyph
->charpos
= CHARPOS (it
->position
);
18069 glyph
->object
= it
->object
;
18070 glyph
->pixel_width
= it
->pixel_width
;
18071 glyph
->ascent
= it
->ascent
;
18072 glyph
->descent
= it
->descent
;
18073 glyph
->voffset
= it
->voffset
;
18074 glyph
->type
= COMPOSITE_GLYPH
;
18075 glyph
->multibyte_p
= it
->multibyte_p
;
18076 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
18077 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
18078 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
18079 || it
->phys_descent
> it
->descent
);
18080 glyph
->padding_p
= 0;
18081 glyph
->glyph_not_available_p
= 0;
18082 glyph
->face_id
= it
->face_id
;
18083 glyph
->u
.cmp_id
= it
->cmp_id
;
18084 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
18085 ++it
->glyph_row
->used
[area
];
18090 /* Change IT->ascent and IT->height according to the setting of
18094 take_vertical_position_into_account (it
)
18099 if (it
->voffset
< 0)
18100 /* Increase the ascent so that we can display the text higher
18102 it
->ascent
+= abs (it
->voffset
);
18104 /* Increase the descent so that we can display the text lower
18106 it
->descent
+= it
->voffset
;
18111 /* Produce glyphs/get display metrics for the image IT is loaded with.
18112 See the description of struct display_iterator in dispextern.h for
18113 an overview of struct display_iterator. */
18116 produce_image_glyph (it
)
18121 int face_ascent
, glyph_ascent
;
18123 xassert (it
->what
== IT_IMAGE
);
18125 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
18127 /* Make sure X resources of the face is loaded. */
18128 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
18130 if (it
->image_id
< 0)
18132 /* Fringe bitmap. */
18133 it
->ascent
= it
->phys_ascent
= 0;
18134 it
->descent
= it
->phys_descent
= 0;
18135 it
->pixel_width
= 0;
18140 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
18142 /* Make sure X resources of the image is loaded. */
18143 prepare_image_for_display (it
->f
, img
);
18145 it
->ascent
= it
->phys_ascent
= glyph_ascent
= image_ascent (img
, face
);
18146 it
->descent
= it
->phys_descent
= img
->height
+ 2 * img
->vmargin
- it
->ascent
;
18147 it
->pixel_width
= img
->width
+ 2 * img
->hmargin
;
18149 /* It's quite possible for images to have an ascent greater than
18150 their height, so don't get confused in that case. */
18151 if (it
->descent
< 0)
18154 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
18155 face_ascent
= face
->font
? FONT_BASE (face
->font
) : FRAME_BASELINE_OFFSET (it
->f
);
18156 if (face_ascent
> it
->ascent
)
18157 it
->ascent
= it
->phys_ascent
= face_ascent
;
18161 if (face
->box
!= FACE_NO_BOX
)
18163 if (face
->box_line_width
> 0)
18165 it
->ascent
+= face
->box_line_width
;
18166 it
->descent
+= face
->box_line_width
;
18169 if (it
->start_of_box_run_p
)
18170 it
->pixel_width
+= abs (face
->box_line_width
);
18171 if (it
->end_of_box_run_p
)
18172 it
->pixel_width
+= abs (face
->box_line_width
);
18175 take_vertical_position_into_account (it
);
18179 struct glyph
*glyph
;
18180 enum glyph_row_area area
= it
->area
;
18182 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
18183 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
18185 glyph
->charpos
= CHARPOS (it
->position
);
18186 glyph
->object
= it
->object
;
18187 glyph
->pixel_width
= it
->pixel_width
;
18188 glyph
->ascent
= glyph_ascent
;
18189 glyph
->descent
= it
->descent
;
18190 glyph
->voffset
= it
->voffset
;
18191 glyph
->type
= IMAGE_GLYPH
;
18192 glyph
->multibyte_p
= it
->multibyte_p
;
18193 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
18194 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
18195 glyph
->overlaps_vertically_p
= 0;
18196 glyph
->padding_p
= 0;
18197 glyph
->glyph_not_available_p
= 0;
18198 glyph
->face_id
= it
->face_id
;
18199 glyph
->u
.img_id
= img
->id
;
18200 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
18201 ++it
->glyph_row
->used
[area
];
18207 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
18208 of the glyph, WIDTH and HEIGHT are the width and height of the
18209 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
18212 append_stretch_glyph (it
, object
, width
, height
, ascent
)
18214 Lisp_Object object
;
18218 struct glyph
*glyph
;
18219 enum glyph_row_area area
= it
->area
;
18221 xassert (ascent
>= 0 && ascent
<= height
);
18223 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
18224 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
18226 glyph
->charpos
= CHARPOS (it
->position
);
18227 glyph
->object
= object
;
18228 glyph
->pixel_width
= width
;
18229 glyph
->ascent
= ascent
;
18230 glyph
->descent
= height
- ascent
;
18231 glyph
->voffset
= it
->voffset
;
18232 glyph
->type
= STRETCH_GLYPH
;
18233 glyph
->multibyte_p
= it
->multibyte_p
;
18234 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
18235 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
18236 glyph
->overlaps_vertically_p
= 0;
18237 glyph
->padding_p
= 0;
18238 glyph
->glyph_not_available_p
= 0;
18239 glyph
->face_id
= it
->face_id
;
18240 glyph
->u
.stretch
.ascent
= ascent
;
18241 glyph
->u
.stretch
.height
= height
;
18242 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
18243 ++it
->glyph_row
->used
[area
];
18248 /* Produce a stretch glyph for iterator IT. IT->object is the value
18249 of the glyph property displayed. The value must be a list
18250 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
18253 1. `:width WIDTH' specifies that the space should be WIDTH *
18254 canonical char width wide. WIDTH may be an integer or floating
18257 2. `:relative-width FACTOR' specifies that the width of the stretch
18258 should be computed from the width of the first character having the
18259 `glyph' property, and should be FACTOR times that width.
18261 3. `:align-to HPOS' specifies that the space should be wide enough
18262 to reach HPOS, a value in canonical character units.
18264 Exactly one of the above pairs must be present.
18266 4. `:height HEIGHT' specifies that the height of the stretch produced
18267 should be HEIGHT, measured in canonical character units.
18269 5. `:relative-height FACTOR' specifies that the height of the
18270 stretch should be FACTOR times the height of the characters having
18271 the glyph property.
18273 Either none or exactly one of 4 or 5 must be present.
18275 6. `:ascent ASCENT' specifies that ASCENT percent of the height
18276 of the stretch should be used for the ascent of the stretch.
18277 ASCENT must be in the range 0 <= ASCENT <= 100. */
18280 produce_stretch_glyph (it
)
18283 /* (space :width WIDTH :height HEIGHT ...) */
18284 Lisp_Object prop
, plist
;
18285 int width
= 0, height
= 0, align_to
= -1;
18286 int zero_width_ok_p
= 0, zero_height_ok_p
= 0;
18289 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
18290 XFontStruct
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
18292 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
18294 /* List should start with `space'. */
18295 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
18296 plist
= XCDR (it
->object
);
18298 /* Compute the width of the stretch. */
18299 if ((prop
= Fplist_get (plist
, QCwidth
), !NILP (prop
))
18300 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 1, 0))
18302 /* Absolute width `:width WIDTH' specified and valid. */
18303 zero_width_ok_p
= 1;
18306 else if (prop
= Fplist_get (plist
, QCrelative_width
),
18309 /* Relative width `:relative-width FACTOR' specified and valid.
18310 Compute the width of the characters having the `glyph'
18313 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
18316 if (it
->multibyte_p
)
18318 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT
? ZV
: GPT
)
18319 - IT_BYTEPOS (*it
));
18320 it2
.c
= STRING_CHAR_AND_LENGTH (p
, maxlen
, it2
.len
);
18323 it2
.c
= *p
, it2
.len
= 1;
18325 it2
.glyph_row
= NULL
;
18326 it2
.what
= IT_CHARACTER
;
18327 x_produce_glyphs (&it2
);
18328 width
= NUMVAL (prop
) * it2
.pixel_width
;
18330 else if ((prop
= Fplist_get (plist
, QCalign_to
), !NILP (prop
))
18331 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 1, &align_to
))
18333 if (it
->glyph_row
== NULL
|| !it
->glyph_row
->mode_line_p
)
18334 align_to
= (align_to
< 0
18336 : align_to
- window_box_left_offset (it
->w
, TEXT_AREA
));
18337 else if (align_to
< 0)
18338 align_to
= window_box_left_offset (it
->w
, TEXT_AREA
);
18339 width
= max (0, (int)tem
+ align_to
- it
->current_x
);
18340 zero_width_ok_p
= 1;
18343 /* Nothing specified -> width defaults to canonical char width. */
18344 width
= FRAME_COLUMN_WIDTH (it
->f
);
18346 if (width
<= 0 && (width
< 0 || !zero_width_ok_p
))
18349 /* Compute height. */
18350 if ((prop
= Fplist_get (plist
, QCheight
), !NILP (prop
))
18351 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 0, 0))
18354 zero_height_ok_p
= 1;
18356 else if (prop
= Fplist_get (plist
, QCrelative_height
),
18358 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
18360 height
= FONT_HEIGHT (font
);
18362 if (height
<= 0 && (height
< 0 || !zero_height_ok_p
))
18365 /* Compute percentage of height used for ascent. If
18366 `:ascent ASCENT' is present and valid, use that. Otherwise,
18367 derive the ascent from the font in use. */
18368 if (prop
= Fplist_get (plist
, QCascent
),
18369 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
18370 ascent
= height
* NUMVAL (prop
) / 100.0;
18371 else if (!NILP (prop
)
18372 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, 0, 0))
18373 ascent
= min (max (0, (int)tem
), height
);
18375 ascent
= (height
* FONT_BASE (font
)) / FONT_HEIGHT (font
);
18377 if (width
> 0 && height
> 0 && it
->glyph_row
)
18379 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
18380 if (!STRINGP (object
))
18381 object
= it
->w
->buffer
;
18382 append_stretch_glyph (it
, object
, width
, height
, ascent
);
18385 it
->pixel_width
= width
;
18386 it
->ascent
= it
->phys_ascent
= ascent
;
18387 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
18388 it
->nglyphs
= width
> 0 && height
> 0 ? 1 : 0;
18390 if (width
> 0 && height
> 0 && face
->box
!= FACE_NO_BOX
)
18392 if (face
->box_line_width
> 0)
18394 it
->ascent
+= face
->box_line_width
;
18395 it
->descent
+= face
->box_line_width
;
18398 if (it
->start_of_box_run_p
)
18399 it
->pixel_width
+= abs (face
->box_line_width
);
18400 if (it
->end_of_box_run_p
)
18401 it
->pixel_width
+= abs (face
->box_line_width
);
18404 take_vertical_position_into_account (it
);
18408 Produce glyphs/get display metrics for the display element IT is
18409 loaded with. See the description of struct display_iterator in
18410 dispextern.h for an overview of struct display_iterator. */
18413 x_produce_glyphs (it
)
18416 it
->glyph_not_available_p
= 0;
18418 if (it
->what
== IT_CHARACTER
)
18422 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
18424 int font_not_found_p
;
18425 struct font_info
*font_info
;
18426 int boff
; /* baseline offset */
18427 /* We may change it->multibyte_p upon unibyte<->multibyte
18428 conversion. So, save the current value now and restore it
18431 Note: It seems that we don't have to record multibyte_p in
18432 struct glyph because the character code itself tells if or
18433 not the character is multibyte. Thus, in the future, we must
18434 consider eliminating the field `multibyte_p' in the struct
18436 int saved_multibyte_p
= it
->multibyte_p
;
18438 /* Maybe translate single-byte characters to multibyte, or the
18440 it
->char_to_display
= it
->c
;
18441 if (!ASCII_BYTE_P (it
->c
))
18443 if (unibyte_display_via_language_environment
18444 && SINGLE_BYTE_CHAR_P (it
->c
)
18446 || !NILP (Vnonascii_translation_table
)))
18448 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
18449 it
->multibyte_p
= 1;
18450 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
18451 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
18453 else if (!SINGLE_BYTE_CHAR_P (it
->c
)
18454 && !it
->multibyte_p
)
18456 it
->multibyte_p
= 1;
18457 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
18458 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
18462 /* Get font to use. Encode IT->char_to_display. */
18463 get_char_face_and_encoding (it
->f
, it
->char_to_display
, it
->face_id
,
18464 &char2b
, it
->multibyte_p
, 0);
18467 /* When no suitable font found, use the default font. */
18468 font_not_found_p
= font
== NULL
;
18469 if (font_not_found_p
)
18471 font
= FRAME_FONT (it
->f
);
18472 boff
= FRAME_BASELINE_OFFSET (it
->f
);
18477 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
18478 boff
= font_info
->baseline_offset
;
18479 if (font_info
->vertical_centering
)
18480 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
18483 if (it
->char_to_display
>= ' '
18484 && (!it
->multibyte_p
|| it
->char_to_display
< 128))
18486 /* Either unibyte or ASCII. */
18491 pcm
= FRAME_RIF (it
->f
)->per_char_metric (font
, &char2b
,
18492 FONT_TYPE_FOR_UNIBYTE (font
, it
->char_to_display
));
18493 it
->ascent
= FONT_BASE (font
) + boff
;
18494 it
->descent
= FONT_DESCENT (font
) - boff
;
18498 it
->phys_ascent
= pcm
->ascent
+ boff
;
18499 it
->phys_descent
= pcm
->descent
- boff
;
18500 it
->pixel_width
= pcm
->width
;
18504 it
->glyph_not_available_p
= 1;
18505 it
->phys_ascent
= FONT_BASE (font
) + boff
;
18506 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
18507 it
->pixel_width
= FONT_WIDTH (font
);
18510 /* If this is a space inside a region of text with
18511 `space-width' property, change its width. */
18512 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
18514 it
->pixel_width
*= XFLOATINT (it
->space_width
);
18516 /* If face has a box, add the box thickness to the character
18517 height. If character has a box line to the left and/or
18518 right, add the box line width to the character's width. */
18519 if (face
->box
!= FACE_NO_BOX
)
18521 int thick
= face
->box_line_width
;
18525 it
->ascent
+= thick
;
18526 it
->descent
+= thick
;
18531 if (it
->start_of_box_run_p
)
18532 it
->pixel_width
+= thick
;
18533 if (it
->end_of_box_run_p
)
18534 it
->pixel_width
+= thick
;
18537 /* If face has an overline, add the height of the overline
18538 (1 pixel) and a 1 pixel margin to the character height. */
18539 if (face
->overline_p
)
18542 take_vertical_position_into_account (it
);
18544 /* If we have to actually produce glyphs, do it. */
18549 /* Translate a space with a `space-width' property
18550 into a stretch glyph. */
18551 int ascent
= (((it
->ascent
+ it
->descent
) * FONT_BASE (font
))
18552 / FONT_HEIGHT (font
));
18553 append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
18554 it
->ascent
+ it
->descent
, ascent
);
18559 /* If characters with lbearing or rbearing are displayed
18560 in this line, record that fact in a flag of the
18561 glyph row. This is used to optimize X output code. */
18562 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
18563 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
18566 else if (it
->char_to_display
== '\n')
18568 /* A newline has no width but we need the height of the line. */
18569 it
->pixel_width
= 0;
18571 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
18572 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
18574 if (face
->box
!= FACE_NO_BOX
18575 && face
->box_line_width
> 0)
18577 it
->ascent
+= face
->box_line_width
;
18578 it
->descent
+= face
->box_line_width
;
18581 else if (it
->char_to_display
== '\t')
18583 int tab_width
= it
->tab_width
* FRAME_COLUMN_WIDTH (it
->f
);
18584 int x
= it
->current_x
+ it
->continuation_lines_width
;
18585 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
18587 /* If the distance from the current position to the next tab
18588 stop is less than a canonical character width, use the
18589 tab stop after that. */
18590 if (next_tab_x
- x
< FRAME_COLUMN_WIDTH (it
->f
))
18591 next_tab_x
+= tab_width
;
18593 it
->pixel_width
= next_tab_x
- x
;
18595 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
18596 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
18600 append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
18601 it
->ascent
+ it
->descent
, it
->ascent
);
18606 /* A multi-byte character. Assume that the display width of the
18607 character is the width of the character multiplied by the
18608 width of the font. */
18610 /* If we found a font, this font should give us the right
18611 metrics. If we didn't find a font, use the frame's
18612 default font and calculate the width of the character
18613 from the charset width; this is what old redisplay code
18616 pcm
= FRAME_RIF (it
->f
)->per_char_metric (font
, &char2b
,
18617 FONT_TYPE_FOR_MULTIBYTE (font
, it
->c
));
18619 if (font_not_found_p
|| !pcm
)
18621 int charset
= CHAR_CHARSET (it
->char_to_display
);
18623 it
->glyph_not_available_p
= 1;
18624 it
->pixel_width
= (FRAME_COLUMN_WIDTH (it
->f
)
18625 * CHARSET_WIDTH (charset
));
18626 it
->phys_ascent
= FONT_BASE (font
) + boff
;
18627 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
18631 it
->pixel_width
= pcm
->width
;
18632 it
->phys_ascent
= pcm
->ascent
+ boff
;
18633 it
->phys_descent
= pcm
->descent
- boff
;
18635 && (pcm
->lbearing
< 0
18636 || pcm
->rbearing
> pcm
->width
))
18637 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
18640 it
->ascent
= FONT_BASE (font
) + boff
;
18641 it
->descent
= FONT_DESCENT (font
) - boff
;
18642 if (face
->box
!= FACE_NO_BOX
)
18644 int thick
= face
->box_line_width
;
18648 it
->ascent
+= thick
;
18649 it
->descent
+= thick
;
18654 if (it
->start_of_box_run_p
)
18655 it
->pixel_width
+= thick
;
18656 if (it
->end_of_box_run_p
)
18657 it
->pixel_width
+= thick
;
18660 /* If face has an overline, add the height of the overline
18661 (1 pixel) and a 1 pixel margin to the character height. */
18662 if (face
->overline_p
)
18665 take_vertical_position_into_account (it
);
18670 it
->multibyte_p
= saved_multibyte_p
;
18672 else if (it
->what
== IT_COMPOSITION
)
18674 /* Note: A composition is represented as one glyph in the
18675 glyph matrix. There are no padding glyphs. */
18678 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
18680 int font_not_found_p
;
18681 struct font_info
*font_info
;
18682 int boff
; /* baseline offset */
18683 struct composition
*cmp
= composition_table
[it
->cmp_id
];
18685 /* Maybe translate single-byte characters to multibyte. */
18686 it
->char_to_display
= it
->c
;
18687 if (unibyte_display_via_language_environment
18688 && SINGLE_BYTE_CHAR_P (it
->c
)
18691 && !NILP (Vnonascii_translation_table
))))
18693 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
18696 /* Get face and font to use. Encode IT->char_to_display. */
18697 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
18698 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
18699 get_char_face_and_encoding (it
->f
, it
->char_to_display
, it
->face_id
,
18700 &char2b
, it
->multibyte_p
, 0);
18703 /* When no suitable font found, use the default font. */
18704 font_not_found_p
= font
== NULL
;
18705 if (font_not_found_p
)
18707 font
= FRAME_FONT (it
->f
);
18708 boff
= FRAME_BASELINE_OFFSET (it
->f
);
18713 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
18714 boff
= font_info
->baseline_offset
;
18715 if (font_info
->vertical_centering
)
18716 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
18719 /* There are no padding glyphs, so there is only one glyph to
18720 produce for the composition. Important is that pixel_width,
18721 ascent and descent are the values of what is drawn by
18722 draw_glyphs (i.e. the values of the overall glyphs composed). */
18725 /* If we have not yet calculated pixel size data of glyphs of
18726 the composition for the current face font, calculate them
18727 now. Theoretically, we have to check all fonts for the
18728 glyphs, but that requires much time and memory space. So,
18729 here we check only the font of the first glyph. This leads
18730 to incorrect display very rarely, and C-l (recenter) can
18731 correct the display anyway. */
18732 if (cmp
->font
!= (void *) font
)
18734 /* Ascent and descent of the font of the first character of
18735 this composition (adjusted by baseline offset). Ascent
18736 and descent of overall glyphs should not be less than
18737 them respectively. */
18738 int font_ascent
= FONT_BASE (font
) + boff
;
18739 int font_descent
= FONT_DESCENT (font
) - boff
;
18740 /* Bounding box of the overall glyphs. */
18741 int leftmost
, rightmost
, lowest
, highest
;
18742 int i
, width
, ascent
, descent
;
18744 cmp
->font
= (void *) font
;
18746 /* Initialize the bounding box. */
18748 && (pcm
= FRAME_RIF (it
->f
)->per_char_metric (font
, &char2b
,
18749 FONT_TYPE_FOR_MULTIBYTE (font
, it
->c
))))
18751 width
= pcm
->width
;
18752 ascent
= pcm
->ascent
;
18753 descent
= pcm
->descent
;
18757 width
= FONT_WIDTH (font
);
18758 ascent
= FONT_BASE (font
);
18759 descent
= FONT_DESCENT (font
);
18763 lowest
= - descent
+ boff
;
18764 highest
= ascent
+ boff
;
18768 && font_info
->default_ascent
18769 && CHAR_TABLE_P (Vuse_default_ascent
)
18770 && !NILP (Faref (Vuse_default_ascent
,
18771 make_number (it
->char_to_display
))))
18772 highest
= font_info
->default_ascent
+ boff
;
18774 /* Draw the first glyph at the normal position. It may be
18775 shifted to right later if some other glyphs are drawn at
18777 cmp
->offsets
[0] = 0;
18778 cmp
->offsets
[1] = boff
;
18780 /* Set cmp->offsets for the remaining glyphs. */
18781 for (i
= 1; i
< cmp
->glyph_len
; i
++)
18783 int left
, right
, btm
, top
;
18784 int ch
= COMPOSITION_GLYPH (cmp
, i
);
18785 int face_id
= FACE_FOR_CHAR (it
->f
, face
, ch
);
18787 face
= FACE_FROM_ID (it
->f
, face_id
);
18788 get_char_face_and_encoding (it
->f
, ch
, face
->id
,
18789 &char2b
, it
->multibyte_p
, 0);
18793 font
= FRAME_FONT (it
->f
);
18794 boff
= FRAME_BASELINE_OFFSET (it
->f
);
18800 = FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
18801 boff
= font_info
->baseline_offset
;
18802 if (font_info
->vertical_centering
)
18803 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
18807 && (pcm
= FRAME_RIF (it
->f
)->per_char_metric (font
, &char2b
,
18808 FONT_TYPE_FOR_MULTIBYTE (font
, ch
))))
18810 width
= pcm
->width
;
18811 ascent
= pcm
->ascent
;
18812 descent
= pcm
->descent
;
18816 width
= FONT_WIDTH (font
);
18821 if (cmp
->method
!= COMPOSITION_WITH_RULE_ALTCHARS
)
18823 /* Relative composition with or without
18824 alternate chars. */
18825 left
= (leftmost
+ rightmost
- width
) / 2;
18826 btm
= - descent
+ boff
;
18827 if (font_info
&& font_info
->relative_compose
18828 && (! CHAR_TABLE_P (Vignore_relative_composition
)
18829 || NILP (Faref (Vignore_relative_composition
,
18830 make_number (ch
)))))
18833 if (- descent
>= font_info
->relative_compose
)
18834 /* One extra pixel between two glyphs. */
18836 else if (ascent
<= 0)
18837 /* One extra pixel between two glyphs. */
18838 btm
= lowest
- 1 - ascent
- descent
;
18843 /* A composition rule is specified by an integer
18844 value that encodes global and new reference
18845 points (GREF and NREF). GREF and NREF are
18846 specified by numbers as below:
18848 0---1---2 -- ascent
18852 9--10--11 -- center
18854 ---3---4---5--- baseline
18856 6---7---8 -- descent
18858 int rule
= COMPOSITION_RULE (cmp
, i
);
18859 int gref
, nref
, grefx
, grefy
, nrefx
, nrefy
;
18861 COMPOSITION_DECODE_RULE (rule
, gref
, nref
);
18862 grefx
= gref
% 3, nrefx
= nref
% 3;
18863 grefy
= gref
/ 3, nrefy
= nref
/ 3;
18866 + grefx
* (rightmost
- leftmost
) / 2
18867 - nrefx
* width
/ 2);
18868 btm
= ((grefy
== 0 ? highest
18870 : grefy
== 2 ? lowest
18871 : (highest
+ lowest
) / 2)
18872 - (nrefy
== 0 ? ascent
+ descent
18873 : nrefy
== 1 ? descent
- boff
18875 : (ascent
+ descent
) / 2));
18878 cmp
->offsets
[i
* 2] = left
;
18879 cmp
->offsets
[i
* 2 + 1] = btm
+ descent
;
18881 /* Update the bounding box of the overall glyphs. */
18882 right
= left
+ width
;
18883 top
= btm
+ descent
+ ascent
;
18884 if (left
< leftmost
)
18886 if (right
> rightmost
)
18894 /* If there are glyphs whose x-offsets are negative,
18895 shift all glyphs to the right and make all x-offsets
18899 for (i
= 0; i
< cmp
->glyph_len
; i
++)
18900 cmp
->offsets
[i
* 2] -= leftmost
;
18901 rightmost
-= leftmost
;
18904 cmp
->pixel_width
= rightmost
;
18905 cmp
->ascent
= highest
;
18906 cmp
->descent
= - lowest
;
18907 if (cmp
->ascent
< font_ascent
)
18908 cmp
->ascent
= font_ascent
;
18909 if (cmp
->descent
< font_descent
)
18910 cmp
->descent
= font_descent
;
18913 it
->pixel_width
= cmp
->pixel_width
;
18914 it
->ascent
= it
->phys_ascent
= cmp
->ascent
;
18915 it
->descent
= it
->phys_descent
= cmp
->descent
;
18917 if (face
->box
!= FACE_NO_BOX
)
18919 int thick
= face
->box_line_width
;
18923 it
->ascent
+= thick
;
18924 it
->descent
+= thick
;
18929 if (it
->start_of_box_run_p
)
18930 it
->pixel_width
+= thick
;
18931 if (it
->end_of_box_run_p
)
18932 it
->pixel_width
+= thick
;
18935 /* If face has an overline, add the height of the overline
18936 (1 pixel) and a 1 pixel margin to the character height. */
18937 if (face
->overline_p
)
18940 take_vertical_position_into_account (it
);
18943 append_composite_glyph (it
);
18945 else if (it
->what
== IT_IMAGE
)
18946 produce_image_glyph (it
);
18947 else if (it
->what
== IT_STRETCH
)
18948 produce_stretch_glyph (it
);
18950 /* Accumulate dimensions. Note: can't assume that it->descent > 0
18951 because this isn't true for images with `:ascent 100'. */
18952 xassert (it
->ascent
>= 0 && it
->descent
>= 0);
18953 if (it
->area
== TEXT_AREA
)
18954 it
->current_x
+= it
->pixel_width
;
18956 it
->descent
+= it
->extra_line_spacing
;
18958 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
18959 it
->max_descent
= max (it
->max_descent
, it
->descent
);
18960 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
18961 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
18965 Output LEN glyphs starting at START at the nominal cursor position.
18966 Advance the nominal cursor over the text. The global variable
18967 updated_window contains the window being updated, updated_row is
18968 the glyph row being updated, and updated_area is the area of that
18969 row being updated. */
18972 x_write_glyphs (start
, len
)
18973 struct glyph
*start
;
18978 xassert (updated_window
&& updated_row
);
18981 /* Write glyphs. */
18983 hpos
= start
- updated_row
->glyphs
[updated_area
];
18984 x
= draw_glyphs (updated_window
, output_cursor
.x
,
18985 updated_row
, updated_area
,
18987 DRAW_NORMAL_TEXT
, 0);
18989 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
18990 if (updated_area
== TEXT_AREA
18991 && updated_window
->phys_cursor_on_p
18992 && updated_window
->phys_cursor
.vpos
== output_cursor
.vpos
18993 && updated_window
->phys_cursor
.hpos
>= hpos
18994 && updated_window
->phys_cursor
.hpos
< hpos
+ len
)
18995 updated_window
->phys_cursor_on_p
= 0;
18999 /* Advance the output cursor. */
19000 output_cursor
.hpos
+= len
;
19001 output_cursor
.x
= x
;
19006 Insert LEN glyphs from START at the nominal cursor position. */
19009 x_insert_glyphs (start
, len
)
19010 struct glyph
*start
;
19015 int line_height
, shift_by_width
, shifted_region_width
;
19016 struct glyph_row
*row
;
19017 struct glyph
*glyph
;
19018 int frame_x
, frame_y
, hpos
;
19020 xassert (updated_window
&& updated_row
);
19022 w
= updated_window
;
19023 f
= XFRAME (WINDOW_FRAME (w
));
19025 /* Get the height of the line we are in. */
19027 line_height
= row
->height
;
19029 /* Get the width of the glyphs to insert. */
19030 shift_by_width
= 0;
19031 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
19032 shift_by_width
+= glyph
->pixel_width
;
19034 /* Get the width of the region to shift right. */
19035 shifted_region_width
= (window_box_width (w
, updated_area
)
19040 frame_x
= window_box_left (w
, updated_area
) + output_cursor
.x
;
19041 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
19043 FRAME_RIF (f
)->shift_glyphs_for_insert (f
, frame_x
, frame_y
, shifted_region_width
,
19044 line_height
, shift_by_width
);
19046 /* Write the glyphs. */
19047 hpos
= start
- row
->glyphs
[updated_area
];
19048 draw_glyphs (w
, output_cursor
.x
, row
, updated_area
,
19050 DRAW_NORMAL_TEXT
, 0);
19052 /* Advance the output cursor. */
19053 output_cursor
.hpos
+= len
;
19054 output_cursor
.x
+= shift_by_width
;
19060 Erase the current text line from the nominal cursor position
19061 (inclusive) to pixel column TO_X (exclusive). The idea is that
19062 everything from TO_X onward is already erased.
19064 TO_X is a pixel position relative to updated_area of
19065 updated_window. TO_X == -1 means clear to the end of this area. */
19068 x_clear_end_of_line (to_x
)
19072 struct window
*w
= updated_window
;
19073 int max_x
, min_y
, max_y
;
19074 int from_x
, from_y
, to_y
;
19076 xassert (updated_window
&& updated_row
);
19077 f
= XFRAME (w
->frame
);
19079 if (updated_row
->full_width_p
)
19080 max_x
= WINDOW_TOTAL_WIDTH (w
);
19082 max_x
= window_box_width (w
, updated_area
);
19083 max_y
= window_text_bottom_y (w
);
19085 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
19086 of window. For TO_X > 0, truncate to end of drawing area. */
19092 to_x
= min (to_x
, max_x
);
19094 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
19096 /* Notice if the cursor will be cleared by this operation. */
19097 if (!updated_row
->full_width_p
)
19098 notice_overwritten_cursor (w
, updated_area
,
19099 output_cursor
.x
, -1,
19101 MATRIX_ROW_BOTTOM_Y (updated_row
));
19103 from_x
= output_cursor
.x
;
19105 /* Translate to frame coordinates. */
19106 if (updated_row
->full_width_p
)
19108 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
19109 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
19113 int area_left
= window_box_left (w
, updated_area
);
19114 from_x
+= area_left
;
19118 min_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
19119 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
19120 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
19122 /* Prevent inadvertently clearing to end of the X window. */
19123 if (to_x
> from_x
&& to_y
> from_y
)
19126 FRAME_RIF (f
)->clear_frame_area (f
, from_x
, from_y
,
19127 to_x
- from_x
, to_y
- from_y
);
19132 #endif /* HAVE_WINDOW_SYSTEM */
19136 /***********************************************************************
19138 ***********************************************************************/
19140 /* Value is the internal representation of the specified cursor type
19141 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
19142 of the bar cursor. */
19144 static enum text_cursor_kinds
19145 get_specified_cursor_type (arg
, width
)
19149 enum text_cursor_kinds type
;
19154 if (EQ (arg
, Qbox
))
19155 return FILLED_BOX_CURSOR
;
19157 if (EQ (arg
, Qhollow
))
19158 return HOLLOW_BOX_CURSOR
;
19160 if (EQ (arg
, Qbar
))
19167 && EQ (XCAR (arg
), Qbar
)
19168 && INTEGERP (XCDR (arg
))
19169 && XINT (XCDR (arg
)) >= 0)
19171 *width
= XINT (XCDR (arg
));
19175 if (EQ (arg
, Qhbar
))
19178 return HBAR_CURSOR
;
19182 && EQ (XCAR (arg
), Qhbar
)
19183 && INTEGERP (XCDR (arg
))
19184 && XINT (XCDR (arg
)) >= 0)
19186 *width
= XINT (XCDR (arg
));
19187 return HBAR_CURSOR
;
19190 /* Treat anything unknown as "hollow box cursor".
19191 It was bad to signal an error; people have trouble fixing
19192 .Xdefaults with Emacs, when it has something bad in it. */
19193 type
= HOLLOW_BOX_CURSOR
;
19198 /* Set the default cursor types for specified frame. */
19200 set_frame_cursor_types (f
, arg
)
19207 FRAME_DESIRED_CURSOR (f
) = get_specified_cursor_type (arg
, &width
);
19208 FRAME_CURSOR_WIDTH (f
) = width
;
19210 /* By default, set up the blink-off state depending on the on-state. */
19212 tem
= Fassoc (arg
, Vblink_cursor_alist
);
19215 FRAME_BLINK_OFF_CURSOR (f
)
19216 = get_specified_cursor_type (XCDR (tem
), &width
);
19217 FRAME_BLINK_OFF_CURSOR_WIDTH (f
) = width
;
19220 FRAME_BLINK_OFF_CURSOR (f
) = DEFAULT_CURSOR
;
19224 /* Return the cursor we want to be displayed in window W. Return
19225 width of bar/hbar cursor through WIDTH arg. Return with
19226 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
19227 (i.e. if the `system caret' should track this cursor).
19229 In a mini-buffer window, we want the cursor only to appear if we
19230 are reading input from this window. For the selected window, we
19231 want the cursor type given by the frame parameter or buffer local
19232 setting of cursor-type. If explicitly marked off, draw no cursor.
19233 In all other cases, we want a hollow box cursor. */
19235 static enum text_cursor_kinds
19236 get_window_cursor_type (w
, glyph
, width
, active_cursor
)
19238 struct glyph
*glyph
;
19240 int *active_cursor
;
19242 struct frame
*f
= XFRAME (w
->frame
);
19243 struct buffer
*b
= XBUFFER (w
->buffer
);
19244 int cursor_type
= DEFAULT_CURSOR
;
19245 Lisp_Object alt_cursor
;
19246 int non_selected
= 0;
19248 *active_cursor
= 1;
19251 if (cursor_in_echo_area
19252 && FRAME_HAS_MINIBUF_P (f
)
19253 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
19255 if (w
== XWINDOW (echo_area_window
))
19257 *width
= FRAME_CURSOR_WIDTH (f
);
19258 return FRAME_DESIRED_CURSOR (f
);
19261 *active_cursor
= 0;
19265 /* Nonselected window or nonselected frame. */
19266 else if (w
!= XWINDOW (f
->selected_window
)
19267 #ifdef HAVE_WINDOW_SYSTEM
19268 || f
!= FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
19272 *active_cursor
= 0;
19274 if (MINI_WINDOW_P (w
) && minibuf_level
== 0)
19280 /* Never display a cursor in a window in which cursor-type is nil. */
19281 if (NILP (b
->cursor_type
))
19284 /* Use cursor-in-non-selected-windows for non-selected window or frame. */
19287 alt_cursor
= Fbuffer_local_value (Qcursor_in_non_selected_windows
, w
->buffer
);
19288 return get_specified_cursor_type (alt_cursor
, width
);
19291 /* Get the normal cursor type for this window. */
19292 if (EQ (b
->cursor_type
, Qt
))
19294 cursor_type
= FRAME_DESIRED_CURSOR (f
);
19295 *width
= FRAME_CURSOR_WIDTH (f
);
19298 cursor_type
= get_specified_cursor_type (b
->cursor_type
, width
);
19300 /* Use normal cursor if not blinked off. */
19301 if (!w
->cursor_off_p
)
19303 if (glyph
!= NULL
&& glyph
->type
== IMAGE_GLYPH
) {
19304 if (cursor_type
== FILLED_BOX_CURSOR
)
19305 cursor_type
= HOLLOW_BOX_CURSOR
;
19307 return cursor_type
;
19310 /* Cursor is blinked off, so determine how to "toggle" it. */
19312 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
19313 if ((alt_cursor
= Fassoc (b
->cursor_type
, Vblink_cursor_alist
), !NILP (alt_cursor
)))
19314 return get_specified_cursor_type (XCDR (alt_cursor
), width
);
19316 /* Then see if frame has specified a specific blink off cursor type. */
19317 if (FRAME_BLINK_OFF_CURSOR (f
) != DEFAULT_CURSOR
)
19319 *width
= FRAME_BLINK_OFF_CURSOR_WIDTH (f
);
19320 return FRAME_BLINK_OFF_CURSOR (f
);
19324 /* Some people liked having a permanently visible blinking cursor,
19325 while others had very strong opinions against it. So it was
19326 decided to remove it. KFS 2003-09-03 */
19328 /* Finally perform built-in cursor blinking:
19329 filled box <-> hollow box
19330 wide [h]bar <-> narrow [h]bar
19331 narrow [h]bar <-> no cursor
19332 other type <-> no cursor */
19334 if (cursor_type
== FILLED_BOX_CURSOR
)
19335 return HOLLOW_BOX_CURSOR
;
19337 if ((cursor_type
== BAR_CURSOR
|| cursor_type
== HBAR_CURSOR
) && *width
> 1)
19340 return cursor_type
;
19348 #ifdef HAVE_WINDOW_SYSTEM
19350 /* Notice when the text cursor of window W has been completely
19351 overwritten by a drawing operation that outputs glyphs in AREA
19352 starting at X0 and ending at X1 in the line starting at Y0 and
19353 ending at Y1. X coordinates are area-relative. X1 < 0 means all
19354 the rest of the line after X0 has been written. Y coordinates
19355 are window-relative. */
19358 notice_overwritten_cursor (w
, area
, x0
, x1
, y0
, y1
)
19360 enum glyph_row_area area
;
19361 int x0
, y0
, x1
, y1
;
19363 int cx0
, cx1
, cy0
, cy1
;
19364 struct glyph_row
*row
;
19366 if (!w
->phys_cursor_on_p
)
19368 if (area
!= TEXT_AREA
)
19371 row
= w
->current_matrix
->rows
+ w
->phys_cursor
.vpos
;
19372 if (!row
->displays_text_p
)
19375 if (row
->cursor_in_fringe_p
)
19377 row
->cursor_in_fringe_p
= 0;
19378 draw_fringe_bitmap (w
, row
, 0);
19379 w
->phys_cursor_on_p
= 0;
19383 cx0
= w
->phys_cursor
.x
;
19384 cx1
= cx0
+ w
->phys_cursor_width
;
19385 if (x0
> cx0
|| (x1
>= 0 && x1
< cx1
))
19388 /* The cursor image will be completely removed from the
19389 screen if the output area intersects the cursor area in
19390 y-direction. When we draw in [y0 y1[, and some part of
19391 the cursor is at y < y0, that part must have been drawn
19392 before. When scrolling, the cursor is erased before
19393 actually scrolling, so we don't come here. When not
19394 scrolling, the rows above the old cursor row must have
19395 changed, and in this case these rows must have written
19396 over the cursor image.
19398 Likewise if part of the cursor is below y1, with the
19399 exception of the cursor being in the first blank row at
19400 the buffer and window end because update_text_area
19401 doesn't draw that row. (Except when it does, but
19402 that's handled in update_text_area.) */
19404 cy0
= w
->phys_cursor
.y
;
19405 cy1
= cy0
+ w
->phys_cursor_height
;
19406 if ((y0
< cy0
|| y0
>= cy1
) && (y1
<= cy0
|| y1
>= cy1
))
19409 w
->phys_cursor_on_p
= 0;
19412 #endif /* HAVE_WINDOW_SYSTEM */
19415 /************************************************************************
19417 ************************************************************************/
19419 #ifdef HAVE_WINDOW_SYSTEM
19422 Fix the display of area AREA of overlapping row ROW in window W. */
19425 x_fix_overlapping_area (w
, row
, area
)
19427 struct glyph_row
*row
;
19428 enum glyph_row_area area
;
19435 for (i
= 0; i
< row
->used
[area
];)
19437 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
19439 int start
= i
, start_x
= x
;
19443 x
+= row
->glyphs
[area
][i
].pixel_width
;
19446 while (i
< row
->used
[area
]
19447 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
19449 draw_glyphs (w
, start_x
, row
, area
,
19451 DRAW_NORMAL_TEXT
, 1);
19455 x
+= row
->glyphs
[area
][i
].pixel_width
;
19465 Draw the cursor glyph of window W in glyph row ROW. See the
19466 comment of draw_glyphs for the meaning of HL. */
19469 draw_phys_cursor_glyph (w
, row
, hl
)
19471 struct glyph_row
*row
;
19472 enum draw_glyphs_face hl
;
19474 /* If cursor hpos is out of bounds, don't draw garbage. This can
19475 happen in mini-buffer windows when switching between echo area
19476 glyphs and mini-buffer. */
19477 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
19479 int on_p
= w
->phys_cursor_on_p
;
19481 x1
= draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
19482 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
19484 w
->phys_cursor_on_p
= on_p
;
19486 if (hl
== DRAW_CURSOR
)
19487 w
->phys_cursor_width
= x1
- w
->phys_cursor
.x
;
19488 /* When we erase the cursor, and ROW is overlapped by other
19489 rows, make sure that these overlapping parts of other rows
19491 else if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
19493 if (row
> w
->current_matrix
->rows
19494 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
19495 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
);
19497 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
19498 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
19499 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
);
19506 Erase the image of a cursor of window W from the screen. */
19509 erase_phys_cursor (w
)
19512 struct frame
*f
= XFRAME (w
->frame
);
19513 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
19514 int hpos
= w
->phys_cursor
.hpos
;
19515 int vpos
= w
->phys_cursor
.vpos
;
19516 int mouse_face_here_p
= 0;
19517 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
19518 struct glyph_row
*cursor_row
;
19519 struct glyph
*cursor_glyph
;
19520 enum draw_glyphs_face hl
;
19522 /* No cursor displayed or row invalidated => nothing to do on the
19524 if (w
->phys_cursor_type
== NO_CURSOR
)
19525 goto mark_cursor_off
;
19527 /* VPOS >= active_glyphs->nrows means that window has been resized.
19528 Don't bother to erase the cursor. */
19529 if (vpos
>= active_glyphs
->nrows
)
19530 goto mark_cursor_off
;
19532 /* If row containing cursor is marked invalid, there is nothing we
19534 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
19535 if (!cursor_row
->enabled_p
)
19536 goto mark_cursor_off
;
19538 /* If row is completely invisible, don't attempt to delete a cursor which
19539 isn't there. This can happen if cursor is at top of a window, and
19540 we switch to a buffer with a header line in that window. */
19541 if (cursor_row
->visible_height
<= 0)
19542 goto mark_cursor_off
;
19544 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
19545 if (cursor_row
->cursor_in_fringe_p
)
19547 cursor_row
->cursor_in_fringe_p
= 0;
19548 draw_fringe_bitmap (w
, cursor_row
, 0);
19549 goto mark_cursor_off
;
19552 /* This can happen when the new row is shorter than the old one.
19553 In this case, either draw_glyphs or clear_end_of_line
19554 should have cleared the cursor. Note that we wouldn't be
19555 able to erase the cursor in this case because we don't have a
19556 cursor glyph at hand. */
19557 if (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])
19558 goto mark_cursor_off
;
19560 /* If the cursor is in the mouse face area, redisplay that when
19561 we clear the cursor. */
19562 if (! NILP (dpyinfo
->mouse_face_window
)
19563 && w
== XWINDOW (dpyinfo
->mouse_face_window
)
19564 && (vpos
> dpyinfo
->mouse_face_beg_row
19565 || (vpos
== dpyinfo
->mouse_face_beg_row
19566 && hpos
>= dpyinfo
->mouse_face_beg_col
))
19567 && (vpos
< dpyinfo
->mouse_face_end_row
19568 || (vpos
== dpyinfo
->mouse_face_end_row
19569 && hpos
< dpyinfo
->mouse_face_end_col
))
19570 /* Don't redraw the cursor's spot in mouse face if it is at the
19571 end of a line (on a newline). The cursor appears there, but
19572 mouse highlighting does not. */
19573 && cursor_row
->used
[TEXT_AREA
] > hpos
)
19574 mouse_face_here_p
= 1;
19576 /* Maybe clear the display under the cursor. */
19577 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
19580 int header_line_height
= WINDOW_HEADER_LINE_HEIGHT (w
);
19582 cursor_glyph
= get_phys_cursor_glyph (w
);
19583 if (cursor_glyph
== NULL
)
19584 goto mark_cursor_off
;
19586 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
19587 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
, cursor_row
->y
));
19589 FRAME_RIF (f
)->clear_frame_area (f
, x
, y
,
19590 cursor_glyph
->pixel_width
, cursor_row
->visible_height
);
19593 /* Erase the cursor by redrawing the character underneath it. */
19594 if (mouse_face_here_p
)
19595 hl
= DRAW_MOUSE_FACE
;
19597 hl
= DRAW_NORMAL_TEXT
;
19598 draw_phys_cursor_glyph (w
, cursor_row
, hl
);
19601 w
->phys_cursor_on_p
= 0;
19602 w
->phys_cursor_type
= NO_CURSOR
;
19607 Display or clear cursor of window W. If ON is zero, clear the
19608 cursor. If it is non-zero, display the cursor. If ON is nonzero,
19609 where to put the cursor is specified by HPOS, VPOS, X and Y. */
19612 display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
)
19614 int on
, hpos
, vpos
, x
, y
;
19616 struct frame
*f
= XFRAME (w
->frame
);
19617 int new_cursor_type
;
19618 int new_cursor_width
;
19620 struct glyph_row
*glyph_row
;
19621 struct glyph
*glyph
;
19623 /* This is pointless on invisible frames, and dangerous on garbaged
19624 windows and frames; in the latter case, the frame or window may
19625 be in the midst of changing its size, and x and y may be off the
19627 if (! FRAME_VISIBLE_P (f
)
19628 || FRAME_GARBAGED_P (f
)
19629 || vpos
>= w
->current_matrix
->nrows
19630 || hpos
>= w
->current_matrix
->matrix_w
)
19633 /* If cursor is off and we want it off, return quickly. */
19634 if (!on
&& !w
->phys_cursor_on_p
)
19637 glyph_row
= MATRIX_ROW (w
->current_matrix
, vpos
);
19638 /* If cursor row is not enabled, we don't really know where to
19639 display the cursor. */
19640 if (!glyph_row
->enabled_p
)
19642 w
->phys_cursor_on_p
= 0;
19647 if (!glyph_row
->exact_window_width_line_p
19648 || hpos
< glyph_row
->used
[TEXT_AREA
])
19649 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
19651 xassert (interrupt_input_blocked
);
19653 /* Set new_cursor_type to the cursor we want to be displayed. */
19654 new_cursor_type
= get_window_cursor_type (w
, glyph
,
19655 &new_cursor_width
, &active_cursor
);
19657 /* If cursor is currently being shown and we don't want it to be or
19658 it is in the wrong place, or the cursor type is not what we want,
19660 if (w
->phys_cursor_on_p
19662 || w
->phys_cursor
.x
!= x
19663 || w
->phys_cursor
.y
!= y
19664 || new_cursor_type
!= w
->phys_cursor_type
19665 || ((new_cursor_type
== BAR_CURSOR
|| new_cursor_type
== HBAR_CURSOR
)
19666 && new_cursor_width
!= w
->phys_cursor_width
)))
19667 erase_phys_cursor (w
);
19669 /* Don't check phys_cursor_on_p here because that flag is only set
19670 to zero in some cases where we know that the cursor has been
19671 completely erased, to avoid the extra work of erasing the cursor
19672 twice. In other words, phys_cursor_on_p can be 1 and the cursor
19673 still not be visible, or it has only been partly erased. */
19676 w
->phys_cursor_ascent
= glyph_row
->ascent
;
19677 w
->phys_cursor_height
= glyph_row
->height
;
19679 /* Set phys_cursor_.* before x_draw_.* is called because some
19680 of them may need the information. */
19681 w
->phys_cursor
.x
= x
;
19682 w
->phys_cursor
.y
= glyph_row
->y
;
19683 w
->phys_cursor
.hpos
= hpos
;
19684 w
->phys_cursor
.vpos
= vpos
;
19687 FRAME_RIF (f
)->draw_window_cursor (w
, glyph_row
, x
, y
,
19688 new_cursor_type
, new_cursor_width
,
19689 on
, active_cursor
);
19693 /* Switch the display of W's cursor on or off, according to the value
19697 update_window_cursor (w
, on
)
19701 /* Don't update cursor in windows whose frame is in the process
19702 of being deleted. */
19703 if (w
->current_matrix
)
19706 display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
19707 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
19713 /* Call update_window_cursor with parameter ON_P on all leaf windows
19714 in the window tree rooted at W. */
19717 update_cursor_in_window_tree (w
, on_p
)
19723 if (!NILP (w
->hchild
))
19724 update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
19725 else if (!NILP (w
->vchild
))
19726 update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
19728 update_window_cursor (w
, on_p
);
19730 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
19736 Display the cursor on window W, or clear it, according to ON_P.
19737 Don't change the cursor's position. */
19740 x_update_cursor (f
, on_p
)
19744 update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
19749 Clear the cursor of window W to background color, and mark the
19750 cursor as not shown. This is used when the text where the cursor
19751 is is about to be rewritten. */
19757 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
19758 update_window_cursor (w
, 0);
19763 Display the active region described by mouse_face_* according to DRAW. */
19766 show_mouse_face (dpyinfo
, draw
)
19767 Display_Info
*dpyinfo
;
19768 enum draw_glyphs_face draw
;
19770 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
19771 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
19773 if (/* If window is in the process of being destroyed, don't bother
19775 w
->current_matrix
!= NULL
19776 /* Don't update mouse highlight if hidden */
19777 && (draw
!= DRAW_MOUSE_FACE
|| !dpyinfo
->mouse_face_hidden
)
19778 /* Recognize when we are called to operate on rows that don't exist
19779 anymore. This can happen when a window is split. */
19780 && dpyinfo
->mouse_face_end_row
< w
->current_matrix
->nrows
)
19782 int phys_cursor_on_p
= w
->phys_cursor_on_p
;
19783 struct glyph_row
*row
, *first
, *last
;
19785 first
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_beg_row
);
19786 last
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_end_row
);
19788 for (row
= first
; row
<= last
&& row
->enabled_p
; ++row
)
19790 int start_hpos
, end_hpos
, start_x
;
19792 /* For all but the first row, the highlight starts at column 0. */
19795 start_hpos
= dpyinfo
->mouse_face_beg_col
;
19796 start_x
= dpyinfo
->mouse_face_beg_x
;
19805 end_hpos
= dpyinfo
->mouse_face_end_col
;
19807 end_hpos
= row
->used
[TEXT_AREA
];
19809 if (end_hpos
> start_hpos
)
19811 draw_glyphs (w
, start_x
, row
, TEXT_AREA
,
19812 start_hpos
, end_hpos
,
19816 = draw
== DRAW_MOUSE_FACE
|| draw
== DRAW_IMAGE_RAISED
;
19820 /* When we've written over the cursor, arrange for it to
19821 be displayed again. */
19822 if (phys_cursor_on_p
&& !w
->phys_cursor_on_p
)
19825 display_and_set_cursor (w
, 1,
19826 w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
19827 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
19832 /* Change the mouse cursor. */
19833 if (draw
== DRAW_NORMAL_TEXT
)
19834 FRAME_RIF (f
)->define_frame_cursor (f
, FRAME_X_OUTPUT (f
)->text_cursor
);
19835 else if (draw
== DRAW_MOUSE_FACE
)
19836 FRAME_RIF (f
)->define_frame_cursor (f
, FRAME_X_OUTPUT (f
)->hand_cursor
);
19838 FRAME_RIF (f
)->define_frame_cursor (f
, FRAME_X_OUTPUT (f
)->nontext_cursor
);
19842 Clear out the mouse-highlighted active region.
19843 Redraw it un-highlighted first. Value is non-zero if mouse
19844 face was actually drawn unhighlighted. */
19847 clear_mouse_face (dpyinfo
)
19848 Display_Info
*dpyinfo
;
19852 if (!dpyinfo
->mouse_face_hidden
&& !NILP (dpyinfo
->mouse_face_window
))
19854 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
19858 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
19859 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
19860 dpyinfo
->mouse_face_window
= Qnil
;
19861 dpyinfo
->mouse_face_overlay
= Qnil
;
19867 Non-zero if physical cursor of window W is within mouse face. */
19870 cursor_in_mouse_face_p (w
)
19873 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (XFRAME (w
->frame
));
19874 int in_mouse_face
= 0;
19876 if (WINDOWP (dpyinfo
->mouse_face_window
)
19877 && XWINDOW (dpyinfo
->mouse_face_window
) == w
)
19879 int hpos
= w
->phys_cursor
.hpos
;
19880 int vpos
= w
->phys_cursor
.vpos
;
19882 if (vpos
>= dpyinfo
->mouse_face_beg_row
19883 && vpos
<= dpyinfo
->mouse_face_end_row
19884 && (vpos
> dpyinfo
->mouse_face_beg_row
19885 || hpos
>= dpyinfo
->mouse_face_beg_col
)
19886 && (vpos
< dpyinfo
->mouse_face_end_row
19887 || hpos
< dpyinfo
->mouse_face_end_col
19888 || dpyinfo
->mouse_face_past_end
))
19892 return in_mouse_face
;
19898 /* Find the glyph matrix position of buffer position CHARPOS in window
19899 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
19900 current glyphs must be up to date. If CHARPOS is above window
19901 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
19902 of last line in W. In the row containing CHARPOS, stop before glyphs
19903 having STOP as object. */
19905 #if 1 /* This is a version of fast_find_position that's more correct
19906 in the presence of hscrolling, for example. I didn't install
19907 it right away because the problem fixed is minor, it failed
19908 in 20.x as well, and I think it's too risky to install
19909 so near the release of 21.1. 2001-09-25 gerd. */
19912 fast_find_position (w
, charpos
, hpos
, vpos
, x
, y
, stop
)
19915 int *hpos
, *vpos
, *x
, *y
;
19918 struct glyph_row
*row
, *first
;
19919 struct glyph
*glyph
, *end
;
19922 first
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
19923 row
= row_containing_pos (w
, charpos
, first
, NULL
, 0);
19926 if (charpos
< MATRIX_ROW_START_CHARPOS (first
))
19928 *x
= *y
= *hpos
= *vpos
= 0;
19933 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
19940 *vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
19942 glyph
= row
->glyphs
[TEXT_AREA
];
19943 end
= glyph
+ row
->used
[TEXT_AREA
];
19945 /* Skip over glyphs not having an object at the start of the row.
19946 These are special glyphs like truncation marks on terminal
19948 if (row
->displays_text_p
)
19950 && INTEGERP (glyph
->object
)
19951 && !EQ (stop
, glyph
->object
)
19952 && glyph
->charpos
< 0)
19954 *x
+= glyph
->pixel_width
;
19959 && !INTEGERP (glyph
->object
)
19960 && !EQ (stop
, glyph
->object
)
19961 && (!BUFFERP (glyph
->object
)
19962 || glyph
->charpos
< charpos
))
19964 *x
+= glyph
->pixel_width
;
19968 *hpos
= glyph
- row
->glyphs
[TEXT_AREA
];
19975 fast_find_position (w
, pos
, hpos
, vpos
, x
, y
, stop
)
19978 int *hpos
, *vpos
, *x
, *y
;
19983 int maybe_next_line_p
= 0;
19984 int line_start_position
;
19985 int yb
= window_text_bottom_y (w
);
19986 struct glyph_row
*row
, *best_row
;
19987 int row_vpos
, best_row_vpos
;
19990 row
= best_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
19991 row_vpos
= best_row_vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
19993 while (row
->y
< yb
)
19995 if (row
->used
[TEXT_AREA
])
19996 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
19998 line_start_position
= 0;
20000 if (line_start_position
> pos
)
20002 /* If the position sought is the end of the buffer,
20003 don't include the blank lines at the bottom of the window. */
20004 else if (line_start_position
== pos
20005 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
20007 maybe_next_line_p
= 1;
20010 else if (line_start_position
> 0)
20013 best_row_vpos
= row_vpos
;
20016 if (row
->y
+ row
->height
>= yb
)
20023 /* Find the right column within BEST_ROW. */
20025 current_x
= best_row
->x
;
20026 for (i
= 0; i
< best_row
->used
[TEXT_AREA
]; i
++)
20028 struct glyph
*glyph
= best_row
->glyphs
[TEXT_AREA
] + i
;
20029 int charpos
= glyph
->charpos
;
20031 if (BUFFERP (glyph
->object
))
20033 if (charpos
== pos
)
20036 *vpos
= best_row_vpos
;
20041 else if (charpos
> pos
)
20044 else if (EQ (glyph
->object
, stop
))
20049 current_x
+= glyph
->pixel_width
;
20052 /* If we're looking for the end of the buffer,
20053 and we didn't find it in the line we scanned,
20054 use the start of the following line. */
20055 if (maybe_next_line_p
)
20060 current_x
= best_row
->x
;
20063 *vpos
= best_row_vpos
;
20064 *hpos
= lastcol
+ 1;
20073 /* Find the position of the glyph for position POS in OBJECT in
20074 window W's current matrix, and return in *X, *Y the pixel
20075 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
20077 RIGHT_P non-zero means return the position of the right edge of the
20078 glyph, RIGHT_P zero means return the left edge position.
20080 If no glyph for POS exists in the matrix, return the position of
20081 the glyph with the next smaller position that is in the matrix, if
20082 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
20083 exists in the matrix, return the position of the glyph with the
20084 next larger position in OBJECT.
20086 Value is non-zero if a glyph was found. */
20089 fast_find_string_pos (w
, pos
, object
, hpos
, vpos
, x
, y
, right_p
)
20092 Lisp_Object object
;
20093 int *hpos
, *vpos
, *x
, *y
;
20096 int yb
= window_text_bottom_y (w
);
20097 struct glyph_row
*r
;
20098 struct glyph
*best_glyph
= NULL
;
20099 struct glyph_row
*best_row
= NULL
;
20102 for (r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
20103 r
->enabled_p
&& r
->y
< yb
;
20106 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
20107 struct glyph
*e
= g
+ r
->used
[TEXT_AREA
];
20110 for (gx
= r
->x
; g
< e
; gx
+= g
->pixel_width
, ++g
)
20111 if (EQ (g
->object
, object
))
20113 if (g
->charpos
== pos
)
20120 else if (best_glyph
== NULL
20121 || ((abs (g
->charpos
- pos
)
20122 < abs (best_glyph
->charpos
- pos
))
20125 : g
->charpos
> pos
)))
20139 *hpos
= best_glyph
- best_row
->glyphs
[TEXT_AREA
];
20143 *x
+= best_glyph
->pixel_width
;
20148 *vpos
= best_row
- w
->current_matrix
->rows
;
20151 return best_glyph
!= NULL
;
20155 /* See if position X, Y is within a hot-spot of an image. */
20158 on_hot_spot_p (hot_spot
, x
, y
)
20159 Lisp_Object hot_spot
;
20162 if (!CONSP (hot_spot
))
20165 if (EQ (XCAR (hot_spot
), Qrect
))
20167 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
20168 Lisp_Object rect
= XCDR (hot_spot
);
20172 if (!CONSP (XCAR (rect
)))
20174 if (!CONSP (XCDR (rect
)))
20176 if (!(tem
= XCAR (XCAR (rect
)), INTEGERP (tem
) && x
>= XINT (tem
)))
20178 if (!(tem
= XCDR (XCAR (rect
)), INTEGERP (tem
) && y
>= XINT (tem
)))
20180 if (!(tem
= XCAR (XCDR (rect
)), INTEGERP (tem
) && x
<= XINT (tem
)))
20182 if (!(tem
= XCDR (XCDR (rect
)), INTEGERP (tem
) && y
<= XINT (tem
)))
20186 else if (EQ (XCAR (hot_spot
), Qcircle
))
20188 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
20189 Lisp_Object circ
= XCDR (hot_spot
);
20190 Lisp_Object lr
, lx0
, ly0
;
20192 && CONSP (XCAR (circ
))
20193 && (lr
= XCDR (circ
), INTEGERP (lr
) || FLOATP (lr
))
20194 && (lx0
= XCAR (XCAR (circ
)), INTEGERP (lx0
))
20195 && (ly0
= XCDR (XCAR (circ
)), INTEGERP (ly0
)))
20197 double r
= XFLOATINT (lr
);
20198 double dx
= XINT (lx0
) - x
;
20199 double dy
= XINT (ly0
) - y
;
20200 return (dx
* dx
+ dy
* dy
<= r
* r
);
20203 else if (EQ (XCAR (hot_spot
), Qpoly
))
20205 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
20206 if (VECTORP (XCDR (hot_spot
)))
20208 struct Lisp_Vector
*v
= XVECTOR (XCDR (hot_spot
));
20209 Lisp_Object
*poly
= v
->contents
;
20213 Lisp_Object lx
, ly
;
20216 /* Need an even number of coordinates, and at least 3 edges. */
20217 if (n
< 6 || n
& 1)
20220 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
20221 If count is odd, we are inside polygon. Pixels on edges
20222 may or may not be included depending on actual geometry of the
20224 if ((lx
= poly
[n
-2], !INTEGERP (lx
))
20225 || (ly
= poly
[n
-1], !INTEGERP (lx
)))
20227 x0
= XINT (lx
), y0
= XINT (ly
);
20228 for (i
= 0; i
< n
; i
+= 2)
20230 int x1
= x0
, y1
= y0
;
20231 if ((lx
= poly
[i
], !INTEGERP (lx
))
20232 || (ly
= poly
[i
+1], !INTEGERP (ly
)))
20234 x0
= XINT (lx
), y0
= XINT (ly
);
20236 /* Does this segment cross the X line? */
20244 if (y
> y0
&& y
> y1
)
20246 if (y
< y0
+ ((y1
- y0
) * (x
- x0
)) / (x1
- x0
))
20256 find_hot_spot (map
, x
, y
)
20260 while (CONSP (map
))
20262 if (CONSP (XCAR (map
))
20263 && on_hot_spot_p (XCAR (XCAR (map
)), x
, y
))
20271 DEFUN ("lookup-image-map", Flookup_image_map
, Slookup_image_map
,
20273 doc
: /* Lookup in image map MAP coordinates X and Y.
20274 An image map is an alist where each element has the format (AREA ID PLIST).
20275 An AREA is specified as either a rectangle, a circle, or a polygon:
20276 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
20277 pixel coordinates of the upper left and bottom right corners.
20278 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
20279 and the radius of the circle; r may be a float or integer.
20280 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
20281 vector describes one corner in the polygon.
20282 Returns the alist element for the first matching AREA in MAP. */)
20293 return find_hot_spot (map
, XINT (x
), XINT (y
));
20297 /* Display frame CURSOR, optionally using shape defined by POINTER. */
20299 define_frame_cursor1 (f
, cursor
, pointer
)
20302 Lisp_Object pointer
;
20304 if (!NILP (pointer
))
20306 if (EQ (pointer
, Qarrow
))
20307 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
20308 else if (EQ (pointer
, Qhand
))
20309 cursor
= FRAME_X_OUTPUT (f
)->hand_cursor
;
20310 else if (EQ (pointer
, Qtext
))
20311 cursor
= FRAME_X_OUTPUT (f
)->text_cursor
;
20312 else if (EQ (pointer
, intern ("hdrag")))
20313 cursor
= FRAME_X_OUTPUT (f
)->horizontal_drag_cursor
;
20314 #ifdef HAVE_X_WINDOWS
20315 else if (EQ (pointer
, intern ("vdrag")))
20316 cursor
= FRAME_X_DISPLAY_INFO (f
)->vertical_scroll_bar_cursor
;
20318 else if (EQ (pointer
, intern ("hourglass")))
20319 cursor
= FRAME_X_OUTPUT (f
)->hourglass_cursor
;
20320 else if (EQ (pointer
, Qmodeline
))
20321 cursor
= FRAME_X_OUTPUT (f
)->modeline_cursor
;
20323 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
20326 #ifndef HAVE_CARBON
20327 if (cursor
!= No_Cursor
)
20329 if (bcmp (&cursor
, &No_Cursor
, sizeof (Cursor
)))
20331 FRAME_RIF (f
)->define_frame_cursor (f
, cursor
);
20334 /* Take proper action when mouse has moved to the mode or header line
20335 or marginal area AREA of window W, x-position X and y-position Y.
20336 X is relative to the start of the text display area of W, so the
20337 width of bitmap areas and scroll bars must be subtracted to get a
20338 position relative to the start of the mode line. */
20341 note_mode_line_or_margin_highlight (w
, x
, y
, area
)
20344 enum window_part area
;
20346 struct frame
*f
= XFRAME (w
->frame
);
20347 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
20348 Cursor cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
20349 Lisp_Object pointer
= Qnil
;
20350 int charpos
, dx
, dy
, width
, height
;
20351 Lisp_Object string
, object
= Qnil
;
20352 Lisp_Object pos
, help
;
20354 if (area
== ON_MODE_LINE
|| area
== ON_HEADER_LINE
)
20355 string
= mode_line_string (w
, area
, &x
, &y
, &charpos
,
20356 &object
, &dx
, &dy
, &width
, &height
);
20359 x
-= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w
);
20360 string
= marginal_area_string (w
, area
, &x
, &y
, &charpos
,
20361 &object
, &dx
, &dy
, &width
, &height
);
20366 if (IMAGEP (object
))
20368 Lisp_Object image_map
, hotspot
;
20369 if ((image_map
= Fplist_get (XCDR (object
), QCmap
),
20371 && (hotspot
= find_hot_spot (image_map
, dx
, dy
),
20373 && (hotspot
= XCDR (hotspot
), CONSP (hotspot
)))
20375 Lisp_Object area_id
, plist
;
20377 area_id
= XCAR (hotspot
);
20378 /* Could check AREA_ID to see if we enter/leave this hot-spot.
20379 If so, we could look for mouse-enter, mouse-leave
20380 properties in PLIST (and do something...). */
20381 if ((plist
= XCDR (hotspot
), CONSP (plist
)))
20383 pointer
= Fplist_get (plist
, Qpointer
);
20384 if (NILP (pointer
))
20386 help
= Fplist_get (plist
, Qhelp_echo
);
20389 help_echo_string
= help
;
20390 /* Is this correct? ++kfs */
20391 XSETWINDOW (help_echo_window
, w
);
20392 help_echo_object
= w
->buffer
;
20393 help_echo_pos
= charpos
;
20396 if (NILP (pointer
))
20397 pointer
= Fplist_get (XCDR (object
), QCpointer
);
20401 if (STRINGP (string
))
20403 pos
= make_number (charpos
);
20404 /* If we're on a string with `help-echo' text property, arrange
20405 for the help to be displayed. This is done by setting the
20406 global variable help_echo_string to the help string. */
20407 help
= Fget_text_property (pos
, Qhelp_echo
, string
);
20410 help_echo_string
= help
;
20411 XSETWINDOW (help_echo_window
, w
);
20412 help_echo_object
= string
;
20413 help_echo_pos
= charpos
;
20416 if (NILP (pointer
))
20417 pointer
= Fget_text_property (pos
, Qpointer
, string
);
20419 /* Change the mouse pointer according to what is under X/Y. */
20420 if (NILP (pointer
) && ((area
== ON_MODE_LINE
) || (area
== ON_HEADER_LINE
)))
20423 map
= Fget_text_property (pos
, Qlocal_map
, string
);
20424 if (!KEYMAPP (map
))
20425 map
= Fget_text_property (pos
, Qkeymap
, string
);
20426 if (!KEYMAPP (map
))
20427 cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
20431 define_frame_cursor1 (f
, cursor
, pointer
);
20436 Take proper action when the mouse has moved to position X, Y on
20437 frame F as regards highlighting characters that have mouse-face
20438 properties. Also de-highlighting chars where the mouse was before.
20439 X and Y can be negative or out of range. */
20442 note_mouse_highlight (f
, x
, y
)
20446 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
20447 enum window_part part
;
20448 Lisp_Object window
;
20450 Cursor cursor
= No_Cursor
;
20451 Lisp_Object pointer
= Qnil
; /* Takes precedence over cursor! */
20454 /* When a menu is active, don't highlight because this looks odd. */
20455 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
20456 if (popup_activated ())
20460 if (NILP (Vmouse_highlight
)
20461 || !f
->glyphs_initialized_p
)
20464 dpyinfo
->mouse_face_mouse_x
= x
;
20465 dpyinfo
->mouse_face_mouse_y
= y
;
20466 dpyinfo
->mouse_face_mouse_frame
= f
;
20468 if (dpyinfo
->mouse_face_defer
)
20471 if (gc_in_progress
)
20473 dpyinfo
->mouse_face_deferred_gc
= 1;
20477 /* Which window is that in? */
20478 window
= window_from_coordinates (f
, x
, y
, &part
, 0, 0, 1);
20480 /* If we were displaying active text in another window, clear that. */
20481 if (! EQ (window
, dpyinfo
->mouse_face_window
))
20482 clear_mouse_face (dpyinfo
);
20484 /* Not on a window -> return. */
20485 if (!WINDOWP (window
))
20488 /* Reset help_echo_string. It will get recomputed below. */
20489 help_echo_string
= Qnil
;
20491 /* Convert to window-relative pixel coordinates. */
20492 w
= XWINDOW (window
);
20493 frame_to_window_pixel_xy (w
, &x
, &y
);
20495 /* Handle tool-bar window differently since it doesn't display a
20497 if (EQ (window
, f
->tool_bar_window
))
20499 note_tool_bar_highlight (f
, x
, y
);
20503 /* Mouse is on the mode, header line or margin? */
20504 if (part
== ON_MODE_LINE
|| part
== ON_HEADER_LINE
20505 || part
== ON_LEFT_MARGIN
|| part
== ON_RIGHT_MARGIN
)
20507 note_mode_line_or_margin_highlight (w
, x
, y
, part
);
20511 if (part
== ON_VERTICAL_BORDER
)
20512 cursor
= FRAME_X_OUTPUT (f
)->horizontal_drag_cursor
;
20513 else if (part
== ON_LEFT_FRINGE
|| part
== ON_RIGHT_FRINGE
)
20514 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
20516 cursor
= FRAME_X_OUTPUT (f
)->text_cursor
;
20518 /* Are we in a window whose display is up to date?
20519 And verify the buffer's text has not changed. */
20520 b
= XBUFFER (w
->buffer
);
20521 if (part
== ON_TEXT
20522 && EQ (w
->window_end_valid
, w
->buffer
)
20523 && XFASTINT (w
->last_modified
) == BUF_MODIFF (b
)
20524 && XFASTINT (w
->last_overlay_modified
) == BUF_OVERLAY_MODIFF (b
))
20526 int hpos
, vpos
, pos
, i
, dx
, dy
, area
;
20527 struct glyph
*glyph
;
20528 Lisp_Object object
;
20529 Lisp_Object mouse_face
= Qnil
, overlay
= Qnil
, position
;
20530 Lisp_Object
*overlay_vec
= NULL
;
20531 int len
, noverlays
;
20532 struct buffer
*obuf
;
20533 int obegv
, ozv
, same_region
;
20535 /* Find the glyph under X/Y. */
20536 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &dx
, &dy
, &area
);
20538 /* Look for :pointer property on image. */
20539 if (glyph
!= NULL
&& glyph
->type
== IMAGE_GLYPH
)
20541 struct image
*img
= IMAGE_FROM_ID (f
, glyph
->u
.img_id
);
20542 if (img
!= NULL
&& IMAGEP (img
->spec
))
20544 Lisp_Object image_map
, hotspot
;
20545 if ((image_map
= Fplist_get (XCDR (img
->spec
), QCmap
),
20547 && (hotspot
= find_hot_spot (image_map
, dx
, dy
),
20549 && (hotspot
= XCDR (hotspot
), CONSP (hotspot
)))
20551 Lisp_Object area_id
, plist
;
20553 area_id
= XCAR (hotspot
);
20554 /* Could check AREA_ID to see if we enter/leave this hot-spot.
20555 If so, we could look for mouse-enter, mouse-leave
20556 properties in PLIST (and do something...). */
20557 if ((plist
= XCDR (hotspot
), CONSP (plist
)))
20559 pointer
= Fplist_get (plist
, Qpointer
);
20560 if (NILP (pointer
))
20562 help_echo_string
= Fplist_get (plist
, Qhelp_echo
);
20563 if (!NILP (help_echo_string
))
20565 help_echo_window
= window
;
20566 help_echo_object
= glyph
->object
;
20567 help_echo_pos
= glyph
->charpos
;
20571 if (NILP (pointer
))
20572 pointer
= Fplist_get (XCDR (img
->spec
), QCpointer
);
20576 /* Clear mouse face if X/Y not over text. */
20578 || area
!= TEXT_AREA
20579 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
)
20581 if (clear_mouse_face (dpyinfo
))
20582 cursor
= No_Cursor
;
20583 if (NILP (pointer
))
20585 if (area
!= TEXT_AREA
)
20586 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
20588 pointer
= Vvoid_text_area_pointer
;
20593 pos
= glyph
->charpos
;
20594 object
= glyph
->object
;
20595 if (!STRINGP (object
) && !BUFFERP (object
))
20598 /* If we get an out-of-range value, return now; avoid an error. */
20599 if (BUFFERP (object
) && pos
> BUF_Z (b
))
20602 /* Make the window's buffer temporarily current for
20603 overlays_at and compute_char_face. */
20604 obuf
= current_buffer
;
20605 current_buffer
= b
;
20611 /* Is this char mouse-active or does it have help-echo? */
20612 position
= make_number (pos
);
20614 if (BUFFERP (object
))
20616 /* Put all the overlays we want in a vector in overlay_vec.
20617 Store the length in len. If there are more than 10, make
20618 enough space for all, and try again. */
20620 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
20621 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
, 0);
20622 if (noverlays
> len
)
20625 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
20626 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
,0);
20629 /* Sort overlays into increasing priority order. */
20630 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
20635 same_region
= (EQ (window
, dpyinfo
->mouse_face_window
)
20636 && vpos
>= dpyinfo
->mouse_face_beg_row
20637 && vpos
<= dpyinfo
->mouse_face_end_row
20638 && (vpos
> dpyinfo
->mouse_face_beg_row
20639 || hpos
>= dpyinfo
->mouse_face_beg_col
)
20640 && (vpos
< dpyinfo
->mouse_face_end_row
20641 || hpos
< dpyinfo
->mouse_face_end_col
20642 || dpyinfo
->mouse_face_past_end
));
20645 cursor
= No_Cursor
;
20647 /* Check mouse-face highlighting. */
20649 /* If there exists an overlay with mouse-face overlapping
20650 the one we are currently highlighting, we have to
20651 check if we enter the overlapping overlay, and then
20652 highlight only that. */
20653 || (OVERLAYP (dpyinfo
->mouse_face_overlay
)
20654 && mouse_face_overlay_overlaps (dpyinfo
->mouse_face_overlay
)))
20656 /* Find the highest priority overlay that has a mouse-face
20659 for (i
= noverlays
- 1; i
>= 0 && NILP (overlay
); --i
)
20661 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
20662 if (!NILP (mouse_face
))
20663 overlay
= overlay_vec
[i
];
20666 /* If we're actually highlighting the same overlay as
20667 before, there's no need to do that again. */
20668 if (!NILP (overlay
)
20669 && EQ (overlay
, dpyinfo
->mouse_face_overlay
))
20670 goto check_help_echo
;
20672 dpyinfo
->mouse_face_overlay
= overlay
;
20674 /* Clear the display of the old active region, if any. */
20675 if (clear_mouse_face (dpyinfo
))
20676 cursor
= No_Cursor
;
20678 /* If no overlay applies, get a text property. */
20679 if (NILP (overlay
))
20680 mouse_face
= Fget_text_property (position
, Qmouse_face
, object
);
20682 /* Handle the overlay case. */
20683 if (!NILP (overlay
))
20685 /* Find the range of text around this char that
20686 should be active. */
20687 Lisp_Object before
, after
;
20690 before
= Foverlay_start (overlay
);
20691 after
= Foverlay_end (overlay
);
20692 /* Record this as the current active region. */
20693 fast_find_position (w
, XFASTINT (before
),
20694 &dpyinfo
->mouse_face_beg_col
,
20695 &dpyinfo
->mouse_face_beg_row
,
20696 &dpyinfo
->mouse_face_beg_x
,
20697 &dpyinfo
->mouse_face_beg_y
, Qnil
);
20699 dpyinfo
->mouse_face_past_end
20700 = !fast_find_position (w
, XFASTINT (after
),
20701 &dpyinfo
->mouse_face_end_col
,
20702 &dpyinfo
->mouse_face_end_row
,
20703 &dpyinfo
->mouse_face_end_x
,
20704 &dpyinfo
->mouse_face_end_y
, Qnil
);
20705 dpyinfo
->mouse_face_window
= window
;
20707 dpyinfo
->mouse_face_face_id
20708 = face_at_buffer_position (w
, pos
, 0, 0,
20710 !dpyinfo
->mouse_face_hidden
);
20712 /* Display it as active. */
20713 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
20714 cursor
= No_Cursor
;
20716 /* Handle the text property case. */
20717 else if (!NILP (mouse_face
) && BUFFERP (object
))
20719 /* Find the range of text around this char that
20720 should be active. */
20721 Lisp_Object before
, after
, beginning
, end
;
20724 beginning
= Fmarker_position (w
->start
);
20725 end
= make_number (BUF_Z (XBUFFER (object
))
20726 - XFASTINT (w
->window_end_pos
));
20728 = Fprevious_single_property_change (make_number (pos
+ 1),
20730 object
, beginning
);
20732 = Fnext_single_property_change (position
, Qmouse_face
,
20735 /* Record this as the current active region. */
20736 fast_find_position (w
, XFASTINT (before
),
20737 &dpyinfo
->mouse_face_beg_col
,
20738 &dpyinfo
->mouse_face_beg_row
,
20739 &dpyinfo
->mouse_face_beg_x
,
20740 &dpyinfo
->mouse_face_beg_y
, Qnil
);
20741 dpyinfo
->mouse_face_past_end
20742 = !fast_find_position (w
, XFASTINT (after
),
20743 &dpyinfo
->mouse_face_end_col
,
20744 &dpyinfo
->mouse_face_end_row
,
20745 &dpyinfo
->mouse_face_end_x
,
20746 &dpyinfo
->mouse_face_end_y
, Qnil
);
20747 dpyinfo
->mouse_face_window
= window
;
20749 if (BUFFERP (object
))
20750 dpyinfo
->mouse_face_face_id
20751 = face_at_buffer_position (w
, pos
, 0, 0,
20753 !dpyinfo
->mouse_face_hidden
);
20755 /* Display it as active. */
20756 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
20757 cursor
= No_Cursor
;
20759 else if (!NILP (mouse_face
) && STRINGP (object
))
20764 b
= Fprevious_single_property_change (make_number (pos
+ 1),
20767 e
= Fnext_single_property_change (position
, Qmouse_face
,
20770 b
= make_number (0);
20772 e
= make_number (SCHARS (object
) - 1);
20773 fast_find_string_pos (w
, XINT (b
), object
,
20774 &dpyinfo
->mouse_face_beg_col
,
20775 &dpyinfo
->mouse_face_beg_row
,
20776 &dpyinfo
->mouse_face_beg_x
,
20777 &dpyinfo
->mouse_face_beg_y
, 0);
20778 fast_find_string_pos (w
, XINT (e
), object
,
20779 &dpyinfo
->mouse_face_end_col
,
20780 &dpyinfo
->mouse_face_end_row
,
20781 &dpyinfo
->mouse_face_end_x
,
20782 &dpyinfo
->mouse_face_end_y
, 1);
20783 dpyinfo
->mouse_face_past_end
= 0;
20784 dpyinfo
->mouse_face_window
= window
;
20785 dpyinfo
->mouse_face_face_id
20786 = face_at_string_position (w
, object
, pos
, 0, 0, 0, &ignore
,
20787 glyph
->face_id
, 1);
20788 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
20789 cursor
= No_Cursor
;
20791 else if (STRINGP (object
) && NILP (mouse_face
))
20793 /* A string which doesn't have mouse-face, but
20794 the text ``under'' it might have. */
20795 struct glyph_row
*r
= MATRIX_ROW (w
->current_matrix
, vpos
);
20796 int start
= MATRIX_ROW_START_CHARPOS (r
);
20798 pos
= string_buffer_position (w
, object
, start
);
20800 mouse_face
= get_char_property_and_overlay (make_number (pos
),
20804 if (!NILP (mouse_face
) && !NILP (overlay
))
20806 Lisp_Object before
= Foverlay_start (overlay
);
20807 Lisp_Object after
= Foverlay_end (overlay
);
20810 /* Note that we might not be able to find position
20811 BEFORE in the glyph matrix if the overlay is
20812 entirely covered by a `display' property. In
20813 this case, we overshoot. So let's stop in
20814 the glyph matrix before glyphs for OBJECT. */
20815 fast_find_position (w
, XFASTINT (before
),
20816 &dpyinfo
->mouse_face_beg_col
,
20817 &dpyinfo
->mouse_face_beg_row
,
20818 &dpyinfo
->mouse_face_beg_x
,
20819 &dpyinfo
->mouse_face_beg_y
,
20822 dpyinfo
->mouse_face_past_end
20823 = !fast_find_position (w
, XFASTINT (after
),
20824 &dpyinfo
->mouse_face_end_col
,
20825 &dpyinfo
->mouse_face_end_row
,
20826 &dpyinfo
->mouse_face_end_x
,
20827 &dpyinfo
->mouse_face_end_y
,
20829 dpyinfo
->mouse_face_window
= window
;
20830 dpyinfo
->mouse_face_face_id
20831 = face_at_buffer_position (w
, pos
, 0, 0,
20833 !dpyinfo
->mouse_face_hidden
);
20835 /* Display it as active. */
20836 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
20837 cursor
= No_Cursor
;
20844 /* Look for a `help-echo' property. */
20845 if (NILP (help_echo_string
)) {
20846 Lisp_Object help
, overlay
;
20848 /* Check overlays first. */
20849 help
= overlay
= Qnil
;
20850 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
20852 overlay
= overlay_vec
[i
];
20853 help
= Foverlay_get (overlay
, Qhelp_echo
);
20858 help_echo_string
= help
;
20859 help_echo_window
= window
;
20860 help_echo_object
= overlay
;
20861 help_echo_pos
= pos
;
20865 Lisp_Object object
= glyph
->object
;
20866 int charpos
= glyph
->charpos
;
20868 /* Try text properties. */
20869 if (STRINGP (object
)
20871 && charpos
< SCHARS (object
))
20873 help
= Fget_text_property (make_number (charpos
),
20874 Qhelp_echo
, object
);
20877 /* If the string itself doesn't specify a help-echo,
20878 see if the buffer text ``under'' it does. */
20879 struct glyph_row
*r
20880 = MATRIX_ROW (w
->current_matrix
, vpos
);
20881 int start
= MATRIX_ROW_START_CHARPOS (r
);
20882 int pos
= string_buffer_position (w
, object
, start
);
20885 help
= Fget_char_property (make_number (pos
),
20886 Qhelp_echo
, w
->buffer
);
20890 object
= w
->buffer
;
20895 else if (BUFFERP (object
)
20898 help
= Fget_text_property (make_number (charpos
), Qhelp_echo
,
20903 help_echo_string
= help
;
20904 help_echo_window
= window
;
20905 help_echo_object
= object
;
20906 help_echo_pos
= charpos
;
20911 /* Look for a `pointer' property. */
20912 if (NILP (pointer
))
20914 /* Check overlays first. */
20915 for (i
= noverlays
- 1; i
>= 0 && NILP (pointer
); --i
)
20916 pointer
= Foverlay_get (overlay_vec
[i
], Qpointer
);
20918 if (NILP (pointer
))
20920 Lisp_Object object
= glyph
->object
;
20921 int charpos
= glyph
->charpos
;
20923 /* Try text properties. */
20924 if (STRINGP (object
)
20926 && charpos
< SCHARS (object
))
20928 pointer
= Fget_text_property (make_number (charpos
),
20930 if (NILP (pointer
))
20932 /* If the string itself doesn't specify a pointer,
20933 see if the buffer text ``under'' it does. */
20934 struct glyph_row
*r
20935 = MATRIX_ROW (w
->current_matrix
, vpos
);
20936 int start
= MATRIX_ROW_START_CHARPOS (r
);
20937 int pos
= string_buffer_position (w
, object
, start
);
20939 pointer
= Fget_char_property (make_number (pos
),
20940 Qpointer
, w
->buffer
);
20943 else if (BUFFERP (object
)
20946 pointer
= Fget_text_property (make_number (charpos
),
20953 current_buffer
= obuf
;
20958 define_frame_cursor1 (f
, cursor
, pointer
);
20963 Clear any mouse-face on window W. This function is part of the
20964 redisplay interface, and is called from try_window_id and similar
20965 functions to ensure the mouse-highlight is off. */
20968 x_clear_window_mouse_face (w
)
20971 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (XFRAME (w
->frame
));
20972 Lisp_Object window
;
20975 XSETWINDOW (window
, w
);
20976 if (EQ (window
, dpyinfo
->mouse_face_window
))
20977 clear_mouse_face (dpyinfo
);
20983 Just discard the mouse face information for frame F, if any.
20984 This is used when the size of F is changed. */
20987 cancel_mouse_face (f
)
20990 Lisp_Object window
;
20991 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
20993 window
= dpyinfo
->mouse_face_window
;
20994 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
20996 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
20997 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
20998 dpyinfo
->mouse_face_window
= Qnil
;
21003 #endif /* HAVE_WINDOW_SYSTEM */
21006 /***********************************************************************
21008 ***********************************************************************/
21010 #ifdef HAVE_WINDOW_SYSTEM
21012 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
21013 which intersects rectangle R. R is in window-relative coordinates. */
21016 expose_area (w
, row
, r
, area
)
21018 struct glyph_row
*row
;
21020 enum glyph_row_area area
;
21022 struct glyph
*first
= row
->glyphs
[area
];
21023 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
21024 struct glyph
*last
;
21025 int first_x
, start_x
, x
;
21027 if (area
== TEXT_AREA
&& row
->fill_line_p
)
21028 /* If row extends face to end of line write the whole line. */
21029 draw_glyphs (w
, 0, row
, area
,
21030 0, row
->used
[area
],
21031 DRAW_NORMAL_TEXT
, 0);
21034 /* Set START_X to the window-relative start position for drawing glyphs of
21035 AREA. The first glyph of the text area can be partially visible.
21036 The first glyphs of other areas cannot. */
21037 start_x
= window_box_left_offset (w
, area
);
21039 if (area
== TEXT_AREA
)
21042 /* Find the first glyph that must be redrawn. */
21044 && x
+ first
->pixel_width
< r
->x
)
21046 x
+= first
->pixel_width
;
21050 /* Find the last one. */
21054 && x
< r
->x
+ r
->width
)
21056 x
+= last
->pixel_width
;
21062 draw_glyphs (w
, first_x
- start_x
, row
, area
,
21063 first
- row
->glyphs
[area
], last
- row
->glyphs
[area
],
21064 DRAW_NORMAL_TEXT
, 0);
21069 /* Redraw the parts of the glyph row ROW on window W intersecting
21070 rectangle R. R is in window-relative coordinates. Value is
21071 non-zero if mouse-face was overwritten. */
21074 expose_line (w
, row
, r
)
21076 struct glyph_row
*row
;
21079 xassert (row
->enabled_p
);
21081 if (row
->mode_line_p
|| w
->pseudo_window_p
)
21082 draw_glyphs (w
, 0, row
, TEXT_AREA
,
21083 0, row
->used
[TEXT_AREA
],
21084 DRAW_NORMAL_TEXT
, 0);
21087 if (row
->used
[LEFT_MARGIN_AREA
])
21088 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
21089 if (row
->used
[TEXT_AREA
])
21090 expose_area (w
, row
, r
, TEXT_AREA
);
21091 if (row
->used
[RIGHT_MARGIN_AREA
])
21092 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
21093 draw_row_fringe_bitmaps (w
, row
);
21096 return row
->mouse_face_p
;
21100 /* Redraw those parts of glyphs rows during expose event handling that
21101 overlap other rows. Redrawing of an exposed line writes over parts
21102 of lines overlapping that exposed line; this function fixes that.
21104 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
21105 row in W's current matrix that is exposed and overlaps other rows.
21106 LAST_OVERLAPPING_ROW is the last such row. */
21109 expose_overlaps (w
, first_overlapping_row
, last_overlapping_row
)
21111 struct glyph_row
*first_overlapping_row
;
21112 struct glyph_row
*last_overlapping_row
;
21114 struct glyph_row
*row
;
21116 for (row
= first_overlapping_row
; row
<= last_overlapping_row
; ++row
)
21117 if (row
->overlapping_p
)
21119 xassert (row
->enabled_p
&& !row
->mode_line_p
);
21121 if (row
->used
[LEFT_MARGIN_AREA
])
21122 x_fix_overlapping_area (w
, row
, LEFT_MARGIN_AREA
);
21124 if (row
->used
[TEXT_AREA
])
21125 x_fix_overlapping_area (w
, row
, TEXT_AREA
);
21127 if (row
->used
[RIGHT_MARGIN_AREA
])
21128 x_fix_overlapping_area (w
, row
, RIGHT_MARGIN_AREA
);
21133 /* Return non-zero if W's cursor intersects rectangle R. */
21136 phys_cursor_in_rect_p (w
, r
)
21140 XRectangle cr
, result
;
21141 struct glyph
*cursor_glyph
;
21143 cursor_glyph
= get_phys_cursor_glyph (w
);
21146 /* r is relative to W's box, but w->phys_cursor.x is relative
21147 to left edge of W's TEXT area. Adjust it. */
21148 cr
.x
= window_box_left_offset (w
, TEXT_AREA
) + w
->phys_cursor
.x
;
21149 cr
.y
= w
->phys_cursor
.y
;
21150 cr
.width
= cursor_glyph
->pixel_width
;
21151 cr
.height
= w
->phys_cursor_height
;
21152 /* ++KFS: W32 version used W32-specific IntersectRect here, but
21153 I assume the effect is the same -- and this is portable. */
21154 return x_intersect_rectangles (&cr
, r
, &result
);
21162 Draw a vertical window border to the right of window W if W doesn't
21163 have vertical scroll bars. */
21166 x_draw_vertical_border (w
)
21169 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
21171 /* We could do better, if we knew what type of scroll-bar the adjacent
21172 windows (on either side) have... But we don't :-(
21173 However, I think this works ok. ++KFS 2003-04-25 */
21175 /* Redraw borders between horizontally adjacent windows. Don't
21176 do it for frames with vertical scroll bars because either the
21177 right scroll bar of a window, or the left scroll bar of its
21178 neighbor will suffice as a border. */
21179 if (!WINDOW_RIGHTMOST_P (w
)
21180 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w
))
21182 int x0
, x1
, y0
, y1
;
21184 window_box_edges (w
, -1, &x0
, &y0
, &x1
, &y1
);
21187 FRAME_RIF (f
)->draw_vertical_window_border (w
, x1
, y0
, y1
);
21189 else if (!WINDOW_LEFTMOST_P (w
)
21190 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w
))
21192 int x0
, x1
, y0
, y1
;
21194 window_box_edges (w
, -1, &x0
, &y0
, &x1
, &y1
);
21197 FRAME_RIF (f
)->draw_vertical_window_border (w
, x0
, y0
, y1
);
21202 /* Redraw the part of window W intersection rectangle FR. Pixel
21203 coordinates in FR are frame-relative. Call this function with
21204 input blocked. Value is non-zero if the exposure overwrites
21208 expose_window (w
, fr
)
21212 struct frame
*f
= XFRAME (w
->frame
);
21214 int mouse_face_overwritten_p
= 0;
21216 /* If window is not yet fully initialized, do nothing. This can
21217 happen when toolkit scroll bars are used and a window is split.
21218 Reconfiguring the scroll bar will generate an expose for a newly
21220 if (w
->current_matrix
== NULL
)
21223 /* When we're currently updating the window, display and current
21224 matrix usually don't agree. Arrange for a thorough display
21226 if (w
== updated_window
)
21228 SET_FRAME_GARBAGED (f
);
21232 /* Frame-relative pixel rectangle of W. */
21233 wr
.x
= WINDOW_LEFT_EDGE_X (w
);
21234 wr
.y
= WINDOW_TOP_EDGE_Y (w
);
21235 wr
.width
= WINDOW_TOTAL_WIDTH (w
);
21236 wr
.height
= WINDOW_TOTAL_HEIGHT (w
);
21238 if (x_intersect_rectangles (fr
, &wr
, &r
))
21240 int yb
= window_text_bottom_y (w
);
21241 struct glyph_row
*row
;
21242 int cursor_cleared_p
;
21243 struct glyph_row
*first_overlapping_row
, *last_overlapping_row
;
21245 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
21246 r
.x
, r
.y
, r
.width
, r
.height
));
21248 /* Convert to window coordinates. */
21249 r
.x
-= WINDOW_LEFT_EDGE_X (w
);
21250 r
.y
-= WINDOW_TOP_EDGE_Y (w
);
21252 /* Turn off the cursor. */
21253 if (!w
->pseudo_window_p
21254 && phys_cursor_in_rect_p (w
, &r
))
21256 x_clear_cursor (w
);
21257 cursor_cleared_p
= 1;
21260 cursor_cleared_p
= 0;
21262 /* Update lines intersecting rectangle R. */
21263 first_overlapping_row
= last_overlapping_row
= NULL
;
21264 for (row
= w
->current_matrix
->rows
;
21269 int y1
= MATRIX_ROW_BOTTOM_Y (row
);
21271 if ((y0
>= r
.y
&& y0
< r
.y
+ r
.height
)
21272 || (y1
> r
.y
&& y1
< r
.y
+ r
.height
)
21273 || (r
.y
>= y0
&& r
.y
< y1
)
21274 || (r
.y
+ r
.height
> y0
&& r
.y
+ r
.height
< y1
))
21276 if (row
->overlapping_p
)
21278 if (first_overlapping_row
== NULL
)
21279 first_overlapping_row
= row
;
21280 last_overlapping_row
= row
;
21283 if (expose_line (w
, row
, &r
))
21284 mouse_face_overwritten_p
= 1;
21291 /* Display the mode line if there is one. */
21292 if (WINDOW_WANTS_MODELINE_P (w
)
21293 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
21295 && row
->y
< r
.y
+ r
.height
)
21297 if (expose_line (w
, row
, &r
))
21298 mouse_face_overwritten_p
= 1;
21301 if (!w
->pseudo_window_p
)
21303 /* Fix the display of overlapping rows. */
21304 if (first_overlapping_row
)
21305 expose_overlaps (w
, first_overlapping_row
, last_overlapping_row
);
21307 /* Draw border between windows. */
21308 x_draw_vertical_border (w
);
21310 /* Turn the cursor on again. */
21311 if (cursor_cleared_p
)
21312 update_window_cursor (w
, 1);
21317 /* Display scroll bar for this window. */
21318 if (!NILP (w
->vertical_scroll_bar
))
21321 If this doesn't work here (maybe some header files are missing),
21322 make a function in macterm.c and call it to do the job! */
21324 = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (w
->vertical_scroll_bar
));
21330 return mouse_face_overwritten_p
;
21335 /* Redraw (parts) of all windows in the window tree rooted at W that
21336 intersect R. R contains frame pixel coordinates. Value is
21337 non-zero if the exposure overwrites mouse-face. */
21340 expose_window_tree (w
, r
)
21344 struct frame
*f
= XFRAME (w
->frame
);
21345 int mouse_face_overwritten_p
= 0;
21347 while (w
&& !FRAME_GARBAGED_P (f
))
21349 if (!NILP (w
->hchild
))
21350 mouse_face_overwritten_p
21351 |= expose_window_tree (XWINDOW (w
->hchild
), r
);
21352 else if (!NILP (w
->vchild
))
21353 mouse_face_overwritten_p
21354 |= expose_window_tree (XWINDOW (w
->vchild
), r
);
21356 mouse_face_overwritten_p
|= expose_window (w
, r
);
21358 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
21361 return mouse_face_overwritten_p
;
21366 Redisplay an exposed area of frame F. X and Y are the upper-left
21367 corner of the exposed rectangle. W and H are width and height of
21368 the exposed area. All are pixel values. W or H zero means redraw
21369 the entire frame. */
21372 expose_frame (f
, x
, y
, w
, h
)
21377 int mouse_face_overwritten_p
= 0;
21379 TRACE ((stderr
, "expose_frame "));
21381 /* No need to redraw if frame will be redrawn soon. */
21382 if (FRAME_GARBAGED_P (f
))
21384 TRACE ((stderr
, " garbaged\n"));
21389 /* MAC_TODO: this is a kludge, but if scroll bars are not activated
21390 or deactivated here, for unknown reasons, activated scroll bars
21391 are shown in deactivated frames in some instances. */
21392 if (f
== FRAME_MAC_DISPLAY_INFO (f
)->x_focus_frame
)
21393 activate_scroll_bars (f
);
21395 deactivate_scroll_bars (f
);
21398 /* If basic faces haven't been realized yet, there is no point in
21399 trying to redraw anything. This can happen when we get an expose
21400 event while Emacs is starting, e.g. by moving another window. */
21401 if (FRAME_FACE_CACHE (f
) == NULL
21402 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
21404 TRACE ((stderr
, " no faces\n"));
21408 if (w
== 0 || h
== 0)
21411 r
.width
= FRAME_COLUMN_WIDTH (f
) * FRAME_COLS (f
);
21412 r
.height
= FRAME_LINE_HEIGHT (f
) * FRAME_LINES (f
);
21422 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.x
, r
.y
, r
.width
, r
.height
));
21423 mouse_face_overwritten_p
= expose_window_tree (XWINDOW (f
->root_window
), &r
);
21425 if (WINDOWP (f
->tool_bar_window
))
21426 mouse_face_overwritten_p
21427 |= expose_window (XWINDOW (f
->tool_bar_window
), &r
);
21429 #ifdef HAVE_X_WINDOWS
21431 #ifndef USE_X_TOOLKIT
21432 if (WINDOWP (f
->menu_bar_window
))
21433 mouse_face_overwritten_p
21434 |= expose_window (XWINDOW (f
->menu_bar_window
), &r
);
21435 #endif /* not USE_X_TOOLKIT */
21439 /* Some window managers support a focus-follows-mouse style with
21440 delayed raising of frames. Imagine a partially obscured frame,
21441 and moving the mouse into partially obscured mouse-face on that
21442 frame. The visible part of the mouse-face will be highlighted,
21443 then the WM raises the obscured frame. With at least one WM, KDE
21444 2.1, Emacs is not getting any event for the raising of the frame
21445 (even tried with SubstructureRedirectMask), only Expose events.
21446 These expose events will draw text normally, i.e. not
21447 highlighted. Which means we must redo the highlight here.
21448 Subsume it under ``we love X''. --gerd 2001-08-15 */
21449 /* Included in Windows version because Windows most likely does not
21450 do the right thing if any third party tool offers
21451 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
21452 if (mouse_face_overwritten_p
&& !FRAME_GARBAGED_P (f
))
21454 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
21455 if (f
== dpyinfo
->mouse_face_mouse_frame
)
21457 int x
= dpyinfo
->mouse_face_mouse_x
;
21458 int y
= dpyinfo
->mouse_face_mouse_y
;
21459 clear_mouse_face (dpyinfo
);
21460 note_mouse_highlight (f
, x
, y
);
21467 Determine the intersection of two rectangles R1 and R2. Return
21468 the intersection in *RESULT. Value is non-zero if RESULT is not
21472 x_intersect_rectangles (r1
, r2
, result
)
21473 XRectangle
*r1
, *r2
, *result
;
21475 XRectangle
*left
, *right
;
21476 XRectangle
*upper
, *lower
;
21477 int intersection_p
= 0;
21479 /* Rearrange so that R1 is the left-most rectangle. */
21481 left
= r1
, right
= r2
;
21483 left
= r2
, right
= r1
;
21485 /* X0 of the intersection is right.x0, if this is inside R1,
21486 otherwise there is no intersection. */
21487 if (right
->x
<= left
->x
+ left
->width
)
21489 result
->x
= right
->x
;
21491 /* The right end of the intersection is the minimum of the
21492 the right ends of left and right. */
21493 result
->width
= (min (left
->x
+ left
->width
, right
->x
+ right
->width
)
21496 /* Same game for Y. */
21498 upper
= r1
, lower
= r2
;
21500 upper
= r2
, lower
= r1
;
21502 /* The upper end of the intersection is lower.y0, if this is inside
21503 of upper. Otherwise, there is no intersection. */
21504 if (lower
->y
<= upper
->y
+ upper
->height
)
21506 result
->y
= lower
->y
;
21508 /* The lower end of the intersection is the minimum of the lower
21509 ends of upper and lower. */
21510 result
->height
= (min (lower
->y
+ lower
->height
,
21511 upper
->y
+ upper
->height
)
21513 intersection_p
= 1;
21517 return intersection_p
;
21520 #endif /* HAVE_WINDOW_SYSTEM */
21523 /***********************************************************************
21525 ***********************************************************************/
21530 Vwith_echo_area_save_vector
= Qnil
;
21531 staticpro (&Vwith_echo_area_save_vector
);
21533 Vmessage_stack
= Qnil
;
21534 staticpro (&Vmessage_stack
);
21536 Qinhibit_redisplay
= intern ("inhibit-redisplay");
21537 staticpro (&Qinhibit_redisplay
);
21539 message_dolog_marker1
= Fmake_marker ();
21540 staticpro (&message_dolog_marker1
);
21541 message_dolog_marker2
= Fmake_marker ();
21542 staticpro (&message_dolog_marker2
);
21543 message_dolog_marker3
= Fmake_marker ();
21544 staticpro (&message_dolog_marker3
);
21547 defsubr (&Sdump_frame_glyph_matrix
);
21548 defsubr (&Sdump_glyph_matrix
);
21549 defsubr (&Sdump_glyph_row
);
21550 defsubr (&Sdump_tool_bar_row
);
21551 defsubr (&Strace_redisplay
);
21552 defsubr (&Strace_to_stderr
);
21554 #ifdef HAVE_WINDOW_SYSTEM
21555 defsubr (&Stool_bar_lines_needed
);
21556 defsubr (&Slookup_image_map
);
21558 defsubr (&Sformat_mode_line
);
21560 staticpro (&Qmenu_bar_update_hook
);
21561 Qmenu_bar_update_hook
= intern ("menu-bar-update-hook");
21563 staticpro (&Qoverriding_terminal_local_map
);
21564 Qoverriding_terminal_local_map
= intern ("overriding-terminal-local-map");
21566 staticpro (&Qoverriding_local_map
);
21567 Qoverriding_local_map
= intern ("overriding-local-map");
21569 staticpro (&Qwindow_scroll_functions
);
21570 Qwindow_scroll_functions
= intern ("window-scroll-functions");
21572 staticpro (&Qredisplay_end_trigger_functions
);
21573 Qredisplay_end_trigger_functions
= intern ("redisplay-end-trigger-functions");
21575 staticpro (&Qinhibit_point_motion_hooks
);
21576 Qinhibit_point_motion_hooks
= intern ("inhibit-point-motion-hooks");
21578 QCdata
= intern (":data");
21579 staticpro (&QCdata
);
21580 Qdisplay
= intern ("display");
21581 staticpro (&Qdisplay
);
21582 Qspace_width
= intern ("space-width");
21583 staticpro (&Qspace_width
);
21584 Qraise
= intern ("raise");
21585 staticpro (&Qraise
);
21586 Qspace
= intern ("space");
21587 staticpro (&Qspace
);
21588 Qmargin
= intern ("margin");
21589 staticpro (&Qmargin
);
21590 Qpointer
= intern ("pointer");
21591 staticpro (&Qpointer
);
21592 Qleft_margin
= intern ("left-margin");
21593 staticpro (&Qleft_margin
);
21594 Qright_margin
= intern ("right-margin");
21595 staticpro (&Qright_margin
);
21596 Qcenter
= intern ("center");
21597 staticpro (&Qcenter
);
21598 QCalign_to
= intern (":align-to");
21599 staticpro (&QCalign_to
);
21600 QCrelative_width
= intern (":relative-width");
21601 staticpro (&QCrelative_width
);
21602 QCrelative_height
= intern (":relative-height");
21603 staticpro (&QCrelative_height
);
21604 QCeval
= intern (":eval");
21605 staticpro (&QCeval
);
21606 QCpropertize
= intern (":propertize");
21607 staticpro (&QCpropertize
);
21608 QCfile
= intern (":file");
21609 staticpro (&QCfile
);
21610 Qfontified
= intern ("fontified");
21611 staticpro (&Qfontified
);
21612 Qfontification_functions
= intern ("fontification-functions");
21613 staticpro (&Qfontification_functions
);
21614 Qtrailing_whitespace
= intern ("trailing-whitespace");
21615 staticpro (&Qtrailing_whitespace
);
21616 Qimage
= intern ("image");
21617 staticpro (&Qimage
);
21618 QCmap
= intern (":map");
21619 staticpro (&QCmap
);
21620 QCpointer
= intern (":pointer");
21621 staticpro (&QCpointer
);
21622 Qrect
= intern ("rect");
21623 staticpro (&Qrect
);
21624 Qcircle
= intern ("circle");
21625 staticpro (&Qcircle
);
21626 Qpoly
= intern ("poly");
21627 staticpro (&Qpoly
);
21628 Qmessage_truncate_lines
= intern ("message-truncate-lines");
21629 staticpro (&Qmessage_truncate_lines
);
21630 Qcursor_in_non_selected_windows
= intern ("cursor-in-non-selected-windows");
21631 staticpro (&Qcursor_in_non_selected_windows
);
21632 Qgrow_only
= intern ("grow-only");
21633 staticpro (&Qgrow_only
);
21634 Qinhibit_menubar_update
= intern ("inhibit-menubar-update");
21635 staticpro (&Qinhibit_menubar_update
);
21636 Qinhibit_eval_during_redisplay
= intern ("inhibit-eval-during-redisplay");
21637 staticpro (&Qinhibit_eval_during_redisplay
);
21638 Qposition
= intern ("position");
21639 staticpro (&Qposition
);
21640 Qbuffer_position
= intern ("buffer-position");
21641 staticpro (&Qbuffer_position
);
21642 Qobject
= intern ("object");
21643 staticpro (&Qobject
);
21644 Qbar
= intern ("bar");
21646 Qhbar
= intern ("hbar");
21647 staticpro (&Qhbar
);
21648 Qbox
= intern ("box");
21650 Qhollow
= intern ("hollow");
21651 staticpro (&Qhollow
);
21652 Qhand
= intern ("hand");
21653 staticpro (&Qhand
);
21654 Qarrow
= intern ("arrow");
21655 staticpro (&Qarrow
);
21656 Qtext
= intern ("text");
21657 staticpro (&Qtext
);
21658 Qrisky_local_variable
= intern ("risky-local-variable");
21659 staticpro (&Qrisky_local_variable
);
21660 Qinhibit_free_realized_faces
= intern ("inhibit-free-realized-faces");
21661 staticpro (&Qinhibit_free_realized_faces
);
21663 list_of_error
= Fcons (Fcons (intern ("error"),
21664 Fcons (intern ("void-variable"), Qnil
)),
21666 staticpro (&list_of_error
);
21668 Qlast_arrow_position
= intern ("last-arrow-position");
21669 staticpro (&Qlast_arrow_position
);
21670 Qlast_arrow_string
= intern ("last-arrow-string");
21671 staticpro (&Qlast_arrow_string
);
21673 Qoverlay_arrow_string
= intern ("overlay-arrow-string");
21674 staticpro (&Qoverlay_arrow_string
);
21675 Qoverlay_arrow_bitmap
= intern ("overlay-arrow-bitmap");
21676 staticpro (&Qoverlay_arrow_bitmap
);
21678 echo_buffer
[0] = echo_buffer
[1] = Qnil
;
21679 staticpro (&echo_buffer
[0]);
21680 staticpro (&echo_buffer
[1]);
21682 echo_area_buffer
[0] = echo_area_buffer
[1] = Qnil
;
21683 staticpro (&echo_area_buffer
[0]);
21684 staticpro (&echo_area_buffer
[1]);
21686 Vmessages_buffer_name
= build_string ("*Messages*");
21687 staticpro (&Vmessages_buffer_name
);
21689 mode_line_proptrans_alist
= Qnil
;
21690 staticpro (&mode_line_proptrans_alist
);
21692 mode_line_string_list
= Qnil
;
21693 staticpro (&mode_line_string_list
);
21695 help_echo_string
= Qnil
;
21696 staticpro (&help_echo_string
);
21697 help_echo_object
= Qnil
;
21698 staticpro (&help_echo_object
);
21699 help_echo_window
= Qnil
;
21700 staticpro (&help_echo_window
);
21701 previous_help_echo_string
= Qnil
;
21702 staticpro (&previous_help_echo_string
);
21703 help_echo_pos
= -1;
21705 #ifdef HAVE_WINDOW_SYSTEM
21706 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
21707 doc
: /* *Non-nil means draw block cursor as wide as the glyph under it.
21708 For example, if a block cursor is over a tab, it will be drawn as
21709 wide as that tab on the display. */);
21710 x_stretch_cursor_p
= 0;
21713 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace
,
21714 doc
: /* *Non-nil means highlight trailing whitespace.
21715 The face used for trailing whitespace is `trailing-whitespace'. */);
21716 Vshow_trailing_whitespace
= Qnil
;
21718 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer
,
21719 doc
: /* *The pointer shape to show in void text areas.
21720 Nil means to show the text pointer. Other options are `arrow', `text',
21721 `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
21722 Vvoid_text_area_pointer
= Qarrow
;
21724 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay
,
21725 doc
: /* Non-nil means don't actually do any redisplay.
21726 This is used for internal purposes. */);
21727 Vinhibit_redisplay
= Qnil
;
21729 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string
,
21730 doc
: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
21731 Vglobal_mode_string
= Qnil
;
21733 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position
,
21734 doc
: /* Marker for where to display an arrow on top of the buffer text.
21735 This must be the beginning of a line in order to work.
21736 See also `overlay-arrow-string'. */);
21737 Voverlay_arrow_position
= Qnil
;
21739 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string
,
21740 doc
: /* String to display as an arrow in non-window frames.
21741 See also `overlay-arrow-position'. */);
21742 Voverlay_arrow_string
= Qnil
;
21744 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list
,
21745 doc
: /* List of variables (symbols) which hold markers for overlay arrows.
21746 The symbols on this list are examined during redisplay to determine
21747 where to display overlay arrows. */);
21748 Voverlay_arrow_variable_list
21749 = Fcons (intern ("overlay-arrow-position"), Qnil
);
21751 DEFVAR_INT ("scroll-step", &scroll_step
,
21752 doc
: /* *The number of lines to try scrolling a window by when point moves out.
21753 If that fails to bring point back on frame, point is centered instead.
21754 If this is zero, point is always centered after it moves off frame.
21755 If you want scrolling to always be a line at a time, you should set
21756 `scroll-conservatively' to a large value rather than set this to 1. */);
21758 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively
,
21759 doc
: /* *Scroll up to this many lines, to bring point back on screen.
21760 A value of zero means to scroll the text to center point vertically
21761 in the window. */);
21762 scroll_conservatively
= 0;
21764 DEFVAR_INT ("scroll-margin", &scroll_margin
,
21765 doc
: /* *Number of lines of margin at the top and bottom of a window.
21766 Recenter the window whenever point gets within this many lines
21767 of the top or bottom of the window. */);
21770 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch
,
21771 doc
: /* Pixels per inch on current display.
21772 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
21773 Vdisplay_pixels_per_inch
= make_float (72.0);
21776 DEFVAR_INT ("debug-end-pos", &debug_end_pos
, doc
: /* Don't ask. */);
21779 DEFVAR_BOOL ("truncate-partial-width-windows",
21780 &truncate_partial_width_windows
,
21781 doc
: /* *Non-nil means truncate lines in all windows less than full frame wide. */);
21782 truncate_partial_width_windows
= 1;
21784 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video
,
21785 doc
: /* nil means display the mode-line/header-line/menu-bar in the default face.
21786 Any other value means to use the appropriate face, `mode-line',
21787 `header-line', or `menu' respectively. */);
21788 mode_line_inverse_video
= 1;
21790 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit
,
21791 doc
: /* *Maximum buffer size for which line number should be displayed.
21792 If the buffer is bigger than this, the line number does not appear
21793 in the mode line. A value of nil means no limit. */);
21794 Vline_number_display_limit
= Qnil
;
21796 DEFVAR_INT ("line-number-display-limit-width",
21797 &line_number_display_limit_width
,
21798 doc
: /* *Maximum line width (in characters) for line number display.
21799 If the average length of the lines near point is bigger than this, then the
21800 line number may be omitted from the mode line. */);
21801 line_number_display_limit_width
= 200;
21803 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows
,
21804 doc
: /* *Non-nil means highlight region even in nonselected windows. */);
21805 highlight_nonselected_windows
= 0;
21807 DEFVAR_BOOL ("multiple-frames", &multiple_frames
,
21808 doc
: /* Non-nil if more than one frame is visible on this display.
21809 Minibuffer-only frames don't count, but iconified frames do.
21810 This variable is not guaranteed to be accurate except while processing
21811 `frame-title-format' and `icon-title-format'. */);
21813 DEFVAR_LISP ("frame-title-format", &Vframe_title_format
,
21814 doc
: /* Template for displaying the title bar of visible frames.
21815 \(Assuming the window manager supports this feature.)
21816 This variable has the same structure as `mode-line-format' (which see),
21817 and is used only on frames for which no explicit name has been set
21818 \(see `modify-frame-parameters'). */);
21820 DEFVAR_LISP ("icon-title-format", &Vicon_title_format
,
21821 doc
: /* Template for displaying the title bar of an iconified frame.
21822 \(Assuming the window manager supports this feature.)
21823 This variable has the same structure as `mode-line-format' (which see),
21824 and is used only on frames for which no explicit name has been set
21825 \(see `modify-frame-parameters'). */);
21827 = Vframe_title_format
21828 = Fcons (intern ("multiple-frames"),
21829 Fcons (build_string ("%b"),
21830 Fcons (Fcons (empty_string
,
21831 Fcons (intern ("invocation-name"),
21832 Fcons (build_string ("@"),
21833 Fcons (intern ("system-name"),
21837 DEFVAR_LISP ("message-log-max", &Vmessage_log_max
,
21838 doc
: /* Maximum number of lines to keep in the message log buffer.
21839 If nil, disable message logging. If t, log messages but don't truncate
21840 the buffer when it becomes large. */);
21841 Vmessage_log_max
= make_number (50);
21843 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions
,
21844 doc
: /* Functions called before redisplay, if window sizes have changed.
21845 The value should be a list of functions that take one argument.
21846 Just before redisplay, for each frame, if any of its windows have changed
21847 size since the last redisplay, or have been split or deleted,
21848 all the functions in the list are called, with the frame as argument. */);
21849 Vwindow_size_change_functions
= Qnil
;
21851 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions
,
21852 doc
: /* List of Functions to call before redisplaying a window with scrolling.
21853 Each function is called with two arguments, the window
21854 and its new display-start position. Note that the value of `window-end'
21855 is not valid when these functions are called. */);
21856 Vwindow_scroll_functions
= Qnil
;
21858 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window
,
21859 doc
: /* *Non-nil means autoselect window with mouse pointer. */);
21860 mouse_autoselect_window
= 0;
21862 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p
,
21863 doc
: /* *Non-nil means automatically resize tool-bars.
21864 This increases a tool-bar's height if not all tool-bar items are visible.
21865 It decreases a tool-bar's height when it would display blank lines
21867 auto_resize_tool_bars_p
= 1;
21869 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p
,
21870 doc
: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
21871 auto_raise_tool_bar_buttons_p
= 1;
21873 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin
,
21874 doc
: /* *Margin around tool-bar buttons in pixels.
21875 If an integer, use that for both horizontal and vertical margins.
21876 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
21877 HORZ specifying the horizontal margin, and VERT specifying the
21878 vertical margin. */);
21879 Vtool_bar_button_margin
= make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN
);
21881 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief
,
21882 doc
: /* *Relief thickness of tool-bar buttons. */);
21883 tool_bar_button_relief
= DEFAULT_TOOL_BAR_BUTTON_RELIEF
;
21885 DEFVAR_LISP ("fontification-functions", &Vfontification_functions
,
21886 doc
: /* List of functions to call to fontify regions of text.
21887 Each function is called with one argument POS. Functions must
21888 fontify a region starting at POS in the current buffer, and give
21889 fontified regions the property `fontified'. */);
21890 Vfontification_functions
= Qnil
;
21891 Fmake_variable_buffer_local (Qfontification_functions
);
21893 DEFVAR_BOOL ("unibyte-display-via-language-environment",
21894 &unibyte_display_via_language_environment
,
21895 doc
: /* *Non-nil means display unibyte text according to language environment.
21896 Specifically this means that unibyte non-ASCII characters
21897 are displayed by converting them to the equivalent multibyte characters
21898 according to the current language environment. As a result, they are
21899 displayed according to the current fontset. */);
21900 unibyte_display_via_language_environment
= 0;
21902 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height
,
21903 doc
: /* *Maximum height for resizing mini-windows.
21904 If a float, it specifies a fraction of the mini-window frame's height.
21905 If an integer, it specifies a number of lines. */);
21906 Vmax_mini_window_height
= make_float (0.25);
21908 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows
,
21909 doc
: /* *How to resize mini-windows.
21910 A value of nil means don't automatically resize mini-windows.
21911 A value of t means resize them to fit the text displayed in them.
21912 A value of `grow-only', the default, means let mini-windows grow
21913 only, until their display becomes empty, at which point the windows
21914 go back to their normal size. */);
21915 Vresize_mini_windows
= Qgrow_only
;
21917 DEFVAR_LISP ("cursor-in-non-selected-windows",
21918 &Vcursor_in_non_selected_windows
,
21919 doc
: /* *Cursor type to display in non-selected windows.
21920 t means to use hollow box cursor. See `cursor-type' for other values. */);
21921 Vcursor_in_non_selected_windows
= Qt
;
21923 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist
,
21924 doc
: /* Alist specifying how to blink the cursor off.
21925 Each element has the form (ON-STATE . OFF-STATE). Whenever the
21926 `cursor-type' frame-parameter or variable equals ON-STATE,
21927 comparing using `equal', Emacs uses OFF-STATE to specify
21928 how to blink it off. */);
21929 Vblink_cursor_alist
= Qnil
;
21931 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p
,
21932 doc
: /* *Non-nil means scroll the display automatically to make point visible. */);
21933 automatic_hscrolling_p
= 1;
21935 DEFVAR_INT ("hscroll-margin", &hscroll_margin
,
21936 doc
: /* *How many columns away from the window edge point is allowed to get
21937 before automatic hscrolling will horizontally scroll the window. */);
21938 hscroll_margin
= 5;
21940 DEFVAR_LISP ("hscroll-step", &Vhscroll_step
,
21941 doc
: /* *How many columns to scroll the window when point gets too close to the edge.
21942 When point is less than `automatic-hscroll-margin' columns from the window
21943 edge, automatic hscrolling will scroll the window by the amount of columns
21944 determined by this variable. If its value is a positive integer, scroll that
21945 many columns. If it's a positive floating-point number, it specifies the
21946 fraction of the window's width to scroll. If it's nil or zero, point will be
21947 centered horizontally after the scroll. Any other value, including negative
21948 numbers, are treated as if the value were zero.
21950 Automatic hscrolling always moves point outside the scroll margin, so if
21951 point was more than scroll step columns inside the margin, the window will
21952 scroll more than the value given by the scroll step.
21954 Note that the lower bound for automatic hscrolling specified by `scroll-left'
21955 and `scroll-right' overrides this variable's effect. */);
21956 Vhscroll_step
= make_number (0);
21958 DEFVAR_LISP ("image-types", &Vimage_types
,
21959 doc
: /* List of supported image types.
21960 Each element of the list is a symbol for a supported image type. */);
21961 Vimage_types
= Qnil
;
21963 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines
,
21964 doc
: /* If non-nil, messages are truncated instead of resizing the echo area.
21965 Bind this around calls to `message' to let it take effect. */);
21966 message_truncate_lines
= 0;
21968 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook
,
21969 doc
: /* Normal hook run for clicks on menu bar, before displaying a submenu.
21970 Can be used to update submenus whose contents should vary. */);
21971 Vmenu_bar_update_hook
= Qnil
;
21973 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update
,
21974 doc
: /* Non-nil means don't update menu bars. Internal use only. */);
21975 inhibit_menubar_update
= 0;
21977 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay
,
21978 doc
: /* Non-nil means don't eval Lisp during redisplay. */);
21979 inhibit_eval_during_redisplay
= 0;
21981 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces
,
21982 doc
: /* Non-nil means don't free realized faces. Internal use only. */);
21983 inhibit_free_realized_faces
= 0;
21986 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id
,
21987 doc
: /* Inhibit try_window_id display optimization. */);
21988 inhibit_try_window_id
= 0;
21990 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing
,
21991 doc
: /* Inhibit try_window_reusing display optimization. */);
21992 inhibit_try_window_reusing
= 0;
21994 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement
,
21995 doc
: /* Inhibit try_cursor_movement display optimization. */);
21996 inhibit_try_cursor_movement
= 0;
21997 #endif /* GLYPH_DEBUG */
22001 /* Initialize this module when Emacs starts. */
22006 Lisp_Object root_window
;
22007 struct window
*mini_w
;
22009 current_header_line_height
= current_mode_line_height
= -1;
22011 CHARPOS (this_line_start_pos
) = 0;
22013 mini_w
= XWINDOW (minibuf_window
);
22014 root_window
= FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w
)));
22016 if (!noninteractive
)
22018 struct frame
*f
= XFRAME (WINDOW_FRAME (XWINDOW (root_window
)));
22021 XWINDOW (root_window
)->top_line
= make_number (FRAME_TOP_MARGIN (f
));
22022 set_window_height (root_window
,
22023 FRAME_LINES (f
) - 1 - FRAME_TOP_MARGIN (f
),
22025 mini_w
->top_line
= make_number (FRAME_LINES (f
) - 1);
22026 set_window_height (minibuf_window
, 1, 0);
22028 XWINDOW (root_window
)->total_cols
= make_number (FRAME_COLS (f
));
22029 mini_w
->total_cols
= make_number (FRAME_COLS (f
));
22031 scratch_glyph_row
.glyphs
[TEXT_AREA
] = scratch_glyphs
;
22032 scratch_glyph_row
.glyphs
[TEXT_AREA
+ 1]
22033 = scratch_glyphs
+ MAX_SCRATCH_GLYPHS
;
22035 /* The default ellipsis glyphs `...'. */
22036 for (i
= 0; i
< 3; ++i
)
22037 default_invis_vector
[i
] = make_number ('.');
22041 /* Allocate the buffer for frame titles.
22042 Also used for `format-mode-line'. */
22044 frame_title_buf
= (char *) xmalloc (size
);
22045 frame_title_buf_end
= frame_title_buf
+ size
;
22046 frame_title_ptr
= NULL
;
22049 help_echo_showing_p
= 0;
22053 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
22054 (do not change this comment) */